diff --git a/.deepsource.toml b/.deepsource.toml deleted file mode 100644 index aebeb0f..0000000 --- a/.deepsource.toml +++ /dev/null @@ -1,8 +0,0 @@ -version = 1 - -[[analyzers]] -name = "python" -enabled = true - - [analyzers.meta] - runtime_version = "3.x.x" \ No newline at end of file diff --git a/.gitignore b/.gitignore index aaa5539..227c0a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,74 +1,6 @@ -# Config file -config.json - -# Byte-compiled / optimized / DLL files +config.py +*.session* +*database.sqlite* __pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -.env/ -venv/ -.venv/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover -.hypothesis/ - -# Translations -*.mo -# *.pot - -# Django stuff: -*.log - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -#Ipython Notebook -.ipynb_checkpoints - -# PyCharm -.idea - -# Database file -uno.sqlite3 +*/__pycache__/ +config.py diff --git a/AUTHORS.md b/AUTHORS.md deleted file mode 100644 index d3dc17a..0000000 --- a/AUTHORS.md +++ /dev/null @@ -1,17 +0,0 @@ -# Credits - -`mau_mau_bot` was originally written and maintained by [Jannes Höke](https://github.com/jh0ker) - -`UnuRobot` is now maintained by [Amano LLC](https://github.com/AmanoTeam) - -## Contributors - -The following wonderful people contributed directly or indirectly to this project: - -- [imlonghao](https://github.com/imlonghao) -- [Iuri Guilherme](https://github.com/iuriguilherme) -- [pan93412](https://github.com/pan93412) -- [qubitnerd](https://github.com/qubitnerd) -- [SYHGroup](https://github.com/SYHGroup) - -Please add yourself here alphabetically when you submit your first pull request. diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index bb84073..0000000 --- a/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM python:alpine3.4 - -RUN apk add --no-cache gettext - -WORKDIR /app/ -COPY requirements.txt . -RUN pip install -r requirements.txt - -COPY . . - -RUN cd locales && find . -maxdepth 2 -type d -name 'LC_MESSAGES' -exec ash -c 'msgfmt {}/unobot.po -o {}/unobot.mo' \; - - -VOLUME /app/data -ENV UNO_DB /app/data/uno.sqlite3 - -ENTRYPOINT python3 ./bot.py diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 2def0e8..0000000 --- a/LICENSE +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 47f9660..0000000 --- a/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# UnuRobot - -[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](./LICENSE) -[![Translation status](https://hosted.weblate.org/widgets/unurobot/-/bot/svg-badge.svg)](https://hosted.weblate.org/engage/unurobot/) - -Telegram Bot that allows you to play the popular card game UNO via inline queries. The bot currently runs as [@UnuRobot](http://t.me/UnuRobot). - -To run the bot yourself, you will need: - -- Python (tested with 3.7+) -- The [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) module -- [Pony ORM](https://ponyorm.com/) - -## Setup - -- Get a bot token from [@BotFather](http://t.me/BotFather) and change configurations in `config.json`. -- Convert all language files from `.po` files to `.mo` by executing the bash script `compile.sh` located in the `locales` folder. - Another option is: `find . -maxdepth 2 -type d -name 'LC_MESSAGES' -exec bash -c 'msgfmt {}/unobot.po -o {}/unobot.mo' \;`. -- Use `/setinline` and `/setinlinefeedback` with BotFather for your bot. -- Use `/setcommands` and submit the list of commands in commandlist.txt -- Install requirements (using a `virtualenv` is recommended): `pip install -r requirements.txt` - -You can change some gameplay parameters like turn times, minimum amount of players and default gamemode in `config.json`. -Current gamemodes available: Classic, Fast (Sanic), Wild, Text and 7-0. Check the details with the `/modes` command. - -Then run the bot with `python3 bot.py`. - -Code documentation is minimal but there. - -## Translating - -- Our translations are being done at our [Weblate](https://hosted.weblate.org/projects/unurobot/bot/) project. - You can contribute to the currently supported languages or translate to a new language. diff --git a/TRANSLATORS.md b/TRANSLATORS.md deleted file mode 100644 index 5cde736..0000000 --- a/TRANSLATORS.md +++ /dev/null @@ -1,20 +0,0 @@ -# Translators - -The following awesome people contributed to this project by translating it: - -| Locale | Translators | -|--------|-------------| -| ca_CA | [retiolus](https://github.com/retiolus) | -| de_DE | [Jannes Höke](https://github.com/jh0ker) | -| es_ES | [José.A Rojo](https://github.com/J4RV), [Ricardo Valverde Hernández](https://t.me/rivh1), Victor, Yuga | -| id_ID | [Erwin Guo](https://www.facebook.com/erwinfransiscus) | -| it_IT | Carola Mariano, ɳick | -| ml_IN | [Adhith T](https://github.com/adhitht123) | -| nb_NO | [Allan Nordhøy](https://github.com/comradekingu) | -| pt_BR | [Iuri Guilherme](https://github.com/iuriguilherme), [João Rodrigo Couto de Oliveira](http://twitter.com/JoaoRodrigoJR) | -| pt | [Silvério Santos](https://github.com/SantosSi) | -| zh_CN | [imlonghao](https://github.com/imlonghao), [XhyEax](https://github.com/XhyEax) | -| zh_HK | [Jed Cheng](https://www.facebook.com/profile.php?id=100002258388821) | -| zh_TW | [Eugene Lam](https://www.facebook.com/eugenelam1118), [jimchen5209](https://www.youtube.com/user/jimchen5209), [pan93412](https://www.github.com/pan93412) | - -Please add yourself here alphabetically when you submit your first translation. diff --git a/actions.py b/actions.py deleted file mode 100644 index e5518e4..0000000 --- a/actions.py +++ /dev/null @@ -1,277 +0,0 @@ -import contextlib -import logging - -from telegram.ext import ContextTypes - -import card as c -from config import MIN_FAST_TURN_TIME, TIME_REMOVAL_AFTER_SKIP -from errors import DeckEmptyError, NotEnoughPlayersError -from internationalization import __ -from shared_vars import gm -from user_setting import UserSetting -from utils import display_name, game_is_running, send_async - -logger = logging.getLogger(__name__) - - -class Countdown: - player = None - job_queue = None - - def __init__(self, player, job_queue) -> None: - self.player = player - self.job_queue = job_queue - - -# TODO do_skip() could get executed in another thread (it can be a job), so it looks like it can't use game.translate? -async def do_skip(context: ContextTypes.DEFAULT_TYPE, player): - game = player.game - skipped_player = game.current_player - next_player = game.current_player.next - job_queue = context.job_queue - - if skipped_player.waiting_time > 0: - skipped_player.anti_cheat += 1 - skipped_player.waiting_time -= TIME_REMOVAL_AFTER_SKIP - skipped_player.waiting_time = max(skipped_player.waiting_time, 0) - with contextlib.suppress(DeckEmptyError): - skipped_player.draw() - n = skipped_player.waiting_time - await send_async( - game, - text=__( - "Waiting time to skip this player has " - "been reduced to {time} seconds.\n" - "Next player: {name}", - multi=game.translate, - ).format(time=n, name=display_name(next_player.user)), - ) - logger.info("%s was skipped!", display_name(player.user)) - game.turn() - if job_queue: - start_player_countdown(context, game) - - else: - chat = game.chat - try: - gm.leave_game(skipped_player.user, chat) - await send_async( - game, - text=__( - "{name1} ran out of time " - "and has been removed from the game!\n" - "Next player: {name2}", - multi=game.translate, - ).format( - name1=display_name(skipped_player.user), - name2=display_name(next_player.user), - ), - ) - logger.info("%s was skipped!", display_name(player.user)) - if job_queue: - start_player_countdown(context, game) - - except NotEnoughPlayersError: - await send_async( - game, - text=__( - "{name} ran out of time " - "and has been removed from the game!\n" - "The game ended.", - multi=game.translate, - ).format(name=display_name(skipped_player.user)), - ) - - gm.end_game(chat, skipped_player.user) - - -def remove_cards(player, result_id): - card = c.from_str(result_id) - player.rm(card) - - -async def subport(context: ContextTypes.DEFAULT_TYPE, player, pi): - game = player.game - user = player.user - - us = UserSetting.get(id=user.id) or UserSetting(id=user.id) - - if us.stats: - us.cards_played += 1 - - await verifi(context, player) - await verifi(context, pi) - - game.turn() - - -async def verifi(context: ContextTypes.DEFAULT_TYPE, player): - game = player.game - chat = game.chat - user = player.user - - us = UserSetting.get(id=user.id) or UserSetting(id=user.id) - - if len(player.cards) == 1: - await send_async(game, text="UNO!") - - if len(player.cards) == 0: - await send_async( - game, - text=__("{name} won!", multi=game.translate).format(name=user.first_name), - ) - - if us.stats: - us.games_played += 1 - - if game.players_won == 0: - us.first_places += 1 - - game.players_won += 1 - - try: - gm.leave_game(user, chat) - except NotEnoughPlayersError: - await send_async(game, text=__("Game ended!", multi=game.translate)) - - us2 = UserSetting.get(id=game.current_player.user.id) - if us2 and us2.stats: - us2.games_played += 1 - - gm.end_game(chat, user) - - -async def do_play_card(context: ContextTypes.DEFAULT_TYPE, player, result_id): - """Plays the selected card and sends an update to the group if needed.""" - card = c.from_str(result_id) - player.play(card) - game = player.game - chat = game.chat - user = player.user - - us = UserSetting.get(id=user.id) or UserSetting(id=user.id) - - if us.stats: - us.cards_played += 1 - - if game.choosing_color: - await send_async(game, text=__("Please choose a color", multi=game.translate)) - - if len(player.cards) == 1: - await send_async(game, text="UNO!") - - if len(player.cards) == 0: - await send_async( - game, - text=__("{name} won!", multi=game.translate).format(name=user.first_name), - ) - - if us.stats: - us.games_played += 1 - - if game.players_won == 0: - us.first_places += 1 - - game.players_won += 1 - - try: - gm.leave_game(user, chat) - except NotEnoughPlayersError: - await send_async(game, text=__("Game ended!", multi=game.translate)) - - us2 = UserSetting.get(id=game.current_player.user.id) - if us2 and us2.stats: - us2.games_played += 1 - - gm.end_game(chat, user) - - -async def do_draw(context: ContextTypes.DEFAULT_TYPE, player): - """Does the drawing.""" - game = player.game - draw_counter_before = game.draw_counter - - try: - player.draw() - except DeckEmptyError: - await send_async( - game, - text=__("There are no more cards in the deck.", multi=game.translate), - ) - - if ( - game.last_card.value == c.DRAW_TWO or game.last_card.special == c.DRAW_FOUR - ) and draw_counter_before > 0: - game.turn() - - -async def do_call_bluff(context: ContextTypes.DEFAULT_TYPE, player): - """Handles the bluff calling.""" - game = player.game - - if player.prev.bluffing: - await send_async( - game, - text=__( - "Bluff called! Giving 4 cards to {name}", - multi=game.translate, - ).format(name=player.prev.user.first_name), - ) - - try: - player.prev.draw() - except DeckEmptyError: - await send_async( - game, - text=__("There are no more cards in the deck.", multi=game.translate), - ) - - else: - game.draw_counter += 2 - await send_async( - game, - text=__( - "{name1} didn't bluff! Giving 6 cards to {name2}", - multi=game.translate, - ).format(name1=player.prev.user.first_name, name2=player.user.first_name), - ) - try: - player.draw() - except DeckEmptyError: - await send_async( - game, - text=__("There are no more cards in the deck.", multi=game.translate), - ) - - game.turn() - - -def start_player_countdown(context: ContextTypes.DEFAULT_TYPE, game): - player = game.current_player - time = player.waiting_time - - time = max(time, MIN_FAST_TURN_TIME) - - if game.mode == "fast": - if game.job: - game.job.schedule_removal() - - job = context.job_queue.run_once( - skip_job, - time, - data=Countdown(player, context.job_queue), - ) - - logger.info( - "Started countdown for player: %s. %s seconds.", - display_name(player.user), - time, - ) - player.game.job = job - - -async def skip_job(context: ContextTypes.DEFAULT_TYPE): - player = context.job.data.player - game = player.game - if game_is_running(game): - await do_skip(context, player) diff --git a/bot.py b/bot.py old mode 100755 new mode 100644 index 6562f2c..3b1d8ee --- a/bot.py +++ b/bot.py @@ -1,976 +1,18 @@ -#!/usr/bin/env python3 -# -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +from config import bot +from hydrogram import idle +from tortoise import run_async +from version import ascii_art +from db import connect_database +import os -import logging -from datetime import datetime -from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update -from telegram.constants import ParseMode -from telegram.ext import ( - CallbackQueryHandler, - ChosenInlineResultHandler, - CommandHandler, - ContextTypes, - InlineQueryHandler, - MessageHandler, - filters, -) +async def main(): + os.system("clear") + print(ascii_art) + await connect_database() + await bot.start() + await idle() + await bot.stop() -import card as c -import settings -import simple_commands -from actions import ( - do_call_bluff, - do_draw, - do_play_card, - do_skip, - remove_cards, - start_player_countdown, - subport, -) -from config import DEFAULT_GAMEMODE, MIN_PLAYERS, WAITING_TIME -from errors import ( - AlreadyJoinedError, - DeckEmptyError, - LobbyClosedError, - NoGameInChatError, - NotEnoughPlayersError, -) -from internationalization import _, __, game_locales, user_locale -from results import ( - add_call_bluff, - add_card, - add_choose_color, - add_choose_player, - add_draw, - add_gameinfo, - add_mode_classic, - add_mode_fast, - add_mode_sete, - add_mode_text, - add_mode_wild, - add_no_game, - add_not_started, - add_other_cards, - add_pass, -) -from shared_vars import application, gm -from simple_commands import help_handler -from utils import ( - answer_async, - display_name, - error, - game_is_running, - send_async, - user_is_creator, - user_is_creator_or_admin, -) -logging.basicConfig( - format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", - level=logging.INFO, -) -logger = logging.getLogger(__name__) - - -@user_locale -async def notify_me(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for /notify_me command, pm people for next game.""" - chat = update.message.chat - - if update.message.chat.type == "private": - await send_async( - chat, - text=_( - "Send this command in a group to be notified " - "when a new game is started there.", - ), - message_thread_id=update.message.message_thread_id, - ) - else: - try: - gm.remind_dict[chat.id].add(update.message.from_user) - except KeyError: - gm.remind_dict[chat.id] = {update.message.from_user} - - await send_async( - chat, - text=_( - "Okay, you will be notified in a private message " - "when the next game is started in this chat. " - "Make sure that I'm allowed to send you messages.", - ), - message_thread_id=update.message.message_thread_id, - ) - - -@user_locale -async def new_game(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /new command.""" - if update.message.chat.type == "private": - await help_handler(update, context) - - else: - if update.message.chat_id in gm.remind_dict: - for user in gm.remind_dict[update.message.chat_id]: - await send_async( - user, - text=_("A new game has been started in {title}").format( - title=update.message.chat.title, - ), - ) - - del gm.remind_dict[update.message.chat_id] - - game = gm.new_game(update.message.chat, update.message.message_thread_id) - game.starter = update.message.from_user - game.owner.append(update.message.from_user.id) - game.mode = DEFAULT_GAMEMODE - await send_async( - game, - text=_( - "Created a new game! Join the game with /join " - "and start the game with /start", - ), - ) - - -@user_locale -async def kill_game(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /kill command.""" - chat = update.message.chat - user = update.message.from_user - games = gm.chatid_games.get(chat.id) - - if update.message.chat.type == "private": - await help_handler(update, context) - return - - if not games: - await send_async( - chat, - text=_("There is no running game in this chat."), - message_thread_id=update.message.message_thread_id, - ) - return - - game = games[-1] - - if await user_is_creator_or_admin(user, game, context, chat): - try: - gm.end_game(chat, user) - await send_async(game, text=__("Game ended!", multi=game.translate)) - - except NoGameInChatError: - await send_async( - game, - text=_( - "The game is not started yet. " - "Join the game with /join and start the game with /start", - ), - reply_to_message_id=update.message.message_id, - ) - - else: - await send_async( - game, - text=_("Only the game creator ({name}) and admin can do that.").format( - name=game.starter.first_name, - ), - reply_to_message_id=update.message.message_id, - ) - - -@user_locale -async def join_game(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /join command.""" - chat = update.message.chat - - if update.message.chat.type == "private": - await help_handler(update, context) - return - - try: - gm.join_game(update.message.from_user, chat) - - except LobbyClosedError: - await send_async( - chat, - text=_("The lobby is closed"), - message_thread_id=update.message.message_thread_id, - ) - - except NoGameInChatError: - await send_async( - chat, - text=_("No game is running at the moment. Create a new game with /new"), - message_thread_id=update.message.message_thread_id, - reply_to_message_id=update.message.message_id, - ) - - except AlreadyJoinedError: - await send_async( - chat, - text=_("You already joined the game. Start the game with /start"), - message_thread_id=update.message.message_thread_id, - reply_to_message_id=update.message.message_id, - ) - - except DeckEmptyError: - await send_async( - chat, - text=_( - "There are not enough cards left in the deck for " - "new players to join.", - ), - message_thread_id=update.message.message_thread_id, - reply_to_message_id=update.message.message_id, - ) - - else: - await send_async( - chat, - text=_("Joined the game"), - message_thread_id=update.message.message_thread_id, - reply_to_message_id=update.message.message_id, - ) - - -@user_locale -async def leave_game(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /leave command.""" - chat = update.message.chat - user = update.message.from_user - - player = gm.player_for_user_in_chat(user, chat) - - if player is None: - await send_async( - chat, - text=_("You are not playing in a game in this group."), - message_thread_id=update.message.message_thread_id, - reply_to_message_id=update.message.message_id, - ) - return - - game = player.game - user = update.message.from_user - - try: - gm.leave_game(user, chat) - - except NoGameInChatError: - await send_async( - game, - text=_("You are not playing in a game in this group."), - reply_to_message_id=update.message.message_id, - ) - - except NotEnoughPlayersError: - gm.end_game(chat, user) - await send_async(game, text=__("Game ended!", multi=game.translate)) - - else: - if game.started: - await send_async( - game, - text=__("Okay. Next Player: {name}", multi=game.translate).format( - name=display_name(game.current_player.user), - ), - reply_to_message_id=update.message.message_id, - ) - else: - await send_async( - game, - text=__( - "{name} left the game before it started.", - multi=game.translate, - ).format(name=display_name(user)), - reply_to_message_id=update.message.message_id, - ) - - -@user_locale -async def kick_player(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /kick command.""" - if update.message.chat.type == "private": - await help_handler(update, context) - return - - chat = update.message.chat - user = update.message.from_user - - try: - game = gm.chatid_games[chat.id][-1] - - except (KeyError, IndexError): - await send_async( - chat, - text=_("No game is running at the moment. Create a new game with /new"), - message_thread_id=update.message.message_thread_id, - reply_to_message_id=update.message.message_id, - ) - return - - if not game.started: - await send_async( - game, - text=_( - "The game is not started yet. " - "Join the game with /join and start the game with /start", - ), - reply_to_message_id=update.message.message_id, - ) - return - - if await user_is_creator_or_admin(user, game, context, chat): - if update.message.reply_to_message: - kicked = update.message.reply_to_message.from_user - - try: - gm.leave_game(kicked, chat) - - except NoGameInChatError: - await send_async( - game, - text=_( - "Player {name} is not found in the current game.".format( - name=display_name(kicked), - ), - ), - reply_to_message_id=update.message.message_id, - ) - return - - except NotEnoughPlayersError: - gm.end_game(chat, user) - await send_async( - game, - text=_( - f"{display_name(kicked)} was kicked by {display_name(user)}", - ), - ) - await send_async(game, text=__("Game ended!", multi=game.translate)) - return - - await send_async( - game, - text=_( - f"{display_name(kicked)} was kicked by {display_name(user)}", - ), - ) - - else: - await send_async( - game, - text=_( - "Please reply to the person you want to kick and type /kick again.", - ), - reply_to_message_id=update.message.message_id, - ) - return - - await send_async( - game, - text=__("Okay. Next Player: {name}", multi=game.translate).format( - name=display_name(game.current_player.user), - ), - reply_to_message_id=update.message.message_id, - ) - - else: - await send_async( - game, - text=_("Only the game creator ({name}) and admin can do that.").format( - name=game.starter.first_name, - ), - reply_to_message_id=update.message.message_id, - ) - - -async def select_game(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for callback queries to select the current game.""" - chat_id = int(update.callback_query.data) - user_id = update.callback_query.from_user.id - players = gm.userid_players[user_id] - for player in players: - if player.game.chat.id == chat_id: - gm.userid_current[user_id] = player - break - else: - await send_async( - update.callback_query.message.chat, - text=_("Game not found."), - message_thread_id=update.message.message_thread_id, - ) - return - - async def selected(bot): - back = [ - [ - InlineKeyboardButton( - text=_("Back to last group"), - switch_inline_query="", - ), - ], - ] - await context.bot.answerCallbackQuery( - update.callback_query.id, - text=_("Please switch to the group you selected!"), - show_alert=False, - ) - - await context.bot.editMessageText( - chat_id=update.callback_query.message.chat_id, - message_id=update.callback_query.message.message_id, - text=_( - "Selected group: {group}\n" - "Make sure that you switch to the correct " - "group!", - ).format(group=gm.userid_current[user_id].game.chat.title), - reply_markup=InlineKeyboardMarkup(back), - parse_mode=ParseMode.HTML, - ) - - await selected(context.bot) - - -@game_locales -async def status_update(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Remove player from game if user leaves the group.""" - chat = update.message.chat - - user = update.message.left_chat_member - - try: - gm.leave_game(user, chat) - game = gm.player_for_user_in_chat(user, chat).game - - except NoGameInChatError: - pass - except NotEnoughPlayersError: - gm.end_game(chat, user) - await send_async( - chat, - text=__("Game ended!", multi=game.translate), - message_thread_id=update.message.message_thread_id, - ) - else: - await send_async( - game, - text=__("Removing {name} from the game", multi=game.translate).format( - name=display_name(user), - ), - ) - - -@game_locales -@user_locale -async def start_game(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /start command.""" - args = context.args - - if update.message.chat.type != "private": - chat = update.message.chat - - try: - game = gm.chatid_games[chat.id][-1] - except (KeyError, IndexError): - await send_async( - chat, - text=_( - "There is no game running in this chat. Create " - "a new one with /new", - ), - ) - return - - if game.started: - await send_async(game, text=_("The game has already started")) - - elif len(game.players) < MIN_PLAYERS: - await send_async( - game, - text=__( - "At least {minplayers} players must /join the game " - "before you can start it", - ).format(minplayers=MIN_PLAYERS), - ) - - else: - # Starting a game - game.start() - - for player in game.players: - player.draw_first_hand() - choice = [ - [ - InlineKeyboardButton( - text=_("Make your choice!"), - switch_inline_query_current_chat="", - ), - ], - ] - first_message = __( - "First player: {name}\n" - "Use /close to stop people from joining the game.\n" - "Enable multi-translations with /enable_translations", - multi=game.translate, - ).format(name=display_name(game.current_player.user)) - - async def send_first(): - """Send the first card and player.""" - await context.bot.send_sticker( - chat.id, - sticker=c.STICKERS[str(game.last_card)], - message_thread_id=game.thread_id, - ) - - await send_async( - game, - text=first_message, - reply_markup=InlineKeyboardMarkup(choice), - ) - - await send_first() - start_player_countdown(context, game) - - elif len(args) and args[0] == "select": - players = gm.userid_players[update.message.from_user.id] - - groups = [] - for player in players: - title = player.game.chat.title - - if player is gm.userid_current[update.message.from_user.id]: - title = f"- {player.game.chat.title} -" - - groups.append( - [ - InlineKeyboardButton( - text=title, - callback_data=str(player.game.chat.id), - ), - ], - ) - - await send_async( - game, - text=_("Please select the group you want to play in."), - reply_markup=InlineKeyboardMarkup(groups), - ) - - else: - await help_handler(update, context) - - -@user_locale -async def close_game(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /close command.""" - chat = update.message.chat - user = update.message.from_user - games = gm.chatid_games.get(chat.id) - - if not games: - await send_async( - chat, - text=_("There is no running game in this chat."), - message_thread_id=update.message.message_thread_id, - ) - return - - game = games[-1] - - if user.id in game.owner: - game.open = False - await send_async( - game, - text=_("Closed the lobby. No more players can join this game."), - ) - else: - await send_async( - game, - text=_("Only the game creator ({name}) and admin can do that.").format( - name=game.starter.first_name, - ), - reply_to_message_id=update.message.message_id, - ) - - return - - -@user_locale -async def open_game(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /open command.""" - chat = update.message.chat - user = update.message.from_user - games = gm.chatid_games.get(chat.id) - - if not games: - await send_async( - chat, - text=_("There is no running game in this chat."), - message_thread_id=update.message.message_thread_id, - ) - return - - game = games[-1] - - if user.id in game.owner: - game.open = True - await send_async( - game, - text=_("Opened the lobby. New players may /join the game."), - ) - else: - await send_async( - game, - text=_("Only the game creator ({name}) and admin can do that.").format( - name=game.starter.first_name, - ), - reply_to_message_id=update.message.message_id, - ) - - return - - -@user_locale -async def enable_translations(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /enable_translations command.""" - chat = update.message.chat - user = update.message.from_user - games = gm.chatid_games.get(chat.id) - - if not games: - await send_async( - chat, - text=_("There is no running game in this chat."), - message_thread_id=update.message.message_thread_id, - ) - return - - game = games[-1] - - if user.id in game.owner: - game.translate = True - await send_async( - game, - text=_("Enabled multi-translations. Disable with /disable_translations"), - ) - else: - await send_async( - game, - text=_("Only the game creator ({name}) and admin can do that.").format( - name=game.starter.first_name, - ), - reply_to_message_id=update.message.message_id, - ) - - return - - -@user_locale -async def disable_translations(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /disable_translations command.""" - chat = update.message.chat - user = update.message.from_user - games = gm.chatid_games.get(chat.id) - - if not games: - await send_async( - chat, - text=_("There is no running game in this chat."), - message_thread_id=update.message.message_thread_id, - ) - return - - game = games[-1] - - if user.id in game.owner: - game.translate = False - await send_async( - game, - text=_( - "Disabled multi-translations. " - "Enable them again with " - "/enable_translations", - ), - ) - else: - await send_async( - game, - text=_("Only the game creator ({name}) and admin can do that.").format( - name=game.starter.first_name, - ), - reply_to_message_id=update.message.message_id, - ) - - return - - -@game_locales -@user_locale -async def skip_player(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /skip command.""" - chat = update.message.chat - user = update.message.from_user - - player = gm.player_for_user_in_chat(user, chat) - if not player: - await send_async( - chat, - text=_("You are not playing in a game in this chat."), - message_thread_id=update.message.message_thread_id, - ) - return - - game = player.game - skipped_player = game.current_player - - started = skipped_player.turn_started - now = datetime.now() - delta = (now - started).seconds - - # You can't skip if the current player still has time left - # You can skip yourself even if you have time left (you'll still draw) - if delta < skipped_player.waiting_time and player != skipped_player: - n = skipped_player.waiting_time - delta - await send_async( - game, - text=_("Please wait {time} second", "Please wait {time} seconds", n).format( - time=n, - ), - reply_to_message_id=update.message.message_id, - ) - else: - await do_skip(context, player) - - -@game_locales -@user_locale -async def reply_to_query(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for inline queries. - Builds the result list for inline queries and answers to the client. - """ - results = [] - switch = None - - try: - user = update.inline_query.from_user - user_id = user.id - players = gm.userid_players[user_id] - player = gm.userid_current[user_id] - game = player.game - except KeyError: - add_no_game(results) - else: - # The game has not started. - # The creator may change the game mode, other users just get a "game has not started" message. - if not game.started: - if user_is_creator(user, game): - add_mode_classic(results) - add_mode_fast(results) - add_mode_wild(results) - add_mode_text(results) - add_mode_sete(results) - else: - add_not_started(results) - - elif user_id == game.current_player.user.id: - if game.choosing_color: - add_choose_color(results, game) - add_other_cards(player, results, game) - elif game.choosing_player: - add_choose_player(player.user.id, results, game) - else: - if not player.drew: - add_draw(player, results) - - else: - add_pass(results, game) - - if game.last_card.special == c.DRAW_FOUR and game.draw_counter: - add_call_bluff(results, game) - - playable = player.playable_cards() - added_ids = [] # Duplicates are not allowed - - for card in sorted(player.cards): - add_card( - game, - card, - results, - can_play=(card in playable and str(card) not in added_ids), - ) - added_ids.append(str(card)) - - add_gameinfo(game, results) - - else: - for card in sorted(player.cards): - add_card(game, card, results, can_play=False) - - for result in results: - result._frozen = False - result.id += ":%d" % player.anti_cheat - result._frozen = True - - if players and game and len(players) > 1: - switch = _("Current game: {game}").format(game=game.chat.title) - - await answer_async( - context, - update.inline_query.id, - results, - cache_time=0, - switch_pm_text=switch, - switch_pm_parameter="select", - ) - - -@game_locales -@user_locale -async def process_result(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for chosen inline results. - Checks the players actions and acts accordingly. - """ - try: - user = update.chosen_inline_result.from_user - player = gm.userid_current[user.id] - game = player.game - result_id = update.chosen_inline_result.result_id - except (KeyError, AttributeError): - return - - logger.debug("Selected result: %s", result_id) - - result_id, anti_cheat = result_id.split(":") - last_anti_cheat = player.anti_cheat - player.anti_cheat += 1 - if result_id in ("hand", "gameinfo", "nogame"): - return - elif result_id.startswith("mode_"): - # First 5 characters are 'mode_', the rest is the gamemode. - mode = result_id[5:] - game.set_mode(mode) - logger.info("Gamemode changed to %s", mode) - await send_async(game, text=__(f"Gamemode changed to {mode}")) - return - elif len(result_id) == 36: # UUID result - return - elif int(anti_cheat) != last_anti_cheat: - await send_async( - game, - text=__("Cheat attempt by {name}", multi=game.translate).format( - name=display_name(player.user), - ), - ) - return - elif result_id == "call_bluff": - await reset_waiting_time(context, player) - await do_call_bluff(context, player) - elif "7" in result_id and game.mode == "7-0" and "player" not in result_id: - game.choosing_player = True - await send_async(game, text="Please choose a player to switch cards") - remove_cards(player, result_id) - elif "0" in result_id and game.mode == "7-0" and "player" not in result_id: - await reset_waiting_time(context, player) - await do_play_card(context, player, result_id) - b = {a: i.cards for a, i in enumerate(game.players)} - for a, i in enumerate(game.players, start=1): - i.cards = b.get(a, b[0]) - elif result_id == "draw": - await reset_waiting_time(context, player) - await do_draw(context, player) - elif result_id == "pass": - game.turn() - elif "player" in result_id: - n = result_id[7:] - for a, i in enumerate(game.players): - if a == int(n): - v = i.user.id - pi = gm.userid_current[v] - pq = pi.cards - pn = player.cards - pi.cards = pn - player.cards = pq - await subport(context, player, pi) - elif result_id in c.COLORS: - game.choose_color(result_id) - else: - await reset_waiting_time(context, player) - await do_play_card(context, player, result_id) - - if game_is_running(game): - nextplayer_message = __("Next player: {name}", multi=game.translate).format( - name=display_name(game.current_player.user), - ) - choice = [ - [ - InlineKeyboardButton( - text=_("Make your choice!"), - switch_inline_query_current_chat="", - ), - ], - ] - await send_async( - game, - text=nextplayer_message, - reply_markup=InlineKeyboardMarkup(choice), - ) - start_player_countdown(context, game) - - -async def reset_waiting_time(context, player): - """Resets waiting time for a player and sends a notice to the group.""" - if player.waiting_time < WAITING_TIME: - player.waiting_time = WAITING_TIME - await send_async( - player.game.thread_id, - text=__( - "Waiting time for {name} has been reset to {time} seconds", - multi=player.game.translate, - ).format(name=display_name(player.user), time=WAITING_TIME), - ) - - -# Add all handlers to the application and run the bot -application.add_handler(InlineQueryHandler(reply_to_query)) -application.add_handler(ChosenInlineResultHandler(process_result)) -application.add_handler(CallbackQueryHandler(select_game)) -application.add_handler(CommandHandler("start", start_game)) -application.add_handler(CommandHandler("new", new_game)) -application.add_handler(CommandHandler("kill", kill_game)) -application.add_handler(CommandHandler("join", join_game)) -application.add_handler(CommandHandler("leave", leave_game)) -application.add_handler(CommandHandler("kick", kick_player)) -application.add_handler(CommandHandler("open", open_game)) -application.add_handler(CommandHandler("close", close_game)) -application.add_handler(CommandHandler("enable_translations", enable_translations)) -application.add_handler(CommandHandler("disable_translations", disable_translations)) -application.add_handler(CommandHandler("skip", skip_player)) -application.add_handler(CommandHandler("notify_me", notify_me)) -simple_commands.register() -settings.register() -application.add_handler( - MessageHandler(filters.StatusUpdate.LEFT_CHAT_MEMBER, status_update), -) -application.add_error_handler(error) - -# start the bot -application.run_polling(drop_pending_updates=True) +run_async(main()) diff --git a/card.py b/card.py index 2f97fd8..407d48a 100644 --- a/card.py +++ b/card.py @@ -1,20 +1,6 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +import os +import json -# Colors RED = "r" BLUE = "b" GREEN = "g" @@ -55,7 +41,6 @@ REVERSE, SKIP, ) -WILD_VALUES = (ONE, TWO, THREE, FOUR, FIVE, DRAW_TWO, REVERSE, SKIP) # Special cards CHOOSE = "colorchooser" @@ -63,155 +48,9 @@ SPECIALS = (CHOOSE, DRAW_FOUR) -STICKERS = { - "b_0": "CAACAgQAAxkDAAI372NtY-V641fF6HhAA4Vuc6CbI_LeAALZAQACX1eZAAEqnpNt3SpG_ysE", - "b_1": "CAACAgQAAxkDAAI38GNtY-UvkNQN3h5p5n_dfNbhPV9HAALbAQACX1eZAAHluPl_BVzaDisE", - "b_2": "CAACAgQAAxkDAAI38WNtY-X4Gvnxt4mofZ-Uv_zmGWHRAALdAQACX1eZAAEFe5JBdpP-cysE", - "b_3": "CAACAgQAAxkDAAI38mNtY-av7Gm6hUEdRs_mONWGzKoGAALfAQACX1eZAAFQJXWHQ2D7uisE", - "b_4": "CAACAgQAAxkDAAI382NtY-YXxHbN1MfXSl6FbzwgWq5vAALhAQACX1eZAAHo1SP4devY_ysE", - "b_5": "CAACAgQAAxkDAAI39GNtY-dNEOn0i1luuPjPOHvqyasxAALjAQACX1eZAALf6g-FruzaKwQ", - "b_6": "CAACAgQAAxkDAAI39WNtY-df9ew41xXE6ARS3VHDKg0NAALlAQACX1eZAAHwMoU1Nb4OgisE", - "b_7": "CAACAgQAAxkDAAI39mNtY-ftENXWBUBNqNTomh-NeufNAALnAQACX1eZAAFOBAnoop1fWisE", - "b_8": "CAACAgQAAxkDAAI392NtY-idvjst_LSKlwP2cEDnS3WpAALpAQACX1eZAAHmKrizqjwJ3isE", - "b_9": "CAACAgQAAxkDAAI3-GNtY-jEw-hh0ei6OxSl2r4DehmIAALrAQACX1eZAAHvul-ZztVWiisE", - "b_draw": "CAACAgQAAxkDAAI3-WNtY-nrtJj_c48YtjbPwydARdwJAALtAQACX1eZAAGdURg9n6qvEysE", - "b_skip": "CAACAgQAAxkDAAI3-mNtY-kVI0dIVd38sOvZrZmtRCv_AALxAQACX1eZAAHAf0ks_Y82JysE", - "b_reverse": "CAACAgQAAxkDAAI3-2NtY-p4_EUUTVDYKX12SMcKA9IbAALvAQACX1eZAAFjAZc535XzNSsE", - "g_0": "CAACAgQAAxkDAAI3_GNtY-qvO3V8NwHojOpf8aIpbnYvAAL3AQACX1eZAAH7m-CsNWDzBSsE", - "g_1": "CAACAgQAAxkDAAI3_WNtY-r28bGOeJGKL7ZtEwUrWXzfAAL5AQACX1eZAAFVNSG--aqs9CsE", - "g_2": "CAACAgQAAxkDAAI3_mNtY-sjqfdB5nu7iKPFqHRItFerAAL7AQACX1eZAAHDX5Qn7VbSdCsE", - "g_3": "CAACAgQAAxkDAAI3_2NtY-ueCVLB_KL8Xz0itFJGWNbYAAL9AQACX1eZAAGwUxSSKSNPaisE", - "g_4": "CAACAgQAAxkDAAI4AAFjbWPsRRrrb0KdkF5SGCO87ni9sAAC_wEAAl9XmQABARICqk9L7OArBA", - "g_5": "CAACAgQAAxkDAAI4AWNtY-zlRyWdS69Z4bcwBgklRcBEAAIBAgACX1eZAAGN2wN5nVhf3ysE", - "g_6": "CAACAgQAAxkDAAI4AmNtY-zXK3F2NTz-XaFeDk2rsP7NAAIDAgACX1eZAAFaJA80kw1XfSsE", - "g_7": "CAACAgQAAxkDAAI4A2NtY-0dqOmBW9-XK_BbtXg0OLRaAAIFAgACX1eZAAGDbLTCiNGLBisE", - "g_8": "CAACAgQAAxkDAAI4BGNtY-2kF7oUCmvU_AbU9lmudtZqAAIHAgACX1eZAAGnWrRTRZj7gSsE", - "g_9": "CAACAgQAAxkDAAI4BWNtY-60BpqwiJQ8-p93unknqHi2AAIJAgACX1eZAAHODOPdhwzltysE", - "g_draw": "CAACAgQAAxkDAAI4BmNtY-53H6EJgbUQSeEpguubOevXAAILAgACX1eZAAFWg06uGplHVysE", - "g_skip": "CAACAgQAAxkDAAI4B2NtY-5VirooDDZAWu4ENrVBBoFHAAIPAgACX1eZAAHn-hBXxRvYQisE", - "g_reverse": "CAACAgQAAxkDAAI4CGNtY-_G8b0fBt0N3OBgx9CIwJziAAINAgACX1eZAAFMYqmCS3vfySsE", - "r_0": "CAACAgQAAxkDAAI4CWNtY-9LOKHb1FqCn3GmqxOYCo_fAAIRAgACX1eZAAHK9atgT_cu_isE", - "r_1": "CAACAgQAAxkDAAI4CmNtY_Dxb_ivl-VHFRDPgHVOilCVAAITAgACX1eZAAH_6pt2airFESsE", - "r_2": "CAACAgQAAxkDAAI4C2NtY_B9bP3cd73NvBd-Un8yZTYzAAIVAgACX1eZAAHQrmSSeMDfgCsE", - "r_3": "CAACAgQAAxkDAAI4DGNtY_Hqk5RPHjNn50jy_ImBPYZLAAIXAgACX1eZAAFeHWWPa-piRysE", - "r_4": "CAACAgQAAxkDAAI4DWNtY_HqY4wNkPulTWHIY9d2Fep-AAIZAgACX1eZAAE7VUWywkd3KCsE", - "r_5": "CAACAgQAAxkDAAI4DmNtY_Lb9j5Qi5RVPEaSW3uZWAnlAAIbAgACX1eZAAF1s0b9V-PUJCsE", - "r_6": "CAACAgQAAxkDAAI4D2NtY_Kklm1t7E0KShmWTbXEwnpNAAIdAgACX1eZAAF8hSz11exIUisE", - "r_7": "CAACAgQAAxkDAAI4EGNtY_LoR07j-LayjpoVlEPLCCe0AAIfAgACX1eZAAEVnCo1RKSqnCsE", - "r_8": "CAACAgQAAxkDAAI4EWNtY_OrIOu5PPIUTZ-cn0FBFcT2AAIhAgACX1eZAAEhXezQrbzKOisE", - "r_9": "CAACAgQAAxkDAAI4EmNtY_PI6uILsPHkkyIDFp4ivFBJAAIjAgACX1eZAAHN4GBkUaxpqisE", - "r_draw": "CAACAgQAAxkDAAI4E2NtY_SNrUaYiRbAIEi9c_X-veafAAIlAgACX1eZAAGZvG1zNp2cVisE", - "r_skip": "CAACAgQAAxkDAAI4FGNtY_SrNSCK9k9FO9Xji2fb9LJMAAIpAgACX1eZAAFprUDwYHBu3SsE", - "r_reverse": "CAACAgQAAxkDAAI4FWNtY_V41t8UX4XtxugfwVMibbqLAAInAgACX1eZAAGay7EvXnoVZisE", - "y_0": "CAACAgQAAxkDAAI4FmNtY_XYaAevT9wxGiAxI1n6e_spAAIrAgACX1eZAAG1mgAB2D5sIc8rBA", - "y_1": "CAACAgQAAxkDAAI4F2NtY_aD1zsrQYWtYoeePhDN1bcvAAItAgACX1eZAAHqNCCjuSEQjisE", - "y_2": "CAACAgQAAxkDAAI4GGNtY_Y9kN6nzxvk8KwX8SnwTntmAAIvAgACX1eZAAH4u547rBAiBCsE", - "y_3": "CAACAgQAAxkDAAI4GWNtY_dJwM67rmUFcLEtByedoFJdAAIxAgACX1eZAAFBQ00TMrpMeisE", - "y_4": "CAACAgQAAxkDAAI4GmNtY_d6JUufI61BWnqI4DTVRxMVAAIzAgACX1eZAAF7IOqIuGqyDSsE", - "y_5": "CAACAgQAAxkDAAI4G2NtY_dxij19aBCA7Tjf5ytWzXgNAAI1AgACX1eZAAHyIiYzI-E-LisE", - "y_6": "CAACAgQAAxkDAAI4HGNtY_hPQ2iuWWmADOUYR-P-nNVFAAI3AgACX1eZAAH_E8fuZ374hysE", - "y_7": "CAACAgQAAxkDAAI4HWNtY_jp9tXZ3lpAV83tzDcazcA4AAI5AgACX1eZAAHPK6qSI6Ku_CsE", - "y_8": "CAACAgQAAxkDAAI4HmNtY_kQwEGUW6F38bBIYXfspzarAAI7AgACX1eZAAHXiL4XwJi0eysE", - "y_9": "CAACAgQAAxkDAAI4H2NtY_kJ_ofl80XkaVobKpd-IgqQAAI9AgACX1eZAAGG_opl6vQSOCsE", - "y_draw": "CAACAgQAAxkDAAI4IGNtY_qbKj2mnuJVlTai4F6se8MNAAI_AgACX1eZAAFrjyuhcA2ksysE", - "y_skip": "CAACAgQAAxkDAAI4IWNtY_rKy-RTeKjfZT0RAYNNreVhAAJDAgACX1eZAAF1m63alvMoxysE", - "y_reverse": "CAACAgQAAxkDAAI4ImNtY_vaX0rQZ_5ZUeFTpMa2ZQABOwACQQIAAl9XmQABCHpDm7MPbakrBA", - "draw_four": "CAACAgQAAxkDAAI4I2NtY_vr1Fa4_Q2Y6dxOopNX7sSsAAL1AQACX1eZAAHXOgABZUCgVkkrBA", - "colorchooser": "CAACAgQAAxkDAAI4JGNtY_vpncCbuHH2xDLokQWxUAXSAALzAQACX1eZAAHI5jbpFQE9bCsE", - "option_draw": "CAACAgQAAxkDAAI4JWNtY_zry4NT2JAlWjTryYiuec4nAAL4AgACX1eZAAH-TdXSlvEa2ysE", - "option_pass": "CAACAgQAAxkDAAI4JmNtY_yMlr6rB3UdTikR3zFCk8kVAAL6AgACX1eZAAFuilR5QnD-VysE", - "option_bluff": "CAACAgQAAxkDAAI4J2NtY_2Dmt5Mi4iZhsUh32OeNVe7AALKAgACX1eZAAHBw478rNqN0CsE", - "option_info": "CAACAgQAAxkDAAI4KGNtY_3tO0Sxhu5NzF1UA3tdUnklAALEAgACX1eZAAGi2Qy93IIQwisE", -} - -STICKERS_GREY = { - "b_0": "CAACAgQAAxkDAAI4KWNtY_3SM2AGtecbGE8XDjlWvcKxAAJFAgACX1eZAAHwXYFNZhQaIysE", - "b_1": "CAACAgQAAxkDAAI4KmNtY_7zNsvijvvGZAJmuxcYVgizAAJHAgACX1eZAAF_ZxC64wgdNCsE", - "b_2": "CAACAgQAAxkDAAI4K2NtY_4z7XEHPzcliqJth5G3ds6vAAJJAgACX1eZAAF-GuNgJ25IAAErBA", - "b_3": "CAACAgQAAxkDAAI4LGNtY_9ZPE9nPCPJQ0Rjf_zOkTsiAAJLAgACX1eZAAHIJQ71XJ39mCsE", - "b_4": "CAACAgQAAxkDAAI4LWNtY_--OWOFczobsp10PPj5p9pZAAJNAgACX1eZAAEjmR2mhJ8SsSsE", - "b_5": "CAACAgQAAxkDAAI4LmNtZAABTkAAAT7kcgxZkdA3rcZmxM0AAk8CAAJfV5kAASN8DC8z_yexKwQ", - "b_6": "CAACAgQAAxkDAAI4L2NtZAABOSkvi7YF9opHBHILrQukJwACUQIAAl9XmQABv35eqFpp188rBA", - "b_7": "CAACAgQAAxkDAAI4MGNtZAABcb94kfODfzBiW7R6caIITgACUwIAAl9XmQABv8VaivrtncwrBA", - "b_8": "CAACAgQAAxkDAAI4MWNtZAEPZcxI8yZZJ7mtvLEhRyQyAAJVAgACX1eZAAF8hUb4bS_NdCsE", - "b_9": "CAACAgQAAxkDAAI4MmNtZAHG55HKa6LNKc496jAPrUCzAAJXAgACX1eZAAGXAmJ0BKvi1ysE", - "b_draw": "CAACAgQAAxkDAAI4M2NtZALeN87Xgly5X7j5XK0dfaznAAJZAgACX1eZAAFS-DsDXK7zdisE", - "b_skip": "CAACAgQAAxkDAAI4NGNtZAJR4ZxfKgABx3HNLp-9w8fNagACXQIAAl9XmQABc7AYk0bGSHorBA", - "b_reverse": "CAACAgQAAxkDAAI4NWNtZAKP0DU5ZIh-4eID9fwEqWDhAAJbAgACX1eZAAHRLf8w4EEJfysE", - "g_0": "CAACAgQAAxkDAAI4NmNtZAMTsoTxk-Gzg61XUbgiWmuDAAJjAgACX1eZAAG_c8FzjSBlOCsE", - "g_1": "CAACAgQAAxkDAAI4N2NtZAOMsFWlo1a6VbET_L4Z33qjAAJlAgACX1eZAAH2R3CHmHduZCsE", - "g_2": "CAACAgQAAxkDAAI4OGNtZASmomincPijzQaGuhzS4NT3AAJnAgACX1eZAAHB14u8vZ5pjSsE", - "g_3": "CAACAgQAAxkDAAI4OWNtZATXrH2F0kmklBKkx5-yLbqeAAJpAgACX1eZAAFaZGnJmMcN9CsE", - "g_4": "CAACAgQAAxkDAAI4OmNtZARrtuTkDtrmFwSWGCMNNyzVAAJrAgACX1eZAAF3KxLEqQq8KysE", - "g_5": "CAACAgQAAxkDAAI4O2NtZAXsq9mIqylmXkuqblUSZ_s5AAJtAgACX1eZAAGObwogvTEInCsE", - "g_6": "CAACAgQAAxkDAAI4PGNtZAXYyNLL6UnAXV2J5fcYDSjcAAJvAgACX1eZAAEpOGFMRnLGmSsE", - "g_7": "CAACAgQAAxkDAAI4PWNtZAYp5RXbOKe2_RQkDLNHRnQsAAJxAgACX1eZAAEe_yu4DVELEisE", - "g_8": "CAACAgQAAxkDAAI4PmNtZAZuRr1ubCO9SBPYf5uVwxOVAAJzAgACX1eZAAH26plyNxWZuCsE", - "g_9": "CAACAgQAAxkDAAI4P2NtZAZ-4ux439AfgakLYhj7NkL7AAJ1AgACX1eZAAGrwYoTMk8UPSsE", - "g_draw": "CAACAgQAAxkDAAI4QGNtZAcDJt3SZBIXhpzxAw-0pCjgAAJ3AgACX1eZAAFnlFIJWhbZIysE", - "g_skip": "CAACAgQAAxkDAAI4QWNtZAdu6EvL3cTpvKgvVvS5TM8oAAJ7AgACX1eZAAFO5CqgPxquYSsE", - "g_reverse": "CAACAgQAAxkDAAI4QmNtZAhYEij-J99P6WZprlvTrO1FAAJ5AgACX1eZAAE9cd3JVwlSEisE", - "r_0": "CAACAgQAAxkDAAI4Q2NtZAhJMx2vsEJ0VqZf4K4vnICEAAJ9AgACX1eZAAEZAg2nRervSCsE", - "r_1": "CAACAgQAAxkDAAI4RGNtZAggA5W5F360ygp-Kt5511ZGAAJ_AgACX1eZAAFtLPMD6heoDysE", - "r_2": "CAACAgQAAxkDAAI4RWNtZAneP8mxTRUYpxCIcSZxrRzaAAKBAgACX1eZAAGuvzFU0Su89SsE", - "r_3": "CAACAgQAAxkDAAI4RmNtZAkm-2Z3z4dgngqsNQKlAAEUIgACgwIAAl9XmQABBRY8MBWexokrBA", - "r_4": "CAACAgQAAxkDAAI4R2NtZAr32JAr0Q5mSzPrZuPKAAEMAAOFAgACX1eZAAHZFzRnwree-ysE", - "r_5": "CAACAgQAAxkDAAI4SGNtZAo06aPW8Bt2bEfhuAwYIAihAAKHAgACX1eZAAHsdpjtu9I2ISsE", - "r_6": "CAACAgQAAxkDAAI4SWNtZArDcMo4iVhDv3V2PkjmODGWAAKJAgACX1eZAAG2D__a-tqZBSsE", - "r_7": "CAACAgQAAxkDAAI4SmNtZAsNc-unKFxRAUfRgRpIu8zGAAKLAgACX1eZAAGXaAtw5YFztSsE", - "r_8": "CAACAgQAAxkDAAI4S2NtZAtXBBjw_QmbUnPCqOjcPciqAAKNAgACX1eZAAGkCOaURWQl8CsE", - "r_9": "CAACAgQAAxkDAAI4TGNtZAxdvNd9s7XbaETEDpraDSB8AAKPAgACX1eZAAH-WS6bmv9CgSsE", - "r_draw": "CAACAgQAAxkDAAI4TWNtZAz-9sSylYycGwF82_5ceXLOAAKRAgACX1eZAAF2dldgt636fysE", - "r_skip": "CAACAgQAAxkDAAI4TmNtZAwwZq3xqWgdKCELX9yXNNDHAAKVAgACX1eZAAGedr9LYgVebCsE", - "r_reverse": "CAACAgQAAxkDAAI4T2NtZA1_h1jpVObJt7ZnGWC0EJu_AAKTAgACX1eZAAECR8T0lu-KmysE", - "y_0": "CAACAgQAAxkDAAI4UGNtZA3XHBEqHJ4oD2s1vu019fCAAAKXAgACX1eZAALmpUbJzkaKKwQ", - "y_1": "CAACAgQAAxkDAAI4UWNtZA70oPDw_EYnua3I_yHnoU0HAAKZAgACX1eZAAGB_02-C22PkysE", - "y_2": "CAACAgQAAxkDAAI4UmNtZA73r_BBydbo0QL4Lrp6zzRgAAKbAgACX1eZAAHVmZUJxJwqmCsE", - "y_3": "CAACAgQAAxkDAAI4U2NtZA7ITY2cWf3hZhbqbRFA2rznAAKdAgACX1eZAAGnajv8YZQj-ysE", - "y_4": "CAACAgQAAxkDAAI4VGNtZA_w89jaIqKJT3mJ3jf4sNfqAAKfAgACX1eZAAEmxeENpAa35SsE", - "y_5": "CAACAgQAAxkDAAI4VWNtZA9pJt03yLW1UVqmabBu03CRAAKhAgACX1eZAAH2evQmPPzx8isE", - "y_6": "CAACAgQAAxkDAAI4VmNtZBBLaA_cEcY1-cmo4oRl7kFUAAKjAgACX1eZAAGYOfBpuoRg_CsE", - "y_7": "CAACAgQAAxkDAAI4V2NtZBC1E-0IzKlEqkiFlLtGQ2djAAKlAgACX1eZAAFYxwrVWROuiysE", - "y_8": "CAACAgQAAxkDAAI4WGNtZBDuCE40_AciHh4BlfOxvd4EAAKnAgACX1eZAAF10j1L6rASCSsE", - "y_9": "CAACAgQAAxkDAAI4WWNtZBERcGe9cafGmVQMrn--6VyEAAKpAgACX1eZAAGV1nEmuqjoJCsE", - "y_draw": "CAACAgQAAxkDAAI4WmNtZBHW7Ik5O4gDp80GEnME_8opAAKrAgACX1eZAAGfJ2XK_ooNFisE", - "y_skip": "CAACAgQAAxkDAAI4W2NtZBLpZ4ilI48Wl42H2--LNZleAAKvAgACX1eZAAEVSSkTcHxJXCsE", - "y_reverse": "CAACAgQAAxkDAAI4XGNtZBJeXdZLAWEB9hQVadvba2mLAAKtAgACX1eZAAEiP9aakPoiDysE", - "draw_four": "CAACAgQAAxkDAAI4XWNtZBOEsZAZxOHFAttWBmLf5WSOAAJhAgACX1eZAAHWx9PCWaCqkysE", - "colorchooser": "CAACAgQAAxkDAAI4XmNtZBPR9vYmNzz7P7Hq24wrLE16AAJfAgACX1eZAAH4WHYrSCRGIisE", -} - - -class Card: - """This class represents an UNO card.""" - - def __init__(self, color, value, special=None) -> None: - self.color = color - self.value = value - self.special = special - - def __str__(self) -> str: - return self.special or f"{self.color}_{self.value}" - - def __repr__(self) -> str: - if self.special: - return f'{COLOR_ICONS.get(self.color, "")}{COLOR_ICONS[BLACK]}{" ".join([s.capitalize() for s in self.special.split("_")])}' - - else: - return f"{COLOR_ICONS[self.color]}{self.value.capitalize()}" - - def __eq__(self, other): - """Needed for sorting the cards.""" - return str(self) == str(other) - - def __lt__(self, other): - """Needed for sorting the cards.""" - return str(self) < str(other) - - -def from_str(string): - """Decodes a Card object from a string.""" - if string in SPECIALS: - return Card(None, None, string) - color, value = string.split("_") - return Card(color, value) +cards = {} +for filename in os.listdir("cards"): + if filename.endswith(".json"): + name = filename.split(".")[0] + with open(f"cards/{filename}", "r") as f: + cards[name] = json.load(f) diff --git a/cards/classic.json b/cards/classic.json new file mode 100644 index 0000000..b01c2ac --- /dev/null +++ b/cards/classic.json @@ -0,0 +1,152 @@ +{ + "STICKERS": { + "b_0": "CAACAgQAAxkDAAI372NtY-V641fF6HhAA4Vuc6CbI_LeAALZAQACX1eZAAEqnpNt3SpG_ysE", + "b_1": "CAACAgQAAxkDAAI38GNtY-UvkNQN3h5p5n_dfNbhPV9HAALbAQACX1eZAAHluPl_BVzaDisE", + "b_2": "CAACAgQAAxkDAAI38WNtY-X4Gvnxt4mofZ-Uv_zmGWHRAALdAQACX1eZAAEFe5JBdpP-cysE", + "b_3": "CAACAgQAAxkDAAI38mNtY-av7Gm6hUEdRs_mONWGzKoGAALfAQACX1eZAAFQJXWHQ2D7uisE", + "b_4": "CAACAgQAAxkDAAI382NtY-YXxHbN1MfXSl6FbzwgWq5vAALhAQACX1eZAAHo1SP4devY_ysE", + "b_5": "CAACAgQAAxkDAAI39GNtY-dNEOn0i1luuPjPOHvqyasxAALjAQACX1eZAALf6g-FruzaKwQ", + "b_6": "CAACAgQAAxkDAAI39WNtY-df9ew41xXE6ARS3VHDKg0NAALlAQACX1eZAAHwMoU1Nb4OgisE", + "b_7": "CAACAgQAAxkDAAI39mNtY-ftENXWBUBNqNTomh-NeufNAALnAQACX1eZAAFOBAnoop1fWisE", + "b_8": "CAACAgQAAxkDAAI392NtY-idvjst_LSKlwP2cEDnS3WpAALpAQACX1eZAAHmKrizqjwJ3isE", + "b_9": "CAACAgQAAxkDAAI3-GNtY-jEw-hh0ei6OxSl2r4DehmIAALrAQACX1eZAAHvul-ZztVWiisE", + "b_draw": "CAACAgQAAxkDAAI3-WNtY-nrtJj_c48YtjbPwydARdwJAALtAQACX1eZAAGdURg9n6qvEysE", + "b_skip": "CAACAgQAAxkDAAI3-mNtY-kVI0dIVd38sOvZrZmtRCv_AALxAQACX1eZAAHAf0ks_Y82JysE", + "b_reverse": "CAACAgQAAxkDAAI3-2NtY-p4_EUUTVDYKX12SMcKA9IbAALvAQACX1eZAAFjAZc535XzNSsE", + "g_0": "CAACAgQAAxkDAAI3_GNtY-qvO3V8NwHojOpf8aIpbnYvAAL3AQACX1eZAAH7m-CsNWDzBSsE", + "g_1": "CAACAgQAAxkDAAI3_WNtY-r28bGOeJGKL7ZtEwUrWXzfAAL5AQACX1eZAAFVNSG--aqs9CsE", + "g_2": "CAACAgQAAxkDAAI3_mNtY-sjqfdB5nu7iKPFqHRItFerAAL7AQACX1eZAAHDX5Qn7VbSdCsE", + "g_3": "CAACAgQAAxkDAAI3_2NtY-ueCVLB_KL8Xz0itFJGWNbYAAL9AQACX1eZAAGwUxSSKSNPaisE", + "g_4": "CAACAgQAAxkDAAI4AAFjbWPsRRrrb0KdkF5SGCO87ni9sAAC_wEAAl9XmQABARICqk9L7OArBA", + "g_5": "CAACAgQAAxkDAAI4AWNtY-zlRyWdS69Z4bcwBgklRcBEAAIBAgACX1eZAAGN2wN5nVhf3ysE", + "g_6": "CAACAgQAAxkDAAI4AmNtY-zXK3F2NTz-XaFeDk2rsP7NAAIDAgACX1eZAAFaJA80kw1XfSsE", + "g_7": "CAACAgQAAxkDAAI4A2NtY-0dqOmBW9-XK_BbtXg0OLRaAAIFAgACX1eZAAGDbLTCiNGLBisE", + "g_8": "CAACAgQAAxkDAAI4BGNtY-2kF7oUCmvU_AbU9lmudtZqAAIHAgACX1eZAAGnWrRTRZj7gSsE", + "g_9": "CAACAgQAAxkDAAI4BWNtY-60BpqwiJQ8-p93unknqHi2AAIJAgACX1eZAAHODOPdhwzltysE", + "g_draw": "CAACAgQAAxkDAAI4BmNtY-53H6EJgbUQSeEpguubOevXAAILAgACX1eZAAFWg06uGplHVysE", + "g_skip": "CAACAgQAAxkDAAI4B2NtY-5VirooDDZAWu4ENrVBBoFHAAIPAgACX1eZAAHn-hBXxRvYQisE", + "g_reverse": "CAACAgQAAxkDAAI4CGNtY-_G8b0fBt0N3OBgx9CIwJziAAINAgACX1eZAAFMYqmCS3vfySsE", + "r_0": "CAACAgQAAxkDAAI4CWNtY-9LOKHb1FqCn3GmqxOYCo_fAAIRAgACX1eZAAHK9atgT_cu_isE", + "r_1": "CAACAgQAAxkDAAI4CmNtY_Dxb_ivl-VHFRDPgHVOilCVAAITAgACX1eZAAH_6pt2airFESsE", + "r_2": "CAACAgQAAxkDAAI4C2NtY_B9bP3cd73NvBd-Un8yZTYzAAIVAgACX1eZAAHQrmSSeMDfgCsE", + "r_3": "CAACAgQAAxkDAAI4DGNtY_Hqk5RPHjNn50jy_ImBPYZLAAIXAgACX1eZAAFeHWWPa-piRysE", + "r_4": "CAACAgQAAxkDAAI4DWNtY_HqY4wNkPulTWHIY9d2Fep-AAIZAgACX1eZAAE7VUWywkd3KCsE", + "r_5": "CAACAgQAAxkDAAI4DmNtY_Lb9j5Qi5RVPEaSW3uZWAnlAAIbAgACX1eZAAF1s0b9V-PUJCsE", + "r_6": "CAACAgQAAxkDAAI4D2NtY_Kklm1t7E0KShmWTbXEwnpNAAIdAgACX1eZAAF8hSz11exIUisE", + "r_7": "CAACAgQAAxkDAAI4EGNtY_LoR07j-LayjpoVlEPLCCe0AAIfAgACX1eZAAEVnCo1RKSqnCsE", + "r_8": "CAACAgQAAxkDAAI4EWNtY_OrIOu5PPIUTZ-cn0FBFcT2AAIhAgACX1eZAAEhXezQrbzKOisE", + "r_9": "CAACAgQAAxkDAAI4EmNtY_PI6uILsPHkkyIDFp4ivFBJAAIjAgACX1eZAAHN4GBkUaxpqisE", + "r_draw": "CAACAgQAAxkDAAI4E2NtY_SNrUaYiRbAIEi9c_X-veafAAIlAgACX1eZAAGZvG1zNp2cVisE", + "r_skip": "CAACAgQAAxkDAAI4FGNtY_SrNSCK9k9FO9Xji2fb9LJMAAIpAgACX1eZAAFprUDwYHBu3SsE", + "r_reverse": "CAACAgQAAxkDAAI4FWNtY_V41t8UX4XtxugfwVMibbqLAAInAgACX1eZAAGay7EvXnoVZisE", + "y_0": "CAACAgQAAxkDAAI4FmNtY_XYaAevT9wxGiAxI1n6e_spAAIrAgACX1eZAAG1mgAB2D5sIc8rBA", + "y_1": "CAACAgQAAxkDAAI4F2NtY_aD1zsrQYWtYoeePhDN1bcvAAItAgACX1eZAAHqNCCjuSEQjisE", + "y_2": "CAACAgQAAxkDAAI4GGNtY_Y9kN6nzxvk8KwX8SnwTntmAAIvAgACX1eZAAH4u547rBAiBCsE", + "y_3": "CAACAgQAAxkDAAI4GWNtY_dJwM67rmUFcLEtByedoFJdAAIxAgACX1eZAAFBQ00TMrpMeisE", + "y_4": "CAACAgQAAxkDAAI4GmNtY_d6JUufI61BWnqI4DTVRxMVAAIzAgACX1eZAAF7IOqIuGqyDSsE", + "y_5": "CAACAgQAAxkDAAI4G2NtY_dxij19aBCA7Tjf5ytWzXgNAAI1AgACX1eZAAHyIiYzI-E-LisE", + "y_6": "CAACAgQAAxkDAAI4HGNtY_hPQ2iuWWmADOUYR-P-nNVFAAI3AgACX1eZAAH_E8fuZ374hysE", + "y_7": "CAACAgQAAxkDAAI4HWNtY_jp9tXZ3lpAV83tzDcazcA4AAI5AgACX1eZAAHPK6qSI6Ku_CsE", + "y_8": "CAACAgQAAxkDAAI4HmNtY_kQwEGUW6F38bBIYXfspzarAAI7AgACX1eZAAHXiL4XwJi0eysE", + "y_9": "CAACAgQAAxkDAAI4H2NtY_kJ_ofl80XkaVobKpd-IgqQAAI9AgACX1eZAAGG_opl6vQSOCsE", + "y_draw": "CAACAgQAAxkDAAI4IGNtY_qbKj2mnuJVlTai4F6se8MNAAI_AgACX1eZAAFrjyuhcA2ksysE", + "y_skip": "CAACAgQAAxkDAAI4IWNtY_rKy-RTeKjfZT0RAYNNreVhAAJDAgACX1eZAAF1m63alvMoxysE", + "y_reverse": "CAACAgQAAxkDAAI4ImNtY_vaX0rQZ_5ZUeFTpMa2ZQABOwACQQIAAl9XmQABCHpDm7MPbakrBA", + "draw_four": "CAACAgQAAxkDAAI4I2NtY_vr1Fa4_Q2Y6dxOopNX7sSsAAL1AQACX1eZAAHXOgABZUCgVkkrBA", + "colorchooser": "CAACAgQAAxkDAAI4JGNtY_vpncCbuHH2xDLokQWxUAXSAALzAQACX1eZAAHI5jbpFQE9bCsE", + "option_draw": "CAACAgQAAxkDAAI4JWNtY_zry4NT2JAlWjTryYiuec4nAAL4AgACX1eZAAH-TdXSlvEa2ysE", + "option_pass": "CAACAgQAAxkDAAI4JmNtY_yMlr6rB3UdTikR3zFCk8kVAAL6AgACX1eZAAFuilR5QnD-VysE", + "option_bluff": "CAACAgQAAxkDAAI4J2NtY_2Dmt5Mi4iZhsUh32OeNVe7AALKAgACX1eZAAHBw478rNqN0CsE", + "option_info": "CAACAgQAAxkDAAI4KGNtY_3tO0Sxhu5NzF1UA3tdUnklAALEAgACX1eZAAGi2Qy93IIQwisE" + }, + "STICKERS_GREY": { + "b_0": "CAACAgQAAxkDAAI4KWNtY_3SM2AGtecbGE8XDjlWvcKxAAJFAgACX1eZAAHwXYFNZhQaIysE", + "b_1": "CAACAgQAAxkDAAI4KmNtY_7zNsvijvvGZAJmuxcYVgizAAJHAgACX1eZAAF_ZxC64wgdNCsE", + "b_2": "CAACAgQAAxkDAAI4K2NtY_4z7XEHPzcliqJth5G3ds6vAAJJAgACX1eZAAF-GuNgJ25IAAErBA", + "b_3": "CAACAgQAAxkDAAI4LGNtY_9ZPE9nPCPJQ0Rjf_zOkTsiAAJLAgACX1eZAAHIJQ71XJ39mCsE", + "b_4": "CAACAgQAAxkDAAI4LWNtY_--OWOFczobsp10PPj5p9pZAAJNAgACX1eZAAEjmR2mhJ8SsSsE", + "b_5": "CAACAgQAAxkDAAI4LmNtZAABTkAAAT7kcgxZkdA3rcZmxM0AAk8CAAJfV5kAASN8DC8z_yexKwQ", + "b_6": "CAACAgQAAxkDAAI4L2NtZAABOSkvi7YF9opHBHILrQukJwACUQIAAl9XmQABv35eqFpp188rBA", + "b_7": "CAACAgQAAxkDAAI4MGNtZAABcb94kfODfzBiW7R6caIITgACUwIAAl9XmQABv8VaivrtncwrBA", + "b_8": "CAACAgQAAxkDAAI4MWNtZAEPZcxI8yZZJ7mtvLEhRyQyAAJVAgACX1eZAAF8hUb4bS_NdCsE", + "b_9": "CAACAgQAAxkDAAI4MmNtZAHG55HKa6LNKc496jAPrUCzAAJXAgACX1eZAAGXAmJ0BKvi1ysE", + "b_draw": "CAACAgQAAxkDAAI4M2NtZALeN87Xgly5X7j5XK0dfaznAAJZAgACX1eZAAFS-DsDXK7zdisE", + "b_skip": "CAACAgQAAxkDAAI4NGNtZAJR4ZxfKgABx3HNLp-9w8fNagACXQIAAl9XmQABc7AYk0bGSHorBA", + "b_reverse": "CAACAgQAAxkDAAI4NWNtZAKP0DU5ZIh-4eID9fwEqWDhAAJbAgACX1eZAAHRLf8w4EEJfysE", + "g_0": "CAACAgQAAxkDAAI4NmNtZAMTsoTxk-Gzg61XUbgiWmuDAAJjAgACX1eZAAG_c8FzjSBlOCsE", + "g_1": "CAACAgQAAxkDAAI4N2NtZAOMsFWlo1a6VbET_L4Z33qjAAJlAgACX1eZAAH2R3CHmHduZCsE", + "g_2": "CAACAgQAAxkDAAI4OGNtZASmomincPijzQaGuhzS4NT3AAJnAgACX1eZAAHB14u8vZ5pjSsE", + "g_3": "CAACAgQAAxkDAAI4OWNtZATXrH2F0kmklBKkx5-yLbqeAAJpAgACX1eZAAFaZGnJmMcN9CsE", + "g_4": "CAACAgQAAxkDAAI4OmNtZARrtuTkDtrmFwSWGCMNNyzVAAJrAgACX1eZAAF3KxLEqQq8KysE", + "g_5": "CAACAgQAAxkDAAI4O2NtZAXsq9mIqylmXkuqblUSZ_s5AAJtAgACX1eZAAGObwogvTEInCsE", + "g_6": "CAACAgQAAxkDAAI4PGNtZAXYyNLL6UnAXV2J5fcYDSjcAAJvAgACX1eZAAEpOGFMRnLGmSsE", + "g_7": "CAACAgQAAxkDAAI4PWNtZAYp5RXbOKe2_RQkDLNHRnQsAAJxAgACX1eZAAEe_yu4DVELEisE", + "g_8": "CAACAgQAAxkDAAI4PmNtZAZuRr1ubCO9SBPYf5uVwxOVAAJzAgACX1eZAAH26plyNxWZuCsE", + "g_9": "CAACAgQAAxkDAAI4P2NtZAZ-4ux439AfgakLYhj7NkL7AAJ1AgACX1eZAAGrwYoTMk8UPSsE", + "g_draw": "CAACAgQAAxkDAAI4QGNtZAcDJt3SZBIXhpzxAw-0pCjgAAJ3AgACX1eZAAFnlFIJWhbZIysE", + "g_skip": "CAACAgQAAxkDAAI4QWNtZAdu6EvL3cTpvKgvVvS5TM8oAAJ7AgACX1eZAAFO5CqgPxquYSsE", + "g_reverse": "CAACAgQAAxkDAAI4QmNtZAhYEij-J99P6WZprlvTrO1FAAJ5AgACX1eZAAE9cd3JVwlSEisE", + "r_0": "CAACAgQAAxkDAAI4Q2NtZAhJMx2vsEJ0VqZf4K4vnICEAAJ9AgACX1eZAAEZAg2nRervSCsE", + "r_1": "CAACAgQAAxkDAAI4RGNtZAggA5W5F360ygp-Kt5511ZGAAJ_AgACX1eZAAFtLPMD6heoDysE", + "r_2": "CAACAgQAAxkDAAI4RWNtZAneP8mxTRUYpxCIcSZxrRzaAAKBAgACX1eZAAGuvzFU0Su89SsE", + "r_3": "CAACAgQAAxkDAAI4RmNtZAkm-2Z3z4dgngqsNQKlAAEUIgACgwIAAl9XmQABBRY8MBWexokrBA", + "r_4": "CAACAgQAAxkDAAI4R2NtZAr32JAr0Q5mSzPrZuPKAAEMAAOFAgACX1eZAAHZFzRnwree-ysE", + "r_5": "CAACAgQAAxkDAAI4SGNtZAo06aPW8Bt2bEfhuAwYIAihAAKHAgACX1eZAAHsdpjtu9I2ISsE", + "r_6": "CAACAgQAAxkDAAI4SWNtZArDcMo4iVhDv3V2PkjmODGWAAKJAgACX1eZAAG2D__a-tqZBSsE", + "r_7": "CAACAgQAAxkDAAI4SmNtZAsNc-unKFxRAUfRgRpIu8zGAAKLAgACX1eZAAGXaAtw5YFztSsE", + "r_8": "CAACAgQAAxkDAAI4S2NtZAtXBBjw_QmbUnPCqOjcPciqAAKNAgACX1eZAAGkCOaURWQl8CsE", + "r_9": "CAACAgQAAxkDAAI4TGNtZAxdvNd9s7XbaETEDpraDSB8AAKPAgACX1eZAAH-WS6bmv9CgSsE", + "r_draw": "CAACAgQAAxkDAAI4TWNtZAz-9sSylYycGwF82_5ceXLOAAKRAgACX1eZAAF2dldgt636fysE", + "r_skip": "CAACAgQAAxkDAAI4TmNtZAwwZq3xqWgdKCELX9yXNNDHAAKVAgACX1eZAAGedr9LYgVebCsE", + "r_reverse": "CAACAgQAAxkDAAI4T2NtZA1_h1jpVObJt7ZnGWC0EJu_AAKTAgACX1eZAAECR8T0lu-KmysE", + "y_0": "CAACAgQAAxkDAAI4UGNtZA3XHBEqHJ4oD2s1vu019fCAAAKXAgACX1eZAALmpUbJzkaKKwQ", + "y_1": "CAACAgQAAxkDAAI4UWNtZA70oPDw_EYnua3I_yHnoU0HAAKZAgACX1eZAAGB_02-C22PkysE", + "y_2": "CAACAgQAAxkDAAI4UmNtZA73r_BBydbo0QL4Lrp6zzRgAAKbAgACX1eZAAHVmZUJxJwqmCsE", + "y_3": "CAACAgQAAxkDAAI4U2NtZA7ITY2cWf3hZhbqbRFA2rznAAKdAgACX1eZAAGnajv8YZQj-ysE", + "y_4": "CAACAgQAAxkDAAI4VGNtZA_w89jaIqKJT3mJ3jf4sNfqAAKfAgACX1eZAAEmxeENpAa35SsE", + "y_5": "CAACAgQAAxkDAAI4VWNtZA9pJt03yLW1UVqmabBu03CRAAKhAgACX1eZAAH2evQmPPzx8isE", + "y_6": "CAACAgQAAxkDAAI4VmNtZBBLaA_cEcY1-cmo4oRl7kFUAAKjAgACX1eZAAGYOfBpuoRg_CsE", + "y_7": "CAACAgQAAxkDAAI4V2NtZBC1E-0IzKlEqkiFlLtGQ2djAAKlAgACX1eZAAFYxwrVWROuiysE", + "y_8": "CAACAgQAAxkDAAI4WGNtZBDuCE40_AciHh4BlfOxvd4EAAKnAgACX1eZAAF10j1L6rASCSsE", + "y_9": "CAACAgQAAxkDAAI4WWNtZBERcGe9cafGmVQMrn--6VyEAAKpAgACX1eZAAGV1nEmuqjoJCsE", + "y_draw": "CAACAgQAAxkDAAI4WmNtZBHW7Ik5O4gDp80GEnME_8opAAKrAgACX1eZAAGfJ2XK_ooNFisE", + "y_skip": "CAACAgQAAxkDAAI4W2NtZBLpZ4ilI48Wl42H2--LNZleAAKvAgACX1eZAAEVSSkTcHxJXCsE", + "y_reverse": "CAACAgQAAxkDAAI4XGNtZBJeXdZLAWEB9hQVadvba2mLAAKtAgACX1eZAAEiP9aakPoiDysE", + "draw_four": "CAACAgQAAxkDAAI4XWNtZBOEsZAZxOHFAttWBmLf5WSOAAJhAgACX1eZAAHWx9PCWaCqkysE", + "colorchooser": "CAACAgQAAxkDAAI4XmNtZBPR9vYmNzz7P7Hq24wrLE16AAJfAgACX1eZAAH4WHYrSCRGIisE" + }, + "CARDS": { + "SPECIALS": ["draw_four","colorchooser"], + "SPECIALS_INFO": { + "draw_four": [4,"."], + "colorchooser": [4,"^(?!.*draw).*$"] + }, + "THEME_CARDS": [], + "COLORS": ["b","g","r","y"], + "COLOR_ICONS": { + "b": "🟦", + "g": "🟩", + "r": "🟥", + "y": "🟨", + "x": "❓" + }, + "VALUES": ["0","1","2","3","4","5","6","7","8","9","draw","skip","reverse"], + "VALUES_ICONS": { + "0": "0️⃣", + "1": "1️⃣", + "2": "2️⃣", + "3": "3️⃣", + "4": "4️⃣", + "5": "5️⃣", + "6": "6️⃣", + "7": "7️⃣", + "8": "8️⃣", + "9": "9️⃣", + "draw": "+2", + "skip": "🚫", + "reverse": "🔁", + "colorchooser": "🌈", + "draw_four": "+4" + } + } +} \ No newline at end of file diff --git a/cards/colorblind.json b/cards/colorblind.json new file mode 100644 index 0000000..7326074 --- /dev/null +++ b/cards/colorblind.json @@ -0,0 +1,179 @@ +{ + "STICKERS": { + "b_0": "CAACAgQAAxkBAAIH7WWViIfZuQW92q6yTE6BQfXj-UWDAAL4EAACSPyQUbrUYl3Db1A4HgQ", + "b_1": "CAACAgQAAxkBAAIH8GWViIgsVZgNZsZYg_RaskmJCKJZAAJxEwAC74SYUVPWLgtyo7g5HgQ", + "b_2": "CAACAgQAAxkBAAIH82WViIklUQmKnrock1_yNBqqMhVJAALTFAACpWGZUfKsVIBvG1-PHgQ", + "b_3": "CAACAgQAAxkBAAIH9mWViIrIYOGeBv0MxhC6FWldvYQyAAI2DQACf7GYUd6_wh0X-J7THgQ", + "b_4": "CAACAgQAAxkBAAIH-WWViIvJL4MFx0Q10L4Y7J6tTgzOAAKVDgACNlqZUVwgv-lUHlwXHgQ", + "b_5": "CAACAgQAAxkBAAIH_GWViIuh16wb9Nb28sRG5uSV6ab5AAKuDAAC4vmZUe8QFnwIbmnlHgQ", + "b_6": "CAACAgQAAxkBAAIH_2WViIzaZQQttfD0R03vcmRiKyQWAAIOFQAC4ZGZUZBi-YQ7FzMEHgQ", + "b_7": "CAACAgQAAxkBAAIIAmWViI0Ur0TXzVyntbIFiUF70ngzAAIjEQAC_92YUS5W3f2SSBmDHgQ", + "b_8": "CAACAgQAAxkBAAIIBWWViI5BriPVz45ADl9kKBP73JTkAALbDQACgTqRUcbtaxxXgXaHHgQ", + "b_9": "CAACAgQAAxkBAAIICGWViI8P2ffbeW1mFnEG4sjeJ58MAAK9DQACtEyZUStZpJE_-CIpHgQ", + "b_draw": "CAACAgQAAxkBAAIIC2WViJGgz0IpM8FbgtwmtZVLeuj6AAKXDgACMX-QUc9ZKhgoHC3BHgQ", + "b_skip": "CAACAgQAAxkBAAIIDmWViJIq_Ib0JQ7UQ5clASSpFNuyAAL5DAACBtmYUaW1SWeyUM1RHgQ", + "b_reverse": "CAACAgQAAxkBAAIIEWWViJOq0hbTlIjYSLZw-7ct8OquAAKiDwACoMmZUQlCnlahydSdHgQ", + "g_0": "CAACAgQAAxkBAAIIFGWViJbNqv-dn_a5j2LuBSFhGKOPAAJODgAChDGYUXTuNH-98HjGHgQ", + "g_1": "CAACAgQAAxkBAAIIF2WViJd4nHU1y1ztouceDT1cfDHuAAJCDgACGSCYUaWyJ_2c21fCHgQ", + "g_2": "CAACAgQAAxkBAAIIGmWViJipH6ctdppuXX21KV-hUEl2AALYFQAC57-YUYQ2I9KNnFuJHgQ", + "g_3": "CAACAgQAAxkBAAIIHWWViJm1DwWP9SJoSSP-YCAvhaGjAAKnDgACM72YUcA7PwoPafsHHgQ", + "g_4": "CAACAgQAAxkBAAIIIGWViJrgai_4_1GWuNTq1SrwHoY6AAJGEAACoXuQURzAtqUt8N9oHgQ", + "g_5": "CAACAgQAAxkBAAIII2WViJuQB3lW1m169IogS1bu-dd2AAICDwACpcuYUcnKDYX_Jtu_HgQ", + "g_6": "CAACAgQAAxkBAAIIJmWViJ02ZaybQAg82BqZBXYSRQ_xAAJWFgAC0ruZUaKBGr8SQK5WHgQ", + "g_7": "CAACAgQAAxkBAAIIKWWViJ55lDw6091FOyalYKntdBRkAALZEgACtxyYUSP7wshU0BuyHgQ", + "g_8": "CAACAgQAAxkBAAIILGWViKIstE4URA2mdsL1qn6GVf-cAALoDAAC6-aYUcFFqsyKY5ZrHgQ", + "g_9": "CAACAgQAAxkBAAIIL2WViKVGxSTn0Do5onLQ3Ofzka4LAAITEQACw2SZUWvwNocY7CyCHgQ", + "g_draw": "CAACAgQAAxkBAAIIMmWViKdf2wdcUNpvrsc_u8cyzSpnAAKEDwACvFiZUf1yHkmnTQABuh4E", + "g_skip": "CAACAgQAAxkBAAIINWWViKiQLKGbJaNtyCoxw_Qyc0lDAAJsFwACqKeRUQ7CQm0NF-TaHgQ", + "g_reverse": "CAACAgQAAxkBAAIIOGWViKlE1G7Dq9BINwhi5e17RV_dAAIyEAAC9U6YUYfbzgshjtx6HgQ", + "r_0": "CAACAgQAAxkBAAIIO2WViKrN7GshtcQ44nYDgpXlvqQ9AALoDwACf9yRUc9YeqIFH_eMHgQ", + "r_1": "CAACAgQAAxkBAAIIPmWViKsB7yhwRpa-SkjkqIfqiDFeAALlDQACD4iZUTH5uVAjzxGtHgQ", + "r_2": "CAACAgQAAxkBAAIIQWWViKx4deWPc3S0fDskZsyKZ5D1AALWDQAC4yOZUSRCxWE3j0MwHgQ", + "r_3": "CAACAgQAAxkBAAIIRGWViK6lgng5gfXIYThsk1g76KS0AAKWEAACrLiZUdai-hpZ9Ab-HgQ", + "r_4": "CAACAgQAAxkBAAIIR2WViK_83kuSnMJ8nFSoi6VDxkAFAAIJGgACp_-RUWeXwAIvWuOnHgQ", + "r_5": "CAACAgQAAxkBAAIISmWViLIafepcDzkS08BMqkq7rZE3AAJXDwACOZqZUQS_ZNV4v1ylHgQ", + "r_6": "CAACAgQAAxkBAAIITWWViLWZySDZcTEnc66aLKx9URsxAAIdDgAC65SRUfYj7KfqdEFUHgQ", + "r_7": "CAACAgQAAxkBAAIIUGWViLZK1GPE83RP8VZ1G134HkzHAAI1DwACs_WRUXmuoe2TSlD4HgQ", + "r_8": "CAACAgQAAxkBAAIIU2WViLjJbF2IM6EfGh7Fi7Eylv_hAALUEAAC5AORUQ-Iih1SLpa_HgQ", + "r_9": "CAACAgQAAxkBAAIIVmWViLlb9lZw4rLF8zE92W492Y2WAALZDgACrWeQUczrPkLQp9_ZHgQ", + "r_draw": "CAACAgQAAxkBAAIIWWWViLqtM1UOYophQ9hlsIO-6CR2AAK9DwACpm6QUYSaRFKhJlATHgQ", + "r_skip": "CAACAgQAAxkBAAIIXGWViLw3gedDiTOUIuNBrUdTOaWNAAJGDgACnxuZUU4LrF0RllHDHgQ", + "r_reverse": "CAACAgQAAxkBAAIIX2WViL3N06HgWmOmAWwRTuf19J92AALlEAACDz2ZUTz4Rj_YOJ9wHgQ", + "y_0": "CAACAgQAAxkBAAIIYmWViL9dzEK2pkuaVGZDpGLHIh3aAAKtDgACvlaZUc1_r14GfZg4HgQ", + "y_1": "CAACAgQAAxkBAAIIZWWViMDADxyaFhJtHoj2OqLeJuXmAAJyDwACaoqZUd9V5Qje7-LsHgQ", + "y_2": "CAACAgQAAxkBAAIIaGWViMGoxYdaIaoz-5lQlAABhnZCEgACkA4AAuDImFEQ8qjFlcKplR4E", + "y_3": "CAACAgQAAxkBAAIIa2WViMLZtKOb5eAEYKPfbGQT4AXoAAL5DAACauiYUYCpWf5jw3vbHgQ", + "y_4": "CAACAgQAAxkBAAIIbmWViMIZL-SbEFuof3HZiwKxQOM-AAKNDgACY0uYUbzSTuR-DHU0HgQ", + "y_5": "CAACAgQAAxkBAAIIcWWViMP8mHHUUxjQTzZME_UqgOucAAKpDwACaBiYUfX97L9sxA1jHgQ", + "y_6": "CAACAgQAAxkBAAIIdGWViMQBqzJYS4zfGHLbPwac4xMnAAJ1DQAC5ZyYURsb-CbXAZgJHgQ", + "y_7": "CAACAgQAAxkBAAIId2WViMUli35f0n4JpRxn2z7TsxIBAALpDAAClAABmFEjw59G8tfe-R4E", + "y_8": "CAACAgQAAxkBAAIIemWViMYHsYK8A8zotkuQL7N9CUGqAAIBEAACL7aRUSJ8n471ZWKWHgQ", + "y_9": "CAACAgQAAxkBAAIIfWWViMbbYCRyvT1RHSb5LAxtpQFcAALEDQACFDyYUeOeX21QIdIsHgQ", + "y_draw": "CAACAgQAAxkBAAIIgGWViMeJKRPlJmIbw7w6-5EyzSRFAALPDgACdxmZUSEuFfXt6pfwHgQ", + "y_skip": "CAACAgQAAxkBAAIIg2WViMmxpEHw_qCaJGGFGv3FCvokAAI-FgACIZuQUb2Gm0U8uCPvHgQ", + "y_reverse": "CAACAgQAAxkBAAIIhmWViMomxSr2ZFGL4S45yqm9XlMRAAJPEAACqAWZUQlEHDh5aCcPHgQ", + "draw_four": "CAACAgQAAxkBAAIIiWWViM99yb-oIkGdZl69f-zLrDcjAAJhEAACueSZUaapceGNYQHEHgQ", + "colorchooser": "CAACAgQAAxkBAAIIjGWViNByhKosbeWF0U5byjtnNxQCAAKuDgAC9faZUSnH8GIMgTmdHgQ", + "option_draw": "CAACAgQAAxkBAAIIj2WViNj1FXsNWL95ZRUbPZJXJoX7AAL4AgACX1eZAAH-TdXSlvEa2x4E", + "option_pass": "CAACAgQAAxkBAAIIkmWViN0_ybsx490zyv0HFLw2sOzzAAL6AgACX1eZAAFuilR5QnD-Vx4E", + "option_bluff": "CAACAgQAAxkBAAIIlWWViOawFS22nDjGn3cB6svJ7ggkAALKAgACX1eZAAHBw478rNqN0B4E", + "option_info": "CAACAgQAAxkBAAIImGWViPjlUoOmQw7LWRFlgDq2a5u8AALEAgACX1eZAAGi2Qy93IIQwh4E" + }, + "STICKERS_GREY": { + "b_0": "CAACAgQAAxkBAAIIm2WViPpU7jFNtr5MybalgKn-vxneAAJFAgACX1eZAAHwXYFNZhQaIx4E", + "b_1": "CAACAgQAAxkBAAIInmWViPtl57X2VaM5XSb6nr1YGSqZAAJHAgACX1eZAAF_ZxC64wgdNB4E", + "b_2": "CAACAgQAAxkBAAIIoWWViP0cJwFXikbDcrJ00t1K_xJXAAJJAgACX1eZAAF-GuNgJ25IAAEeBA", + "b_3": "CAACAgQAAxkBAAIIpGWViP4BDkd8vKhBxGnHvbjRu_8CAAJLAgACX1eZAAHIJQ71XJ39mB4E", + "b_4": "CAACAgQAAxkBAAIIp2WViP7A3X1R9vjYv0bmvOY-rUPIAAJNAgACX1eZAAEjmR2mhJ8SsR4E", + "b_5": "CAACAgQAAxkBAAIIqmWViP9fFkit6AU8yMRBi0nbvU6CAAJPAgACX1eZAAEjfAwvM_8nsR4E", + "b_6": "CAACAgQAAxkBAAIIrWWViQABRYTEtaNJlrWkobC-DWakRQACUQIAAl9XmQABv35eqFpp188eBA", + "b_7": "CAACAgQAAxkBAAIIsGWViQEyYkmw3Hp_6yEuDEZPg_UGAAJTAgACX1eZAAG_xVqK-u2dzB4E", + "b_8": "CAACAgQAAxkBAAIIs2WViQHf7qbfR_X1dOxCxDyKQVJ6AAJVAgACX1eZAAF8hUb4bS_NdB4E", + "b_9": "CAACAgQAAxkBAAIItmWViQLMnaQOj_1KJ4QB7v7CtgmlAAJXAgACX1eZAAGXAmJ0BKvi1x4E", + "b_draw": "CAACAgQAAxkBAAIIuWWViQQt6MhXUnHrxX6ujGLp9OoUAAJZAgACX1eZAAFS-DsDXK7zdh4E", + "b_skip": "CAACAgQAAxkBAAIIvGWViQXzcWvBVYYuv8gUbBvJmWNzAAJdAgACX1eZAAFzsBiTRsZIeh4E", + "b_reverse": "CAACAgQAAxkBAAIIv2WViQYnXthYtIst_A_lYy9wsFJUAAJbAgACX1eZAAHRLf8w4EEJfx4E", + "g_0": "CAACAgQAAxkBAAIIwmWViQfpxDfIp0PyGemF3zYUIOmgAAJjAgACX1eZAAG_c8FzjSBlOB4E", + "g_1": "CAACAgQAAxkBAAIIxWWViQgejt9YHBrForCHSWyvLnqtAAJlAgACX1eZAAH2R3CHmHduZB4E", + "g_2": "CAACAgQAAxkBAAIIyGWViQnnGcwMI9BRuuD5XkWTP2xQAAJnAgACX1eZAAHB14u8vZ5pjR4E", + "g_3": "CAACAgQAAxkBAAIIy2WViQq0QobbZleDp9ZJpFEbdmrMAAJpAgACX1eZAAFaZGnJmMcN9B4E", + "g_4": "CAACAgQAAxkBAAIIzmWViQpJScW-f97n0rQpOSOYYAeSAAJrAgACX1eZAAF3KxLEqQq8Kx4E", + "g_5": "CAACAgQAAxkBAAII0WWViQteMUvnKyrbndV_TWRSpMuKAAJtAgACX1eZAAGObwogvTEInB4E", + "g_6": "CAACAgQAAxkBAAII1GWViQxEufLsZ6qPMt_0muYHN0c4AAJvAgACX1eZAAEpOGFMRnLGmR4E", + "g_7": "CAACAgQAAxkBAAII12WViQ38LxBaAsypjKdrLorXOGB1AAJxAgACX1eZAAEe_yu4DVELEh4E", + "g_8": "CAACAgQAAxkBAAII2mWViQ5o2Qj2SD-2uqkvRLIkpY74AAJzAgACX1eZAAH26plyNxWZuB4E", + "g_9": "CAACAgQAAxkBAAII3WWViQ4X_eX6VuMP3gmi0Z8WUiIPAAJ1AgACX1eZAAGrwYoTMk8UPR4E", + "g_draw": "CAACAgQAAxkBAAII4GWViQ-wjvGkjoKeN7G_VN7QeAbFAAJ3AgACX1eZAAFnlFIJWhbZIx4E", + "g_skip": "CAACAgQAAxkBAAII42WViRBlqJS24Dpe9jckZjx9NhFrAAJ7AgACX1eZAAFO5CqgPxquYR4E", + "g_reverse": "CAACAgQAAxkBAAII5mWViRGErVTAmwzzL8Gaw6m1uEJWAAJ5AgACX1eZAAE9cd3JVwlSEh4E", + "r_0": "CAACAgQAAxkBAAII6WWViRPUrdPmRLxJB_wPYSEz9VzJAAJ9AgACX1eZAAEZAg2nRervSB4E", + "r_1": "CAACAgQAAxkBAAII7GWViRTYSpKji8JFsJ7grOJpqR63AAJ_AgACX1eZAAFtLPMD6heoDx4E", + "r_2": "CAACAgQAAxkBAAII72WViRSJl1uLaIrhIlvDHumJ9WW7AAKBAgACX1eZAAGuvzFU0Su89R4E", + "r_3": "CAACAgQAAxkBAAII8mWViRWQGHlRWTZ9izrjtocY12kKAAKDAgACX1eZAAEFFjwwFZ7GiR4E", + "r_4": "CAACAgQAAxkBAAII9WWViRYsYsaPYMtVNqEQI14epvFuAAKFAgACX1eZAAHZFzRnwree-x4E", + "r_5": "CAACAgQAAxkBAAII-GWViRc1hhpZfuknLhDcTFE4fAwkAAKHAgACX1eZAAHsdpjtu9I2IR4E", + "r_6": "CAACAgQAAxkBAAII-2WViRhw6hgkC2hTtz5M01PWq4iaAAKJAgACX1eZAAG2D__a-tqZBR4E", + "r_7": "CAACAgQAAxkBAAII_mWViRh0xCPOW62vVVX3eW8qVcYXAAKLAgACX1eZAAGXaAtw5YFztR4E", + "r_8": "CAACAgQAAxkBAAIJAWWViRna-E8mEMrtaJgEN6kadagKAAKNAgACX1eZAAGkCOaURWQl8B4E", + "r_9": "CAACAgQAAxkBAAIJBGWViRpz1cu-hntkeMicpiUWFV1fAAKPAgACX1eZAAH-WS6bmv9CgR4E", + "r_draw": "CAACAgQAAxkBAAIJB2WViRvF9IaFuwLG8Aml_lXaIuVUAAKRAgACX1eZAAF2dldgt636fx4E", + "r_skip": "CAACAgQAAxkBAAIJCmWViRz7AyvfbVzBEGknm69vAlgCAAKVAgACX1eZAAGedr9LYgVebB4E", + "r_reverse": "CAACAgQAAxkBAAIJDWWViR3n0qcDtix_O4w8xWjd9U_1AAKTAgACX1eZAAECR8T0lu-Kmx4E", + "y_0": "CAACAgQAAxkBAAIJEGWViR87oSq_59nWAAFy01lTX4JdxgAClwIAAl9XmQAC5qVGyc5Gih4E", + "y_1": "CAACAgQAAxkBAAIJE2WViSD6-Sq3oTIMqVz-J9zOmIddAAKZAgACX1eZAAGB_02-C22Pkx4E", + "y_2": "CAACAgQAAxkBAAIJFmWViSEE44UOkY4s8r0LLBtvmjcbAAKbAgACX1eZAAHVmZUJxJwqmB4E", + "y_3": "CAACAgQAAxkBAAIJGWWViSGVT72rqzZe98CDc4lP66KnAAKdAgACX1eZAAGnajv8YZQj-x4E", + "y_4": "CAACAgQAAxkBAAIJHGWViSLM42LKJuClX_EVkJIUqhb8AAKfAgACX1eZAAEmxeENpAa35R4E", + "y_5": "CAACAgQAAxkBAAIJH2WViSMRJDYER1V6jctmpe4_LnjBAAKhAgACX1eZAAH2evQmPPzx8h4E", + "y_6": "CAACAgQAAxkBAAIJImWViSTTa8PENvS4oBsjCjyxsOq0AAKjAgACX1eZAAGYOfBpuoRg_B4E", + "y_7": "CAACAgQAAxkBAAIJJWWViSX62G9bAiolY1qdo7wt-lu_AAKlAgACX1eZAAFYxwrVWROuix4E", + "y_8": "CAACAgQAAxkBAAIJKGWViSYRfMC3KTuSH8FBi3GuERF3AAKnAgACX1eZAAF10j1L6rASCR4E", + "y_9": "CAACAgQAAxkBAAIJK2WViSaZDLJsteU3mN3JaZgxbUiQAAKpAgACX1eZAAGV1nEmuqjoJB4E", + "y_draw": "CAACAgQAAxkBAAIJLmWViSfj0w5rRfqv3G7Ehafi-cmIAAKrAgACX1eZAAGfJ2XK_ooNFh4E", + "y_skip": "CAACAgQAAxkBAAIJMWWViSiyvVRcF4fuiitl0tKoZyZ1AAKvAgACX1eZAAEVSSkTcHxJXB4E", + "y_reverse": "CAACAgQAAxkBAAIJNGWViSkfoWKkDlIjj5qEdo5I-W0QAAKtAgACX1eZAAEiP9aakPoiDx4E", + "draw_four": "CAACAgQAAxkBAAIJN2WViSw_fFBkTPJ6F984sRBdaXBDAAJhAgACX1eZAAHWx9PCWaCqkx4E", + "colorchooser": "CAACAgQAAxkBAAIJOmWViS0VcoFfcxzhI8MIvv7NuJZXAAJfAgACX1eZAAH4WHYrSCRGIh4E" + }, + "CARDS": { + "SPECIALS": [ + "draw_four", + "colorchooser" + ], + "SPECIALS_INFO": { + "draw_four": [ + 4, + "." + ], + "colorchooser": [ + 4, + "^(?!.*draw).*$" + ] + }, + "THEME_CARDS": [], + "COLORS": [ + "b", + "g", + "r", + "y" + ], + "COLOR_ICONS": { + "b": "blue", + "g": "green", + "r": "red", + "y": "yellow" + }, + "VALUES": [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "draw", + "skip", + "reverse" + ], + "VALUES_ICONS": { + "0": "0️⃣", + "1": "1️⃣", + "2": "2️⃣", + "3": "3️⃣", + "4": "4️⃣", + "5": "5️⃣", + "6": "6️⃣", + "7": "7️⃣", + "8": "8️⃣", + "9": "9️⃣", + "draw": "+2", + "skip": "🚫", + "reverse": "🔁", + "colorchooser": "🌈", + "draw_four": "+4" + } + } +} \ No newline at end of file diff --git a/cards/minimalist.json b/cards/minimalist.json new file mode 100644 index 0000000..2aca3c7 --- /dev/null +++ b/cards/minimalist.json @@ -0,0 +1,190 @@ +{ + "STICKERS": { + "b_0": "CAACAgEAAxkDAAEDe6tllA16pjgNwKfYPSG2fa3-RWCLZgACAwIAAsJ8kUXyk7MLF9xdBh4E", + "b_1": "CAACAgEAAxkDAAEDe6xllA18NuZNUwJvWlQd4oM1ET_DGQACqQMAAnHukEXmnSMIA9EHZh4E", + "b_2": "CAACAgEAAxkDAAEDe61llA1_v5dlOv1S_43ufmWuI9jGKwACXQIAAv_qkEVgclfo22dTXx4E", + "b_3": "CAACAgEAAxkDAAEDe65llA2By62MlWJL1KoSwAABXX6FJ8MAAhIDAAJ0vpBF7s5S-tulgzceBA", + "b_4": "CAACAgEAAxkDAAEDe69llA2EotC8Sxq2BV0_UNLFHiCraAACZwIAAhZvkUVhDXOLwAahsR4E", + "b_5": "CAACAgEAAxkDAAEDe7BllA2GMRqzd1XwtbPsB21ysznGggACKgMAAl3TkUU4NWqARyrisR4E", + "b_6": "CAACAgEAAxkDAAEDe7FllA2IGUW-kUGfNUNo1yLkEhlTKwACZQIAAkEamUXoN8eyf3WbVR4E", + "b_7": "CAACAgEAAxkDAAEDe7JllA2Kl-KJ4CzGnWR6bvmWdsuT3gACPgIAAr9DkUXKlfdmjxSZUx4E", + "b_8": "CAACAgEAAxkDAAEDe7NllA2MWfQmdO8qYnV-xd9Tm8pblgAC2AIAAqIskUUWu-bHbGOF8R4E", + "b_9": "CAACAgEAAxkDAAEDe7RllA2OcK42iYTR8YHEJLvqzqgZCAACkwIAAgbhkEW3VEnx24JUBh4E", + "b_draw": "CAACAgEAAxkDAAEDe7VllA2eJar5j6ts-sL1xCCZBaCKCQACBgMAAkYMkUVyqsDxtyrruR4E", + "b_skip": "CAACAgEAAxkDAAEDe7ZllA2gqoH1ykM-E62WG4JKVb0evwAC5AIAAoMOkUXTMcadXYpdLR4E", + "b_reverse": "CAACAgEAAxkDAAEDe7dllA2ing8hJqUzPezMWG-u9NJhlAACAwMAAlFCkEUfaBJjzqysoR4E", + "g_0": "CAACAgEAAxkDAAEDe7hllA2lB0XmfQX5HerEZEz37IILdwACcQIAAswfkUVCj6ddvIx5iR4E", + "g_1": "CAACAgEAAxkDAAEDe7lllA2nl8MoGoxPec0DhQ_rvhBoLAACDwMAApnYkEU_b4TvaFm6-B4E", + "g_2": "CAACAgEAAxkDAAEDe7pllA2pP4FIrMKVOnCgvgesr5hhOQACSAIAAruTkEXqutZPzXqcXx4E", + "g_3": "CAACAgEAAxkDAAEDe7tllA2r9sc-h0p5781yXUxmIjG30QACCwIAAqnskEWxoXpxAW_zch4E", + "g_4": "CAACAgEAAxkDAAEDe7xllA2tI7jBpElvA-v9_y11syRh5AACQQMAAkh4kUWGlbmFagXAQB4E", + "g_5": "CAACAgEAAxkDAAEDe71llA2vGXcCAxbTfq3quZMhjtfQHgACbgIAApcckUVhphMsBYqfJx4E", + "g_6": "CAACAgEAAxkDAAEDe75llA2xHxOm-TiqMLml4YfVgIGHugACPgIAAi_OkEUiL81ENcLfSx4E", + "g_7": "CAACAgEAAxkDAAEDe79llA2yzUGRwz_nGdHVmyYKXdtUIAACDQMAAhSVkEVK2TL696mHEh4E", + "g_8": "CAACAgEAAxkDAAEDe8BllA20x6V1fiYfPK0AAZubQti3x90AAgkCAAI68ZFFxalNVgrhumweBA", + "g_9": "CAACAgEAAxkDAAEDe8FllA22AtfyKfEy2D1TD9yBg_vjhwAC8gIAAvp_kEUHMIge7TYyKB4E", + "g_draw": "CAACAgEAAxkDAAEDe8JllA24zAKP_EPj3WxQxWoCPY4edAACRAIAAujlkEXQU7jwZxRZiB4E", + "g_skip": "CAACAgEAAxkBAAIM12ZfWhoZlohTFinVWlZsgdV5CCEkAAITAgACuh2QRcLStZTh5J7VHgQ", + "g_reverse": "CAACAgEAAxkDAAEDe8RllA29Dre8XGZlqa4AAfSEXjS9LQYAAqsCAAKkLJFFiweqZ2bqu1QeBA", + "r_0": "CAACAgEAAxkDAAEDe8VllA3B-RkLpk1nq0jdcwy9BoSkHgACkAIAAloBkUX_0_LhZSJczR4E", + "r_1": "CAACAgEAAxkDAAEDe8ZllA3EVB2FIhJGiPIrtAACEeGVkgACggIAAuUMkUXYO2A7fOgafR4E", + "r_2": "CAACAgEAAxkDAAEDe8dllA3GdC6M4zzPTt8hxQNIQ7slzgACGAIAAv7xkEXl-k_R6oY76x4E", + "r_3": "CAACAgEAAxkDAAEDe8hllA3JRFrTn-sd5PRN4xWCM90tHwACGgMAAuC2kEXPCeJ41Blilx4E", + "r_4": "CAACAgEAAxkDAAEDe8lllA3MMqjbGbOk65ZW-iKojTrsFAAC5QIAAr8akUWeAsacvKVD7B4E", + "r_5": "CAACAgEAAxkDAAEDe8pllA3O9EyO50Rao1PvMn0fED0i7gAChwIAAhmTkEXI8f4hQtAPgB4E", + "r_6": "CAACAgEAAxkDAAEDe8tllA7PL1JfkjtApb9xfoFTDvDd2QACyAEAAnxpkUUXkvlBf7LZaR4E", + "r_7": "CAACAgEAAxkDAAEDe8xllA3TwEfjLkRJOk3bCYuMd_BhgAACtAEAAoGNkUW3IDX6hbLIRR4E", + "r_8": "CAACAgEAAxkDAAEDe81llA3Whl0dV_B5gN-LYVHHFFzJBAAC9wEAAl1lkEX1oBklhfbG7h4E", + "r_9": "CAACAgEAAxkDAAEDe85llA3ZKoQVIMWcAkgHEUebPu1BkwACpAIAAkG5kEWg5cauEqb-Eh4E", + "r_draw": "CAACAgEAAxkDAAEDe89llA3bEXr4bslsjfbgKJxX6_soWAACbAMAAiXikEUOrMwjMnq71h4E", + "r_skip": "CAACAgEAAxkDAAEDe9BllA3e3VxyE6B9kKt_o0uo3gO0QgAC_gIAAsVPkUXDxwuskYP9wB4E", + "r_reverse": "CAACAgEAAxkDAAEDe9FllA3h6JFRqSvdtHK7AzPGKhR93QAC3gIAAqXNkEVHBrFdkXLu8B4E", + "y_0": "CAACAgEAAxkDAAEDe9JllA3jVjW8wkE9VFRUdbvukteHigACTgIAAsdskUUJCGkroV6nOx4E", + "y_1": "CAACAgEAAxkDAAEDe9NllA3mM3HzFiwpLbIZmn1y7og-ogAC6QEAApAEkEVBGUptZYFNtx4E", + "y_2": "CAACAgEAAxkDAAEDe9RllA3pSe6Pq6XfdXrGSUwO_XnNRwAC9QIAAumPkUWO0RtAwk-gqh4E", + "y_3": "CAACAgEAAxkDAAEDe9ZllA3yb8nE9KLHDwf4TpLVSQi8PwACKAMAAlZkkEX3DMzHkfKt4x4E", + "y_4": "CAACAgEAAxkDAAEDe9dllA31GtSoqcIH83bG6E_-e_LMGwACcwIAAvhqkUVHXHrGg4bzkB4E", + "y_5": "CAACAgEAAxkDAAEDe9hllA34eX3HlQVCB3yz4jE_hxkcPgACvAIAAlrSkUXmuFcRjj_Ykh4E", + "y_6": "CAACAgEAAxkDAAEDe9lllA38BYT4tiz3UynZ1KlgBeE9zwACjAIAAucGkEUklwtxCimr8h4E", + "y_7": "CAACAgEAAxkDAAEDe9pllA3_D9P4Z8gbdSrJolueNEReHgACpAIAAmLqkEW8I1ITQ-K4UR4E", + "y_8": "CAACAgEAAxkDAAEDe9tllA4CfpWusm9qPlMzZB4d1OZuOwACDQIAAl0VkEUjRoTZaTeIiR4E", + "y_9": "CAACAgEAAxkDAAEDe9xllA4F1NkFzxkbrUN-tdzZP5X7HwACtwIAAleokUWrFCx6aDoY1B4E", + "y_draw": "CAACAgEAAxkDAAEDe91llA4IQ-kifRI4cFbGbMZBA3rWvwACVAIAAmnbkUWKjhkSgboWox4E", + "y_skip": "CAACAgEAAxkDAAEDe95llA4MjLGS0nj2fCILrVq0VDOu9AAC4gEAAsUYkUVNLlmImNML9h4E", + "y_reverse": "CAACAgEAAxkDAAEDe99llA4QK1OuIZxHXrjpHa72GHwnQwACxAIAAn1JkEUTDAHVfy579h4E", + "draw_four": "CAACAgEAAxkDAAEDd9tldPH_lqQbjb_fguXSJiUEZmXMDgACCAIAAmfQkEWdQcu_mD_LxR4E", + "colorchooser": "CAACAgEAAxkDAAEDd9xldPICMlwKe0ZQLmNenTD1fQ3cNQACaAIAAgeNkUXMnabDbsOjOh4E", + "mirror": "CAACAgEAAxkBAAIJjGWXDOVcBxySviDWuqpeCBt2wzsRAALfAgACM5iRRbhn4u7C82kqHgQ", + "option_draw": "CAACAgEAAxkDAAEDeJpldQABh5BKyV9yoabNg_K5EBnWbAkAAtYEAAL1-6hHbSd5q2HZFrAeBA", + "option_pass": "CAACAgQAAxkDAAI4JmNtY_yMlr6rB3UdTikR3zFCk8kVAAL6AgACX1eZAAFuilR5QnD-VysE", + "option_bluff": "CAACAgQAAxkDAAI4J2NtY_2Dmt5Mi4iZhsUh32OeNVe7AALKAgACX1eZAAHBw478rNqN0CsE", + "option_info": "CAACAgQAAxkDAAI4KGNtY_3tO0Sxhu5NzF1UA3tdUnklAALEAgACX1eZAAGi2Qy93IIQwisE" + }, + "STICKERS_GREY": { + "b_0": "CAACAgEAAxkDAAEDeBhldPQpr_HP5jMfg5eqmF9WwcbANwACzAEAAvMQkUW3xk9Rm7wDdB4E", + "b_1": "CAACAgEAAxkDAAEDeBlldPQtK30FApRgW8VPDinDZiBcMwACHAMAAhT5kEU5hLA1PG5mNx4E", + "b_2": "CAACAgEAAxkDAAEDeBpldPQy489pxZnGU_OJivHLZUz_rgAC8gIAAhWNkUUj2qPu53BQAR4E", + "b_3": "CAACAgEAAxkDAAEDeBtldPQ1QGHrATJf8y6xY1WOESH19wACywIAAoCvkEUusWPJE3SO8R4E", + "b_4": "CAACAgEAAxkDAAEDeBxldPQ4gNTK8wbbKPySKhH9HRQjvwACKAIAApa_kEU9N3ivQr1-1x4E", + "b_5": "CAACAgEAAxkDAAEDeB1ldPQ7La8udS3TXWrlx0X1-hfj-gACRwIAArP5kEVCQ9gkbL8Byh4E", + "b_6": "CAACAgEAAxkDAAEDeB5ldPQ-GnWfnbES5XLjjeEnCCx9QgACKQMAAqPkkUUugGSOjf9txR4E", + "b_7": "CAACAgEAAxkDAAEDeB9ldPRC1btFrtNIrvF2r5Cm46WbnQACWQIAAomUmUUvhGYvR8jwPh4E", + "b_8": "CAACAgEAAxkDAAEDeCBldPRFe3GVn8NG-kFW-6kCBfbZTwACaAIAAgg5kUUsEUnkv0FafR4E", + "b_9": "CAACAgEAAxkDAAEDeCFldPRIRXMxVF6-2SIuN9N2TcYSbwACSgwAAr8jkEXx2Ncg-cKr-B4E", + "b_draw": "CAACAgEAAxkDAAEDeCJldPRM9VR0-q4Nr1CH71nRpi3_-AACZQMAAtvQkUWdG5DeUdyYbR4E", + "b_skip": "CAACAgEAAxkDAAEDeCNldPRQkadczfkJ1AGbpGhP4hJoYQAClwMAAgQSkEVJkgABSqHf3RMeBA", + "b_reverse": "CAACAgEAAxkDAAEDeCRldPRSBY2Xe8gqahJ5uX7jhk72lgACXgIAArfzkUVdqU8Skpie5B4E", + "g_0": "CAACAgEAAxkDAAEDeCVldPRWthIVrMEDrpNDQkWocduO_AACcgIAAkpskEV35BNxHr8V5x4E", + "g_1": "CAACAgEAAxkDAAEDeCZldPRantCOaUJ5thTqgnk1aiL5QgACCwMAAs3ukUVOx82xQv9Ffx4E", + "g_2": "CAACAgEAAxkDAAEDeCdldPRdO7pkiMb9Jiiy5470Z8rUzAACewIAApPKkEUHSvig3w4D6R4E", + "g_3": "CAACAgEAAxkDAAEDeChldPRh9Wyk3_ttBrB4dKFW534KJQACNRYAAl_mkUUjJPhaXCrytR4E", + "g_4": "CAACAgEAAxkDAAEDeClldPRk_MvviiZl7flLtfzE_oJTLQAC2AIAAkIjkEU6INaWefsnbR4E", + "g_5": "CAACAgEAAxkDAAEDeCpldPRmgqPSrQI-xX4Y4tL9-ejIKQACSAMAAsXrkUU8dg1tlvXuIx4E", + "g_6": "CAACAgEAAxkDAAEDeCtldPRqS9IxSLuq2bC61gABw2TBEQADfgIAAtKEkEV2q3ae2QfTlR4E", + "g_7": "CAACAgEAAxkDAAEDeCxldPRuL0gfAcA0n2sx_f0iv5sctwACaQIAAvBfkEWujcXUoCoNkh4E", + "g_8": "CAACAgEAAxkDAAEDeDBldPTZGi65G5L8tGWUO3wOSixVhwACYAMAAr7jkUW_EGWLU2VY3x4E", + "g_9": "CAACAgEAAxkDAAEDeDFldPTatuaW2a1roWs1yQ0CknzrFAACZAIAAofZkUV4qNUOIfMGfB4E", + "g_draw": "CAACAgEAAxkDAAEDeDJldPTbUcBqKAzvWXOb7hYO3ebsVAAC2QIAAojIkEWLotFWFUrd9B4E", + "g_skip": "CAACAgEAAxkDAAEDeDNldPTdh9PvZ_VZ8XIm9Km6bX2J_QACTQIAArBokEVwbQsgazaHHB4E", + "g_reverse": "CAACAgEAAxkDAAEDeDRldPTd9yIAAZ4Y6szNLr_KmTCgvCgAAu8CAAKLQJFFVS-Ee507SeQeBA", + "r_0": "CAACAgEAAxkDAAEDeDVldPTeA_iz6315Ync-7RV5bjg8lgACMgYAAqQtkEUfzWAEmEoSsx4E", + "r_1": "CAACAgEAAxkDAAEDeDZldPTfPZCyQY-NBUz4YHZKVqkFdQACvgIAAhRRkUXPAAFc1XcuDSseBA", + "r_2": "CAACAgEAAxkDAAEDeDdldPTf3s_igw3SQLjEpVeg7cxa2AAC8wIAAn5ukEXFPt-unsEYFB4E", + "r_3": "CAACAgEAAxkDAAEDeDhldPTgnLoEQVmm8PXRZNjfcKT08wACHQMAAg0HkEUTAAEuHgIFMMgeBA", + "r_4": "CAACAgEAAxkDAAEDeDlldPTh80oMZu94S4aEgOHe_ETbzwACMgIAAloEkEU4V1zqccv4px4E", + "r_5": "CAACAgEAAxkBAAINHGZfWnsZDbEzrk-2D3HjMV1F65AAA6ACAAI7OJFFF9QnY0HDd4YeBA", + "r_6": "CAACAgEAAxkDAAEDeDtldPTjto0-gDKrLfvtOnLR3yedfwAC8QEAAh0PkUWDDCnQ0yKJ4B4E", + "r_7": "CAACAgEAAxkDAAEDeDxldPTj_eXDrdZOTuAgDapmmCGopgACjAIAAnyFkUWR0nnKzFE9Ox4E", + "r_8": "CAACAgEAAxkDAAEDeD1ldPTksKpKl4svmqhZp754lHk_4AAC1QIAAnjkkEWe22LmFa-TXx4E", + "r_9": "CAACAgEAAxkDAAEDeD5ldPTkK9WuHM_JGtcqX82HXids2AACBQQAAlV2kEXV6etMTirPNh4E", + "r_draw": "CAACAgEAAxkDAAEDeD9ldPTl95GlyWxd13otkkbwgYxnuQACIQIAArN7kEXAyhLPjeuM0B4E", + "r_skip": "CAACAgEAAxkDAAEDeEBldPTmDSmE_hf8iqfvTNw_MhN-DgACjQIAAgFikUUbhvkdjEvL_B4E", + "r_reverse": "CAACAgEAAxkDAAEDeEFldPTm_FseoIs4TkycuysDW93ClgACiwIAAvKekEWH4bB4fK_JAh4E", + "y_0": "CAACAgEAAxkDAAEDeEJldPUSOSBzeDwybGll4Z8UKWuTzgACzQIAAlZRkEUaN3RtvlPkhx4E", + "y_1": "CAACAgEAAxkDAAEDeENldPUTdMKXIDNbaFklvDnV8eyHfQAC_QIAAmS8kUWe4Qhj7djTNx4E", + "y_2": "CAACAgEAAxkDAAEDeERldPUTCwm7oP44jKDQXw_0v0EHFwACDAMAAkYEkEXwjgrHAngn8h4E", + "y_3": "CAACAgEAAxkDAAEDeEVldPUUK3_GcOUCyoAz9QxD6m21tAAC9AMAAuu9kUVv0c8dISk1Ix4E", + "y_4": "CAACAgEAAxkDAAEDeEZldPUUxdlEgfu7gmJvazzHtiVjLQACbwQAAp9KkUWXChzRPGdXKh4E", + "y_5": "CAACAgEAAxkDAAEDeEdldPUVJRjFaF2gCyeb9FI5eLHJYwACFQMAAqTfkUWYvUcRvcNxhh4E", + "y_6": "CAACAgEAAxkDAAEDeEhldPUWzqtfWclTzKpnM9poibfNIQACpgIAAhZ3kEW9Xv1BRth-4B4E", + "y_7": "CAACAgEAAxkDAAEDeElldPUWLMeeIuoZ_vL46CgPfzDTxwAC7QEAApxekEUmO5PhRBZWdx4E", + "y_8": "CAACAgEAAxkDAAEDeEpldPUXs-BExZa_58xEDvMRbS4_nAACfgIAAmg-kUUoRbaAW_B4HR4E", + "y_9": "CAACAgEAAxkDAAEDeEtldPUYcpBSMEHnXZkFkK6mAyF49AACqwIAAtsVkEVRqf1U9QqfdB4E", + "y_draw": "CAACAgEAAxkDAAEDeExldPUYd5oe-E69-C2kjrolu2s64wACqwIAAk1xkUXw_oyRmWZrwx4E", + "y_skip": "CAACAgEAAxkDAAEDeE1ldPUZ57bOPol5KNgUnLGEsWOCRQACUAIAAq70mEW_IHyXZAkgxB4E", + "y_reverse": "CAACAgEAAxkDAAEDeE5ldPUZlq9iapYBJlTdZv0OJ1HjiQACzwIAAiozkEUGSQFnhRdepR4E", + "draw_four": "CAACAgEAAxkDAAEDeE9ldPUmQloxc6_ReBmEx6mUL1GYTwACBAIAAisrmUUd5e1D0lszKB4E", + "colorchooser": "CAACAgEAAxkDAAEDeFBldPUxrSNyn9WqB7y9yp7QTeyTaAACDQIAAlZtkEUPHKKL4f24nR4E", + "mirror": "CAACAgEAAxkDAAEDeLpldRDJK0FwP0BId9Tnvf_2yBrz7AACBgIAAtSKkUWN6yeT8oqBeB4E" + }, + "CARDS": { + "SPECIALS": [ + "draw_four", + "colorchooser", + "mirror" + ], + "SPECIALS_INFO": { + "draw_four": [ + 4, + "." + ], + "colorchooser": [ + 4, + "^(?!.*draw).*$" + ], + "mirror": [ + 2, + "draw|skip" + ] + }, + "THEME_CARDS": [ + "mirror" + ], + "COLORS": [ + "b", + "g", + "r", + "y" + ], + "COLOR_ICONS": { + "b": "🟦", + "g": "🟩", + "r": "🟥", + "y": "🟨", + "x": "❓" + }, + "VALUES": [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "draw", + "skip", + "reverse" + ], + "VALUES_ICONS": { + "0": "0️⃣", + "1": "1️⃣", + "2": "2️⃣", + "3": "3️⃣", + "4": "4️⃣", + "5": "5️⃣", + "6": "6️⃣", + "7": "7️⃣", + "8": "8️⃣", + "9": "9️⃣", + "draw": "+2", + "skip": "🚫", + "reverse": "🔁", + "colorchooser": "🌈", + "draw_four": "+4", + "mirror": "🪞" + } + } +} \ No newline at end of file diff --git a/commandlist.txt b/commandlist.txt deleted file mode 100644 index e1aa46a..0000000 --- a/commandlist.txt +++ /dev/null @@ -1,18 +0,0 @@ -new - Start a new game -join - Join the current game -start - Start the game -leave - Leave the game you're in -close - Close the game lobby -open - Open the game lobby -kill - Terminate the game -kick - Kick players out of the game -enable_translations - Enable multi-translations -disable_translations - Disable multi-translations -skip - Skip the current player -notify_me - Get a message when there's a new game in this group -help - How to use this bot? -modes - Explanation of game modes -settings - Language and other settings -stats - Show statistics -source - See source information -news - All news about this bot diff --git a/config-example.py b/config-example.py new file mode 100644 index 0000000..c8ecdb0 --- /dev/null +++ b/config-example.py @@ -0,0 +1,12 @@ +from hydrogram import Client + + +games = {} +player_game = {} + +API_ID = '' +API_HASH = '' + +#--- Telegram config --- + +bot = Client("bot", api_id=API_ID, api_hash=API_HASH, plugins=dict(root="plugins")) diff --git a/config.json.example b/config.json.example deleted file mode 100644 index 0639c8c..0000000 --- a/config.json.example +++ /dev/null @@ -1,12 +0,0 @@ -{ - "token": "token_here", - "base_url": "https://api.telegram.org/bot", - "admin_list": [0], - "open_lobby": true, - "enable_translations": false, - "default_gamemode": "fast", - "waiting_time": 120, - "time_removal_after_skip": 20, - "min_fast_turn_time": 15, - "min_players": 2 -} diff --git a/config.py b/config.py deleted file mode 100644 index e5ac151..0000000 --- a/config.py +++ /dev/null @@ -1,31 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import json - -with open("config.json") as f: - config = json.loads(f.read()) - -TOKEN = config.get("token") -BASE_URL = config.get("base_url", "https://api.telegram.org/bot") -ADMIN_LIST = config.get("admin_list", None) -OPEN_LOBBY = config.get("open_lobby", True) -ENABLE_TRANSLATIONS = config.get("enable_translations", False) -DEFAULT_GAMEMODE = config.get("default_gamemode", "fast") -WAITING_TIME = config.get("waiting_time", 120) -TIME_REMOVAL_AFTER_SKIP = config.get("time_removal_after_skip", 20) -MIN_FAST_TURN_TIME = config.get("min_fast_turn_time", 15) -MIN_PLAYERS = config.get("min_players", 2) diff --git a/database.py b/database.py deleted file mode 100644 index d73b89e..0000000 --- a/database.py +++ /dev/null @@ -1,20 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -from pony.orm import Database - -# Database singleton -db = Database() diff --git a/db.py b/db.py new file mode 100644 index 0000000..220c4bf --- /dev/null +++ b/db.py @@ -0,0 +1,48 @@ +import os + +from tortoise import Tortoise, connections, fields +from tortoise.backends.base.client import Capabilities +from tortoise.models import Model + + +class Chat(Model): + id = fields.IntField(pk=True) + theme = fields.CharField(max_length=255, default="classic") + bluff = fields.BooleanField(default=True) + seven = fields.BooleanField(default=False) + one_win = fields.BooleanField(default=False) + one_card = fields.BooleanField(default=False) + lang = fields.CharField(max_length=255, default="en-US") + +class User(Model): + id = fields.BigIntField(pk=True) + placar = fields.BooleanField(default=False) + wins = fields.IntField(default=0) + matches = fields.IntField(default=0) + cards = fields.IntField(default=0) + sudo = fields.BooleanField(default=False) + lang = fields.CharField(max_length=255, default="en-US") + + +async def connect_database(): + await Tortoise.init( + { + "connections": { + "bot_db": os.getenv("DATABASE_URL", "sqlite://database.sqlite") + }, + "apps": {"bot": {"models": [__name__], "default_connection": "bot_db"}}, + } + ) + + conn = connections.get("bot_db") + conn.capabilities = Capabilities( + "sqlite", + daemon=False, + requires_limit=True, + inline_comment=True, + support_for_update=False, + support_update_limit_order_by=False, + ) + + # Generate the schema + await Tortoise.generate_schemas() diff --git a/deck.py b/deck.py index a8852a8..fa5fb6b 100644 --- a/deck.py +++ b/deck.py @@ -1,83 +1,23 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import logging -from random import shuffle - -import card as c -from card import Card -from errors import DeckEmptyError +import random +from card import cards class Deck: - """This class represents a deck of cards.""" - - def __init__(self) -> None: - self.cards = [] - self.graveyard = [] - self.logger = logging.getLogger(__name__) - - self.logger.debug(self.cards) + def __init__(self, theme) -> None: + self.cards = [ + (color, value) + for _ in range(2) + for color in cards[theme]["CARDS"]["COLORS"] + for value in cards[theme]["CARDS"]["VALUES"] + ] + self.cards += [ + ("x", car) + for car in cards[theme]["CARDS"]["SPECIALS"] + for _ in range(cards[theme]["CARDS"]["SPECIALS_INFO"][car][0]) + ] def shuffle(self): - """Shuffles the deck.""" - self.logger.debug("Shuffling Deck") - shuffle(self.cards) - - def draw(self): - """Draws a card from this deck.""" - try: - card = self.cards.pop() - self.logger.debug("Drawing card %s", str(card)) - return card - except IndexError as e: - if not self.graveyard: - raise DeckEmptyError from e - while self.graveyard: - self.cards.append(self.graveyard.pop()) - self.shuffle() - return self.draw() - - def dismiss(self, card): - """Returns a card to the deck.""" - if card.special: - card.color = None - self.graveyard.append(card) - - def _fill_classic_(self): - # Fill deck with the classic card set - self.cards.clear() - for color in c.COLORS: - for value in c.VALUES: - self.cards.append(Card(color, value)) - if value != c.ZERO: - self.cards.append(Card(color, value)) - for special in c.SPECIALS: - for _ in range(4): - self.cards.append(Card(None, None, special=special)) - self.shuffle() + random.shuffle(self.cards) - def _fill_wild_(self): - # Fill deck with a wild card set - self.cards.clear() - for color in c.COLORS: - for value in c.WILD_VALUES: - for _ in range(4): - self.cards.append(Card(color, value)) - for special in c.SPECIALS: - for _ in range(6): - self.cards.append(Card(None, None, special=special)) - self.shuffle() + def draw(self, amount): + return [self.cards.pop(0) for _ in range(amount) if self.cards] diff --git a/errors.py b/errors.py deleted file mode 100644 index 748181b..0000000 --- a/errors.py +++ /dev/null @@ -1,35 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - - -class NoGameInChatError(Exception): - pass - - -class AlreadyJoinedError(Exception): - pass - - -class LobbyClosedError(Exception): - pass - - -class NotEnoughPlayersError(Exception): - pass - - -class DeckEmptyError(Exception): - pass diff --git a/game.py b/game.py index 349a6ca..0f5e717 100644 --- a/game.py +++ b/game.py @@ -1,142 +1,24 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import logging -from datetime import datetime - -from telegram import Chat - -import card as c -from config import ADMIN_LIST, DEFAULT_GAMEMODE, ENABLE_TRANSLATIONS, OPEN_LOBBY +from hydrogram.types import Chat, User from deck import Deck class Game: - """This class represents a game of UNO.""" - - current_player = None - reversed = False - choosing_color = False - choosing_player = False - started = False - draw_counter = 0 - players_won = 0 - starter = None - mode = DEFAULT_GAMEMODE - job = None - owner = ADMIN_LIST - open = OPEN_LOBBY - translate = ENABLE_TRANSLATIONS - - def __init__(self, chat: Chat, thread_id: int) -> None: + def __init__(self, chat: Chat, theme) -> None: self.chat = chat - self.thread_id = thread_id - self.last_card = None - - self.deck = Deck() - - self.logger = logging.getLogger(__name__) - - @property - def players(self): - """Returns a list of all players in this game.""" - players = [] - if not self.current_player: - return players - - current_player = self.current_player - itplayer = current_player.next - players.append(current_player) - while itplayer and itplayer is not current_player: - players.append(itplayer) - itplayer = itplayer.next - return players - - def start(self): - if self.mode is None or self.mode != "wild": - self.deck._fill_classic_() - else: - self.deck._fill_wild_() - - self._first_card_() - self.started = True - - def set_mode(self, mode): - self.mode = mode - - def reverse(self): - """Reverses the direction of game.""" - self.reversed = not self.reversed - - def turn(self): - """Marks the turn as over and change the current player.""" - self.logger.debug("Next Player") - self.current_player = self.current_player.next - self.current_player.drew = False - self.current_player.turn_started = datetime.now() - self.choosing_color = False - self.choosing_player = False - - def _first_card_(self): - # In case that the player did not select a game mode - if not self.deck.cards: - self.set_mode(DEFAULT_GAMEMODE) - - # The first card should not be a special card - while not self.last_card or self.last_card.special: - self.last_card = self.deck.draw() - # If the card drawn was special, return it to the deck and loop again - if self.last_card.special: - self.deck.dismiss(self.last_card) - - self.play_card(self.last_card) - - def play_card(self, card): - """Plays a card and triggers its effects. - Should be called only from Player.play or on game start to play the - first card. - """ - self.deck.dismiss(self.last_card) - self.last_card = card - - self.logger.info("Playing card %s", card) - if card.value == c.SKIP: - self.turn() - elif card.special == c.DRAW_FOUR: - self.draw_counter += 4 - self.logger.debug("Draw counter increased by 4") - elif card.value == c.DRAW_TWO: - self.draw_counter += 2 - self.logger.debug("Draw counter increased by 2") - elif card.value == c.REVERSE: - # Special rule for two players - if self.current_player is self.current_player.next.next: - self.turn() - else: - self.reverse() - - # Don't turn if the current player has to choose a color - if card.special not in (c.CHOOSE, c.DRAW_FOUR): - self.turn() - else: - self.logger.debug("Choosing Color...") - self.choosing_color = True - - def choose_color(self, color): - """Carries out the color choosing and turns the game.""" - self.last_card.color = color - self.turn() + self.last_card_2 = None + self.next_player:User = None + self.deck = Deck(theme) + self.players = {} + self.is_started = False + self.draw = 0 + self.chosen = None + self.closed = False + self.winner = True + + def next(self): + if self.draw >= 0: + indice = list(self.players.keys()).index(self.next_player.id) + next_ind = (indice + 1) % len(self.players) + next_key = list(self.players.keys())[next_ind] + self.next_player = self.players[next_key] diff --git a/game_manager.py b/game_manager.py deleted file mode 100644 index 6099357..0000000 --- a/game_manager.py +++ /dev/null @@ -1,176 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import contextlib -import logging -from typing import Optional - -from telegram import Chat - -from errors import ( - AlreadyJoinedError, - LobbyClosedError, - NoGameInChatError, - NotEnoughPlayersError, -) -from game import Game -from player import Player - - -class GameManager: - """Manages all running games by using a confusing amount of dicts.""" - - def __init__(self) -> None: - self.chatid_games = {} - self.userid_players = {} - self.userid_current = {} - self.remind_dict = {} - - self.logger = logging.getLogger(__name__) - - def new_game(self, chat: Chat, thread_id: Optional[int] = None): - """Create a new game in this chat.""" - chat_id = chat.id - - self.logger.debug("Creating new game in chat %s", str(chat_id)) - game = Game(chat, thread_id) - - if chat_id not in self.chatid_games: - self.chatid_games[chat_id] = [] - - # remove old games - for g in list(self.chatid_games[chat_id]): - if not g.players: - self.chatid_games[chat_id].remove(g) - - self.chatid_games[chat_id].append(game) - return game - - def join_game(self, user, chat): - """Create a player from the Telegram user and add it to the game.""" - self.logger.info("Joining game with id %s", chat.id) - - try: - game = self.chatid_games[chat.id][-1] - except (KeyError, IndexError) as e: - raise NoGameInChatError from e - - if not game.open: - raise LobbyClosedError - - if user.id not in self.userid_players: - self.userid_players[user.id] = [] - - players = self.userid_players[user.id] - - # Don not re-add a player and remove the player from previous games in - # this chat, if he is in one of them - for player in players: - if player in game.players: - raise AlreadyJoinedError - - try: - self.leave_game(user, chat) - except NoGameInChatError: - pass - except NotEnoughPlayersError: - self.end_game(chat, user) - - if user.id not in self.userid_players: - self.userid_players[user.id] = [] - - players = self.userid_players[user.id] - - player = Player(game, user) - if game.started: - player.draw_first_hand() - - players.append(player) - self.userid_current[user.id] = player - - def leave_game(self, user, chat): - """Remove a player from its current game.""" - player = self.player_for_user_in_chat(user, chat) - players = self.userid_players.get(user.id, []) - - if not player: - games = self.chatid_games[chat.id] - for g in games: - for p in g.players: - if p.user.id == user.id: - if p is g.current_player: - g.turn() - - p.leave() - return - - raise NoGameInChatError - - game = player.game - - if len(game.players) < 3: - raise NotEnoughPlayersError - - if player is game.current_player: - game.turn() - - player.leave() - players.remove(player) - - # If this is the selected game, switch to another - if self.userid_current.get(user.id) is player: - if players: - self.userid_current[user.id] = players[0] - else: - del self.userid_current[user.id] - del self.userid_players[user.id] - - def end_game(self, chat, user): - """End a game.""" - self.logger.info("Game in chat %s ended", chat.id) - - # Find the correct game instance to end - player = self.player_for_user_in_chat(user, chat) - - if not player: - raise NoGameInChatError - - game = player.game - - # Clear game - for player_in_game in game.players: - this_users_players = self.userid_players.get(player_in_game.user.id, []) - - with contextlib.suppress(ValueError): - this_users_players.remove(player_in_game) - if this_users_players: - with contextlib.suppress(KeyError): - self.userid_current[player_in_game.user.id] = this_users_players[0] - else: - with contextlib.suppress(KeyError): - del self.userid_players[player_in_game.user.id] - with contextlib.suppress(KeyError): - del self.userid_current[player_in_game.user.id] - self.chatid_games[chat.id].remove(game) - if not self.chatid_games[chat.id]: - del self.chatid_games[chat.id] - - def player_for_user_in_chat(self, user, chat): - players = self.userid_players.get(user.id, []) - return next( - (player for player in players if player.game.chat.id == chat.id), - None, - ) diff --git a/genpot.sh b/genpot.sh deleted file mode 100755 index 9c64849..0000000 --- a/genpot.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -currentVer='1.0' - -xgettext *.py -o ./locales/unobot.pot --foreign-user \ - --package-name="uno_bot" \ - --package-version="$currentVer" \ - --msgid-bugs-address='uno@jhoeke.de' \ - --keyword=__ \ - --keyword=_ \ - --keyword=_:1,2 \ - --keyword=__:1,2 diff --git a/images/jpg/b_0.jpg b/images/jpg/b_0.jpg deleted file mode 100644 index 17c6cf1..0000000 Binary files a/images/jpg/b_0.jpg and /dev/null differ diff --git a/images/jpg/b_1.jpg b/images/jpg/b_1.jpg deleted file mode 100644 index 8a13c88..0000000 Binary files a/images/jpg/b_1.jpg and /dev/null differ diff --git a/images/jpg/b_2.jpg b/images/jpg/b_2.jpg deleted file mode 100644 index 1524948..0000000 Binary files a/images/jpg/b_2.jpg and /dev/null differ diff --git a/images/jpg/b_3.jpg b/images/jpg/b_3.jpg deleted file mode 100644 index d7e19ab..0000000 Binary files a/images/jpg/b_3.jpg and /dev/null differ diff --git a/images/jpg/b_4.jpg b/images/jpg/b_4.jpg deleted file mode 100644 index 4f34e06..0000000 Binary files a/images/jpg/b_4.jpg and /dev/null differ diff --git a/images/jpg/b_5.jpg b/images/jpg/b_5.jpg deleted file mode 100644 index e85ac46..0000000 Binary files a/images/jpg/b_5.jpg and /dev/null differ diff --git a/images/jpg/b_6.jpg b/images/jpg/b_6.jpg deleted file mode 100644 index a9be485..0000000 Binary files a/images/jpg/b_6.jpg and /dev/null differ diff --git a/images/jpg/b_7.jpg b/images/jpg/b_7.jpg deleted file mode 100644 index aa73e39..0000000 Binary files a/images/jpg/b_7.jpg and /dev/null differ diff --git a/images/jpg/b_8.jpg b/images/jpg/b_8.jpg deleted file mode 100644 index a6e63fb..0000000 Binary files a/images/jpg/b_8.jpg and /dev/null differ diff --git a/images/jpg/b_9.jpg b/images/jpg/b_9.jpg deleted file mode 100644 index e753ea2..0000000 Binary files a/images/jpg/b_9.jpg and /dev/null differ diff --git a/images/jpg/b_draw.jpg b/images/jpg/b_draw.jpg deleted file mode 100644 index 92e234b..0000000 Binary files a/images/jpg/b_draw.jpg and /dev/null differ diff --git a/images/jpg/b_reverse.jpg b/images/jpg/b_reverse.jpg deleted file mode 100644 index 8e593d6..0000000 Binary files a/images/jpg/b_reverse.jpg and /dev/null differ diff --git a/images/jpg/b_skip.jpg b/images/jpg/b_skip.jpg deleted file mode 100644 index 762bc36..0000000 Binary files a/images/jpg/b_skip.jpg and /dev/null differ diff --git a/images/jpg/colorchooser.jpg b/images/jpg/colorchooser.jpg deleted file mode 100644 index a5793ac..0000000 Binary files a/images/jpg/colorchooser.jpg and /dev/null differ diff --git a/images/jpg/draw_four.jpg b/images/jpg/draw_four.jpg deleted file mode 100644 index 3474002..0000000 Binary files a/images/jpg/draw_four.jpg and /dev/null differ diff --git a/images/jpg/g_0.jpg b/images/jpg/g_0.jpg deleted file mode 100644 index 01ece18..0000000 Binary files a/images/jpg/g_0.jpg and /dev/null differ diff --git a/images/jpg/g_1.jpg b/images/jpg/g_1.jpg deleted file mode 100644 index b84d80c..0000000 Binary files a/images/jpg/g_1.jpg and /dev/null differ diff --git a/images/jpg/g_2.jpg b/images/jpg/g_2.jpg deleted file mode 100644 index f009fff..0000000 Binary files a/images/jpg/g_2.jpg and /dev/null differ diff --git a/images/jpg/g_3.jpg b/images/jpg/g_3.jpg deleted file mode 100644 index a48fa89..0000000 Binary files a/images/jpg/g_3.jpg and /dev/null differ diff --git a/images/jpg/g_4.jpg b/images/jpg/g_4.jpg deleted file mode 100644 index 58fa959..0000000 Binary files a/images/jpg/g_4.jpg and /dev/null differ diff --git a/images/jpg/g_5.jpg b/images/jpg/g_5.jpg deleted file mode 100644 index f3f508f..0000000 Binary files a/images/jpg/g_5.jpg and /dev/null differ diff --git a/images/jpg/g_6.jpg b/images/jpg/g_6.jpg deleted file mode 100644 index 4b84eff..0000000 Binary files a/images/jpg/g_6.jpg and /dev/null differ diff --git a/images/jpg/g_7.jpg b/images/jpg/g_7.jpg deleted file mode 100644 index 78ca3c5..0000000 Binary files a/images/jpg/g_7.jpg and /dev/null differ diff --git a/images/jpg/g_8.jpg b/images/jpg/g_8.jpg deleted file mode 100644 index 16c2a82..0000000 Binary files a/images/jpg/g_8.jpg and /dev/null differ diff --git a/images/jpg/g_9.jpg b/images/jpg/g_9.jpg deleted file mode 100644 index aba66e0..0000000 Binary files a/images/jpg/g_9.jpg and /dev/null differ diff --git a/images/jpg/g_draw.jpg b/images/jpg/g_draw.jpg deleted file mode 100644 index 3de8513..0000000 Binary files a/images/jpg/g_draw.jpg and /dev/null differ diff --git a/images/jpg/g_reverse.jpg b/images/jpg/g_reverse.jpg deleted file mode 100644 index b6cd82f..0000000 Binary files a/images/jpg/g_reverse.jpg and /dev/null differ diff --git a/images/jpg/g_skip.jpg b/images/jpg/g_skip.jpg deleted file mode 100644 index be98d12..0000000 Binary files a/images/jpg/g_skip.jpg and /dev/null differ diff --git a/images/jpg/r_0.jpg b/images/jpg/r_0.jpg deleted file mode 100644 index efe1682..0000000 Binary files a/images/jpg/r_0.jpg and /dev/null differ diff --git a/images/jpg/r_1.jpg b/images/jpg/r_1.jpg deleted file mode 100644 index 99665c8..0000000 Binary files a/images/jpg/r_1.jpg and /dev/null differ diff --git a/images/jpg/r_2.jpg b/images/jpg/r_2.jpg deleted file mode 100644 index bf20299..0000000 Binary files a/images/jpg/r_2.jpg and /dev/null differ diff --git a/images/jpg/r_3.jpg b/images/jpg/r_3.jpg deleted file mode 100644 index c53a9c8..0000000 Binary files a/images/jpg/r_3.jpg and /dev/null differ diff --git a/images/jpg/r_4.jpg b/images/jpg/r_4.jpg deleted file mode 100644 index d38af6e..0000000 Binary files a/images/jpg/r_4.jpg and /dev/null differ diff --git a/images/jpg/r_5.jpg b/images/jpg/r_5.jpg deleted file mode 100644 index 39bd3dc..0000000 Binary files a/images/jpg/r_5.jpg and /dev/null differ diff --git a/images/jpg/r_6.jpg b/images/jpg/r_6.jpg deleted file mode 100644 index 6a5ed8a..0000000 Binary files a/images/jpg/r_6.jpg and /dev/null differ diff --git a/images/jpg/r_7.jpg b/images/jpg/r_7.jpg deleted file mode 100644 index 862dea3..0000000 Binary files a/images/jpg/r_7.jpg and /dev/null differ diff --git a/images/jpg/r_8.jpg b/images/jpg/r_8.jpg deleted file mode 100644 index de039ef..0000000 Binary files a/images/jpg/r_8.jpg and /dev/null differ diff --git a/images/jpg/r_9.jpg b/images/jpg/r_9.jpg deleted file mode 100644 index aed52d8..0000000 Binary files a/images/jpg/r_9.jpg and /dev/null differ diff --git a/images/jpg/r_draw.jpg b/images/jpg/r_draw.jpg deleted file mode 100644 index 00ebb75..0000000 Binary files a/images/jpg/r_draw.jpg and /dev/null differ diff --git a/images/jpg/r_reverse.jpg b/images/jpg/r_reverse.jpg deleted file mode 100644 index ac2562c..0000000 Binary files a/images/jpg/r_reverse.jpg and /dev/null differ diff --git a/images/jpg/r_skip.jpg b/images/jpg/r_skip.jpg deleted file mode 100644 index 68c9bb6..0000000 Binary files a/images/jpg/r_skip.jpg and /dev/null differ diff --git a/images/jpg/y_0.jpg b/images/jpg/y_0.jpg deleted file mode 100644 index ffa8ff9..0000000 Binary files a/images/jpg/y_0.jpg and /dev/null differ diff --git a/images/jpg/y_1.jpg b/images/jpg/y_1.jpg deleted file mode 100644 index c0d642b..0000000 Binary files a/images/jpg/y_1.jpg and /dev/null differ diff --git a/images/jpg/y_2.jpg b/images/jpg/y_2.jpg deleted file mode 100644 index 40da9b3..0000000 Binary files a/images/jpg/y_2.jpg and /dev/null differ diff --git a/images/jpg/y_3.jpg b/images/jpg/y_3.jpg deleted file mode 100644 index a66ba59..0000000 Binary files a/images/jpg/y_3.jpg and /dev/null differ diff --git a/images/jpg/y_4.jpg b/images/jpg/y_4.jpg deleted file mode 100644 index 124126f..0000000 Binary files a/images/jpg/y_4.jpg and /dev/null differ diff --git a/images/jpg/y_5.jpg b/images/jpg/y_5.jpg deleted file mode 100644 index ee67566..0000000 Binary files a/images/jpg/y_5.jpg and /dev/null differ diff --git a/images/jpg/y_6.jpg b/images/jpg/y_6.jpg deleted file mode 100644 index 10dff5a..0000000 Binary files a/images/jpg/y_6.jpg and /dev/null differ diff --git a/images/jpg/y_7.jpg b/images/jpg/y_7.jpg deleted file mode 100644 index 379c34a..0000000 Binary files a/images/jpg/y_7.jpg and /dev/null differ diff --git a/images/jpg/y_8.jpg b/images/jpg/y_8.jpg deleted file mode 100644 index f220e34..0000000 Binary files a/images/jpg/y_8.jpg and /dev/null differ diff --git a/images/jpg/y_9.jpg b/images/jpg/y_9.jpg deleted file mode 100644 index 82afb10..0000000 Binary files a/images/jpg/y_9.jpg and /dev/null differ diff --git a/images/jpg/y_draw.jpg b/images/jpg/y_draw.jpg deleted file mode 100644 index 88eb833..0000000 Binary files a/images/jpg/y_draw.jpg and /dev/null differ diff --git a/images/jpg/y_reverse.jpg b/images/jpg/y_reverse.jpg deleted file mode 100644 index c37fefb..0000000 Binary files a/images/jpg/y_reverse.jpg and /dev/null differ diff --git a/images/jpg/y_skip.jpg b/images/jpg/y_skip.jpg deleted file mode 100644 index b4fae71..0000000 Binary files a/images/jpg/y_skip.jpg and /dev/null differ diff --git a/images/png/b_0.png b/images/png/b_0.png deleted file mode 100644 index 6f2b3f0..0000000 Binary files a/images/png/b_0.png and /dev/null differ diff --git a/images/png/b_1.png b/images/png/b_1.png deleted file mode 100644 index 2ef5867..0000000 Binary files a/images/png/b_1.png and /dev/null differ diff --git a/images/png/b_2.png b/images/png/b_2.png deleted file mode 100644 index 3aad78a..0000000 Binary files a/images/png/b_2.png and /dev/null differ diff --git a/images/png/b_3.png b/images/png/b_3.png deleted file mode 100644 index e4c5221..0000000 Binary files a/images/png/b_3.png and /dev/null differ diff --git a/images/png/b_4.png b/images/png/b_4.png deleted file mode 100644 index ec94357..0000000 Binary files a/images/png/b_4.png and /dev/null differ diff --git a/images/png/b_5.png b/images/png/b_5.png deleted file mode 100644 index 46f6dc5..0000000 Binary files a/images/png/b_5.png and /dev/null differ diff --git a/images/png/b_6.png b/images/png/b_6.png deleted file mode 100644 index 7de3cad..0000000 Binary files a/images/png/b_6.png and /dev/null differ diff --git a/images/png/b_7.png b/images/png/b_7.png deleted file mode 100644 index 25c213a..0000000 Binary files a/images/png/b_7.png and /dev/null differ diff --git a/images/png/b_8.png b/images/png/b_8.png deleted file mode 100644 index 3f05237..0000000 Binary files a/images/png/b_8.png and /dev/null differ diff --git a/images/png/b_9.png b/images/png/b_9.png deleted file mode 100644 index 744249f..0000000 Binary files a/images/png/b_9.png and /dev/null differ diff --git a/images/png/b_draw.png b/images/png/b_draw.png deleted file mode 100644 index cc62931..0000000 Binary files a/images/png/b_draw.png and /dev/null differ diff --git a/images/png/b_reverse.png b/images/png/b_reverse.png deleted file mode 100644 index 20f5cae..0000000 Binary files a/images/png/b_reverse.png and /dev/null differ diff --git a/images/png/b_skip.png b/images/png/b_skip.png deleted file mode 100644 index 56d83aa..0000000 Binary files a/images/png/b_skip.png and /dev/null differ diff --git a/images/png/colorchooser.png b/images/png/colorchooser.png deleted file mode 100644 index 365fe13..0000000 Binary files a/images/png/colorchooser.png and /dev/null differ diff --git a/images/png/draw_four.png b/images/png/draw_four.png deleted file mode 100644 index edd4359..0000000 Binary files a/images/png/draw_four.png and /dev/null differ diff --git a/images/png/g_0.png b/images/png/g_0.png deleted file mode 100644 index b4ee30c..0000000 Binary files a/images/png/g_0.png and /dev/null differ diff --git a/images/png/g_1.png b/images/png/g_1.png deleted file mode 100644 index 2c998a9..0000000 Binary files a/images/png/g_1.png and /dev/null differ diff --git a/images/png/g_2.png b/images/png/g_2.png deleted file mode 100644 index 1b5faa5..0000000 Binary files a/images/png/g_2.png and /dev/null differ diff --git a/images/png/g_3.png b/images/png/g_3.png deleted file mode 100644 index dd2407c..0000000 Binary files a/images/png/g_3.png and /dev/null differ diff --git a/images/png/g_4.png b/images/png/g_4.png deleted file mode 100644 index 31517d8..0000000 Binary files a/images/png/g_4.png and /dev/null differ diff --git a/images/png/g_5.png b/images/png/g_5.png deleted file mode 100644 index 0fbc34b..0000000 Binary files a/images/png/g_5.png and /dev/null differ diff --git a/images/png/g_6.png b/images/png/g_6.png deleted file mode 100644 index dbc58ef..0000000 Binary files a/images/png/g_6.png and /dev/null differ diff --git a/images/png/g_7.png b/images/png/g_7.png deleted file mode 100644 index 904b93b..0000000 Binary files a/images/png/g_7.png and /dev/null differ diff --git a/images/png/g_8.png b/images/png/g_8.png deleted file mode 100644 index 41d452d..0000000 Binary files a/images/png/g_8.png and /dev/null differ diff --git a/images/png/g_9.png b/images/png/g_9.png deleted file mode 100644 index 6d14681..0000000 Binary files a/images/png/g_9.png and /dev/null differ diff --git a/images/png/g_draw.png b/images/png/g_draw.png deleted file mode 100644 index 1ab27e3..0000000 Binary files a/images/png/g_draw.png and /dev/null differ diff --git a/images/png/g_reverse.png b/images/png/g_reverse.png deleted file mode 100644 index 79e47ad..0000000 Binary files a/images/png/g_reverse.png and /dev/null differ diff --git a/images/png/g_skip.png b/images/png/g_skip.png deleted file mode 100644 index fc13b83..0000000 Binary files a/images/png/g_skip.png and /dev/null differ diff --git a/images/png/option_bluff.png b/images/png/option_bluff.png deleted file mode 100644 index 9731155..0000000 Binary files a/images/png/option_bluff.png and /dev/null differ diff --git a/images/png/option_draw.png b/images/png/option_draw.png deleted file mode 100644 index c7e4cfa..0000000 Binary files a/images/png/option_draw.png and /dev/null differ diff --git a/images/png/option_draw2.png b/images/png/option_draw2.png deleted file mode 100644 index ffbe6f5..0000000 Binary files a/images/png/option_draw2.png and /dev/null differ diff --git a/images/png/option_info.png b/images/png/option_info.png deleted file mode 100644 index a8e568c..0000000 Binary files a/images/png/option_info.png and /dev/null differ diff --git a/images/png/option_pass.png b/images/png/option_pass.png deleted file mode 100644 index 076d314..0000000 Binary files a/images/png/option_pass.png and /dev/null differ diff --git a/images/png/option_pass2.png b/images/png/option_pass2.png deleted file mode 100644 index 3cc9621..0000000 Binary files a/images/png/option_pass2.png and /dev/null differ diff --git a/images/png/r_0.png b/images/png/r_0.png deleted file mode 100644 index c1d8788..0000000 Binary files a/images/png/r_0.png and /dev/null differ diff --git a/images/png/r_1.png b/images/png/r_1.png deleted file mode 100644 index c644f3f..0000000 Binary files a/images/png/r_1.png and /dev/null differ diff --git a/images/png/r_2.png b/images/png/r_2.png deleted file mode 100644 index a363b7d..0000000 Binary files a/images/png/r_2.png and /dev/null differ diff --git a/images/png/r_3.png b/images/png/r_3.png deleted file mode 100644 index cebf575..0000000 Binary files a/images/png/r_3.png and /dev/null differ diff --git a/images/png/r_4.png b/images/png/r_4.png deleted file mode 100644 index 05958f2..0000000 Binary files a/images/png/r_4.png and /dev/null differ diff --git a/images/png/r_5.png b/images/png/r_5.png deleted file mode 100644 index 3607eb8..0000000 Binary files a/images/png/r_5.png and /dev/null differ diff --git a/images/png/r_6.png b/images/png/r_6.png deleted file mode 100644 index b0be4a2..0000000 Binary files a/images/png/r_6.png and /dev/null differ diff --git a/images/png/r_7.png b/images/png/r_7.png deleted file mode 100644 index 663e26c..0000000 Binary files a/images/png/r_7.png and /dev/null differ diff --git a/images/png/r_8.png b/images/png/r_8.png deleted file mode 100644 index 1ae438f..0000000 Binary files a/images/png/r_8.png and /dev/null differ diff --git a/images/png/r_9.png b/images/png/r_9.png deleted file mode 100644 index dc7799b..0000000 Binary files a/images/png/r_9.png and /dev/null differ diff --git a/images/png/r_draw.png b/images/png/r_draw.png deleted file mode 100644 index 64b9ccd..0000000 Binary files a/images/png/r_draw.png and /dev/null differ diff --git a/images/png/r_reverse.png b/images/png/r_reverse.png deleted file mode 100644 index d1cc84a..0000000 Binary files a/images/png/r_reverse.png and /dev/null differ diff --git a/images/png/r_skip.png b/images/png/r_skip.png deleted file mode 100644 index c0a42b3..0000000 Binary files a/images/png/r_skip.png and /dev/null differ diff --git a/images/png/y_0.png b/images/png/y_0.png deleted file mode 100644 index 69bd151..0000000 Binary files a/images/png/y_0.png and /dev/null differ diff --git a/images/png/y_1.png b/images/png/y_1.png deleted file mode 100644 index 75303aa..0000000 Binary files a/images/png/y_1.png and /dev/null differ diff --git a/images/png/y_2.png b/images/png/y_2.png deleted file mode 100644 index 7180a43..0000000 Binary files a/images/png/y_2.png and /dev/null differ diff --git a/images/png/y_3.png b/images/png/y_3.png deleted file mode 100644 index 6341271..0000000 Binary files a/images/png/y_3.png and /dev/null differ diff --git a/images/png/y_4.png b/images/png/y_4.png deleted file mode 100644 index 038cce3..0000000 Binary files a/images/png/y_4.png and /dev/null differ diff --git a/images/png/y_5.png b/images/png/y_5.png deleted file mode 100644 index 40cd6e6..0000000 Binary files a/images/png/y_5.png and /dev/null differ diff --git a/images/png/y_6.png b/images/png/y_6.png deleted file mode 100644 index d7ee0c1..0000000 Binary files a/images/png/y_6.png and /dev/null differ diff --git a/images/png/y_7.png b/images/png/y_7.png deleted file mode 100644 index f42e64e..0000000 Binary files a/images/png/y_7.png and /dev/null differ diff --git a/images/png/y_8.png b/images/png/y_8.png deleted file mode 100644 index db9073d..0000000 Binary files a/images/png/y_8.png and /dev/null differ diff --git a/images/png/y_9.png b/images/png/y_9.png deleted file mode 100644 index 108122c..0000000 Binary files a/images/png/y_9.png and /dev/null differ diff --git a/images/png/y_draw.png b/images/png/y_draw.png deleted file mode 100644 index 9c5b14b..0000000 Binary files a/images/png/y_draw.png and /dev/null differ diff --git a/images/png/y_reverse.png b/images/png/y_reverse.png deleted file mode 100644 index 5ed3816..0000000 Binary files a/images/png/y_reverse.png and /dev/null differ diff --git a/images/png/y_skip.png b/images/png/y_skip.png deleted file mode 100644 index cca5fd7..0000000 Binary files a/images/png/y_skip.png and /dev/null differ diff --git a/images/png_lowsat/b_0.png b/images/png_lowsat/b_0.png deleted file mode 100644 index 79184a7..0000000 Binary files a/images/png_lowsat/b_0.png and /dev/null differ diff --git a/images/png_lowsat/b_1.png b/images/png_lowsat/b_1.png deleted file mode 100644 index e27034b..0000000 Binary files a/images/png_lowsat/b_1.png and /dev/null differ diff --git a/images/png_lowsat/b_2.png b/images/png_lowsat/b_2.png deleted file mode 100644 index 5117cdb..0000000 Binary files a/images/png_lowsat/b_2.png and /dev/null differ diff --git a/images/png_lowsat/b_3.png b/images/png_lowsat/b_3.png deleted file mode 100644 index 304bef2..0000000 Binary files a/images/png_lowsat/b_3.png and /dev/null differ diff --git a/images/png_lowsat/b_4.png b/images/png_lowsat/b_4.png deleted file mode 100644 index b22aafe..0000000 Binary files a/images/png_lowsat/b_4.png and /dev/null differ diff --git a/images/png_lowsat/b_5.png b/images/png_lowsat/b_5.png deleted file mode 100644 index ad8e2d9..0000000 Binary files a/images/png_lowsat/b_5.png and /dev/null differ diff --git a/images/png_lowsat/b_6.png b/images/png_lowsat/b_6.png deleted file mode 100644 index f3ec00d..0000000 Binary files a/images/png_lowsat/b_6.png and /dev/null differ diff --git a/images/png_lowsat/b_7.png b/images/png_lowsat/b_7.png deleted file mode 100644 index bbaa943..0000000 Binary files a/images/png_lowsat/b_7.png and /dev/null differ diff --git a/images/png_lowsat/b_8.png b/images/png_lowsat/b_8.png deleted file mode 100644 index 6580bd9..0000000 Binary files a/images/png_lowsat/b_8.png and /dev/null differ diff --git a/images/png_lowsat/b_9.png b/images/png_lowsat/b_9.png deleted file mode 100644 index 0a047a5..0000000 Binary files a/images/png_lowsat/b_9.png and /dev/null differ diff --git a/images/png_lowsat/b_draw.png b/images/png_lowsat/b_draw.png deleted file mode 100644 index 4f97093..0000000 Binary files a/images/png_lowsat/b_draw.png and /dev/null differ diff --git a/images/png_lowsat/b_reverse.png b/images/png_lowsat/b_reverse.png deleted file mode 100644 index a2203f2..0000000 Binary files a/images/png_lowsat/b_reverse.png and /dev/null differ diff --git a/images/png_lowsat/b_skip.png b/images/png_lowsat/b_skip.png deleted file mode 100644 index 1028d3a..0000000 Binary files a/images/png_lowsat/b_skip.png and /dev/null differ diff --git a/images/png_lowsat/colorchooser.png b/images/png_lowsat/colorchooser.png deleted file mode 100644 index ef9c70e..0000000 Binary files a/images/png_lowsat/colorchooser.png and /dev/null differ diff --git a/images/png_lowsat/draw_four.png b/images/png_lowsat/draw_four.png deleted file mode 100644 index 80e518d..0000000 Binary files a/images/png_lowsat/draw_four.png and /dev/null differ diff --git a/images/png_lowsat/g_0.png b/images/png_lowsat/g_0.png deleted file mode 100644 index e7bd6ef..0000000 Binary files a/images/png_lowsat/g_0.png and /dev/null differ diff --git a/images/png_lowsat/g_1.png b/images/png_lowsat/g_1.png deleted file mode 100644 index 5a3a838..0000000 Binary files a/images/png_lowsat/g_1.png and /dev/null differ diff --git a/images/png_lowsat/g_2.png b/images/png_lowsat/g_2.png deleted file mode 100644 index 186643d..0000000 Binary files a/images/png_lowsat/g_2.png and /dev/null differ diff --git a/images/png_lowsat/g_3.png b/images/png_lowsat/g_3.png deleted file mode 100644 index de06423..0000000 Binary files a/images/png_lowsat/g_3.png and /dev/null differ diff --git a/images/png_lowsat/g_4.png b/images/png_lowsat/g_4.png deleted file mode 100644 index 6a063f4..0000000 Binary files a/images/png_lowsat/g_4.png and /dev/null differ diff --git a/images/png_lowsat/g_5.png b/images/png_lowsat/g_5.png deleted file mode 100644 index 341507e..0000000 Binary files a/images/png_lowsat/g_5.png and /dev/null differ diff --git a/images/png_lowsat/g_6.png b/images/png_lowsat/g_6.png deleted file mode 100644 index fdc706d..0000000 Binary files a/images/png_lowsat/g_6.png and /dev/null differ diff --git a/images/png_lowsat/g_7.png b/images/png_lowsat/g_7.png deleted file mode 100644 index 4eff73d..0000000 Binary files a/images/png_lowsat/g_7.png and /dev/null differ diff --git a/images/png_lowsat/g_8.png b/images/png_lowsat/g_8.png deleted file mode 100644 index 195b9a3..0000000 Binary files a/images/png_lowsat/g_8.png and /dev/null differ diff --git a/images/png_lowsat/g_9.png b/images/png_lowsat/g_9.png deleted file mode 100644 index 8624548..0000000 Binary files a/images/png_lowsat/g_9.png and /dev/null differ diff --git a/images/png_lowsat/g_draw.png b/images/png_lowsat/g_draw.png deleted file mode 100644 index c223ced..0000000 Binary files a/images/png_lowsat/g_draw.png and /dev/null differ diff --git a/images/png_lowsat/g_reverse.png b/images/png_lowsat/g_reverse.png deleted file mode 100644 index 869c5c6..0000000 Binary files a/images/png_lowsat/g_reverse.png and /dev/null differ diff --git a/images/png_lowsat/g_skip.png b/images/png_lowsat/g_skip.png deleted file mode 100644 index 527bf65..0000000 Binary files a/images/png_lowsat/g_skip.png and /dev/null differ diff --git a/images/png_lowsat/r_0.png b/images/png_lowsat/r_0.png deleted file mode 100644 index 0e4130d..0000000 Binary files a/images/png_lowsat/r_0.png and /dev/null differ diff --git a/images/png_lowsat/r_1.png b/images/png_lowsat/r_1.png deleted file mode 100644 index ccef019..0000000 Binary files a/images/png_lowsat/r_1.png and /dev/null differ diff --git a/images/png_lowsat/r_2.png b/images/png_lowsat/r_2.png deleted file mode 100644 index 264166b..0000000 Binary files a/images/png_lowsat/r_2.png and /dev/null differ diff --git a/images/png_lowsat/r_3.png b/images/png_lowsat/r_3.png deleted file mode 100644 index 4e28cdf..0000000 Binary files a/images/png_lowsat/r_3.png and /dev/null differ diff --git a/images/png_lowsat/r_4.png b/images/png_lowsat/r_4.png deleted file mode 100644 index e03d37d..0000000 Binary files a/images/png_lowsat/r_4.png and /dev/null differ diff --git a/images/png_lowsat/r_5.png b/images/png_lowsat/r_5.png deleted file mode 100644 index c0bd1cd..0000000 Binary files a/images/png_lowsat/r_5.png and /dev/null differ diff --git a/images/png_lowsat/r_6.png b/images/png_lowsat/r_6.png deleted file mode 100644 index 89c78d6..0000000 Binary files a/images/png_lowsat/r_6.png and /dev/null differ diff --git a/images/png_lowsat/r_7.png b/images/png_lowsat/r_7.png deleted file mode 100644 index 0dd84cd..0000000 Binary files a/images/png_lowsat/r_7.png and /dev/null differ diff --git a/images/png_lowsat/r_8.png b/images/png_lowsat/r_8.png deleted file mode 100644 index c21b9bf..0000000 Binary files a/images/png_lowsat/r_8.png and /dev/null differ diff --git a/images/png_lowsat/r_9.png b/images/png_lowsat/r_9.png deleted file mode 100644 index 9e51a85..0000000 Binary files a/images/png_lowsat/r_9.png and /dev/null differ diff --git a/images/png_lowsat/r_draw.png b/images/png_lowsat/r_draw.png deleted file mode 100644 index 852729f..0000000 Binary files a/images/png_lowsat/r_draw.png and /dev/null differ diff --git a/images/png_lowsat/r_reverse.png b/images/png_lowsat/r_reverse.png deleted file mode 100644 index 269efe0..0000000 Binary files a/images/png_lowsat/r_reverse.png and /dev/null differ diff --git a/images/png_lowsat/r_skip.png b/images/png_lowsat/r_skip.png deleted file mode 100644 index 6c5296a..0000000 Binary files a/images/png_lowsat/r_skip.png and /dev/null differ diff --git a/images/png_lowsat/y_0.png b/images/png_lowsat/y_0.png deleted file mode 100644 index 120827c..0000000 Binary files a/images/png_lowsat/y_0.png and /dev/null differ diff --git a/images/png_lowsat/y_1.png b/images/png_lowsat/y_1.png deleted file mode 100644 index 9b342c5..0000000 Binary files a/images/png_lowsat/y_1.png and /dev/null differ diff --git a/images/png_lowsat/y_2.png b/images/png_lowsat/y_2.png deleted file mode 100644 index 33ec56c..0000000 Binary files a/images/png_lowsat/y_2.png and /dev/null differ diff --git a/images/png_lowsat/y_3.png b/images/png_lowsat/y_3.png deleted file mode 100644 index 96d6c98..0000000 Binary files a/images/png_lowsat/y_3.png and /dev/null differ diff --git a/images/png_lowsat/y_4.png b/images/png_lowsat/y_4.png deleted file mode 100644 index 492e6c2..0000000 Binary files a/images/png_lowsat/y_4.png and /dev/null differ diff --git a/images/png_lowsat/y_5.png b/images/png_lowsat/y_5.png deleted file mode 100644 index 845a8a6..0000000 Binary files a/images/png_lowsat/y_5.png and /dev/null differ diff --git a/images/png_lowsat/y_6.png b/images/png_lowsat/y_6.png deleted file mode 100644 index 1b1960e..0000000 Binary files a/images/png_lowsat/y_6.png and /dev/null differ diff --git a/images/png_lowsat/y_7.png b/images/png_lowsat/y_7.png deleted file mode 100644 index 60149b9..0000000 Binary files a/images/png_lowsat/y_7.png and /dev/null differ diff --git a/images/png_lowsat/y_8.png b/images/png_lowsat/y_8.png deleted file mode 100644 index ac61ac3..0000000 Binary files a/images/png_lowsat/y_8.png and /dev/null differ diff --git a/images/png_lowsat/y_9.png b/images/png_lowsat/y_9.png deleted file mode 100644 index ca8b28a..0000000 Binary files a/images/png_lowsat/y_9.png and /dev/null differ diff --git a/images/png_lowsat/y_draw.png b/images/png_lowsat/y_draw.png deleted file mode 100644 index 93f5ff7..0000000 Binary files a/images/png_lowsat/y_draw.png and /dev/null differ diff --git a/images/png_lowsat/y_reverse.png b/images/png_lowsat/y_reverse.png deleted file mode 100644 index 66fb71f..0000000 Binary files a/images/png_lowsat/y_reverse.png and /dev/null differ diff --git a/images/png_lowsat/y_skip.png b/images/png_lowsat/y_skip.png deleted file mode 100644 index e9b0548..0000000 Binary files a/images/png_lowsat/y_skip.png and /dev/null differ diff --git a/images/source.txt b/images/source.txt deleted file mode 100644 index db33e86..0000000 --- a/images/source.txt +++ /dev/null @@ -1 +0,0 @@ -https://commons.wikimedia.org/wiki/File:UNO_cards_deck.svg diff --git a/images/svg/b_0.svg b/images/svg/b_0.svg deleted file mode 100644 index 4edf4d2..0000000 --- a/images/svg/b_0.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/b_1.svg b/images/svg/b_1.svg deleted file mode 100644 index 10b7b34..0000000 --- a/images/svg/b_1.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/b_2.svg b/images/svg/b_2.svg deleted file mode 100644 index c431bde..0000000 --- a/images/svg/b_2.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/b_3.svg b/images/svg/b_3.svg deleted file mode 100644 index b05de30..0000000 --- a/images/svg/b_3.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/b_4.svg b/images/svg/b_4.svg deleted file mode 100644 index 4ad3942..0000000 --- a/images/svg/b_4.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/b_5.svg b/images/svg/b_5.svg deleted file mode 100644 index 5ac8867..0000000 --- a/images/svg/b_5.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/b_6.svg b/images/svg/b_6.svg deleted file mode 100644 index 2b50369..0000000 --- a/images/svg/b_6.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/b_7.svg b/images/svg/b_7.svg deleted file mode 100644 index e354763..0000000 --- a/images/svg/b_7.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/b_8.svg b/images/svg/b_8.svg deleted file mode 100644 index f2b7435..0000000 --- a/images/svg/b_8.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/b_9.svg b/images/svg/b_9.svg deleted file mode 100644 index 743cad5..0000000 --- a/images/svg/b_9.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/b_draw.svg b/images/svg/b_draw.svg deleted file mode 100644 index f86de73..0000000 --- a/images/svg/b_draw.svg +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - diff --git a/images/svg/b_reverse.svg b/images/svg/b_reverse.svg deleted file mode 100644 index 5004456..0000000 --- a/images/svg/b_reverse.svg +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - diff --git a/images/svg/b_skip.svg b/images/svg/b_skip.svg deleted file mode 100644 index 69d1a05..0000000 --- a/images/svg/b_skip.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/colorchooser.svg b/images/svg/colorchooser.svg deleted file mode 100644 index 728ec0c..0000000 --- a/images/svg/colorchooser.svg +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/images/svg/draw_four.svg b/images/svg/draw_four.svg deleted file mode 100644 index 7bfdae4..0000000 --- a/images/svg/draw_four.svg +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/images/svg/g_0.svg b/images/svg/g_0.svg deleted file mode 100644 index 987b401..0000000 --- a/images/svg/g_0.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/g_1.svg b/images/svg/g_1.svg deleted file mode 100644 index 70fb3c3..0000000 --- a/images/svg/g_1.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/g_2.svg b/images/svg/g_2.svg deleted file mode 100644 index 5679ff8..0000000 --- a/images/svg/g_2.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/g_3.svg b/images/svg/g_3.svg deleted file mode 100644 index 515db1e..0000000 --- a/images/svg/g_3.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/g_4.svg b/images/svg/g_4.svg deleted file mode 100644 index c52a9ef..0000000 --- a/images/svg/g_4.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/g_5.svg b/images/svg/g_5.svg deleted file mode 100644 index d2e9c62..0000000 --- a/images/svg/g_5.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/g_6.svg b/images/svg/g_6.svg deleted file mode 100644 index 4117bcb..0000000 --- a/images/svg/g_6.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/g_7.svg b/images/svg/g_7.svg deleted file mode 100644 index 370b15e..0000000 --- a/images/svg/g_7.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/g_8.svg b/images/svg/g_8.svg deleted file mode 100644 index f34f8b3..0000000 --- a/images/svg/g_8.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/g_9.svg b/images/svg/g_9.svg deleted file mode 100644 index 1c2602c..0000000 --- a/images/svg/g_9.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/g_draw.svg b/images/svg/g_draw.svg deleted file mode 100644 index e245b0c..0000000 --- a/images/svg/g_draw.svg +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - diff --git a/images/svg/g_reverse.svg b/images/svg/g_reverse.svg deleted file mode 100644 index cb706fb..0000000 --- a/images/svg/g_reverse.svg +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - diff --git a/images/svg/g_skip.svg b/images/svg/g_skip.svg deleted file mode 100644 index 4314a8e..0000000 --- a/images/svg/g_skip.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_0.svg b/images/svg/r_0.svg deleted file mode 100644 index 04803e8..0000000 --- a/images/svg/r_0.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_1.svg b/images/svg/r_1.svg deleted file mode 100644 index 453a06f..0000000 --- a/images/svg/r_1.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_2.svg b/images/svg/r_2.svg deleted file mode 100644 index 8e27640..0000000 --- a/images/svg/r_2.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_3.svg b/images/svg/r_3.svg deleted file mode 100644 index eb1e3bc..0000000 --- a/images/svg/r_3.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_4.svg b/images/svg/r_4.svg deleted file mode 100644 index d71ac7a..0000000 --- a/images/svg/r_4.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_5.svg b/images/svg/r_5.svg deleted file mode 100644 index d78f261..0000000 --- a/images/svg/r_5.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_6.svg b/images/svg/r_6.svg deleted file mode 100644 index 5cf23e5..0000000 --- a/images/svg/r_6.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_7.svg b/images/svg/r_7.svg deleted file mode 100644 index 013e933..0000000 --- a/images/svg/r_7.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_8.svg b/images/svg/r_8.svg deleted file mode 100644 index 00ab479..0000000 --- a/images/svg/r_8.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_9.svg b/images/svg/r_9.svg deleted file mode 100644 index 38881b6..0000000 --- a/images/svg/r_9.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/r_draw.svg b/images/svg/r_draw.svg deleted file mode 100644 index 73b43f4..0000000 --- a/images/svg/r_draw.svg +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - diff --git a/images/svg/r_reverse.svg b/images/svg/r_reverse.svg deleted file mode 100644 index 1dd8d13..0000000 --- a/images/svg/r_reverse.svg +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - diff --git a/images/svg/r_skip.svg b/images/svg/r_skip.svg deleted file mode 100644 index dc5b362..0000000 --- a/images/svg/r_skip.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_0.svg b/images/svg/y_0.svg deleted file mode 100644 index 07a7217..0000000 --- a/images/svg/y_0.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_1.svg b/images/svg/y_1.svg deleted file mode 100644 index c96416b..0000000 --- a/images/svg/y_1.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_2.svg b/images/svg/y_2.svg deleted file mode 100644 index 5717a89..0000000 --- a/images/svg/y_2.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_3.svg b/images/svg/y_3.svg deleted file mode 100644 index 72c0f29..0000000 --- a/images/svg/y_3.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_4.svg b/images/svg/y_4.svg deleted file mode 100644 index 8a4316d..0000000 --- a/images/svg/y_4.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_5.svg b/images/svg/y_5.svg deleted file mode 100644 index 55c5f11..0000000 --- a/images/svg/y_5.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_6.svg b/images/svg/y_6.svg deleted file mode 100644 index 5fdf529..0000000 --- a/images/svg/y_6.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_7.svg b/images/svg/y_7.svg deleted file mode 100644 index e04a0c1..0000000 --- a/images/svg/y_7.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_8.svg b/images/svg/y_8.svg deleted file mode 100644 index a1da081..0000000 --- a/images/svg/y_8.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_9.svg b/images/svg/y_9.svg deleted file mode 100644 index 34f8389..0000000 --- a/images/svg/y_9.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/svg/y_draw.svg b/images/svg/y_draw.svg deleted file mode 100644 index ffe743b..0000000 --- a/images/svg/y_draw.svg +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - diff --git a/images/svg/y_reverse.svg b/images/svg/y_reverse.svg deleted file mode 100644 index d57f8ac..0000000 --- a/images/svg/y_reverse.svg +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - diff --git a/images/svg/y_skip.svg b/images/svg/y_skip.svg deleted file mode 100644 index 96b353f..0000000 --- a/images/svg/y_skip.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/images/thumb/b_0.jpg b/images/thumb/b_0.jpg deleted file mode 100644 index a45820e..0000000 Binary files a/images/thumb/b_0.jpg and /dev/null differ diff --git a/images/thumb/b_1.jpg b/images/thumb/b_1.jpg deleted file mode 100644 index 7f85f22..0000000 Binary files a/images/thumb/b_1.jpg and /dev/null differ diff --git a/images/thumb/b_2.jpg b/images/thumb/b_2.jpg deleted file mode 100644 index cac1288..0000000 Binary files a/images/thumb/b_2.jpg and /dev/null differ diff --git a/images/thumb/b_3.jpg b/images/thumb/b_3.jpg deleted file mode 100644 index 3be34c9..0000000 Binary files a/images/thumb/b_3.jpg and /dev/null differ diff --git a/images/thumb/b_4.jpg b/images/thumb/b_4.jpg deleted file mode 100644 index cd09ae8..0000000 Binary files a/images/thumb/b_4.jpg and /dev/null differ diff --git a/images/thumb/b_5.jpg b/images/thumb/b_5.jpg deleted file mode 100644 index 2629bed..0000000 Binary files a/images/thumb/b_5.jpg and /dev/null differ diff --git a/images/thumb/b_6.jpg b/images/thumb/b_6.jpg deleted file mode 100644 index c620fea..0000000 Binary files a/images/thumb/b_6.jpg and /dev/null differ diff --git a/images/thumb/b_7.jpg b/images/thumb/b_7.jpg deleted file mode 100644 index c4b1982..0000000 Binary files a/images/thumb/b_7.jpg and /dev/null differ diff --git a/images/thumb/b_8.jpg b/images/thumb/b_8.jpg deleted file mode 100644 index d7738a8..0000000 Binary files a/images/thumb/b_8.jpg and /dev/null differ diff --git a/images/thumb/b_9.jpg b/images/thumb/b_9.jpg deleted file mode 100644 index 2b04594..0000000 Binary files a/images/thumb/b_9.jpg and /dev/null differ diff --git a/images/thumb/b_draw.jpg b/images/thumb/b_draw.jpg deleted file mode 100644 index b0f8a41..0000000 Binary files a/images/thumb/b_draw.jpg and /dev/null differ diff --git a/images/thumb/b_reverse.jpg b/images/thumb/b_reverse.jpg deleted file mode 100644 index e81c28f..0000000 Binary files a/images/thumb/b_reverse.jpg and /dev/null differ diff --git a/images/thumb/b_skip.jpg b/images/thumb/b_skip.jpg deleted file mode 100644 index 0940e3f..0000000 Binary files a/images/thumb/b_skip.jpg and /dev/null differ diff --git a/images/thumb/colorchooser.jpg b/images/thumb/colorchooser.jpg deleted file mode 100644 index 67ff2ff..0000000 Binary files a/images/thumb/colorchooser.jpg and /dev/null differ diff --git a/images/thumb/draw_four.jpg b/images/thumb/draw_four.jpg deleted file mode 100644 index ae5aa21..0000000 Binary files a/images/thumb/draw_four.jpg and /dev/null differ diff --git a/images/thumb/g_0.jpg b/images/thumb/g_0.jpg deleted file mode 100644 index 7c8fd97..0000000 Binary files a/images/thumb/g_0.jpg and /dev/null differ diff --git a/images/thumb/g_1.jpg b/images/thumb/g_1.jpg deleted file mode 100644 index 3d8b927..0000000 Binary files a/images/thumb/g_1.jpg and /dev/null differ diff --git a/images/thumb/g_2.jpg b/images/thumb/g_2.jpg deleted file mode 100644 index f527986..0000000 Binary files a/images/thumb/g_2.jpg and /dev/null differ diff --git a/images/thumb/g_3.jpg b/images/thumb/g_3.jpg deleted file mode 100644 index 6669244..0000000 Binary files a/images/thumb/g_3.jpg and /dev/null differ diff --git a/images/thumb/g_4.jpg b/images/thumb/g_4.jpg deleted file mode 100644 index 66ea924..0000000 Binary files a/images/thumb/g_4.jpg and /dev/null differ diff --git a/images/thumb/g_5.jpg b/images/thumb/g_5.jpg deleted file mode 100644 index 10a89db..0000000 Binary files a/images/thumb/g_5.jpg and /dev/null differ diff --git a/images/thumb/g_6.jpg b/images/thumb/g_6.jpg deleted file mode 100644 index c4e005b..0000000 Binary files a/images/thumb/g_6.jpg and /dev/null differ diff --git a/images/thumb/g_7.jpg b/images/thumb/g_7.jpg deleted file mode 100644 index 79e205c..0000000 Binary files a/images/thumb/g_7.jpg and /dev/null differ diff --git a/images/thumb/g_8.jpg b/images/thumb/g_8.jpg deleted file mode 100644 index bd3eba1..0000000 Binary files a/images/thumb/g_8.jpg and /dev/null differ diff --git a/images/thumb/g_9.jpg b/images/thumb/g_9.jpg deleted file mode 100644 index 403dc25..0000000 Binary files a/images/thumb/g_9.jpg and /dev/null differ diff --git a/images/thumb/g_draw.jpg b/images/thumb/g_draw.jpg deleted file mode 100644 index c082bfe..0000000 Binary files a/images/thumb/g_draw.jpg and /dev/null differ diff --git a/images/thumb/g_reverse.jpg b/images/thumb/g_reverse.jpg deleted file mode 100644 index d655b20..0000000 Binary files a/images/thumb/g_reverse.jpg and /dev/null differ diff --git a/images/thumb/g_skip.jpg b/images/thumb/g_skip.jpg deleted file mode 100644 index 8ab1e1b..0000000 Binary files a/images/thumb/g_skip.jpg and /dev/null differ diff --git a/images/thumb/r_0.jpg b/images/thumb/r_0.jpg deleted file mode 100644 index 5476f83..0000000 Binary files a/images/thumb/r_0.jpg and /dev/null differ diff --git a/images/thumb/r_1.jpg b/images/thumb/r_1.jpg deleted file mode 100644 index 81d1486..0000000 Binary files a/images/thumb/r_1.jpg and /dev/null differ diff --git a/images/thumb/r_2.jpg b/images/thumb/r_2.jpg deleted file mode 100644 index 5cae25f..0000000 Binary files a/images/thumb/r_2.jpg and /dev/null differ diff --git a/images/thumb/r_3.jpg b/images/thumb/r_3.jpg deleted file mode 100644 index 8aec569..0000000 Binary files a/images/thumb/r_3.jpg and /dev/null differ diff --git a/images/thumb/r_4.jpg b/images/thumb/r_4.jpg deleted file mode 100644 index f22de30..0000000 Binary files a/images/thumb/r_4.jpg and /dev/null differ diff --git a/images/thumb/r_5.jpg b/images/thumb/r_5.jpg deleted file mode 100644 index 6a4e0da..0000000 Binary files a/images/thumb/r_5.jpg and /dev/null differ diff --git a/images/thumb/r_6.jpg b/images/thumb/r_6.jpg deleted file mode 100644 index 7e6f0d1..0000000 Binary files a/images/thumb/r_6.jpg and /dev/null differ diff --git a/images/thumb/r_7.jpg b/images/thumb/r_7.jpg deleted file mode 100644 index 23a13f4..0000000 Binary files a/images/thumb/r_7.jpg and /dev/null differ diff --git a/images/thumb/r_8.jpg b/images/thumb/r_8.jpg deleted file mode 100644 index a281d5e..0000000 Binary files a/images/thumb/r_8.jpg and /dev/null differ diff --git a/images/thumb/r_9.jpg b/images/thumb/r_9.jpg deleted file mode 100644 index 66d1995..0000000 Binary files a/images/thumb/r_9.jpg and /dev/null differ diff --git a/images/thumb/r_draw.jpg b/images/thumb/r_draw.jpg deleted file mode 100644 index f02ed4e..0000000 Binary files a/images/thumb/r_draw.jpg and /dev/null differ diff --git a/images/thumb/r_reverse.jpg b/images/thumb/r_reverse.jpg deleted file mode 100644 index 78c43a8..0000000 Binary files a/images/thumb/r_reverse.jpg and /dev/null differ diff --git a/images/thumb/r_skip.jpg b/images/thumb/r_skip.jpg deleted file mode 100644 index 40c2a1a..0000000 Binary files a/images/thumb/r_skip.jpg and /dev/null differ diff --git a/images/thumb/y_0.jpg b/images/thumb/y_0.jpg deleted file mode 100644 index b50f47c..0000000 Binary files a/images/thumb/y_0.jpg and /dev/null differ diff --git a/images/thumb/y_1.jpg b/images/thumb/y_1.jpg deleted file mode 100644 index edc1af8..0000000 Binary files a/images/thumb/y_1.jpg and /dev/null differ diff --git a/images/thumb/y_2.jpg b/images/thumb/y_2.jpg deleted file mode 100644 index 2ae91a9..0000000 Binary files a/images/thumb/y_2.jpg and /dev/null differ diff --git a/images/thumb/y_3.jpg b/images/thumb/y_3.jpg deleted file mode 100644 index fe73c2f..0000000 Binary files a/images/thumb/y_3.jpg and /dev/null differ diff --git a/images/thumb/y_4.jpg b/images/thumb/y_4.jpg deleted file mode 100644 index c1a25af..0000000 Binary files a/images/thumb/y_4.jpg and /dev/null differ diff --git a/images/thumb/y_5.jpg b/images/thumb/y_5.jpg deleted file mode 100644 index 41523f7..0000000 Binary files a/images/thumb/y_5.jpg and /dev/null differ diff --git a/images/thumb/y_6.jpg b/images/thumb/y_6.jpg deleted file mode 100644 index c850582..0000000 Binary files a/images/thumb/y_6.jpg and /dev/null differ diff --git a/images/thumb/y_7.jpg b/images/thumb/y_7.jpg deleted file mode 100644 index af9e818..0000000 Binary files a/images/thumb/y_7.jpg and /dev/null differ diff --git a/images/thumb/y_8.jpg b/images/thumb/y_8.jpg deleted file mode 100644 index b7980d9..0000000 Binary files a/images/thumb/y_8.jpg and /dev/null differ diff --git a/images/thumb/y_9.jpg b/images/thumb/y_9.jpg deleted file mode 100644 index faea4bb..0000000 Binary files a/images/thumb/y_9.jpg and /dev/null differ diff --git a/images/thumb/y_draw.jpg b/images/thumb/y_draw.jpg deleted file mode 100644 index 66b5baf..0000000 Binary files a/images/thumb/y_draw.jpg and /dev/null differ diff --git a/images/thumb/y_reverse.jpg b/images/thumb/y_reverse.jpg deleted file mode 100644 index de1657c..0000000 Binary files a/images/thumb/y_reverse.jpg and /dev/null differ diff --git a/images/thumb/y_skip.jpg b/images/thumb/y_skip.jpg deleted file mode 100644 index 9020ff4..0000000 Binary files a/images/thumb/y_skip.jpg and /dev/null differ diff --git a/images/webp/b_0.webp b/images/webp/b_0.webp deleted file mode 100644 index 420eb52..0000000 Binary files a/images/webp/b_0.webp and /dev/null differ diff --git a/images/webp/b_1.webp b/images/webp/b_1.webp deleted file mode 100644 index 84e5a58..0000000 Binary files a/images/webp/b_1.webp and /dev/null differ diff --git a/images/webp/b_2.webp b/images/webp/b_2.webp deleted file mode 100644 index 3e1639b..0000000 Binary files a/images/webp/b_2.webp and /dev/null differ diff --git a/images/webp/b_3.webp b/images/webp/b_3.webp deleted file mode 100644 index 55924c0..0000000 Binary files a/images/webp/b_3.webp and /dev/null differ diff --git a/images/webp/b_4.webp b/images/webp/b_4.webp deleted file mode 100644 index de9d39f..0000000 Binary files a/images/webp/b_4.webp and /dev/null differ diff --git a/images/webp/b_5.webp b/images/webp/b_5.webp deleted file mode 100644 index c9b7f2d..0000000 Binary files a/images/webp/b_5.webp and /dev/null differ diff --git a/images/webp/b_6.webp b/images/webp/b_6.webp deleted file mode 100644 index 27a6777..0000000 Binary files a/images/webp/b_6.webp and /dev/null differ diff --git a/images/webp/b_7.webp b/images/webp/b_7.webp deleted file mode 100644 index b8e259e..0000000 Binary files a/images/webp/b_7.webp and /dev/null differ diff --git a/images/webp/b_8.webp b/images/webp/b_8.webp deleted file mode 100644 index f5862da..0000000 Binary files a/images/webp/b_8.webp and /dev/null differ diff --git a/images/webp/b_9.webp b/images/webp/b_9.webp deleted file mode 100644 index b173edd..0000000 Binary files a/images/webp/b_9.webp and /dev/null differ diff --git a/images/webp/b_draw.webp b/images/webp/b_draw.webp deleted file mode 100644 index 5cd9285..0000000 Binary files a/images/webp/b_draw.webp and /dev/null differ diff --git a/images/webp/b_reverse.webp b/images/webp/b_reverse.webp deleted file mode 100644 index 4bc8846..0000000 Binary files a/images/webp/b_reverse.webp and /dev/null differ diff --git a/images/webp/b_skip.webp b/images/webp/b_skip.webp deleted file mode 100644 index 3b0a40c..0000000 Binary files a/images/webp/b_skip.webp and /dev/null differ diff --git a/images/webp/colorchooser.webp b/images/webp/colorchooser.webp deleted file mode 100644 index 5254ae5..0000000 Binary files a/images/webp/colorchooser.webp and /dev/null differ diff --git a/images/webp/draw_four.webp b/images/webp/draw_four.webp deleted file mode 100644 index c67b6f0..0000000 Binary files a/images/webp/draw_four.webp and /dev/null differ diff --git a/images/webp/g_0.webp b/images/webp/g_0.webp deleted file mode 100644 index 42b1d53..0000000 Binary files a/images/webp/g_0.webp and /dev/null differ diff --git a/images/webp/g_1.webp b/images/webp/g_1.webp deleted file mode 100644 index d62936f..0000000 Binary files a/images/webp/g_1.webp and /dev/null differ diff --git a/images/webp/g_2.webp b/images/webp/g_2.webp deleted file mode 100644 index 3146b6e..0000000 Binary files a/images/webp/g_2.webp and /dev/null differ diff --git a/images/webp/g_3.webp b/images/webp/g_3.webp deleted file mode 100644 index 09c333e..0000000 Binary files a/images/webp/g_3.webp and /dev/null differ diff --git a/images/webp/g_4.webp b/images/webp/g_4.webp deleted file mode 100644 index af456c0..0000000 Binary files a/images/webp/g_4.webp and /dev/null differ diff --git a/images/webp/g_5.webp b/images/webp/g_5.webp deleted file mode 100644 index 185150e..0000000 Binary files a/images/webp/g_5.webp and /dev/null differ diff --git a/images/webp/g_6.webp b/images/webp/g_6.webp deleted file mode 100644 index 6f27df6..0000000 Binary files a/images/webp/g_6.webp and /dev/null differ diff --git a/images/webp/g_7.webp b/images/webp/g_7.webp deleted file mode 100644 index ffe779a..0000000 Binary files a/images/webp/g_7.webp and /dev/null differ diff --git a/images/webp/g_8.webp b/images/webp/g_8.webp deleted file mode 100644 index d912fde..0000000 Binary files a/images/webp/g_8.webp and /dev/null differ diff --git a/images/webp/g_9.webp b/images/webp/g_9.webp deleted file mode 100644 index dd7e19c..0000000 Binary files a/images/webp/g_9.webp and /dev/null differ diff --git a/images/webp/g_draw.webp b/images/webp/g_draw.webp deleted file mode 100644 index 1de1392..0000000 Binary files a/images/webp/g_draw.webp and /dev/null differ diff --git a/images/webp/g_reverse.webp b/images/webp/g_reverse.webp deleted file mode 100644 index 34b83ff..0000000 Binary files a/images/webp/g_reverse.webp and /dev/null differ diff --git a/images/webp/g_skip.webp b/images/webp/g_skip.webp deleted file mode 100644 index f3ee3f2..0000000 Binary files a/images/webp/g_skip.webp and /dev/null differ diff --git a/images/webp/option_bluff.webp b/images/webp/option_bluff.webp deleted file mode 100644 index 8c531a4..0000000 Binary files a/images/webp/option_bluff.webp and /dev/null differ diff --git a/images/webp/option_draw.webp b/images/webp/option_draw.webp deleted file mode 100644 index 5332b23..0000000 Binary files a/images/webp/option_draw.webp and /dev/null differ diff --git a/images/webp/option_draw_old.webp b/images/webp/option_draw_old.webp deleted file mode 100644 index 3880f1e..0000000 Binary files a/images/webp/option_draw_old.webp and /dev/null differ diff --git a/images/webp/option_info.webp b/images/webp/option_info.webp deleted file mode 100644 index 2022781..0000000 Binary files a/images/webp/option_info.webp and /dev/null differ diff --git a/images/webp/option_pass.webp b/images/webp/option_pass.webp deleted file mode 100644 index ca6ce9d..0000000 Binary files a/images/webp/option_pass.webp and /dev/null differ diff --git a/images/webp/option_pass_old.webp b/images/webp/option_pass_old.webp deleted file mode 100644 index d02a611..0000000 Binary files a/images/webp/option_pass_old.webp and /dev/null differ diff --git a/images/webp/r_0.webp b/images/webp/r_0.webp deleted file mode 100644 index 4d434ee..0000000 Binary files a/images/webp/r_0.webp and /dev/null differ diff --git a/images/webp/r_1.webp b/images/webp/r_1.webp deleted file mode 100644 index 54e25b3..0000000 Binary files a/images/webp/r_1.webp and /dev/null differ diff --git a/images/webp/r_2.webp b/images/webp/r_2.webp deleted file mode 100644 index 31686cf..0000000 Binary files a/images/webp/r_2.webp and /dev/null differ diff --git a/images/webp/r_3.webp b/images/webp/r_3.webp deleted file mode 100644 index 5ac698e..0000000 Binary files a/images/webp/r_3.webp and /dev/null differ diff --git a/images/webp/r_4.webp b/images/webp/r_4.webp deleted file mode 100644 index fef9835..0000000 Binary files a/images/webp/r_4.webp and /dev/null differ diff --git a/images/webp/r_5.webp b/images/webp/r_5.webp deleted file mode 100644 index 67cd405..0000000 Binary files a/images/webp/r_5.webp and /dev/null differ diff --git a/images/webp/r_6.webp b/images/webp/r_6.webp deleted file mode 100644 index b61fe11..0000000 Binary files a/images/webp/r_6.webp and /dev/null differ diff --git a/images/webp/r_7.webp b/images/webp/r_7.webp deleted file mode 100644 index aeba4b3..0000000 Binary files a/images/webp/r_7.webp and /dev/null differ diff --git a/images/webp/r_8.webp b/images/webp/r_8.webp deleted file mode 100644 index f5f0d2b..0000000 Binary files a/images/webp/r_8.webp and /dev/null differ diff --git a/images/webp/r_9.webp b/images/webp/r_9.webp deleted file mode 100644 index c78676b..0000000 Binary files a/images/webp/r_9.webp and /dev/null differ diff --git a/images/webp/r_draw.webp b/images/webp/r_draw.webp deleted file mode 100644 index c3d56cc..0000000 Binary files a/images/webp/r_draw.webp and /dev/null differ diff --git a/images/webp/r_reverse.webp b/images/webp/r_reverse.webp deleted file mode 100644 index a18c382..0000000 Binary files a/images/webp/r_reverse.webp and /dev/null differ diff --git a/images/webp/r_skip.webp b/images/webp/r_skip.webp deleted file mode 100644 index 4922dc7..0000000 Binary files a/images/webp/r_skip.webp and /dev/null differ diff --git a/images/webp/y_0.webp b/images/webp/y_0.webp deleted file mode 100644 index b7ad2b2..0000000 Binary files a/images/webp/y_0.webp and /dev/null differ diff --git a/images/webp/y_1.webp b/images/webp/y_1.webp deleted file mode 100644 index f9aa282..0000000 Binary files a/images/webp/y_1.webp and /dev/null differ diff --git a/images/webp/y_2.webp b/images/webp/y_2.webp deleted file mode 100644 index e292c49..0000000 Binary files a/images/webp/y_2.webp and /dev/null differ diff --git a/images/webp/y_3.webp b/images/webp/y_3.webp deleted file mode 100644 index 4d49fac..0000000 Binary files a/images/webp/y_3.webp and /dev/null differ diff --git a/images/webp/y_4.webp b/images/webp/y_4.webp deleted file mode 100644 index b713f10..0000000 Binary files a/images/webp/y_4.webp and /dev/null differ diff --git a/images/webp/y_5.webp b/images/webp/y_5.webp deleted file mode 100644 index cd9c819..0000000 Binary files a/images/webp/y_5.webp and /dev/null differ diff --git a/images/webp/y_6.webp b/images/webp/y_6.webp deleted file mode 100644 index 1350187..0000000 Binary files a/images/webp/y_6.webp and /dev/null differ diff --git a/images/webp/y_7.webp b/images/webp/y_7.webp deleted file mode 100644 index 24683f1..0000000 Binary files a/images/webp/y_7.webp and /dev/null differ diff --git a/images/webp/y_8.webp b/images/webp/y_8.webp deleted file mode 100644 index 66e4e6f..0000000 Binary files a/images/webp/y_8.webp and /dev/null differ diff --git a/images/webp/y_9.webp b/images/webp/y_9.webp deleted file mode 100644 index 385f465..0000000 Binary files a/images/webp/y_9.webp and /dev/null differ diff --git a/images/webp/y_draw.webp b/images/webp/y_draw.webp deleted file mode 100644 index ebbc5ed..0000000 Binary files a/images/webp/y_draw.webp and /dev/null differ diff --git a/images/webp/y_reverse.webp b/images/webp/y_reverse.webp deleted file mode 100644 index c67f1de..0000000 Binary files a/images/webp/y_reverse.webp and /dev/null differ diff --git a/images/webp/y_skip.webp b/images/webp/y_skip.webp deleted file mode 100644 index ed98743..0000000 Binary files a/images/webp/y_skip.webp and /dev/null differ diff --git a/images/webp_lowsat/b_0.webp b/images/webp_lowsat/b_0.webp deleted file mode 100644 index 3f89279..0000000 Binary files a/images/webp_lowsat/b_0.webp and /dev/null differ diff --git a/images/webp_lowsat/b_1.webp b/images/webp_lowsat/b_1.webp deleted file mode 100644 index 117403a..0000000 Binary files a/images/webp_lowsat/b_1.webp and /dev/null differ diff --git a/images/webp_lowsat/b_2.webp b/images/webp_lowsat/b_2.webp deleted file mode 100644 index b300c00..0000000 Binary files a/images/webp_lowsat/b_2.webp and /dev/null differ diff --git a/images/webp_lowsat/b_3.webp b/images/webp_lowsat/b_3.webp deleted file mode 100644 index b2f1a03..0000000 Binary files a/images/webp_lowsat/b_3.webp and /dev/null differ diff --git a/images/webp_lowsat/b_4.webp b/images/webp_lowsat/b_4.webp deleted file mode 100644 index 6cdb693..0000000 Binary files a/images/webp_lowsat/b_4.webp and /dev/null differ diff --git a/images/webp_lowsat/b_5.webp b/images/webp_lowsat/b_5.webp deleted file mode 100644 index 8734f05..0000000 Binary files a/images/webp_lowsat/b_5.webp and /dev/null differ diff --git a/images/webp_lowsat/b_6.webp b/images/webp_lowsat/b_6.webp deleted file mode 100644 index d56868d..0000000 Binary files a/images/webp_lowsat/b_6.webp and /dev/null differ diff --git a/images/webp_lowsat/b_7.webp b/images/webp_lowsat/b_7.webp deleted file mode 100644 index 0cdb0a6..0000000 Binary files a/images/webp_lowsat/b_7.webp and /dev/null differ diff --git a/images/webp_lowsat/b_8.webp b/images/webp_lowsat/b_8.webp deleted file mode 100644 index 90a78f2..0000000 Binary files a/images/webp_lowsat/b_8.webp and /dev/null differ diff --git a/images/webp_lowsat/b_9.webp b/images/webp_lowsat/b_9.webp deleted file mode 100644 index 6f385cb..0000000 Binary files a/images/webp_lowsat/b_9.webp and /dev/null differ diff --git a/images/webp_lowsat/b_draw.webp b/images/webp_lowsat/b_draw.webp deleted file mode 100644 index 498149a..0000000 Binary files a/images/webp_lowsat/b_draw.webp and /dev/null differ diff --git a/images/webp_lowsat/b_reverse.webp b/images/webp_lowsat/b_reverse.webp deleted file mode 100644 index ba6f1f7..0000000 Binary files a/images/webp_lowsat/b_reverse.webp and /dev/null differ diff --git a/images/webp_lowsat/b_skip.webp b/images/webp_lowsat/b_skip.webp deleted file mode 100644 index cfe955a..0000000 Binary files a/images/webp_lowsat/b_skip.webp and /dev/null differ diff --git a/images/webp_lowsat/colorchooser.webp b/images/webp_lowsat/colorchooser.webp deleted file mode 100644 index ee5c7fa..0000000 Binary files a/images/webp_lowsat/colorchooser.webp and /dev/null differ diff --git a/images/webp_lowsat/draw_four.webp b/images/webp_lowsat/draw_four.webp deleted file mode 100644 index a93b759..0000000 Binary files a/images/webp_lowsat/draw_four.webp and /dev/null differ diff --git a/images/webp_lowsat/g_0.webp b/images/webp_lowsat/g_0.webp deleted file mode 100644 index d380e1a..0000000 Binary files a/images/webp_lowsat/g_0.webp and /dev/null differ diff --git a/images/webp_lowsat/g_1.webp b/images/webp_lowsat/g_1.webp deleted file mode 100644 index 0709297..0000000 Binary files a/images/webp_lowsat/g_1.webp and /dev/null differ diff --git a/images/webp_lowsat/g_2.webp b/images/webp_lowsat/g_2.webp deleted file mode 100644 index d77b87c..0000000 Binary files a/images/webp_lowsat/g_2.webp and /dev/null differ diff --git a/images/webp_lowsat/g_3.webp b/images/webp_lowsat/g_3.webp deleted file mode 100644 index 2289300..0000000 Binary files a/images/webp_lowsat/g_3.webp and /dev/null differ diff --git a/images/webp_lowsat/g_4.webp b/images/webp_lowsat/g_4.webp deleted file mode 100644 index 3611653..0000000 Binary files a/images/webp_lowsat/g_4.webp and /dev/null differ diff --git a/images/webp_lowsat/g_5.webp b/images/webp_lowsat/g_5.webp deleted file mode 100644 index cb29d26..0000000 Binary files a/images/webp_lowsat/g_5.webp and /dev/null differ diff --git a/images/webp_lowsat/g_6.webp b/images/webp_lowsat/g_6.webp deleted file mode 100644 index 938f501..0000000 Binary files a/images/webp_lowsat/g_6.webp and /dev/null differ diff --git a/images/webp_lowsat/g_7.webp b/images/webp_lowsat/g_7.webp deleted file mode 100644 index 0a42d2a..0000000 Binary files a/images/webp_lowsat/g_7.webp and /dev/null differ diff --git a/images/webp_lowsat/g_8.webp b/images/webp_lowsat/g_8.webp deleted file mode 100644 index 4d06b4c..0000000 Binary files a/images/webp_lowsat/g_8.webp and /dev/null differ diff --git a/images/webp_lowsat/g_9.webp b/images/webp_lowsat/g_9.webp deleted file mode 100644 index 22112f3..0000000 Binary files a/images/webp_lowsat/g_9.webp and /dev/null differ diff --git a/images/webp_lowsat/g_draw.webp b/images/webp_lowsat/g_draw.webp deleted file mode 100644 index bcbd98b..0000000 Binary files a/images/webp_lowsat/g_draw.webp and /dev/null differ diff --git a/images/webp_lowsat/g_reverse.webp b/images/webp_lowsat/g_reverse.webp deleted file mode 100644 index 59838a6..0000000 Binary files a/images/webp_lowsat/g_reverse.webp and /dev/null differ diff --git a/images/webp_lowsat/g_skip.webp b/images/webp_lowsat/g_skip.webp deleted file mode 100644 index 603ebbd..0000000 Binary files a/images/webp_lowsat/g_skip.webp and /dev/null differ diff --git a/images/webp_lowsat/r_0.webp b/images/webp_lowsat/r_0.webp deleted file mode 100644 index 4a13ae0..0000000 Binary files a/images/webp_lowsat/r_0.webp and /dev/null differ diff --git a/images/webp_lowsat/r_1.webp b/images/webp_lowsat/r_1.webp deleted file mode 100644 index 9ed6277..0000000 Binary files a/images/webp_lowsat/r_1.webp and /dev/null differ diff --git a/images/webp_lowsat/r_2.webp b/images/webp_lowsat/r_2.webp deleted file mode 100644 index 6389660..0000000 Binary files a/images/webp_lowsat/r_2.webp and /dev/null differ diff --git a/images/webp_lowsat/r_3.webp b/images/webp_lowsat/r_3.webp deleted file mode 100644 index 71fb6be..0000000 Binary files a/images/webp_lowsat/r_3.webp and /dev/null differ diff --git a/images/webp_lowsat/r_4.webp b/images/webp_lowsat/r_4.webp deleted file mode 100644 index ef3d574..0000000 Binary files a/images/webp_lowsat/r_4.webp and /dev/null differ diff --git a/images/webp_lowsat/r_5.webp b/images/webp_lowsat/r_5.webp deleted file mode 100644 index addb5f9..0000000 Binary files a/images/webp_lowsat/r_5.webp and /dev/null differ diff --git a/images/webp_lowsat/r_6.webp b/images/webp_lowsat/r_6.webp deleted file mode 100644 index 09718a4..0000000 Binary files a/images/webp_lowsat/r_6.webp and /dev/null differ diff --git a/images/webp_lowsat/r_7.webp b/images/webp_lowsat/r_7.webp deleted file mode 100644 index 0ad64df..0000000 Binary files a/images/webp_lowsat/r_7.webp and /dev/null differ diff --git a/images/webp_lowsat/r_8.webp b/images/webp_lowsat/r_8.webp deleted file mode 100644 index cf70b5d..0000000 Binary files a/images/webp_lowsat/r_8.webp and /dev/null differ diff --git a/images/webp_lowsat/r_9.webp b/images/webp_lowsat/r_9.webp deleted file mode 100644 index 8508990..0000000 Binary files a/images/webp_lowsat/r_9.webp and /dev/null differ diff --git a/images/webp_lowsat/r_draw.webp b/images/webp_lowsat/r_draw.webp deleted file mode 100644 index 4ac1d72..0000000 Binary files a/images/webp_lowsat/r_draw.webp and /dev/null differ diff --git a/images/webp_lowsat/r_reverse.webp b/images/webp_lowsat/r_reverse.webp deleted file mode 100644 index c5effef..0000000 Binary files a/images/webp_lowsat/r_reverse.webp and /dev/null differ diff --git a/images/webp_lowsat/r_skip.webp b/images/webp_lowsat/r_skip.webp deleted file mode 100644 index 780707d..0000000 Binary files a/images/webp_lowsat/r_skip.webp and /dev/null differ diff --git a/images/webp_lowsat/y_0.webp b/images/webp_lowsat/y_0.webp deleted file mode 100644 index d497b59..0000000 Binary files a/images/webp_lowsat/y_0.webp and /dev/null differ diff --git a/images/webp_lowsat/y_1.webp b/images/webp_lowsat/y_1.webp deleted file mode 100644 index 5a7b632..0000000 Binary files a/images/webp_lowsat/y_1.webp and /dev/null differ diff --git a/images/webp_lowsat/y_2.webp b/images/webp_lowsat/y_2.webp deleted file mode 100644 index 37bacff..0000000 Binary files a/images/webp_lowsat/y_2.webp and /dev/null differ diff --git a/images/webp_lowsat/y_3.webp b/images/webp_lowsat/y_3.webp deleted file mode 100644 index b8f24d3..0000000 Binary files a/images/webp_lowsat/y_3.webp and /dev/null differ diff --git a/images/webp_lowsat/y_4.webp b/images/webp_lowsat/y_4.webp deleted file mode 100644 index 98ef259..0000000 Binary files a/images/webp_lowsat/y_4.webp and /dev/null differ diff --git a/images/webp_lowsat/y_5.webp b/images/webp_lowsat/y_5.webp deleted file mode 100644 index cc94b9e..0000000 Binary files a/images/webp_lowsat/y_5.webp and /dev/null differ diff --git a/images/webp_lowsat/y_6.webp b/images/webp_lowsat/y_6.webp deleted file mode 100644 index d8effbe..0000000 Binary files a/images/webp_lowsat/y_6.webp and /dev/null differ diff --git a/images/webp_lowsat/y_7.webp b/images/webp_lowsat/y_7.webp deleted file mode 100644 index d1eed2c..0000000 Binary files a/images/webp_lowsat/y_7.webp and /dev/null differ diff --git a/images/webp_lowsat/y_8.webp b/images/webp_lowsat/y_8.webp deleted file mode 100644 index 619b648..0000000 Binary files a/images/webp_lowsat/y_8.webp and /dev/null differ diff --git a/images/webp_lowsat/y_9.webp b/images/webp_lowsat/y_9.webp deleted file mode 100644 index c581723..0000000 Binary files a/images/webp_lowsat/y_9.webp and /dev/null differ diff --git a/images/webp_lowsat/y_draw.webp b/images/webp_lowsat/y_draw.webp deleted file mode 100644 index 0fb569a..0000000 Binary files a/images/webp_lowsat/y_draw.webp and /dev/null differ diff --git a/images/webp_lowsat/y_reverse.webp b/images/webp_lowsat/y_reverse.webp deleted file mode 100644 index e6fa51c..0000000 Binary files a/images/webp_lowsat/y_reverse.webp and /dev/null differ diff --git a/images/webp_lowsat/y_skip.webp b/images/webp_lowsat/y_skip.webp deleted file mode 100644 index f9f6eee..0000000 Binary files a/images/webp_lowsat/y_skip.webp and /dev/null differ diff --git a/images/xcf/bluff.xcf b/images/xcf/bluff.xcf deleted file mode 100644 index 1aaa539..0000000 Binary files a/images/xcf/bluff.xcf and /dev/null differ diff --git a/images/xcf/draw.xcf b/images/xcf/draw.xcf deleted file mode 100644 index c661781..0000000 Binary files a/images/xcf/draw.xcf and /dev/null differ diff --git a/images/xcf/info.xcf b/images/xcf/info.xcf deleted file mode 100644 index 6c3a400..0000000 Binary files a/images/xcf/info.xcf and /dev/null differ diff --git a/images/xcf/pass.xcf b/images/xcf/pass.xcf deleted file mode 100644 index 7dd29dc..0000000 Binary files a/images/xcf/pass.xcf and /dev/null differ diff --git a/internationalization.py b/internationalization.py deleted file mode 100644 index 9bf4a9e..0000000 --- a/internationalization.py +++ /dev/null @@ -1,168 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import gettext -from functools import wraps - -from pony.orm import db_session -from telegram import Update -from telegram.ext import ContextTypes - -from locales import available_locales -from shared_vars import gm -from user_setting import UserSetting - -GETTEXT_DOMAIN = "unobot" -GETTEXT_DIR = "locales" - - -class _Underscore: - """Class to emulate flufl.i18n behaviour, but with plural support.""" - - def __init__(self) -> None: - self.translators = { - locale: gettext.GNUTranslations( - open( - gettext.find(GETTEXT_DOMAIN, GETTEXT_DIR, languages=[locale]), - "rb", - ), - ) - for locale in available_locales - if locale != "en_US" # No translation file for en_US - } - self.locale_stack = [] - - def push(self, locale): - self.locale_stack.append(locale) - - def pop(self): - return self.locale_stack.pop() if self.locale_stack else None - - @property - def code(self): - return self.locale_stack[-1] if self.locale_stack else None - - def __call__(self, singular, plural=None, n=1, locale=None): - if not locale: - locale = self.locale_stack[-1] - - if locale not in self.translators.keys(): - return singular if n == 1 else plural - translator = self.translators[locale] - - if plural is None: - return translator.gettext(singular) - else: - return translator.ngettext(singular, plural, n) - - -_ = _Underscore() - - -def __(singular, plural=None, n=1, multi=False): - """Translates text into all locales on the stack.""" - translations = [] - - if not multi and set(_.locale_stack): - translations.append(_(singular, plural, n, "en_US")) - - else: - for locale in _.locale_stack: - translation = _(singular, plural, n, locale) - - if translation not in translations: - translations.append(translation) - - return "\n".join(translations) - - -def user_locale(func): - @wraps(func) - async def wrapped( - update: Update, - context: ContextTypes.DEFAULT_TYPE, - *pargs, - **kwargs, - ): - user = _user_chat_from_update(update)[0] - - with db_session: - us = UserSetting.get(id=user.id) - - if us and us.lang != "en": - _.push(us.lang) - else: - _.push("en_US") - - result = await func(update, context, *pargs, **kwargs) - _.pop() - return result - - return wrapped - - -def game_locales(func): - @wraps(func) - async def wrapped( - update: Update, - context: ContextTypes.DEFAULT_TYPE, - *pargs, - **kwargs, - ): - user, chat = _user_chat_from_update(update) - player = gm.player_for_user_in_chat(user, chat) - locales = [] - - if player: - for player in player.game.players: - with db_session: - us = UserSetting.get(id=player.user.id) - - loc = us.lang if us and us.lang != "en" else "en_US" - if loc in locales: - continue - - _.push(loc) - locales.append(loc) - - result = await func(update, context, *pargs, **kwargs) - - while _.code: - _.pop() - - return result - - return wrapped - - -def _user_chat_from_update(update): - try: - user = update.message.from_user - chat = update.message.chat - except (NameError, AttributeError): - try: - user = update.inline_query.from_user - chat = gm.userid_current[user.id].game.chat - except KeyError: - chat = None - except (NameError, AttributeError): - try: - user = update.chosen_inline_result.from_user - chat = gm.userid_current[user.id].game.chat - except (NameError, AttributeError, KeyError): - chat = None - - return user, chat diff --git a/locales.py b/locales.py new file mode 100644 index 0000000..c5afb0a --- /dev/null +++ b/locales.py @@ -0,0 +1,93 @@ +import os +from functools import partial, wraps +from glob import glob +from typing import Dict, List +from hydrogram.types import Message +from hydrogram.enums import ChatType +from config import player_game +from game import Game + +import yaml + +from db import User, Chat + +langs = ["en-US", "pt-BR"] + +default_language = "en-US" + + +def cache_localizations(files: List[str]) -> Dict[str, Dict[str, Dict[str, str]]]: + ldict = {lang: {} for lang in langs} + for file in files: + _, pname = file.split(os.path.sep) + lang = pname.split(".")[0] + with open(file, "r") as f: + ldict[lang] = yaml.safe_load(f) + return ldict + + +jsons = [] + +for locale in langs: + jsons += glob(os.path.join("locales", f"{locale}.yml")) + +langdict = cache_localizations(jsons) + + +def use_lang(): + def decorator(func): + @wraps(func) + async def wrapper(client, message): + ulang = (await User.get_or_create(id=message.from_user.id))[0].lang + if not isinstance(message, Message): + if message.from_user.id not in player_game: + clang = ulang + else: + game: Game = player_game[message.from_user.id] + chatid = game.chat.id + clang = (await Chat.get_or_create(id=chatid))[0].lang + else: + clang = (await Chat.get_or_create(id=message.chat.id))[0].lang + ulfunc = partial(get_locale_string, ulang) + clfunc = partial(get_locale_string, clang) + return await func(client, message, ulfunc, clfunc) + + return wrapper + + return decorator + + +def use_chat_lang(): + def decorator(func): + @wraps(func) + async def wrapper(client, message): + mmessage = message.message if not isinstance(message, Message) else message + if mmessage.chat.type == ChatType.PRIVATE: + clang = (await User.get_or_create(id=mmessage.chat.id))[0].lang + else: + clang = (await Chat.get_or_create(id=mmessage.chat.id))[0].lang + clfunc = partial(get_locale_string, clang) + return await func(client, message, clfunc) + + return wrapper + + return decorator + + +def use_user_lang(): + def decorator(func): + @wraps(func) + async def wrapper(client, message): + ulang = (await User.get_or_create(id=message.from_user.id))[0].lang + ulfunc = partial(get_locale_string, ulang) + return await func(client, message, ulfunc) + + return wrapper + + return decorator + + +def get_locale_string(language: str, key: str) -> str: + print(f"Getting {key} for {language}") + res: str = langdict[language].get(key) or key + return res diff --git a/locales/__init__.py b/locales/__init__.py deleted file mode 100644 index c646639..0000000 --- a/locales/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -from .available import available_locales - -__all__ = ["available_locales"] diff --git a/locales/available.py b/locales/available.py deleted file mode 100644 index d777661..0000000 --- a/locales/available.py +++ /dev/null @@ -1,43 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - - -"""Defines a dict of all available locales to the language name.""" - -OFFSET = 127462 - ord("A") - - -def flag(code): - return chr(ord(code[0]) + OFFSET) + chr(ord(code[1]) + OFFSET) - - -available_locales = { - "en_US": flag("US") + " English (US)", - "de_DE": flag("DE") + " Deutsch (DE)", - "es_ES": flag("ES") + " Español (ES)", - "id_ID": flag("ID") + " Bahasa Indonesia", - "it_IT": flag("IT") + " Italiano", - "pt_BR": flag("BR") + " Português Brasileiro", - "pt": flag("PT") + " Português", - "nb_NO": flag("NO") + " norsk", - "ru_RU": flag("RU") + " Русский язык", - "tr_TR": flag("TR") + " Türkçe", - "zh_CN": flag("CN") + " 中文(简体)", - "zh_HK": flag("HK") + " 廣東話", - "zh_TW": flag("TW") + " 中文(台灣)", - "ca_CA": flag("ES") + " Catalan", - "ml_IN": flag("IN") + " Malayalam", -} diff --git a/locales/ca_CA/LC_MESSAGES/unobot.po b/locales/ca_CA/LC_MESSAGES/unobot.po deleted file mode 100644 index fdffcc8..0000000 --- a/locales/ca_CA/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,557 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-12 02:46-0300\n" -"PO-Revision-Date: 2022-11-12 05:22+0000\n" -"Last-Translator: Alisson Lauffer \n" -"Language-Team: Catalan \n" -"Language: ca_CA\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} ha guanyat!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "Partida acabada!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "Si us plau, selecciona un color" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "No hi ha més cartes al plat." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "Era un fanal! {name} reb 4 cartes" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} no ha fet cap fanal! {name2} reb 6 cartes" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "" -"Nova partida creada! Uniu-vos a la partida amb /join i comenceu amb /start" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "No hi ha cap partida en execució en aquest xat." - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "" - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "La sala està tancada" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "" -"En aquest moment no hi ha cap partida en marxa. Crea una partida nova amb /" -"new" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "Ja t'has unit a la partida. Inicia-la amb /start" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" - -#: bot.py:250 -msgid "Joined the game" -msgstr "{name} s'ha unit a la partida" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "No estàs jugant a cap partida en aquest grup." - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "Okay. Següent jugagor: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "" - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "" - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "" - -#: bot.py:426 -msgid "Game not found." -msgstr "Partida no trobada." - -#: bot.py:433 -msgid "Back to last group" -msgstr "Torna a l'últim grup" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "Si us plau canvia al grup que has seleccionat!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"Grup seleccionat: {group}\n" -"Assegura't d'haver canviat al grup correcte!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "Eliminant {name} de la partida" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "No hi ha cap partida en aquest xat. Crea una nova amb /new" - -#: bot.py:508 -msgid "The game has already started" -msgstr "La partida ja ha començat" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" -"Abans de començar la partida, al menys {minplayers} jugadors han de unir-se " -"utilitzant /join" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"Primer jugador: {name}\n" -"Utilitza /close per evitar que la gent s'afageixi a la partida.\n" -"Habilita multi-traduccions amb /enable_translations." - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "Selecciona el grup en el qual vols jugar." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "" -"Sala tancada. No hi ha més jugadors que puguin unir-se a aquesta partida." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "Sala oberta. Els jugadors nous poden unir-se a la partida amb /join." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "Multi-traduccions activades. Desactiva-les amb /disable_translations" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "Multi-traduccions desactivades. Ativales amb /enable_translations" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "No estàs a cap partida en aquest xat." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "Si us plau, espera {time} segon" -msgstr[1] "Si us plau, espera {time} segons" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "{name} ha intentat fer trampes" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "Següent jugador: {name}." - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "El temps d'espera per a {name} s'ha reiniciat a {time} segons" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "Selecciona un color" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "" -msgstr[1] "" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} carta)" -msgstr[1] "{name} ({number} cartes)" - -#: results.py:91 -msgid "You are not playing" -msgstr "No estàs jugant" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"No estàs jugant en aquest moment. Utilitza /new Per començar una partida o /" -"join si ja hi ha una partida en curs dins d'aquest grup" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "La partida encara no ha començat" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "Comença la partida amb /start" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "Agafant {number} carta del piló" -msgstr[1] "Agafant {number} cartes del piló" - -#: results.py:209 -msgid "Pass" -msgstr "Passar" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "Es un fanal!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "Jugador actual: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "Última carta: {card}." - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "Jugador: {player_list}" -msgstr[1] "Jugadors: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "Si us plau, edita els teus ajustos en un xat privat amb el bot." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "Esborrar les estadístiques" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "Activar les estadístiques" - -#: settings.py:50 -msgid "Language" -msgstr "Idioma" - -#: settings.py:53 -msgid "Settings" -msgstr "Configuració" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "Estadístiques activades!" - -#: settings.py:77 -msgid "Select locale" -msgstr "Selecciona la teva llengua" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "Estadístiques esborrades i desactivades!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "Llengua seleccionada!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"Aquest bot és programari lliure i està llicenciat sota l'AGPL. El codi està " -"disponible aquí: \n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "Totes les noticies aquí: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"Les teves estadístiques no estan activades. Utilitza /settings en un xat " -"privat amb el bot per activarles." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "{number} partida jugada" -msgstr[1] "{number} partides jugades" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "{number} primer lloc ({percent}%)" -msgstr[1] "{number} primers llocs ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "{number} carta jugada" -msgstr[1] "{number} cartes jugades" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} Vermell" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} Blau" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} Vert" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} Groc" diff --git a/locales/compile.sh b/locales/compile.sh deleted file mode 100755 index f911e17..0000000 --- a/locales/compile.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash -# This script compiles the unobot.po file for all languages. - -if [ ${PWD##*/} = "locales" ]; -then - function compile { - cd './'$1'/LC_MESSAGES/' - msgfmt unobot.po -o unobot.mo - cd ../../ - }; -else - echo 'Only execute this in the "locales" directory' - exit 1; -fi - -# Deutsch -compile de_DE -# Spanish -compile es_ES -# Indonesian -compile id_ID -# Italian -compile it_IT -# Portuguese (Brazil) -compile pt_BR -# Portuguese -compile pt -# Norwegian Bokmål -compile nb_NO -# Russian -compile ru_RU -# Turkish -compile tr_TR -# Simplified Chinese -compile zh_CN -# Chinese (Honk Kong) -compile zh_HK -# Traditional Chinese -compile zh_TW -# Catalan -compile ca_CA -#Malayalam -compile ml_IN diff --git a/locales/de_DE/LC_MESSAGES/unobot.po b/locales/de_DE/LC_MESSAGES/unobot.po deleted file mode 100644 index c068ec7..0000000 --- a/locales/de_DE/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,560 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# Jannes Höke , 2016. -# -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2022-11-12 05:22+0000\n" -"Last-Translator: Alisson Lauffer \n" -"Language-Team: German " -"\n" -"Language: de_DE\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: utf-8\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} hat gewonnen!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "Spiel beendet!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "Bitte wähle eine Farbe" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "Es sind keine Karten mehr im Deck." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "Bluff gecalled! {name} bekommt 4 Karten" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} hat nicht geblufft! {name2} bekommt 6 Karten" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" -"Benutze diesen Befehl in einer Gruppe, um über das nächste neu eröffnete " -"Spiel informiert zu werden." - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "In der Gruppe {title} wurde gerade ein neues Spiel gestartet" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "" -"Neues Spiel erstellt! Tritt dem Spiel mit /join bei und starte es mit /start" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "In dieser Gruppe läuft gerade kein Spiel." - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "" - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "Die Lobby ist geschlossen" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "Zur Zeit läuft kein Spiel. Erstelle ein neues mit /new" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "Du bist dem Spiel bereits beigetreten. Starte es mit /start" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" - -#: bot.py:250 -msgid "Joined the game" -msgstr "Spiel beigetreten" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "Du spielst in keinem Spiel in dieser Gruppe." - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "Okay. Nächster Spieler: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "" - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "" - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "" - -#: bot.py:426 -msgid "Game not found." -msgstr "Spiel nicht gefunden." - -#: bot.py:433 -msgid "Back to last group" -msgstr "Zurück zur letzten Gruppe" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "Bitte wechsele zu der Gruppe, die du gewählt hast!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"Ausgewählte Gruppe: {group}\n" -"Stell sicher, dass du in die richtige Gruppe wechselst!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "Entferne {name} aus dem Spiel" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "" -"In dieser Gruppe gibt es kein laufendes Spiel. Erstelle ein neues mit /new" - -#: bot.py:508 -msgid "The game has already started" -msgstr "Das Spiel hat bereits begonnen" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"Erster Spieler: {name}\n" -"Benutze /close, um zu verhindern, dass weitere Spieler beitreten.\n" -"Aktivieren Sie Mehrfachübersetzungen mit /enable_translations" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "Bitte wähle die Gruppe, in der du spielen willst." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "" -"Lobby geschlossen. Diesem Spiel können keine weiteren Spieler beitreten." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "Lobby geöffnet. Neue Spieler können nun beitreten." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "Multi-Übersetzungen aktiviert. Deaktivieren mit /disable_translations" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "" -"Multi-Übersetzungen deaktiviert. Aktiviere sie wieder mit /" -"enable_translations" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "Du spielst kein Spiel in dieser Gruppe." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "Bitte warte {time} Sekunde" -msgstr[1] "Bitte warte {time} Sekunden" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "Aktuelles Spiel: {game}" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "{name} hat versucht zu schummeln" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "Nächster Spieler: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "Wähle Farbe" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "" -msgstr[1] "" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} Karte)" -msgstr[1] "{name} ({number} Karten)" - -#: results.py:91 -msgid "You are not playing" -msgstr "Du spielst gerade nicht" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"Du spielst gerade nicht. Benutze /new um ein neues Spiel zu starten oder /" -"join, um einem bestehenden Spiel beizutreten" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "Das Spiel wurde noch nicht gestartet" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "Starte das Spiel mit /start" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "Ich ziehe {number} Karte" -msgstr[1] "Ich ziehe {number} Karten" - -#: results.py:209 -msgid "Pass" -msgstr "Passe" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "Ich glaube du bluffst!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "Aktueller Spieler: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "Letzte Karte: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "Spieler: {player_list}" -msgstr[1] "Spieler: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "Bitte ändere deine Einstellungen in einem privaten Chat mit dem Bot." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "Alle Statistiken löschen" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "Statistiken aktivieren" - -#: settings.py:50 -msgid "Language" -msgstr "Sprache" - -#: settings.py:53 -msgid "Settings" -msgstr "Einstellungen" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "Statistiken aktiviert!" - -#: settings.py:77 -msgid "Select locale" -msgstr "Bitte Sprache auswählen" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "Alle Statistiken gelöscht und deaktiviert!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "Sprache gesetzt!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"Dieser Bot ist Freie Software und lizenziert unter der AGPL. Der Quellcode " -"ist hier verfügbar:\n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "Alle News hier: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"Du hast die Spiel-Statistiken nicht aktiviert. Aktiviere sie, mit dem /" -"settings-Kommando in einem privaten Chat mit dem Bot." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "{number} gespieltes Spiel" -msgstr[1] "{number} gespielte Spiele" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "{number} mal 1. Platz ({percent}%)" -msgstr[1] "{number} mal 1. Platz ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "{number} gespielte Karte" -msgstr[1] "{number} gespielte Karten" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} Rot" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} Blau" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} Grün" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} Gelb" diff --git a/locales/en-US.yml b/locales/en-US.yml new file mode 100644 index 0000000..6373c01 --- /dev/null +++ b/locales/en-US.yml @@ -0,0 +1,69 @@ +lang_name: English +lang_flag: 🇺🇸 +lang_changed: The language has been changed to English! +back: Back +theme: Theme +info_theme: You choose a theme for the cards +seven_zero: 7-0 +info_seven: When a 7 is played, the player can swap cards with another player. When a 0 is played, everyone passes their cards to the next player. +sbluff: Bluff +info_bluff: When a player plays a +4 card, the next one can challenge. If the player who played the +4 card has another card to play, they draw 4 cards. If not, the one who challenged draws 6. +one_win: One winner +info_one_win: When the first player runs out of cards, the game ends and they are the winner. +one_card: Say UNO +info_one_card: When a player has only one card, they must say UNO. If they don't, they must draw 2 cards. +language: Language +info_lang: You can change the bot's language. +choose_lang: Choose a language +start_text: "Hello! I am the UNO Bot, a bot to play UNO on Telegram!\n\nTo play, put me in a group and send /new to start a new game!\n\nor to configure use the buttons below!" +game_mode: Game Mode +status: Status +game_mode_text: "Showing information of available game modes!\n\n" +settings: "Welcome to the settings menu!\n\nChoose an option below to configure the bot." +theme_config: "Choose a theme for the cards:" +minimalist: Minimalist +classic: Classic +colorblind: Colorblind +game_existis: There is already a game in progress! +only_group: This command only works in groups! +already_in_game: You are already in another game +already_joined: You are already in the game! +join: Join +leave: Leave +start_game: Start Game +game_started: A new game has started! +no_game: There is no game in progress! +no_game_text: No game in progress, send /new to start a new game! +lobby_closed: The lobby is closed! +lobby_opened: The lobby is open! +joined_game: You joined the game! +player_joined: "{} joined the game!" +no_joinned: You are not in the game! +next: Next {} +game_over: The game is over! +player_left: "{} left the game!" +left_game: You left the game! +not_allowed: You are not allowed to do that! +game_started: The game has already started! +info_text: 🃏 Game Information:\nCurrent player - {current_player}\nLast card - {last_card}\n +info_text2: "{player}: {cards} cards, " +pass: Pass +buy: Buy {} card(s) +bluff: I think you're bluffing! +cards_swapped: "{name1} swapped cards with {name2}" +not_swapped: Due to the number of players, it was not possible to swap cards! +swapped: The cards have been swapped! +bought: You bought {buy} cards! +bluffed: "{name} You can't bluff!\n{name} drew {draw} cards!" +not_bluffed: "{name1} You didn't bluff!\n{name2} drew {draw} cards!" +colorchoose: "{name} choose a color!" +colorchoosed: I chose the color {color}! +playerchoose: "{name} choose a player!" +invalid_card: Invalid move! +said_uno: "{name} shouted UNO!" +say_uno: "{name} say UNO or draw 2 cards!" +not_said_uno: "{name} You didn't shout UNO!\n{name} drew 2 cards!" +first: " in first" +won: "{name} won the game{comp}!" +continuing: continuing the game with {count} players +play: Play diff --git a/locales/es_ES/LC_MESSAGES/unobot.po b/locales/es_ES/LC_MESSAGES/unobot.po deleted file mode 100644 index c249ccd..0000000 --- a/locales/es_ES/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,630 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2023-02-22 18:37+0000\n" -"Last-Translator: gallegonovato \n" -"Language-Team: Spanish " -"\n" -"Language: es_ES\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.16-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" -"El tiempo de espera para saltar a este jugador se ha reducido a {time} " -"segundos.\n" -"Siguiente jugador: {name}" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" -"¡{name1} se quedó sin tiempo y ha sido eliminado de la partida!\n" -"Siguiente jugador: {name2}" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" -"¡{name} se ha quedado sin tiempo y ha sido eliminado de la partida!\n" -"La partida terminó." - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "¡{name} ganó!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "¡Fin de la partida!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "Por favor, selecciona un color" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "No hay más cartas en la baraja." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "¡Era un farol! {name} recibe 4 cartas" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "¡{name1} no se había tirado un farol!, {name2} recibe 6 cartas" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" -"Envía este comando en un grupo para recibir una notificación cuando comience " -"una nueva partida allí." - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" -"Ok, serás notificado en un mensaje privado cuando la próxima partida se " -"inicie en este chat. Asegúrate de que tengo permiso para enviarte mensajes." - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "Se ha iniciado una nueva partida en {title}" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "" -"¡Nueva partida creada! Únete con /join. Cuando estéis todos listos, haz /" -"start para empezar" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "No hay ninguna partida en curso en este grupo." - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" -"La partida aún no ha comenzado. Únete al partida con /join y comienza la " -"partida con /start" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "" -"Solo el creador del juego ({name}) y el administrador pueden hacer eso." - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "La sala está cerrada" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "No hay ninguna partida en curso. Crea una partida con /new" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "Ya te uniste a esta partida. Comienza la partida con /start" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" -"No quedan suficientes cartas en el mazo para que se unan nuevos jugadores." - -#: bot.py:250 -msgid "Joined the game" -msgstr "Te uniste a la partida" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "No estas jugando a una partida en este grupo." - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "Bueno. Siguiente jugador: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "{name} abandonó la partida antes de que empezara." - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "El jugador {name} no se encuentra en la partida actual." - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "{0} fue expulsado por {1}" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "Responda a la persona que desea expulsar y escriba /kick nuevamente." - -#: bot.py:426 -msgid "Game not found." -msgstr "Partida no encontrada." - -#: bot.py:433 -msgid "Back to last group" -msgstr "Volver al último grupo" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "¡Por favor, cambie al grupo que seleccionó!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"Grupo seleccionado: {group}\n" -"¡Asegúrate de haber cambiado al grupo correcto!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "Eliminando a {name} de la partida" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "No hay ninguna partida en curso en este chat. Crea una nueva con /new" - -#: bot.py:508 -msgid "The game has already started" -msgstr "La partida ya ha comenzado" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" -"Antes de iniciar la partida, al menos {minplayers} jugadores deben unirse " -"usando /join" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "¡Haz tu elección!" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"Primer jugador: {name}\n" -"Utiliza /close para impedir que la gente se una a la partida.\n" -"Activa las multitraducciones con /enable_translations" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "Elige el grupo en el que deseas jugar." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "Sala cerrada. No podrán unirse más jugadores a la partida." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "Sala abierta. Ahora pueden unirse nuevos jugadores usando /join." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "" -"Traducciones múltiples habilitadas. Deshabilitar con /disable_translations" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "" -"Multitraducciones deshabilitadas. Habilítelos de nuevo con " -"/enable_translations" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "No estás jugando una partida en este chat." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "Por favor, espere {time} segundo" -msgstr[1] "Por favor, espere {time} segundos" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "Partida actual: {game}" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "El modo de juego ha cambiado a {mode}" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "{name} intentó hacer trampa" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "Siguiente Jugador: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "El tiempo de espera para {name} se ha reiniciado a {time} segundos" - -#: results.py:37 -msgid "Choose Player" -msgstr "Elegir jugador" - -#: results.py:50 -msgid "Choose Color" -msgstr "Selecciona un color" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "Carta (toque para el estado del juego):" -msgstr[1] "Cartas (toque para el estado del juego):" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} carta)" -msgstr[1] "{name} ({number} cartas)" - -#: results.py:91 -msgid "You are not playing" -msgstr "No estás jugando" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"No estás jugando en este momento. Usa /new para comenzar una partida o /join " -"si hay una partida en curso en este grupo" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "La partida no ha comenzado todavía" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "Comienza la partida con /start" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "🎻 Modo clásico" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "Clásico 🎻" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "🚀 Modo Sanic" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "¡Hay que ir rápido! 🚀" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "🐉 Modo salvaje" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "Hacia lo salvaje~ 🐉" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "🔫 Modo 7-0" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "Modo carioca activado 🔫" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "✍️ Modo texto" - -#: results.py:165 -msgid "Text ✍️" -msgstr "Texto ✍️" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "Robando {number} carta" -msgstr[1] "Robando {number} cartas" - -#: results.py:209 -msgid "Pass" -msgstr "Pasar" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "¡Es un farol!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "Jugador actual: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "Última carta: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "Jugador: {player_list}" -msgstr[1] "Jugadores: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "Por favor, edita tus ajustes en un chat privado con el bot." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "Borrar estadísticas" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "Habilitar estadísticas" - -#: settings.py:50 -msgid "Language" -msgstr "Idioma" - -#: settings.py:53 -msgid "Settings" -msgstr "Ajustes" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "¡Estadísticas habilitadas!" - -#: settings.py:77 -msgid "Select locale" -msgstr "Selecciona tu idioma" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "¡Estadísticas borradas y deshabilitadas!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "¡Idioma seleccionado!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" -"Sigue estos pasos:\n" -"\n" -"1. Agregue este bot a un grupo\n" -"2. En el grupo, comience un juego nuevo con /nuevo o únase a un juego que ya " -"se está ejecutando con /unirse\n" -"3. Después de que se hayan unido al menos dos jugadores, comience el juego " -"con /start\n" -"4. Tipo@UnuRoboten tu ventana de chat y presionaespacio, " -"o haga clic en elvía @UnuRobottexto junto a los mensajes. Verá " -"sus tarjetas (algunas atenuadas), cualquier opción adicional como dibujar y " -"un?para ver el estado actual del juego. lostarjetas atenuadasson esos que tuno puedo jugaren este momento. Toque una opción para " -"ejecutar la acción seleccionada.\n" -"Los jugadores pueden unirse al juego en cualquier momento. Para salir de un " -"juego, usa /leave. Si un jugador tarda más de 90 segundos en jugar, puede " -"usar /skip para omitir a ese jugador. Usa /notify_me para recibir un mensaje " -"privado cuando se inicia un nuevo juego.\n" -"\n" -"Idiomay otras configuraciones: /configuraciones\n" -"Otros comandos (solo creador de juegos):\n" -"/cerrar - Cerrar el vestíbulo\n" -"/open - Abrir vestíbulo\n" -"/kill - Terminar el juego\n" -"/kick - Selecciona un jugador para patear respondiéndole\n" -"/enable_translations - Traduce textos relevantes a todos los idiomas " -"hablados en un juego\n" -"/disable_translations - Usa inglés para esos textos\n" -"\n" -"Experimental:Juega en varios grupos al mismo tiempo. presione " -"elJuego actual: ...y seleccione el grupo en el que desea jugar " -"una carta.\n" -"Si te gusta este bot, únete alcanal " -"de actualizacióny compra un juego de cartas UNO." - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" -"Este bot de UNO tiene cinco modos de juego: Clásico, Sanic, Salvaje, Texto y " -"7-0.\n" -"\n" -" 🎻 El modo Clásico usa el deck UNO convencional y no hay salto automático.\n" -" 🚀 El modo Sanic usa el mazo UNO convencional y el bot omite " -"automáticamente a un jugador si tarda demasiado en jugar su turno\n" -" 🐉 El modo Wild usa un mazo con más cartas especiales, menos variedad de " -"números y sin saltos automáticos.\n" -" ✍️ El modo Texto usa el mazo UNO convencional pero en lugar de stickers usa " -"el texto.\n" -" 🔫 El modo 7-0 usa el mazo UNO convencional, pero cuando un jugador juega " -"un 7, puede elegir un jugador con el que intercambiar cartas. Cuando un " -"jugador juega un 0, todas las cartas se intercambiarán entre los jugadores " -"actuales.\n" -"\n" -"Para cambiar el modo del juego, el CREADOR DEL JUEGO debe escribir el apodo " -"del bot y un espacio, al igual que cuando juega una carta, y deberían " -"aparecer todas las opciones del modo de juego." - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"Este bot es Software Libre y esta licenciado bajo AGPL. El código esta " -"disponible aquí:\n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" -"Atribuciones:\n" -"Diseño de los iconos por Faithtoken\n" -"Visto bueno a los iconos Delapouite\n" -"Los originales se pueden encontrar en http://game-icons.net\n" -"Iconos editados por ɳick" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "Todas las noticias aquí: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"Tus estadísticas no están habilitadas. Usa /settings en un chat privado con " -"el bot para habilitarlas." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "{number} partida jugada" -msgstr[1] "{number} partidas jugadas" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "{number} primer lugar ({percent}%)" -msgstr[1] "{number} primeros lugares ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "{number} carta jugada" -msgstr[1] "{number} cartas jugadas" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} Rojo" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} Azul" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} Verde" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} Amarillo" diff --git a/locales/id_ID/LC_MESSAGES/unobot.po b/locales/id_ID/LC_MESSAGES/unobot.po deleted file mode 100644 index e9bb299..0000000 --- a/locales/id_ID/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,579 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# Jannes Höke , 2016. -# -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2023-06-24 02:40+0000\n" -"Last-Translator: Reza Almanda \n" -"Language-Team: Indonesian \n" -"Language: id_ID\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: utf-8\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Weblate 4.18.1\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" -"Waktu tunggu terhadap {name} telah dikurangi menjadi {time} detik.\n" -"Next player: {name}" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" -"{name1} kehabisan waktu dan telah dikeluarkan dari permainan!\n" -"Pemain berikutnya: {name2}" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" -"{name} kehabisan waktu dan telah dikeluarkan dari permainan!\n" -"Permainan berakhir." - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} menang!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "Permainan berakhir!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "Silakan pilih warna" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "Tidak ada kartu lagi tersedia." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "Ternyata hanya gertakan! Memberikan 4 kartu kepada {name}" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} tidak hanya menggertak! Memberikan 6 kartu kepada {name2}" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" -"Kirim perintah ini dalam grup untuk mendapatkan notifikasi ketika game baru " -"dimulai di sana." - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" -"Oke, Anda akan diberitahu melalui pesan pribadi ketika permainan berikutnya " -"dimulai dalam obrolan ini. Pastikan bahwa saya diizinkan untuk mengirimi " -"Anda pesan." - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "Permainan baru telah dimulai di {title}" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "" -"Membuat permmainan baru! Ayo bergabung dengan perintah /join dan mulailah " -"permainan tersebut dengan perintah /start" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "Tidak ada permainan yang berjalan pada grup chat ini." - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" -"Permainan belum dimulai. Bergabunglah dengan permainan dengan /gabung dan " -"mulai permainan dengan /mulai" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "Hanya pembuat game ({name}) dan admin yang dapat melakukannya." - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "Lobby ditutup" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "" -"Tidak ada permainan yang berlangsung. Buat permainan baru dengan perintah /" -"new" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "" -"Kamu sudah bergabung dengan permainan. Mulai permainan dengan perintah /start" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" -"Tidak ada cukup kartu yang tersisa di dek untuk pemain baru untuk bergabung." - -#: bot.py:250 -msgid "Joined the game" -msgstr "Tergabung dengan permainan" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "Kamu tidak bermain di grup ini." - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "Baiklah. Pemain berikutnya: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "{name} meninggalkan pertandingan sebelum pertandingan dimulai." - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "Pemain {name} tidak ditemukan dalam permainan saat ini." - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "{0} ditendang oleh {1}" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "Silakan balas orang yang ingin Anda tendang dan ketik /tendang lagi." - -#: bot.py:426 -msgid "Game not found." -msgstr "Permainan tidak ditemukan." - -#: bot.py:433 -msgid "Back to last group" -msgstr "Kembali ke grup sebelumnya" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "Silakan pilih grup!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"Grup terpilih: {group}\n" -"Pastikan kamu sudah memilih grup yang benar!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "Mengeluarkan {name} dari permainan" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "" -"Tidak ada permainan yang berlangsung saat ini. Buat permainan baru dengan " -"perintah /new" - -#: bot.py:508 -msgid "The game has already started" -msgstr "Permainan sudah dimulai" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"Pemain pertama: {name}\n" -"Gunakan /close untuk menghentikan pemain baru bergabung pada game ini.\n" -"Aktifkan translasi multi bahasa dengan /enable_translations" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "Silakan pilih pada grup mana kamu akan bermain." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "Lobby ditutup. Tidak ada pemain yang bisa bergabung lagi." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "Membuka lobby. Pemain baru bisa bergabung dengan perintah /join." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "" -"Mengaktifkan translasi multi bahasa. Non-aktifkan dengan /" -"disable_translations" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "" -"Menon-aktifkan translasi multi bahasa. Nyalakan kembali dengan perintah /" -"enable_translations" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "Kamu sedang tidak bermain." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "" -msgstr[1] "" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "Percobaan curang dilakukan oleh {name}" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "Pemain berikutnya: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "Pilih warna" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "" -msgstr[1] "" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "" -msgstr[1] "" - -#: results.py:91 -msgid "You are not playing" -msgstr "Kamu sedang tidak bermain" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"Saat ini sedang tidak ada permainan. Gunakan perintah /new untuk memulai " -"permainan atau /join untuk bergabung dengan permainan yang sedang " -"berlangsung di grup ini" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "Permainan belum dimulai" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "Mulailah permainan dengan perintah /start" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "" -msgstr[1] "" - -#: results.py:209 -msgid "Pass" -msgstr "Lewati" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "Saya bilang, kamu hanya menggertak!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "Pemain saat ini: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "Kartu terakhir: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "" -msgstr[1] "" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "Silakan ubah pengaturan melalui chat pribadi dengan bot." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "Menghapus semua statistik" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "Mengaktifkan statistik" - -#: settings.py:50 -msgid "Language" -msgstr "Bahasa" - -#: settings.py:53 -msgid "Settings" -msgstr "Pengaturan" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "Mengaktifkan statistik" - -#: settings.py:77 -msgid "Select locale" -msgstr "Memilih lokasi" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "Menghapus dan menonaktifkan statisk!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "Pilih lokasi!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"Bot ini adalah software gratis dan berlisensi dibawah AGPL. Kode nya " -"tersedia disini: \n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "Semua berita ada di sini: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"Kamu belum menyalakan statistik. Gunakan /settings melalui chat pribadi " -"kepada bot untuk menyalakannya." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "" -msgstr[1] "" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "" -msgstr[1] "" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "" -msgstr[1] "" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} Merah" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} Biru" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} Hijau" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} Kuning" diff --git a/locales/it_IT/LC_MESSAGES/unobot.po b/locales/it_IT/LC_MESSAGES/unobot.po deleted file mode 100644 index 6dd1d6b..0000000 --- a/locales/it_IT/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,557 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2022-11-12 05:22+0000\n" -"Last-Translator: Alisson Lauffer \n" -"Language-Team: Italian " -"\n" -"Language: it_IT\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} ha vinto!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "La partita è conclusa!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "Per favore, scegli un colore" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "Non ci sono più carte sul tavolo." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "Il baro è stato scoperto! {name} deve pescare 4 carte" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} non ha barato! {name2} deve pescare 6 carte" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "" -"È stata creata una nuova partita! Unisciti con /join e inizia a giocare con /" -"start" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "Non c'è alcuna partita aperta in questa chat." - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "" - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "La stanza è chiusa. Nessun nuovo giocatore può unirsi alla partita" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "Non c'è nessuna partita aperta al momento. Iniziane una nuova con /new" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "Ti sei già unito/a alla partita. Inizia a giocare con /start" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" - -#: bot.py:250 -msgid "Joined the game" -msgstr "Si è unito/a alla partita" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "Non stai giocando alcuna partita in questo gruppo." - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "Okay. Prossimo giocatore: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "" - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "" - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "" - -#: bot.py:426 -msgid "Game not found." -msgstr "Partita non trovata." - -#: bot.py:433 -msgid "Back to last group" -msgstr "Vai all'ultimo gruppo" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "Per favore, vai sul gruppo che hai selezionato!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"Gruppo selezionato: {group}\n" -"Assicurati di spostarti nel gruppo giusto!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "Sto rimuovendo {name} dalla partita" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "" -"Non c'è alcuna partita aperta in questa chat. Creane una nuova con /new" - -#: bot.py:508 -msgid "The game has already started" -msgstr "La partita è già iniziata" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"Primo giocatore: {name}\n" -"Usa /close per impedire a nuovi giocatori di unirsi alla partita.\n" -"Abilita la funzione di multi-traduzione con /enable_translations" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "Per favore, seleziona il gruppo dove vuoi giocare." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "" -"La stanza è chiusa. Nessun nuovo giocatore può unirsi alla partita in corso." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "" -"La stanza è aperta. Nuovi giocatori possono unirsi alla partita con /join." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "Multi-traduzione abilitata. Disabilitala con /disable_translations" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "Multi-traduzione disabilitata. Abilitala con /enable_translations" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "Non stai giocando alcuna partita in questa chat." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "Per favore, attendi {time} secondo" -msgstr[1] "Per favore, attendi {time} secondi" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "{name} ha tentato di barare" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "Prossimo giocatore: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "Scegli il colore" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "" -msgstr[1] "" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} carta)" -msgstr[1] "{name} ({number} carte)" - -#: results.py:91 -msgid "You are not playing" -msgstr "Non stai giocando in questa partita" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"Non stai giocando in questo momento. Usa /new per iniziare una nuova partita " -"o /join per partecipare a quella già avviata in questo gruppo" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "La partita non è ancora iniziata" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "Inizia la partita con /start" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "Sto pescando {number} carta" -msgstr[1] "Sto pescando {number} carte" - -#: results.py:209 -msgid "Pass" -msgstr "Passo" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "Penso che tu stia barando!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "Giocatore attuale: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "Ultima carta: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "Giocatori: {player_list}" -msgstr[1] "Giocatori: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "" -"Per favore, modifica le tue impostazioni in una chat privata con il bot." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "Elimina tutte le statistiche" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "Abilita le statistiche" - -#: settings.py:50 -msgid "Language" -msgstr "Lingua" - -#: settings.py:53 -msgid "Settings" -msgstr "Impostazioni" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "Statistiche abilitate!" - -#: settings.py:77 -msgid "Select locale" -msgstr "Seleziona la lingua" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "Le statistiche sono state eliminate e disabilitate!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "Lingua impostata!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"Questo bot è un software gratuito e distribuito sotto licenza AGPL. Il " -"codice è disponibile qui:\n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "Tutte le novità le trovi qui: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"Non hai abilitato le statistiche. Usa /settings in una chat privata col bot " -"per abilitarle." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "{number} partite giocate" -msgstr[1] "{number} partite giocate" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "{number} vittorie ({percent}%)" -msgstr[1] "{number} vittorie ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "{number} carta giocate" -msgstr[1] "{number} carte giocate" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} Rosso" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} Blu" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} Verde" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} Giallo" diff --git a/locales/ml_IN/LC_MESSAGES/unobot.po b/locales/ml_IN/LC_MESSAGES/unobot.po deleted file mode 100644 index 54fe482..0000000 --- a/locales/ml_IN/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,559 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2022-11-12 05:22+0000\n" -"Last-Translator: Alisson Lauffer \n" -"Language-Team: Malayalam \n" -"Language: ml_IN\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} ജയിച്ചു!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "കളി അവസാനിച്ചു!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "നിറം തിരഞ്ഞെടുക്കുക." - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "ഡെക്കിൽ കൂടുതൽ കാർഡുകളൊന്നുമില്ല." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "ബ്ലഫ് വിളിച്ചു! {name} ന് 4 കാർഡുകൾ നൽകുന്നു" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} bluff ചെയ്തില്ല. {name2} ന് 6 കാർഡ് നല്‍കുന്നു" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "" -"പുതിയ ഗെയിം സൃഷ്ടിച്ചു! /join ഉപയോഗിച്ച് ഗെയിം ജോയിൻ ചെയ്തതിനു ശേഷം /start " -"ഉപയോഗിച്ച് ഗെയിം തുടങ്ങു" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "ഈ ചാറ്റിൽ പ്രവർത്തിക്കുന്ന ഗെയിമുകളൊന്നുമില്ല." - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "" - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "ലോബി അടച്ചു" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "ഒരു കളിയും ഇപ്പോൾ നടക്കുന്നില്ല /new പുതിയ കളി സൃഷ്ടിക്കുക" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "നിങ്ങൾ ഇതിനകം ഗെയിമിൽ ചേർന്നു. /start വച്ച് ഗെയിം സ്റ്റാർട്ട് ചെയ്യൂ" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" - -#: bot.py:250 -msgid "Joined the game" -msgstr "ഗെയിമിൽ ചേർന്നു." - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "നിങ്ങൾ ഈ ഗ്രൂപ്പിൽ ഗെയിം കളിക്കുന്നില്ല." - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "ശരി. അടുത്ത കളിക്കാരൻ: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "" - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "" - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "" - -#: bot.py:426 -msgid "Game not found." -msgstr "ഗെയിം കണ്ടെത്താന് ആയില്ല." - -#: bot.py:433 -msgid "Back to last group" -msgstr "അവസാന ഗ്രൂപ്പിലേക്ക് മടങ്ങുന്നു" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "അവസാന ഗ്രൂപ്പിലേക്ക് മടങ്ങു!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"തിരഞ്ഞെടുത്ത ഗ്രൂപ്പ്: {group}n\n" -" നിങ്ങൾ ശരിയായ ഗ്രൂപ്പിലേക്ക് മാറുന്നുവെന്ന് ഉറപ്പാക്കുക! " - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "ഗെയിമിൽ നിന്ന് {name} നീക്കംചെയ്യുന്നു" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "" -"ഈ ചാറ്റിൽ ഒരു ഗെയിമും പ്രവർത്തിക്കുന്നില്ല. /new പുതിയത് ഉപയോഗിച്ച് " -"പുതിയൊരെണ്ണം തുടങ്ങൂ" - -#: bot.py:508 -msgid "The game has already started" -msgstr "ഗെയിം തുടങ്ങി കഴിഞ്ഞു" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "ഗെയിം ആരംഭിക്കുന്നതിന് മുമ്പ് കുറഞ്ഞത് {minplayers} /join ചെയ്യണം" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"ആദ്യ കളിക്കാരൻ: {name}\n" -"ആളുകളെ ഗെയിമിൽ ചേരുന്നത് തടയാൻ ഉപയോഗിക്കുക /close.\n" -"/enable_translations ഉപയോഗിച്ച് ഒന്നിലധികം വിവർത്തനങ്ങൾ ഉപയോഗിക്കൂ" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "നിങ്ങൾ കളിക്കാൻ ആഗ്രഹിക്കുന്ന ഗ്രൂപ്പ് തിരഞ്ഞെടുക്കുക." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "ലോബി അടച്ചു. കൂടുതൽ കളിക്കാർക്ക് ഈ ഗെയിമിൽ ചേരാനാവില്ല." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "ലോബി തുറന്നു. പുതിയ കളിക്കാർക്ക് ഗെയിം കളിക്കാൻ /join." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "" -"ഭാഷ വിവർത്തനങ്ങൾ ഉപയോഗിക്കുന്നു. വിവർത്തനങ്ങൾ ഒഴിവാക്കാൻ /" -"disable_translations ഉപയോഗിക്കുക" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "" -"മറ്റ് ഭാഷ വിവർത്തനങ്ങൾ പ്രവർത്തനരഹിതമാക്കി. വിവർത്തനങ്ങൾ ഉപയോഗിക്കാൻ " -"/enable_translations" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "നിങ്ങൾ ഈ ചാറ്റിൽ ഗെയിം കളിക്കുന്നില്ല." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "{time} സെക്കൻഡ് വെയിറ്റ് ചെയ്യൂ" -msgstr[1] "{time} സെക്കൻഡ് വെയിറ്റ് ചെയ്യൂ" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "കള്ളകളി കളിക്കാനുള്ള ശ്രമം {name}" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "അടുത്ത കളിക്കാരൻ : {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "{name} നു വേണ്ടി കാതിരിക്കാനുള്ള സമയം {time} ലേക്ക് റീസെറ്റ് ചെയ്തു" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "നിറം തിരഞ്ഞെടുക്കുക." - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "" -msgstr[1] "" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} കാർഡ്)" -msgstr[1] "{name} ({number} കാർഡുകൾ)" - -#: results.py:91 -msgid "You are not playing" -msgstr "നിങ്ങൾ കളിക്കുന്നില്ല" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"നിങ്ങൾ ഇപ്പോൾ കളിക്കുന്നില്ല. /new ഉപയോഗിച്ച് പുതിയ ഗെയിം തുടങ്ങൂ " -"അല്ലെങ്കില്‍ /join ഉപയോഗിച്ച് ഗെയിൽ കളിക്കൂ" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "ഗെയിം ഇതുവരെ തുടങ്ങിയില്ല" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "ഗെയിം തുടങ്ങുന്നതിന് /start" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "{number} കാർഡ് വലിക്കുന്നു" -msgstr[1] "{number} കാർഡുകൾ വലിക്കുന്നു" - -#: results.py:209 -msgid "Pass" -msgstr "പാസ്" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "ഞാന് bluff വിളിക്കുന്നു!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "നിലവിലെ കളിക്കാരൻ: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "അവസാന കാർഡ് (ഗെയിം നിലയ്ക്കായി ടാപ്പുചെയ്യുക): {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "കളിക്കാരൻ: {player_list}" -msgstr[1] "കളിക്കാർ: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "നിങ്ങളുടെ ക്രമീകരണങ്ങൾ പ്രൈവറ്റ് ചാറ്റിൽ അപ്ഡേറ്റ് ചെയ്യുക." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "ഗെയിം വിവരങ്ങൾ ഡിലീറ്റ് ചെയ്യുന്നതിന്" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "ഗെയിം വിവരങ്ങൾ ലഭ്യമാക്കുന്നതിന്" - -#: settings.py:50 -msgid "Language" -msgstr "ഭാഷ" - -#: settings.py:53 -msgid "Settings" -msgstr "സജീകരണങ്ങൾ" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "ഗെയിം വിവരങ്ങൾ enable ചെയ്തു!" - -#: settings.py:77 -msgid "Select locale" -msgstr "ഭാഷ തിരഞ്ഞെടുക്കൂ" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "ഗെയിം വിവരങ്ങൾ ഡിലീറ്റ് ചെയ്യുകയും disable ചെയ്യുകയും ചെയ്തു!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "ഭാഷ തിരഞ്ഞെടുക്കൂ!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"ഈ ബോട്ട് ഒരു സ്വതന്ത്ര സോഫ്റ്റ് വെയർ ആണ്, എജിപിഎൽ കീഴിൽ ലൈസൻസ് ഉള്ളതാണ്. കോഡ് ഇവിടെ " -"ലഭ്യമാണ്: \n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "അപ്‌ഡേറ്റുകൾക്കായി ഗ്രൂപ്പ് ജോയിൻ ചെയ്യാം https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"ഗെയിം വിവരങ്ങൾ enable ചെയ്തിട്ടില്ല. /settings ബോടിന്റെ പ്രൈവറ്റ് ചാറ്റിൽ " -"ഉപയോഗിച്ച് ഗെയിം വിവരങ്ങൾ പ്രവർത്തനക്ഷമമാക്കൂ." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "{number} ഗെയിം കളിച്ചു" -msgstr[1] "{number} ഗെയിം കളിച്ചു" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "{number} ഒന്നാം സ്ഥാനം ({percent}%)" -msgstr[1] "{number} ഒന്നാം സ്ഥാനങ്ങൾ ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "{number} കാർഡ് കളിച്ചു" -msgstr[1] "{number} കാർഡ് കളിച്ചു" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} ചുവപ്പ്" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} നീല" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} പച്ച" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} മഞ്ഞ" diff --git a/locales/nb_NO/LC_MESSAGES/unobot.po b/locales/nb_NO/LC_MESSAGES/unobot.po deleted file mode 100644 index f50681d..0000000 --- a/locales/nb_NO/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,621 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 1.0\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2022-11-14 17:00+0000\n" -"Last-Translator: Allan Nordhøy \n" -"Language-Team: Norwegian Bokmål \n" -"Language: nb_NO\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" -"Ventetid før denne spilleren hoppes over er redusert til {time} sekunder.\n" -"Neste spiller: {name}" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" -"{name1} slapp opp for tid og har blitt fjernet fra spillet.\n" -"Neste spiller: {name2}" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" -"{name} slapp opp for tid og har blitt fjernet fra spillet.\n" -"Spillet er over." - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} har vunnet." - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "Spillet er over." - -#: actions.py:164 -msgid "Please choose a color" -msgstr "Velg en farge" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "Ingen flere kort i kortstokken." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "Bløff sett. Gir 4 kort til {name}." - -#: actions.py:241 -#, fuzzy, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} bløffet ikke. Gir seks kort til {name2}." - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" -"Send denne kommandoen i en gruppe du vil varsle når et nytt spill starter " -"her." - -#: bot.py:113 -#, fuzzy -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" -"OK. Du vil få en privat melding når neste spill starter i denne sludringen. " -"Sørg for at jeg kan sende deg meldinger." - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "Et nytt spill har blitt startet i {title}" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "" -"Opprettet nytt spill. Ta del i spillet med «/join» og start spillet med " -"«/start»." - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -#, fuzzy -msgid "There is no running game in this chat." -msgstr "Ingen kjørende spill i denne sludringen." - -#: bot.py:185 bot.py:336 -#, fuzzy -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" -"Spillet har ikke startet enda. Ta del i spillet med «/join» og start det ed " -"«/start»." - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "Kun spillskaperen ({name}) og administratorer kan gjøre dette." - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "Lobbyen er lukket" - -#: bot.py:223 bot.py:326 -#, fuzzy -msgid "No game is running at the moment. Create a new game with /new" -msgstr "Ingen spill kjører for øyeblikket. Start et nytt spill med «/new»." - -#: bot.py:231 -#, fuzzy -msgid "You already joined the game. Start the game with /start" -msgstr "Du har allerede tatt del i spillet. Start spillet med «/start»." - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "Ikke nok kort igjen i kortstokken til at nye spillere kan ta del." - -#: bot.py:250 -msgid "Joined the game" -msgstr "Tok del i spillet" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "Du er ikke delaktig i noe spill i denne gruppen." - -#: bot.py:294 bot.py:397 -#, fuzzy, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "OK. Neste avspiller: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "{name} forlot spillet før det startet." - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "Fant ikke spilleren «{name}» i nåværende spill." - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "{0} ble kastet ut av {1}" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "Svar personen du vil kaste ut og skriv «/kick» igjen." - -#: bot.py:426 -msgid "Game not found." -msgstr "Fant ikke spillet." - -#: bot.py:433 -msgid "Back to last group" -msgstr "Tilbake til forrige gruppe" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "Bytt til gruppen du valgte." - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"Valgt gruppe: {group}\n" -"Sørg for at du har byttet til riktig gruppe." - -#: bot.py:479 -#, fuzzy, python-brace-format -msgid "Removing {name} from the game" -msgstr "Ferner {name} fra spillet …" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "Ingen aktive spill i denne sludringen. Opprett et med «/new»." - -#: bot.py:508 -msgid "The game has already started" -msgstr "Spillet har allerede startet" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" -"Minst {minplayers} spillere må skrive «/join» for å ta del i spillet før du " -"kan starte det." - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "Gjør ditt valg." - -#: bot.py:533 -#, fuzzy, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"Første spiller: {name}\n" -"Bruk «/close» for å stoppe folk fra å ta del i spillet.\n" -"Skru på multi-oversettelser med «/enable_translations»." - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "Velg gruppen du vil spille i." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "Lukket lobbyen. Ingen flere spillere kan ta del i spillet." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "Åpnet lobbyen. Nye spillere kan skrive «/join» for å ta del i spillet." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "Multi-oversettelser påskrudd. Skru av med «/disable_translations»." - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "Multi-oversettelser avskrudd. Skru på igjen med «/enable_translations»." - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "Du spiller ikke i noe spill i denne sludringen." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "Vent {time} sekund" -msgstr[1] "Vent {time} sekunder" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "Nåværende spill: {game}" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "Spillmodus endret til {mode}" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "Forsøk på juks av {name}." - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "Neste avspiller: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "Ventetid for {name} har blitt tilbakestilt til {time} sekunder." - -#: results.py:37 -msgid "Choose Player" -msgstr "Velg avspiller" - -#: results.py:50 -msgid "Choose Color" -msgstr "Velg farge" - -#: results.py:66 -#, fuzzy -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "Kort (trykk for spilltilstand):" -msgstr[1] "Kort (trykk for spilltilstand):" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} kort)" -msgstr[1] "{name} ({number} kort)" - -#: results.py:91 -msgid "You are not playing" -msgstr "Du spiller ikke." - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"Spiller ikke akkurat nå. Bruk «/new» for å starte et spill, eller «/join» " -"for å ta del i nåværende spill i denne gruppen." - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "Spillet har ikke startet enda" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "Start spillet med «/start»" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "🎻 Klassisk modus" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "Klassisk 🎻" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "🚀 Sanic-modus" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "Hurtighet først! 🚀" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "🐉 Vilt modus" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "Inn i naturen~ 🐉" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "🔫 7-0 -modus" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "Carioca-modus påslått 🔫" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "✍️ Tekst-modus" - -#: results.py:165 -msgid "Text ✍️" -msgstr "Tekst ✍️" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "Trekker {number} kort" -msgstr[1] "Trekker {number} kort" - -#: results.py:209 -msgid "Pass" -msgstr "Pass" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "Jeg ser bløffen din." - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "Nåværende spiller: {name}" - -#: results.py:264 -#, fuzzy, python-brace-format -msgid "Last card: {card}" -msgstr "Siste kort: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "Spiller: {player_list}" -msgstr[1] "Spillere: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "Rediger innstillingene dine i en privat sludring med botten." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "Slett all statistikk" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "Skru på statistikk" - -#: settings.py:50 -msgid "Language" -msgstr "Språk" - -#: settings.py:53 -msgid "Settings" -msgstr "Innstillinger" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "Statistikk påskrudd." - -#: settings.py:77 -#, fuzzy -msgid "Select locale" -msgstr "Velg språk" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "Statistikk slettet og avskrudd." - -#: settings.py:100 -#, fuzzy -msgid "Set locale!" -msgstr "Sett språk." - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" -"Følg disse stegene:\n" -"\n" -"1. Legg til denne botten i en gruppe\n" -"2. I gruppen kan du starte et nytt spill med «/new», eller ta del i et " -"allerede kjørende spill med «/join»\n" -"3. Etter at minst to spillere har blitt med kan du starte spillet med " -"«/start»\n" -"4. Skriv @UnuRobot i sludringsboksen og trykk mellomrom, " -"eller klikk på via @UnuRobot-teksten ved siden av meldinger. Du " -"vil se kortene dine (noen utgrået), noen ekstra alternativer som tegning og " -"et ? for å se gjeldende spilltilstand. Utgråede kort er dem du " -"ikke kan spille for øyeblikket. Trykk på et alternativ for å utføre " -"valgt handling.\n" -"Spillere kan bli med i spillet når som helst. For å forlate et spill, bruker " -"du «/leave». Hvis en spiller bruker mer enn 90 sekunder på å spille, kan du " -"bruke «/skip» for å hoppe over den spilleren. Bruk «/notify_me» for å motta " -"en privat melding når et nytt spill startes.\n" -"\n" -" Språk og andre innstillinger: /settings\n" -"Andre kommandoer (kun for spillskaperen):\n" -"«/close» - Lukk lobbyen\n" -"«/open» - Åpne lobbyen\n" -"«/kill» - Avslutt spillet\n" -"«/kick» - Velg en spiller å sparke ved å svare vedkommende\n" -"«/enable_translations» - Oversett relevante tekster til alle språk som " -"snakkes i et spill\n" -"«/disable_translations» - Bruk engelsk for disse tekstene\n" -"\n" -" Eksperimentelt: Spill i flere grupper samtidig. Trykk på " -"Gjeldende spill: ...-knappen og velg gruppen du vil spille et " -"kort i.\n" -"Hvis du liker denne botten, kan du bli med i oppdateringskanalen og kjøpe et UNO-kortspill." - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" -"Denne UNO-boten har fem spillmodus: Klassisk, Sanic, vilt, tekst og 7-0.\n" -"\n" -" 🎻 Klassisk modus bruker den konvensjonelle UNO-kortstokken og ingen hoppes " -"over automatisk.\n" -" 🚀 Sanic-modus bruker den konvensjonelle UNO-kortstokken og botten hopper " -"automatisk over en spiller hvis vedkommende bruker for lang tid på sin tur.\n" -" 🐉 Vilt modus bruker en kortstokk med flere spesialkort, mindre " -"tallvariasjon, og ingen hoppes over automatisk.\n" -" ✍️ Tekstmodus bruker den konvensjonelle UNO-kortstokken, men i stedet for " -"klistremerker bruker den tekst.\n" -" 🔫 7-0 -modus bruker den konvensjonelle UNO-kortstokken, men når en spiller " -"legger ned en 7-er, kan vedkommende velge en spiller å bytte kort med. Når " -"en spiller legger ned et 0-kort, vil alle kort byttes mellom de nåværende " -"spillerne.\n" -"\n" -"For å endre spillmodus må spillskaperen skrive inn kallenavnet og et " -"mellomrom, akkurat som når du spiller et kort, og alle " -"spillmodusalternativer vises." - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"Denne botten er fri programvare, lisensiert AGPLv3+. Kildekoden er " -"tilgjengelig på\n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -#, fuzzy -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" -"Bidragsytere:\n" -"Korttrekkingsikon av Faithtoken\n" -"Pass-ikon av Delapouite\n" -"Originaler tilgjengelig på https://game-icons.net\n" -"Ikoner redigert av ɳick" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "Alle nyheter her: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"Du har ikke skrudd på statistikk. Bruk «/settings» i et privat " -"sludringsvindu med botten for å skru dette på." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "{number} spill spilt" -msgstr[1] "{number} spill spilt" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "{number} førsteplass ({percent}%)" -msgstr[1] "{number} førsteplasser ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "{number} kort spilt" -msgstr[1] "{number} kort spilt" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} Rød" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} Blå" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} Grønn" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} Gul" diff --git a/locales/pt-BR.yml b/locales/pt-BR.yml new file mode 100644 index 0000000..380a353 --- /dev/null +++ b/locales/pt-BR.yml @@ -0,0 +1,69 @@ +lang_name: Português +lang_flag: 🇧🇷 +lang_changed: O idioma foi alterado para Português! +back: Voltar +theme: Tema +info_theme: Você escolhe um tema para as cartas +seven_zero: 7-0 +info_seven: Quando um 7 é jogado, o jogador pode trocar as cartas com outro jogador. Quando um 0 é jogado, todos passam as cartas para o próximo jogador. +sbluff: Blefe +info_bluff: Quando um jogador joga uma carta +4, o próximo pode desafiar. Se o jogador que jogou a carta +4 tiver outra carta para jogar, ele compra 4 cartas. Se não tiver, quem desafiou compra 6. +one_win: Um vencedor +info_one_win: Quando o primeiro jogador fica sem cartas, o jogo acaba e ele é o vencedor. +one_card: Dizer UNO +info_one_card: Quando um jogador tem apenas uma carta, ele deve dizer UNO. Se ele não disser, ele deve comprar 2 cartas. +language: Idioma +info_lang: Você pode alterar o idioma do bot. +choose_lang: Escolha um idioma +start_text: "Olá! Eu sou o UNO Bot, um bot para jogar UNO no Telegram!\n\nPara jogar me coloque em um grupo e mande /new para começar um novo jogo!\n\nou para configurar use os botões abaixo!" +game_mode: Modo de Jogo +status: Status +game_mode_text: "Mostrando informações dos modos de jogo disponíveis!\n\n" +settings: "Bem vindo ao menu de configurações!\n\nEscolha uma opçãoe abaixo para configurar o bot." +theme_config: "Escolha um tema para as cartas:" +minimalist: Minimalista +classic: Clássico +colorblind: Daltônico +game_existis: Já existe um jogo em andamento! +only_group: Esse comando só funciona em grupos! +already_in_game: Você já está em outro jogo +already_joined: Você já está no jogo! +join: Entrar +leave: Sair +start_game: Começar Jogo +game_started: Um novo jogo foi iniciado! +no_game: Não há jogo em andamento! +no_game_text: Nenhum jogo em andamento, mande /new para iniciar um novo jogo! +lobby_closed: O lobby está fechado! +lobby_opened: O lobby está aberto! +joined_game: Você entrou no jogo! +player_joined: "{} entrou no jogo!" +no_joinned: Você não está no jogo! +next: Próximo {} +game_over: O jogo acabou! +player_left: "{} saiu do jogo!" +left_game: Você saiu do jogo! +not_allowed: Você não tem permissão para fazer isso! +game_started: O jogo já começou! +info_text: 🃏 Informações do Jogo:\nJogador atual - {current_player}\nÚltima carta - {last_card}\n +info_text2: "{player}: {cards} cartas, " +pass: Passar +buy: Comprar {} carta(s) +bluff: Eu acho que você está blefando! +cards_swapped: "{name1} trocou as cartas com {name2}" +not_swapped: Devido ao numero de jogadores, não foi possível trocar as cartas! +swapped: As cartas foram trocadas! +bought: Você comprou {buy} cartas! +bluffed: "{name} Você não pode blefar!\n{name} comprou {draw} cartas!" +not_bluffed: "{name1} Você não blefou!\n{name2} comprou {draw} cartas!" +colorchoose: "{name} escolha uma cor!" +colorchoosed: Eu escolhi a cor {color}! +playerchoose: "{name} escolha um jogador!" +invalid_card: Jogada inválida! +said_uno: "{name} gritou UNO!" +say_uno: "{name} fale UNO ou compre 2 cartas!" +not_said_uno: "{name} Você não gritou UNO!\n{name} comprou 2 cartas!" +first: " em primeiro" +won: "{name} ganhou o jogo{comp}!" +continuing: continuando o jogo com {count} jogadores +play: Jogar \ No newline at end of file diff --git a/locales/pt/LC_MESSAGES/unobot.po b/locales/pt/LC_MESSAGES/unobot.po deleted file mode 100644 index a178133..0000000 --- a/locales/pt/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,622 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 1.0\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2023-02-19 20:32+0000\n" -"Last-Translator: ssantos \n" -"Language-Team: Portuguese \n" -"Language: pt\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.16-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" -"O tempo de espera para pular este jogador foi reduzido a {time} segundos.\n" -"Próximo jogador: {name}" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" -"{name1} ficou sem tempo e foi removido da partida!\n" -"Próximo jogador: {name2}" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" -"{name} ficou sem tempo e foi removido da partida!\n" -"A partida acabou." - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} venceu!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "Fim de partida!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "Por favor, escolha uma cor" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "Não há mais cartas no deck." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "Blefe revelado! Dando 4 cartas para {name}" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} não blefou! Dando 6 cartas para {name2}" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" -"Envie este comando num grupo para ser notificado quando uma nova partida for " -"iniciada." - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" -"Ok, você será notificado numa mensagem privada quando a próxima partida for " -"iniciada neste chat. Certifique-se de que tenho permissão para lhe enviar " -"mensagens." - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "Uma nova partida foi iniciada no grupo {title}" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "Nova partida criada! Entre na partida com /join e inicie-a com /start" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "Não há uma partida sendo jogada nesta conversa." - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" -"A partida ainda não iniciou. Junte-se a partida com /join e inicie-a com " -"/start" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "Somente o criador do jogo ({name}) e administradores podem fazer isso." - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "O lobby está fechado" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "Nenhuma partida está a ser jogada. Crie uma partida com /new" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "Já entrou na partida. Inicie-a com /start" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" -"Não há cartas suficientes no baralho para que novos jogadores possam " -"participar." - -#: bot.py:250 -msgid "Joined the game" -msgstr "Entrou na partida" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "Não joga nenhuma partida nesse grupo." - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "Ok. Próximo(a) jogador(a): {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "{name} deixou a partida antes de ela começar." - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "O jogador {name} não está na partida atual." - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "{0} foi removido por {1}" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "" -"Por favor, responda à pessoa que deseja remover e digite /kick novamente." - -#: bot.py:426 -msgid "Game not found." -msgstr "Partida não encontrada." - -#: bot.py:433 -msgid "Back to last group" -msgstr "Voltar ao último grupo" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "Por favor, mude para o grupo selecionado!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"Grupo selecionado: {group}\n" -"Tenha certeza de que mudou para o grupo certo!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "Removendo {name} da partida" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "" -"Não há nenhuma partida sendo jogada nesta conversa. Crie um nova partida com " -"/new" - -#: bot.py:508 -msgid "The game has already started" -msgstr "A partida já começou" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" -"Pelo menos {minplayers} jogadores devem se juntar (/join) a partida antes de " -"poder iniciá-la" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "Faça sua escolha!" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"Primeiro jogador: {name}\n" -"Use /close para impedir que mais pessoas entrem na partida.\n" -"Ative as multi-traduções com /enable_translations" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "Por favor, selecione o grupo em que deseja jogar." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "" -"O lobby está fechado. Não é permitida a entrada de novos jogadores nessa " -"partida." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "" -"O lobby está aberto. Novos jogadores podem entrar na partida usando /join." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "Multi-traduções ativadas. Desative com /disable_translations" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "" -"Multi-traduções desativadas. Ative-as novamente com /enable_translations" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "Não participa numa partida nesta conversa." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "Por favor, aguarde {time} segundo" -msgstr[1] "Por favor, aguarde {time} segundos" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "Partida atual: {game}" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "Modo de jogo alterado para {mode}" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "Tentativa de trapaça por {name}" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "Próximo jogador: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "O tempo de espera para {name} foi redefinido para {time} segundos" - -#: results.py:37 -msgid "Choose Player" -msgstr "Escolha o Jogador" - -#: results.py:50 -msgid "Choose Color" -msgstr "Escolher Cor" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "Carta (toque para estado de jogo):" -msgstr[1] "Cartas (toque para estado de jogo):" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} carta)" -msgstr[1] "{name} ({number} cartas)" - -#: results.py:91 -msgid "You are not playing" -msgstr "Não está a jogar" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"Não está a jogar. Use /new para criar uma partida ou /join para entrar na " -"partida atual neste grupo" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "A partida ainda não começou" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "Inicie a partida com /start" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "🎻 Modo clássico" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "Clássico 🎻" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "🚀 Modo sanico" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "Temos que ir rápido! 🚀" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "🐉 Modo selvagem" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "Para o selvagem~ 🐉" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "🔫 modo 7-0" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "Modo carioca ativo 🔫" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "✍️ Modo texto" - -#: results.py:165 -msgid "Text ✍️" -msgstr "Texto ✍️" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "Sacando {number} carta" -msgstr[1] "Sacando {number} cartas" - -#: results.py:209 -msgid "Pass" -msgstr "Passo" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "Está a blefar!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "Jogador atual: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "Última carta: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "Jogador(a): {player_list}" -msgstr[1] "Jogadores(as): {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "" -"Por favor, ajuste as suas configurações numa conversa privada com o bot." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "Apagar todas estatísticas" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "Ativar estatísticas" - -#: settings.py:50 -msgid "Language" -msgstr "Idioma" - -#: settings.py:53 -msgid "Settings" -msgstr "Configurações" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "Estatísticas ativadas!" - -#: settings.py:77 -msgid "Select locale" -msgstr "Definir linguagem" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "Estatísticas apagadas e desativadas!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "Linguagem selecionada!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" -"Siga esses passos:\n" -"\n" -"1. Adicione este bot a um grupo\n" -"2. No grupo, inicie uma nova partida com /new ou entre numa partida já em " -"execução com /join\n" -"3. Após a entrada de pelo menos dois jogadores, inicie a partida com /start\n" -"4. Digite @UnuRobot na sua caixa de bate-papo e pressione " -"espaço, ou clique no texto via @UnuRobot ao lado das " -"mensagens. Verá as suas cartas (algumas esmaecidas), opções extras como " -"desenhar e um ? para ver o estado atual do jogo. As cartas " -"acinzentadas são aquelas que não pode jogar no momento. Toque " -"numa opção para executar a ação selecionada.\n" -"Os jogadores podem entrar na partida a qualquer momento. Para sair de uma " -"partida, use /leave. Se um jogador demorar mais de 90 segundos para jogar, " -"pode usar /skip para pular esse jogador. Use /notify_me para receber uma " -"mensagem privada quando um novo jogo for iniciado.\n" -"\n" -"Idioma e outras configurações: /settings\n" -"Outros comandos (somente criador do jogo):\n" -"/close - Fechar lobby\n" -"/open - Abrir lobby\n" -"/kill - Termina o jogo\n" -"/kick - Selecione um jogador para chutar por lhe responder\n" -"/enable_translations - Traduz textos relevantes para todos os idiomas " -"falados num jogo\n" -"/disable_translations - Use inglês para esses textos\n" -"\n" -"Experimental: Jogue em vários grupos ao mesmo tempo. Pressione o " -"botão Partida atual: ... e selecione o grupo no qual deseja " -"jogar uma carta.\n" -"Se gosta deste bot, entre no canal " -"de atualização e compre um jogo de cartas UNO." - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" -"Este bot do UNO tem cinco modos de jogo: Clássico, Sanico, Selvagem, Texto e " -"7-0.\n" -"\n" -" 🎻 O modo Clássico utiliza o deck convencional UNO e não há pulo automático " -"de jogadores.\n" -" 🚀 O modo Sanico usa o deck UNO convencional e o bot pula automaticamente " -"um jogador se ele demorar muito tempo para jogar a sua vez.\n" -" 🐉 O modo Selvagem usa um baralho com mais cartas especiais, menos " -"variedade de números e sem pulo automático.\n" -" ✍️ O modo Texto usa o baralho convencional UNO, mas em vez de stickers, usa " -"texto.\n" -" 🔫 O modo 7-0 usa o baralho convencional UNO, mas quando um jogador joga um " -"7, ele pode escolher um jogador para trocar as cartas. Quando um jogador " -"joga um 0, todas as cartas serão trocadas entre os jogadores atuais.\n" -"\n" -"Para mudar o modo de jogo, o CRIADOR DO JOGO tem que digitar o username do " -"bot e um espaço, assim como quando se joga uma carta e todas as opções de " -"modo de jogo devem aparecer." - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"Esse bot é um Software livre, grátis e licenciado com AGPL. O código está " -"disponível aqui: \n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" -"Atribuições:\n" -"Ícone de retirada de cartas feito por Faithtoken\n" -"Ícone de passe feito pot por Delapouite\n" -"Originais disponíveis em http://game-icons.net\n" -"Ícones editados por ɳick" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "Todas as novidades aqui: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"Não ativou as estatísticas. Use /settings numa conversa privada com o bot " -"para ativá-las." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "{number} partida jogada" -msgstr[1] "{number} partidas jogadas" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "{number} vez em primeiro lugar ({percent}%)" -msgstr[1] "{number} vezes em primeiro lugar ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "{number} carta jogada" -msgstr[1] "{number} cartas jogadas" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} Vermelho" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} Azul" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} Verde" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} Amarelo" diff --git a/locales/pt_BR/LC_MESSAGES/unobot.po b/locales/pt_BR/LC_MESSAGES/unobot.po deleted file mode 100644 index b642f3a..0000000 --- a/locales/pt_BR/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,634 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2022-11-12 06:21+0000\n" -"Last-Translator: Alisson Lauffer \n" -"Language-Team: Portuguese (Brazil) \n" -"Language: pt_BR\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" -"O tempo de espera para pular este jogador foi reduzido a {time} segundos.\n" -"Próximo jogador: {name}" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" -"{name1} ficou sem tempo e foi removido da partida!\n" -"Próximo jogador: {name2}" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" -"{name} ficou sem tempo e foi removido da partida!\n" -"A partida acabou." - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} venceu!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "Fim de partida!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "Por favor, escolha uma cor" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "Não há mais cartas no deck." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "Blefe revelado! Dando 4 cartas para {name}" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} não blefou! Dando 6 cartas para {name2}" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" -"Envie este comando em um grupo para ser notificado quando uma nova partida " -"for iniciada." - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" -"Ok, você será notificado em uma mensagem privada quando a próxima partida " -"for iniciada neste chat. Certifique-se de que tenho permissão para lhe " -"enviar mensagens." - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "Uma nova partida foi iniciada no grupo {title}" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "Nova partida criada! Entre na partida com /join e inicie-a com /start" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "Não há uma partida sendo jogada nesta conversa." - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" -"A partida ainda não iniciou. Junte-se a partida com /join e inicie-a com /" -"start" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "Somente o criador do jogo ({name}) e administradores podem fazer isso." - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "O lobby está fechado" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "Nenhuma partida está sendo jogada. Crie uma nova partida com /new" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "Você já entrou na partida. Inicie-a com /start" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" -"Não há cartas suficientes no baralho para que novos jogadores possam " -"participar." - -#: bot.py:250 -msgid "Joined the game" -msgstr "Entrou na partida" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "Você não está jogando nenhuma partida nesse grupo." - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "Ok. Próximo(a) jogador(a): {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "{name} deixou a partida antes de ela começar." - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "O jogador {name} não está na partida atual." - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "{0} foi removido por {1}" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "" -"Por favor, responda à pessoa que você deseja remover e digite /kick " -"novamente." - -#: bot.py:426 -msgid "Game not found." -msgstr "Partida não encontrada." - -#: bot.py:433 -msgid "Back to last group" -msgstr "Voltar ao último grupo" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "Por favor, mude para o grupo selecionado!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"Grupo selecionado: {group}\n" -"Tenha certeza de que mudou para o grupo certo!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "Removendo {name} da partida" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "" -"Não há nenhuma partida sendo jogada nesta conversa. Crie um nova partida " -"com /new" - -#: bot.py:508 -msgid "The game has already started" -msgstr "A partida já começou" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" -"Pelo menos {minplayers} jogadores devem se juntar (/join) a partida antes de " -"poder iniciá-la" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "Faça sua escolha!" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"Primeiro jogador: {name}\n" -"Use /close para impedir que mais pessoas entrem na partida.\n" -"Ative as multi-traduções com /enable_translations" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "Por favor, selecione o grupo em que deseja jogar." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "" -"O lobby está fechado. Não é permitida a entrada de novos jogadores nessa " -"partida." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "" -"O lobby está aberto. Novos jogadores podem entrar na partida usando /join." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "Multi-traduções ativadas. Desative com /disable_translations" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "" -"Multi-traduções desativadas. Ative-as novamente com /enable_translations" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "Você não está participando de uma partida nesta conversa." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "Por favor, aguarde {time} segundo" -msgstr[1] "Por favor, aguarde {time} segundos" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "Partida atual: {game}" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "Modo de jogo alterado para {mode}" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "Tentativa de trapaça por {name}" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "Próximo jogador: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "O tempo de espera para {name} foi redefinido para {time} segundos" - -#: results.py:37 -msgid "Choose Player" -msgstr "Escolha o Jogador" - -#: results.py:50 -msgid "Choose Color" -msgstr "Escolher Cor" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "Carta (toque para estado de jogo):" -msgstr[1] "Cartas (toque para estado de jogo):" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} carta)" -msgstr[1] "{name} ({number} cartas)" - -#: results.py:91 -msgid "You are not playing" -msgstr "Você não está jogando" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"Você não está jogando. Use /new para criar uma partida ou /join para entrar " -"na partida atual neste grupo" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "A partida ainda não começou" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "Inicie a partida com /start" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "🎻 Modo clássico" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "Clássico 🎻" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "🚀 Modo sanico" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "Temos que ir rápido! 🚀" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "🐉 Modo selvagem" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "Para o selvagem~ 🐉" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "🔫 modo 7-0" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "Modo carioca ativo 🔫" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "✍️ Modo texto" - -#: results.py:165 -msgid "Text ✍️" -msgstr "Texto ✍️" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "Sacando {number} carta" -msgstr[1] "Sacando {number} cartas" - -#: results.py:209 -msgid "Pass" -msgstr "Passo" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "Você está blefando!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "Jogador atual: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "Última carta: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "Jogador(a): {player_list}" -msgstr[1] "Jogadores(as): {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "" -"Por favor, ajuste suas configurações em uma conversa privada com o bot." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "Apagar todas estatísticas" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "Habilitar estatísticas" - -#: settings.py:50 -msgid "Language" -msgstr "Idioma" - -#: settings.py:53 -msgid "Settings" -msgstr "Configurações" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "Estatísticas habilitadas!" - -#: settings.py:77 -msgid "Select locale" -msgstr "Definir linguagem" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "Estatísticas apagadas e desabilitadas!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "Linguagem selecionada!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" -"Siga esses passos:\n" -"\n" -"1. Adicione este bot a um grupo\n" -"2. No grupo, inicie uma nova partida com /new ou entre em uma partida já em " -"execução com /join\n" -"3. Após a entrada de pelo menos dois jogadores, inicie a partida com /start\n" -"4. Digite @UnuRobot em sua caixa de bate-papo e pressione " -"espaço, ou clique no texto via @UnuRobot ao lado das " -"mensagens. Você verá suas cartas (algumas esmaecidas), opções extras como " -"desenhar e um ? para ver o estado atual do jogo. As cartas " -"acinzentadas são aquelas que você não pode jogar no momento. " -"Toque em uma opção para executar a ação selecionada.\n" -"Os jogadores podem entrar na partida a qualquer momento. Para sair de uma " -"partida, use /leave. Se um jogador demorar mais de 90 segundos para jogar, " -"você pode usar /skip para pular esse jogador. Use /notify_me para receber " -"uma mensagem privada quando um novo jogo for iniciado.\n" -"\n" -"Idioma e outras configurações: /settings\n" -"Outros comandos (somente criador do jogo):\n" -"/close - Fechar lobby\n" -"/open - Abrir lobby\n" -"/kill - Termina o jogo\n" -"/kick - Selecione um jogador para chutar respondendo a ele\n" -"/enable_translations - Traduz textos relevantes para todos os idiomas " -"falados em um jogo\n" -"/disable_translations - Use inglês para esses textos\n" -"\n" -"Experimental: Jogue em vários grupos ao mesmo tempo. Pressione o " -"botão Partida atual: ... e selecione o grupo no qual deseja " -"jogar uma carta.\n" -"Se você gosta deste bot, entre no canal de atualização e compre um jogo de cartas UNO." - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" -"Este bot do UNO tem cinco modos de jogo: Clássico, Sanico, Selvagem, Texto e " -"7-0.\n" -"\n" -" 🎻 O modo Clássico utiliza o deck convencional UNO e não há pulo automático " -"de jogadores.\n" -" 🚀 O modo Sanico usa o deck UNO convencional e o bot pula automaticamente " -"um jogador se ele demorar muito tempo para jogar sua vez.\n" -" 🐉 O modo Selvagem usa um baralho com mais cartas especiais, menos " -"variedade de números e sem pulo automático.\n" -" ✍️ O modo Texto usa o baralho convencional UNO, mas em vez de stickers, usa " -"texto.\n" -" 🔫 O modo 7-0 usa o baralho convencional UNO, mas quando um jogador joga um " -"7, ele pode escolher um jogador para trocar as cartas. Quando um jogador " -"joga um 0, todas as cartas serão trocadas entre os jogadores atuais.\n" -"\n" -"Para mudar o modo de jogo, o CRIADOR DO JOGO tem que digitar o username do " -"bot e um espaço, assim como quando se joga uma carta, e todas as opções de " -"modo de jogo devem aparecer." - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"Esse bot é um Software livre, grátis e licenciado com AGPL. O código está " -"disponível aqui: \n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" -"Atribuições:\n" -"Ícone de retirada de cartas feito por Faithtoken\n" -"Ícone de passe feito pot por Delapouite\n" -"Originais disponíveis em http://game-icons.net\n" -"Ícones editados por ɳick" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "Todas as novidades aqui: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"Você não habilitou as estatísticas. Use /settings em uma conversa privada " -"com o bot para ativá-las." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "{number} partida jogada" -msgstr[1] "{number} partidas jogadas" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "{number} vez em primeiro lugar ({percent}%)" -msgstr[1] "{number} vezes em primeiro lugar ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "{number} carta jogada" -msgstr[1] "{number} cartas jogadas" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} Vermelho" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} Azul" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} Verde" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} Amarelo" diff --git a/locales/ru_RU/LC_MESSAGES/unobot.po b/locales/ru_RU/LC_MESSAGES/unobot.po deleted file mode 100644 index 01414bc..0000000 --- a/locales/ru_RU/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,557 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# Jannes Höke , 2016. -# -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2022-11-12 05:22+0000\n" -"Last-Translator: Alisson Lauffer \n" -"Language-Team: Russian " -"\n" -"Language: ru_RU\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: utf-8\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} победил!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "Игра окончена!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "Пожалуйста, выберите цвет" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "В колоде больше нет карт." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "Это блеф! {name} получает 4 карты" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} не блефовал! {name2} получает 6 карт" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" -"Отправьте эту команду в группе, чтобы получать уведомления о новых партиях." - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "В {title} началась новая игра" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "" -"Создана новая игра! Присоединитесь к ней командой /join и начните, написав /" -"start" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "Нет ни одной игры в данном чате." - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "" - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "Лобби закрыто" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "Нет активных партий в данный момент. Создайте новую, написав /new" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "Вы уже присоединились к этой игре. Начните ее с помощью /start" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" - -#: bot.py:250 -msgid "Joined the game" -msgstr "Присоединился к игре" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "Вы не играете в данной группе." - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "Ок. Следующий игрок: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "" - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "" - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "" - -#: bot.py:426 -msgid "Game not found." -msgstr "Игры не найдены." - -#: bot.py:433 -msgid "Back to last group" -msgstr "Вернуться к последней группе" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "Пожалуйста, переключитесь на выбранную группу!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"Выбранная группа: {group}\n" -"Убедитесь, что Вы переключились на нее!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "Удаляю {name} из игры" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "Нет ни одной игры в данном чате. Создайте новую командой /new" - -#: bot.py:508 -msgid "The game has already started" -msgstr "Игра уже началась" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"Первый игрок: {name}\n" -"Напишите /close, чтобы запретить присоединяться к этой игре.\n" -"Включите перевод текстов командой /enable_translations" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "Пожалуйста, выберите группу, в которой хотите играть." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "Лобби закрыто. К данной игре нельзя присоединиться." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "Лобби открыто. Теперь к игре можно присоединиться." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "Перевод активирован. Выключите с помощью /disable_translations" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "" -"Перевод отключен. Вы можете включить его с помощью /enable_translations" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "Вы не играете ни в одну из партий в данном чате." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "Пожалуйста, подождите {time} секунды" -msgstr[1] "Пожалуйста, подождите {time} секунд" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "Текущая игра: {game}" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "{name} попытался сжульничать" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "Следующий игрок: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "Выберите цвет" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "" -msgstr[1] "" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} карты)" -msgstr[1] "{name} ({number} карт)" - -#: results.py:91 -msgid "You are not playing" -msgstr "Вы не играете" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"В данный момент Вы не играете. Используйте /new, чтобы начать новую, или /" -"join, чтобы присоединиться к текущей" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "Игра еще не началась" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "Начните новую игру с помощью /start" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "Забирает {number} карты" -msgstr[1] "Забирает {number} карты" - -#: results.py:209 -msgid "Pass" -msgstr "Пас" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "Я бросаю тебе вызов!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "Текущий игрок: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "Последняя карта: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "Игрок: {player_list}" -msgstr[1] "Игроки: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "Пожалуйста, напишите боту для изменения своих настроек." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "Удалить всю статистику" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "Включить статистику" - -#: settings.py:50 -msgid "Language" -msgstr "Язык" - -#: settings.py:53 -msgid "Settings" -msgstr "Настройки" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "Статистика включена!" - -#: settings.py:77 -msgid "Select locale" -msgstr "Выберите язык" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "Статистика удалена и отключена!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "Язык установлен!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"Этот бот является программой с открытым исходным кодом и выпущен под " -"лицензией AGPL. Весь код доступен по адресу:\n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "Все новости здесь: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"Вы не включали статистику. Чтобы ее активировать, напишите /settings в " -"приватном чате с ботом." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "{number} игры сыграно" -msgstr[1] "{number} игр сыграно" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "{number} первое место ({percent}%)" -msgstr[1] "{number} первых мест ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "{number} карты сыграно" -msgstr[1] "{number} карты сыграно" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} Красный" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} Синий" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} Зеленый" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} Желтый" diff --git a/locales/tr_TR/LC_MESSAGES/unobot.po b/locales/tr_TR/LC_MESSAGES/unobot.po deleted file mode 100644 index 9088ba3..0000000 --- a/locales/tr_TR/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,558 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 1.0\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2022-11-12 05:22+0000\n" -"Last-Translator: Alisson Lauffer \n" -"Language-Team: Turkish " -"\n" -"Language: tr_TR\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" -"Bu oyuncuyu atlamak için gereken süre {time} saniyeye düşürüldü.\n" -"Sıradaki oyuncu: {name}" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" -"{name1}’ın süresi doldu ve oyundan çıkarıldı!\n" -"Sıradaki oyuncu: {name2}" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" -"{name}’ın süresi doldu ve oyundan çıkarıldı!\n" -"Oyun sona erdi." - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} kazandı!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "Oyun Bitti!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "Lütfen bir renk seçin" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "Destede yeterli kart kalmadı." - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "Blöf yapıyor! {name}’a 4 kart ver" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} blöf yapmıyordu! {name2}’a 6 kart ver" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" -"Bu komutu, bir grupta yeni bir oyuna başladığında bildirim almak için o " -"gruba gönderin." - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "Şu grupta yeni bir oyun başladı: {title}" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "" -"Yeni bir oyun oluşturuldu! Oyuna katılmak için /join yaz ve oyunu başlatmak " -"için /start komutunu gönder" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "Bu sohbette başlamış bir oyun yok." - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" -"Oyun henüz başlamadı. Oyuna katılmak için /join yazve oyunu başlatmak için /" -"start komutunu gönder" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "Yalnızca oyunun kurucusu ({name}) ve yönetici bunu yapabilir." - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "Girişler kapatıldı" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "Şu anda oyun mevcut değil. /new ile yeni bir oyun oluşturabilirsin" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "Zaten oyuna katıldın. Oyunu başlatmak için /start komutunu kullan" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "Yeni oyuncuların katılması için destede yeterli kart kalmadı." - -#: bot.py:250 -msgid "Joined the game" -msgstr "Oyuna katıldın" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "Bu gruptaki bir oyunda yoksunuz." - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "Pekala. Sıradaki Oyuncu: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "{name}, başlamadan oyundan ayrıldı." - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "Oyuncu {name} mevcut oyunda bulunamadı." - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "{0}, {1} tarafından atıldı" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "Lütfen atmak istediğiniz kişiyi alıntılayarak/kick komutunu yazın" - -#: bot.py:426 -msgid "Game not found." -msgstr "Oyun bulunamadı." - -#: bot.py:433 -msgid "Back to last group" -msgstr "Son gruba geri dön" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "Lütfen seçtiğiniz gruba geçin!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"Grup seçildi: {group}\n" -" Doğru gruba geçtiğinizden emin olun!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "{name} oyundan silindi" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "Bu sohbette şu an oyun yok. /new ile yeni bir oyun oluşturabilirsin" - -#: bot.py:508 -msgid "The game has already started" -msgstr "Oyun zaten başladı" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" -"Oyun başlatmak için en az {minplayers} kişi oyuna /join yazarak katılmalı" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"İlk oyuncu: {name}\n" -"/close yazarak oyuna daha fazla kişinin katılmasını kapatabilirsin.\n" -"Çoklu dili etkinleştirmek için /enable_translations yaz" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "Lütfen oynamak istediğiniz grubu seçin." - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "Girişler kapatıldı. Oyuna daha fazla oyuncu katılamaz." - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "Girişler açıldı. Yeni oyuncular /join yazarak oyuna katılabilir." - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "Çoklu dil etkinleştirildi. Kapatmak için /disable_translations yaz" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "Çoklu dil kapatıldı. Açmak için /enable_translations yaz" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "Bu sohbetteki bir oyunda oynamıyorsun." - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "Lütfen {time} saniye bekleyin" -msgstr[1] "Lütfen {time} saniye bekleyin" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "Mevcut oyun: {game}" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "Oyun modu değiştirildi: {mode}" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "{name}, hile yapmaya çalıştı" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "Sıradaki oyuncu: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "{name} için bekleme süresi {time} saniye olarak sıfırlandı" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "Renk Seç" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "Kart (oyun durumu için dokunun):" -msgstr[1] "Kartlar (oyun durumu için dokunun):" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name}’ın ({number} kartı kaldı.)" -msgstr[1] "{name}’ın ({number} kartı kaldı.)" - -#: results.py:91 -msgid "You are not playing" -msgstr "Oyunda değilsin" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"Şu anda bir oyunda yoksun. Yeni bir oyun kurmak için /new, mevcut oyuna " -"katılmak için /join yaz" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "Oyun henüz başlamadı" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "Oyunu /start ile başlat" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "🎻 Klasik mod" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "Klasik 🎻" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "🚀 Fişek mod" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "Daha hızlı ol! 🚀" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "🐉 Vahşi mod" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "Vahşi doğuya ~ 🐉" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "{number} kart çekildi" -msgstr[1] "{number} kart çekildi" - -#: results.py:209 -msgid "Pass" -msgstr "Pas" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "Blöf yapıyorsun!!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "Şu anki oyuncu: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "Son kart: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "Oyuncu: {player_list}" -msgstr[1] "Oyuncular: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "Lütfen ayarlarınızı botun özel sohbetinde düzenleyin." - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "Tüm istatistikleri sil" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "İstatistikleri Aç" - -#: settings.py:50 -msgid "Language" -msgstr "Dil" - -#: settings.py:53 -msgid "Settings" -msgstr "Ayarlar" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "İstatistikler açıldı!" - -#: settings.py:77 -msgid "Select locale" -msgstr "Dili seçiniz" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "İstatistikler devredışı bırakıldı ve silindi!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "Dil seçildi!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"Bu bot Açık Kaynak ve AGPL lisanslıdır. Kodları burada: \n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" -"Teşekkürler:\n" -"Çekme simgesi Faithtoken\n" -"Pas simgesi Delapouite\n" -"Orijinalleri http://game-icons.net\n" -"ɳick taradından düzenlendi.\n" -"Türkçe çevirisi: @holytotem tarafından yapılmıştır." - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "Tüm yenilikler burada: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"İstatistikleri etkinleştirmediniz. Bota özel sohbetten/settings komutunu " -"gönderve istatistik ayarını aç." - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "{number} Oyun oynandı" -msgstr[1] "{number} Oyun oynandı" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "{number} Defa birincilik ({percent}%)" -msgstr[1] "{number} Defa birincilik ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "{number} Kart oynandı" -msgstr[1] "{number} Kart oynandı" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} Kırmızı" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} Mavi" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} Yeşil" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} Sarı" diff --git a/locales/unobot.pot b/locales/unobot.pot deleted file mode 100644 index 6598b90..0000000 --- a/locales/unobot.pot +++ /dev/null @@ -1,527 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 1.0\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "" - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "" - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "" - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" - -#: bot.py:250 -msgid "Joined the game" -msgstr "" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "" - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "" - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "" - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "" - -#: bot.py:426 -msgid "Game not found." -msgstr "" - -#: bot.py:433 -msgid "Back to last group" -msgstr "" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "" - -#: bot.py:508 -msgid "The game has already started" -msgstr "" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "" - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "" - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "" - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "" - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "" -msgstr[1] "" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "" -msgstr[1] "" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "" -msgstr[1] "" - -#: results.py:91 -msgid "You are not playing" -msgstr "" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "" -msgstr[1] "" - -#: results.py:209 -msgid "Pass" -msgstr "" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "" -msgstr[1] "" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "" - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "" - -#: settings.py:50 -msgid "Language" -msgstr "" - -#: settings.py:53 -msgid "Settings" -msgstr "" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "" - -#: settings.py:77 -msgid "Select locale" -msgstr "" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "" - -#: settings.py:100 -msgid "Set locale!" -msgstr "" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "" -msgstr[1] "" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "" -msgstr[1] "" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "" -msgstr[1] "" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "" diff --git a/locales/zh_CN/LC_MESSAGES/unobot.po b/locales/zh_CN/LC_MESSAGES/unobot.po deleted file mode 100644 index 41ade41..0000000 --- a/locales/zh_CN/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,551 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2022-11-11 01:28+0000\n" -"Last-Translator: Anonymous \n" -"Language-Team: Chinese (Simplified) \n" -"Language: zh_CN\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" -"该玩家的等待时间已降至 {time} 秒。\n" -"轮到: {name}" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" -"{name1} 已经被连续跳过了 4 次。\n" -"轮到: {name2}" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" -"{name} 已经被连续跳过了 4 次。\n" -"游戏结束。" - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} 赢了!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "游戏结束!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "请选择颜色" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "牌堆中已经没有更多的牌了。" - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "质疑成功!给 {name} 4 张牌" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "质疑 {name1} 失败!给 {name2} 6 张牌" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "在群组中发送该指令,以在新游戏开始时通知您。" - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "新游戏已在 {title} 开始" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "创建新游戏成功!请使用 /join 加入游戏,然后使用 /start 开始游戏" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "这个群中并没有正在运行的游戏。" - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "游戏尚未开始。请使用 /join 加入游戏,然后使用 /start 开始游戏" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "只有游戏创建者 ({name}) 和管理员才能执行该命令。" - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "已禁止中途加入游戏" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "这个群并没有运行中的游戏。请使用 /new 创建新游戏" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "您已经加入了游戏。请使用 /start 开始游戏" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "牌堆中已经没有足够给新加入玩家的牌了。" - -#: bot.py:250 -msgid "Joined the game" -msgstr "游戏加入成功" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "您在这个群中并没有参加游戏。" - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "好的,轮到: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "{name} 在游戏开始前就离开游戏了。" - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "未在当前游戏中找到{name}玩家。" - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "{0} 已被 {1} 踢出游戏" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "请回复要踢出的人,并再次输入 /kick 。" - -#: bot.py:426 -msgid "Game not found." -msgstr "游戏未找到。" - -#: bot.py:433 -msgid "Back to last group" -msgstr "返回上一个群" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "请切换到您选择的群!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"选择群: {group}\n" -"请确保您已切换到正确的群!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "已成功将 {name} 移出游戏" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "这个群并没有运行中的游戏。请使用 /new 创建新游戏" - -#: bot.py:508 -msgid "The game has already started" -msgstr "游戏已经开始" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "至少需要 {minplayers} 个人 /join 加入游戏,才能开始游戏" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"第一个出牌的玩家: {name}\n" -"可使用 /close 阻止其他人中途加入游戏。\n" -"使用 /enable_translations 启动游戏翻译功能" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "请选择您要参加游戏的群。" - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "游戏已设置成不允许中途加入,玩家将不允许加入游戏。" - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "游戏已设置成允许中途加入,新玩家现在可以使用 /join 加入游戏。" - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "游戏翻译已启用,使用 /disable_translations 可以停用该功能" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "游戏翻译已停用,使用 /enable_translations 可以启用该功能" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "您并不在游戏中。" - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "请等待 {time} 秒" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "当前游戏: {game}" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "游戏模式已切换为 {mode}" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "{name} 试图作弊" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "轮到: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "{name} 的等待时间已经重置为 {time} 秒" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "选择颜色" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "手牌 (点击查看游戏状况):" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} 张牌)" - -#: results.py:91 -msgid "You are not playing" -msgstr "您并不在游戏中" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "" -"您并不在游戏中。请使用 /new 创建一个新游戏,或者使用 /join 加入一个现有的游戏" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "游戏还没有开始" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "请先使用 /start 开始游戏" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "🎻 经典模式" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "经典 🎻" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "🚀 Sanic 模式" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "搞快点! 🚀\"" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "🐉 野性模式" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "进入旷野~ 🐉" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "抽取 {number} 张牌" - -#: results.py:209 -msgid "Pass" -msgstr "过" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "我要质疑你!" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "轮到: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "上一张牌: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "玩家: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "请私聊我修改您的设置。" - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "删除所有统计数据" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "启用数据统计" - -#: settings.py:50 -msgid "Language" -msgstr "语言" - -#: settings.py:53 -msgid "Settings" -msgstr "设置" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "数据统计已启用!" - -#: settings.py:77 -msgid "Select locale" -msgstr "请选择语言" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "统计数据已经被删除并已停用!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "语言设置成功!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"本机器人是一个在 AGPL 协议下发行的自由软件。源代码可以在这里取得:\n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" -"来源:\n" -"抽牌图标来自 Faithtoken。\n" -"跳过图标來自 Delapouite。\n" -"原始图标可在 http://game-icons.net 获取。\n" -"图标由 ɳick 编辑" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "查看机器人的所有更新: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "您并没有启用数据统计。请私聊我发送 /settings 进行设置。" - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "玩了 {number} 盘" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "赢了 {number} 盘 ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "总共出过 {number} 张牌" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} 红色" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} 蓝色" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} 绿色" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} 黄色" diff --git a/locales/zh_HK/LC_MESSAGES/unobot.po b/locales/zh_HK/LC_MESSAGES/unobot.po deleted file mode 100644 index cdd2704..0000000 --- a/locales/zh_HK/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,540 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2022-11-12 05:22+0000\n" -"Last-Translator: Alisson Lauffer \n" -"Language-Team: Chinese (Traditional, Hong Kong) \n" -"Language: zh_HK\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} 贏咗!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "遊戲結束!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "請揀一隻顏色" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "檯上面冇哂牌" - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "Call咗bluff, {name} draw 4張牌" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1}冇bluff, {name2} draw 6 張牌" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "" - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "已經開始咗新一盤! 用/join加入同埋/start去開始" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "呢個對話入面冇嘢玩緊喎。" - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "" - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "Lobby已經閂咗" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "宜家冇遊戲運行, 用 /new開展新一盤" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "你已經加入咗啦, 用 /start開始呢一盤" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "" - -#: bot.py:250 -msgid "Joined the game" -msgstr "加入咗" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "你唔喺呢個group玩緊" - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "OK 下一個: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "" - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "" - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "" - -#: bot.py:426 -msgid "Game not found." -msgstr "Game not found." - -#: bot.py:433 -msgid "Back to last group" -msgstr "去返前一個group" - -#: bot.py:437 -#, fuzzy -msgid "Please switch to the group you selected!" -msgstr "請轉去你揀咗果個group!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"揀咗呢個group: {group}\n" -"記住轉過去正確嘅group" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "{name} 已經比人踢咗" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "呢個對話入面冇遊戲運行緊, 用/new開始新一盤" - -#: bot.py:508 -msgid "The game has already started" -msgstr "呢一盤已經開始咗" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"第一個玩家: {name}\n" -"唔想其他人加入遊戲嘅話可以選擇 /close\n" -"用 /enable_translations 啓用翻譯功能" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "你想喺邊個group玩?" - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "Lobby已經閂咗, 其他玩家已經冇得加入" - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "開咗個lobby, 宜家可以 /join 呢一盤" - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "啓用咗其他語言, 可以用 /disable_translations 停用" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "已經停用咗其他語言, 想重新嘅話可以揀 /enable_translations" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "你冇喺呢個對話入面玩。" - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "請等{time}秒" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "{name} chok cheat" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "下一個: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "揀顏色" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} ({number} 張牌)" - -#: results.py:91 -msgid "You are not playing" -msgstr "你唔係玩緊喎" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "你唔係玩緊喎, 用 /new 開始新一盤或者 /join 加入宜家嘅遊戲" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "呢一盤仲未開始喎" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "用/start開始呢一盤" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "Draw緊{number}張牌" - -#: results.py:209 -msgid "Pass" -msgstr "Pass" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "我call你bluff" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "宜家嘅玩家: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "前一張牌: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "玩家: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "請pm個bot修改你嘅設定" - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "刪除所有數據" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "啓用數據記錄" - -#: settings.py:50 -msgid "Language" -msgstr "語言" - -#: settings.py:53 -msgid "Settings" -msgstr "設定" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "已經啓用咗數據記錄!" - -#: settings.py:77 -msgid "Select locale" -msgstr "請揀個區域" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "已經熄咗同埋delete咗數據記錄!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "Set咗個區域!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"呢個bot係一個免費嘅Software, 根據AGPL授權 \n" -"Code可以係呢度搵到\n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "所有update都喺晒度: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "你冇啓用數據記錄, pm個bot去啓用。" - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "玩咗{number}盤" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "贏咗{number}次 ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "已經玩咗{number}張牌" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} 紅色" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} 藍色" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} 綠色" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} 黃色" diff --git a/locales/zh_TW/LC_MESSAGES/unobot.po b/locales/zh_TW/LC_MESSAGES/unobot.po deleted file mode 100644 index aa87da2..0000000 --- a/locales/zh_TW/LC_MESSAGES/unobot.po +++ /dev/null @@ -1,552 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -msgid "" -msgstr "" -"Project-Id-Version: uno_bot 0.1\n" -"Report-Msgid-Bugs-To: uno@jhoeke.de\n" -"POT-Creation-Date: 2022-11-13 01:49-0300\n" -"PO-Revision-Date: 2022-11-12 05:22+0000\n" -"Last-Translator: Alisson Lauffer \n" -"Language-Team: Chinese (Traditional) \n" -"Language: zh_TW\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.15-dev\n" - -#: actions.py:43 -#, python-brace-format -msgid "" -"Waiting time to skip this player has been reduced to {time} seconds.\n" -"Next player: {name}" -msgstr "" -"跳過此玩家的等待時間已縮短至 {time} 秒。\n" -"輪到: {name}" - -#: actions.py:61 -#, python-brace-format -msgid "" -"{name1} ran out of time and has been removed from the game!\n" -"Next player: {name2}" -msgstr "" -"{name1} 已逾時,且已將其從此場遊戲移除!\n" -"輪到: {name2}" - -#: actions.py:78 -#, python-brace-format -msgid "" -"{name} ran out of time and has been removed from the game!\n" -"The game ended." -msgstr "" -"{name} 已逾時,且已將其從此場遊戲移除!\n" -"遊戲結束。" - -#: actions.py:125 actions.py:172 -#, python-brace-format -msgid "{name} won!" -msgstr "{name} 贏了!" - -#: actions.py:139 actions.py:186 bot.py:179 bot.py:288 bot.py:373 bot.py:473 -msgid "Game ended!" -msgstr "遊戲結束!" - -#: actions.py:164 -msgid "Please choose a color" -msgstr "請選擇顏色" - -#: actions.py:206 actions.py:233 actions.py:249 -msgid "There are no more cards in the deck." -msgstr "卡堆中已經沒牌了。" - -#: actions.py:224 -#, python-brace-format -msgid "Bluff called! Giving 4 cards to {name}" -msgstr "已確定為虛張聲勢! 給 {name} 4 張牌" - -#: actions.py:241 -#, python-brace-format -msgid "{name1} didn't bluff! Giving 6 cards to {name2}" -msgstr "{name1} 並未虛張聲勢! 給 {name2} 6 張牌" - -#: bot.py:99 -msgid "" -"Send this command in a group to be notified when a new game is started there." -msgstr "請將這個指令傳到群組中,以在新遊戲開始時通知您。" - -#: bot.py:113 -msgid "" -"Okay, you will be notified in a private message when the next game is " -"started in this chat. Make sure that I'm allowed to send you messages." -msgstr "" - -#: bot.py:134 -#, python-brace-format -msgid "A new game has been started in {title}" -msgstr "新遊戲已經在 {title} 開始!" - -#: bot.py:148 -msgid "" -"Created a new game! Join the game with /join and start the game with /start" -msgstr "已建立新遊戲! 使用 /join 加入遊戲,並使用 /start 開始遊戲" - -#: bot.py:168 bot.py:595 bot.py:630 bot.py:665 bot.py:700 -msgid "There is no running game in this chat." -msgstr "此聊天室尚無進行中的遊戲。" - -#: bot.py:185 bot.py:336 -msgid "" -"The game is not started yet. Join the game with /join and start the game " -"with /start" -msgstr "遊戲尚未開始。請使用 /join 加入遊戲,並使用 /start 開始遊戲" - -#: bot.py:194 bot.py:406 bot.py:611 bot.py:646 bot.py:681 bot.py:720 -#, python-brace-format -msgid "Only the game creator ({name}) and admin can do that." -msgstr "只有遊戲建立者 ({name}) 及管理員才能執行。" - -#: bot.py:216 -msgid "The lobby is closed" -msgstr "遊戲大廳已關閉" - -#: bot.py:223 bot.py:326 -msgid "No game is running at the moment. Create a new game with /new" -msgstr "目前沒有進行中的遊戲。請使用 /new 建立新遊戲" - -#: bot.py:231 -msgid "You already joined the game. Start the game with /start" -msgstr "您已加入遊戲。請使用 /start 開始遊戲" - -#: bot.py:240 -msgid "There are not enough cards left in the deck for new players to join." -msgstr "卡堆中已經沒有足夠給新進玩家的牌了。" - -#: bot.py:250 -msgid "Joined the game" -msgstr "已加入遊戲" - -#: bot.py:267 bot.py:282 -msgid "You are not playing in a game in this group." -msgstr "您不在此群組的遊戲中。" - -#: bot.py:294 bot.py:397 -#, python-brace-format -msgid "Okay. Next Player: {name}" -msgstr "好的。下一位玩家: {name}" - -#: bot.py:303 -#, python-brace-format -msgid "{name} left the game before it started." -msgstr "{name} 在遊戲開始前就離開遊戲了。" - -#: bot.py:355 -#, python-brace-format -msgid "Player {name} is not found in the current game." -msgstr "未在目前遊戲找到 {name} 玩家。" - -#: bot.py:368 bot.py:379 -#, python-brace-format -msgid "{0} was kicked by {1}" -msgstr "{0} 被 {1} 踢出" - -#: bot.py:389 -msgid "Please reply to the person you want to kick and type /kick again." -msgstr "請回覆要踢出的人,並再次輸入 /kick 。" - -#: bot.py:426 -msgid "Game not found." -msgstr "找不到遊戲。" - -#: bot.py:433 -msgid "Back to last group" -msgstr "回到上一個群組" - -#: bot.py:437 -msgid "Please switch to the group you selected!" -msgstr "請切換到您選取的群組!" - -#: bot.py:445 -#, python-brace-format -msgid "" -"Selected group: {group}\n" -"Make sure that you switch to the correct group!" -msgstr "" -"已選擇的群組: {group}\n" -"請確保您已切換到正確群組!" - -#: bot.py:479 -#, python-brace-format -msgid "Removing {name} from the game" -msgstr "將 {name} 從遊戲移除" - -#: bot.py:501 -msgid "There is no game running in this chat. Create a new one with /new" -msgstr "此聊天室目前沒有進行中的遊戲,使用 /new 開始新遊戲" - -#: bot.py:508 -msgid "The game has already started" -msgstr "遊戲已經開始" - -#: bot.py:514 -#, python-brace-format -msgid "" -"At least {minplayers} players must /join the game before you can start it" -msgstr "必須至少要有 {minplayers} 個人 /join 才能開始遊戲" - -#: bot.py:528 bot.py:931 -msgid "Make your choice!" -msgstr "" - -#: bot.py:533 -#, python-brace-format -msgid "" -"First player: {name}\n" -"Use /close to stop people from joining the game.\n" -"Enable multi-translations with /enable_translations" -msgstr "" -"第一位玩家: {name}\n" -"可使用 /close 防止玩家加入此場遊戲。\n" -"請使用 /enable_translations 開啟多翻譯模式" - -#: bot.py:577 -msgid "Please select the group you want to play in." -msgstr "請選擇你要遊玩的群組。" - -#: bot.py:606 -msgid "Closed the lobby. No more players can join this game." -msgstr "已關閉遊戲大廳。其他玩家無法再加入此場遊戲。" - -#: bot.py:641 -msgid "Opened the lobby. New players may /join the game." -msgstr "已開啟遊戲大廳。新玩家可以使用 /join 加入此場遊戲。" - -#: bot.py:676 -msgid "Enabled multi-translations. Disable with /disable_translations" -msgstr "已啟用多翻譯模式。可使用 /disable_translations 停用" - -#: bot.py:712 -msgid "" -"Disabled multi-translations. Enable them again with /enable_translations" -msgstr "已停用多翻譯模式。可使用 /enable_translations 再次啟用。" - -#: bot.py:740 -msgid "You are not playing in a game in this chat." -msgstr "您不在此聊天室的遊戲中。" - -#: bot.py:758 -#, python-brace-format -msgid "Please wait {time} second" -msgid_plural "Please wait {time} seconds" -msgstr[0] "請等待 {time} 秒" - -#: bot.py:837 -#, python-brace-format -msgid "Current game: {game}" -msgstr "目前遊戲: {game}" - -#: bot.py:877 -#, python-brace-format -msgid "Gamemode changed to {mode}" -msgstr "遊戲模式已變更成 {mode}" - -#: bot.py:884 -#, python-brace-format -msgid "Cheat attempt by {name}" -msgstr "{name} 嘗試作弊" - -#: bot.py:925 -#, python-brace-format -msgid "Next player: {name}" -msgstr "輪到: {name}" - -#: bot.py:951 -#, python-brace-format -msgid "Waiting time for {name} has been reset to {time} seconds" -msgstr "{name} 的等待時間已重設成 {time} 秒" - -#: results.py:37 -msgid "Choose Player" -msgstr "" - -#: results.py:50 -msgid "Choose Color" -msgstr "選擇顏色" - -#: results.py:66 -msgid "Card (tap for game state):" -msgid_plural "Cards (tap for game state):" -msgstr[0] "卡牌 (按一下取得遊戲狀態):" - -#: results.py:80 -#, python-brace-format -msgid "{name} ({number} card)" -msgid_plural "{name} ({number} cards)" -msgstr[0] "{name} (有 {number} 張牌)" - -#: results.py:91 -msgid "You are not playing" -msgstr "您不在遊戲中" - -#: results.py:94 -msgid "" -"Not playing right now. Use /new to start a game or /join to join the current " -"game in this group" -msgstr "您現在不在遊戲中。請使用 /new 開始新遊戲,或使用 /join 加入目前此群組的遊戲" - -#: results.py:108 -msgid "The game wasn't started yet" -msgstr "遊戲尚未開始" - -#: results.py:110 -msgid "Start the game with /start" -msgstr "請使用 /start 開始遊戲" - -#: results.py:121 -msgid "🎻 Classic mode" -msgstr "🎻 傳統模式" - -#: results.py:122 -msgid "Classic 🎻" -msgstr "傳統 🎻" - -#: results.py:132 -msgid "🚀 Sanic mode" -msgstr "🚀 Sanic 模式" - -#: results.py:133 -msgid "Gotta go fast! 🚀" -msgstr "得快點! 🚀" - -#: results.py:143 -msgid "🐉 Wild mode" -msgstr "🐉 野外 (Wild) 模式" - -#: results.py:144 -msgid "Into the Wild~ 🐉" -msgstr "走進野外~ 🐉" - -#: results.py:153 -msgid "🔫 7-0 mode" -msgstr "" - -#: results.py:154 -msgid "Carioca mode on 🔫" -msgstr "" - -#: results.py:164 -msgid "✍️ Text mode" -msgstr "" - -#: results.py:165 -msgid "Text ✍️" -msgstr "" - -#: results.py:180 -#, python-brace-format -msgid "Drawing {number} card" -msgid_plural "Drawing {number} cards" -msgstr[0] "抽 {number} 張牌" - -#: results.py:209 -msgid "Pass" -msgstr "PASS! 下一位!" - -#: results.py:222 -msgid "I'm calling your bluff!" -msgstr "別騙了,虛張聲勢 = =" - -#: results.py:262 -#, python-brace-format -msgid "Current player: {name}" -msgstr "目前玩家: {name}" - -#: results.py:264 -#, python-brace-format -msgid "Last card: {card}" -msgstr "上一張牌: {card}" - -#: results.py:266 -#, python-brace-format -msgid "Player: {player_list}" -msgid_plural "Players: {player_list}" -msgstr[0] "玩家: {player_list}" - -#: settings.py:34 -msgid "Please edit your settings in a private chat with the bot." -msgstr "請私訊這台機器人來編輯設定。" - -#: settings.py:45 -msgid "Delete all statistics" -msgstr "刪除所有統計資料" - -#: settings.py:47 -msgid "Enable statistics" -msgstr "啟用統計資料" - -#: settings.py:50 -msgid "Language" -msgstr "語言" - -#: settings.py:53 -msgid "Settings" -msgstr "設定" - -#: settings.py:67 -msgid "Enabled statistics!" -msgstr "已啟用統計資料!" - -#: settings.py:77 -msgid "Select locale" -msgstr "選擇語言" - -#: settings.py:87 -msgid "Deleted and disabled statistics!" -msgstr "已停用並刪除統計資料!" - -#: settings.py:100 -msgid "Set locale!" -msgstr "已設定語言!" - -#: simple_commands.py:31 -msgid "" -"Follow these steps:\n" -"\n" -"1. Add this bot to a group\n" -"2. In the group, start a new game with /new or join an already running game " -"with /join\n" -"3. After at least two players have joined, start the game with /start\n" -"4. Type @UnuRobot into your chat box and hit space, or " -"click the via @UnuRobot text next to messages. You will see " -"your cards (some greyed out), any extra options like drawing, and a ? " -"to see the current game state. The greyed out cards are those you " -"can not play at the moment. Tap an option to execute the selected " -"action.\n" -"Players can join the game at any time. To leave a game, use /leave. If a " -"player takes more than 90 seconds to play, you can use /skip to skip that " -"player. Use /notify_me to receive a private message when a new game is " -"started.\n" -"\n" -"Language and other settings: /settings\n" -"Other commands (only game creator):\n" -"/close - Close lobby\n" -"/open - Open lobby\n" -"/kill - Terminate the game\n" -"/kick - Select a player to kick by replying to him or her\n" -"/enable_translations - Translate relevant texts into all languages spoken in " -"a game\n" -"/disable_translations - Use English for those texts\n" -"\n" -"Experimental: Play in multiple groups at the same time. Press the " -"Current game: ... button and select the group you want to play " -"a card in.\n" -"If you enjoy this bot, join the update channel and buy an UNO card game." -msgstr "" - -#: simple_commands.py:79 -msgid "" -"This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n" -"\n" -" 🎻 The Classic mode uses the conventional UNO deck and there is no auto " -"skip.\n" -" 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically " -"skips a player if he/she takes too long to play its turn\n" -" 🐉 The Wild mode uses a deck with more special cards, less number variety " -"and no auto skip.\n" -" ✍️ The Text mode uses the conventional UNO deck but instead of stickers it " -"uses the text.\n" -" 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, " -"he/she can choose a player to swap cards with. When a player plays a 0, all " -"cards will be swapped between the current players.\n" -"\n" -"To change the game mode, the GAME CREATOR has to type the bot nickname and a " -"space, just like when playing a card, and all gamemode options should appear." -msgstr "" - -#: simple_commands.py:102 -msgid "" -"This bot is Free Software and licensed under the AGPL. The code is available " -"here: \n" -"https://github.com/AmanoTeam/UnuRobot" -msgstr "" -"這台機器人是自由軟體,使用 AGPL 授權。程式碼可在此處取得:\n" -"https://github.com/AmanoTeam/UnuRobot" - -#: simple_commands.py:107 -msgid "" -"Attributions:\n" -"Draw icon by Faithtoken\n" -"Pass icon by Delapouite\n" -"Originals available on http://game-icons.net\n" -"Icons edited by ɳick" -msgstr "" -"來源:\n" -"抽牌 (Draw) 圖示來自 Faithtoken。\n" -"跳過 (Pass) 圖示來自 Delapouite。\n" -"原始圖示可在 http://game-icons.net 取得。\n" -"圖示由 ɳick 編輯。" - -#: simple_commands.py:130 -msgid "All news here: https://t.me/UnuRobotUpdates" -msgstr "新聞頻道: https://t.me/UnuRobotUpdates" - -#: simple_commands.py:145 -msgid "" -"You did not enable statistics. Use /settings in a private chat with the bot " -"to enable them." -msgstr "" -"您尚未啟用統計資料。請在這台機器人的私人對話中傳送 /settings 以" -"啟用。" - -#: simple_commands.py:153 -#, python-brace-format -msgid "{number} game played" -msgid_plural "{number} games played" -msgstr[0] "已遊玩 {number} 場遊戲" - -#: simple_commands.py:160 -#, python-brace-format -msgid "{number} first place ({percent}%)" -msgid_plural "{number} first places ({percent}%)" -msgstr[0] "拿了 {number} 次第一名 ({percent}%)" - -#: simple_commands.py:168 -#, python-brace-format -msgid "{number} card played" -msgid_plural "{number} cards played" -msgstr[0] "已遊玩 {number} 張牌" - -#: utils.py:54 utils.py:66 -#, python-brace-format -msgid "{emoji} Red" -msgstr "{emoji} 紅色" - -#: utils.py:56 utils.py:68 -#, python-brace-format -msgid "{emoji} Blue" -msgstr "{emoji} 藍色" - -#: utils.py:58 utils.py:70 -#, python-brace-format -msgid "{emoji} Green" -msgstr "{emoji} 綠色" - -#: utils.py:60 utils.py:72 -#, python-brace-format -msgid "{emoji} Yellow" -msgstr "{emoji} 黃色" diff --git a/logo.png b/logo.png deleted file mode 100644 index 08b32b7..0000000 Binary files a/logo.png and /dev/null differ diff --git a/mwt.py b/mwt.py deleted file mode 100644 index 58dd00f..0000000 --- a/mwt.py +++ /dev/null @@ -1,45 +0,0 @@ -# Source: http://code.activestate.com/recipes/325905-memoize-decorator-with-timeout/#c1 - -import time - - -class MWT: - """Memoize With Timeout.""" - - _caches = {} - _timeouts = {} - - def __init__(self, timeout=2) -> None: - self.timeout = timeout - - def collect(self): - """Clear cache of results which have timed out.""" - for func in self._caches: - cache = { - key: self._caches[func][key] - for key in self._caches[func] - if (time.time() - self._caches[func][key][1]) < self._timeouts[func] - } - - self._caches[func] = cache - - def __call__(self, f): - self.cache = self._caches[f] = {} - self._timeouts[f] = self.timeout - - def func(*args, **kwargs): - kw = sorted(kwargs.items()) - key = (args, tuple(kw)) - try: - v = self.cache[key] - print("cache") - if (time.time() - v[1]) > self.timeout: - raise KeyError - except KeyError: - print("new") - v = self.cache[key] = f(*args, **kwargs), time.time() - return v[0] - - func.func_name = f.__name__ - - return func diff --git a/player.py b/player.py deleted file mode 100644 index 3d94bc0..0000000 --- a/player.py +++ /dev/null @@ -1,184 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import logging -from datetime import datetime - -import card as c -from config import WAITING_TIME -from errors import DeckEmptyError - - -class Player: - """This class represents a player. - It is basically a doubly-linked ring list with the option to reverse the - direction. On initialization, it will connect itself to a game and its - other players by placing itself behind the current player. - """ - - def __init__(self, game, user) -> None: - self.cards = [] - self.game = game - self.user = user - self.logger = logging.getLogger(__name__) - - # Check if this player is the first player in this game. - if game.current_player: - self.next = game.current_player - self.prev = game.current_player.prev - game.current_player.prev.next = self - game.current_player.prev = self - else: - self._next = self - self._prev = self - game.current_player = self - - self.bluffing = False - self.drew = False - self.anti_cheat = 0 - self.turn_started = datetime.now() - self.waiting_time = WAITING_TIME - - def draw_first_hand(self): - try: - for _ in range(7): - self.cards.append(self.game.deck.draw()) - except DeckEmptyError: - for card in self.cards: - self.game.deck.dismiss(card) - - raise - - def leave(self): - """Removes player from the game and closes the gap in the list.""" - if self.next is self: - return - - self.next.prev = self.prev - self.prev.next = self.next - self.next = None - self.prev = None - - for card in self.cards: - self.game.deck.dismiss(card) - - self.cards = [] - - def __repr__(self) -> str: - return repr(self.user) - - def __str__(self) -> str: - return str(self.user) - - @property - def next(self): - return self._prev if self.game.reversed else self._next - - @next.setter - def next(self, player): - if not self.game.reversed: - self._next = player - else: - self._prev = player - - @property - def prev(self): - return self._next if self.game.reversed else self._prev - - @prev.setter - def prev(self, player): - if not self.game.reversed: - self._prev = player - else: - self._next = player - - def draw(self): - """Draws 1+ cards from the deck, depending on the draw counter.""" - _amount = self.game.draw_counter or 1 - - try: - for _ in range(_amount): - self.cards.append(self.game.deck.draw()) - - except DeckEmptyError: - raise - - finally: - self.game.draw_counter = 0 - self.drew = True - - def rm(self, card): - """Plays a card and removes it from hand.""" - self.cards.remove(card) - - def play(self, card): - """Plays a card and removes it from hand.""" - self.cards.remove(card) - self.game.play_card(card) - - def playable_cards(self): - """Returns a list of the cards this player can play right now.""" - playable = [] - last = self.game.last_card - - self.logger.debug("Last card was %s", str(last)) - - cards = self.cards - if self.drew: - cards = self.cards[-1:] - - # You may only play a +4 if you have no cards of the correct color - self.bluffing = False - for card in cards: - if self._card_playable(card): - self.logger.debug("Matching!") - playable.append(card) - - self.bluffing = self.bluffing or card.color == last.color - - # You may not play a chooser or +4 as your last card - return [] if len(self.cards) == 1 and self.cards[0].special else playable - - def _card_playable(self, card): - """Check a single card if it can be played.""" - is_playable = True - last = self.game.last_card - self.logger.debug("Checking card %s", str(card)) - - if card.color != last.color and card.value != last.value and not card.special: - self.logger.debug("Card's color or value doesn't match") - is_playable = False - elif ( - last.value == c.DRAW_TWO - and card.value != c.DRAW_TWO - and self.game.draw_counter - ): - self.logger.debug("Player has to draw and can't counter") - is_playable = False - elif last.special == c.DRAW_FOUR and self.game.draw_counter: - self.logger.debug("Player has to draw and can't counter") - is_playable = False - elif last.special in [c.CHOOSE, c.DRAW_FOUR] and card.special in [ - c.CHOOSE, - c.DRAW_FOUR, - ]: - self.logger.debug("Can't play colorchooser on another one") - is_playable = False - elif not last.color: - self.logger.debug("Last card has no color") - is_playable = False - - return is_playable diff --git a/plugins/game.py b/plugins/game.py new file mode 100644 index 0000000..dae8333 --- /dev/null +++ b/plugins/game.py @@ -0,0 +1,607 @@ +import importlib +import re + +from hydrogram import Client, filters +from hydrogram.enums import ChatType +from hydrogram.types import ( + ChosenInlineResult, + InlineKeyboardButton, + InlineKeyboardMarkup, + InlineQueryResultArticle, + InlineQueryResultCachedSticker, + InputTextMessageContent, + Message, + InlineQuery, + CallbackQuery, +) +from hydrogram.errors import ListenerTimeout + +from card import COLORS, cards +from config import games, player_game +from db import Chat, User +from game import Game +from typing import Union +from locales import use_lang + + +@Client.on_message(filters.command("new")) +@use_lang() +async def new_game(c: Client, m: Message, ut, ct): + await Chat.get_or_create(id=m.chat.id) + if ( + m.chat.id in games + or m.chat.type == ChatType.PRIVATE + or player_game.get(m.from_user.id) + ): + return await m.reply_text( + ut("game_existis") + if m.chat.id in games + else ut("only_group") + if m.chat.type == ChatType.PRIVATE + else ut("already_in_game") + ) + + game = Game(m.chat, (await Chat.get(id=m.chat.id)).theme) + game.players[m.from_user.id] = m.from_user + games[m.chat.id] = game + player_game[m.from_user.id] = game + keyb = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton(ct("join"), callback_data="join_game"), + InlineKeyboardButton(ct("leave"), callback_data="leave_game"), + ], + [InlineKeyboardButton(ct("start_game"), callback_data="start_game")], + ] + ) + return await m.reply_text(ct("game_started"), reply_markup=keyb) + + +@Client.on_message(filters.command("join")) +@Client.on_callback_query(filters.regex("^join_game$")) +@use_lang() +async def join_game(c: Client, m: Union[Message, CallbackQuery], ut, ct): + if isinstance(m, CallbackQuery): + func = m.answer + else: + func = m.reply_text + game: Game = games.get(m.chat.id if isinstance(m, Message) else m.message.chat.id) + if not game or m.from_user.id in game.players or player_game.get(m.from_user.id): + return await func( + ut("no_game") + if not game + else ut("already_joined") + if m.from_user.id in game.players + else ut('already_in_game') + ) + elif game.closed: + return await func(ct("lobby_closed")) + + game.players[m.from_user.id] = m.from_user + player_game[m.from_user.id] = game + await func(ut("joined_game")) + if isinstance(m, CallbackQuery): + await c.send_message( + m.message.chat.id, ct("player_joined").format(m.from_user.mention) + ) + + if game.is_started: + game.players[m.from_user.id].cards = game.deck.draw(7) + game.players[m.from_user.id].total_cards = 0 + + +@Client.on_callback_query(filters.regex("^leave_game$")) +@Client.on_message(filters.command("leave")) +@use_lang() +async def leave_game(c: Client, m: Union[Message, CallbackQuery], ut, ct): + if isinstance(m, CallbackQuery): + func = m.answer + else: + func = m.reply_text + game: Game = games.get(m.chat.id if isinstance(m, Message) else m.message.chat.id) + if not game or m.from_user.id not in game.players: + return await func( + ut("no_game") if not game else ut("no_joinned") + ) + + if game.is_started and game.next_player.id == m.from_user.id: + inline_keyb = InlineKeyboardMarkup( + [[InlineKeyboardButton(ct("play"), switch_inline_query_current_chat="")]] + ) + game.next() + await c.send_message( + game.chat.id, ct("next").format(game.next_player.mention), reply_markup=inline_keyb + ) + del game.players[m.from_user.id] + del player_game[m.from_user.id] + chat_id = m.chat.id if isinstance(m, Message) else m.message.chat.id + + if len(game.players) == 0: + games.pop(m.chat.id if isinstance(m, Message) else m.message.chat.id) + if isinstance(m, CallbackQuery): + await c.send_message( + chat_id=chat_id, + text=ct("player_left").format(m.from_user.mention)+", "+ct("game_over"), + ) + return await func(ut("game_over")) + if isinstance(m, CallbackQuery): + await c.send_message( + chat_id=chat_id, text=ct("player_left").format(m.from_user.mention) + ) + return await func(ut("left_game")) + + +@Client.on_message(filters.command("close")) +@use_lang() +async def close_game(c: Client, m: Message, ut, ct): + game = games.get(m.chat.id) + if not game or m.from_user != list(game.players.values())[0]: + return await m.reply_text( + ut("no_game") + if not game + else ut("not_allowed") + ) + + games.closed = True + return await m.reply_text(ct("lobby_closed")) + + +@Client.on_message(filters.command("open")) +@use_lang() +async def open_game(c: Client, m: Message, ut, ct): + """Handles the opening of a game.""" + game = games.get(m.chat.id) + if not game or m.from_user != list(game.players.values())[0]: + return await m.reply_text( + ut("no_game") + if not game + else ut("not_allowed") + ) + + games.closed = False + return await m.reply_text(ct("lobby_opened")) + + +@Client.on_message(filters.command("kill")) +@use_lang() +async def kill_game(c: Client, m: Message, ut, ct): + game = games.get(m.chat.id) + if not game or m.from_user != list(game.players.values())[0]: + return await m.reply_text( + ut("no_game") + if not game + else ut("not_allowed") + ) + + games.pop(m.chat.id) + for player in game.players: + player_game.pop(player) + return await m.reply_text(ct("game_over")) + + +@Client.on_message(filters.command("start") & ~filters.private) +@Client.on_callback_query(filters.regex("^start_game$")) +@use_lang() +async def start_game(c: Client, m: Union[Message, CallbackQuery], ut, ct): + if isinstance(m, CallbackQuery): + func = m.answer + chat_id = m.message.chat.id + else: + func = m.reply_text + chat_id = m.chat.id + config = await Chat.get(id=chat_id) + theme = config.theme + game = games.get(chat_id) + if not game or m.from_user != list(game.players.values())[0]: + return await func( + ut("no_game") + if not game + else ut("not_allowed") + ) + + game.is_started = True + game.deck.shuffle() + for player in game.players.values(): + player.cards = game.deck.draw(7) + player.total_cards = 0 + + await c.send_message(chat_id=chat_id, text=ct("game_started")) + pcard = next( + ( + lcard + for lcard in game.deck.cards + if lcard[1] not in cards[config.theme]["CARDS"]["SPECIALS"] + ), + None, + ) + game.deck.cards.remove(pcard) + game.deck.cards.append(pcard) + if pcard[1] == "draw": + if game.draw == -1: + game.draw = 0 + game.draw += 2 + await c.send_sticker( + chat_id=chat_id, sticker=cards[theme]["STICKERS"][f"{pcard[0]}_{pcard[1]}"] + ) + game.last_card = pcard + game.next_player = list(game.players.values())[0] + inline_keyb = InlineKeyboardMarkup( + [[InlineKeyboardButton(ct("play"), switch_inline_query_current_chat="")]] + ) + return await c.send_message( + chat_id, + ct("next").format(game.next_player.mention), + reply_markup=inline_keyb, + ) + + +@Client.on_inline_query(group=3) +@use_lang() +async def inline_query(c: Client, m: InlineQuery, ut, ct): + game = player_game.get(m.from_user.id) + if not game: + articles = [ + InlineQueryResultArticle( + id="none", + title=ut("no_game"), + input_message_content=InputTextMessageContent( + ut("no_game_text") + ), + ) + ] + return await m.answer(articles, cache_time=0) + + config = await Chat.get(id=game.chat.id) + theme = config.theme + COLOR_ICONS = cards[theme]["CARDS"]["COLOR_ICONS"] + VALUES_ICONS = cards[theme]["CARDS"]["VALUES_ICONS"] + if game.chosen == "color" and game.next_player.id == m.from_user.id: + pre = "" + if game.last_card[1] in cards[theme]["CARDS"]["THEME_CARDS"]: + pre = f"{game.last_card[1]}-" + articles = [ + InlineQueryResultArticle( + id=pre + color, + title=COLOR_ICONS[color], + input_message_content=InputTextMessageContent( + ct("colorchoosed").format(color=COLOR_ICONS[color]) + ), + ) + for color in COLORS + ] + await m.answer(articles, cache_time=0) + return + elif game.chosen == "player" and game.next_player.id == m.from_user.id: + players = list(game.players.keys()) + players.remove(m.from_user.id) + articles = [] + pre = "" + if game.last_card[1] in cards[theme]["CARDS"]["THEME_CARDS"]: + pre = f"{game.last_card[1]}-" + for player in players: + if len(players) == 1 or player != m.from_user.id: + articles.append( + InlineQueryResultArticle( + id=pre + str(player), + title=game.players[player].first_name, + input_message_content=InputTextMessageContent( + game.players[player].mention + ), + ) + ) + await m.answer(articles, cache_time=0) + return + + info_text = ut("info_text").format(current_player=game.next_player.mention, last_card=COLOR_ICONS[game.last_card[0]]+VALUES_ICONS[game.last_card[1]]) + for fplayer in game.players: + info_text += ut("info_text2").format(player=game.players[fplayer].mention, cards=len(game.players[fplayer].cards)) + + if not game or m.from_user.id != game.next_player.id: + articles = [] + for num, pcard in enumerate(game.players[m.from_user.id].cards): + sticker_type = pcard[1] if pcard[0] == "x" else f"{pcard[0]}_{pcard[1]}" + articles += [ + InlineQueryResultCachedSticker( + id=f"info-{num}", + sticker_file_id=cards[theme]["STICKERS_GREY"][sticker_type], + input_message_content=InputTextMessageContent(info_text), + ) + ] + + return await m.answer(articles, cache_time=0, is_gallery=True) + + gcards = game.players[m.from_user.id].cards + lcard = game.last_card if game.draw < 2 else ("p", "draw") + xcard = f"{lcard[0]}_{lcard[1]}" + sticker_id = "option_pass" if game.draw == -1 else "option_draw" + sticker_text = ( + ut("pass") + if game.draw == -1 + else ut("buy").format(1) + if game.draw == 0 + else ut("buy").format(game.draw) + ) + articles = [ + InlineQueryResultCachedSticker( + id=sticker_id, + sticker_file_id=cards[theme]["STICKERS"][sticker_id], + input_message_content=InputTextMessageContent(sticker_text), + ) + ] + + if game.last_card[1] == "draw_four" and game.draw == 4: + if (await Chat.get(id=game.chat.id)).bluff: + articles.append( + InlineQueryResultCachedSticker( + id="option_bluff", + sticker_file_id=cards[theme]["STICKERS"]["option_bluff"], + input_message_content=InputTextMessageContent( + ut("bluff") + ), + ) + ) + + for num, pcard in enumerate(gcards): + sticker_type = pcard[1] if pcard[0] == "x" else f"{pcard[0]}_{pcard[1]}" + if ( + ( + pcard[1] in cards[theme]["CARDS"]["SPECIALS_INFO"] + and re.search( + cards[theme]["CARDS"]["SPECIALS_INFO"][pcard[1]][1], string=xcard + ) + ) + or pcard[0] == lcard[0] + or pcard[1] == lcard[1] + ): + articles.append( + InlineQueryResultCachedSticker( + id=f"{pcard[0]}-{pcard[1]}-{num}", + sticker_file_id=cards[theme]["STICKERS"][sticker_type], + ) + ) + else: + articles.append( + InlineQueryResultCachedSticker( + id=f"info-{num}", + sticker_file_id=cards[theme]["STICKERS_GREY"][sticker_type], + input_message_content=InputTextMessageContent(info_text), + ) + ) + + await m.answer(articles, cache_time=0, is_gallery=True) + + +@Client.on_chosen_inline_result(group=1) +@use_lang() +async def choosen(c: Client, ir: ChosenInlineResult, ut, ct): + game: Game = player_game.get(ir.from_user.id) + if not game and game.next_player.id != ir.from_user.id: + return + + config = await Chat.get(id=game.chat.id) + pcard = ir.result_id.split("-")[:2] + ncard = ir.result_id.split("-")[2] if len(ir.result_id.split("-")) > 2 else None + lcard = game.last_card if game.draw <= 1 else ("y", "draw") + print(game.deck.cards) + inline_keyb = InlineKeyboardMarkup( + [[InlineKeyboardButton(ct("play"), switch_inline_query_current_chat="")]] + ) + if pcard[0] == "info": + return + elif game.chosen == "color": + game.last_card = (ir.result_id, game.last_card[1]) + game.chosen = None + elif game.chosen == "player" and game.last_card_2["card"][1] == "7": + game.players[ir.from_user.id].cards, game.players[int(pcard[0])].cards = ( + game.players[int(pcard[0])].cards, + game.players[ir.from_user.id].cards, + ) + game.chosen = None + await c.send_message( + game.chat.id, + ct("cards_swapped").format(name1=game.next_player.mention, name2=game.players[int(pcard[0])].mention), + ) + game.next() + pcard.append("player") + await verify_cards(game, c, ir, game.players[int(pcard[0])], ut, ct) + elif pcard[0] == "option_draw": + buy = game.draw if game.draw > 0 else 1 + game.players[ir.from_user.id].cards.extend(game.deck.draw(buy)) + await c.send_message(game.chat.id, ct("bought").format(buy=buy)) + game.draw = 0 if buy >= 2 else -1 if len(game.players) != 1 else 0 + elif pcard[0] == "option_pass": + game.draw = 0 + elif pcard[0] == "option_bluff": + lplayer = game.players[game.last_card_2["player"]] + bcard = game.last_card_2["card"] + if any(bcard[0] in tupla or bcard[1] in tupla for tupla in lplayer.cards): + lplayer.cards.extend(game.deck.draw(game.draw)) + await c.send_message( + game.chat.id, + ct("bluffed").format(name=lplayer.mention, draw=game.draw), + ) + game.draw = 0 + await c.send_message( + game.chat.id, + ct("next").format(game.next_player.mention), + reply_markup=inline_keyb, + ) + return + else: + game.players[ir.from_user.id].cards.extend(game.deck.draw(game.draw + 2)) + await c.send_message( + game.chat.id, + ct("not_bluffed").format(name1=lplayer.mention, name2=ir.from_user.mention, draw=game.draw + 2), + ) + game.draw = 0 + game.next() + await c.send_message( + game.chat.id, + f"Próximo: {game.next_player.mention}", + reply_markup=inline_keyb, + ) + return + elif pcard[0] == "x" and pcard[1] in ["colorchooser", "draw_four"]: + game.players[ir.from_user.id].total_cards += 1 + if pcard[1] == "draw_four": + if game.draw == -1: + game.draw = 0 + game.draw += 4 + game.last_card_2 = {"card": game.last_card, "player": ir.from_user.id} + game.last_card = game.players[ir.from_user.id].cards.pop(int(ncard)) + game.deck.cards.append(game.last_card) + game.chosen = "color" + return await c.send_message( + game.chat.id, + ct("colorchoose").format(name=game.next_player.mention), + reply_markup=inline_keyb, + ) + elif ( + pcard[0] in cards[config.theme]["CARDS"]["THEME_CARDS"] + or (pcard[1] and pcard[1] in cards[config.theme]["CARDS"]["THEME_CARDS"]) + ): + game.deck.cards.append(game.last_card) + module = importlib.import_module(f"spetials.{config.theme}") + function = getattr( + module, + pcard[1] + if pcard[1] in cards[config.theme]["CARDS"]["THEME_CARDS"] + else pcard[0], + ) + ret = await function(c, ir, game) + if ret: + return + elif pcard[0] != "x" and (pcard[1] == lcard[1] or pcard[0] == lcard[0]): + game.players[ir.from_user.id].total_cards += 1 + game.draw += 2 if pcard[1] == "draw" else 0 + game.last_card_2 = {"card": game.last_card, "player": ir.from_user.id} + game.last_card = game.players[ir.from_user.id].cards.pop(int(ncard)) + game.deck.cards.append(game.last_card) + if pcard[1] == "reverse": + game.players = { + k: game.players[k] for k in reversed(list(game.players.keys())) + } + game.next() if len(game.players) == 2 else None + elif pcard[1] == "skip": + game.next() + elif ((await Chat.get(id=game.chat.id)).seven) and ( + pcard[1] == "7" or pcard[1] == "0" + ): + if pcard[1] == "7": + if len(game.players) == 1 or len(game.players) == 2: + await c.send_message( + game.chat.id, + ct("not_swapped") + ) + else: + game.chosen = "player" + game.last_card_2 = { + "card": game.last_card, + "player": ir.from_user.id, + } + return await c.send_message( + game.chat.id, + ct("playerchoose").format(name=game.next_player.mention), + reply_markup=inline_keyb, + ) + else: + # Aqui irá trocar as cartas dos jogadores na ordem do jogo + gcards = {} + a = 0 + for i in game.players: + gcards[a] = game.players[i].cards + a += 1 + + a = 1 + for i in game.players: + if a in gcards: + game.players[i].cards = gcards[a] + else: + game.players[i].cards = gcards[0] + a += 1 + await verify_cards(game, c, ir, game.players[i], ut, ct) + + await c.send_message(game.chat.id, ct("swapped")) + if game.draw == -1: + game.draw = 0 + else: + return await c.send_message(game.chat.id, ct("invalid_card")) + + if games.get(game.chat.id): + await verify_cards(game, c, ir, ir.from_user, ut, ct) + game.next() + return await c.send_message( + game.chat.id, ct("next").format(game.next_player.mention), reply_markup=inline_keyb + ) + +async def verify_cards(game, c, ir, user, ut, t): + inline_keyb = InlineKeyboardMarkup( + [[InlineKeyboardButton(t("play"), switch_inline_query_current_chat="")]] + ) + if len(game.players[user.id].cards) == 1: + if not (await Chat.get(id=game.chat.id)).one_card: + await c.send_message(game.chat.id, t("said_uno").format(name=user.mention)) + else: + await c.send_message( + game.chat.id, + ut("say_uno").format(name=user.mention), + ) + uno = False + while True: + try: + cmessage = await game.chat.listen( + filters.text | filters.user(user.id), timeout=5 + ) + if (cmessage and cmessage.text) and "uno" in cmessage.text.lower(): + uno = True + break + except ListenerTimeout: + break + if uno: + await c.send_message( + game.chat.id, t("said_uno").format(name=user.mention) + ) + else: + game.players[user.id].cards.extend(game.deck.draw(2)) + await c.send_message( + game.chat.id, + t("not_said_uno").format(name=user.mention), + ) + + elif len(game.players[user.id].cards) == 0: + comp_text = t("first") if game.winner else "" + await c.send_message(game.chat.id, t("won").format(name=user.mention, comp=comp_text)) + if game.winner: + game.winner = False + db_user = await User.get_or_none(id=user.id) + if db_user and db_user.placar: + db_user.wins += 1 + await db_user.save() + if (await Chat.get(id=game.chat.id)).one_win and len(game.players) > 2: + db_user = await User.get_or_none(id=user.id) + if db_user and db_user.placar: + db_user.matches += 1 + db_user.cards += game.players[user.id].total_cards + await db_user.save() + game.next() + game.players.pop(user.id) + player_game.pop(user.id) + await c.send_message( + game.chat.id, t("continuing").format(count=len(game.players)) + ) + await c.send_message( + game.chat.id, + t("next").format(game.next_player.mention), + reply_markup=inline_keyb, + ) + else: + games.pop(game.chat.id) + for player in game.players: + db_user = await User.get_or_none(id=player) + if db_user and db_user.placar: + db_user.matches += 1 + db_user.cards += game.players[player].total_cards + await db_user.save() + player_game.pop(player) + await c.send_message(game.chat.id, t("game_over")) + return diff --git a/plugins/settings.py b/plugins/settings.py new file mode 100644 index 0000000..09ad5e9 --- /dev/null +++ b/plugins/settings.py @@ -0,0 +1,209 @@ +from hydrogram import Client, filters +from hydrogram.types import Message, CallbackQuery +from hydrogram.enums import ChatType, ChatMemberStatus +from hydrogram.types import InlineKeyboardMarkup, InlineKeyboardButton +from typing import Union +from functools import partial +from card import cards +from db import Chat, User +from config import games +from locales import langs, get_locale_string, use_chat_lang, use_user_lang +from hydrogram.helpers import ikb + + +@Client.on_callback_query(filters.regex("^settings$")) +@Client.on_message(filters.command("settings")) +@use_chat_lang() +async def settings(c: Client, m: Union[Message, CallbackQuery], t): + if ( + isinstance(m, Message) + and m.chat.type == ChatType.PRIVATE + or isinstance(m, CallbackQuery) + and m.message.chat.type == ChatType.PRIVATE + ): + print(m) + if isinstance(m, Message): + func = m.reply_text + else: + func = m.edit_message_text + + x = await User.get(id=m.from_user.id) + keyb = [ + [(t("language"), "info_lang"), (t("lang_flag"), "lang")], + [(t("status"), "status"), ("✅" if x.placar else "✖️", "ch_status")], + ] + + if await filters.filter_sudoers(c, m): + keyb.append([("sudos", "sudos")]) + + keyb.append([(t("back"), "start")]) + + await func(t("settings"), reply_markup=ikb(keyb)) + else: + chat_id = m.chat.id if isinstance(m, Message) else m.message.chat.id + admin = await c.get_chat_member(chat_id, m.from_user.id) + print(admin) + if admin.status == ChatMemberStatus.MEMBER: + await m.reply("You need to be an admin to change the settings!") + return + if games.get(chat_id) and games[chat_id].is_started: + await m.reply("You can't change the settings while a game is running!") + return + x = (await Chat.get_or_create(id=chat_id))[0] + keyb = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton(t("theme"), callback_data="info_theme"), + InlineKeyboardButton(t(x.theme), callback_data="theme"), + ], + [ + InlineKeyboardButton(t("seven_zero"), callback_data="info_seven"), + InlineKeyboardButton( + "✅" if x.seven else "✖️", callback_data="mode_seven" + ), + ], + [ + InlineKeyboardButton(t("sbluff"), callback_data="info_bluff"), + InlineKeyboardButton( + "✅" if x.bluff else "✖️", callback_data="mode_bluff" + ), + ], + [ + InlineKeyboardButton(t("one_win"), callback_data="info_one_win"), + InlineKeyboardButton( + "✅" if x.one_win else "✖️", callback_data="mode_one_win" + ), + ], + [ + InlineKeyboardButton(t("one_card"), callback_data="info_one_card"), + InlineKeyboardButton( + "✅" if x.one_card else "✖️", callback_data="mode_one_card" + ), + ], + [ + InlineKeyboardButton(t("language"), callback_data="info_lang"), + InlineKeyboardButton(t("lang_flag"), callback_data="lang"), + ], + ] + ) + if isinstance(m, Message): + await m.reply_text(t("settings"), reply_markup=keyb) + else: + await m.edit_message_text(t("settings"), reply_markup=keyb) + + +@Client.on_callback_query(filters.regex("^theme")) +@use_chat_lang() +async def theme(c: Client, cq: CallbackQuery, t): + if " " in cq.data: + await Chat.get(id=cq.message.chat.id).update(theme=cq.data.split(" ")[1]) + keyb = InlineKeyboardMarkup( + [[InlineKeyboardButton(t("back"), callback_data="theme")]] + ) + await cq.message.edit_text("Theme changed!", reply_markup=keyb) + else: + themes = cards.keys() + tkeyb = [ + InlineKeyboardButton(text=t(theme), callback_data=f"theme {theme}") + for theme in themes + ] + keyb = InlineKeyboardMarkup( + [tkeyb, [InlineKeyboardButton(text=t("back"), callback_data="settings")]] + ) + await cq.message.edit_text(t("theme_config"), reply_markup=keyb) + + +@Client.on_callback_query(filters.regex("mode_")) +@use_chat_lang() +async def mode(c: Client, cq: CallbackQuery, t): + admin = await c.get_chat_member(cq.message.chat.id, cq.from_user.id) + if admin.status is ChatMemberStatus.MEMBER: + await cq.answer("You need to be an admin to change the settings!") + return + x = await Chat.get(id=cq.message.chat.id) + if cq.data == "mode_seven": + await Chat.get(id=cq.message.chat.id).update(seven=not x.seven) + elif cq.data == "mode_bluff": + await Chat.get(id=cq.message.chat.id).update(bluff=not x.bluff) + elif cq.data == "mode_one_win": + await Chat.get(id=cq.message.chat.id).update(one_win=not x.one_win) + elif cq.data == "mode_one_card": + await Chat.get(id=cq.message.chat.id).update(one_card=not x.one_card) + await cq.answer("Done!") + x = await Chat.get(id=cq.message.chat.id) + keyb = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton(t("theme"), callback_data="info_theme"), + InlineKeyboardButton(t(x.theme), callback_data="theme"), + ], + [ + InlineKeyboardButton(t("seven_zero"), callback_data="info_seven"), + InlineKeyboardButton( + "✅" if x.seven else "✖️", callback_data="mode_seven" + ), + ], + [ + InlineKeyboardButton(t("sbluff"), callback_data="info_bluff"), + InlineKeyboardButton( + "✅" if x.bluff else "✖️", callback_data="mode_bluff" + ), + ], + [ + InlineKeyboardButton(t("one_win"), callback_data="info_one_win"), + InlineKeyboardButton( + "✅" if x.one_win else "✖️", callback_data="mode_one_win" + ), + ], + [ + InlineKeyboardButton(t("one_card"), callback_data="info_one_card"), + InlineKeyboardButton( + "✅" if x.one_card else "✖️", callback_data="mode_one_card" + ), + ], + [ + InlineKeyboardButton(t("language"), callback_data="info_lang"), + InlineKeyboardButton(t("lang_flag"), callback_data="lang"), + ], + ] + ) + await cq.message.edit_text(t("settings"), reply_markup=keyb) + + +@Client.on_callback_query(filters.regex("^lang")) +@use_chat_lang() +async def lang(c: Client, cq: CallbackQuery, t): + if cq.message.chat.type != ChatType.PRIVATE: + admin = await c.get_chat_member(cq.message.chat.id, cq.from_user.id) + if admin.status is ChatMemberStatus.MEMBER: + await cq.answer("You need to be an admin to change the theme!") + return + if "_" in cq.data: + nt = partial(get_locale_string, cq.data.split("_")[1]) + if cq.message.chat.type == ChatType.PRIVATE: + await User.get(id=cq.message.chat.id).update(lang=cq.data.split("_")[1]) + else: + await Chat.get(id=cq.message.chat.id).update(lang=cq.data.split("_")[1]) + keyb = InlineKeyboardMarkup( + [[InlineKeyboardButton(nt("back"), callback_data="settings")]] + ) + await cq.message.edit_text(nt("lang_changed"), reply_markup=keyb) + else: + keyb = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + get_locale_string(lang, "lang_name"), + callback_data=f"lang_{lang}", + ) + ] + for lang in langs + ] + ) + await cq.message.edit_text(t("choose_lang"), reply_markup=keyb) + + +@Client.on_callback_query(filters.regex("^info_")) +@use_user_lang() +async def info(c: Client, cq: CallbackQuery, t): + await cq.answer(t(cq.data), show_alert=True) diff --git a/plugins/start.py b/plugins/start.py new file mode 100644 index 0000000..4dfb28c --- /dev/null +++ b/plugins/start.py @@ -0,0 +1,68 @@ +from hydrogram import Client, filters +from hydrogram.types import Message, CallbackQuery +from hydrogram.helpers import ikb +from typing import Union +from db import User +from locales import use_user_lang + + +@Client.on_message(filters.command("start") & filters.private) +@Client.on_callback_query(filters.regex("^start$")) +@use_user_lang() +async def start(c: Client, m: Union[Message, CallbackQuery], t): + if isinstance(m, CallbackQuery): + func = m.edit_message_text + else: + func = m.reply_text + await User.get_or_create(id=m.from_user.id) + print(m.from_user.id) + keyb = [[("help", "help"), ("configurações", "settings")]] + await func(t("start_text"), reply_markup=ikb(keyb)) + + +@Client.on_callback_query(filters.regex("^help$")) +@use_user_lang() +async def help(c: Client, cq: CallbackQuery, t): + keyb = [ + [(t("game_mode"), "help_game")], + [(t("back"), "start")], + ] + await cq.edit_message_text( + "Ecolha uma opção de ajuda abaixo:", reply_markup=ikb(keyb) + ) + + +@Client.on_callback_query(filters.regex("^help_game$")) +@use_user_lang() +async def help_game(c: Client, cq: CallbackQuery, t): + text = t("game_mode_text") + text += "" + t("seven_zero") + ": " + t("info_seven") + "\n\n" + text += "" + t("sbluff") + ": " + t("info_bluff") + "\n\n" + text += "" + t("one_win") + ": " + t("info_one_win") + "\n\n" + text += "" + t("one_card") + ": " + t("info_one_card") + "\n\n" + keyb = [[(t("back"), "help")]] + + await cq.edit_message_text(text, reply_markup=ikb(keyb)) + + +@Client.on_message(filters.command("status")) +@Client.on_callback_query(filters.regex("^status$")) +async def status(c: Client, m: Union[Message, CallbackQuery]): + user = await User.get_or_create(id=m.from_user.id) + porcentagem = (user[0].wins / user[0].matches) * 100 if user[0].matches > 0 else 0 + if (await User.get(id=m.from_user.id)).placar: + text = f"{user[0].matches} partidas jogadas\n{user[0].wins} vezes em primeiro lugas ({porcentagem}%)\n{user[0].cards} cartas jogadas" + else: + text = "Ligue para saber suas estatísticas como quantas partidas jogadas, quantas vezes em primeiro lugar e quantas cartas jogadas" + if isinstance(m, Message): + await m.reply_text(text) + else: + await m.answer(text, show_alert=True) + +@Client.on_callback_query(filters.regex("^ch_status$")) +async def ch_status(c: Client, cq: CallbackQuery): + user = await User.get_or_create(id=cq.from_user.id) + user = user[0] + user.placar = not user.placar + await user.save() + await cq.answer("Status alterado com sucesso") diff --git a/plugins/sudos.py b/plugins/sudos.py new file mode 100644 index 0000000..b3f72cd --- /dev/null +++ b/plugins/sudos.py @@ -0,0 +1,467 @@ +from asyncio import sleep +from json import dump +from typing import Union + +from hydrogram import Client, filters +from hydrogram.errors import ListenerTimeout, MediaEmpty +from hydrogram.types import ( + CallbackQuery, + InlineKeyboardButton, + InlineKeyboardMarkup, + InlineQuery, + InlineQueryResultCachedSticker, + Message, +) + +from card import cards +from config import sudoers +from db import User + + +async def filter_sudoers_logic(flt, c, u): + if not u.from_user: + return None + usr = u.from_user + db_usr = await User.get_or_none(id=usr.id) + if not db_usr: + return False + if db_usr.sudo or usr.id in sudoers: + return True + else: + return False + + +filter_sudoers = filters.create(filter_sudoers_logic, "FilterSudoers") +filters.filter_sudoers = filter_sudoers + + +@Client.on_message(filters.command("sudos") & filters.private & filter_sudoers) +@Client.on_callback_query(filters.regex("^sudos$") & filter_sudoers) +async def start(c: Client, m: Union[Message, CallbackQuery]): + if isinstance(m, CallbackQuery): + func = m.edit_message_text + else: + func = m.reply_text + keyb = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton("Sudos", callback_data="settings_sudos"), + InlineKeyboardButton("themes", callback_data="settings_sudo_themc"), + ], + [ + InlineKeyboardButton("Voltar", callback_data="settings"), + ] + ] + ) + await func( + "Bem vindo ao menu de configurações do UnuRobot, aqui você pode configurar o bot da forma que quiser, para isso basta clicar em um dos botões abaixo!", + reply_markup=keyb, + ) + + +@Client.on_callback_query(filters.regex("^settings_sudos$") & filter_sudoers) +async def settings_sudos(c: Client, cq: CallbackQuery): + usrs = await c.get_users(sudoers) + db_usrs = await User.filter(sudo=True) + usrs += await c.get_users([usr.id for usr in db_usrs]) + text = "Lista de sudos:\n\n" + for usr in usrs: + text += f"👤 {usr.mention}\n" + + keyb = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton("Adicionar", callback_data="settings_sudos_add"), + InlineKeyboardButton("Remover", callback_data="settings_sudos_remove"), + ], + [InlineKeyboardButton("Voltar", callback_data="sudos")], + ] + ) + + await cq.edit_message_text(text, reply_markup=keyb) + + +@Client.on_callback_query(filters.regex("^settings_sudos_add$") & filter_sudoers) +async def settings_sudos_add(c: Client, cq: CallbackQuery): + await cq.edit_message_text("Envie o ID do usuário que deseja adicionar aos sudos") + cmessage = None + # Wait for the user to send a message with the new emoji + while cmessage is None: + try: + cmessage = await cq.message.chat.listen(filters.text) + print(cmessage) + except ListenerTimeout: + return + + text = cmessage.text + user = await c.get_users(text) + + if not user: + await cmessage.reply_text("Usuário não encontrado") + return + + user_db = await User.get_or_create(id=user.id) + + if user_db[0].sudo: + await cmessage.reply_text("Usuário já é sudo") + return + + user_db[0].sudo = True + await user_db[0].save() + + await cmessage.reply_text( + "Usuário adicionado aos sudos", + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("Voltar", callback_data="settings_sudos")]] + ), + ) + + +@Client.on_callback_query(filters.regex("^settings_sudos_remove") & filter_sudoers) +async def settings_sudos_remove(c: Client, cq: CallbackQuery): + if cq.data == "settings_sudos_remove": + db_users = await User.filter(sudo=True) + users = await c.get_users([usr.id for usr in db_users]) + text = "Selecione o usuário que deseja remover dos sudos:\n\n" + keyb = [] + for user in users: + keyb.append( + [ + InlineKeyboardButton( + user.first_name, + callback_data=f"settings_sudos_remove_{user.id}", + ) + ] + ) + + keyb.append([InlineKeyboardButton("Voltar", callback_data="settings_sudos")]) + await cq.edit_message_text(text, reply_markup=InlineKeyboardMarkup(keyb)) + return + + db_users = await User.filter(sudo=True) + sudoers = [usr.id for usr in db_users] + + user_id = int(cq.data.split("_")[3]) + if user_id not in sudoers: + await cq.answer("Usuário não é sudo") + return + + await User.get(id=user_id).update(sudo=False) + + await cq.edit_message_text( + "Usuário removido dos sudos", + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("Voltar", callback_data="settings_sudos")]] + ), + ) + + +@Client.on_callback_query(filters.regex("^settings_sudo_themc$") & filter_sudoers) +async def settings_sudo_themc(c: Client, cq: CallbackQuery): + keyb = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=theme, callback_data=f"settings_sudo_themc {theme}" + ) + for theme in cards.keys() + ], + [ + InlineKeyboardButton( + "Adicionar novo", callback_data="settings_sudo_themc_new" + ), + InlineKeyboardButton("Voltar", callback_data="sudos"), + ], + ] + ) + await cq.edit_message_text("Selecione um tema:", reply_markup=keyb) + + +@Client.on_callback_query(filters.regex("^settings_sudo_themc_new$") & filter_sudoers) +async def settings_themes_new(c: Client, cq: CallbackQuery): + await cq.edit_message_text("Envie o nome do tema") + cmessage = None + # Wait for the user to send a message with the new emoji + while cmessage is None: + try: + cmessage = await cq.message.chat.listen(filters.text) + print(cmessage) + except ListenerTimeout: + return + + name = cmessage.text + + ncards = cards["classic"] + + for card in ncards["STICKERS"]: + await c.send_message( + cq.message.chat.id, "Mande um sticker para substituir o sticker:" + ) + await c.send_sticker(cq.message.chat.id, ncards["STICKERS"][card]) + + cmessage = None + # Wait for the user to send a message with the new emoji + while cmessage is None: + try: + cmessage = await cq.message.chat.listen(filters.sticker) + ncards["STICKERS"][card] = cmessage.sticker.file_id + except ListenerTimeout: + return + for card in ncards["STICKERS_GREY"]: + await c.send_message( + cq.message.chat.id, "Mande um sticker para substituir o sticker:" + ) + await c.send_sticker(cq.message.chat.id, ncards["STICKERS_GREY"][card]) + + cmessage = None + # Wait for the user to send a message with the new emoji + while cmessage is None: + try: + cmessage = await cq.message.chat.listen(filters.sticker) + ncards["STICKERS_GREY"][card] = cmessage.sticker.file_id + except ListenerTimeout: + return + + with open(f"cards/{name}.json", "w") as f: + dump(ncards, f) + + await c.send_message( + cq.message.chat.id, + "Tema adicionado com sucesso!", + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("Voltar", callback_data="settings_sudo_themc")]] + ), + ) + + +@Client.on_callback_query(filters.regex("^settings_sudo_themc ") & filter_sudoers) +async def settings_themes(c: Client, cq: CallbackQuery): + theme = cq.data.split(" ")[1] + keyb = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Adicionar", callback_data="settings_sudo_themc_add " + theme + ), + InlineKeyboardButton( + "Atualizar", callback_data="settings_sudo_themc_update " + theme + ), + InlineKeyboardButton( + "Verificar", callback_data="settings_sudo_themc_check " + theme + ), + ], + [InlineKeyboardButton("Voltar", callback_data="settings_sudo_themc")], + ] + ) + await cq.edit_message_text( + f"O que deseja fazer com o tema {theme}?", reply_markup=keyb + ) + + +@Client.on_callback_query(filters.regex("^settings_sudo_themc_add ") & filter_sudoers) +async def settings_themes_add(c: Client, cq: CallbackQuery): + theme = cq.data.split(" ")[1] + await cq.edit_message_text("Envie o código da nova carta") + + cmessage = None + + while cmessage is None: + try: + cmessage = await cq.message.chat.listen(filters.text) + except ListenerTimeout: + return + + code = cmessage.text + + await c.send_message(cq.message.chat.id, f"Mande um sticker colorido para o {code}") + + cmessage = None + + while cmessage is None: + try: + cmessage = await cq.message.chat.listen(filters.sticker) + except ListenerTimeout: + return + + stickerc = cmessage.sticker.file_id + + await c.send_message(cq.message.chat.id, f"Mande um sticker cinza para o {code}") + + cmessage = None + + while cmessage is None: + try: + cmessage = await cq.message.chat.listen(filters.sticker) + except ListenerTimeout: + return + + stickerg = cmessage.sticker.file_id + + cards[theme]["STICKERS"][code] = stickerc + cards[theme]["STICKERS_GREY"][code] = stickerg + + with open(f"cards/{theme}.json", "w") as f: + dump(cards[theme], f) + + await c.send_message( + cq.message.chat.id, + "Carta adicionada com sucesso!", + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("Voltar", callback_data="settings_sudo_themc")]] + ), + ) + + +@Client.on_callback_query( + filters.regex("^settings_sudo_themc_update ") & filter_sudoers +) +async def settings_themes_update(c: Client, cq: CallbackQuery): + sp = cq.data.split(" ")[1:] + print(sp) + theme = sp[0] + if len(sp) == 1: + keyb = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Light", + callback_data=f"settings_sudo_themc_update {theme} Light", + ), + InlineKeyboardButton( + "Dark", callback_data=f"settings_sudo_themc_update {theme} Dark" + ), + ], + ] + ) + await cq.edit_message_text( + "Escolha o tema que deseja atualizar", reply_markup=keyb + ) + if len(sp) == 2: + keyb = [] + for color in cards[theme]["CARDS"]["COLORS"]: + keyb.append( + InlineKeyboardButton( + color, + callback_data=f"settings_sudo_themc_update {theme} {sp[1]} {color}", + ) + ) + keyb.append( + InlineKeyboardButton( + "SPECIALS", + callback_data=f"settings_sudo_themc_update {theme} {sp[1]} SPECIALS", + ) + ) + await cq.edit_message_text( + "Escolha a cor da carta que deseja atualizar", + reply_markup=InlineKeyboardMarkup([keyb]), + ) + elif len(sp) == 3: + keyb = [] + if sp[2] == "SPECIALS": + for card in cards[theme]["CARDS"]["SPECIALS"]: + keyb.append( + [ + InlineKeyboardButton( + card, + callback_data=f"settings_sudo_themc_update {theme} {sp[1]} x {card}", + ) + ] + ) + else: + for card in cards[theme]["CARDS"]["VALUES"]: + keyb.append( + [ + InlineKeyboardButton( + card, + callback_data=f"settings_sudo_themc_update {theme} {sp[1]} {sp[2]} {card}", + ) + ] + ) + await cq.edit_message_text( + "Escolha o valor da carta que deseja atualizar", + reply_markup=InlineKeyboardMarkup(keyb), + ) + elif len(sp) == 4: + await cq.edit_message_text("Envie um sticker para substituir a carta:") + cardid = sp[2] + "_" + sp[3] if sp[2] != "x" else sp[3] + cardtm = "STICKERS_GREY" if sp[1] == "Dark" else "STICKERS" + await c.send_sticker(cq.message.chat.id, cards[theme][cardtm][cardid]) + + cmessage = None + + while cmessage is None: + try: + cmessage = await cq.message.chat.listen(filters.sticker) + except ListenerTimeout: + return + + cards[theme][cardtm][cardid] = cmessage.sticker.file_id + + with open(f"cards/{theme}.json", "w") as f: + dump(cards[theme], f) + + await c.send_message( + cq.message.chat.id, + "Carta atualizada com sucesso!", + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("Voltar", callback_data="settings_sudo_themc")]] + ), + ) + + +@Client.on_callback_query(filters.regex("^settings_sudo_themc_check ") & filter_sudoers) +async def settings_themes_check(c: Client, cq: CallbackQuery): + theme = cq.data.split(" ")[1] + card_types = ["STICKERS", "STICKERS_GREY"] + messages = ["Verificando cartas coloridas...", "Verificando cartas cinzas..."] + + for card_type, message in zip(card_types, messages): + await c.send_message(cq.message.chat.id, message) + for card in cards[theme][card_type]: + try: + m2 = await c.send_sticker( + cq.message.chat.id, cards[theme][card_type][card] + ) + await m2.delete() + await sleep(0.3) + except MediaEmpty: + await c.send_message( + cq.message.chat.id, + f"Carta {card} não encontrada, mande a carta para substitui-lá", + ) + + while True: + try: + cmessage = await cq.message.chat.listen(filters.sticker) + break + except ListenerTimeout: + return + + cards[theme][card_type][card] = cmessage.sticker.file_id + await c.send_message( + cq.message.chat.id, f"Carta {card} atualizada com sucesso!" + ) + + with open(f"cards/{theme}.json", "w") as f: + dump(cards[theme], f) + + await c.send_message(cq.message.chat.id, "Cartas verificadas com sucesso!") + + +@Client.on_inline_query(filters.regex("^change ") & filter_sudoers) +async def change(c: Client, iq: InlineQuery): + theme = iq.query.split(" ")[1] + articles = [] + for card in cards[theme]["STICKERS"]: + articles.append( + InlineQueryResultCachedSticker( + id="sudo" + card, sticker_file_id=cards[theme]["STICKERS"][card] + ) + ) + for card in cards[theme]["STICKERS_GREY"]: + articles.append( + InlineQueryResultCachedSticker( + id="sudog" + card, sticker_file_id=cards[theme]["STICKERS_GREY"][card] + ) + ) + return await iq.answer(articles, cache_time=0) diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index a73e847..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -python-telegram-bot>=20.0a5,<21.0 -pony diff --git a/results.py b/results.py deleted file mode 100644 index 2edace3..0000000 --- a/results.py +++ /dev/null @@ -1,267 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -"""Defines helper functions to build the inline result list.""" - -from uuid import uuid4 - -from telegram import InlineQueryResultArticle, InputTextMessageContent -from telegram import InlineQueryResultCachedSticker as Sticker - -import card as c -from internationalization import _, __ -from utils import display_color, display_color_group, display_name - - -def add_choose_player(name, results, game): - """Add choose color options.""" - for a, i in enumerate(game.players): - if name != i.user.id or len(game.players) == 1: - results.append( - InlineQueryResultArticle( - id=f"player_{a}", - title=_("Choose Player"), - description=f"{i.user.first_name} - {len(i.cards)}", - input_message_content=InputTextMessageContent(i.user.first_name), - ), - ) - - -def add_choose_color(results, game): - """Add choose color options.""" - for color in c.COLORS: - results.append( - InlineQueryResultArticle( - id=color, - title=_("Choose Color"), - description=display_color(color), - input_message_content=InputTextMessageContent( - display_color_group(color, game), - ), - ), - ) - - -def add_other_cards(player, results, game): - """Add hand cards when choosing colors.""" - results.append( - InlineQueryResultArticle( - "hand", - title=_( - "Card (tap for game state):", - "Cards (tap for game state):", - len(player.cards), - ), - description=", ".join([repr(card) for card in player.cards]), - input_message_content=game_info(game), - ), - ) - - -def player_list(game): - """Generate list of player strings.""" - return [ - _( - "{name} ({number} card)", - "{name} ({number} cards)", - len(player.cards), - ).format(name=player.user.first_name, number=len(player.cards)) - for player in game.players - ] - - -def add_no_game(results): - """Add text result if user is not playing.""" - results.append( - InlineQueryResultArticle( - "nogame", - title=_("You are not playing"), - input_message_content=InputTextMessageContent( - _( - "Not playing right now. Use /new to " - "start a game or /join to join the " - "current game in this group", - ), - ), - ), - ) - - -def add_not_started(results): - """Add text result if the game has not yet started.""" - results.append( - InlineQueryResultArticle( - "nogame", - title=_("The game wasn't started yet"), - input_message_content=InputTextMessageContent( - _("Start the game with /start"), - ), - ), - ) - - -def add_mode_classic(results): - """Change mode to classic.""" - results.append( - InlineQueryResultArticle( - "mode_classic", - title=_("🎻 Classic mode"), - input_message_content=InputTextMessageContent(_("Classic 🎻")), - ), - ) - - -def add_mode_fast(results): - """Change mode to classic.""" - results.append( - InlineQueryResultArticle( - "mode_fast", - title=_("🚀 Sanic mode"), - input_message_content=InputTextMessageContent(_("Gotta go fast! 🚀")), - ), - ) - - -def add_mode_wild(results): - """Change mode to classic.""" - results.append( - InlineQueryResultArticle( - "mode_wild", - title=_("🐉 Wild mode"), - input_message_content=InputTextMessageContent(_("Into the Wild~ 🐉")), - ), - ) - - -def add_mode_sete(results): - results.append( - InlineQueryResultArticle( - "mode_7-0", - title=_("🔫 7-0 mode"), - input_message_content=InputTextMessageContent(_("Carioca mode on 🔫")), - ), - ) - - -def add_mode_text(results): - """Change mode to text.""" - results.append( - InlineQueryResultArticle( - "mode_text", - title=_("✍️ Text mode"), - input_message_content=InputTextMessageContent(_("Text ✍️")), - ), - ) - - -def add_draw(player, results): - """Add option to draw.""" - n = player.game.draw_counter or 1 - - results.append( - Sticker( - "draw", - sticker_file_id=c.STICKERS["option_draw"], - input_message_content=InputTextMessageContent( - __( - "Drawing {number} card", - "Drawing {number} cards", - n, - multi=player.game.translate, - ).format(number=n), - ), - ), - ) - - -def add_gameinfo(game, results): - """Add option to show game info.""" - results.append( - Sticker( - "gameinfo", - sticker_file_id=c.STICKERS["option_info"], - input_message_content=game_info(game), - ), - ) - - -def add_pass(results, game): - """Add option to pass.""" - results.append( - Sticker( - "pass", - sticker_file_id=c.STICKERS["option_pass"], - input_message_content=InputTextMessageContent( - __("Pass", multi=game.translate), - ), - ), - ) - - -def add_call_bluff(results, game): - """Add option to call a bluff.""" - results.append( - Sticker( - "call_bluff", - sticker_file_id=c.STICKERS["option_bluff"], - input_message_content=InputTextMessageContent( - __("I'm calling your bluff!", multi=game.translate), - ), - ), - ) - - -def add_card(game, card, results, can_play): - """Add an option that represents a card.""" - if can_play: - if game.mode != "text": - results.append(Sticker(str(card), sticker_file_id=c.STICKERS[str(card)])) - if game.mode == "text": - results.append( - Sticker( - str(card), - sticker_file_id=c.STICKERS[str(card)], - input_message_content=InputTextMessageContent( - "Card Played: {card}".format( - card=repr(card) - .replace("Draw Four", "+4") - .replace("Draw", "+2") - .replace("Colorchooser", "Color Chooser"), - ), - ), - ), - ) - else: - results.append( - Sticker( - str(uuid4()), - sticker_file_id=c.STICKERS_GREY[str(card)], - input_message_content=game_info(game), - ), - ) - - -def game_info(game): - players = player_list(game) - return InputTextMessageContent( - _("Current player: {name}").format(name=display_name(game.current_player.user)) - + "\n" - + _("Last card: {card}").format(card=repr(game.last_card)) - + "\n" - + _("Player: {player_list}", "Players: {player_list}", len(players)).format( - player_list=" -> ".join(players), - ), - ) diff --git a/settings.py b/settings.py deleted file mode 100644 index 9e076ea..0000000 --- a/settings.py +++ /dev/null @@ -1,108 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -from telegram import ReplyKeyboardMarkup, Update -from telegram.ext import CommandHandler, ContextTypes, MessageHandler, filters - -from internationalization import _, user_locale -from locales import available_locales -from shared_vars import application -from user_setting import UserSetting -from utils import send_async - - -@user_locale -async def show_settings(update: Update, context: ContextTypes.DEFAULT_TYPE): - chat = update.message.chat - - if update.message.chat.type != "private": - await send_async( - chat, - text=_("Please edit your settings in a private chat with the bot."), - message_thread_id=update.message.message_thread_id, - ) - return - - us = UserSetting.get(id=update.message.from_user.id) or UserSetting( - id=update.message.from_user.id, - ) - - stats = ( - "❌" + " " + _("Delete all statistics") - if us.stats - else "📊" + " " + _("Enable statistics") - ) - - kb = [[stats], ["🌍" + " " + _("Language")]] - await send_async( - chat, - text="🔧" + " " + _("Settings"), - reply_markup=ReplyKeyboardMarkup(keyboard=kb, one_time_keyboard=True), - ) - - -@user_locale -async def kb_select(update: Update, context: ContextTypes.DEFAULT_TYPE): - chat = update.message.chat - user = update.message.from_user - option = context.matches[0].group(1) - - if option == "📊": - us = UserSetting.get(id=user.id) - us.stats = True - await send_async(chat, text=_("Enabled statistics!")) - - elif option == "🌍": - kb = [ - [f"{locale} - {descr}"] - for locale, descr in sorted(available_locales.items()) - ] - - await send_async( - chat, - text=_("Select locale"), - reply_markup=ReplyKeyboardMarkup(keyboard=kb, one_time_keyboard=True), - ) - - elif option == "❌": - us = UserSetting.get(id=user.id) - us.stats = False - us.first_places = 0 - us.games_played = 0 - us.cards_played = 0 - await send_async(chat, text=_("Deleted and disabled statistics!")) - - -@user_locale -async def locale_select(update: Update, context: ContextTypes.DEFAULT_TYPE): - chat = update.message.chat - user = update.message.from_user - option = context.matches[0].group(1) - - if option in available_locales: - us = UserSetting.get(id=user.id) - us.lang = option - _.push(option) - await send_async(chat, text=_("Set locale!")) - _.pop() - - -def register(): - application.add_handler(CommandHandler("settings", show_settings)) - application.add_handler(MessageHandler(filters.Regex(r"^([📊🌍❌]) .+$"), kb_select)) - application.add_handler( - MessageHandler(filters.Regex(r"^(\w\w(_\w\w)?) - .*"), locale_select), - ) diff --git a/shared_vars.py b/shared_vars.py deleted file mode 100644 index 7184b6d..0000000 --- a/shared_vars.py +++ /dev/null @@ -1,33 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import os - -from telegram.ext import Application - -from config import BASE_URL, TOKEN -from database import db -from game_manager import GameManager - -# Explicitly import UserSetting to avoid circular imports, -# since UserSetting must be loaded before generating database mapping -from user_setting import UserSetting # noqa: F401 - -db.bind("sqlite", os.getenv("UNO_DB", "uno.sqlite3"), create_db=True) -db.generate_mapping(create_tables=True) - -gm = GameManager() -application = Application.builder().token(TOKEN).base_url(BASE_URL).build() diff --git a/simple_commands.py b/simple_commands.py deleted file mode 100644 index 9e219c4..0000000 --- a/simple_commands.py +++ /dev/null @@ -1,183 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -from telegram import Update -from telegram.constants import ParseMode -from telegram.ext import CommandHandler, ContextTypes - -from internationalization import _, user_locale -from shared_vars import application -from user_setting import UserSetting -from utils import send_async - - -@user_locale -async def help_handler(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /help command.""" - help_text = _( - "Follow these steps:\n\n" - "1. Add this bot to a group\n" - "2. In the group, start a new game with /new or join an already" - " running game with /join\n" - "3. After at least two players have joined, start the game with" - " /start\n" - "4. Type @UnuRobot into your chat box and hit " - "space, or click the via @UnuRobot text " - "next to messages. You will see your cards (some greyed out), " - "any extra options like drawing, and a ? to see the " - "current game state. The greyed out cards are those you " - "can not play at the moment. Tap an option to execute " - "the selected action.\n" - "Players can join the game at any time. To leave a game, " - "use /leave. If a player takes more than 90 seconds to play, " - "you can use /skip to skip that player. Use /notify_me to " - "receive a private message when a new game is started.\n\n" - "Language and other settings: /settings\n" - "Other commands (only game creator):\n" - "/close - Close lobby\n" - "/open - Open lobby\n" - "/kill - Terminate the game\n" - "/kick - Select a player to kick " - "by replying to him or her\n" - "/enable_translations - Translate relevant texts into all " - "languages spoken in a game\n" - "/disable_translations - Use English for those texts\n\n" - "Experimental: Play in multiple groups at the same time. " - "Press the Current game: ... button and select the " - "group you want to play a card in.\n" - "If you enjoy this bot, join the " - 'update channel' - " and buy an UNO card game.", - ) - - await send_async( - update.message.chat, - text=help_text, - parse_mode=ParseMode.HTML, - message_thread_id=update.message.message_thread_id, - disable_web_page_preview=True, - ) - - -@user_locale -async def modes(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /help command.""" - modes_explanation = _( - "This UNO bot has five game modes: Classic, Sanic, Wild, Text and 7-0.\n\n" - " 🎻 The Classic mode uses the conventional UNO deck and there is no auto skip.\n" - " 🚀 The Sanic mode uses the conventional UNO deck and the bot automatically skips a player if he/she takes too long to play its turn\n" - " 🐉 The Wild mode uses a deck with more special cards, less number variety and no auto skip.\n" - " ✍️ The Text mode uses the conventional UNO deck but instead of stickers it uses the text.\n" - " 🔫 The 7-0 mode uses the conventional UNO deck but when a player plays a 7, he/she can choose a player to swap cards with." - " When a player plays a 0, all cards will be swapped between the current players.\n\n" - "To change the game mode, the GAME CREATOR has to type the bot nickname and a space, " - "just like when playing a card, and all gamemode options should appear.", - ) - await send_async( - update.message.chat, - text=modes_explanation, - parse_mode=ParseMode.HTML, - message_thread_id=update.message.message_thread_id, - disable_web_page_preview=True, - ) - - -@user_locale -async def source(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /help command.""" - source_text = _( - "This bot is Free Software and licensed under the AGPL. " - "The code is available here: \n" - "https://github.com/AmanoTeam/UnuRobot", - ) - attributions = _( - "Attributions:\n" - "Draw icon by " - 'Faithtoken\n' - "Pass icon by " - 'Delapouite\n' - "Originals available on http://game-icons.net\n" - "Icons edited by ɳick", - ) - - await send_async( - update.message.chat, - text=source_text + "\n" + attributions, - parse_mode=ParseMode.HTML, - message_thread_id=update.message.message_thread_id, - disable_web_page_preview=True, - ) - - -@user_locale -async def news(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handler for the /news command.""" - await send_async( - update.message.chat, - text=_("All news here: https://t.me/UnuRobotUpdates"), - message_thread_id=update.message.message_thread_id, - disable_web_page_preview=True, - ) - - -@user_locale -async def stats(update: Update, context: ContextTypes.DEFAULT_TYPE): - user = update.message.from_user - chat = update.message.chat - us = UserSetting.get(id=user.id) - if not us or not us.stats: - await send_async( - chat, - text=_( - "You did not enable statistics. Use /settings in " - "a private chat with the bot to enable them.", - ), - message_thread_id=update.message.message_thread_id, - ) - else: - n = us.games_played - stats_text = [ - _("{number} game played", "{number} games played", n).format(number=n), - ] - - n = us.first_places - m = round((us.first_places / us.games_played) * 100) if us.games_played else 0 - stats_text.append( - _( - "{number} first place ({percent}%)", - "{number} first places ({percent}%)", - n, - ).format(number=n, percent=m), - ) - - n = us.cards_played - stats_text.append( - _("{number} card played", "{number} cards played", n).format(number=n), - ) - - await send_async( - chat, - text="\n".join(stats_text), - message_thread_id=update.message.message_thread_id, - ) - - -def register(): - application.add_handler(CommandHandler("help", help_handler)) - application.add_handler(CommandHandler("source", source)) - application.add_handler(CommandHandler("news", news)) - application.add_handler(CommandHandler("stats", stats)) - application.add_handler(CommandHandler("modes", modes)) diff --git a/spetials/minimalist.py b/spetials/minimalist.py new file mode 100644 index 0000000..a06af66 --- /dev/null +++ b/spetials/minimalist.py @@ -0,0 +1,32 @@ +from hydrogram import Client +from hydrogram.types import ChosenInlineResult +from hydrogram.types import InlineKeyboardMarkup, InlineKeyboardButton +from game import Game + +inline_keyb = InlineKeyboardMarkup( + [[InlineKeyboardButton("Jogar", switch_inline_query_current_chat="")]] +) + + +async def mirror(c: Client, ir: ChosenInlineResult, game: Game): + if game.draw < 2: + await c.send_message(game.chat.id, "Você não pode descartar essa carta agora!") + return True + else: + print(game.last_card_2, game.last_card) + game.players[ir.from_user.id].total_cards += 1 + ncard = ir.result_id.split("-")[2] + player = game.last_card_2["player"] + player = game.players[int(player)] + player.cards.extend(game.deck.draw(game.draw)) + await c.send_message( + game.chat.id, f"{player.mention} comprou {game.draw} cartas!" + ) + game.players[ir.from_user.id].cards.pop(int(ncard)) + await c.send_message( + game.chat.id, + f"Próximo: {game.next_player.mention}", + reply_markup=inline_keyb, + ) + game.draw = 0 + return True diff --git a/test/__init__.py b/test/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/test/test_game_manager.py b/test/test_game_manager.py deleted file mode 100644 index d28349b..0000000 --- a/test/test_game_manager.py +++ /dev/null @@ -1,116 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import unittest - -from telegram import Chat, User - -from errors import ( - AlreadyJoinedError, - LobbyClosedError, - NoGameInChatError, - NotEnoughPlayersError, -) -from game_manager import GameManager - - -class Test(unittest.TestCase): - game = None - - def setUp(self): - self.gm = GameManager() - - self.chat0 = Chat(0, "group") - self.chat1 = Chat(1, "group") - self.chat2 = Chat(2, "group") - - self.user0 = User(0, "user0", False) - self.user1 = User(1, "user1", False) - self.user2 = User(2, "user2", False) - - def test_new_game(self): - g0 = self.gm.new_game(self.chat0) - g1 = self.gm.new_game(self.chat1) - - self.assertListEqual(self.gm.chatid_games[0], [g0]) - self.assertListEqual(self.gm.chatid_games[1], [g1]) - - def test_join_game(self): - self.assertRaises( - NoGameInChatError, - self.gm.join_game, - *(self.user0, self.chat0), - ) - - g0 = self.gm.new_game(self.chat0) - - self.gm.join_game(self.user0, self.chat0) - assert len(g0.players) == 1 - - self.gm.join_game(self.user1, self.chat0) - assert len(g0.players) == 2 - - g0.open = False - self.assertRaises( - LobbyClosedError, - self.gm.join_game, - *(self.user2, self.chat0), - ) - - g0.open = True - self.assertRaises( - AlreadyJoinedError, - self.gm.join_game, - *(self.user1, self.chat0), - ) - - def test_leave_game(self): - self.start_and_join() - self.assertRaises( - NotEnoughPlayersError, - self.gm.leave_game, - *(self.user1, self.chat0), - ) - - self.gm.join_game(self.user2, self.chat0) - self.gm.leave_game(self.user0, self.chat0) - - self.assertRaises( - NoGameInChatError, - self.gm.leave_game, - *(self.user0, self.chat0), - ) - - def test_end_game(self): - self.start_and_join() - assert len(self.gm.userid_players[0]) == 1 - - self.gm.new_game(self.chat0) - self.gm.join_game(self.user2, self.chat0) - - self.gm.end_game(self.chat0, self.user0) - assert len(self.gm.chatid_games[0]) == 1 - - self.gm.end_game(self.chat0, self.user2) - assert 0 not in self.gm.chatid_games - assert 0 not in self.gm.userid_players - assert 1 not in self.gm.userid_players - assert 2 not in self.gm.userid_players - - def start_and_join(self): - self.gm.new_game(self.chat0) - self.gm.join_game(self.user0, self.chat0) - self.gm.join_game(self.user1, self.chat0) diff --git a/test/test_player.py b/test/test_player.py deleted file mode 100644 index f32d21b..0000000 --- a/test/test_player.py +++ /dev/null @@ -1,181 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import unittest - -import card as c -from game import Game -from player import Player - - -class Test(unittest.TestCase): - game = None - - def setUp(self): - self.game = Game(None, None) - - def test_insert(self): - p0 = Player(self.game, "Player 0") - p1 = Player(self.game, "Player 1") - p2 = Player(self.game, "Player 2") - - assert p0 == p2.next - assert p1 == p0.next - assert p2 == p1.next - - assert p0.prev == p2 - assert p1.prev == p0 - assert p2.prev == p1 - - def test_reverse(self): - p0 = Player(self.game, "Player 0") - p1 = Player(self.game, "Player 1") - p2 = Player(self.game, "Player 2") - self.game.reverse() - p3 = Player(self.game, "Player 3") - - assert p0 == p3.next - assert p1 == p2.next - assert p2 == p0.next - assert p3 == p1.next - - assert p0 == p2.prev - assert p1 == p3.prev - assert p2 == p1.prev - assert p3 == p0.prev - - def test_leave(self): - p0 = Player(self.game, "Player 0") - p1 = Player(self.game, "Player 1") - p2 = Player(self.game, "Player 2") - - p1.leave() - - assert p0 == p2.next - assert p2 == p0.next - - def test_draw(self): - p = Player(self.game, "Player 0") - self.game.start() - - deck_before = len(self.game.deck.cards) - top_card = self.game.deck.cards[-1] - - p.draw() - - assert top_card == p.cards[-1] - assert deck_before == len(self.game.deck.cards) + 1 - - def test_draw_two(self): - p = Player(self.game, "Player 0") - self.game.start() - - deck_before = len(self.game.deck.cards) - self.game.draw_counter = 2 - - p.draw() - - assert deck_before == len(self.game.deck.cards) + 2 - - def test_playable_cards_simple(self): - p = Player(self.game, "Player 0") - - self.game.last_card = c.Card(c.RED, "5") - - p.cards = [ - c.Card(c.RED, "0"), - c.Card(c.RED, "5"), - c.Card(c.BLUE, "0"), - c.Card(c.GREEN, "5"), - c.Card(c.GREEN, "8"), - ] - - expected = [c.Card(c.RED, "0"), c.Card(c.RED, "5"), c.Card(c.GREEN, "5")] - - self.assertListEqual(p.playable_cards(), expected) - - def test_playable_cards_on_draw_two(self): - p = Player(self.game, "Player 0") - - self.game.last_card = c.Card(c.RED, c.DRAW_TWO) - self.game.draw_counter = 2 - - p.cards = [ - c.Card(c.RED, c.DRAW_TWO), - c.Card(c.RED, "5"), - c.Card(c.BLUE, "0"), - c.Card(c.GREEN, "5"), - c.Card(c.GREEN, c.DRAW_TWO), - ] - - expected = [c.Card(c.RED, c.DRAW_TWO), c.Card(c.GREEN, c.DRAW_TWO)] - - self.assertListEqual(p.playable_cards(), expected) - - def test_playable_cards_on_draw_four(self): - p = Player(self.game, "Player 0") - - self.game.last_card = c.Card(c.RED, None, c.DRAW_FOUR) - self.game.draw_counter = 4 - - p.cards = [ - c.Card(c.RED, c.DRAW_TWO), - c.Card(c.RED, "5"), - c.Card(c.BLUE, "0"), - c.Card(c.GREEN, "5"), - c.Card(c.GREEN, c.DRAW_TWO), - c.Card(None, None, c.DRAW_FOUR), - c.Card(None, None, c.CHOOSE), - ] - - expected = [] - - self.assertListEqual(p.playable_cards(), expected) - - def test_bluffing(self): - p = Player(self.game, "Player 0") - Player(self.game, "Player 01") - - self.game.last_card = c.Card(c.RED, "1") - - p.cards = [ - c.Card(c.RED, c.DRAW_TWO), - c.Card(c.RED, "5"), - c.Card(c.BLUE, "0"), - c.Card(c.GREEN, "5"), - c.Card(c.RED, "5"), - c.Card(c.GREEN, c.DRAW_TWO), - c.Card(None, None, c.DRAW_FOUR), - c.Card(None, None, c.CHOOSE), - ] - - p.playable_cards() - assert p.bluffing - - p.cards = [ - c.Card(c.BLUE, "1"), - c.Card(c.GREEN, "1"), - c.Card(c.GREEN, c.DRAW_TWO), - c.Card(None, None, c.DRAW_FOUR), - c.Card(None, None, c.CHOOSE), - ] - - p.playable_cards() - - p.play(c.Card(None, None, c.DRAW_FOUR)) - self.game.choose_color(c.GREEN) - - assert not self.game.current_player.prev.bluffing diff --git a/user_setting.py b/user_setting.py deleted file mode 100644 index b8cf059..0000000 --- a/user_setting.py +++ /dev/null @@ -1,29 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -from pony.orm import Optional, PrimaryKey - -from database import db - - -class UserSetting(db.Entity): - id = PrimaryKey(int, auto=False, size=64) # Telegram User ID - lang = Optional(str, default="") # The language setting for this user - stats = Optional(bool, default=False) # Opt-in to keep game statistics - first_places = Optional(int, default=0) # Nr. of games won in first place - games_played = Optional(int, default=0) # Nr. of games completed - cards_played = Optional(int, default=0) # Nr. of cards played total - use_keyboards = Optional(bool, default=False) # Use keyboards (unused) diff --git a/utils.py b/utils.py deleted file mode 100644 index e99e426..0000000 --- a/utils.py +++ /dev/null @@ -1,126 +0,0 @@ -# Telegram bot to play UNO in group chats -# Copyright (c) 2016 Jannes Höke -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -import logging -from typing import Union - -from telegram import Chat, Update, User -from telegram.ext import ContextTypes - -from game import Game -from internationalization import _, __ -from mwt import MWT -from shared_vars import gm - -logger = logging.getLogger(__name__) - -TIMEOUT = 2.5 - - -def list_subtract(list1, list2): - """Helper function to subtract two lists and return the sorted result.""" - list1 = list1.copy() - - for x in list2: - list1.remove(x) - - return sorted(list1) - - -def display_name(user): - """Get the current players name including their username, if possible.""" - user_name = user.first_name - if user.username: - user_name += f" (@{user.username})" - return user_name - - -def display_color(color): - """Convert a color code to actual color name.""" - if color == "r": - return _("{emoji} Red").format(emoji="❤️") - if color == "b": - return _("{emoji} Blue").format(emoji="💙") - if color == "g": - return _("{emoji} Green").format(emoji="💚") - if color == "y": - return _("{emoji} Yellow").format(emoji="💛") - return None - - -def display_color_group(color, game): - """Convert a color code to actual color name.""" - if color == "r": - return __("{emoji} Red", game.translate).format(emoji="❤️") - if color == "b": - return __("{emoji} Blue", game.translate).format(emoji="💙") - if color == "g": - return __("{emoji} Green", game.translate).format(emoji="💚") - if color == "y": - return __("{emoji} Yellow", game.translate).format(emoji="💛") - return None - - -async def error(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Simple error handler.""" - if isinstance(context, Exception): - logger.exception(context) - else: - logger.exception(context.error) - - -async def send_async(context: Union[Game, Chat, User], *args, **kwargs): - """Send a message asynchronously.""" - if isinstance(context, Game) and not kwargs.get("message_thread_id"): - kwargs["message_thread_id"] = context.thread_id - - chat = context.chat if isinstance(context, Game) else context - try: - await chat.send_message(*args, **kwargs) - except Exception as e: - await error(None, e) - - -async def answer_async(context: ContextTypes.DEFAULT_TYPE, *args, **kwargs): - """Answer an inline query asynchronously.""" - try: - await context.bot.answer_inline_query(*args, **kwargs) - except Exception as e: - await error(None, e) - - -def game_is_running(game): - return game in gm.chatid_games.get(game.chat.id, []) - - -def user_is_creator(user, game): - return user.id in game.owner - - -async def user_is_admin(user, context, chat): - return user.id in await get_admin_ids(context, chat.id) - - -async def user_is_creator_or_admin(user, game, context, chat): - return user_is_creator(user, game) or await user_is_admin(user, context, chat) - - -@MWT(timeout=60 * 60) -async def get_admin_ids(context, chat_id): - """Returns a list of admin IDs for a given chat. Results are cached for 1 hour.""" - return [ - admin.user.id for admin in await context.bot.get_chat_administrators(chat_id) - ] diff --git a/version.py b/version.py new file mode 100644 index 0000000..9f715b1 --- /dev/null +++ b/version.py @@ -0,0 +1,13 @@ +version = "1.0.0-beta" + +ascii_art = f""" ___ ___ ___ + /\\__\\ /\\__\\ /\\__\\ + /:/ _/_ /:| _|_ /:/ _/_ + /:/_/\\__\\ /::|/\\__\\ /:/_/\\__\\ + \\:\\/:/ / \\/|::/ / \\:\\/:/ / + \\::/ / |:/ / \\::/ / _ _ |_ _ |_ + \\/__/ \\/__/ \\/__/ | (_)|_)(_)|_ + + Version: {version} - Powered by Hydrogram + +"""