From 534a78e447df6a90ace638e6845129265568a1a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20G?= Date: Mon, 27 Apr 2020 11:21:56 -0400 Subject: [PATCH] Iplocalise update --- .gitignore | 23 +- LICENSE | 874 ++++++++++++++++----------------- README.md | 68 +-- autoinstall.sh | 292 +++++------ bot.py | 282 +++++------ cogs/admin.py | 814 +++++++++++++++--------------- cogs/afk.py | 136 +++--- cogs/atc.py | 248 +++++----- cogs/basics.py | 142 +++--- cogs/ci.py | 622 +++++++++++------------ cogs/filter_messages.py | 120 ++--- cogs/funs.py | 380 +++++++-------- cogs/monitoring.py | 82 ++-- cogs/role.py | 304 ++++++------ cogs/search.py | 314 ++++++------ cogs/send_logs.py | 210 ++++---- cogs/sondage.py | 198 ++++---- cogs/utility.py | 815 +++++++++++++++++-------------- cogs/utils/checks.py | 248 +++++----- cogs/utils/cli_colors.py | 92 ++-- cogs/utils/db.py | 58 +-- cogs/utils/formats.py | 150 +++--- cogs/utils/maps.py | 294 +++++------ cogs/utils/menu.py | 278 +++++------ cogs/utils/paginator.py | 1004 +++++++++++++++++++------------------- cogs/vocal.py | 226 ++++----- init.sh | 6 +- requirements.txt | 20 +- texts/ci-info.md | 22 +- texts/clocks.md | 22 +- texts/help.md | 78 +-- texts/info.md | 48 +- texts/jokes.json | 28 +- texts/passport-info.md | 18 +- texts/pokemons.json | 2 +- texts/roles.md | 24 +- texts/rpoll.md | 28 +- texts/search.md | 12 +- texts/ytb.json | 30 +- 39 files changed, 4354 insertions(+), 4258 deletions(-) diff --git a/.gitignore b/.gitignore index 3663aba..ae04963 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,13 @@ -#Python -__pycache__/ -*.pyc -.env -config.py -.DS_Store -private.py - -#jetbrains -.idea/ \ No newline at end of file +#Python +__pycache__/ +*.pyc +.env +config.py +.DS_Store +private.py + +#jetbrains +.idea/ + +#Ipinfo key +ipinfoio.key \ No newline at end of file diff --git a/LICENSE b/LICENSE index d60efe4..164da0c 100755 --- a/LICENSE +++ b/LICENSE @@ -1,437 +1,437 @@ -Attribution-NonCommercial-ShareAlike 4.0 International - -======================================================================= - -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More_considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - -======================================================================= - -Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International -Public License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution-NonCommercial-ShareAlike 4.0 International Public License -("Public License"). To the extent this Public License may be -interpreted as a contract, You are granted the Licensed Rights in -consideration of Your acceptance of these terms and conditions, and the -Licensor grants You such rights in consideration of benefits the -Licensor receives from making the Licensed Material available under -these terms and conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. BY-NC-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - - d. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - e. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - f. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution, NonCommercial, and ShareAlike. - - h. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - i. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - j. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - k. NonCommercial means not primarily intended for or directed towards - commercial advantage or monetary compensation. For purposes of - this Public License, the exchange of the Licensed Material for - other material subject to Copyright and Similar Rights by digital - file-sharing or similar means is NonCommercial provided there is - no payment of monetary compensation in connection with the - exchange. - - l. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - m. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - n. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part, for NonCommercial purposes only; and - - b. produce, reproduce, and Share Adapted Material for - NonCommercial purposes only. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - - c. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties, including when - the Licensed Material is used other than for NonCommercial - purposes. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - b. ShareAlike. - - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-NC-SA Compatible License. - - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database for NonCommercial purposes - only; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material, - including for purposes of Section 3(b); and - - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - -======================================================================= - -Creative Commons is not a party to its public -licenses. Notwithstanding, Creative Commons may elect to apply one of -its public licenses to material it publishes and in those instances -will be considered the “Licensor.” The text of the Creative Commons -public licenses is dedicated to the public domain under the CC0 Public -Domain Dedication. Except for the limited purpose of indicating that -material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the -public licenses. - -Creative Commons may be contacted at creativecommons.org. +Attribution-NonCommercial-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International +Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-NonCommercial-ShareAlike 4.0 International Public License +("Public License"). To the extent this Public License may be +interpreted as a contract, You are granted the Licensed Rights in +consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the +Licensor receives from making the Licensed Material available under +these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-NC-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution, NonCommercial, and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. NonCommercial means not primarily intended for or directed towards + commercial advantage or monetary compensation. For purposes of + this Public License, the exchange of the Licensed Material for + other material subject to Copyright and Similar Rights by digital + file-sharing or similar means is NonCommercial provided there is + no payment of monetary compensation in connection with the + exchange. + + l. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + m. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + n. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part, for NonCommercial purposes only; and + + b. produce, reproduce, and Share Adapted Material for + NonCommercial purposes only. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties, including when + the Licensed Material is used other than for NonCommercial + purposes. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-NC-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database for NonCommercial purposes + only; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + including for purposes of Section 3(b); and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/README.md b/README.md index 4c06089..e3f5960 100755 --- a/README.md +++ b/README.md @@ -1,33 +1,35 @@ -TuxBot, un bot discord écrit en Python. -Ici ce trouve le code source du bot provenant du serveur Discord [Aide GNU/Linux-Fr"](https://gnous.eu/discord "Rejoindre le serveur"), il à été créé spécialement pour ce discord, si vous souhaitez l'utiliser il vous faudra modifier ``params.json`` et ``cogs/utils/checks.py`` ;) - -### Pré-requis - -Il vous faut : - -- Un ordinateur sous **GNU/Linux** avec une connexion à internet; -- Python3.7 ou + ; -- Installer ``requirements.txt`` (avec ``pip install -r requirements.txt`` par ex) - -### Installation - -Une fois les pré-requis installés et ``config.py.example`` renommé en ``config.py`` éditez le. Ensuite placez vous dans le repertoire de tuxbot et lancez ``bot.py`` avec python3 (ex: ``python3 bot.py``) - -## Démarrage - -Placez vous dans le repertoire de tuxbot et exécutez ``bot.py`` avec python3 (ex: ``python3 bot.py``) - -## Fabriqué avec -* [PyCharm](https://www.jetbrains.com/pycharm/) - Editeur de texte payant :3 -* [discord.py](https://github.com/Rapptz/discord.py) - API Python pour discord - -## Versions -Liste des versions : [Cliquer pour afficher](https://github.com/outout14/tuxbot-bot/tags) - -## Auteurs -* **Maël** _alias_ [@outout14](https://github.com/outout14) -* **Romain** _alias_ [Romain le malchanceux](https://github.com/Rom194) - -## License - -Ce projet est sous licence ``Creative Commons BY-NC-SA 4.0`` - voir le fichier [LICENSE.md](LICENSE.md) pour plus d'informations +TuxBot, un bot discord écrit en Python. +Ici ce trouve le code source du bot provenant du serveur Discord [Aide GNU/Linux-Fr"](https://gnous.eu/discord "Rejoindre le serveur"), il à été créé spécialement pour ce discord, si vous souhaitez l'utiliser il vous faudra modifier ``params.json`` et ``cogs/utils/checks.py`` ;) + +### Pré-requis + +Il vous faut : + +- Un ordinateur sous **GNU/Linux** avec une connexion à internet; +- Python3.7 ou + ; +- Installer ``requirements.txt`` (avec ``pip install -r requirements.txt`` par ex) + +### Installation + +Une fois les pré-requis installés et ``config.py.example`` renommé en ``config.py`` éditez le. Ensuite placez vous dans le repertoire de tuxbot et lancez ``bot.py`` avec python3 (ex: ``python3 bot.py``) + +Tuxbot recommande l'utilisation de l'API https://ipinfo.io/ pour des résultats plus précis. Placez votre token d'accès dans un fichier nommé ``ipinfoio.key`` à la racine du dossier du bot. Si vous ne souhaitez pas utiliser leur API le bot rollback automatiquement sur une librairie moins précise. + +## Démarrage + +Placez vous dans le repertoire de tuxbot et exécutez ``bot.py`` avec python3 (ex: ``python3 bot.py``) + +## Fabriqué avec +* [PyCharm](https://www.jetbrains.com/pycharm/) - Editeur de texte payant :3 +* [discord.py](https://github.com/Rapptz/discord.py) - API Python pour discord + +## Versions +Liste des versions : [Cliquer pour afficher](https://github.com/outout14/tuxbot-bot/tags) + +## Auteurs +* **Maël** _alias_ [@outout14](https://github.com/outout14) +* **Romain** _alias_ [Romain le malchanceux](https://github.com/Rom194) + +## License + +Ce projet est sous licence ``Creative Commons BY-NC-SA 4.0`` - voir le fichier [LICENSE.md](LICENSE.md) pour plus d'informations diff --git a/autoinstall.sh b/autoinstall.sh index 8b85a50..ff3a607 100644 --- a/autoinstall.sh +++ b/autoinstall.sh @@ -1,146 +1,146 @@ -#!/bin/bash - -# This script is meant for easy install Tuxbot using curl/wget -printf "Welcome to Tuxbot's installation guide.\n" -printf "\nLog file is in ~/.tuxinstall.log\n" -# Command checking -if (( $EUID != 0 )); then - printf "\n\nError : Please run this script as ROOT" - exit 0 -fi - -if ! [ -x "$(command -v git)" ]; then - printf "\n\nError : Git is not installed" - exit 0 -fi - -if ! [ -x "$(command -v pip3.7)" ]; then - printf "\n\nError : pip3.7 is not installed (using pip3.7 command)\nPlease install it to continue" - exit 0 -fi - -# Tuxbot directory answer -read -p "In which directory Tuxbot should be installed ? : [/srv/]" na -na=${na:-"/srv/"} - -# Cloning tuxbot USING GNOUS'S GIT MIRROR -printf "Cloning git repository, please wait... \n" & -git clone https://git.gnous.eu/gnouseu/tuxbot-bot $na/tuxbot-bot &> ~/.tuxinstall.log -sleep 1 - -printf "Tuxbot has been cloned to $na.\n" 5 50 -sleep 1 -printf "Installing pip modules, please wait...\n" 5 50 & -sleep 1 - -# Downloading PIP modules using pip3.7 cmd -pip3.7 install -U discord.py[voice] &> ~/.tuxinstall.log -cd $na/tuxbot-bot -pip3.7 install -r requirements.txt &> ~/.tuxinstall.log -sleep 1 - -printf "Tuxbot's python dependencies have been downloaded\n" -sleep 1 - -# Answers to generate config -function generateConfig { - DATE=`date +%Y-%m-%d` - read -p "Enter your Discord API Token : " cToken - read -p "Enter the bot client ID : " cID - read -p "Enter the log channel ID : " cLogID - read -p "Enter the main channel of your server : " cSrvID - read -p "What game tuxbot should display as playing (eg : 'Eat potatoes') : " cGame - read -p "What is you're discord user ID (for admin cmd) : " cAdmin - echo "------------" - read -p "MySQL's tuxbot user : " mSQLuser - read -p "MySQL's tuxbot password : " mSQLpass - read -p "MySQL's tuxbot database name : " mSQLdb - echo """ -#Generated by Tuxbot install script -#$DATE -token = \"$cToken\" -client_id = \"$cID\" -log_channel_id = \"$cLogID\" -main_server_id = \"$cSrvID\" -game = \"$cGame\" -authorized_id = [\"$cAdmin\"] -prefix = [\".\"] -description = '.' -mysql = { - \"host\": \"localhost\", - \"username\": \"$mSQLuser\", - \"password\": \"$mSQLpass\", - \"dbname\": \"$mSQLdb\" -} -fonts = { - \"normal\": \"NotoSansCJK-Regular.ttc\", - \"bold\": \"NotoSansCJK-Bold.ttc\" -} -""" &> $na/tuxbot-bot/config.py -} - -printf "Do you want to generate config file ?\n1 - Yes (selected)\n2 - No\n" -read -p "(1-2) : " initConf -initConf=${initConf:-"1"} -case $initConf in - 1) generateConfig;; -esac - -#Non login user -echo "Adding tuxbot non-login user..." -useradd -M tuxbot -sleep 1 - -#Chown all perms to the non login user -echo "Fixing permissions..." -chown tuxbot:tuxbot -R $na/tuxbot-bot/ -sleep 1 - -#Create the service file -echo "Adding Tuxbot service & start it..." -echo """[Unit] -Description=Tuxbot, a discord bot -#After=network.target - -[Service] -Type=simple -User=tuxbot - -Restart=on-failure -Restart=always -RestartSec=1 - -WorkingDirectory=$na/tuxbot-bot/ -ExecStart=/usr/bin/env python3.7 $na/tuxbot-bot/bot.py - -StandardOutput=file:/var/log/tuxbot.log - -[Install] -WantedBy=multi-user.target -""" &> /lib/systemd/system/tuxbot.service -systemctl daemon-reload -systemctl start tuxbot -sleep 1 -echo "Activation of tuxbot at startup..." -sleep 1 -systemctl enable tuxbot - -#End message -echo """ - - -Tuxbot should be correctly installed. -Please check if all is good by execute : -systemctl status tuxbot -And .ping command in discord. - -Configuration file is $na/tuxbot-bot/config.py -Main tuxbot directory is $na/tuxbot-bot/ - -Any question ? => Make an issue on github - -https://git.gnous.eu/gnouseu/tuxbot-bot -https://github.com/outout14/tuxbot-bot - - -""" +#!/bin/bash + +# This script is meant for easy install Tuxbot using curl/wget +printf "Welcome to Tuxbot's installation guide.\n" +printf "\nLog file is in ~/.tuxinstall.log\n" +# Command checking +if (( $EUID != 0 )); then + printf "\n\nError : Please run this script as ROOT" + exit 0 +fi + +if ! [ -x "$(command -v git)" ]; then + printf "\n\nError : Git is not installed" + exit 0 +fi + +if ! [ -x "$(command -v pip3.7)" ]; then + printf "\n\nError : pip3.7 is not installed (using pip3.7 command)\nPlease install it to continue" + exit 0 +fi + +# Tuxbot directory answer +read -p "In which directory Tuxbot should be installed ? : [/srv/]" na +na=${na:-"/srv/"} + +# Cloning tuxbot USING GNOUS'S GIT MIRROR +printf "Cloning git repository, please wait... \n" & +git clone https://git.gnous.eu/gnouseu/tuxbot-bot $na/tuxbot-bot &> ~/.tuxinstall.log +sleep 1 + +printf "Tuxbot has been cloned to $na.\n" 5 50 +sleep 1 +printf "Installing pip modules, please wait...\n" 5 50 & +sleep 1 + +# Downloading PIP modules using pip3.7 cmd +pip3.7 install -U discord.py[voice] &> ~/.tuxinstall.log +cd $na/tuxbot-bot +pip3.7 install -r requirements.txt &> ~/.tuxinstall.log +sleep 1 + +printf "Tuxbot's python dependencies have been downloaded\n" +sleep 1 + +# Answers to generate config +function generateConfig { + DATE=`date +%Y-%m-%d` + read -p "Enter your Discord API Token : " cToken + read -p "Enter the bot client ID : " cID + read -p "Enter the log channel ID : " cLogID + read -p "Enter the main channel of your server : " cSrvID + read -p "What game tuxbot should display as playing (eg : 'Eat potatoes') : " cGame + read -p "What is you're discord user ID (for admin cmd) : " cAdmin + echo "------------" + read -p "MySQL's tuxbot user : " mSQLuser + read -p "MySQL's tuxbot password : " mSQLpass + read -p "MySQL's tuxbot database name : " mSQLdb + echo """ +#Generated by Tuxbot install script +#$DATE +token = \"$cToken\" +client_id = \"$cID\" +log_channel_id = \"$cLogID\" +main_server_id = \"$cSrvID\" +game = \"$cGame\" +authorized_id = [\"$cAdmin\"] +prefix = [\".\"] +description = '.' +mysql = { + \"host\": \"localhost\", + \"username\": \"$mSQLuser\", + \"password\": \"$mSQLpass\", + \"dbname\": \"$mSQLdb\" +} +fonts = { + \"normal\": \"NotoSansCJK-Regular.ttc\", + \"bold\": \"NotoSansCJK-Bold.ttc\" +} +""" &> $na/tuxbot-bot/config.py +} + +printf "Do you want to generate config file ?\n1 - Yes (selected)\n2 - No\n" +read -p "(1-2) : " initConf +initConf=${initConf:-"1"} +case $initConf in + 1) generateConfig;; +esac + +#Non login user +echo "Adding tuxbot non-login user..." +useradd -M tuxbot +sleep 1 + +#Chown all perms to the non login user +echo "Fixing permissions..." +chown tuxbot:tuxbot -R $na/tuxbot-bot/ +sleep 1 + +#Create the service file +echo "Adding Tuxbot service & start it..." +echo """[Unit] +Description=Tuxbot, a discord bot +#After=network.target + +[Service] +Type=simple +User=tuxbot + +Restart=on-failure +Restart=always +RestartSec=1 + +WorkingDirectory=$na/tuxbot-bot/ +ExecStart=/usr/bin/env python3.7 $na/tuxbot-bot/bot.py + +StandardOutput=file:/var/log/tuxbot.log + +[Install] +WantedBy=multi-user.target +""" &> /lib/systemd/system/tuxbot.service +systemctl daemon-reload +systemctl start tuxbot +sleep 1 +echo "Activation of tuxbot at startup..." +sleep 1 +systemctl enable tuxbot + +#End message +echo """ + + +Tuxbot should be correctly installed. +Please check if all is good by execute : +systemctl status tuxbot +And .ping command in discord. + +Configuration file is $na/tuxbot-bot/config.py +Main tuxbot directory is $na/tuxbot-bot/ + +Any question ? => Make an issue on github + +https://git.gnous.eu/gnouseu/tuxbot-bot +https://github.com/outout14/tuxbot-bot + + +""" diff --git a/bot.py b/bot.py index 174694d..ddf0fd7 100755 --- a/bot.py +++ b/bot.py @@ -1,141 +1,141 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -__author__ = "Maël / Outout | Romain" -__licence__ = "WTFPL Licence 2.0" - - -import copy -import datetime -import os -import sys -import traceback - -import aiohttp -import discord -from discord.ext import commands - -import cogs.utils.cli_colors as colors -import config -from cogs.utils import checks - -if sys.version_info[1] < 7 or sys.version_info[0] < 3: - print(f"{colors.text_colors.RED}[ERROR] Python 3.7 or + is required.{colors.ENDC}") - exit() - -l_extensions = ( - 'cogs.admin', - 'cogs.afk', - 'cogs.atc', - 'cogs.basics', - 'cogs.ci', - 'cogs.filter_messages', - 'cogs.funs', - 'cogs.role', - 'cogs.search', - 'cogs.send_logs', - 'cogs.sondage', - 'cogs.utility', - 'cogs.vocal', - 'cogs.private', - 'cogs.monitoring', - 'jishaku' -) - -help_attrs = dict(hidden=True, in_help=True, name="DONOTUSE") - - -class TuxBot(commands.Bot): - def __init__(self): - self.uptime = datetime.datetime.utcnow() - self.config = config - super().__init__(command_prefix=self.config.prefix[0], - description=self.config.description, - pm_help=None, - help_command=None) - - self.client_id = self.config.client_id - self.session = aiohttp.ClientSession(loop=self.loop) - self._events = [] - - self.add_command(self.do) - - for extension in l_extensions: - try: - self.load_extension(extension) - print(f"{colors.text_colors.GREEN}\"{extension}\"" - f" chargé !{colors.ENDC}") - except Exception as e: - print(f"{colors.text_colors.RED}" - f"Impossible de charger l'extension {extension}\n" - f"{type(e).__name__}: {e}{colors.ENDC}", file=sys.stderr) - - async def is_owner(self, user: discord.User): - return str(user.id) in config.authorized_id - - async def on_command_error(self, ctx, error): - if isinstance(error, commands.NoPrivateMessage): - await ctx.author.send('Cette commande ne peut pas être utilisee ' - 'en message privee.') - elif isinstance(error, commands.DisabledCommand): - await ctx.author.send('Desoler mais cette commande est desactive, ' - 'elle ne peut donc pas être utilisée.') - elif isinstance(error, commands.CommandInvokeError): - print(f'In {ctx.command.qualified_name}:', file=sys.stderr) - traceback.print_tb(error.original.__traceback__) - print(f'{error.original.__class__.__name__}: {error.original}', - file=sys.stderr) - - async def on_ready(self): - log_channel_id = await self.fetch_channel(self.config.log_channel_id) - - print('\n\n---------------------') - print('CONNECTÉ :') - print(f'Nom d\'utilisateur: {self.user} {colors.text_style.DIM}' - f'(ID: {self.user.id}){colors.ENDC}') - print(f'Channel de log: {log_channel_id} {colors.text_style.DIM}' - f'(ID: {log_channel_id.id}){colors.ENDC}') - print(f'Prefix: {self.config.prefix[0]}') - print('Merci d\'utiliser TuxBot') - print('---------------------\n\n') - - await self.change_presence(status=discord.Status.dnd, - activity=discord.Game( - name=self.config.game) - ) - - @staticmethod - async def on_resumed(): - print('resumed...') - - async def on_message(self, message): - if message.author.bot: - return - - try: - await self.process_commands(message) - except Exception as e: - print(f'{colors.text_colors.RED}Erreur rencontré : \n' - f' {type(e).__name__}: {e}{colors.ENDC} \n \n') - - def run(self): - super().run(self.config.token, reconnect=True) - - @checks.has_permissions(administrator=True) - @commands.command(pass_context=True, hidden=True) - async def do(self, ctx, times: int, *, command): - """Repeats a command a specified number of times.""" - msg = copy.copy(ctx.message) - msg.content = command - for i in range(times): - await self.process_commands(msg) - - -if __name__ == '__main__': - if os.path.exists('config.py') is not True: - print(f"{colors.text_colors.RED}" - f"Veuillez créer le fichier config.py{colors.ENDC}") - exit() - - tuxbot = TuxBot() - tuxbot.run() +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +__author__ = "Maël / Outout | Romain" +__licence__ = "WTFPL Licence 2.0" + + +import copy +import datetime +import os +import sys +import traceback + +import aiohttp +import discord +from discord.ext import commands + +import cogs.utils.cli_colors as colors +import config +from cogs.utils import checks + +if sys.version_info[1] < 7 or sys.version_info[0] < 3: + print(f"{colors.text_colors.RED}[ERROR] Python 3.7 or + is required.{colors.ENDC}") + exit() + +l_extensions = ( + 'cogs.admin', + 'cogs.afk', + 'cogs.atc', + 'cogs.basics', + 'cogs.ci', + 'cogs.filter_messages', + 'cogs.funs', + 'cogs.role', + 'cogs.search', + 'cogs.send_logs', + 'cogs.sondage', + 'cogs.utility', + 'cogs.vocal', + 'cogs.private', + 'cogs.monitoring', + 'jishaku' +) + +help_attrs = dict(hidden=True, in_help=True, name="DONOTUSE") + + +class TuxBot(commands.Bot): + def __init__(self): + self.uptime = datetime.datetime.utcnow() + self.config = config + super().__init__(command_prefix=self.config.prefix[0], + description=self.config.description, + pm_help=None, + help_command=None) + + self.client_id = self.config.client_id + self.session = aiohttp.ClientSession(loop=self.loop) + self._events = [] + + self.add_command(self.do) + + for extension in l_extensions: + try: + self.load_extension(extension) + print(f"{colors.text_colors.GREEN}\"{extension}\"" + f" chargé !{colors.ENDC}") + except Exception as e: + print(f"{colors.text_colors.RED}" + f"Impossible de charger l'extension {extension}\n" + f"{type(e).__name__}: {e}{colors.ENDC}", file=sys.stderr) + + async def is_owner(self, user: discord.User): + return str(user.id) in config.authorized_id + + async def on_command_error(self, ctx, error): + if isinstance(error, commands.NoPrivateMessage): + await ctx.author.send('Cette commande ne peut pas être utilisee ' + 'en message privee.') + elif isinstance(error, commands.DisabledCommand): + await ctx.author.send('Desoler mais cette commande est desactive, ' + 'elle ne peut donc pas être utilisée.') + elif isinstance(error, commands.CommandInvokeError): + print(f'In {ctx.command.qualified_name}:', file=sys.stderr) + traceback.print_tb(error.original.__traceback__) + print(f'{error.original.__class__.__name__}: {error.original}', + file=sys.stderr) + + async def on_ready(self): + log_channel_id = await self.fetch_channel(self.config.log_channel_id) + + print('\n\n---------------------') + print('CONNECTÉ :') + print(f'Nom d\'utilisateur: {self.user} {colors.text_style.DIM}' + f'(ID: {self.user.id}){colors.ENDC}') + print(f'Channel de log: {log_channel_id} {colors.text_style.DIM}' + f'(ID: {log_channel_id.id}){colors.ENDC}') + print(f'Prefix: {self.config.prefix[0]}') + print('Merci d\'utiliser TuxBot') + print('---------------------\n\n') + + await self.change_presence(status=discord.Status.dnd, + activity=discord.Game( + name=self.config.game) + ) + + @staticmethod + async def on_resumed(): + print('resumed...') + + async def on_message(self, message): + if message.author.bot: + return + + try: + await self.process_commands(message) + except Exception as e: + print(f'{colors.text_colors.RED}Erreur rencontré : \n' + f' {type(e).__name__}: {e}{colors.ENDC} \n \n') + + def run(self): + super().run(self.config.token, reconnect=True) + + @checks.has_permissions(administrator=True) + @commands.command(pass_context=True, hidden=True) + async def do(self, ctx, times: int, *, command): + """Repeats a command a specified number of times.""" + msg = copy.copy(ctx.message) + msg.content = command + for i in range(times): + await self.process_commands(msg) + + +if __name__ == '__main__': + if os.path.exists('config.py') is not True: + print(f"{colors.text_colors.RED}" + f"Veuillez créer le fichier config.py{colors.ENDC}") + exit() + + tuxbot = TuxBot() + tuxbot.run() diff --git a/cogs/admin.py b/cogs/admin.py index c5586f6..641ae3e 100755 --- a/cogs/admin.py +++ b/cogs/admin.py @@ -1,407 +1,407 @@ -import aiohttp -from discord.ext import commands -import discord -from .utils import checks - -from .utils.checks import get_user - - -class Admin(commands.Cog): - """Commandes secrètes d'administration.""" - - def __init__(self, bot): - self.bot = bot - self._last_result = None - self.sessions = set() - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name="upload", pass_context=True) - async def _upload(self, ctx, *, url=""): - if len(ctx.message.attachments) >= 1: - file = ctx.message.attachments[0].url - elif url != "": - file = url - else: - em = discord.Embed(title='Une erreur est survenue', - description="Fichier introuvable.", - colour=0xDC3546) - await ctx.send(embed=em) - return - - async with aiohttp.ClientSession() as session: - async with session.get(file) as r: - image = await r.content.read() - - with open(f"data/tmp/{str(ctx.author.id)}.png", 'wb') as f: - f.write(image) - f.close() - await ctx.send(file=discord.File(f"data/tmp/{str(ctx.author.id)}.png")) - - @checks.has_permissions(administrator=True) - @commands.command(name="ban", pass_context=True) - async def _ban(self, ctx, user, *, reason=""): - """Ban user""" - user = get_user(ctx.message, user) - if user and str(user.id) not in self.bot.config.unkickable_id: - try: - await user.ban(reason=reason) - return_msg = f"`{user.mention}` a été banni\n" - if reason: - return_msg += f"raison : `{reason}`" - return_msg += "." - await ctx.send(return_msg) - except discord.Forbidden: - await ctx.send('Impossible de bannir cet user,' - ' probleme de permission.') - else: - return await ctx.send('Impossible de trouver l\'user.') - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name="kick", pass_context=True) - async def _kick(self, ctx, user, *, reason=""): - """Kick a user""" - user = get_user(ctx.message, user) - if user and str(user.id) not in self.bot.config.unkickable_id: - try: - await user.kick(reason=reason) - return_msg = f"`{user.mention}` a été kické\n" - if reason: - return_msg += f"raison : `{reason}`" - return_msg += "." - await ctx.send(return_msg) - except discord.Forbidden: - await ctx.send('Impossible de kicker cet user,' - ' probleme de permission.') - else: - return await ctx.send('Impossible de trouver l\'user.') - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name='clear', pass_context=True) - async def _clear(self, ctx, number: int, silent: str = True): - """Clear of message(s)""" - try: - await ctx.message.delete() - except Exception: - print(f"Impossible de supprimer le message " - f"\"{str(ctx.message.content)}\"") - if number < 1000: - try: - await ctx.message.channel.purge(limit=number) - except Exception as e: # TODO : A virer dans l'event on_error - if silent is not True: - await ctx.send(f':sob: Une erreur est survenue : \n' - f' {type(e).__name__}: {e}') - if silent is not True: - await ctx.send("Hop voila j'ai viré des messages! Hello World") - print(f"{str(number)} messages ont été supprimés") - else: - await ctx.send('Trop de messages, entre un nombre < 1000') - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name='say', pass_context=True) - async def _say(self, ctx, *, tosay: str): - """Say a message in the current channel""" - try: - try: - await ctx.message.delete() - except Exception: - print(f"Impossible de supprimer le message " - f"\"{str(ctx.message.content)}\"") - await ctx.send(tosay) - except Exception as e: # TODO : A virer dans l'event on_error - await ctx.send(f':sob: Une erreur est survenue : \n' - f' {type(e).__name__}: {e}') - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name='sayto', pass_context=True) - async def _sayto(self, ctx, channel_id: int, *, tosay: str): - """Say a message in the channel""" - try: - chan = self.bot.get_channel(channel_id) - try: - await ctx.message.delete() - except Exception: - print(f"Impossible de supprimer le message " - f"\"{str(ctx.message.content)}\"") - try: - await chan.send(tosay) - except Exception: - print(f"Impossible d'envoyer le message dans {str(channel_id)}") - except Exception as e: # TODO : A virer dans l'event on_error - await ctx.send(f':sob: Une erreur est survenue : \n' - f' {type(e).__name__}: {e}') - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name='sayto_dm', pass_context=True) - async def _sayto_dm(self, ctx, user_id: int, *, tosay: str): - """Say a message to the user""" - try: - user = self.bot.get_user(user_id) - try: - await ctx.message.delete() - except Exception: - print(f"Impossible de supprimer le message " - f"\"{str(ctx.message.content)}\"") - try: - await user.send(tosay) - except Exception: - print(f"Impossible d'envoyer le message dans {str(user_id)}") - except Exception as e: # TODO : A virer dans l'event on_error - await ctx.send(f':sob: Une erreur est survenue : \n' - f' {type(e).__name__}: {e}') - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name='editsay', pass_context=True) - async def _editsay(self, ctx, message_id: int, *, new_content: str): - """Edit a bot's message""" - try: - try: - await ctx.message.delete() - except Exception: - print(f"Impossible de supprimer le message " - f"\"{str(ctx.message.content)}\"") - toedit = await ctx.channel.fetch_message(message_id) - except discord.errors.NotFound: - await ctx.send(f"Impossible de trouver le message avec l'id " - f"`{message_id}` sur ce salon") - return - try: - await toedit.edit(content=str(new_content)) - except discord.errors.Forbidden: - await ctx.send("J'ai po les perms pour editer mes messages :(") - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name='addreaction', pass_context=True) - async def _addreaction(self, ctx, message_id: int, reaction: str): - """Add reactions to a message""" - try: - try: - await ctx.message.delete() - except Exception: - print(f"Impossible de supprimer le message " - f"\"{str(ctx.message.content)}\"") - toadd = await ctx.channel.fetch_message(message_id) - except discord.errors.NotFound: - await ctx.send(f"Impossible de trouver le message avec l'id " - f"`{message_id}` sur ce salon") - return - try: - await toadd.add_reaction(reaction) - except discord.errors.Forbidden: - await ctx.send("J'ai po les perms pour ajouter des réactions :(") - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name='delete', pass_context=True) - async def _delete(self, ctx, message_id: int): - """Delete message in current channel""" - try: - try: - await ctx.message.delete() - except Exception: - print(f"Impossible de supprimer le message " - f"\"{str(ctx.message.content)}\"") - todelete = await ctx.channel.fetch_message(message_id) - except discord.errors.NotFound: - await ctx.send(f"Impossible de trouver le message avec l'id " - f"`{message_id}` sur ce salon") - return - try: - await todelete.delete() - except discord.errors.Forbidden: - await ctx.send("J'ai po les perms pour supprimer des messages :(") - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name='deletefrom', pass_context=True) - async def _deletefrom(self, ctx, chan_id: int, *, message_id: int): - """Delete message in channel""" - try: - chan = self.bot.get_channel(chan_id) - try: - await ctx.message.delete() - except Exception: - print(f"Impossible de supprimer le message " - f"\"{str(ctx.message.content)}\"") - todelete = await chan.fetch_message(message_id) - except discord.errors.NotFound: - await ctx.send(f"Impossible de trouver le message avec l'id " - f"`{id}` sur le salon") - return - try: - await todelete.delete() - except discord.errors.Forbidden: - await ctx.send("J'ai po les perms pour supprimer le message :(") - - """---------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @commands.command(name='embed', pass_context=True) - async def _embed(self, ctx, *, msg: str = "help"): - """Send an embed""" - if msg != "help": - ptext = title \ - = description \ - = image \ - = thumbnail \ - = color \ - = footer \ - = author \ - = None - timestamp = discord.Embed.Empty - embed_values = msg.split('|') - for i in embed_values: - if i.strip().lower().startswith('ptext='): - ptext = i.strip()[6:].strip() - elif i.strip().lower().startswith('title='): - title = i.strip()[6:].strip() - elif i.strip().lower().startswith('description='): - description = i.strip()[12:].strip() - elif i.strip().lower().startswith('desc='): - description = i.strip()[5:].strip() - elif i.strip().lower().startswith('image='): - image = i.strip()[6:].strip() - elif i.strip().lower().startswith('thumbnail='): - thumbnail = i.strip()[10:].strip() - elif i.strip().lower().startswith('colour='): - color = i.strip()[7:].strip() - elif i.strip().lower().startswith('color='): - color = i.strip()[6:].strip() - elif i.strip().lower().startswith('footer='): - footer = i.strip()[7:].strip() - elif i.strip().lower().startswith('author='): - author = i.strip()[7:].strip() - elif i.strip().lower().startswith('timestamp'): - timestamp = ctx.message.created_at - else: - if description is None and not i.strip()\ - .lower().startswith('field='): - description = i.strip() - - if color: - if color.startswith('#'): - color = color[1:] - if not color.startswith('0x'): - color = '0x' + color - - if ptext \ - is title \ - is description \ - is image \ - is thumbnail \ - is color \ - is footer \ - is author \ - is None \ - and 'field=' not in msg: - try: - await ctx.message.delete() - except Exception: - print("Impossible de supprimer le message \"" + str( - ctx.message.content) + "\"") - return await ctx.send(content=None, - embed=discord.Embed(description=msg)) - - if color: - em = discord.Embed(timestamp=timestamp, title=title, - description=description, - color=int(color, 16)) - else: - em = discord.Embed(timestamp=timestamp, title=title, - description=description) - for i in embed_values: - if i.strip().lower().startswith('field='): - field_inline = True - field = i.strip().lstrip('field=') - field_name, field_value = field.split('value=') - if 'inline=' in field_value: - field_value, field_inline = field_value.split( - 'inline=') - if 'false' in field_inline.lower() \ - or 'no' in field_inline.lower(): - field_inline = False - field_name = field_name.strip().lstrip('name=') - em.add_field(name=field_name, value=field_value.strip(), - inline=field_inline) - if author: - if 'icon=' in author: - text, icon = author.split('icon=') - if 'url=' in icon: - em.set_author(name=text.strip()[5:], - icon_url=icon.split('url=')[0].strip(), - url=icon.split('url=')[1].strip()) - else: - em.set_author(name=text.strip()[5:], icon_url=icon) - else: - if 'url=' in author: - em.set_author(name=author.split('url=')[0].strip()[5:], - url=author.split('url=')[1].strip()) - else: - em.set_author(name=author) - - if image: - em.set_image(url=image) - if thumbnail: - em.set_thumbnail(url=thumbnail) - if footer: - if 'icon=' in footer: - text, icon = footer.split('icon=') - em.set_footer(text=text.strip()[5:], icon_url=icon) - else: - em.set_footer(text=footer) - - try: - await ctx.message.delete() - except Exception: - print("Impossible de supprimer le message \"" + str( - ctx.message.content) + "\"") - await ctx.send(content=ptext, embed=em) - - else: - embed = discord.Embed( - title="Aide sur l'utilisation de la commande .embed:") - embed.add_field(name="Titre:", value="title=", - inline=True) - embed.add_field(name="Description:", - value="description=", inline=True) - embed.add_field(name="Couleur:", value="color=", - inline=True) - embed.add_field(name="Image:", - value="image=", - inline=True) - embed.add_field(name="Thumbnail:", - value="thumbnail=", inline=True) - embed.add_field(name="Auteur:", value="author=", - inline=True) - embed.add_field(name="Icon", value="icon=", - inline=True) - embed.add_field(name="Footer", value="footer=", - inline=True) - embed.set_footer(text="Exemple: .embed title=Un titre |" - " description=Une description |" - " color=3AB35E |" - " field=name=test value=test") - - await ctx.send(embed=embed) - - -def setup(bot): - bot.add_cog(Admin(bot)) +import aiohttp +from discord.ext import commands +import discord +from .utils import checks + +from .utils.checks import get_user + + +class Admin(commands.Cog): + """Commandes secrètes d'administration.""" + + def __init__(self, bot): + self.bot = bot + self._last_result = None + self.sessions = set() + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name="upload", pass_context=True) + async def _upload(self, ctx, *, url=""): + if len(ctx.message.attachments) >= 1: + file = ctx.message.attachments[0].url + elif url != "": + file = url + else: + em = discord.Embed(title='Une erreur est survenue', + description="Fichier introuvable.", + colour=0xDC3546) + await ctx.send(embed=em) + return + + async with aiohttp.ClientSession() as session: + async with session.get(file) as r: + image = await r.content.read() + + with open(f"data/tmp/{str(ctx.author.id)}.png", 'wb') as f: + f.write(image) + f.close() + await ctx.send(file=discord.File(f"data/tmp/{str(ctx.author.id)}.png")) + + @checks.has_permissions(administrator=True) + @commands.command(name="ban", pass_context=True) + async def _ban(self, ctx, user, *, reason=""): + """Ban user""" + user = get_user(ctx.message, user) + if user and str(user.id) not in self.bot.config.unkickable_id: + try: + await user.ban(reason=reason) + return_msg = f"`{user.mention}` a été banni\n" + if reason: + return_msg += f"raison : `{reason}`" + return_msg += "." + await ctx.send(return_msg) + except discord.Forbidden: + await ctx.send('Impossible de bannir cet user,' + ' probleme de permission.') + else: + return await ctx.send('Impossible de trouver l\'user.') + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name="kick", pass_context=True) + async def _kick(self, ctx, user, *, reason=""): + """Kick a user""" + user = get_user(ctx.message, user) + if user and str(user.id) not in self.bot.config.unkickable_id: + try: + await user.kick(reason=reason) + return_msg = f"`{user.mention}` a été kické\n" + if reason: + return_msg += f"raison : `{reason}`" + return_msg += "." + await ctx.send(return_msg) + except discord.Forbidden: + await ctx.send('Impossible de kicker cet user,' + ' probleme de permission.') + else: + return await ctx.send('Impossible de trouver l\'user.') + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name='clear', pass_context=True) + async def _clear(self, ctx, number: int, silent: str = True): + """Clear of message(s)""" + try: + await ctx.message.delete() + except Exception: + print(f"Impossible de supprimer le message " + f"\"{str(ctx.message.content)}\"") + if number < 1000: + try: + await ctx.message.channel.purge(limit=number) + except Exception as e: # TODO : A virer dans l'event on_error + if silent is not True: + await ctx.send(f':sob: Une erreur est survenue : \n' + f' {type(e).__name__}: {e}') + if silent is not True: + await ctx.send("Hop voila j'ai viré des messages! Hello World") + print(f"{str(number)} messages ont été supprimés") + else: + await ctx.send('Trop de messages, entre un nombre < 1000') + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name='say', pass_context=True) + async def _say(self, ctx, *, tosay: str): + """Say a message in the current channel""" + try: + try: + await ctx.message.delete() + except Exception: + print(f"Impossible de supprimer le message " + f"\"{str(ctx.message.content)}\"") + await ctx.send(tosay) + except Exception as e: # TODO : A virer dans l'event on_error + await ctx.send(f':sob: Une erreur est survenue : \n' + f' {type(e).__name__}: {e}') + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name='sayto', pass_context=True) + async def _sayto(self, ctx, channel_id: int, *, tosay: str): + """Say a message in the channel""" + try: + chan = self.bot.get_channel(channel_id) + try: + await ctx.message.delete() + except Exception: + print(f"Impossible de supprimer le message " + f"\"{str(ctx.message.content)}\"") + try: + await chan.send(tosay) + except Exception: + print(f"Impossible d'envoyer le message dans {str(channel_id)}") + except Exception as e: # TODO : A virer dans l'event on_error + await ctx.send(f':sob: Une erreur est survenue : \n' + f' {type(e).__name__}: {e}') + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name='sayto_dm', pass_context=True) + async def _sayto_dm(self, ctx, user_id: int, *, tosay: str): + """Say a message to the user""" + try: + user = self.bot.get_user(user_id) + try: + await ctx.message.delete() + except Exception: + print(f"Impossible de supprimer le message " + f"\"{str(ctx.message.content)}\"") + try: + await user.send(tosay) + except Exception: + print(f"Impossible d'envoyer le message dans {str(user_id)}") + except Exception as e: # TODO : A virer dans l'event on_error + await ctx.send(f':sob: Une erreur est survenue : \n' + f' {type(e).__name__}: {e}') + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name='editsay', pass_context=True) + async def _editsay(self, ctx, message_id: int, *, new_content: str): + """Edit a bot's message""" + try: + try: + await ctx.message.delete() + except Exception: + print(f"Impossible de supprimer le message " + f"\"{str(ctx.message.content)}\"") + toedit = await ctx.channel.fetch_message(message_id) + except discord.errors.NotFound: + await ctx.send(f"Impossible de trouver le message avec l'id " + f"`{message_id}` sur ce salon") + return + try: + await toedit.edit(content=str(new_content)) + except discord.errors.Forbidden: + await ctx.send("J'ai po les perms pour editer mes messages :(") + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name='addreaction', pass_context=True) + async def _addreaction(self, ctx, message_id: int, reaction: str): + """Add reactions to a message""" + try: + try: + await ctx.message.delete() + except Exception: + print(f"Impossible de supprimer le message " + f"\"{str(ctx.message.content)}\"") + toadd = await ctx.channel.fetch_message(message_id) + except discord.errors.NotFound: + await ctx.send(f"Impossible de trouver le message avec l'id " + f"`{message_id}` sur ce salon") + return + try: + await toadd.add_reaction(reaction) + except discord.errors.Forbidden: + await ctx.send("J'ai po les perms pour ajouter des réactions :(") + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name='delete', pass_context=True) + async def _delete(self, ctx, message_id: int): + """Delete message in current channel""" + try: + try: + await ctx.message.delete() + except Exception: + print(f"Impossible de supprimer le message " + f"\"{str(ctx.message.content)}\"") + todelete = await ctx.channel.fetch_message(message_id) + except discord.errors.NotFound: + await ctx.send(f"Impossible de trouver le message avec l'id " + f"`{message_id}` sur ce salon") + return + try: + await todelete.delete() + except discord.errors.Forbidden: + await ctx.send("J'ai po les perms pour supprimer des messages :(") + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name='deletefrom', pass_context=True) + async def _deletefrom(self, ctx, chan_id: int, *, message_id: int): + """Delete message in channel""" + try: + chan = self.bot.get_channel(chan_id) + try: + await ctx.message.delete() + except Exception: + print(f"Impossible de supprimer le message " + f"\"{str(ctx.message.content)}\"") + todelete = await chan.fetch_message(message_id) + except discord.errors.NotFound: + await ctx.send(f"Impossible de trouver le message avec l'id " + f"`{id}` sur le salon") + return + try: + await todelete.delete() + except discord.errors.Forbidden: + await ctx.send("J'ai po les perms pour supprimer le message :(") + + """---------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @commands.command(name='embed', pass_context=True) + async def _embed(self, ctx, *, msg: str = "help"): + """Send an embed""" + if msg != "help": + ptext = title \ + = description \ + = image \ + = thumbnail \ + = color \ + = footer \ + = author \ + = None + timestamp = discord.Embed.Empty + embed_values = msg.split('|') + for i in embed_values: + if i.strip().lower().startswith('ptext='): + ptext = i.strip()[6:].strip() + elif i.strip().lower().startswith('title='): + title = i.strip()[6:].strip() + elif i.strip().lower().startswith('description='): + description = i.strip()[12:].strip() + elif i.strip().lower().startswith('desc='): + description = i.strip()[5:].strip() + elif i.strip().lower().startswith('image='): + image = i.strip()[6:].strip() + elif i.strip().lower().startswith('thumbnail='): + thumbnail = i.strip()[10:].strip() + elif i.strip().lower().startswith('colour='): + color = i.strip()[7:].strip() + elif i.strip().lower().startswith('color='): + color = i.strip()[6:].strip() + elif i.strip().lower().startswith('footer='): + footer = i.strip()[7:].strip() + elif i.strip().lower().startswith('author='): + author = i.strip()[7:].strip() + elif i.strip().lower().startswith('timestamp'): + timestamp = ctx.message.created_at + else: + if description is None and not i.strip()\ + .lower().startswith('field='): + description = i.strip() + + if color: + if color.startswith('#'): + color = color[1:] + if not color.startswith('0x'): + color = '0x' + color + + if ptext \ + is title \ + is description \ + is image \ + is thumbnail \ + is color \ + is footer \ + is author \ + is None \ + and 'field=' not in msg: + try: + await ctx.message.delete() + except Exception: + print("Impossible de supprimer le message \"" + str( + ctx.message.content) + "\"") + return await ctx.send(content=None, + embed=discord.Embed(description=msg)) + + if color: + em = discord.Embed(timestamp=timestamp, title=title, + description=description, + color=int(color, 16)) + else: + em = discord.Embed(timestamp=timestamp, title=title, + description=description) + for i in embed_values: + if i.strip().lower().startswith('field='): + field_inline = True + field = i.strip().lstrip('field=') + field_name, field_value = field.split('value=') + if 'inline=' in field_value: + field_value, field_inline = field_value.split( + 'inline=') + if 'false' in field_inline.lower() \ + or 'no' in field_inline.lower(): + field_inline = False + field_name = field_name.strip().lstrip('name=') + em.add_field(name=field_name, value=field_value.strip(), + inline=field_inline) + if author: + if 'icon=' in author: + text, icon = author.split('icon=') + if 'url=' in icon: + em.set_author(name=text.strip()[5:], + icon_url=icon.split('url=')[0].strip(), + url=icon.split('url=')[1].strip()) + else: + em.set_author(name=text.strip()[5:], icon_url=icon) + else: + if 'url=' in author: + em.set_author(name=author.split('url=')[0].strip()[5:], + url=author.split('url=')[1].strip()) + else: + em.set_author(name=author) + + if image: + em.set_image(url=image) + if thumbnail: + em.set_thumbnail(url=thumbnail) + if footer: + if 'icon=' in footer: + text, icon = footer.split('icon=') + em.set_footer(text=text.strip()[5:], icon_url=icon) + else: + em.set_footer(text=footer) + + try: + await ctx.message.delete() + except Exception: + print("Impossible de supprimer le message \"" + str( + ctx.message.content) + "\"") + await ctx.send(content=ptext, embed=em) + + else: + embed = discord.Embed( + title="Aide sur l'utilisation de la commande .embed:") + embed.add_field(name="Titre:", value="title=", + inline=True) + embed.add_field(name="Description:", + value="description=", inline=True) + embed.add_field(name="Couleur:", value="color=", + inline=True) + embed.add_field(name="Image:", + value="image=", + inline=True) + embed.add_field(name="Thumbnail:", + value="thumbnail=", inline=True) + embed.add_field(name="Auteur:", value="author=", + inline=True) + embed.add_field(name="Icon", value="icon=", + inline=True) + embed.add_field(name="Footer", value="footer=", + inline=True) + embed.set_footer(text="Exemple: .embed title=Un titre |" + " description=Une description |" + " color=3AB35E |" + " field=name=test value=test") + + await ctx.send(embed=embed) + + +def setup(bot): + bot.add_cog(Admin(bot)) diff --git a/cogs/afk.py b/cogs/afk.py index d53d35f..34b5ec5 100755 --- a/cogs/afk.py +++ b/cogs/afk.py @@ -1,68 +1,68 @@ -from discord.ext import commands -import discord -import random - - -class AFK(commands.Cog): - """Commandes utilitaires.""" - - def __init__(self, bot): - self.bot = bot - self.afk_users = [] - - """---------------------------------------------------------------------""" - - @commands.command(pass_context=True) - async def afk(self, ctx, action: str = ""): - - if action.lower() == "list": - try: - await ctx.send(*self.afk_users) - except discord.HTTPException: - await ctx.send("Il n'y a personne d'afk...") - else: - user = ctx.author - self.afk_users.append(user) - msgs = ["s'absente de discord quelques instants", - "se casse de son pc", - "va sortir son chien", - "reviens bientôt", - "va nourrir son cochon", - "va manger des cookies", - "va manger de la poutine", - "va faire caca", - "va faire pipi"] - - await ctx.send(f"**{user.mention}** {random.choice(msgs)}...") - - """---------------------------------------------------------------------""" - - @commands.Cog.listener() - async def on_message(self, message): - if message.author.bot \ - or message.guild.id != int(self.bot.config.main_server_id): - return - - user = message.author - - if user in self.afk_users \ - and message.content != self.bot.config.prefix[0] + "afk": - self.afk_users.remove(user) - - msgs = ["a réssuscité", - "est de nouveau parmi nous", - "a fini de faire caca", - "a fini d'uriner", - "n'est plus mort", - "est de nouveau sur son PC", - "a fini de manger sa poutine", - "a fini de danser", - "s'est réveillé", - "est de retour dans ce monde cruel"] - - await message.channel.send(f"**{user.mention}**" - f" {random.choice(msgs)}...") - - -def setup(bot): - bot.add_cog(AFK(bot)) +from discord.ext import commands +import discord +import random + + +class AFK(commands.Cog): + """Commandes utilitaires.""" + + def __init__(self, bot): + self.bot = bot + self.afk_users = [] + + """---------------------------------------------------------------------""" + + @commands.command(pass_context=True) + async def afk(self, ctx, action: str = ""): + + if action.lower() == "list": + try: + await ctx.send(*self.afk_users) + except discord.HTTPException: + await ctx.send("Il n'y a personne d'afk...") + else: + user = ctx.author + self.afk_users.append(user) + msgs = ["s'absente de discord quelques instants", + "se casse de son pc", + "va sortir son chien", + "reviens bientôt", + "va nourrir son cochon", + "va manger des cookies", + "va manger de la poutine", + "va faire caca", + "va faire pipi"] + + await ctx.send(f"**{user.mention}** {random.choice(msgs)}...") + + """---------------------------------------------------------------------""" + + @commands.Cog.listener() + async def on_message(self, message): + if message.author.bot \ + or message.guild.id != int(self.bot.config.main_server_id): + return + + user = message.author + + if user in self.afk_users \ + and message.content != self.bot.config.prefix[0] + "afk": + self.afk_users.remove(user) + + msgs = ["a réssuscité", + "est de nouveau parmi nous", + "a fini de faire caca", + "a fini d'uriner", + "n'est plus mort", + "est de nouveau sur son PC", + "a fini de manger sa poutine", + "a fini de danser", + "s'est réveillé", + "est de retour dans ce monde cruel"] + + await message.channel.send(f"**{user.mention}**" + f" {random.choice(msgs)}...") + + +def setup(bot): + bot.add_cog(AFK(bot)) diff --git a/cogs/atc.py b/cogs/atc.py index ea50ed3..e56ad23 100755 --- a/cogs/atc.py +++ b/cogs/atc.py @@ -1,124 +1,124 @@ -import asyncio - -from bs4 import BeautifulSoup -import requests -import re - -import discord -from discord.ext import commands - - -class ATC(commands.Cog): - - def __init__(self, bot): - self.bot = bot - self.playing = False - self.author = None - self.voice = None - - @staticmethod - async def extra(self, ctx, icao): - if icao == "stop_playing": - if self.playing and ( - ctx.author.id == self.author.id - or ctx.message.channel.permissions_for(ctx.message.author).administrator is True - ): - await self.voice.disconnect() - self.playing = False - await ctx.send("Écoute terminée !") - return "quit" - else: - await ctx.send("Veuillez specifier un icao") - return "quit" - if icao == "info": - em = discord.Embed(title=f"Infos sur les services utilisés par {self.bot.config.prefix[0]}atc") - em.add_field(name="Service pour les communications:", - value="[liveatc.net](https://www.liveatc.net/)", - inline=False) - em.add_field(name="Service pour les plans des aéroports:", - value="[universalweather.com](http://www.universalweather.com/)", - inline=False) - await ctx.send(embed=em) - return "quit" - - """---------------------------------------------------------------------""" - - @commands.command(name="atc", no_pm=True, pass_context=True) - async def _atc(self, ctx, icao="stop_playing"): - user = ctx.author - if not user.voice: - await ctx.send('Veuillez aller dans un channel vocal.') - return - - if await self.extra(self, ctx, icao) == "quit": - return - - if self.playing: - await ctx.send(f"Une écoute est déja en court, " - f"demandez à {self.author.mention} de faire " - f"`.atc stop_playing` pour l'arreter") - return - self.author = user - headers = { - 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.35 Safari/537.36', - } - req = requests.post("https://www.liveatc.net/search/", - data={'icao': icao}, - headers=headers) - html = BeautifulSoup(req.text, features="lxml") - regex = r"(javascript: pageTracker\._trackPageview\('\/listen\/)(.*)(\'\)\;)" - - possibilities = {} - emojis = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣', '🔟', - '0⃣', '🇦', '🇧', '🇨', '🇩', '🇪', '🇫', '🇬', '🇭', '🇮'] - to_react = [] - - idx = 0 - for a in html.findAll("a", onclick=True): - val = a.get('onclick') - for match in re.finditer(regex, val): - possibilities[idx] = f"{emojis[idx]} - {match.groups()[1]}\n" - to_react.append(emojis[idx]) - idx += 1 - - em = discord.Embed(title='Résultats pour : ' + icao, - description=str(''.join(possibilities.values())), - colour=0x4ECDC4) - em.set_image( - url=f"http://www.universalweather.com/regusers/mod-bin/uvtp_airport_image?icao={icao}") - - poll_msg = await ctx.send(embed=em) - for emote in to_react: - await poll_msg.add_reaction(emote) - - def check(reaction, user): - return user == ctx.author and reaction.emoji in to_react and \ - reaction.message.id == poll_msg.id - - async def waiter(future: asyncio.Future): - reaction, user = await self.bot.wait_for('reaction_add', - check=check) - - future.set_result(emojis.index(reaction.emoji)) - - added_emoji = asyncio.Future() - self.bot.loop.create_task(waiter(added_emoji)) - - while not added_emoji.done(): - await asyncio.sleep(0.1) - - freq = possibilities[added_emoji.result()].split('- ')[1] - - if possibilities: - self.playing = True - self.voice = await user.voice.channel.connect() - self.voice.play( - discord.FFmpegPCMAudio(f"http://yyz.liveatc.net/{freq}")) - await poll_msg.delete() - await ctx.send(f"Écoute de {freq}") - else: - await ctx.send(f"Aucun résultat trouvé pour {icao} {freq}") - - -def setup(bot): - bot.add_cog(ATC(bot)) +import asyncio + +from bs4 import BeautifulSoup +import requests +import re + +import discord +from discord.ext import commands + + +class ATC(commands.Cog): + + def __init__(self, bot): + self.bot = bot + self.playing = False + self.author = None + self.voice = None + + @staticmethod + async def extra(self, ctx, icao): + if icao == "stop_playing": + if self.playing and ( + ctx.author.id == self.author.id + or ctx.message.channel.permissions_for(ctx.message.author).administrator is True + ): + await self.voice.disconnect() + self.playing = False + await ctx.send("Écoute terminée !") + return "quit" + else: + await ctx.send("Veuillez specifier un icao") + return "quit" + if icao == "info": + em = discord.Embed(title=f"Infos sur les services utilisés par {self.bot.config.prefix[0]}atc") + em.add_field(name="Service pour les communications:", + value="[liveatc.net](https://www.liveatc.net/)", + inline=False) + em.add_field(name="Service pour les plans des aéroports:", + value="[universalweather.com](http://www.universalweather.com/)", + inline=False) + await ctx.send(embed=em) + return "quit" + + """---------------------------------------------------------------------""" + + @commands.command(name="atc", no_pm=True, pass_context=True) + async def _atc(self, ctx, icao="stop_playing"): + user = ctx.author + if not user.voice: + await ctx.send('Veuillez aller dans un channel vocal.') + return + + if await self.extra(self, ctx, icao) == "quit": + return + + if self.playing: + await ctx.send(f"Une écoute est déja en court, " + f"demandez à {self.author.mention} de faire " + f"`.atc stop_playing` pour l'arreter") + return + self.author = user + headers = { + 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.35 Safari/537.36', + } + req = requests.post("https://www.liveatc.net/search/", + data={'icao': icao}, + headers=headers) + html = BeautifulSoup(req.text, features="lxml") + regex = r"(javascript: pageTracker\._trackPageview\('\/listen\/)(.*)(\'\)\;)" + + possibilities = {} + emojis = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣', '🔟', + '0⃣', '🇦', '🇧', '🇨', '🇩', '🇪', '🇫', '🇬', '🇭', '🇮'] + to_react = [] + + idx = 0 + for a in html.findAll("a", onclick=True): + val = a.get('onclick') + for match in re.finditer(regex, val): + possibilities[idx] = f"{emojis[idx]} - {match.groups()[1]}\n" + to_react.append(emojis[idx]) + idx += 1 + + em = discord.Embed(title='Résultats pour : ' + icao, + description=str(''.join(possibilities.values())), + colour=0x4ECDC4) + em.set_image( + url=f"http://www.universalweather.com/regusers/mod-bin/uvtp_airport_image?icao={icao}") + + poll_msg = await ctx.send(embed=em) + for emote in to_react: + await poll_msg.add_reaction(emote) + + def check(reaction, user): + return user == ctx.author and reaction.emoji in to_react and \ + reaction.message.id == poll_msg.id + + async def waiter(future: asyncio.Future): + reaction, user = await self.bot.wait_for('reaction_add', + check=check) + + future.set_result(emojis.index(reaction.emoji)) + + added_emoji = asyncio.Future() + self.bot.loop.create_task(waiter(added_emoji)) + + while not added_emoji.done(): + await asyncio.sleep(0.1) + + freq = possibilities[added_emoji.result()].split('- ')[1] + + if possibilities: + self.playing = True + self.voice = await user.voice.channel.connect() + self.voice.play( + discord.FFmpegPCMAudio(f"http://yyz.liveatc.net/{freq}")) + await poll_msg.delete() + await ctx.send(f"Écoute de {freq}") + else: + await ctx.send(f"Aucun résultat trouvé pour {icao} {freq}") + + +def setup(bot): + bot.add_cog(ATC(bot)) diff --git a/cogs/basics.py b/cogs/basics.py index d0fa175..461baaa 100755 --- a/cogs/basics.py +++ b/cogs/basics.py @@ -1,71 +1,71 @@ -import platform -import socket -import subprocess - -import discord -from discord.ext import commands -from discord.http import Route - - -class Basics(commands.Cog): - """Commandes générales.""" - - def __init__(self, bot): - self.bot = bot - - @commands.command() - async def ping(self, ctx): - ping_res = str(subprocess.Popen(["/bin/ping", "-c1", "discordapp.com"], - stdout=subprocess.PIPE).stdout.read()) - formated_res = [item for item in ping_res.split() if 'time=' in item] - result = self.bot.latency * 1000 # str(formated_res[0])[5:] - - if float(result) >= 200: - em = discord.Embed(title="Ping : " + str(result) + "ms", - description="... c'est quoi ce ping !", - colour=0xFF1111) - await ctx.send(embed=em) - elif float(result) > 100 < 200: - em = discord.Embed(title="Ping : " + str(result) + "ms", - description="Ca va, ça peut aller, mais j'ai " - "l'impression d'avoir 40 ans !", - colour=0xFFA500) - await ctx.send(embed=em) - else: - em = discord.Embed(title="Ping : " + str(result) + "ms", - description="Wow c'te vitesse de réaction, " - "je m'épate moi-même !", - colour=0x11FF11) - await ctx.send(embed=em) - - """---------------------------------------------------------------------""" - - @commands.command() - async def info(self, ctx): - """Affiches des informations sur le bot""" - text = open('texts/info.md').read() - os_info = str(platform.system()) + " / " + str(platform.release()) - em = discord.Embed(title='Informations sur TuxBot', - description=text.format(os_info, - platform.python_version(), - socket.gethostname(), - discord.__version__, - Route.BASE), - colour=0x89C4F9) - em.set_footer(text="/home/****/bot.py") - await ctx.send(embed=em) - - """---------------------------------------------------------------------""" - - @commands.command() - async def help(self, ctx, page: int = 1): - """Affiches l'aide du bot""" - page = int(page) if 0 < int(page) < 5 else 1 - text = open('texts/help.md').read().split("[split]") - em = discord.Embed(title='Commandes de TuxBot', description=text[page - 1], - colour=0x89C4F9) - await ctx.send(content=f"page {page}/{len(text)}", embed=em) - - -def setup(bot): - bot.add_cog(Basics(bot)) +import platform +import socket +import subprocess + +import discord +from discord.ext import commands +from discord.http import Route + + +class Basics(commands.Cog): + """Commandes générales.""" + + def __init__(self, bot): + self.bot = bot + + @commands.command() + async def ping(self, ctx): + ping_res = str(subprocess.Popen(["/bin/ping", "-c1", "discordapp.com"], + stdout=subprocess.PIPE).stdout.read()) + formated_res = [item for item in ping_res.split() if 'time=' in item] + result = self.bot.latency * 1000 # str(formated_res[0])[5:] + + if float(result) >= 200: + em = discord.Embed(title="Ping : " + str(result) + "ms", + description="... c'est quoi ce ping !", + colour=0xFF1111) + await ctx.send(embed=em) + elif float(result) > 100 < 200: + em = discord.Embed(title="Ping : " + str(result) + "ms", + description="Ca va, ça peut aller, mais j'ai " + "l'impression d'avoir 40 ans !", + colour=0xFFA500) + await ctx.send(embed=em) + else: + em = discord.Embed(title="Ping : " + str(result) + "ms", + description="Wow c'te vitesse de réaction, " + "je m'épate moi-même !", + colour=0x11FF11) + await ctx.send(embed=em) + + """---------------------------------------------------------------------""" + + @commands.command() + async def info(self, ctx): + """Affiches des informations sur le bot""" + text = open('texts/info.md').read() + os_info = str(platform.system()) + " / " + str(platform.release()) + em = discord.Embed(title='Informations sur TuxBot', + description=text.format(os_info, + platform.python_version(), + socket.gethostname(), + discord.__version__, + Route.BASE), + colour=0x89C4F9) + em.set_footer(text="/home/****/bot.py") + await ctx.send(embed=em) + + """---------------------------------------------------------------------""" + + @commands.command() + async def help(self, ctx, page: int = 1): + """Affiches l'aide du bot""" + page = int(page) if 0 < int(page) < 5 else 1 + text = open('texts/help.md').read().split("[split]") + em = discord.Embed(title='Commandes de TuxBot', description=text[page - 1], + colour=0x89C4F9) + await ctx.send(content=f"page {page}/{len(text)}", embed=em) + + +def setup(bot): + bot.add_cog(Basics(bot)) diff --git a/cogs/ci.py b/cogs/ci.py index 3115bb1..2e56e90 100755 --- a/cogs/ci.py +++ b/cogs/ci.py @@ -1,311 +1,311 @@ -import datetime -import random - -import discord -import requests -from discord.ext import commands - -from .utils import checks -from .utils import db -from .utils.checks import get_user, check_date - - -class Identity(commands.Cog): - """Commandes des cartes d'identité .""" - - def __init__(self, bot): - self.bot = bot - - self.conn = db.connect_to_db(self) - self.cursor = self.conn.cursor() - - self.cursor.execute("""SHOW TABLES LIKE 'users'""") - result = self.cursor.fetchone() - - if not result: - # Creation table Utilisateur si premiere fois - sql = "CREATE TABLE users ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, userid TEXT null, username TEXT null, os TEXT null, config TEXT null, useravatar TEXT null, userbirth TEXT null, pays TEXT null, cidate TEXT null, cibureau TEXT null);" - self.cursor.execute(sql) - - """--------------------------------------------------------------------------------------------------------------------------""" - - @commands.group(name="ci", no_pm=True, pass_context=True) - async def _ci(self, ctx): - """Cartes d'identité""" - - if ctx.invoked_subcommand is None: - text = open('texts/ci-info.md').read() - em = discord.Embed(title='Commandes de carte d\'identité de TuxBot', description=text, colour=0x89C4F9) - await ctx.send(embed=em) - - """--------------------------------------------------------------------------------------------------------------------------""" - - @_ci.command(pass_context=True, name="show") - async def ci_show(self, ctx, args: str = None): - self.conn = db.connect_to_db(self) - self.cursor = self.conn.cursor() - - if args == None: - user = get_user(ctx.message, ctx.author.name) - else: - user = get_user(ctx.message, args) - - if user: - self.cursor.execute("""SELECT userid, username, useravatar, userbirth, cidate, cibureau, os, config, pays, id FROM users WHERE userid=%s""",(str(user.id))) - result = self.cursor.fetchone() - - def isexist(var): - if not var: - return "Non renseigné." - else: - return var - - if not result: - await ctx.send(f"{ctx.author.mention}> :x: Désolé mais {user.mention} est sans papier !") - else: - try: - user_birth = datetime.datetime.fromisoformat(result[3]) - user_birth_day = check_date(str(user_birth.day)) - user_birth_month = check_date(str(user_birth.month)) - - formated_user_birth = str(user_birth_day) + "/" + str(user_birth_month) + "/" + str(user_birth.year) - - try: ## a virer une fois le patch appliqué pour tout le monde - cidate = datetime.datetime.fromisoformat(result[4]) - cidate_day = check_date(str(cidate.day)) ## a garder - cidate_month = check_date(str(cidate.month)) ## a garder - - formated_cidate = str(cidate_day) + "/" + str(cidate_month) + "/" + str(cidate.year) ## a garder - except ValueError: ## a virer une fois le patch appliqué pour tout le monde - formated_cidate = str(result[4]).replace('-', '/') ## a virer une fois le patch appliqué pour tout le monde - await ctx.send(f"{user.mention} vous êtes prié(e) de faire la commande `.ci update` afin de regler un probleme de date coté bdd") ## a virer une fois le patch appliqué pour tout le monde - - embed=discord.Embed(title="Carte d'identité | Communisme Linuxien") - embed.set_author(name=result[1], icon_url=result[2]) - embed.set_thumbnail(url = result[2]) - embed.add_field(name="Nom :", value=result[1], inline=True) - embed.add_field(name="Système d'exploitation :", value=isexist(result[6]), inline=True) - embed.add_field(name="Configuration Système : ", value=isexist(result[7]), inline=False) - embed.add_field(name="Date de naissance sur discord : ", value=formated_user_birth, inline=True) - embed.add_field(name="Pays : ", value=isexist(result[8]), inline=True) - embed.add_field(name="Profil sur le web : ", value="*indisponible*") # value=f"https://tuxbot.gnous.eu/users/{result[9]}", inline=True) - embed.set_footer(text=f"Enregistré dans le bureau {result[5]} le {formated_cidate}.") - await ctx.send(embed=embed) - except Exception as e: - await ctx.send(f"{ctx.author.mention}> :x: Désolé mais la carte d'identité de {user.mention} est trop longue de ce fait je ne peux te l'envoyer, essaye de l'aléger, {user.mention} :wink: !") - await ctx.send(f':sob: Une erreur est survenue : \n {type(e).__name__}: {e}') - else: - return await ctx.send('Impossible de trouver l\'user.') - - """--------------------------------------------------------------------------------------------------------------------------""" - - @_ci.command(pass_context=True, name="register") - async def ci_register(self, ctx): - self.conn = db.connect_to_db(self) - self.cursor = self.conn.cursor() - - self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) - result = self.cursor.fetchone() - - if result: - await ctx.send("Mais tu as déja une carte d'identité ! u_u") - else: - now = datetime.datetime.now() - - self.cursor.execute("""INSERT INTO users(userid, username, useravatar, userbirth, cidate, cibureau) VALUES(%s, %s, %s, %s, %s, %s)""", (str(ctx.author.id), str(ctx.author), str(ctx.author.avatar_url_as(format="jpg", size=512)), str(ctx.author.created_at), now, str(ctx.message.guild.name))) - self.conn.commit() - await ctx.send(f":clap: Bievenue à toi {ctx.author.name} dans le communisme {ctx.message.guild.name} ! Fait ``.ci`` pour plus d'informations !") - - """--------------------------------------------------------------------------------------------------------------------------""" - - @_ci.command(pass_context=True, name="delete") - async def ci_delete(self, ctx): - self.conn = db.connect_to_db(self) - self.cursor = self.conn.cursor() - - self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) - result = self.cursor.fetchone() - - if result: - self.cursor.execute("""DELETE FROM users WHERE userid =%s""", (str(ctx.author.id))) - self.conn.commit() - await ctx.send("Tu es maintenant sans papiers !") - else: - await ctx.send("Déja enregistre ta carte d'identité avant de la supprimer u_u (après c'est pas logique...)") - - """--------------------------------------------------------------------------------------------------------------------------""" - - @_ci.command(pass_context=True, name="update") - async def ci_update(self, ctx): - self.conn = db.connect_to_db(self) - self.cursor = self.conn.cursor() - - try: - self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) - result = self.cursor.fetchone() - - if result: - self.cursor.execute("""SELECT cidate FROM users WHERE userid=%s""",(str(ctx.author.id))) - old_ci_date = self.cursor.fetchone() - - try: - new_ci_date = datetime.datetime.fromisoformat(old_ci_date[0]) - except ValueError: - old_ci_date = datetime.datetime.strptime(old_ci_date[0].replace('/', '-'), '%d-%m-%Y') - - old_ci_date_day = check_date(str(old_ci_date.day)) - old_ci_date_month = check_date(str(old_ci_date.month)) - - new_ci_date = f"{str(old_ci_date.year)}-{str(old_ci_date_month)}-{str(old_ci_date_day)} 00:00:00.000000" - - await ctx.send("succes update") - - self.cursor.execute("""UPDATE users SET cidate = %s WHERE userid = %s""", (str(new_ci_date), str(ctx.author.id))) - self.conn.commit() - - self.cursor.execute("""UPDATE users SET useravatar = %s, username = %s, cibureau = %s WHERE userid = %s""", (str(ctx.author.avatar_url_as(format="jpg", size=512)), str(ctx.author), str(ctx.message.guild), str(ctx.author.id))) - self.conn.commit() - await ctx.send(f"{ctx.author.mention}> Tu viens, en quelques sortes, de renaitre !") - else: - await ctx.send(f"{ctx.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !") - - except Exception as e: #TODO : A virer dans l'event on_error - await ctx.send(':( Erreur veuillez contacter votre administrateur :') - await ctx.send(f'{type(e).__name__}: {e}') - - """--------------------------------------------------------------------------------------------------------------------------""" - - @_ci.command(pass_context=True, name="setconfig") - async def ci_setconfig(self, ctx, *, conf: str = None): - self.conn = db.connect_to_db(self) - self.cursor = self.conn.cursor() - - if conf: - self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) - result = self.cursor.fetchone() - - if result: - self.cursor.execute("""UPDATE users SET config = %s WHERE userid = %s""", (str(conf), str(ctx.author.id))) - self.conn.commit() - await ctx.send(f"{ctx.author.mention}> :ok_hand: Carte d'identité mise à jour !") - else: - await ctx.send(f"{ctx.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !") - else: - await ctx.send(f"{ctx.author.mention}> :x: Il manque un paramètre !") - - """--------------------------------------------------------------------------------------------------------------------------""" - - @_ci.command(pass_context=True, name="setos") - async def ci_setos(self, ctx, *, conf: str = None): - self.conn = db.connect_to_db(self) - self.cursor = self.conn.cursor() - - if conf: - self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) - result = self.cursor.fetchone() - - if result: - self.cursor.execute("""UPDATE users SET os = %s WHERE userid = %s""", (str(conf), str(ctx.author.id))) - self.conn.commit() - await ctx.send(f"{ctx.author.mention}> :ok_hand: Carte d'identité mise à jour !") - else: - await ctx.send(f"{ctx.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !") - else: - await ctx.send(f"{ctx.author.mention}> :x: Il manque un paramètre !") - - """--------------------------------------------------------------------------------------------------------------------------""" - - @_ci.command(pass_context=True, name="setcountry") - async def ci_setcountry(self, ctx, *, country: str = None): - self.conn = db.connect_to_db(self) - self.cursor = self.conn.cursor() - - if country: - self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) - result = self.cursor.fetchone() - - if result: - self.cursor.execute("""UPDATE users SET pays = %s WHERE userid = %s""", (str(country), str(ctx.author.id))) - self.conn.commit() - await ctx.send(f"{ctx.author.mention}> :ok_hand: Carte d'identité mise à jour !") - else: - await ctx.send(f"{ctx.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !") - else: - await ctx.send(f"{ctx.author.mention}> :x: Il manque un paramètre !") - - """--------------------------------------------------------------------------------------------------------------------------""" - - @_ci.command(pass_context=True, name="online_edit") - async def ci_online_edit(self, ctx): - self.conn = db.connect_to_db(self) - self.cursor = self.conn.cursor() - - self.cursor.execute("""SELECT id FROM users WHERE userid=%s""",(str(ctx.author.id))) - result = self.cursor.fetchone() - - if not result: - return await ctx.send(f"Déja enregistre ta carte d'identité avant de l'éditer u_u (après c'est pas logique...)") - - dm = await ctx.author.create_dm() - - try: - def is_exist(key, value): - self.cursor.execute("""SELECT * FROM sessions WHERE {}=%s""".format(str(key)), (str(value))) - return self.cursor.fetchone() - - user_id = result[0] - is_admin = '1' if str(ctx.author.id) in self.bot.config.authorized_id else '0' - token = ''.join(random.sample('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'*25, 25)) - created_at = datetime.datetime.utcnow() - - while is_exist('token', token): - token = ''.join(random.sample('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'*25, 25)) - - if is_exist('user_id', user_id): - self.cursor.execute("""UPDATE sessions SET is_admin = %s, token = %s, updated_at = %s WHERE user_id = %s""", (str(is_admin), str(token), str(created_at), str(user_id))) - self.conn.commit() - else: - self.cursor.execute("""INSERT INTO sessions(user_id, is_admin, token, created_at, updated_at) VALUES(%s, %s, %s, %s, %s)""", (str(user_id), str(is_admin), str(token), str(created_at), str(created_at))) - self.conn.commit() - - embed=discord.Embed(title="Clé d'édition pour tuxweb", description=f"Voici ta clé d'édition, vas sur [https://tuxbot.gnous.eu/fr/users/{user_id}](https://tuxbot.gnous.eu/fr/users/{user_id}) puis cliques sur `editer` et entre la clé afin de pouvoir modifier ta ci", colour=0x89C4F9) - embed.set_footer(text=f"Cette clé sera valide durant les 10 prochaines minutes, ne la communiques à personne !") - await dm.send(embed=embed) - await dm.send(token) - - await ctx.send(f"{ctx.author.mention} ta clé d'édition t'a été envoyée en message privé") - - except Exception as e: - await ctx.send(f"{ctx.author.mention}, je ne peux pas t'envoyer de message privé :(. Penses à autoriser les messages privés provenant des membres du serveur pour que je puisse te donner ta clef d'édition") - - """--------------------------------------------------------------------------------------------------------------------------""" - - @checks.has_permissions(administrator=True) - @_ci.command(pass_context=True, name="list") - async def ci_list(self, ctx): - self.conn = db.connect_to_db(self) - self.cursor = self.conn.cursor() - - self.cursor.execute("""SELECT id, username FROM users""") - rows = self.cursor.fetchall() - msg = "" - try: - for row in rows: - row_id = row[0] - row_name = row[1].encode('utf-8') - msg += f"{str(row_id)} : {str(row_name)} \n" - post = requests.post("https://hastebin.com/documents", data=msg) - await ctx.send(f"{ctx.author.mention} liste posté avec succès sur :\nhttps://hastebin.com/{post.json()['key']}.txt") - - with open('ci_list.txt', 'w', encoding='utf-8') as fp: - for row in rows: - row_id = row[0] - row_name = row[1] - - fp.write(f"{str(row_id)} : {str(row_name)} \n") - - except Exception as e: - await ctx.send(f':sob: Une erreur est survenue : \n {type(e).__name__}: {e}') - -def setup(bot): - bot.add_cog(Identity(bot)) +import datetime +import random + +import discord +import requests +from discord.ext import commands + +from .utils import checks +from .utils import db +from .utils.checks import get_user, check_date + + +class Identity(commands.Cog): + """Commandes des cartes d'identité .""" + + def __init__(self, bot): + self.bot = bot + + self.conn = db.connect_to_db(self) + self.cursor = self.conn.cursor() + + self.cursor.execute("""SHOW TABLES LIKE 'users'""") + result = self.cursor.fetchone() + + if not result: + # Creation table Utilisateur si premiere fois + sql = "CREATE TABLE users ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, userid TEXT null, username TEXT null, os TEXT null, config TEXT null, useravatar TEXT null, userbirth TEXT null, pays TEXT null, cidate TEXT null, cibureau TEXT null);" + self.cursor.execute(sql) + + """--------------------------------------------------------------------------------------------------------------------------""" + + @commands.group(name="ci", no_pm=True, pass_context=True) + async def _ci(self, ctx): + """Cartes d'identité""" + + if ctx.invoked_subcommand is None: + text = open('texts/ci-info.md').read() + em = discord.Embed(title='Commandes de carte d\'identité de TuxBot', description=text, colour=0x89C4F9) + await ctx.send(embed=em) + + """--------------------------------------------------------------------------------------------------------------------------""" + + @_ci.command(pass_context=True, name="show") + async def ci_show(self, ctx, args: str = None): + self.conn = db.connect_to_db(self) + self.cursor = self.conn.cursor() + + if args == None: + user = get_user(ctx.message, ctx.author.name) + else: + user = get_user(ctx.message, args) + + if user: + self.cursor.execute("""SELECT userid, username, useravatar, userbirth, cidate, cibureau, os, config, pays, id FROM users WHERE userid=%s""",(str(user.id))) + result = self.cursor.fetchone() + + def isexist(var): + if not var: + return "Non renseigné." + else: + return var + + if not result: + await ctx.send(f"{ctx.author.mention}> :x: Désolé mais {user.mention} est sans papier !") + else: + try: + user_birth = datetime.datetime.fromisoformat(result[3]) + user_birth_day = check_date(str(user_birth.day)) + user_birth_month = check_date(str(user_birth.month)) + + formated_user_birth = str(user_birth_day) + "/" + str(user_birth_month) + "/" + str(user_birth.year) + + try: ## a virer une fois le patch appliqué pour tout le monde + cidate = datetime.datetime.fromisoformat(result[4]) + cidate_day = check_date(str(cidate.day)) ## a garder + cidate_month = check_date(str(cidate.month)) ## a garder + + formated_cidate = str(cidate_day) + "/" + str(cidate_month) + "/" + str(cidate.year) ## a garder + except ValueError: ## a virer une fois le patch appliqué pour tout le monde + formated_cidate = str(result[4]).replace('-', '/') ## a virer une fois le patch appliqué pour tout le monde + await ctx.send(f"{user.mention} vous êtes prié(e) de faire la commande `.ci update` afin de regler un probleme de date coté bdd") ## a virer une fois le patch appliqué pour tout le monde + + embed=discord.Embed(title="Carte d'identité | Communisme Linuxien") + embed.set_author(name=result[1], icon_url=result[2]) + embed.set_thumbnail(url = result[2]) + embed.add_field(name="Nom :", value=result[1], inline=True) + embed.add_field(name="Système d'exploitation :", value=isexist(result[6]), inline=True) + embed.add_field(name="Configuration Système : ", value=isexist(result[7]), inline=False) + embed.add_field(name="Date de naissance sur discord : ", value=formated_user_birth, inline=True) + embed.add_field(name="Pays : ", value=isexist(result[8]), inline=True) + embed.add_field(name="Profil sur le web : ", value="*indisponible*") # value=f"https://tuxbot.gnous.eu/users/{result[9]}", inline=True) + embed.set_footer(text=f"Enregistré dans le bureau {result[5]} le {formated_cidate}.") + await ctx.send(embed=embed) + except Exception as e: + await ctx.send(f"{ctx.author.mention}> :x: Désolé mais la carte d'identité de {user.mention} est trop longue de ce fait je ne peux te l'envoyer, essaye de l'aléger, {user.mention} :wink: !") + await ctx.send(f':sob: Une erreur est survenue : \n {type(e).__name__}: {e}') + else: + return await ctx.send('Impossible de trouver l\'user.') + + """--------------------------------------------------------------------------------------------------------------------------""" + + @_ci.command(pass_context=True, name="register") + async def ci_register(self, ctx): + self.conn = db.connect_to_db(self) + self.cursor = self.conn.cursor() + + self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) + result = self.cursor.fetchone() + + if result: + await ctx.send("Mais tu as déja une carte d'identité ! u_u") + else: + now = datetime.datetime.now() + + self.cursor.execute("""INSERT INTO users(userid, username, useravatar, userbirth, cidate, cibureau) VALUES(%s, %s, %s, %s, %s, %s)""", (str(ctx.author.id), str(ctx.author), str(ctx.author.avatar_url_as(format="jpg", size=512)), str(ctx.author.created_at), now, str(ctx.message.guild.name))) + self.conn.commit() + await ctx.send(f":clap: Bievenue à toi {ctx.author.name} dans le communisme {ctx.message.guild.name} ! Fait ``.ci`` pour plus d'informations !") + + """--------------------------------------------------------------------------------------------------------------------------""" + + @_ci.command(pass_context=True, name="delete") + async def ci_delete(self, ctx): + self.conn = db.connect_to_db(self) + self.cursor = self.conn.cursor() + + self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) + result = self.cursor.fetchone() + + if result: + self.cursor.execute("""DELETE FROM users WHERE userid =%s""", (str(ctx.author.id))) + self.conn.commit() + await ctx.send("Tu es maintenant sans papiers !") + else: + await ctx.send("Déja enregistre ta carte d'identité avant de la supprimer u_u (après c'est pas logique...)") + + """--------------------------------------------------------------------------------------------------------------------------""" + + @_ci.command(pass_context=True, name="update") + async def ci_update(self, ctx): + self.conn = db.connect_to_db(self) + self.cursor = self.conn.cursor() + + try: + self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) + result = self.cursor.fetchone() + + if result: + self.cursor.execute("""SELECT cidate FROM users WHERE userid=%s""",(str(ctx.author.id))) + old_ci_date = self.cursor.fetchone() + + try: + new_ci_date = datetime.datetime.fromisoformat(old_ci_date[0]) + except ValueError: + old_ci_date = datetime.datetime.strptime(old_ci_date[0].replace('/', '-'), '%d-%m-%Y') + + old_ci_date_day = check_date(str(old_ci_date.day)) + old_ci_date_month = check_date(str(old_ci_date.month)) + + new_ci_date = f"{str(old_ci_date.year)}-{str(old_ci_date_month)}-{str(old_ci_date_day)} 00:00:00.000000" + + await ctx.send("succes update") + + self.cursor.execute("""UPDATE users SET cidate = %s WHERE userid = %s""", (str(new_ci_date), str(ctx.author.id))) + self.conn.commit() + + self.cursor.execute("""UPDATE users SET useravatar = %s, username = %s, cibureau = %s WHERE userid = %s""", (str(ctx.author.avatar_url_as(format="jpg", size=512)), str(ctx.author), str(ctx.message.guild), str(ctx.author.id))) + self.conn.commit() + await ctx.send(f"{ctx.author.mention}> Tu viens, en quelques sortes, de renaitre !") + else: + await ctx.send(f"{ctx.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !") + + except Exception as e: #TODO : A virer dans l'event on_error + await ctx.send(':( Erreur veuillez contacter votre administrateur :') + await ctx.send(f'{type(e).__name__}: {e}') + + """--------------------------------------------------------------------------------------------------------------------------""" + + @_ci.command(pass_context=True, name="setconfig") + async def ci_setconfig(self, ctx, *, conf: str = None): + self.conn = db.connect_to_db(self) + self.cursor = self.conn.cursor() + + if conf: + self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) + result = self.cursor.fetchone() + + if result: + self.cursor.execute("""UPDATE users SET config = %s WHERE userid = %s""", (str(conf), str(ctx.author.id))) + self.conn.commit() + await ctx.send(f"{ctx.author.mention}> :ok_hand: Carte d'identité mise à jour !") + else: + await ctx.send(f"{ctx.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !") + else: + await ctx.send(f"{ctx.author.mention}> :x: Il manque un paramètre !") + + """--------------------------------------------------------------------------------------------------------------------------""" + + @_ci.command(pass_context=True, name="setos") + async def ci_setos(self, ctx, *, conf: str = None): + self.conn = db.connect_to_db(self) + self.cursor = self.conn.cursor() + + if conf: + self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) + result = self.cursor.fetchone() + + if result: + self.cursor.execute("""UPDATE users SET os = %s WHERE userid = %s""", (str(conf), str(ctx.author.id))) + self.conn.commit() + await ctx.send(f"{ctx.author.mention}> :ok_hand: Carte d'identité mise à jour !") + else: + await ctx.send(f"{ctx.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !") + else: + await ctx.send(f"{ctx.author.mention}> :x: Il manque un paramètre !") + + """--------------------------------------------------------------------------------------------------------------------------""" + + @_ci.command(pass_context=True, name="setcountry") + async def ci_setcountry(self, ctx, *, country: str = None): + self.conn = db.connect_to_db(self) + self.cursor = self.conn.cursor() + + if country: + self.cursor.execute("""SELECT id, userid FROM users WHERE userid=%s""", (str(ctx.author.id))) + result = self.cursor.fetchone() + + if result: + self.cursor.execute("""UPDATE users SET pays = %s WHERE userid = %s""", (str(country), str(ctx.author.id))) + self.conn.commit() + await ctx.send(f"{ctx.author.mention}> :ok_hand: Carte d'identité mise à jour !") + else: + await ctx.send(f"{ctx.author.mention}> :x: Veuillez enregistrer votre carte d'identité pour commencer !") + else: + await ctx.send(f"{ctx.author.mention}> :x: Il manque un paramètre !") + + """--------------------------------------------------------------------------------------------------------------------------""" + + @_ci.command(pass_context=True, name="online_edit") + async def ci_online_edit(self, ctx): + self.conn = db.connect_to_db(self) + self.cursor = self.conn.cursor() + + self.cursor.execute("""SELECT id FROM users WHERE userid=%s""",(str(ctx.author.id))) + result = self.cursor.fetchone() + + if not result: + return await ctx.send(f"Déja enregistre ta carte d'identité avant de l'éditer u_u (après c'est pas logique...)") + + dm = await ctx.author.create_dm() + + try: + def is_exist(key, value): + self.cursor.execute("""SELECT * FROM sessions WHERE {}=%s""".format(str(key)), (str(value))) + return self.cursor.fetchone() + + user_id = result[0] + is_admin = '1' if str(ctx.author.id) in self.bot.config.authorized_id else '0' + token = ''.join(random.sample('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'*25, 25)) + created_at = datetime.datetime.utcnow() + + while is_exist('token', token): + token = ''.join(random.sample('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'*25, 25)) + + if is_exist('user_id', user_id): + self.cursor.execute("""UPDATE sessions SET is_admin = %s, token = %s, updated_at = %s WHERE user_id = %s""", (str(is_admin), str(token), str(created_at), str(user_id))) + self.conn.commit() + else: + self.cursor.execute("""INSERT INTO sessions(user_id, is_admin, token, created_at, updated_at) VALUES(%s, %s, %s, %s, %s)""", (str(user_id), str(is_admin), str(token), str(created_at), str(created_at))) + self.conn.commit() + + embed=discord.Embed(title="Clé d'édition pour tuxweb", description=f"Voici ta clé d'édition, vas sur [https://tuxbot.gnous.eu/fr/users/{user_id}](https://tuxbot.gnous.eu/fr/users/{user_id}) puis cliques sur `editer` et entre la clé afin de pouvoir modifier ta ci", colour=0x89C4F9) + embed.set_footer(text=f"Cette clé sera valide durant les 10 prochaines minutes, ne la communiques à personne !") + await dm.send(embed=embed) + await dm.send(token) + + await ctx.send(f"{ctx.author.mention} ta clé d'édition t'a été envoyée en message privé") + + except Exception as e: + await ctx.send(f"{ctx.author.mention}, je ne peux pas t'envoyer de message privé :(. Penses à autoriser les messages privés provenant des membres du serveur pour que je puisse te donner ta clef d'édition") + + """--------------------------------------------------------------------------------------------------------------------------""" + + @checks.has_permissions(administrator=True) + @_ci.command(pass_context=True, name="list") + async def ci_list(self, ctx): + self.conn = db.connect_to_db(self) + self.cursor = self.conn.cursor() + + self.cursor.execute("""SELECT id, username FROM users""") + rows = self.cursor.fetchall() + msg = "" + try: + for row in rows: + row_id = row[0] + row_name = row[1].encode('utf-8') + msg += f"{str(row_id)} : {str(row_name)} \n" + post = requests.post("https://hastebin.com/documents", data=msg) + await ctx.send(f"{ctx.author.mention} liste posté avec succès sur :\nhttps://hastebin.com/{post.json()['key']}.txt") + + with open('ci_list.txt', 'w', encoding='utf-8') as fp: + for row in rows: + row_id = row[0] + row_name = row[1] + + fp.write(f"{str(row_id)} : {str(row_name)} \n") + + except Exception as e: + await ctx.send(f':sob: Une erreur est survenue : \n {type(e).__name__}: {e}') + +def setup(bot): + bot.add_cog(Identity(bot)) diff --git a/cogs/filter_messages.py b/cogs/filter_messages.py index 396b47c..89400c3 100755 --- a/cogs/filter_messages.py +++ b/cogs/filter_messages.py @@ -1,60 +1,60 @@ -from discord.ext import commands -import re - - -class FilterMessages(commands.Cog): - """Flitre des messages""" - - def __init__(self, bot): - self.bot = bot - - @commands.Cog.listener() - async def on_message(self, message): - no_pub_guild = [280805240977227776, 303633056944881686, - 274247231534792704] - lien_channel = [280805783795662848, 508794201509593088, - 516017286948061204] - sondage_channel = [394146769107419146, 477147964393914388] - - if message.author.bot \ - or str(message.author.id) in self.bot.config.authorized_id \ - or message.channel.permissions_for(message.author).administrator is True: - return - - discord_invite_regex = re.compile(r"(discord\.(gg|io|me|li)|discordapp\.com\/invite)\/[0-9A-Za-z]*", re.IGNORECASE) - invalid_link_regex = re.compile(r"^(\[[^\]]+\]|<\:[a-z0-9]+\:[0-9]+>) .+ https?:\/\/\S*$", re.IGNORECASE) - - try: - if message.guild.id in no_pub_guild: - if isinstance(discord_invite_regex.search(message.content), re.Match): - author = self.bot.get_user(message.author.id) - await message.delete() - await author.send("La pub pour les serveurs discord n'est pas autorisée ici") - - if message.channel.id in lien_channel \ - and not isinstance(invalid_link_regex.search(message.content), re.Match): - author = self.bot.get_user(message.author.id) - await message.delete() - await author.send(f"Votre message `{message.content}` a été " - f"supprimé du channel `liens` ou `projets` " - f"car il ne respecte pas la structure " - f"définie. Pour partager un lien veuillez " - f"suivre la structure suivante :" - f" ` [Sujet] Descirption http(s)://....`") - await author.send("Si vous voulez commenter ou discuter à " - "propos d'un lien ou d'un projet, veuillez " - "le faire dans le channel" - " `#discussion-des-liens` ou" - " `#discussion-projets`.") - - if message.channel.id in sondage_channel: - prefix_lenght = len(await self.bot.get_prefix(message)) - command = (message.content.split()[0])[prefix_lenght:] - if command != "sondage": - await message.delete() - except AttributeError: - pass - - -def setup(bot): - bot.add_cog(FilterMessages(bot)) +from discord.ext import commands +import re + + +class FilterMessages(commands.Cog): + """Flitre des messages""" + + def __init__(self, bot): + self.bot = bot + + @commands.Cog.listener() + async def on_message(self, message): + no_pub_guild = [280805240977227776, 303633056944881686, + 274247231534792704] + lien_channel = [280805783795662848, 508794201509593088, + 516017286948061204] + sondage_channel = [394146769107419146, 477147964393914388] + + if message.author.bot \ + or str(message.author.id) in self.bot.config.authorized_id \ + or message.channel.permissions_for(message.author).administrator is True: + return + + discord_invite_regex = re.compile(r"(discord\.(gg|io|me|li)|discordapp\.com\/invite)\/[0-9A-Za-z]*", re.IGNORECASE) + invalid_link_regex = re.compile(r"^(\[[^\]]+\]|<\:[a-z0-9]+\:[0-9]+>) .+ https?:\/\/\S*$", re.IGNORECASE) + + try: + if message.guild.id in no_pub_guild: + if isinstance(discord_invite_regex.search(message.content), re.Match): + author = self.bot.get_user(message.author.id) + await message.delete() + await author.send("La pub pour les serveurs discord n'est pas autorisée ici") + + if message.channel.id in lien_channel \ + and not isinstance(invalid_link_regex.search(message.content), re.Match): + author = self.bot.get_user(message.author.id) + await message.delete() + await author.send(f"Votre message `{message.content}` a été " + f"supprimé du channel `liens` ou `projets` " + f"car il ne respecte pas la structure " + f"définie. Pour partager un lien veuillez " + f"suivre la structure suivante :" + f" ` [Sujet] Descirption http(s)://....`") + await author.send("Si vous voulez commenter ou discuter à " + "propos d'un lien ou d'un projet, veuillez " + "le faire dans le channel" + " `#discussion-des-liens` ou" + " `#discussion-projets`.") + + if message.channel.id in sondage_channel: + prefix_lenght = len(await self.bot.get_prefix(message)) + command = (message.content.split()[0])[prefix_lenght:] + if command != "sondage": + await message.delete() + except AttributeError: + pass + + +def setup(bot): + bot.add_cog(FilterMessages(bot)) diff --git a/cogs/funs.py b/cogs/funs.py index 0ebd204..d374d1e 100755 --- a/cogs/funs.py +++ b/cogs/funs.py @@ -1,190 +1,190 @@ -from discord.ext import commands -import asyncio -import discord -import urllib.request -import json -import random -import requests - - -class Funs(commands.Cog): - """Commandes funs.""" - - def __init__(self, bot): - self.bot = bot - - """---------------------------------------------------------------------""" - - @commands.command() - async def avatar(self, ctx, user: discord.Member = None): - """Récuperer l'avatar de ...""" - - if user is None: - user = ctx.message.author - - embed = discord.Embed(title="Avatar de " + user.name, - description=f"[Ouvrir dans mon navigateur]" - f"({user.avatar_url_as(format='png')})") - embed.set_image(url=user.avatar_url_as(format='png')) - await ctx.send(embed=embed) - - """---------------------------------------------------------------------""" - - @commands.command(pass_context=True) - async def poke(self, ctx, user: discord.Member): - """Poke quelqu'un""" - await ctx.send(f":clap: Hey {user.mention} tu t'es fait poker par" - f" {ctx.message.author} !") - await ctx.message.delete() - - """---------------------------------------------------------------------""" - - @commands.command() - async def btcprice(self, ctx): - """Le prix du BTC""" - loading = await ctx.send("_réfléchis..._") - try: - url = urllib.request.urlopen("https://blockchain.info/fr/ticker") - btc = json.loads(url.read().decode()) - except KeyError: - btc = 1 - - if btc == 1: - await loading.edit(content="Impossible d'accèder à l'API" - " blockchain.info, veuillez réessayer" - " ultérieurment ! :c") - else: - frbtc = str(btc["EUR"]["last"]).replace(".", ",") - usbtc = str(btc["USD"]["last"]).replace(".", ",") - await loading.edit(content=f"Un bitcoin est égal à :" - f" {usbtc}$US soit {frbtc}€.") - - """---------------------------------------------------------------------""" - - @commands.command() - async def joke(self, ctx, number: str = 0): - """Print a random joke in a json file""" - with open('texts/jokes.json') as js: - jk = json.load(js) - - try: - if 15 >= int(number) > 0: - clef = str(number) - else: - clef = str(random.randint(1, 15)) - except Exception: - clef = str(random.randint(1, 15)) - - joke = jk["{}".format(clef)] - - embed = discord.Embed(title="Blague _{}_ : ".format(clef), - description=joke['content'], colour=0x03C9A9) - embed.set_footer(text="Par " + joke['author']) - embed.set_thumbnail(url='https://outout.tech/tuxbot/blobjoy.png') - await ctx.send(embed=embed) - - """---------------------------------------------------------------------""" - - @commands.command() - async def ethylotest(self, ctx): - """Ethylotest simulator 2018""" - results_poulet = ["Désolé mais mon ethylotest est sous Windows Vista, " - "merci de patienter...", - "_(ethylotest)_ : Une erreur est survenue. Windows " - "cherche une solution à se problème.", - "Mais j'l'ai foutu où ce p\\*\\*\\* d'ethylotest de m\\*\\*\\* " - "bordel fait ch\\*\\*\\*", - "C'est pas possible z'avez cassé l'ethylotest !"] - results_client = ["D'accord, il n'y a pas de problème à cela je suis " - "complètement clean", - "Bien sur si c'est votre devoir !", "Suce bi\\*e !", - "J'ai l'air d'être bourré ?", - "_laissez moi prendre un bonbon à la menthe..._"] - - result_p = random.choice(results_poulet) - result_c = random.choice(results_client) - - await ctx.send(":oncoming_police_car: Bonjour bonjour, contrôle " - "d'alcoolémie !") - await asyncio.sleep(0.5) - await ctx.send(":man: " + result_c) - await asyncio.sleep(1) - await ctx.send(":police_car: " + result_p) - - """---------------------------------------------------------------------""" - - @commands.command() - async def coin(self, ctx): - """Coin flip simulator 2025""" - starts_msg = ["Je lance la pièce !", "C'est parti !", "C'est une pièce" - " d'un cent faut" - " pas la perdre", - "C'est une pièce d'un euro faut pas la perdre", - "Je lance !"] - results_coin = ["{0} pile", "{0} face", "{1} Heu c'est quoi pile c'est" - " quoi face enfaite ?", - "{1} Oh shit, je crois que je l'ai perdue", - "{1} Et bim je te vol ta pièce !", - "{0} Oh une erreur d'impression il n'y a ni pile ni" - " face !"] - - start = random.choice(starts_msg) - result = random.choice(results_coin) - - await ctx.send(start) - await asyncio.sleep(0.6) - await ctx.send(result.format(":moneybag: Et la pièce retombe sur ...", - ":robot:")) - - """---------------------------------------------------------------------""" - - @commands.command() - async def pokemon(self, ctx): - """Random pokemon fight""" - with open('texts/pokemons.json') as js: - jk = json.load(js) - - poke1 = jk[random.randint(1, 150)] - poke2 = jk[random.randint(1, 150)] - - try: - if poke1['MaxHP'] > poke2['MaxHP']: - winer = poke1 - else: - winer = poke2 - except KeyError: - winer = poke1 - - await ctx.send(":flag_white: **Le combat commence !**") - await asyncio.sleep(1) - await ctx.send(":loudspeaker: Les concurants sont {} contre {} ! Bonne" - " chance à eux !".format(poke1["Name"], poke2["Name"])) - await asyncio.sleep(0.5) - await ctx.send(":boom: {} commence et utilise {}".format( - poke1["Name"], poke1["Fast Attack(s)"][0]["Name"])) - await asyncio.sleep(1) - await ctx.send(":dash: {} réplique avec {}".format( - poke2["Name"], poke2["Fast Attack(s)"][0]["Name"])) - await asyncio.sleep(1.2) - await ctx.send("_le combat continue de se dérouler..._") - await asyncio.sleep(1.5) - await ctx.send(":trophy: Le gagnant est **{}** !".format( - winer["Name"])) - - """---------------------------------------------------------------------""" - - @commands.command() - async def randomcat(self, ctx): - """Display a random cat""" - r = requests.get('http://aws.random.cat/meow') - cat = str(r.json()['file']) - embed = discord.Embed(title="Meow", - description="[Voir le chat plus grand]({})". - format(cat), colour=0x03C9A9) - embed.set_thumbnail(url=cat) - embed.set_author(name="Random.cat", url='https://random.cat/') - await ctx.send(embed=embed) - - -def setup(bot): - bot.add_cog(Funs(bot)) +from discord.ext import commands +import asyncio +import discord +import urllib.request +import json +import random +import requests + + +class Funs(commands.Cog): + """Commandes funs.""" + + def __init__(self, bot): + self.bot = bot + + """---------------------------------------------------------------------""" + + @commands.command() + async def avatar(self, ctx, user: discord.Member = None): + """Récuperer l'avatar de ...""" + + if user is None: + user = ctx.message.author + + embed = discord.Embed(title="Avatar de " + user.name, + description=f"[Ouvrir dans mon navigateur]" + f"({user.avatar_url_as(format='png')})") + embed.set_image(url=user.avatar_url_as(format='png')) + await ctx.send(embed=embed) + + """---------------------------------------------------------------------""" + + @commands.command(pass_context=True) + async def poke(self, ctx, user: discord.Member): + """Poke quelqu'un""" + await ctx.send(f":clap: Hey {user.mention} tu t'es fait poker par" + f" {ctx.message.author} !") + await ctx.message.delete() + + """---------------------------------------------------------------------""" + + @commands.command() + async def btcprice(self, ctx): + """Le prix du BTC""" + loading = await ctx.send("_réfléchis..._") + try: + url = urllib.request.urlopen("https://blockchain.info/fr/ticker") + btc = json.loads(url.read().decode()) + except KeyError: + btc = 1 + + if btc == 1: + await loading.edit(content="Impossible d'accèder à l'API" + " blockchain.info, veuillez réessayer" + " ultérieurment ! :c") + else: + frbtc = str(btc["EUR"]["last"]).replace(".", ",") + usbtc = str(btc["USD"]["last"]).replace(".", ",") + await loading.edit(content=f"Un bitcoin est égal à :" + f" {usbtc}$US soit {frbtc}€.") + + """---------------------------------------------------------------------""" + + @commands.command() + async def joke(self, ctx, number: str = 0): + """Print a random joke in a json file""" + with open('texts/jokes.json') as js: + jk = json.load(js) + + try: + if 15 >= int(number) > 0: + clef = str(number) + else: + clef = str(random.randint(1, 15)) + except Exception: + clef = str(random.randint(1, 15)) + + joke = jk["{}".format(clef)] + + embed = discord.Embed(title="Blague _{}_ : ".format(clef), + description=joke['content'], colour=0x03C9A9) + embed.set_footer(text="Par " + joke['author']) + embed.set_thumbnail(url='https://outout.tech/tuxbot/blobjoy.png') + await ctx.send(embed=embed) + + """---------------------------------------------------------------------""" + + @commands.command() + async def ethylotest(self, ctx): + """Ethylotest simulator 2018""" + results_poulet = ["Désolé mais mon ethylotest est sous Windows Vista, " + "merci de patienter...", + "_(ethylotest)_ : Une erreur est survenue. Windows " + "cherche une solution à se problème.", + "Mais j'l'ai foutu où ce p\\*\\*\\* d'ethylotest de m\\*\\*\\* " + "bordel fait ch\\*\\*\\*", + "C'est pas possible z'avez cassé l'ethylotest !"] + results_client = ["D'accord, il n'y a pas de problème à cela je suis " + "complètement clean", + "Bien sur si c'est votre devoir !", "Suce bi\\*e !", + "J'ai l'air d'être bourré ?", + "_laissez moi prendre un bonbon à la menthe..._"] + + result_p = random.choice(results_poulet) + result_c = random.choice(results_client) + + await ctx.send(":oncoming_police_car: Bonjour bonjour, contrôle " + "d'alcoolémie !") + await asyncio.sleep(0.5) + await ctx.send(":man: " + result_c) + await asyncio.sleep(1) + await ctx.send(":police_car: " + result_p) + + """---------------------------------------------------------------------""" + + @commands.command() + async def coin(self, ctx): + """Coin flip simulator 2025""" + starts_msg = ["Je lance la pièce !", "C'est parti !", "C'est une pièce" + " d'un cent faut" + " pas la perdre", + "C'est une pièce d'un euro faut pas la perdre", + "Je lance !"] + results_coin = ["{0} pile", "{0} face", "{1} Heu c'est quoi pile c'est" + " quoi face enfaite ?", + "{1} Oh shit, je crois que je l'ai perdue", + "{1} Et bim je te vol ta pièce !", + "{0} Oh une erreur d'impression il n'y a ni pile ni" + " face !"] + + start = random.choice(starts_msg) + result = random.choice(results_coin) + + await ctx.send(start) + await asyncio.sleep(0.6) + await ctx.send(result.format(":moneybag: Et la pièce retombe sur ...", + ":robot:")) + + """---------------------------------------------------------------------""" + + @commands.command() + async def pokemon(self, ctx): + """Random pokemon fight""" + with open('texts/pokemons.json') as js: + jk = json.load(js) + + poke1 = jk[random.randint(1, 150)] + poke2 = jk[random.randint(1, 150)] + + try: + if poke1['MaxHP'] > poke2['MaxHP']: + winer = poke1 + else: + winer = poke2 + except KeyError: + winer = poke1 + + await ctx.send(":flag_white: **Le combat commence !**") + await asyncio.sleep(1) + await ctx.send(":loudspeaker: Les concurants sont {} contre {} ! Bonne" + " chance à eux !".format(poke1["Name"], poke2["Name"])) + await asyncio.sleep(0.5) + await ctx.send(":boom: {} commence et utilise {}".format( + poke1["Name"], poke1["Fast Attack(s)"][0]["Name"])) + await asyncio.sleep(1) + await ctx.send(":dash: {} réplique avec {}".format( + poke2["Name"], poke2["Fast Attack(s)"][0]["Name"])) + await asyncio.sleep(1.2) + await ctx.send("_le combat continue de se dérouler..._") + await asyncio.sleep(1.5) + await ctx.send(":trophy: Le gagnant est **{}** !".format( + winer["Name"])) + + """---------------------------------------------------------------------""" + + @commands.command() + async def randomcat(self, ctx): + """Display a random cat""" + r = requests.get('http://aws.random.cat/meow') + cat = str(r.json()['file']) + embed = discord.Embed(title="Meow", + description="[Voir le chat plus grand]({})". + format(cat), colour=0x03C9A9) + embed.set_thumbnail(url=cat) + embed.set_author(name="Random.cat", url='https://random.cat/') + await ctx.send(embed=embed) + + +def setup(bot): + bot.add_cog(Funs(bot)) diff --git a/cogs/monitoring.py b/cogs/monitoring.py index 8edcb06..c9c6456 100644 --- a/cogs/monitoring.py +++ b/cogs/monitoring.py @@ -1,41 +1,41 @@ -import asyncio -import threading -from aiohttp import web - -from discord.ext import commands -from bot import TuxBot - - -class Monitoring(commands.Cog): - - def __init__(self): - self.app = web.Application() - - t = threading.Thread( - target=self.run_server, - args=(self.aiohttp_server(),) - ) - t.start() - - def aiohttp_server(self): - async def hi(request): - return web.Response(text="I'm alive !") - - self.app.add_routes([web.get('/', hi)]) - runner = web.AppRunner(self.app) - - return runner - - @staticmethod - def run_server(runner): - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - loop.run_until_complete(runner.setup()) - site = web.TCPSite(runner, '0.0.0.0', 3389) - loop.run_until_complete(site.start()) - loop.run_forever() - - -def setup(bot: TuxBot): - bot.add_cog(Monitoring()) - +import asyncio +import threading +from aiohttp import web + +from discord.ext import commands +from bot import TuxBot + + +class Monitoring(commands.Cog): + + def __init__(self): + self.app = web.Application() + + t = threading.Thread( + target=self.run_server, + args=(self.aiohttp_server(),) + ) + t.start() + + def aiohttp_server(self): + async def hi(request): + return web.Response(text="I'm alive !") + + self.app.add_routes([web.get('/', hi)]) + runner = web.AppRunner(self.app) + + return runner + + @staticmethod + def run_server(runner): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + loop.run_until_complete(runner.setup()) + site = web.TCPSite(runner, '0.0.0.0', 3389) + loop.run_until_complete(site.start()) + loop.run_forever() + + +def setup(bot: TuxBot): + bot.add_cog(Monitoring()) + diff --git a/cogs/role.py b/cogs/role.py index c16169e..f4f248c 100755 --- a/cogs/role.py +++ b/cogs/role.py @@ -1,152 +1,152 @@ -from discord.ext import commands -import discord - - -class Role(commands.Cog): - """Commandes role.""" - - def __init__(self, bot): - self.bot = bot - - self.ARCH_ROLE = 393077257826205706 - self.DEBIAN_ROLE = 393077933209550859 - self.RHEL_ROLE = 393078333245751296 - self.ANDROID_ROLE = 393087862972612627 - self.BSD_ROLE = 401791543708745738 - - @commands.group(name="role", no_pm=True, pass_context=True, - case_insensitive=True) - async def _role(self, ctx): - """Affiche l'aide sur la commande role""" - if ctx.message.guild.id != 280805240977227776: - return - - if ctx.invoked_subcommand is None: - text = open('texts/roles.md').read() - em = discord.Embed(title='Gestionnaires de rôles', - description=text, colour=0x89C4F9) - await ctx.send(embed=em) - - """---------------------------------------------------------------------""" - - @_role.command(name="arch", aliases=["archlinux", "arch_linux"], - pass_context=True) - async def role_arch(self, ctx): - """Ajoute/retire le role 'Arch user'""" - roles = ctx.message.author.roles - role_id = [] - for role in roles: - role_id.append(role.id) - - user = ctx.message.author - if self.ARCH_ROLE in role_id: - await user.remove_roles(discord.Object(id=self.ARCH_ROLE)) - await ctx.send(f"{ctx.message.author.mention} > Pourquoi tu viens " - f"de supprimer Arch Linux, c'était trop compliqué " - f"pour toi ? <:sad:343723037331292170>") - else: - await user.add_roles(discord.Object(id=self.ARCH_ROLE)) - await ctx.send(f"{ctx.message.author.mention} > How un " - f"ArchLinuxien, c'est bon les ``yaourt`` ? " - f"<:hap:354275645574086656>") - - """---------------------------------------------------------------------""" - - @_role.command(name="debian", pass_context=True) - async def role_debian(self, ctx): - """Ajoute/retire le role 'debian user'""" - roles = ctx.message.author.roles - role_id = [] - for role in roles: - role_id.append(role.id) - - user = ctx.message.author - if self.DEBIAN_ROLE in role_id: - await user.remove_roles(discord.Object(id=self.DEBIAN_ROLE)) - await ctx.send(f"{ctx.message.author.mention} > Adieu ! Tu verras, " - f"APT te manquera ! ") - else: - await user.add_roles(discord.Object(id=self.DEBIAN_ROLE)) - await ctx.send(f"{ctx.message.author.mention} > Un utilisateur de " - f"Debian, encore et encore ! " - f"<:stuck_out_tongue:343723077412323339>") - - """---------------------------------------------------------------------""" - - @_role.command(name="rhel", pass_context=True) - async def role_rhel(self, ctx): - """Ajoute/retire le role 'rhel user'""" - roles = ctx.message.author.roles - role_id = [] - for role in roles: - role_id.append(role.id) - - user = ctx.message.author - if self.RHEL_ROLE in role_id: - await user.remove_roles(discord.Object(id=self.RHEL_ROLE)) - await ctx.send(f"{ctx.message.author.mention} > Pourquoi tu t'en " - f"vas, il sont déjà assez seul là-bas " - f"<:sad:343723037331292170>") - else: - await user.add_roles(discord.Object(id=self.RHEL_ROLE)) - await ctx.send(f"{ctx.message.author.mention} > Mais, voila " - f"quelqu'un qui porte des chapeaux ! " - f"<:hap:354275645574086656>") - - """---------------------------------------------------------------------""" - - @_role.command(name="android", pass_context=True) - async def role_android(self, ctx): - """Ajoute/retire le role 'android user'""" - roles = ctx.message.author.roles - role_id = [] - for role in roles: - role_id.append(role.id) - - user = ctx.message.author - if self.ANDROID_ROLE in role_id: - await user.remove_roles(discord.Object(id=self.ANDROID_ROLE)) - await ctx.send(f"{ctx.message.author.mention} >How, me dit pas " - f"que tu as compris que les Android's allaient " - f"exterminer le monde ? " - f"<:trollface:375327667160875008>") - else: - await user.add_roles(discord.Object(id=self.ANDROID_ROLE)) - await ctx.send(f"{ctx.message.author.mention} > Hey, un utilisateur" - f" d'Android, prêt à continuer l'extermination de " - f"WP et iOS ? " - f"<:stuck_out_tongue:343723077412323339>") - - """---------------------------------------------------------------------""" - - @_role.command(name="bsd", pass_context=True) - async def role_bsd(self, ctx): - """Ajoute/retire le role 'BSD user'""" - roles = ctx.message.author.roles - role_id = [] - for role in roles: - role_id.append(role.id) - - user = ctx.message.author - if self.BSD_ROLE in role_id: - await user.remove_roles(discord.Object(id=self.BSD_ROLE)) - await ctx.send(f"{ctx.message.author.mention} > Ohhhh fait gaffe " - f"ou le démon va te piquer") - else: - await user.add_roles(discord.Object(id=self.BSD_ROLE)) - await ctx.send(f"{ctx.message.author.mention} > Quelqu'un sous " - f"BSD ! Au moins il a pas besoin de mettre GNU " - f"devant son OS à chaque fois :d") - - """---------------------------------------------------------------------""" - - @_role.command(name="staff", pass_context=True, hidden=True) - async def role_staff(self, ctx): - """Easter egg""" - - await ctx.send(f"{ctx.message.author.mention} > Vous n'avez pas " - f"le rôle staff, tu crois quoi :joy:") - - -def setup(bot): - bot.add_cog(Role(bot)) +from discord.ext import commands +import discord + + +class Role(commands.Cog): + """Commandes role.""" + + def __init__(self, bot): + self.bot = bot + + self.ARCH_ROLE = 393077257826205706 + self.DEBIAN_ROLE = 393077933209550859 + self.RHEL_ROLE = 393078333245751296 + self.ANDROID_ROLE = 393087862972612627 + self.BSD_ROLE = 401791543708745738 + + @commands.group(name="role", no_pm=True, pass_context=True, + case_insensitive=True) + async def _role(self, ctx): + """Affiche l'aide sur la commande role""" + if ctx.message.guild.id != 280805240977227776: + return + + if ctx.invoked_subcommand is None: + text = open('texts/roles.md').read() + em = discord.Embed(title='Gestionnaires de rôles', + description=text, colour=0x89C4F9) + await ctx.send(embed=em) + + """---------------------------------------------------------------------""" + + @_role.command(name="arch", aliases=["archlinux", "arch_linux"], + pass_context=True) + async def role_arch(self, ctx): + """Ajoute/retire le role 'Arch user'""" + roles = ctx.message.author.roles + role_id = [] + for role in roles: + role_id.append(role.id) + + user = ctx.message.author + if self.ARCH_ROLE in role_id: + await user.remove_roles(discord.Object(id=self.ARCH_ROLE)) + await ctx.send(f"{ctx.message.author.mention} > Pourquoi tu viens " + f"de supprimer Arch Linux, c'était trop compliqué " + f"pour toi ? <:sad:343723037331292170>") + else: + await user.add_roles(discord.Object(id=self.ARCH_ROLE)) + await ctx.send(f"{ctx.message.author.mention} > How un " + f"ArchLinuxien, c'est bon les ``yaourt`` ? " + f"<:hap:354275645574086656>") + + """---------------------------------------------------------------------""" + + @_role.command(name="debian", pass_context=True) + async def role_debian(self, ctx): + """Ajoute/retire le role 'debian user'""" + roles = ctx.message.author.roles + role_id = [] + for role in roles: + role_id.append(role.id) + + user = ctx.message.author + if self.DEBIAN_ROLE in role_id: + await user.remove_roles(discord.Object(id=self.DEBIAN_ROLE)) + await ctx.send(f"{ctx.message.author.mention} > Adieu ! Tu verras, " + f"APT te manquera ! ") + else: + await user.add_roles(discord.Object(id=self.DEBIAN_ROLE)) + await ctx.send(f"{ctx.message.author.mention} > Un utilisateur de " + f"Debian, encore et encore ! " + f"<:stuck_out_tongue:343723077412323339>") + + """---------------------------------------------------------------------""" + + @_role.command(name="rhel", pass_context=True) + async def role_rhel(self, ctx): + """Ajoute/retire le role 'rhel user'""" + roles = ctx.message.author.roles + role_id = [] + for role in roles: + role_id.append(role.id) + + user = ctx.message.author + if self.RHEL_ROLE in role_id: + await user.remove_roles(discord.Object(id=self.RHEL_ROLE)) + await ctx.send(f"{ctx.message.author.mention} > Pourquoi tu t'en " + f"vas, il sont déjà assez seul là-bas " + f"<:sad:343723037331292170>") + else: + await user.add_roles(discord.Object(id=self.RHEL_ROLE)) + await ctx.send(f"{ctx.message.author.mention} > Mais, voila " + f"quelqu'un qui porte des chapeaux ! " + f"<:hap:354275645574086656>") + + """---------------------------------------------------------------------""" + + @_role.command(name="android", pass_context=True) + async def role_android(self, ctx): + """Ajoute/retire le role 'android user'""" + roles = ctx.message.author.roles + role_id = [] + for role in roles: + role_id.append(role.id) + + user = ctx.message.author + if self.ANDROID_ROLE in role_id: + await user.remove_roles(discord.Object(id=self.ANDROID_ROLE)) + await ctx.send(f"{ctx.message.author.mention} >How, me dit pas " + f"que tu as compris que les Android's allaient " + f"exterminer le monde ? " + f"<:trollface:375327667160875008>") + else: + await user.add_roles(discord.Object(id=self.ANDROID_ROLE)) + await ctx.send(f"{ctx.message.author.mention} > Hey, un utilisateur" + f" d'Android, prêt à continuer l'extermination de " + f"WP et iOS ? " + f"<:stuck_out_tongue:343723077412323339>") + + """---------------------------------------------------------------------""" + + @_role.command(name="bsd", pass_context=True) + async def role_bsd(self, ctx): + """Ajoute/retire le role 'BSD user'""" + roles = ctx.message.author.roles + role_id = [] + for role in roles: + role_id.append(role.id) + + user = ctx.message.author + if self.BSD_ROLE in role_id: + await user.remove_roles(discord.Object(id=self.BSD_ROLE)) + await ctx.send(f"{ctx.message.author.mention} > Ohhhh fait gaffe " + f"ou le démon va te piquer") + else: + await user.add_roles(discord.Object(id=self.BSD_ROLE)) + await ctx.send(f"{ctx.message.author.mention} > Quelqu'un sous " + f"BSD ! Au moins il a pas besoin de mettre GNU " + f"devant son OS à chaque fois :d") + + """---------------------------------------------------------------------""" + + @_role.command(name="staff", pass_context=True, hidden=True) + async def role_staff(self, ctx): + """Easter egg""" + + await ctx.send(f"{ctx.message.author.mention} > Vous n'avez pas " + f"le rôle staff, tu crois quoi :joy:") + + +def setup(bot): + bot.add_cog(Role(bot)) diff --git a/cogs/search.py b/cogs/search.py index 536413f..b9d6e36 100755 --- a/cogs/search.py +++ b/cogs/search.py @@ -1,157 +1,157 @@ -from discord.ext import commands -import discord -import asyncio -import urllib.request -import wikipedia - -wikipedia.set_lang("fr") - - -class Search(commands.Cog): - """Commandes de WWW.""" - - def __init__(self, bot): - self.bot = bot - - @commands.group(name="search", no_pm=True, pass_context=True) - async def _search(self, ctx): - """Rechercher sur le world wide web""" - if ctx.invoked_subcommand is None: - text = open('texts/search.md').read() - em = discord.Embed(title='Commandes de search TuxBot', - description=text, - colour=0x89C4F9) - await ctx.send(embed=em) - - @_search.command(pass_context=True, name="docubuntu") - async def search_docubuntu(self, ctx, args): - attends = await ctx.send("_Je te cherche ça {} !_".format( - ctx.message.author.mention)) - html = urllib.request.urlopen("https://doc.ubuntu-fr.org/" + - args).read() - if "avez suivi un lien" in str(html): - await attends.edit(content=":sob: Nooooon ! Cette page n'existe " - "pas, mais tu peux toujours la créer : " - "https://doc.ubuntu-fr.org/" + args) - else: - await attends.delete() - embed = discord.Embed(description="Voila j'ai trouvé ! Voici la " - "page ramenant à votre recherche," - " toujours aussi bien rédigée " - ":wink: : https://doc.ubuntu-fr." - "org/" + args, - url='http://doc.ubuntu-fr.org/') - embed.set_author(name="DocUbuntu-Fr", - url='http://doc.ubuntu-fr.org/', - icon_url='https://tuxbot.outout.xyz/data/ubuntu.png') - embed.set_thumbnail(url='https://tuxbot.outout.xyz/data/ubuntu.png') - embed.set_footer(text="Merci à ceux qui ont pris le temps d'écrire " - "cette documentation") - await ctx.send(embed=embed) - - @_search.command(pass_context=True, name="docarch") - async def search_docarch(self, ctx, args): - attends = await ctx.send("_Je te cherche ça {} !_".format( - ctx.message.author.mention)) - html = urllib.request.urlopen("https://wiki.archlinux.org/index.php/" + - args).read() - if "There is currently no text in this page" in str(html): - await attends.edit(content=":sob: Nooooon ! Cette page n'existe " - "pas.") - else: - await attends.delete() - embed = discord.Embed(description="Voila j'ai trouvé ! Voici la " - "page ramenant à votre recherche," - " toujours aussi bien rédigée " - ":wink: : https://wiki.archlinux." - "org/index.php/" + args, - url='https://wiki.archlinux.org/index.php/') - embed.set_author(name="Doc ArchLinux", - url='https://wiki.archlinux.org/index.php/', - icon_url='https://tuxbot.outout.xyz/data/arch.png') - embed.set_thumbnail(url='https://tuxbot.outout.xyz/data/arch.png') - embed.set_footer(text="Merci à ceux qui ont pris le temps d'écrire " - "cette documentation") - await ctx.send(embed=embed) - - @_search.command(pass_context=True, name="wikipedia") - async def search_wikipedia(self, ctx: commands.Context, args): - """Fait une recherche sur wikipd""" - - wait = await ctx.send("_Je cherche..._") - results = wikipedia.search(args) - nbmr = 0 - mmssgg = "" - - for value in results: - nbmr = nbmr + 1 - mmssgg = mmssgg + "**{}**: {} \n".format(str(nbmr), value) - - em = discord.Embed(title='Résultats de : ' + args, - description = mmssgg, - colour=0x4ECDC4) - em.set_thumbnail(url="https://upload.wikimedia.org/wikipedia/commons/" - "2/26/Paullusmagnus-logo_%28large%29.png") - await wait.delete() - - sending = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟"] - - def check(reaction, user): - return user == ctx.author and reaction.emoji in sending and \ - reaction.message.id == msg.id - - async def waiter(future: asyncio.Future): - reaction, user = await self.bot.wait_for('reaction_add', - check=check) - future.set_result(reaction.emoji) - - emoji = asyncio.Future() - self.bot.loop.create_task(waiter(emoji)) - - msg = await ctx.send(embed=em) - for e in sending: - await msg.add_reaction(e) - if emoji.done(): - break - - while not emoji.done(): - await asyncio.sleep(0.1) - - page = int(sending.index(emoji.result())) - - args_ = results[page] - - try: - await msg.delete() - await ctx.trigger_typing() - wait = await ctx.send(ctx.message.author.mention + - " ah ok sympa cette recherche, je l'effectue de suite !") - wp = wikipedia.page(args_) - wp_contenu = wp.summary[:200] + "..." - em = discord.Embed(title='Wikipedia : ' + wp.title, - description = "{} \n_Lien_ : {} ".format( - wp_contenu, wp.url), - colour=0x9B59B6) - em.set_author(name="Wikipedia", - url='http://wikipedia.org', - icon_url='https://upload.wikimedia.org/wikipedia/' - 'commons/2/26/Paullusmagnus-logo_%28large' - '%29.png') - em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/" - "commons/2/26/Paullusmagnus-logo_%28large" - "%29.png") - em.set_footer(text="Merci à eux de nous fournir une encyclopédie " - "libre !") - await wait.delete() - await ctx.send(embed=em) - - except wikipedia.exceptions.PageError: - # TODO : A virer dans l'event on_error - await ctx.send(":open_mouth: Une **erreur interne** est survenue," - " si cela ce reproduit contactez votre" - " administrateur ou faites une Issue sur" - " ``gitea`` !") - - -def setup(bot): - bot.add_cog(Search(bot)) +from discord.ext import commands +import discord +import asyncio +import urllib.request +import wikipedia + +wikipedia.set_lang("fr") + + +class Search(commands.Cog): + """Commandes de WWW.""" + + def __init__(self, bot): + self.bot = bot + + @commands.group(name="search", no_pm=True, pass_context=True) + async def _search(self, ctx): + """Rechercher sur le world wide web""" + if ctx.invoked_subcommand is None: + text = open('texts/search.md').read() + em = discord.Embed(title='Commandes de search TuxBot', + description=text, + colour=0x89C4F9) + await ctx.send(embed=em) + + @_search.command(pass_context=True, name="docubuntu") + async def search_docubuntu(self, ctx, args): + attends = await ctx.send("_Je te cherche ça {} !_".format( + ctx.message.author.mention)) + html = urllib.request.urlopen("https://doc.ubuntu-fr.org/" + + args).read() + if "avez suivi un lien" in str(html): + await attends.edit(content=":sob: Nooooon ! Cette page n'existe " + "pas, mais tu peux toujours la créer : " + "https://doc.ubuntu-fr.org/" + args) + else: + await attends.delete() + embed = discord.Embed(description="Voila j'ai trouvé ! Voici la " + "page ramenant à votre recherche," + " toujours aussi bien rédigée " + ":wink: : https://doc.ubuntu-fr." + "org/" + args, + url='http://doc.ubuntu-fr.org/') + embed.set_author(name="DocUbuntu-Fr", + url='http://doc.ubuntu-fr.org/', + icon_url='https://tuxbot.outout.xyz/data/ubuntu.png') + embed.set_thumbnail(url='https://tuxbot.outout.xyz/data/ubuntu.png') + embed.set_footer(text="Merci à ceux qui ont pris le temps d'écrire " + "cette documentation") + await ctx.send(embed=embed) + + @_search.command(pass_context=True, name="docarch") + async def search_docarch(self, ctx, args): + attends = await ctx.send("_Je te cherche ça {} !_".format( + ctx.message.author.mention)) + html = urllib.request.urlopen("https://wiki.archlinux.org/index.php/" + + args).read() + if "There is currently no text in this page" in str(html): + await attends.edit(content=":sob: Nooooon ! Cette page n'existe " + "pas.") + else: + await attends.delete() + embed = discord.Embed(description="Voila j'ai trouvé ! Voici la " + "page ramenant à votre recherche," + " toujours aussi bien rédigée " + ":wink: : https://wiki.archlinux." + "org/index.php/" + args, + url='https://wiki.archlinux.org/index.php/') + embed.set_author(name="Doc ArchLinux", + url='https://wiki.archlinux.org/index.php/', + icon_url='https://tuxbot.outout.xyz/data/arch.png') + embed.set_thumbnail(url='https://tuxbot.outout.xyz/data/arch.png') + embed.set_footer(text="Merci à ceux qui ont pris le temps d'écrire " + "cette documentation") + await ctx.send(embed=embed) + + @_search.command(pass_context=True, name="wikipedia") + async def search_wikipedia(self, ctx: commands.Context, args): + """Fait une recherche sur wikipd""" + + wait = await ctx.send("_Je cherche..._") + results = wikipedia.search(args) + nbmr = 0 + mmssgg = "" + + for value in results: + nbmr = nbmr + 1 + mmssgg = mmssgg + "**{}**: {} \n".format(str(nbmr), value) + + em = discord.Embed(title='Résultats de : ' + args, + description = mmssgg, + colour=0x4ECDC4) + em.set_thumbnail(url="https://upload.wikimedia.org/wikipedia/commons/" + "2/26/Paullusmagnus-logo_%28large%29.png") + await wait.delete() + + sending = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟"] + + def check(reaction, user): + return user == ctx.author and reaction.emoji in sending and \ + reaction.message.id == msg.id + + async def waiter(future: asyncio.Future): + reaction, user = await self.bot.wait_for('reaction_add', + check=check) + future.set_result(reaction.emoji) + + emoji = asyncio.Future() + self.bot.loop.create_task(waiter(emoji)) + + msg = await ctx.send(embed=em) + for e in sending: + await msg.add_reaction(e) + if emoji.done(): + break + + while not emoji.done(): + await asyncio.sleep(0.1) + + page = int(sending.index(emoji.result())) + + args_ = results[page] + + try: + await msg.delete() + await ctx.trigger_typing() + wait = await ctx.send(ctx.message.author.mention + + " ah ok sympa cette recherche, je l'effectue de suite !") + wp = wikipedia.page(args_) + wp_contenu = wp.summary[:200] + "..." + em = discord.Embed(title='Wikipedia : ' + wp.title, + description = "{} \n_Lien_ : {} ".format( + wp_contenu, wp.url), + colour=0x9B59B6) + em.set_author(name="Wikipedia", + url='http://wikipedia.org', + icon_url='https://upload.wikimedia.org/wikipedia/' + 'commons/2/26/Paullusmagnus-logo_%28large' + '%29.png') + em.set_thumbnail(url = "https://upload.wikimedia.org/wikipedia/" + "commons/2/26/Paullusmagnus-logo_%28large" + "%29.png") + em.set_footer(text="Merci à eux de nous fournir une encyclopédie " + "libre !") + await wait.delete() + await ctx.send(embed=em) + + except wikipedia.exceptions.PageError: + # TODO : A virer dans l'event on_error + await ctx.send(":open_mouth: Une **erreur interne** est survenue," + " si cela ce reproduit contactez votre" + " administrateur ou faites une Issue sur" + " ``gitea`` !") + + +def setup(bot): + bot.add_cog(Search(bot)) diff --git a/cogs/send_logs.py b/cogs/send_logs.py index 46c8952..058dcc9 100755 --- a/cogs/send_logs.py +++ b/cogs/send_logs.py @@ -1,105 +1,105 @@ -import datetime -import socket - -import discord -from discord.ext import commands - - -class SendLogs(commands.Cog): - """Send logs to a specific channel""" - - def __init__(self, bot): - - self.bot = bot - self.log_channel = None - self.main_server_id = int(self.bot.config.main_server_id) - - @commands.Cog.listener() - async def on_resumed(self): - em = discord.Embed(title="Et hop je me reconnecte à l'api 😃", - colour=0x5cb85c) - em.timestamp = datetime.datetime.utcnow() - await self.log_channel.send(embed=em) - - @commands.Cog.listener() - async def on_ready(self): - self.log_channel = await self.bot.fetch_channel(int(self.bot.config.log_channel_id)) - em = discord.Embed(title="Je suis opérationnel 😃", - description=f"*Instance lancée sur " - f"{socket.gethostname()}*", colour=0x5cb85c) - em.timestamp = datetime.datetime.utcnow() - await self.log_channel.send(embed=em) - - """---------------------------------------------------------------------""" - - @commands.Cog.listener() - async def on_guild_join(self, guild: discord.Guild): - em = discord.Embed(title=f"On m'a ajouté à : {str(guild.name)} 😃", - colour=0x51A351) - em.timestamp = datetime.datetime.utcnow() - await self.log_channel.send(embed=em) - - @commands.Cog.listener() - async def on_guild_remove(self, guild: discord.Guild): - em = discord.Embed(title=f"On m'a viré de : {str(guild.name)} 😦", - colour=0xBD362F) - em.timestamp = datetime.datetime.utcnow() - await self.log_channel.send(embed=em) - - """---------------------------------------------------------------------""" - - @commands.Cog.listener() - async def on_member_join(self, member): - if member.guild.id == self.main_server_id: - em = discord.Embed(title=f"{str(member)} *`({str(member.id)})`* " - f"nous a rejoint 😃", colour=0x51A351) - em.set_footer(text=f"Compte crée le {member.created_at}") - em.timestamp = datetime.datetime.utcnow() - await self.log_channel.send(embed=em) - - @commands.Cog.listener() - async def on_member_remove(self, member): - if member.guild.id == self.main_server_id: - em = discord.Embed(title=f"{str(member)} *`({str(member.id)})`* " - f"nous a quitté 😦", colour=0xBD362F) - em.timestamp = datetime.datetime.utcnow() - await self.log_channel.send(embed=em) - - """---------------------------------------------------------------------""" - - @commands.Cog.listener() - async def on_message_delete(self, message): - if message.guild.id == self.main_server_id and not message.author.bot: - async def is_a_command(message): - prefix_lenght = len(await self.bot.get_prefix(message)) - command = (message.content.split()[0])[prefix_lenght:] - if command == '': - command = "not_a_command" - - return self.bot.get_command(str(command)) - - if await is_a_command(message) is None: - em = discord.Embed(title=f"Message supprimé dans :" - f" {str(message.channel.name)}", - colour=0xBD362F) - em.add_field(name=f"{str(message.author)} " - f"*`({str(message.author.id)})`* " - f"a supprimé :", value=str(message.content)) - em.timestamp = datetime.datetime.utcnow() - await self.log_channel.send(embed=em) - - @commands.Cog.listener() - async def on_message_edit(self, before, after): - if before.guild.id == self.main_server_id and not before.author.bot: - em = discord.Embed(title=f"Message edité dans : " - f"{before.channel.name}", colour=0x0088CC) - em.add_field(name=f"{str(before.author)} " - f"*`({str(before.author.id)})`* a" - f" edité :", value=str(before.content)) - em.add_field(name="Pour remplacer par :", value=str(after.content)) - em.timestamp = datetime.datetime.utcnow() - await self.log_channel.send(embed=em) - - -def setup(bot): - bot.add_cog(SendLogs(bot)) +import datetime +import socket + +import discord +from discord.ext import commands + + +class SendLogs(commands.Cog): + """Send logs to a specific channel""" + + def __init__(self, bot): + + self.bot = bot + self.log_channel = None + self.main_server_id = int(self.bot.config.main_server_id) + + @commands.Cog.listener() + async def on_resumed(self): + em = discord.Embed(title="Et hop je me reconnecte à l'api 😃", + colour=0x5cb85c) + em.timestamp = datetime.datetime.utcnow() + await self.log_channel.send(embed=em) + + @commands.Cog.listener() + async def on_ready(self): + self.log_channel = await self.bot.fetch_channel(int(self.bot.config.log_channel_id)) + em = discord.Embed(title="Je suis opérationnel 😃", + description=f"*Instance lancée sur " + f"{socket.gethostname()}*", colour=0x5cb85c) + em.timestamp = datetime.datetime.utcnow() + await self.log_channel.send(embed=em) + + """---------------------------------------------------------------------""" + + @commands.Cog.listener() + async def on_guild_join(self, guild: discord.Guild): + em = discord.Embed(title=f"On m'a ajouté à : {str(guild.name)} 😃", + colour=0x51A351) + em.timestamp = datetime.datetime.utcnow() + await self.log_channel.send(embed=em) + + @commands.Cog.listener() + async def on_guild_remove(self, guild: discord.Guild): + em = discord.Embed(title=f"On m'a viré de : {str(guild.name)} 😦", + colour=0xBD362F) + em.timestamp = datetime.datetime.utcnow() + await self.log_channel.send(embed=em) + + """---------------------------------------------------------------------""" + + @commands.Cog.listener() + async def on_member_join(self, member): + if member.guild.id == self.main_server_id: + em = discord.Embed(title=f"{str(member)} *`({str(member.id)})`* " + f"nous a rejoint 😃", colour=0x51A351) + em.set_footer(text=f"Compte crée le {member.created_at}") + em.timestamp = datetime.datetime.utcnow() + await self.log_channel.send(embed=em) + + @commands.Cog.listener() + async def on_member_remove(self, member): + if member.guild.id == self.main_server_id: + em = discord.Embed(title=f"{str(member)} *`({str(member.id)})`* " + f"nous a quitté 😦", colour=0xBD362F) + em.timestamp = datetime.datetime.utcnow() + await self.log_channel.send(embed=em) + + """---------------------------------------------------------------------""" + + @commands.Cog.listener() + async def on_message_delete(self, message): + if message.guild.id == self.main_server_id and not message.author.bot: + async def is_a_command(message): + prefix_lenght = len(await self.bot.get_prefix(message)) + command = (message.content.split()[0])[prefix_lenght:] + if command == '': + command = "not_a_command" + + return self.bot.get_command(str(command)) + + if await is_a_command(message) is None: + em = discord.Embed(title=f"Message supprimé dans :" + f" {str(message.channel.name)}", + colour=0xBD362F) + em.add_field(name=f"{str(message.author)} " + f"*`({str(message.author.id)})`* " + f"a supprimé :", value=str(message.content)) + em.timestamp = datetime.datetime.utcnow() + await self.log_channel.send(embed=em) + + @commands.Cog.listener() + async def on_message_edit(self, before, after): + if before.guild.id == self.main_server_id and not before.author.bot: + em = discord.Embed(title=f"Message edité dans : " + f"{before.channel.name}", colour=0x0088CC) + em.add_field(name=f"{str(before.author)} " + f"*`({str(before.author.id)})`* a" + f" edité :", value=str(before.content)) + em.add_field(name="Pour remplacer par :", value=str(after.content)) + em.timestamp = datetime.datetime.utcnow() + await self.log_channel.send(embed=em) + + +def setup(bot): + bot.add_cog(SendLogs(bot)) diff --git a/cogs/sondage.py b/cogs/sondage.py index d2c803b..5ac837a 100755 --- a/cogs/sondage.py +++ b/cogs/sondage.py @@ -1,99 +1,99 @@ -import asyncio - -import discord -from discord.ext import commands - - -class Sondage(commands.Cog): - """Commandes sondage.""" - - def __init__(self, bot): - self.bot = bot - - @commands.command(pass_context=True) - async def sondage(self, ctx, *, msg="help"): - if msg != "help": - await ctx.message.delete() - options = msg.split(" | ") - - times = [x for x in options if x.startswith("time=")] - - if times: - time = int(times[0].strip("time=")) - options.remove(times[0]) - else: - time = 0 - - if len(options) <= 1: - raise commands.errors.MissingRequiredArgument - if len(options) >= 22: - return await ctx.send(f"{ctx.message.author.mention}> " - f":octagonal_sign: Vous ne pouvez pas " - f"mettre plus de 20 réponses !") - - emoji = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣', '🔟', '0⃣', - '🇦', '🇧', '🇨', '🇩', '🇪', '🇫', '🇬', '🇭', '🇮'] - to_react = [] - confirmation_msg = f"**{options[0].rstrip('?')}?**:\n\n" - - for idx, option in enumerate(options[1:]): - confirmation_msg += f"{emoji[idx]} - {option}\n" - to_react.append(emoji[idx]) - - confirmation_msg += "*Sondage proposé par* " + \ - str(ctx.message.author.mention) - if time == 0: - confirmation_msg += "" - else: - confirmation_msg += f"\n\nVous avez {time} secondes pour voter!" - - poll_msg = await ctx.send(confirmation_msg) - for emote in to_react: - await poll_msg.add_reaction(emote) - - if time != 0: - await asyncio.sleep(time) - async for message in ctx.message.channel.history(): - if message.id == poll_msg.id: - poll_msg = message - - results = {} - - for reaction in poll_msg.reactions: - if reaction.emoji in to_react: - results[reaction.emoji] = reaction.count - 1 - end_msg = "Le sondage est términé. Les résultats sont:\n\n" - - for result in results: - end_msg += "{} {} - {} votes\n". \ - format(result, - options[emoji.index(result)+1], - results[result]) - - top_result = max(results, key=lambda key: results[key]) - - if len([x for x in results - if results[x] == results[top_result]]) > 1: - top_results = [] - for key, value in results.items(): - if value == results[top_result]: - top_results.append(options[emoji.index(key)+1]) - end_msg += "\nLes gagnants sont : {}". \ - format(", ".join(top_results)) - else: - top_result = options[emoji.index(top_result)+1] - end_msg += "\n\"{}\" est le gagnant!".format(top_result) - await ctx.send(end_msg) - else: - await ctx.send("please use `@tuxbot poll` (this is rewrite version in beta") - await ctx.message.delete() - - text = open('texts/rpoll.md').read() - em = discord.Embed(title='Aide sur le sondage', - description=text, - colour=0xEEEEEE) - await ctx.send(embed=em) - - -def setup(bot): - bot.add_cog(Sondage(bot)) +import asyncio + +import discord +from discord.ext import commands + + +class Sondage(commands.Cog): + """Commandes sondage.""" + + def __init__(self, bot): + self.bot = bot + + @commands.command(pass_context=True) + async def sondage(self, ctx, *, msg="help"): + if msg != "help": + await ctx.message.delete() + options = msg.split(" | ") + + times = [x for x in options if x.startswith("time=")] + + if times: + time = int(times[0].strip("time=")) + options.remove(times[0]) + else: + time = 0 + + if len(options) <= 1: + raise commands.errors.MissingRequiredArgument + if len(options) >= 22: + return await ctx.send(f"{ctx.message.author.mention}> " + f":octagonal_sign: Vous ne pouvez pas " + f"mettre plus de 20 réponses !") + + emoji = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣', '🔟', '0⃣', + '🇦', '🇧', '🇨', '🇩', '🇪', '🇫', '🇬', '🇭', '🇮'] + to_react = [] + confirmation_msg = f"**{options[0].rstrip('?')}?**:\n\n" + + for idx, option in enumerate(options[1:]): + confirmation_msg += f"{emoji[idx]} - {option}\n" + to_react.append(emoji[idx]) + + confirmation_msg += "*Sondage proposé par* " + \ + str(ctx.message.author.mention) + if time == 0: + confirmation_msg += "" + else: + confirmation_msg += f"\n\nVous avez {time} secondes pour voter!" + + poll_msg = await ctx.send(confirmation_msg) + for emote in to_react: + await poll_msg.add_reaction(emote) + + if time != 0: + await asyncio.sleep(time) + async for message in ctx.message.channel.history(): + if message.id == poll_msg.id: + poll_msg = message + + results = {} + + for reaction in poll_msg.reactions: + if reaction.emoji in to_react: + results[reaction.emoji] = reaction.count - 1 + end_msg = "Le sondage est términé. Les résultats sont:\n\n" + + for result in results: + end_msg += "{} {} - {} votes\n". \ + format(result, + options[emoji.index(result)+1], + results[result]) + + top_result = max(results, key=lambda key: results[key]) + + if len([x for x in results + if results[x] == results[top_result]]) > 1: + top_results = [] + for key, value in results.items(): + if value == results[top_result]: + top_results.append(options[emoji.index(key)+1]) + end_msg += "\nLes gagnants sont : {}". \ + format(", ".join(top_results)) + else: + top_result = options[emoji.index(top_result)+1] + end_msg += "\n\"{}\" est le gagnant!".format(top_result) + await ctx.send(end_msg) + else: + await ctx.send("please use `@tuxbot poll` (this is rewrite version in beta") + await ctx.message.delete() + + text = open('texts/rpoll.md').read() + em = discord.Embed(title='Aide sur le sondage', + description=text, + colour=0xEEEEEE) + await ctx.send(embed=em) + + +def setup(bot): + bot.add_cog(Sondage(bot)) diff --git a/cogs/utility.py b/cogs/utility.py index 30d5f49..f66d5ee 100755 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -1,363 +1,452 @@ -import datetime -import json -import pytz -import random -import urllib - -import discord -import requests -from discord.ext import commands -import socket - -class Utility(commands.Cog): - """Commandes utilitaires.""" - - def __init__(self, bot): - self.bot = bot - - @commands.group(name="clock", pass_context=True, case_insensitive=True) - async def clock(self, ctx): - """Display hour in a country""" - - if ctx.invoked_subcommand is None: - text = open('texts/clocks.md').read() - em = discord.Embed(title='Liste des Horloges', description=text, colour=0xEEEEEE) - await ctx.send(embed=em) - - @clock.command(name="montréal", aliases=["mtl", "montreal"], pass_context=True) - async def clock_montreal(self, ctx): - then = datetime.datetime.now(pytz.utc) - - utc = then.astimezone(pytz.timezone('America/Montreal')) - site = "http://ville.montreal.qc.ca/" - img = "https://upload.wikimedia.org/wikipedia/commons/e/e0/Rentier_fws_1.jpg" - country = "au Canada, Québec" - description = "Montréal est la deuxième ville la plus peuplée du Canada. Elle se situe dans la région du Québec" - - form = '%H heures %M' - tt = utc.strftime(form) - - em = discord.Embed(title='Heure à Montréal', description=f"A [Montréal]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) - em.set_thumbnail(url = img) - await ctx.send(embed=em) - - @clock.command(name="vancouver", pass_context=True) - async def clock_vancouver(self, ctx): - then = datetime.datetime.now(pytz.utc) - - utc = then.astimezone(pytz.timezone('America/Vancouver')) - site = "http://vancouver.ca/" - img = "https://upload.wikimedia.org/wikipedia/commons/f/fe/Dock_Vancouver.JPG" - country = "au Canada" - description = "Vancouver, officiellement City of Vancouver, est une cité portuaire au Canada" - - form = '%H heures %M' - tt = utc.strftime(form) - - em = discord.Embed(title='Heure à Vancouver', description=f"A [Vancouver]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) - em.set_thumbnail(url = img) - await ctx.send(embed=em) - - @clock.command(name="new-york",aliases=["ny", "n-y", "new york"], pass_context=True) - async def clock_new_york(self, ctx): - then = datetime.datetime.now(pytz.utc) - - utc = then.astimezone(pytz.timezone('America/New_York')) - site = "http://www1.nyc.gov/" - img = "https://upload.wikimedia.org/wikipedia/commons/e/e3/NewYork_LibertyStatue.jpg" - country = "aux U.S.A." - description = "New York, est la plus grande ville des États-Unis en termes d'habitants et l'une des plus importantes du continent américain. " - - form = '%H heures %M' - tt = utc.strftime(form) - - em = discord.Embed(title='Heure à New York', description=f"A [str(New York]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) - em.set_thumbnail(url = img) - await ctx.send(embed=em) - - @clock.command(name="la", aliases=["los-angeles", "losangeles", "l-a", "los angeles"], pass_context=True) - async def clock_la(self, ctx): - then = datetime.datetime.now(pytz.utc) - - utc = then.astimezone(pytz.timezone('America/Los_Angeles')) - site = "https://www.lacity.org/" - img = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/LA_Skyline_Mountains2.jpg/800px-LA_Skyline_Mountains2.jpg" - country = "aux U.S.A." - description = "Los Angeles est la deuxième ville la plus peuplée des États-Unis après New York. Elle est située dans le sud de l'État de Californie, sur la côte pacifique." - - form = '%H heures %M' - tt = utc.strftime(form) - - em = discord.Embed(title='Heure à Los Angeles', description=f"A [Los Angeles]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) - em.set_thumbnail(url = img) - await ctx.send(embed=em) - - @clock.command(name="paris", aliases=["baguette"],pass_context=True) - async def clock_paris(self, ctx): - then = datetime.datetime.now(pytz.utc) - - utc = then.astimezone(pytz.timezone('Europe/Paris')) - site = "http://www.paris.fr/" - img = "https://upload.wikimedia.org/wikipedia/commons/a/af/Tour_eiffel_at_sunrise_from_the_trocadero.jpg" - country = "en France" - description = "Paris est la capitale de la France. Elle se situe au cœur d'un vaste bassin sédimentaire aux sols fertiles et au climat tempéré, le bassin parisien." - - form = '%H heures %M' - tt = utc.strftime(form) - - em = discord.Embed(title='Heure à Paris', description=f"A [Paris]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) - em.set_thumbnail(url = img) - await ctx.send(embed=em) - - @clock.command(name="berlin", pass_context=True) - async def clock_berlin(self, ctx): - then = datetime.datetime.now(pytz.utc) - - utc = then.astimezone(pytz.timezone('Europe/Berlin')) - site = "http://www.berlin.de/" - img = "https://upload.wikimedia.org/wikipedia/commons/9/91/Eduard_Gaertner_Schlossfreiheit.jpg" - country = "en Allemagne" - description = "Berlin est la capitale et la plus grande ville d'Allemagne. Située dans le nord-est du pays, elle compte environ 3,5 millions d'habitants. " - - form = '%H heures %M' - tt = utc.strftime(form) - - em = discord.Embed(title='Heure à Berlin', description=f"A [Berlin]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) - em.set_thumbnail(url = img) - await ctx.send(embed=em) - - @clock.command(name="berne", aliases=["zurich", "bern"], pass_context=True) - async def clock_berne(self, ctx): - then = datetime.datetime.now(pytz.utc) - - utc = then.astimezone(pytz.timezone('Europe/Zurich')) - site = "http://www.berne.ch/" - img = "https://upload.wikimedia.org/wikipedia/commons/d/db/Justitia_Statue_02.jpg" - country = "en Suisse" - description = "Berne est la cinquième plus grande ville de Suisse et la capitale du canton homonyme. Depuis 1848, Berne est la « ville fédérale »." - - form = '%H heures %M' - tt = utc.strftime(form) - - em = discord.Embed(title='Heure à Berne', description=f"A [Berne]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) - em.set_thumbnail(url = img) - await ctx.send(embed=em) - - @clock.command(name="tokyo", pass_context=True) - async def clock_tokyo(self, ctx): - then = datetime.datetime.now(pytz.utc) - - utc = then.astimezone(pytz.timezone('Asia/Tokyo')) - site = "http://www.gotokyo.org/" - img = "https://upload.wikimedia.org/wikipedia/commons/3/37/TaroTokyo20110213-TokyoTower-01.jpg" - country = "au Japon" - description = "Tokyo, anciennement Edo, officiellement la préfecture métropolitaine de Tokyo, est la capitale du Japon." - - form = '%H heures %M' - tt = utc.strftime(form) - - em = discord.Embed(title='Heure à Tokyo', description=f"A [Tokyo]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) - em.set_thumbnail(url = img) - await ctx.send(embed=em) - - @clock.command(name="moscou", aliases=["moscow", "moskova"], pass_context=True) - async def clock_moscou(self, ctx): - then = datetime.datetime.now(pytz.utc) - - utc = then.astimezone(pytz.timezone('Europe/Moscow')) - site = "https://www.mos.ru/" - img = "https://upload.wikimedia.org/wikipedia/commons/f/f7/Andreyevsky_Zal.jpg" - country = "en Russie" - description = "Moscou est la capitale de la Fédération de Russie et la plus grande ville d'Europe. Moscou est situé sur la rivière Moskova. " - - form = '%H heures %M' - tt = utc.strftime(form) - - em = discord.Embed(title='Heure à Moscou', description=f"A [Moscou]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) - em.set_thumbnail(url = img) - await ctx.send(embed=em) - - """---------------------------------------------------------------------""" - - @commands.command() - async def ytdiscover(self, ctx): - """Random youtube channel""" - with open('texts/ytb.json') as js: - ytb = json.load(js) - - clef = str(random.randint(0,12)) - chaine = ytb["{}".format(clef)] - - embed = discord.Embed(title=chaine['name'], - url=chaine['url'], - description=f"**{chaine['name']}**, {chaine['desc']} \n[Je veux voir ça]({chaine['url']})") - embed.set_thumbnail(url='https://outout.tech/tuxbot/yt.png') - await ctx.send(embed=embed) - - """---------------------------------------------------------------------""" - - @commands.command(name='iplocalise', pass_context=True) - async def _iplocalise(self, ctx, ipaddress, iptype=""): - realipaddress = ipaddress - """Recup headers.""" - if ipaddress.startswith("http://"): - if ipaddress[-1:] == '/': - ipaddress = ipaddress[:-1] - ipaddress = ipaddress.split("http://")[1] - if ipaddress.startswith("https://"): - if ipaddress[-1:] == '/': - ipaddress = ipaddress[:-1] - ipaddress = ipaddress.split("https://")[1] - - if(iptype=="ipv6" or iptype=="v6"): - try: - ipaddress = socket.getaddrinfo(ipaddress, None, socket.AF_INET6)[1][4][0] - - if (ipaddress == "2602:fe53:b:1::87") and not ("gnous" in realipaddress): - await ctx.send("Erreur, cette adresse n'est pas disponible en IPv6.") - return - except Exception as e: - await ctx.send("Erreur, cette adresse n'est pas disponible en IPv6.") - print(e) - return - - iploading = await ctx.send("_réfléchis..._") - ipapi = urllib.request.urlopen("http://ip-api.com/json/" + ipaddress) - ipinfo = json.loads(ipapi.read().decode()) - - if ipinfo["status"] != "fail": - if ipinfo['query']: - embed = discord.Embed(title=f"Informations pour ``{realipaddress}`` *`({ipinfo['query']})`*", color=0x5858d7) - - if ipinfo['org']: - embed.add_field(name="Appartient à :", value=ipinfo['org'], inline = False) - - if ipinfo['city']: - embed.add_field(name="Se situe à :", value=ipinfo['city'], inline = True) - - - if ipinfo['country']: - if ipinfo['regionName']: - regionName = ipinfo['regionName'] - else: - regionName = "N/A" - embed.add_field(name="Region :", value=f"{regionName} ({ipinfo['country']})", inline = True) - - embed.set_thumbnail(url=f"https://www.countryflags.io/{ipinfo['countryCode']}/flat/64.png") - await ctx.send(embed=embed) - else: - await ctx.send(content=f"Erreur, impossible d'avoir des informations sur l'adresse IP ``{ipinfo['query']}``") - await iploading.delete() - - """---------------------------------------------------------------------""" - @commands.command(name='getheaders', pass_context=True) - async def _getheaders(self, ctx, *, adresse): - """Recuperer les HEADERS :d""" - if adresse.startswith("http://") != True and adresse.startswith("https://") != True: - adresse = "http://" + adresse - if len(adresse) > 200: - await ctx.send("{0} Essaye d'entrer une adresse de moins de 200 caractères plutôt.".format(ctx.author.mention)) - - elif adresse.startswith("http://") or adresse.startswith("https://") or adresse.startswith("ftp://"): - try: - get = urllib.request.urlopen(adresse, timeout = 1) - embed = discord.Embed(title="Entêtes de {0}".format(adresse), color=0xd75858) - embed.add_field(name="Code Réponse", value=get.getcode(), inline = True) - embed.set_thumbnail(url="https://http.cat/{}".format(str(get.getcode()))) - if get.getheader('location'): - embed.add_field(name="Redirection vers", value=get.getheader('location'), inline=True) - if get.getheader('server'): - embed.add_field(name="Serveur", value=get.getheader('server'), inline=True) - if get.getheader('content-type'): - embed.add_field(name="Type de contenu", value = get.getheader('content-type'), inline = True) - if get.getheader('x-content-type-options'): - embed.add_field(name="x-content-type", value= get.getheader('x-content-type-options'), inline=True) - if get.getheader('x-frame-options'): - embed.add_field(name="x-frame-options", value= get.getheader('x-frame-options'), inline=True) - if get.getheader('cache-control'): - embed.add_field(name="Controle du cache", value = get.getheader('cache-control'), inline = True) - await ctx.send(embed=embed) - except urllib.error.HTTPError as e: - embed = discord.Embed(title="Entêtes de {0}".format(adresse), color=0xd75858) - embed.add_field(name="Code Réponse", value=e.getcode(), inline = True) - embed.set_thumbnail(url="https://http.cat/{}".format(str(e.getcode()))) - await ctx.send(embed=embed) - print('''An error occurred: {} The response code was {}'''.format(e, e.getcode())) - except urllib.error.URLError as e: - if "No address associated" in str(e): - await ctx.send("Erreur, aucune adresse n'est associé à ce nom d'hôte.") - return - if "timed out" in str(e): - await ctx.send("Erreur, l'adresse en question dépasse le délais d'attente :(") - return - if "SSL" in str(e): - await ctx.send("Erreur avec le certificat SSL, essayez sans ``https://`` !") - return - return - if "no host": - await ctx.send("Erreur, aucun nom d'hôte n'a été donné.") - return - if "not known": - await ctx.send("Erreur, nom de l'hôte inconnu.") - return - print("ERROR @ getheaders @ urlerror : {} - adress {}".format(e, adresse)) - await ctx.send('[CONTACTER ADMIN] URLError: {}'.format(e.reason)) - except Exception as e: - print("ERROR @ getheaders @ Exception : {} - adress {}".format(e, adresse)) - await ctx.send("{0} Impossible d'accèder à {1}, es-tu sur que l'adresse {1} est correcte et que le serveur est allumé ?".format(ctx.author.mention, adresse)) - else: - await ctx.send("{0} Merci de faire commencer {1} par ``https://``, ``http://`` ou ``ftp://``.".format(ctx.author.mention, adresse)) - - """---------------------------------------------------------------------""" - - @commands.command(name='git', pass_context=True) - async def _git(self, ctx): - """Pour voir mon code""" - text = "How tu veux voir mon repos Gitea pour me disséquer ? " \ - "Pas de soucis ! Je suis un Bot, je ne ressens pas la " \ - "douleur !\n https://git.gnous.eu/gnouseu/tuxbot-bot" - em = discord.Embed(title='Repos TuxBot-Bot', description=text, colour=0xE9D460) - em.set_author(name='Gnous', icon_url="https://cdn.discordapp.com/" - "icons/280805240977227776/" - "9ba1f756c9d9bfcf27989d0d0abb3862" - ".png") - await ctx.send(embed=em) - - """---------------------------------------------------------------------""" - - @commands.command(name='quote', pass_context=True) - async def _quote(self, ctx, quote_id): - global quoted_message - - async def get_message(message_id: int): - for channel in ctx.message.guild.channels: - if isinstance(channel, discord.TextChannel): - test_chan = await self.bot.fetch_channel(channel.id) - try: - return await test_chan.fetch_message(message_id) - except (discord.NotFound, discord.Forbidden): - pass - return None - - quoted_message = await get_message(int(quote_id)) - - if quoted_message is not None: - embed = discord.Embed(colour=quoted_message.author.colour, - description=quoted_message.clean_content, - timestamp=quoted_message.created_at) - embed.set_author(name=quoted_message.author.display_name, - icon_url=quoted_message.author.avatar_url_as( - format="jpg")) - if len(quoted_message.attachments) >= 1: - embed.set_image(url=quoted_message.attachments[0].url) - embed.add_field(name="**Original**", - value=f"[Go!]({quoted_message.jump_url})") - embed.set_footer(text="#" + quoted_message.channel.name) - - await ctx.send(embed=embed) - else: - await ctx.send("Impossible de trouver le message.") - - -def setup(bot): - bot.add_cog(Utility(bot)) +import datetime +import json +import pytz +import random +import urllib +import ipinfo as ipinfoio + +from ipwhois.net import Net +from ipwhois.asn import IPASN + +import discord +import requests +from discord.ext import commands +import socket + +class Utility(commands.Cog): + """Commandes utilitaires.""" + + def __init__(self, bot): + self.bot = bot + + @commands.group(name="clock", pass_context=True, case_insensitive=True) + async def clock(self, ctx): + """Display hour in a country""" + + if ctx.invoked_subcommand is None: + text = open('texts/clocks.md').read() + em = discord.Embed(title='Liste des Horloges', description=text, colour=0xEEEEEE) + await ctx.send(embed=em) + + @clock.command(name="montréal", aliases=["mtl", "montreal"], pass_context=True) + async def clock_montreal(self, ctx): + then = datetime.datetime.now(pytz.utc) + + utc = then.astimezone(pytz.timezone('America/Montreal')) + site = "http://ville.montreal.qc.ca/" + img = "https://upload.wikimedia.org/wikipedia/commons/e/e0/Rentier_fws_1.jpg" + country = "au Canada, Québec" + description = "Montréal est la deuxième ville la plus peuplée du Canada. Elle se situe dans la région du Québec" + + form = '%H heures %M' + tt = utc.strftime(form) + + em = discord.Embed(title='Heure à Montréal', description=f"A [Montréal]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) + em.set_thumbnail(url = img) + await ctx.send(embed=em) + + @clock.command(name="vancouver", pass_context=True) + async def clock_vancouver(self, ctx): + then = datetime.datetime.now(pytz.utc) + + utc = then.astimezone(pytz.timezone('America/Vancouver')) + site = "http://vancouver.ca/" + img = "https://upload.wikimedia.org/wikipedia/commons/f/fe/Dock_Vancouver.JPG" + country = "au Canada" + description = "Vancouver, officiellement City of Vancouver, est une cité portuaire au Canada" + + form = '%H heures %M' + tt = utc.strftime(form) + + em = discord.Embed(title='Heure à Vancouver', description=f"A [Vancouver]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) + em.set_thumbnail(url = img) + await ctx.send(embed=em) + + @clock.command(name="new-york",aliases=["ny", "n-y", "new york"], pass_context=True) + async def clock_new_york(self, ctx): + then = datetime.datetime.now(pytz.utc) + + utc = then.astimezone(pytz.timezone('America/New_York')) + site = "http://www1.nyc.gov/" + img = "https://upload.wikimedia.org/wikipedia/commons/e/e3/NewYork_LibertyStatue.jpg" + country = "aux U.S.A." + description = "New York, est la plus grande ville des États-Unis en termes d'habitants et l'une des plus importantes du continent américain. " + + form = '%H heures %M' + tt = utc.strftime(form) + + em = discord.Embed(title='Heure à New York', description=f"A [str(New York]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) + em.set_thumbnail(url = img) + await ctx.send(embed=em) + + @clock.command(name="la", aliases=["los-angeles", "losangeles", "l-a", "los angeles"], pass_context=True) + async def clock_la(self, ctx): + then = datetime.datetime.now(pytz.utc) + + utc = then.astimezone(pytz.timezone('America/Los_Angeles')) + site = "https://www.lacity.org/" + img = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/LA_Skyline_Mountains2.jpg/800px-LA_Skyline_Mountains2.jpg" + country = "aux U.S.A." + description = "Los Angeles est la deuxième ville la plus peuplée des États-Unis après New York. Elle est située dans le sud de l'État de Californie, sur la côte pacifique." + + form = '%H heures %M' + tt = utc.strftime(form) + + em = discord.Embed(title='Heure à Los Angeles', description=f"A [Los Angeles]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) + em.set_thumbnail(url = img) + await ctx.send(embed=em) + + @clock.command(name="paris", aliases=["baguette"],pass_context=True) + async def clock_paris(self, ctx): + then = datetime.datetime.now(pytz.utc) + + utc = then.astimezone(pytz.timezone('Europe/Paris')) + site = "http://www.paris.fr/" + img = "https://upload.wikimedia.org/wikipedia/commons/a/af/Tour_eiffel_at_sunrise_from_the_trocadero.jpg" + country = "en France" + description = "Paris est la capitale de la France. Elle se situe au cœur d'un vaste bassin sédimentaire aux sols fertiles et au climat tempéré, le bassin parisien." + + form = '%H heures %M' + tt = utc.strftime(form) + + em = discord.Embed(title='Heure à Paris', description=f"A [Paris]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) + em.set_thumbnail(url = img) + await ctx.send(embed=em) + + @clock.command(name="berlin", pass_context=True) + async def clock_berlin(self, ctx): + then = datetime.datetime.now(pytz.utc) + + utc = then.astimezone(pytz.timezone('Europe/Berlin')) + site = "http://www.berlin.de/" + img = "https://upload.wikimedia.org/wikipedia/commons/9/91/Eduard_Gaertner_Schlossfreiheit.jpg" + country = "en Allemagne" + description = "Berlin est la capitale et la plus grande ville d'Allemagne. Située dans le nord-est du pays, elle compte environ 3,5 millions d'habitants. " + + form = '%H heures %M' + tt = utc.strftime(form) + + em = discord.Embed(title='Heure à Berlin', description=f"A [Berlin]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) + em.set_thumbnail(url = img) + await ctx.send(embed=em) + + @clock.command(name="berne", aliases=["zurich", "bern"], pass_context=True) + async def clock_berne(self, ctx): + then = datetime.datetime.now(pytz.utc) + + utc = then.astimezone(pytz.timezone('Europe/Zurich')) + site = "http://www.berne.ch/" + img = "https://upload.wikimedia.org/wikipedia/commons/d/db/Justitia_Statue_02.jpg" + country = "en Suisse" + description = "Berne est la cinquième plus grande ville de Suisse et la capitale du canton homonyme. Depuis 1848, Berne est la « ville fédérale »." + + form = '%H heures %M' + tt = utc.strftime(form) + + em = discord.Embed(title='Heure à Berne', description=f"A [Berne]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) + em.set_thumbnail(url = img) + await ctx.send(embed=em) + + @clock.command(name="tokyo", pass_context=True) + async def clock_tokyo(self, ctx): + then = datetime.datetime.now(pytz.utc) + + utc = then.astimezone(pytz.timezone('Asia/Tokyo')) + site = "http://www.gotokyo.org/" + img = "https://upload.wikimedia.org/wikipedia/commons/3/37/TaroTokyo20110213-TokyoTower-01.jpg" + country = "au Japon" + description = "Tokyo, anciennement Edo, officiellement la préfecture métropolitaine de Tokyo, est la capitale du Japon." + + form = '%H heures %M' + tt = utc.strftime(form) + + em = discord.Embed(title='Heure à Tokyo', description=f"A [Tokyo]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) + em.set_thumbnail(url = img) + await ctx.send(embed=em) + + @clock.command(name="moscou", aliases=["moscow", "moskova"], pass_context=True) + async def clock_moscou(self, ctx): + then = datetime.datetime.now(pytz.utc) + + utc = then.astimezone(pytz.timezone('Europe/Moscow')) + site = "https://www.mos.ru/" + img = "https://upload.wikimedia.org/wikipedia/commons/f/f7/Andreyevsky_Zal.jpg" + country = "en Russie" + description = "Moscou est la capitale de la Fédération de Russie et la plus grande ville d'Europe. Moscou est situé sur la rivière Moskova. " + + form = '%H heures %M' + tt = utc.strftime(form) + + em = discord.Embed(title='Heure à Moscou', description=f"A [Moscou]({site}) {country}, Il est **{str(tt)}** ! \n {description} \n _source des images et du texte : [Wikimedia foundation](http://commons.wikimedia.org/)_", colour=0xEEEEEE) + em.set_thumbnail(url = img) + await ctx.send(embed=em) + + """---------------------------------------------------------------------""" + + @commands.command() + async def ytdiscover(self, ctx): + """Random youtube channel""" + with open('texts/ytb.json') as js: + ytb = json.load(js) + + clef = str(random.randint(0,12)) + chaine = ytb["{}".format(clef)] + + embed = discord.Embed(title=chaine['name'], + url=chaine['url'], + description=f"**{chaine['name']}**, {chaine['desc']} \n[Je veux voir ça]({chaine['url']})") + embed.set_thumbnail(url='https://outout.tech/tuxbot/yt.png') + await ctx.send(embed=embed) + + """---------------------------------------------------------------------""" + + @commands.command(name='iplocalise', pass_context=True) + async def _iplocalise(self, ctx, ipaddress, iptype=""): + realipaddress = ipaddress + """Getting headers.""" + if ipaddress.startswith("http://"): + if ipaddress[-1:] == '/': + ipaddress = ipaddress[:-1] + ipaddress = ipaddress.split("http://")[1] + if ipaddress.startswith("https://"): + if ipaddress[-1:] == '/': + ipaddress = ipaddress[:-1] + ipaddress = ipaddress.split("https://")[1] + + if(iptype=="ipv6" or iptype=="v6" or iptype=="-6"): + try: + ipaddress = socket.getaddrinfo(ipaddress, None, socket.AF_INET6)[1][4][0] + except Exception as e: + await ctx.send("Erreur, cette adresse n'est pas disponible en IPv6.") + return + elif(iptype=="ipv4" or iptype=="v4" or iptype=="-4"): + try: + ipaddress = socket.getaddrinfo(ipaddress, None, socket.AF_INET)[1][4][0] + except Exception as e: + await ctx.send("Erreur, cette adresse n'est pas disponible en IPv4.") + return + else: + try: + ipaddress = socket.getaddrinfo(ipaddress, None)[1][4][0] + except Exception as e: + await ctx.send("Erreur, cette adresse n'est pas disponible.") + return + + iploading = await ctx.send("_Récupération des informations..._") + + net = Net(ipaddress) + obj = IPASN(net) + ipinfo = obj.lookup() + + try: + iphostname = socket.gethostbyaddr(ipaddress)[0] + except: + iphostname = "N/A" + + # IPINFO api + api_result = True + try: + access_token = open('ipinfoio.key').read() + handler = ipinfoio.getHandler(access_token) + details = handler.getDetails(ipaddress) + except: + api_result = False + + try: + embed = discord.Embed(title=f"Informations pour ``{realipaddress} ({ipaddress})``", color=0x5858d7) + + if(api_result): + embed.add_field(name="Appartient à :", value=f"{details.org}") + else: + embed.add_field(name="Appartient à :", value=f"{ipinfo['asn_description']} (AS{ipinfo['asn']})", inline = False) + + embed.add_field(name="RIR :", value=f"{ipinfo['asn_registry']}", inline = True) + + if(api_result): + embed.add_field(name="Région :", value=f"{details.city} - {details.region} ({details.country})") + else: + embed.add_field(name="Région :", value=f"{ipinfo['asn_country_code']}") + embed.add_field(name="Nom de l'hôte :", value=f"{iphostname}") + + # Adding country flag + if(api_result): + embed.set_thumbnail(url=f"https://www.countryflags.io/{details.country}/shiny/64.png") + else: + embed.set_thumbnail(url=f"https://www.countryflags.io/{ipinfo['asn_country_code']}/shiny/64.png") + + await ctx.send(embed=embed) + except: + await ctx.send(content=f"Erreur, impossible d'avoir des informations sur l'adresse IP ``{realipaddress}``") + await iploading.delete() + + """---------------------------------------------------------------------""" + @commands.command(name='getheaders', pass_context=True) + async def _getheaders(self, ctx, *, adresse): + """Recuperer les HEADERS :d""" + if adresse.startswith("http://") != True and adresse.startswith("https://") != True: + adresse = "http://" + adresse + if len(adresse) > 200: + await ctx.send("{0} Essaye d'entrer une adresse de moins de 200 caractères plutôt.".format(ctx.author.mention)) + + elif adresse.startswith("http://") or adresse.startswith("https://") or adresse.startswith("ftp://"): + try: + get = urllib.request.urlopen(adresse, timeout = 1) + embed = discord.Embed(title="Entêtes de {0}".format(adresse), color=0xd75858) + embed.add_field(name="Code Réponse", value=get.getcode(), inline = True) + embed.set_thumbnail(url="https://http.cat/{}".format(str(get.getcode()))) + if get.getheader('location'): + embed.add_field(name="Redirection vers", value=get.getheader('location'), inline=True) + if get.getheader('server'): + embed.add_field(name="Serveur", value=get.getheader('server'), inline=True) + if get.getheader('content-type'): + embed.add_field(name="Type de contenu", value = get.getheader('content-type'), inline = True) + if get.getheader('x-content-type-options'): + embed.add_field(name="x-content-type", value= get.getheader('x-content-type-options'), inline=True) + if get.getheader('x-frame-options'): + embed.add_field(name="x-frame-options", value= get.getheader('x-frame-options'), inline=True) + if get.getheader('cache-control'): + embed.add_field(name="Controle du cache", value = get.getheader('cache-control'), inline = True) + await ctx.send(embed=embed) + except urllib.error.HTTPError as e: + embed = discord.Embed(title="Entêtes de {0}".format(adresse), color=0xd75858) + embed.add_field(name="Code Réponse", value=e.getcode(), inline = True) + embed.set_thumbnail(url="https://http.cat/{}".format(str(e.getcode()))) + await ctx.send(embed=embed) + print('''An error occurred: {} The response code was {}'''.format(e, e.getcode())) + except urllib.error.URLError as e: + if "No address associated" in str(e): + await ctx.send("Erreur, aucune adresse n'est associé à ce nom d'hôte.") + return + if "timed out" in str(e): + await ctx.send("Erreur, l'adresse en question dépasse le délais d'attente :(") + return + if "SSL" in str(e): + await ctx.send("Erreur avec le certificat SSL, essayez sans ``https://`` !") + return + return + if "no host": + await ctx.send("Erreur, aucun nom d'hôte n'a été donné.") + return + if "not known": + await ctx.send("Erreur, nom de l'hôte inconnu.") + return + print("ERROR @ getheaders @ urlerror : {} - adress {}".format(e, adresse)) + await ctx.send('[CONTACTER ADMIN] URLError: {}'.format(e.reason)) + except Exception as e: + print("ERROR @ getheaders @ Exception : {} - adress {}".format(e, adresse)) + await ctx.send("{0} Impossible d'accèder à {1}, es-tu sur que l'adresse {1} est correcte et que le serveur est allumé ?".format(ctx.author.mention, adresse)) + else: + await ctx.send("{0} Merci de faire commencer {1} par ``https://``, ``http://`` ou ``ftp://``.".format(ctx.author.mention, adresse)) + + """---------------------------------------------------------------------""" + @commands.command(name='peeringdb', pass_context=True) + async def _peeringdb(self, ctx, *, asn): + def notEmptyField(embed, name, value): + if(value != ""): + embed.add_field(name=name, value=value) + + if asn.startswith("AS"): + asn = asn[2:] + loadingmsg = await ctx.send("_Récupération des informations..._") + + """Getting the ASN id in the peeringdb database""" + try: + asnid = urllib.request.urlopen("https://www.peeringdb.com/api/as_set/" + asn) + asnid = json.loads(asnid.read().decode()) + pdbid = asnid["data"][0][asn] + + asinfo = urllib.request.urlopen("https://www.peeringdb.com/api/net?irr_as_set=" + pdbid) + + asinfo = json.loads(asinfo.read().decode())["data"] + + for asndata in asinfo: + if(asndata['asn'] == int(asn)): + asinfo = asndata + + asproto = "" + if(asinfo["info_ipv6"]): + asproto = asproto + "IPv6 " + if(asinfo["info_unicast"]): + asproto = asproto + "Unicast " + if(asinfo["info_multicast"]): + asproto = asproto + "Multicast " + if(asinfo["info_never_via_route_servers"]): + asproto = asproto + "Never via Route servers" + + + print(pdbid) + + embed = discord.Embed(title=f"Informations pour {asinfo['name']} ``AS{asn}``", color=0x5858d7) + notEmptyField(embed, name="Nom :", value=asinfo['name']) + notEmptyField(embed, name="Aka :", value=asinfo['aka']) + notEmptyField(embed, name="Site :", value=asinfo['website']) + notEmptyField(embed, name="Looking Glass :", value=asinfo['looking_glass']) + notEmptyField(embed, name="Traffic :", value=asinfo['info_traffic']) + notEmptyField(embed, name="Ratio du traffic :", value=asinfo['info_ratio']) + notEmptyField(embed, name="Prefixes IPv4 :", value=asinfo['info_prefixes4']) + notEmptyField(embed, name="Prefixes IPv6 :", value=asinfo['info_prefixes6']) + notEmptyField(embed, name="Politique de Peering :", value=f"[{asinfo['policy_general']}]({asinfo['policy_url']})") + notEmptyField(embed, name="Protocoles supportés :", value=asproto) + embed.set_footer(text=f"https://www.peeringdb.com/") + await ctx.send(embed=embed) + await loadingmsg.delete() + except IndexError: + await ctx.send(f"Impossible d'avoir des informations sur l'AS AS{asn}") + await loadingmsg.delete() + except urllib.error.HTTPError: + await ctx.send(f"L'AS{asn} est introuvable dans la base de données de PeeringDB.") + await loadingmsg.delete() + + """---------------------------------------------------------------------""" + + @commands.command(name='git', pass_context=True) + async def _git(self, ctx): + """Pour voir mon code""" + text = "How tu veux voir mon repos Gitea pour me disséquer ? " \ + "Pas de soucis ! Je suis un Bot, je ne ressens pas la " \ + "douleur !\n https://git.gnous.eu/gnouseu/tuxbot-bot" + em = discord.Embed(title='Repos TuxBot-Bot', description=text, colour=0xE9D460) + em.set_author(name='Gnous', icon_url="https://cdn.discordapp.com/" + "icons/280805240977227776/" + "9ba1f756c9d9bfcf27989d0d0abb3862" + ".png") + await ctx.send(embed=em) + + """---------------------------------------------------------------------""" + + @commands.command(name='quote', pass_context=True) + async def _quote(self, ctx, quote_id): + global quoted_message + + async def get_message(message_id: int): + for channel in ctx.message.guild.channels: + if isinstance(channel, discord.TextChannel): + test_chan = await self.bot.fetch_channel(channel.id) + try: + return await test_chan.fetch_message(message_id) + except (discord.NotFound, discord.Forbidden): + pass + return None + + quoted_message = await get_message(int(quote_id)) + + if quoted_message is not None: + embed = discord.Embed(colour=quoted_message.author.colour, + description=quoted_message.clean_content, + timestamp=quoted_message.created_at) + embed.set_author(name=quoted_message.author.display_name, + icon_url=quoted_message.author.avatar_url_as( + format="jpg")) + if len(quoted_message.attachments) >= 1: + embed.set_image(url=quoted_message.attachments[0].url) + embed.add_field(name="**Original**", + value=f"[Go!]({quoted_message.jump_url})") + embed.set_footer(text="#" + quoted_message.channel.name) + + await ctx.send(embed=embed) + else: + await ctx.send("Impossible de trouver le message.") + + +def setup(bot): + bot.add_cog(Utility(bot)) diff --git a/cogs/utils/checks.py b/cogs/utils/checks.py index b965267..7bff60b 100755 --- a/cogs/utils/checks.py +++ b/cogs/utils/checks.py @@ -1,124 +1,124 @@ -from discord.ext import commands - - -def is_owner_check(message): - return str(message.author.id) in ['171685542553976832', - '269156684155453451'] - - -def is_owner(warn=True): - def check(ctx, log): - owner = is_owner_check(ctx.message) - if not owner and log: - print(ctx.message.author.name + " à essayer d'executer " + ctx.message.content + " sur le serveur " + ctx.message.guild.name) - return owner - - owner = commands.check(lambda ctx: check(ctx, warn)) - return owner - - -"""-------------------------------------------------------------------------""" - - -async def check_permissions(ctx, perms, *, check=all): - is_owner = await ctx.bot.is_owner(ctx.author) - if is_owner or is_owner_check(ctx.message) is True: - return True - - resolved = ctx.channel.permissions_for(ctx.author) - return check(getattr(resolved, name, None) == value for name, value in - perms.items()) - - -def has_permissions(*, check=all, **perms): - async def pred(ctx): - return await check_permissions(ctx, perms, check=check) - - return commands.check(pred) - - -async def check_guild_permissions(ctx, perms, *, check=all): - is_owner = await ctx.bot.is_owner(ctx.author) - if is_owner: - return True - - if ctx.guild is None: - return False - - resolved = ctx.author.guild_permissions - return check(getattr(resolved, name, None) == value for name, value in - perms.items()) - - -def has_guild_permissions(*, check=all, **perms): - async def pred(ctx): - return await check_guild_permissions(ctx, perms, check=check) - - return commands.check(pred) - - -# These do not take channel overrides into account - - -def is_mod(): - async def pred(ctx): - return await check_guild_permissions(ctx, {'manage_guild': True}) - - return commands.check(pred) - - -def is_admin(): - async def pred(ctx): - return await check_guild_permissions(ctx, {'administrator': True}) - - return commands.check(pred) - - -def mod_or_permissions(**perms): - perms['manage_guild'] = True - - async def predicate(ctx): - return await check_guild_permissions(ctx, perms, check=any) - - return commands.check(predicate) - - -def admin_or_permissions(**perms): - perms['administrator'] = True - - async def predicate(ctx): - return await check_guild_permissions(ctx, perms, check=any) - - return commands.check(predicate) - - -def is_in_guilds(*guild_ids): - def predicate(ctx): - guild = ctx.guild - if guild is None: - return False - return guild.id in guild_ids - - return commands.check(predicate) - - -def get_user(message, user): - try: - member = message.mentions[0] - except: - member = message.guild.get_member_named(user) - if not member: - try: - member = message.guild.get_member(int(user)) - except ValueError: - pass - if not member: - return None - return member - - -def check_date(date: str): - if len(date) == 1: - return f"0{date}" - else: - return date +from discord.ext import commands + + +def is_owner_check(message): + return str(message.author.id) in ['171685542553976832', + '269156684155453451'] + + +def is_owner(warn=True): + def check(ctx, log): + owner = is_owner_check(ctx.message) + if not owner and log: + print(ctx.message.author.name + " à essayer d'executer " + ctx.message.content + " sur le serveur " + ctx.message.guild.name) + return owner + + owner = commands.check(lambda ctx: check(ctx, warn)) + return owner + + +"""-------------------------------------------------------------------------""" + + +async def check_permissions(ctx, perms, *, check=all): + is_owner = await ctx.bot.is_owner(ctx.author) + if is_owner or is_owner_check(ctx.message) is True: + return True + + resolved = ctx.channel.permissions_for(ctx.author) + return check(getattr(resolved, name, None) == value for name, value in + perms.items()) + + +def has_permissions(*, check=all, **perms): + async def pred(ctx): + return await check_permissions(ctx, perms, check=check) + + return commands.check(pred) + + +async def check_guild_permissions(ctx, perms, *, check=all): + is_owner = await ctx.bot.is_owner(ctx.author) + if is_owner: + return True + + if ctx.guild is None: + return False + + resolved = ctx.author.guild_permissions + return check(getattr(resolved, name, None) == value for name, value in + perms.items()) + + +def has_guild_permissions(*, check=all, **perms): + async def pred(ctx): + return await check_guild_permissions(ctx, perms, check=check) + + return commands.check(pred) + + +# These do not take channel overrides into account + + +def is_mod(): + async def pred(ctx): + return await check_guild_permissions(ctx, {'manage_guild': True}) + + return commands.check(pred) + + +def is_admin(): + async def pred(ctx): + return await check_guild_permissions(ctx, {'administrator': True}) + + return commands.check(pred) + + +def mod_or_permissions(**perms): + perms['manage_guild'] = True + + async def predicate(ctx): + return await check_guild_permissions(ctx, perms, check=any) + + return commands.check(predicate) + + +def admin_or_permissions(**perms): + perms['administrator'] = True + + async def predicate(ctx): + return await check_guild_permissions(ctx, perms, check=any) + + return commands.check(predicate) + + +def is_in_guilds(*guild_ids): + def predicate(ctx): + guild = ctx.guild + if guild is None: + return False + return guild.id in guild_ids + + return commands.check(predicate) + + +def get_user(message, user): + try: + member = message.mentions[0] + except: + member = message.guild.get_member_named(user) + if not member: + try: + member = message.guild.get_member(int(user)) + except ValueError: + pass + if not member: + return None + return member + + +def check_date(date: str): + if len(date) == 1: + return f"0{date}" + else: + return date diff --git a/cogs/utils/cli_colors.py b/cogs/utils/cli_colors.py index 2dd3466..7b15e1e 100755 --- a/cogs/utils/cli_colors.py +++ b/cogs/utils/cli_colors.py @@ -1,46 +1,46 @@ -class text_colors: - BLACK = '\033[30m' - RED = '\033[31m' - GREEN = '\033[32m' - YELLOW = '\033[33m' - BLUE = '\033[34m' - MAGENTA = '\033[35m' - CYAN = '\033[36m' - LIGHT_GRAY = '\033[37m' - DARK_GRAY = '\033[90m' - LIGHT_RED = '\033[91m' - LIGHT_GREEN = '\033[92m' - LIGHT_YELLOW = '\033[93m' - LIGHT_BLUE = '\033[94m' - LIGHT_MAGENTA = '\033[95m' - LIGHT_CYAN = '\033[96m' - WHITE = '\033[97m' - - -class bg_colors: - BLACK = '\033[40m' - RED = '\033[41m' - GREEN = '\033[42m' - YELLOW = '\033[43m' - BLUE = '\033[44m' - MAGENTA = '\033[45m' - CYAN = '\033[46m' - LIGHT_GRAY = '\033[47m' - DARK_GRAY = '\033[100m' - LIGHT_RED = '\033[101m' - LIGHT_GREEN = '\033[102m' - LIGHT_YELLOW = '\033[103m' - LIGHT_BLUE = '\033[104m' - LIGHT_MAGENTA = '\033[105m' - LIGHT_CYAN = '\033[106m' - WHITE = '\033[107m' - - -class text_style: - BOLD = '\033[1m' - DIM = '\033[2m' - UNDERLINE = '\033[4m' - BLINK = '\033[5m' - - -ENDC = '\033[0m' +class text_colors: + BLACK = '\033[30m' + RED = '\033[31m' + GREEN = '\033[32m' + YELLOW = '\033[33m' + BLUE = '\033[34m' + MAGENTA = '\033[35m' + CYAN = '\033[36m' + LIGHT_GRAY = '\033[37m' + DARK_GRAY = '\033[90m' + LIGHT_RED = '\033[91m' + LIGHT_GREEN = '\033[92m' + LIGHT_YELLOW = '\033[93m' + LIGHT_BLUE = '\033[94m' + LIGHT_MAGENTA = '\033[95m' + LIGHT_CYAN = '\033[96m' + WHITE = '\033[97m' + + +class bg_colors: + BLACK = '\033[40m' + RED = '\033[41m' + GREEN = '\033[42m' + YELLOW = '\033[43m' + BLUE = '\033[44m' + MAGENTA = '\033[45m' + CYAN = '\033[46m' + LIGHT_GRAY = '\033[47m' + DARK_GRAY = '\033[100m' + LIGHT_RED = '\033[101m' + LIGHT_GREEN = '\033[102m' + LIGHT_YELLOW = '\033[103m' + LIGHT_BLUE = '\033[104m' + LIGHT_MAGENTA = '\033[105m' + LIGHT_CYAN = '\033[106m' + WHITE = '\033[107m' + + +class text_style: + BOLD = '\033[1m' + DIM = '\033[2m' + UNDERLINE = '\033[4m' + BLINK = '\033[5m' + + +ENDC = '\033[0m' diff --git a/cogs/utils/db.py b/cogs/utils/db.py index 502d11a..47fcc6f 100755 --- a/cogs/utils/db.py +++ b/cogs/utils/db.py @@ -1,29 +1,29 @@ -import pymysql - - -def connect_to_db(self): - mysqlHost = self.bot.config.mysql["host"] - mysqlUser = self.bot.config.mysql["username"] - mysqlPass = self.bot.config.mysql["password"] - mysqlDB = self.bot.config.mysql["dbname"] - - try: - return pymysql.connect(host=mysqlHost, user=mysqlUser, - passwd=mysqlPass, db=mysqlDB, charset='utf8') - except KeyError: - print( - "Rest in peperoni, Impossible de se connecter a la base de données.") - print(str(KeyError)) - return - - -def reconnect_to_db(self): - if not self.conn: - mysqlHost = self.bot.config.mysql["host"] - mysqlUser = self.bot.config.mysql["username"] - mysqlPass = self.bot.config.mysql["password"] - mysqlDB = self.bot.config.mysql["dbname"] - - return pymysql.connect(host=mysqlHost, user=mysqlUser, - passwd=mysqlPass, db=mysqlDB, charset='utf8') - return self.conn +import pymysql + + +def connect_to_db(self): + mysqlHost = self.bot.config.mysql["host"] + mysqlUser = self.bot.config.mysql["username"] + mysqlPass = self.bot.config.mysql["password"] + mysqlDB = self.bot.config.mysql["dbname"] + + try: + return pymysql.connect(host=mysqlHost, user=mysqlUser, + passwd=mysqlPass, db=mysqlDB, charset='utf8') + except KeyError: + print( + "Rest in peperoni, Impossible de se connecter a la base de données.") + print(str(KeyError)) + return + + +def reconnect_to_db(self): + if not self.conn: + mysqlHost = self.bot.config.mysql["host"] + mysqlUser = self.bot.config.mysql["username"] + mysqlPass = self.bot.config.mysql["password"] + mysqlDB = self.bot.config.mysql["dbname"] + + return pymysql.connect(host=mysqlHost, user=mysqlUser, + passwd=mysqlPass, db=mysqlDB, charset='utf8') + return self.conn diff --git a/cogs/utils/formats.py b/cogs/utils/formats.py index d483dac..32cb9f7 100755 --- a/cogs/utils/formats.py +++ b/cogs/utils/formats.py @@ -1,75 +1,75 @@ -async def entry_to_code(bot, entries): - width = max(map(lambda t: len(t[0]), entries)) - output = ['```'] - fmt = '{0:<{width}}: {1}' - for name, entry in entries: - output.append(fmt.format(name, entry, width=width)) - output.append('```') - await bot.say('\n'.join(output)) - -import datetime - -async def indented_entry_to_code(bot, entries): - width = max(map(lambda t: len(t[0]), entries)) - output = ['```'] - fmt = '\u200b{0:>{width}}: {1}' - for name, entry in entries: - output.append(fmt.format(name, entry, width=width)) - output.append('```') - await bot.say('\n'.join(output)) - -async def too_many_matches(bot, msg, matches, entry): - check = lambda m: m.content.isdigit() - await bot.say('There are too many matches... Which one did you mean? **Only say the number**.') - await bot.say('\n'.join(map(entry, enumerate(matches, 1)))) - - # only give them 3 tries. - for i in range(3): - message = await bot.wait_for_message(author=msg.author, channel=msg.channel, check=check) - index = int(message.content) - try: - return matches[index - 1] - except: - await bot.say('Please give me a valid number. {} tries remaining...'.format(2 - i)) - - raise ValueError('Too many tries. Goodbye.') - -class Plural: - def __init__(self, **attr): - iterator = attr.items() - self.name, self.value = next(iter(iterator)) - - def __str__(self): - v = self.value - if v > 1: - return '%s %ss' % (v, self.name) - return '%s %s' % (v, self.name) - -def human_timedelta(dt): - now = datetime.datetime.utcnow() - delta = now - dt - hours, remainder = divmod(int(delta.total_seconds()), 3600) - minutes, seconds = divmod(remainder, 60) - days, hours = divmod(hours, 24) - years, days = divmod(days, 365) - - if years: - if days: - return '%s and %s ago' % (Plural(year=years), Plural(day=days)) - return '%s ago' % Plural(year=years) - - if days: - if hours: - return '%s and %s ago' % (Plural(day=days), Plural(hour=hours)) - return '%s ago' % Plural(day=days) - - if hours: - if minutes: - return '%s and %s ago' % (Plural(hour=hours), Plural(minute=minutes)) - return '%s ago' % Plural(hour=hours) - - if minutes: - if seconds: - return '%s and %s ago' % (Plural(minute=minutes), Plural(second=seconds)) - return '%s ago' % Plural(minute=minutes) - return '%s ago' % Plural(second=seconds) +async def entry_to_code(bot, entries): + width = max(map(lambda t: len(t[0]), entries)) + output = ['```'] + fmt = '{0:<{width}}: {1}' + for name, entry in entries: + output.append(fmt.format(name, entry, width=width)) + output.append('```') + await bot.say('\n'.join(output)) + +import datetime + +async def indented_entry_to_code(bot, entries): + width = max(map(lambda t: len(t[0]), entries)) + output = ['```'] + fmt = '\u200b{0:>{width}}: {1}' + for name, entry in entries: + output.append(fmt.format(name, entry, width=width)) + output.append('```') + await bot.say('\n'.join(output)) + +async def too_many_matches(bot, msg, matches, entry): + check = lambda m: m.content.isdigit() + await bot.say('There are too many matches... Which one did you mean? **Only say the number**.') + await bot.say('\n'.join(map(entry, enumerate(matches, 1)))) + + # only give them 3 tries. + for i in range(3): + message = await bot.wait_for_message(author=msg.author, channel=msg.channel, check=check) + index = int(message.content) + try: + return matches[index - 1] + except: + await bot.say('Please give me a valid number. {} tries remaining...'.format(2 - i)) + + raise ValueError('Too many tries. Goodbye.') + +class Plural: + def __init__(self, **attr): + iterator = attr.items() + self.name, self.value = next(iter(iterator)) + + def __str__(self): + v = self.value + if v > 1: + return '%s %ss' % (v, self.name) + return '%s %s' % (v, self.name) + +def human_timedelta(dt): + now = datetime.datetime.utcnow() + delta = now - dt + hours, remainder = divmod(int(delta.total_seconds()), 3600) + minutes, seconds = divmod(remainder, 60) + days, hours = divmod(hours, 24) + years, days = divmod(days, 365) + + if years: + if days: + return '%s and %s ago' % (Plural(year=years), Plural(day=days)) + return '%s ago' % Plural(year=years) + + if days: + if hours: + return '%s and %s ago' % (Plural(day=days), Plural(hour=hours)) + return '%s ago' % Plural(day=days) + + if hours: + if minutes: + return '%s and %s ago' % (Plural(hour=hours), Plural(minute=minutes)) + return '%s ago' % Plural(hour=hours) + + if minutes: + if seconds: + return '%s and %s ago' % (Plural(minute=minutes), Plural(second=seconds)) + return '%s ago' % Plural(minute=minutes) + return '%s ago' % Plural(second=seconds) diff --git a/cogs/utils/maps.py b/cogs/utils/maps.py index c062452..b507173 100755 --- a/cogs/utils/maps.py +++ b/cogs/utils/maps.py @@ -1,147 +1,147 @@ -#!/bin/env python - -# With credit to DanielKO - -from lxml import etree -import datetime, re -import asyncio, aiohttp - -NINTENDO_LOGIN_PAGE = "https://id.nintendo.net/oauth/authorize" -SPLATNET_CALLBACK_URL = "https://splatoon.nintendo.net/users/auth/nintendo/callback" -SPLATNET_CLIENT_ID = "12af3d0a3a1f441eb900411bb50a835a" -SPLATNET_SCHEDULE_URL = "https://splatoon.nintendo.net/schedule" - -class Rotation(object): - def __init__(self): - self.start = None - self.end = None - self.turf_maps = [] - self.ranked_mode = None - self.ranked_maps = [] - - - @property - def is_over(self): - return self.end < datetime.datetime.utcnow() - - def __str__(self): - now = datetime.datetime.utcnow() - prefix = '' - if self.start > now: - minutes_delta = int((self.start - now) / datetime.timedelta(minutes=1)) - hours = int(minutes_delta / 60) - minutes = minutes_delta % 60 - prefix = '**In {0} hours and {1} minutes**:\n'.format(hours, minutes) - else: - prefix = '**Current Rotation**:\n' - - fmt = 'Turf War is {0[0]} and {0[1]}\n{1} is {2[0]} and {2[1]}' - return prefix + fmt.format(self.turf_maps, self.ranked_mode, self.ranked_maps) - -# based on https://github.com/Wiwiweb/SakuraiBot/blob/master/src/sakuraibot.py -async def get_new_splatnet_cookie(username, password): - parameters = {'client_id': SPLATNET_CLIENT_ID, - 'response_type': 'code', - 'redirect_uri': SPLATNET_CALLBACK_URL, - 'username': username, - 'password': password} - - async with aiohttp.post(NINTENDO_LOGIN_PAGE, data=parameters) as response: - cookie = response.history[-1].cookies.get('_wag_session') - if cookie is None: - print(req) - raise Exception("Couldn't retrieve cookie") - return cookie - -def parse_splatnet_time(timestr): - # time is given as "MM/DD at H:MM [p|a].m. (PDT|PST)" - # there is a case where it goes over the year, e.g. 12/31 at ... and then 1/1 at ... - # this case is kind of weird though and is currently unexpected - # it could even end up being e.g. 12/31/2015 ... and then 1/1/2016 ... - # we'll never know - - regex = r'(?P\d+)\/(?P\d+)\s*at\s*(?P\d+)\:(?P\d+)\s*(?P

a\.m\.|p\.m\.)\s*\((?P.+)\)' - m = re.match(regex, timestr.strip()) - - if m is None: - raise RuntimeError('Apparently the timestamp "{}" does not match the regex.'.format(timestr)) - - matches = m.groupdict() - tz = matches['tz'].strip().upper() - offset = None - if tz == 'PDT': - # EDT is UTC - 4, PDT is UTC - 7, so you need +7 to make it UTC - offset = +7 - elif tz == 'PST': - # EST is UTC - 5, PST is UTC - 8, so you need +8 to make it UTC - offset = +8 - else: - raise RuntimeError('Unknown timezone found: {}'.format(tz)) - - pm = matches['p'].replace('.', '') # a.m. -> am - - current_time = datetime.datetime.utcnow() - - # Kind of hacky. - fmt = "{2}/{0[month]}/{0[day]} {0[hour]}:{0[minutes]} {1}".format(matches, pm, current_time.year) - splatoon_time = datetime.datetime.strptime(fmt, '%Y/%m/%d %I:%M %p') + datetime.timedelta(hours=offset) - - # check for new year - if current_time.month == 12 and splatoon_time.month == 1: - splatoon_time.replace(current_time.year + 1) - - return splatoon_time - - -async def get_splatnet_schedule(splatnet_cookie): - cookies = {'_wag_session': splatnet_cookie} - - - """ - This is repeated 3 times: - - ... <--- figure out how to parse this -

-
- <--- turf war -
- ... ... - ... ... -
-
-
- <--- ranked -
- ... ... <--- Splat Zones, Rainmaker, Tower Control - ... ... - ... ... -
- """ - - schedule = [] - async with aiohttp.get(SPLATNET_SCHEDULE_URL, cookies=cookies, data={'locale':"en"}) as response: - text = await response.text() - root = etree.fromstring(text, etree.HTMLParser()) - stage_schedule_nodes = root.xpath("//*[@class='stage-schedule']") - stage_list_nodes = root.xpath("//*[@class='stage-list']") - - if len(stage_schedule_nodes)*2 != len(stage_list_nodes): - raise RuntimeError("SplatNet changed, need to update the parsing!") - - for sched_node in stage_schedule_nodes: - r = Rotation() - - start_time, end_time = sched_node.text.split("~") - r.start = parse_splatnet_time(start_time) - r.end = parse_splatnet_time(end_time) - - tw_list_node = stage_list_nodes.pop(0) - r.turf_maps = tw_list_node.xpath(".//*[@class='map-name']/text()") - - ranked_list_node = stage_list_nodes.pop(0) - r.ranked_maps = ranked_list_node.xpath(".//*[@class='map-name']/text()") - r.ranked_mode = ranked_list_node.xpath(".//*[@class='rule-description']/text()")[0] - - schedule.append(r) - - return schedule +#!/bin/env python + +# With credit to DanielKO + +from lxml import etree +import datetime, re +import asyncio, aiohttp + +NINTENDO_LOGIN_PAGE = "https://id.nintendo.net/oauth/authorize" +SPLATNET_CALLBACK_URL = "https://splatoon.nintendo.net/users/auth/nintendo/callback" +SPLATNET_CLIENT_ID = "12af3d0a3a1f441eb900411bb50a835a" +SPLATNET_SCHEDULE_URL = "https://splatoon.nintendo.net/schedule" + +class Rotation(object): + def __init__(self): + self.start = None + self.end = None + self.turf_maps = [] + self.ranked_mode = None + self.ranked_maps = [] + + + @property + def is_over(self): + return self.end < datetime.datetime.utcnow() + + def __str__(self): + now = datetime.datetime.utcnow() + prefix = '' + if self.start > now: + minutes_delta = int((self.start - now) / datetime.timedelta(minutes=1)) + hours = int(minutes_delta / 60) + minutes = minutes_delta % 60 + prefix = '**In {0} hours and {1} minutes**:\n'.format(hours, minutes) + else: + prefix = '**Current Rotation**:\n' + + fmt = 'Turf War is {0[0]} and {0[1]}\n{1} is {2[0]} and {2[1]}' + return prefix + fmt.format(self.turf_maps, self.ranked_mode, self.ranked_maps) + +# based on https://github.com/Wiwiweb/SakuraiBot/blob/master/src/sakuraibot.py +async def get_new_splatnet_cookie(username, password): + parameters = {'client_id': SPLATNET_CLIENT_ID, + 'response_type': 'code', + 'redirect_uri': SPLATNET_CALLBACK_URL, + 'username': username, + 'password': password} + + async with aiohttp.post(NINTENDO_LOGIN_PAGE, data=parameters) as response: + cookie = response.history[-1].cookies.get('_wag_session') + if cookie is None: + print(req) + raise Exception("Couldn't retrieve cookie") + return cookie + +def parse_splatnet_time(timestr): + # time is given as "MM/DD at H:MM [p|a].m. (PDT|PST)" + # there is a case where it goes over the year, e.g. 12/31 at ... and then 1/1 at ... + # this case is kind of weird though and is currently unexpected + # it could even end up being e.g. 12/31/2015 ... and then 1/1/2016 ... + # we'll never know + + regex = r'(?P\d+)\/(?P\d+)\s*at\s*(?P\d+)\:(?P\d+)\s*(?P

a\.m\.|p\.m\.)\s*\((?P.+)\)' + m = re.match(regex, timestr.strip()) + + if m is None: + raise RuntimeError('Apparently the timestamp "{}" does not match the regex.'.format(timestr)) + + matches = m.groupdict() + tz = matches['tz'].strip().upper() + offset = None + if tz == 'PDT': + # EDT is UTC - 4, PDT is UTC - 7, so you need +7 to make it UTC + offset = +7 + elif tz == 'PST': + # EST is UTC - 5, PST is UTC - 8, so you need +8 to make it UTC + offset = +8 + else: + raise RuntimeError('Unknown timezone found: {}'.format(tz)) + + pm = matches['p'].replace('.', '') # a.m. -> am + + current_time = datetime.datetime.utcnow() + + # Kind of hacky. + fmt = "{2}/{0[month]}/{0[day]} {0[hour]}:{0[minutes]} {1}".format(matches, pm, current_time.year) + splatoon_time = datetime.datetime.strptime(fmt, '%Y/%m/%d %I:%M %p') + datetime.timedelta(hours=offset) + + # check for new year + if current_time.month == 12 and splatoon_time.month == 1: + splatoon_time.replace(current_time.year + 1) + + return splatoon_time + + +async def get_splatnet_schedule(splatnet_cookie): + cookies = {'_wag_session': splatnet_cookie} + + + """ + This is repeated 3 times: + + ... <--- figure out how to parse this +

+
+ <--- turf war +
+ ... ... + ... ... +
+
+
+ <--- ranked +
+ ... ... <--- Splat Zones, Rainmaker, Tower Control + ... ... + ... ... +
+ """ + + schedule = [] + async with aiohttp.get(SPLATNET_SCHEDULE_URL, cookies=cookies, data={'locale':"en"}) as response: + text = await response.text() + root = etree.fromstring(text, etree.HTMLParser()) + stage_schedule_nodes = root.xpath("//*[@class='stage-schedule']") + stage_list_nodes = root.xpath("//*[@class='stage-list']") + + if len(stage_schedule_nodes)*2 != len(stage_list_nodes): + raise RuntimeError("SplatNet changed, need to update the parsing!") + + for sched_node in stage_schedule_nodes: + r = Rotation() + + start_time, end_time = sched_node.text.split("~") + r.start = parse_splatnet_time(start_time) + r.end = parse_splatnet_time(end_time) + + tw_list_node = stage_list_nodes.pop(0) + r.turf_maps = tw_list_node.xpath(".//*[@class='map-name']/text()") + + ranked_list_node = stage_list_nodes.pop(0) + r.ranked_maps = ranked_list_node.xpath(".//*[@class='map-name']/text()") + r.ranked_mode = ranked_list_node.xpath(".//*[@class='rule-description']/text()")[0] + + schedule.append(r) + + return schedule diff --git a/cogs/utils/menu.py b/cogs/utils/menu.py index ea2c809..6316ae5 100755 --- a/cogs/utils/menu.py +++ b/cogs/utils/menu.py @@ -1,140 +1,140 @@ -import asyncio - -class Menu: - """An interactive menu class for Discord.""" - - - class Submenu: - """A metaclass of the Menu class.""" - def __init__(self, name, content): - self.content = content - self.leads_to = [] - self.name = name - - def get_text(self): - text = "" - for idx, menu in enumerate(self.leads_to): - text += "[{}] {}\n".format(idx+1, menu.name) - return text - - def get_child(self, child_idx): - try: - return self.leads_to[child_idx] - except IndexError: - raise IndexError("child index out of range") - - def add_child(self, child): - self.leads_to.append(child) - - class InputSubmenu: - """A metaclass of the Menu class for submenu options that take input, instead of prompting the user to pick an option.""" - def __init__(self, name, content, input_function, leads_to): - self.content = content - self.name = name - self.input_function = input_function - self.leads_to = leads_to - - def next_child(self): - return self.leads_to - - class ChoiceSubmenu: - """A metaclass of the Menu class for submenu options for choosing an option from a list.""" - def __init__(self, name, content, options, input_function, leads_to): - self.content = content - self.name = name - self.options = options - self.input_function = input_function - self.leads_to = leads_to - - def next_child(self): - return self.leads_to - - - def __init__(self, main_page): - self.children = [] - self.main = self.Submenu("main", main_page) - - def add_child(self, child): - self.main.add_child(child) - - async def start(self, ctx): - current = self.main - menu_msg = None - while True: - output = "" - - if type(current) == self.Submenu: - if type(current.content) == str: - output += current.content + "\n" - elif callable(current.content): - current.content() - else: - raise TypeError("submenu body is not a str or function") - - if not current.leads_to: - if not menu_msg: - menu_msg = await ctx.send("```" + output + "```") - else: - await menu_msg.edit(content="```" + output + "```") - break - - output += "\n" + current.get_text() + "\n" - output += "Enter a number." - - if not menu_msg: - menu_msg = await ctx.send("```" + output + "```") - else: - await menu_msg.edit(content="```" + output + "```") - - reply = await ctx.bot.wait_for("message", check=lambda m: m.author == ctx.bot.user and m.content.isdigit() and m.channel == ctx.message.channel) - await reply.delete() - - try: - current = current.get_child(int(reply.content) - 1) - except IndexError: - print("Invalid number.") - break - - elif type(current) == self.InputSubmenu: - if type(current.content) == list: - answers = [] - for question in current.content: - await menu_msg.edit(content="```" + question + "\n\nEnter a value." + "```") - reply = await ctx.bot.wait_for("message", check=lambda m: m.author == ctx.bot.user and m.channel == ctx.message.channel) - await reply.delete() - answers.append(reply) - current.input_function(*answers) - else: - await menu_msg.edit(content="```" + current.content + "\n\nEnter a value." + "```") - reply = await ctx.bot.wait_for("message", check=lambda m: m.author == ctx.bot.user and m.channel == ctx.message.channel) - await reply.delete() - current.input_function(reply) - - if not current.leads_to: - break - - current = current.leads_to - - elif type(current) == self.ChoiceSubmenu: - result = "```" + current.content + "\n\n" - if type(current.options) == dict: - indexes = {} - for idx, option in enumerate(current.options): - result += "[{}] {}: {}\n".format(idx+1, option, current.options[option]) - indexes[idx] = option - else: - for idx, option in current.options: - result += "[{}] {}\n".format(idx+1, option) - await menu_msg.edit(content=result + "\nPick an option.```") - reply = await ctx.bot.wait_for("message", check=lambda m: m.author == ctx.bot.user and m.content.isdigit() and m.channel == ctx.message.channel) - await reply.delete() - if type(current.options) == dict: - current.input_function(reply, indexes[int(reply.content)-1]) - else: - current.input_function(reply, current.options[reply-1]) - - if not current.leads_to: - break - - current = current.leads_to +import asyncio + +class Menu: + """An interactive menu class for Discord.""" + + + class Submenu: + """A metaclass of the Menu class.""" + def __init__(self, name, content): + self.content = content + self.leads_to = [] + self.name = name + + def get_text(self): + text = "" + for idx, menu in enumerate(self.leads_to): + text += "[{}] {}\n".format(idx+1, menu.name) + return text + + def get_child(self, child_idx): + try: + return self.leads_to[child_idx] + except IndexError: + raise IndexError("child index out of range") + + def add_child(self, child): + self.leads_to.append(child) + + class InputSubmenu: + """A metaclass of the Menu class for submenu options that take input, instead of prompting the user to pick an option.""" + def __init__(self, name, content, input_function, leads_to): + self.content = content + self.name = name + self.input_function = input_function + self.leads_to = leads_to + + def next_child(self): + return self.leads_to + + class ChoiceSubmenu: + """A metaclass of the Menu class for submenu options for choosing an option from a list.""" + def __init__(self, name, content, options, input_function, leads_to): + self.content = content + self.name = name + self.options = options + self.input_function = input_function + self.leads_to = leads_to + + def next_child(self): + return self.leads_to + + + def __init__(self, main_page): + self.children = [] + self.main = self.Submenu("main", main_page) + + def add_child(self, child): + self.main.add_child(child) + + async def start(self, ctx): + current = self.main + menu_msg = None + while True: + output = "" + + if type(current) == self.Submenu: + if type(current.content) == str: + output += current.content + "\n" + elif callable(current.content): + current.content() + else: + raise TypeError("submenu body is not a str or function") + + if not current.leads_to: + if not menu_msg: + menu_msg = await ctx.send("```" + output + "```") + else: + await menu_msg.edit(content="```" + output + "```") + break + + output += "\n" + current.get_text() + "\n" + output += "Enter a number." + + if not menu_msg: + menu_msg = await ctx.send("```" + output + "```") + else: + await menu_msg.edit(content="```" + output + "```") + + reply = await ctx.bot.wait_for("message", check=lambda m: m.author == ctx.bot.user and m.content.isdigit() and m.channel == ctx.message.channel) + await reply.delete() + + try: + current = current.get_child(int(reply.content) - 1) + except IndexError: + print("Invalid number.") + break + + elif type(current) == self.InputSubmenu: + if type(current.content) == list: + answers = [] + for question in current.content: + await menu_msg.edit(content="```" + question + "\n\nEnter a value." + "```") + reply = await ctx.bot.wait_for("message", check=lambda m: m.author == ctx.bot.user and m.channel == ctx.message.channel) + await reply.delete() + answers.append(reply) + current.input_function(*answers) + else: + await menu_msg.edit(content="```" + current.content + "\n\nEnter a value." + "```") + reply = await ctx.bot.wait_for("message", check=lambda m: m.author == ctx.bot.user and m.channel == ctx.message.channel) + await reply.delete() + current.input_function(reply) + + if not current.leads_to: + break + + current = current.leads_to + + elif type(current) == self.ChoiceSubmenu: + result = "```" + current.content + "\n\n" + if type(current.options) == dict: + indexes = {} + for idx, option in enumerate(current.options): + result += "[{}] {}: {}\n".format(idx+1, option, current.options[option]) + indexes[idx] = option + else: + for idx, option in current.options: + result += "[{}] {}\n".format(idx+1, option) + await menu_msg.edit(content=result + "\nPick an option.```") + reply = await ctx.bot.wait_for("message", check=lambda m: m.author == ctx.bot.user and m.content.isdigit() and m.channel == ctx.message.channel) + await reply.delete() + if type(current.options) == dict: + current.input_function(reply, indexes[int(reply.content)-1]) + else: + current.input_function(reply, current.options[reply-1]) + + if not current.leads_to: + break + + current = current.leads_to \ No newline at end of file diff --git a/cogs/utils/paginator.py b/cogs/utils/paginator.py index 8947bad..1819ba0 100755 --- a/cogs/utils/paginator.py +++ b/cogs/utils/paginator.py @@ -1,503 +1,503 @@ -# Help paginator by Rapptz -# Edited by F4stZ4p - -import asyncio -import discord - -class CannotPaginate(Exception): - pass - -class Pages: - """Implements a paginator that queries the user for the - pagination interface. - Pages are 1-index based, not 0-index based. - If the user does not reply within 2 minutes then the pagination - interface exits automatically. - Parameters - ------------ - ctx: Context - The context of the command. - entries: List[str] - A list of entries to paginate. - per_page: int - How many entries show up per page. - show_entry_count: bool - Whether to show an entry count in the footer. - Attributes - ----------- - embed: discord.Embed - The embed object that is being used to send pagination info. - Feel free to modify this externally. Only the description, - footer fields, and colour are internally modified. - permissions: discord.Permissions - Our permissions for the channel. - """ - def __init__(self, ctx, *, entries, per_page=12, show_entry_count=True): - self.bot = ctx.bot - self.entries = entries - self.message = ctx.message - self.channel = ctx.channel - self.author = ctx.author - self.per_page = per_page - pages, left_over = divmod(len(self.entries), self.per_page) - if left_over: - pages += 1 - self.maximum_pages = pages - self.embed = discord.Embed(colour=discord.Color.green()) - self.paginating = len(entries) > per_page - self.show_entry_count = show_entry_count - self.reaction_emojis = [ - ('\N{BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}', self.first_page), - ('\N{BLACK LEFT-POINTING TRIANGLE}', self.previous_page), - ('\N{BLACK RIGHT-POINTING TRIANGLE}', self.next_page), - ('\N{BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}', self.last_page), - ('\N{INPUT SYMBOL FOR NUMBERS}', self.numbered_page ), - ('\N{BLACK SQUARE FOR STOP}', self.stop_pages), - ('\N{INFORMATION SOURCE}', self.show_help), - ] - - if ctx.guild is not None: - self.permissions = self.channel.permissions_for(ctx.guild.me) - else: - self.permissions = self.channel.permissions_for(ctx.bot.user) - - if not self.permissions.embed_links: - raise CannotPaginate('Bot does not have embed links permission.') - - if not self.permissions.send_messages: - raise CannotPaginate('Bot cannot send messages.') - - if self.paginating: - # verify we can actually use the pagination session - if not self.permissions.add_reactions: - raise CannotPaginate('Bot does not have add reactions permission.') - - if not self.permissions.read_message_history: - raise CannotPaginate('Bot does not have Read Message History permission.') - - def get_page(self, page): - base = (page - 1) * self.per_page - return self.entries[base:base + self.per_page] - - async def show_page(self, page, *, first=False): - self.current_page = page - entries = self.get_page(page) - p = [] - for index, entry in enumerate(entries, 1 + ((page - 1) * self.per_page)): - p.append(f'{index}. {entry}') - - if self.maximum_pages > 1: - if self.show_entry_count: - text = f'Page {page}/{self.maximum_pages} ({len(self.entries)} entries)' - else: - text = f'Page {page}/{self.maximum_pages}' - - self.embed.set_footer(text=text) - - if not self.paginating: - self.embed.description = '\n'.join(p) - return await self.channel.send(embed=self.embed) - - if not first: - self.embed.description = '\n'.join(p) - await self.message.edit(embed=self.embed) - return - - p.append('') - p.append('Confused? React with \N{INFORMATION SOURCE} for more info.') - self.embed.description = '\n'.join(p) - self.message = await self.channel.send(embed=self.embed) - for (reaction, _) in self.reaction_emojis: - if self.maximum_pages == 2 and reaction in ('\u23ed', '\u23ee'): - # no |<< or >>| buttons if we only have two pages - # we can't forbid it if someone ends up using it but remove - # it from the default set - continue - - await self.message.add_reaction(reaction) - - async def checked_show_page(self, page): - if page != 0 and page <= self.maximum_pages: - await self.show_page(page) - - async def first_page(self): - """goes to the first page""" - await self.show_page(1) - - async def last_page(self): - """goes to the last page""" - await self.show_page(self.maximum_pages) - - async def next_page(self): - """goes to the next page""" - await self.checked_show_page(self.current_page + 1) - - async def previous_page(self): - """goes to the previous page""" - await self.checked_show_page(self.current_page - 1) - - async def show_current_page(self): - if self.paginating: - await self.show_page(self.current_page) - - async def numbered_page(self): - """lets you type a page number to go to""" - to_delete = [] - to_delete.append(await self.channel.send('What page do you want to go to?')) - - def message_check(m): - return m.author == self.author and \ - self.channel == m.channel and \ - m.content.isdigit() - - try: - msg = await self.bot.wait_for('message', check=message_check, timeout=30.0) - except asyncio.TimeoutError: - to_delete.append(await self.channel.send('Took too long.')) - await asyncio.sleep(5) - else: - page = int(msg.content) - to_delete.append(msg) - if page != 0 and page <= self.maximum_pages: - await self.show_page(page) - else: - to_delete.append(await self.channel.send(f'Invalid page given. ({page}/{self.maximum_pages})')) - await asyncio.sleep(5) - - try: - await self.channel.delete_messages(to_delete) - except Exception: - pass - - async def show_help(self): - """shows this message""" - messages = ['Welcome to the interactive paginator!\n'] - messages.append('This interactively allows you to see pages of text by navigating with ' \ - 'reactions. They are as follows:\n') - - for (emoji, func) in self.reaction_emojis: - messages.append(f'{emoji} {func.__doc__}') - - self.embed.description = '\n'.join(messages) - self.embed.clear_fields() - self.embed.set_footer(text=f'We were on page {self.current_page} before this message.') - await self.message.edit(embed=self.embed) - - async def go_back_to_current_page(): - await asyncio.sleep(60.0) - await self.show_current_page() - - self.bot.loop.create_task(go_back_to_current_page()) - - async def stop_pages(self): - """stops the interactive pagination session""" - await self.message.delete() - self.paginating = False - - def react_check(self, reaction, user): - if user is None or user.id != self.author.id: - return False - - if reaction.message.id != self.message.id: - return False - - for (emoji, func) in self.reaction_emojis: - if reaction.emoji == emoji: - self.match = func - return True - return False - - async def paginate(self): - """Actually paginate the entries and run the interactive loop if necessary.""" - first_page = self.show_page(1, first=True) - if not self.paginating: - await first_page - else: - # allow us to react to reactions right away if we're paginating - self.bot.loop.create_task(first_page) - - while self.paginating: - try: - reaction, user = await self.bot.wait_for('reaction_add', check=self.react_check, timeout=120.0) - except asyncio.TimeoutError: - self.paginating = False - try: - await self.message.clear_reactions() - except: - pass - finally: - break - - try: - await self.message.remove_reaction(reaction, user) - except: - pass # can't remove it so don't bother doing so - - await self.match() - -class FieldPages(Pages): - """Similar to Pages except entries should be a list of - tuples having (key, value) to show as embed fields instead. - """ - async def show_page(self, page, *, first=False): - self.current_page = page - entries = self.get_page(page) - - self.embed.clear_fields() - self.embed.description = discord.Embed.Empty - - for key, value in entries: - self.embed.add_field(name=key, value=value, inline=False) - - if self.maximum_pages > 1: - if self.show_entry_count: - text = f'Page {page}/{self.maximum_pages} ({len(self.entries)} entries)' - else: - text = f'Page {page}/{self.maximum_pages}' - - self.embed.set_footer(text=text) - - if not self.paginating: - return await self.channel.send(embed=self.embed) - - if not first: - await self.message.edit(embed=self.embed) - return - - self.message = await self.channel.send(embed=self.embed) - for (reaction, _) in self.reaction_emojis: - if self.maximum_pages == 2 and reaction in ('\u23ed', '\u23ee'): - # no |<< or >>| buttons if we only have two pages - # we can't forbid it if someone ends up using it but remove - # it from the default set - continue - - await self.message.add_reaction(reaction) - -import itertools -import inspect -import re - -# ?help -# ?help Cog -# ?help command -# -> could be a subcommand - -_mention = re.compile(r'<@\!?([0-9]{1,19})>') - -def cleanup_prefix(bot, prefix): - m = _mention.match(prefix) - if m: - user = bot.get_user(int(m.group(1))) - if user: - return f'@{user.name} ' - return prefix - -async def _can_run(cmd, ctx): - try: - return await cmd.can_run(ctx) - except: - return False - -def _command_signature(cmd): - # this is modified from discord.py source - # which I wrote myself lmao - - result = [cmd.qualified_name] - if cmd.usage: - result.append(cmd.usage) - return ' '.join(result) - - params = cmd.clean_params - if not params: - return ' '.join(result) - - for name, param in params.items(): - if param.default is not param.empty: - # We don't want None or '' to trigger the [name=value] case and instead it should - # do [name] since [name=None] or [name=] are not exactly useful for the user. - should_print = param.default if isinstance(param.default, str) else param.default is not None - if should_print: - result.append(f'[{name}={param.default!r}]') - else: - result.append(f'[{name}]') - elif param.kind == param.VAR_POSITIONAL: - result.append(f'[{name}...]') - else: - result.append(f'<{name}>') - - return ' '.join(result) - -class HelpPaginator(Pages): - def __init__(self, ctx, entries, *, per_page=4): - super().__init__(ctx, entries=entries, per_page=per_page) - self.reaction_emojis.append(('\N{WHITE QUESTION MARK ORNAMENT}', self.show_bot_help)) - self.total = len(entries) - - @classmethod - async def from_cog(cls, ctx, cog): - cog_name = cog.__class__.__name__ - - # get the commands - entries = sorted(ctx.bot.get_cog(cog_name).get_commands(), key=lambda c: c.name) - - # remove the ones we can't run - entries = [cmd for cmd in entries if (await _can_run(cmd, ctx)) and not cmd.hidden] - - self = cls(ctx, entries) - self.title = f'{cog_name} Commands' - self.description = inspect.getdoc(cog) - self.prefix = cleanup_prefix(ctx.bot, ctx.prefix) - - return self - - @classmethod - async def from_command(cls, ctx, command): - try: - entries = sorted(command.commands, key=lambda c: c.name) - except AttributeError: - entries = [] - else: - entries = [cmd for cmd in entries if (await _can_run(cmd, ctx)) and not cmd.hidden] - - self = cls(ctx, entries) - self.title = command.signature - - if command.description: - self.description = f'{command.description}\n\n{command.help}' - else: - self.description = command.help or 'No help given.' - - self.prefix = cleanup_prefix(ctx.bot, ctx.prefix) - return self - - @classmethod - async def from_bot(cls, ctx): - def key(c): - return c.cog_name or '\u200bMisc' - - entries = sorted(ctx.bot.commands, key=key) - nested_pages = [] - per_page = 9 - - # 0: (cog, desc, commands) (max len == 9) - # 1: (cog, desc, commands) (max len == 9) - # ... - - for cog, commands in itertools.groupby(entries, key=key): - plausible = [cmd for cmd in commands if (await _can_run(cmd, ctx)) and not cmd.hidden] - if len(plausible) == 0: - continue - - description = ctx.bot.get_cog(cog) - if description is None: - description = discord.Embed.Empty - else: - description = inspect.getdoc(description) or discord.Embed.Empty - - nested_pages.extend((cog, description, plausible[i:i + per_page]) for i in range(0, len(plausible), per_page)) - - self = cls(ctx, nested_pages, per_page=1) # this forces the pagination session - self.prefix = cleanup_prefix(ctx.bot, ctx.prefix) - - # swap the get_page implementation with one that supports our style of pagination - self.get_page = self.get_bot_page - self._is_bot = True - - # replace the actual total - self.total = sum(len(o) for _, _, o in nested_pages) - return self - - def get_bot_page(self, page): - cog, description, commands = self.entries[page - 1] - self.title = f'{cog} Commands' - self.description = description - return commands - - async def show_page(self, page, *, first=False): - self.current_page = page - entries = self.get_page(page) - - self.embed.clear_fields() - self.embed.description = self.description - self.embed.title = self.title - - if hasattr(self, '_is_bot'): - value ='Check the bot source: **[GitHub Link](https://github.com/F4stZ4p/DJ5n4k3/)**' - self.embed.add_field(name='**GitHub**', value=value, inline=False) - - self.embed.set_footer(text=f'Use "{self.prefix}help command" for more info on a command.') - - signature = _command_signature - - for entry in entries: - self.embed.add_field(name=signature(entry), value=entry.short_doc or "No help given", inline=False) - - if self.maximum_pages: - self.embed.set_author(name=f'Page {page}/{self.maximum_pages} ({self.total} commands)') - - if not self.paginating: - return await self.channel.send(embed=self.embed) - - if not first: - await self.message.edit(embed=self.embed) - return - - self.message = await self.channel.send(embed=self.embed) - for (reaction, _) in self.reaction_emojis: - if self.maximum_pages == 2 and reaction in ('\u23ed', '\u23ee'): - # no |<< or >>| buttons if we only have two pages - # we can't forbid it if someone ends up using it but remove - # it from the default set - continue - - await self.message.add_reaction(reaction) - - async def show_help(self): - """shows this message""" - - self.embed.title = 'Paginator help' - self.embed.description = 'Hello! Welcome to the help page.' - - messages = [f'{emoji} {func.__doc__}' for emoji, func in self.reaction_emojis] - self.embed.clear_fields() - self.embed.add_field(name='What are these reactions for?', value='\n'.join(messages), inline=False) - - self.embed.set_footer(text=f'We were on page {self.current_page} before this message.') - await self.message.edit(embed=self.embed) - - async def go_back_to_current_page(): - await asyncio.sleep(30.0) - await self.show_current_page() - - self.bot.loop.create_task(go_back_to_current_page()) - - async def show_bot_help(self): - """shows how to use the bot""" - - self.embed.title = 'Using the bot' - self.embed.description = 'Hello! Welcome to the help page.' - self.embed.clear_fields() - - entries = ( - ('', 'This means the argument is __**required**__.'), - ('[argument]', 'This means the argument is __**optional**__.'), - ('[A|B]', 'This means the it can be __**either A or B**__.'), - ('[argument...]', 'This means you can have multiple arguments.\n' \ - 'Now that you know the basics, it should be noted that...\n' \ - '__**You do not type in the brackets!**__') - ) - - self.embed.add_field(name='How do I use this bot?', value='Reading the bot signature is pretty simple.') - - for name, value in entries: - self.embed.add_field(name=name, value=value, inline=False) - - self.embed.set_footer(text=f'We were on page {self.current_page} before this message.') - await self.message.edit(embed=self.embed) - - async def go_back_to_current_page(): - await asyncio.sleep(30.0) - await self.show_current_page() - +# Help paginator by Rapptz +# Edited by F4stZ4p + +import asyncio +import discord + +class CannotPaginate(Exception): + pass + +class Pages: + """Implements a paginator that queries the user for the + pagination interface. + Pages are 1-index based, not 0-index based. + If the user does not reply within 2 minutes then the pagination + interface exits automatically. + Parameters + ------------ + ctx: Context + The context of the command. + entries: List[str] + A list of entries to paginate. + per_page: int + How many entries show up per page. + show_entry_count: bool + Whether to show an entry count in the footer. + Attributes + ----------- + embed: discord.Embed + The embed object that is being used to send pagination info. + Feel free to modify this externally. Only the description, + footer fields, and colour are internally modified. + permissions: discord.Permissions + Our permissions for the channel. + """ + def __init__(self, ctx, *, entries, per_page=12, show_entry_count=True): + self.bot = ctx.bot + self.entries = entries + self.message = ctx.message + self.channel = ctx.channel + self.author = ctx.author + self.per_page = per_page + pages, left_over = divmod(len(self.entries), self.per_page) + if left_over: + pages += 1 + self.maximum_pages = pages + self.embed = discord.Embed(colour=discord.Color.green()) + self.paginating = len(entries) > per_page + self.show_entry_count = show_entry_count + self.reaction_emojis = [ + ('\N{BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}', self.first_page), + ('\N{BLACK LEFT-POINTING TRIANGLE}', self.previous_page), + ('\N{BLACK RIGHT-POINTING TRIANGLE}', self.next_page), + ('\N{BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}', self.last_page), + ('\N{INPUT SYMBOL FOR NUMBERS}', self.numbered_page ), + ('\N{BLACK SQUARE FOR STOP}', self.stop_pages), + ('\N{INFORMATION SOURCE}', self.show_help), + ] + + if ctx.guild is not None: + self.permissions = self.channel.permissions_for(ctx.guild.me) + else: + self.permissions = self.channel.permissions_for(ctx.bot.user) + + if not self.permissions.embed_links: + raise CannotPaginate('Bot does not have embed links permission.') + + if not self.permissions.send_messages: + raise CannotPaginate('Bot cannot send messages.') + + if self.paginating: + # verify we can actually use the pagination session + if not self.permissions.add_reactions: + raise CannotPaginate('Bot does not have add reactions permission.') + + if not self.permissions.read_message_history: + raise CannotPaginate('Bot does not have Read Message History permission.') + + def get_page(self, page): + base = (page - 1) * self.per_page + return self.entries[base:base + self.per_page] + + async def show_page(self, page, *, first=False): + self.current_page = page + entries = self.get_page(page) + p = [] + for index, entry in enumerate(entries, 1 + ((page - 1) * self.per_page)): + p.append(f'{index}. {entry}') + + if self.maximum_pages > 1: + if self.show_entry_count: + text = f'Page {page}/{self.maximum_pages} ({len(self.entries)} entries)' + else: + text = f'Page {page}/{self.maximum_pages}' + + self.embed.set_footer(text=text) + + if not self.paginating: + self.embed.description = '\n'.join(p) + return await self.channel.send(embed=self.embed) + + if not first: + self.embed.description = '\n'.join(p) + await self.message.edit(embed=self.embed) + return + + p.append('') + p.append('Confused? React with \N{INFORMATION SOURCE} for more info.') + self.embed.description = '\n'.join(p) + self.message = await self.channel.send(embed=self.embed) + for (reaction, _) in self.reaction_emojis: + if self.maximum_pages == 2 and reaction in ('\u23ed', '\u23ee'): + # no |<< or >>| buttons if we only have two pages + # we can't forbid it if someone ends up using it but remove + # it from the default set + continue + + await self.message.add_reaction(reaction) + + async def checked_show_page(self, page): + if page != 0 and page <= self.maximum_pages: + await self.show_page(page) + + async def first_page(self): + """goes to the first page""" + await self.show_page(1) + + async def last_page(self): + """goes to the last page""" + await self.show_page(self.maximum_pages) + + async def next_page(self): + """goes to the next page""" + await self.checked_show_page(self.current_page + 1) + + async def previous_page(self): + """goes to the previous page""" + await self.checked_show_page(self.current_page - 1) + + async def show_current_page(self): + if self.paginating: + await self.show_page(self.current_page) + + async def numbered_page(self): + """lets you type a page number to go to""" + to_delete = [] + to_delete.append(await self.channel.send('What page do you want to go to?')) + + def message_check(m): + return m.author == self.author and \ + self.channel == m.channel and \ + m.content.isdigit() + + try: + msg = await self.bot.wait_for('message', check=message_check, timeout=30.0) + except asyncio.TimeoutError: + to_delete.append(await self.channel.send('Took too long.')) + await asyncio.sleep(5) + else: + page = int(msg.content) + to_delete.append(msg) + if page != 0 and page <= self.maximum_pages: + await self.show_page(page) + else: + to_delete.append(await self.channel.send(f'Invalid page given. ({page}/{self.maximum_pages})')) + await asyncio.sleep(5) + + try: + await self.channel.delete_messages(to_delete) + except Exception: + pass + + async def show_help(self): + """shows this message""" + messages = ['Welcome to the interactive paginator!\n'] + messages.append('This interactively allows you to see pages of text by navigating with ' \ + 'reactions. They are as follows:\n') + + for (emoji, func) in self.reaction_emojis: + messages.append(f'{emoji} {func.__doc__}') + + self.embed.description = '\n'.join(messages) + self.embed.clear_fields() + self.embed.set_footer(text=f'We were on page {self.current_page} before this message.') + await self.message.edit(embed=self.embed) + + async def go_back_to_current_page(): + await asyncio.sleep(60.0) + await self.show_current_page() + + self.bot.loop.create_task(go_back_to_current_page()) + + async def stop_pages(self): + """stops the interactive pagination session""" + await self.message.delete() + self.paginating = False + + def react_check(self, reaction, user): + if user is None or user.id != self.author.id: + return False + + if reaction.message.id != self.message.id: + return False + + for (emoji, func) in self.reaction_emojis: + if reaction.emoji == emoji: + self.match = func + return True + return False + + async def paginate(self): + """Actually paginate the entries and run the interactive loop if necessary.""" + first_page = self.show_page(1, first=True) + if not self.paginating: + await first_page + else: + # allow us to react to reactions right away if we're paginating + self.bot.loop.create_task(first_page) + + while self.paginating: + try: + reaction, user = await self.bot.wait_for('reaction_add', check=self.react_check, timeout=120.0) + except asyncio.TimeoutError: + self.paginating = False + try: + await self.message.clear_reactions() + except: + pass + finally: + break + + try: + await self.message.remove_reaction(reaction, user) + except: + pass # can't remove it so don't bother doing so + + await self.match() + +class FieldPages(Pages): + """Similar to Pages except entries should be a list of + tuples having (key, value) to show as embed fields instead. + """ + async def show_page(self, page, *, first=False): + self.current_page = page + entries = self.get_page(page) + + self.embed.clear_fields() + self.embed.description = discord.Embed.Empty + + for key, value in entries: + self.embed.add_field(name=key, value=value, inline=False) + + if self.maximum_pages > 1: + if self.show_entry_count: + text = f'Page {page}/{self.maximum_pages} ({len(self.entries)} entries)' + else: + text = f'Page {page}/{self.maximum_pages}' + + self.embed.set_footer(text=text) + + if not self.paginating: + return await self.channel.send(embed=self.embed) + + if not first: + await self.message.edit(embed=self.embed) + return + + self.message = await self.channel.send(embed=self.embed) + for (reaction, _) in self.reaction_emojis: + if self.maximum_pages == 2 and reaction in ('\u23ed', '\u23ee'): + # no |<< or >>| buttons if we only have two pages + # we can't forbid it if someone ends up using it but remove + # it from the default set + continue + + await self.message.add_reaction(reaction) + +import itertools +import inspect +import re + +# ?help +# ?help Cog +# ?help command +# -> could be a subcommand + +_mention = re.compile(r'<@\!?([0-9]{1,19})>') + +def cleanup_prefix(bot, prefix): + m = _mention.match(prefix) + if m: + user = bot.get_user(int(m.group(1))) + if user: + return f'@{user.name} ' + return prefix + +async def _can_run(cmd, ctx): + try: + return await cmd.can_run(ctx) + except: + return False + +def _command_signature(cmd): + # this is modified from discord.py source + # which I wrote myself lmao + + result = [cmd.qualified_name] + if cmd.usage: + result.append(cmd.usage) + return ' '.join(result) + + params = cmd.clean_params + if not params: + return ' '.join(result) + + for name, param in params.items(): + if param.default is not param.empty: + # We don't want None or '' to trigger the [name=value] case and instead it should + # do [name] since [name=None] or [name=] are not exactly useful for the user. + should_print = param.default if isinstance(param.default, str) else param.default is not None + if should_print: + result.append(f'[{name}={param.default!r}]') + else: + result.append(f'[{name}]') + elif param.kind == param.VAR_POSITIONAL: + result.append(f'[{name}...]') + else: + result.append(f'<{name}>') + + return ' '.join(result) + +class HelpPaginator(Pages): + def __init__(self, ctx, entries, *, per_page=4): + super().__init__(ctx, entries=entries, per_page=per_page) + self.reaction_emojis.append(('\N{WHITE QUESTION MARK ORNAMENT}', self.show_bot_help)) + self.total = len(entries) + + @classmethod + async def from_cog(cls, ctx, cog): + cog_name = cog.__class__.__name__ + + # get the commands + entries = sorted(ctx.bot.get_cog(cog_name).get_commands(), key=lambda c: c.name) + + # remove the ones we can't run + entries = [cmd for cmd in entries if (await _can_run(cmd, ctx)) and not cmd.hidden] + + self = cls(ctx, entries) + self.title = f'{cog_name} Commands' + self.description = inspect.getdoc(cog) + self.prefix = cleanup_prefix(ctx.bot, ctx.prefix) + + return self + + @classmethod + async def from_command(cls, ctx, command): + try: + entries = sorted(command.commands, key=lambda c: c.name) + except AttributeError: + entries = [] + else: + entries = [cmd for cmd in entries if (await _can_run(cmd, ctx)) and not cmd.hidden] + + self = cls(ctx, entries) + self.title = command.signature + + if command.description: + self.description = f'{command.description}\n\n{command.help}' + else: + self.description = command.help or 'No help given.' + + self.prefix = cleanup_prefix(ctx.bot, ctx.prefix) + return self + + @classmethod + async def from_bot(cls, ctx): + def key(c): + return c.cog_name or '\u200bMisc' + + entries = sorted(ctx.bot.commands, key=key) + nested_pages = [] + per_page = 9 + + # 0: (cog, desc, commands) (max len == 9) + # 1: (cog, desc, commands) (max len == 9) + # ... + + for cog, commands in itertools.groupby(entries, key=key): + plausible = [cmd for cmd in commands if (await _can_run(cmd, ctx)) and not cmd.hidden] + if len(plausible) == 0: + continue + + description = ctx.bot.get_cog(cog) + if description is None: + description = discord.Embed.Empty + else: + description = inspect.getdoc(description) or discord.Embed.Empty + + nested_pages.extend((cog, description, plausible[i:i + per_page]) for i in range(0, len(plausible), per_page)) + + self = cls(ctx, nested_pages, per_page=1) # this forces the pagination session + self.prefix = cleanup_prefix(ctx.bot, ctx.prefix) + + # swap the get_page implementation with one that supports our style of pagination + self.get_page = self.get_bot_page + self._is_bot = True + + # replace the actual total + self.total = sum(len(o) for _, _, o in nested_pages) + return self + + def get_bot_page(self, page): + cog, description, commands = self.entries[page - 1] + self.title = f'{cog} Commands' + self.description = description + return commands + + async def show_page(self, page, *, first=False): + self.current_page = page + entries = self.get_page(page) + + self.embed.clear_fields() + self.embed.description = self.description + self.embed.title = self.title + + if hasattr(self, '_is_bot'): + value ='Check the bot source: **[GitHub Link](https://github.com/F4stZ4p/DJ5n4k3/)**' + self.embed.add_field(name='**GitHub**', value=value, inline=False) + + self.embed.set_footer(text=f'Use "{self.prefix}help command" for more info on a command.') + + signature = _command_signature + + for entry in entries: + self.embed.add_field(name=signature(entry), value=entry.short_doc or "No help given", inline=False) + + if self.maximum_pages: + self.embed.set_author(name=f'Page {page}/{self.maximum_pages} ({self.total} commands)') + + if not self.paginating: + return await self.channel.send(embed=self.embed) + + if not first: + await self.message.edit(embed=self.embed) + return + + self.message = await self.channel.send(embed=self.embed) + for (reaction, _) in self.reaction_emojis: + if self.maximum_pages == 2 and reaction in ('\u23ed', '\u23ee'): + # no |<< or >>| buttons if we only have two pages + # we can't forbid it if someone ends up using it but remove + # it from the default set + continue + + await self.message.add_reaction(reaction) + + async def show_help(self): + """shows this message""" + + self.embed.title = 'Paginator help' + self.embed.description = 'Hello! Welcome to the help page.' + + messages = [f'{emoji} {func.__doc__}' for emoji, func in self.reaction_emojis] + self.embed.clear_fields() + self.embed.add_field(name='What are these reactions for?', value='\n'.join(messages), inline=False) + + self.embed.set_footer(text=f'We were on page {self.current_page} before this message.') + await self.message.edit(embed=self.embed) + + async def go_back_to_current_page(): + await asyncio.sleep(30.0) + await self.show_current_page() + + self.bot.loop.create_task(go_back_to_current_page()) + + async def show_bot_help(self): + """shows how to use the bot""" + + self.embed.title = 'Using the bot' + self.embed.description = 'Hello! Welcome to the help page.' + self.embed.clear_fields() + + entries = ( + ('', 'This means the argument is __**required**__.'), + ('[argument]', 'This means the argument is __**optional**__.'), + ('[A|B]', 'This means the it can be __**either A or B**__.'), + ('[argument...]', 'This means you can have multiple arguments.\n' \ + 'Now that you know the basics, it should be noted that...\n' \ + '__**You do not type in the brackets!**__') + ) + + self.embed.add_field(name='How do I use this bot?', value='Reading the bot signature is pretty simple.') + + for name, value in entries: + self.embed.add_field(name=name, value=value, inline=False) + + self.embed.set_footer(text=f'We were on page {self.current_page} before this message.') + await self.message.edit(embed=self.embed) + + async def go_back_to_current_page(): + await asyncio.sleep(30.0) + await self.show_current_page() + self.bot.loop.create_task(go_back_to_current_page()) \ No newline at end of file diff --git a/cogs/vocal.py b/cogs/vocal.py index fc21169..e233038 100755 --- a/cogs/vocal.py +++ b/cogs/vocal.py @@ -1,113 +1,113 @@ -import asyncio -import os -import re -import subprocess -import uuid - -import discord -from discord.ext import commands -from gtts import gTTS - - -class Vocal(commands.Cog): - - def __init__(self, bot): - self.bot = bot - self.playing = False - self.author = None - self.voice = None - - """---------------------------------------------------------------------""" - - @staticmethod - def get_duration(file): - popen = subprocess.Popen(("ffprobe", - "-show_entries", - "format=duration", - "-i", file), - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - output, err = popen.communicate() - match = re.search(r"[-+]?\d*\.\d+|\d+", str(output)) - return float(match.group()) - - @commands.command(name="voc", no_pm=True, pass_context=True) - async def _voc(self, ctx, *, message=""): - if message == "": - await ctx.send("Veuillez écrire un message...") - return - if message == "stop_playing" \ - and ( - ctx.author.id == self.author.id - or ctx.message.channel.permissions_for( - ctx.message.author - ).administrator is True - ) \ - and self.playing is True: - - await ctx.send('stop') - await self.voice.disconnect() - self.playing = False - return - - if self.playing is True: - await ctx.send("Je suis déja en train de parler," - " merci de réenvoyer ton message" - " quand j'aurais fini.") - return - - user = ctx.author - self.author = user - - if user.voice: - self.playing = True - filename = f"data/tmp/voc/{uuid.uuid1()}.mp3" - lang = [x for x in message.split(" ") if x.startswith("lang=")] - - loading = await ctx.send("*Chargement du message en cours...*") - - if lang: - choice_lang = (lang[0])[5:] - message = f"{user.display_name} à dit: {message.strip(lang[0])}" if len(ctx.author.voice.channel.members) >= 4 else message.strip(lang[0]) - - try: - tts = gTTS( - text=message, - lang=str(choice_lang)) - except ValueError: - tts = gTTS( - text=message, - lang="fr") - await ctx.send("La langue n'est pas supportée," - " le francais a donc été choisi") - else: - message = f"{user.display_name} à dit: {message}" if len(ctx.author.voice.channel.members) >= 4 else message - tts = gTTS(text=message, - lang="fr") - - tts.save(filename) - - self.voice = await user.voice.channel.connect() - self.voice.play(discord.FFmpegPCMAudio(filename)) - counter = 0 - duration = self.get_duration(filename) - while not counter >= duration: - if self.playing: - await loading.edit( - content=f"Lecture du message de {self.author.display_name} en cours : {counter}sec/{duration}sec") - await asyncio.sleep(1) - counter += 1 - else: - break - await self.voice.disconnect() - - await loading.edit(content="Lecture terminée") - self.voice = None - os.remove(filename) - self.playing = False - else: - await ctx.send('Veuillez aller dans un channel vocal.') - - -def setup(bot): - bot.add_cog(Vocal(bot)) +import asyncio +import os +import re +import subprocess +import uuid + +import discord +from discord.ext import commands +from gtts import gTTS + + +class Vocal(commands.Cog): + + def __init__(self, bot): + self.bot = bot + self.playing = False + self.author = None + self.voice = None + + """---------------------------------------------------------------------""" + + @staticmethod + def get_duration(file): + popen = subprocess.Popen(("ffprobe", + "-show_entries", + "format=duration", + "-i", file), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + output, err = popen.communicate() + match = re.search(r"[-+]?\d*\.\d+|\d+", str(output)) + return float(match.group()) + + @commands.command(name="voc", no_pm=True, pass_context=True) + async def _voc(self, ctx, *, message=""): + if message == "": + await ctx.send("Veuillez écrire un message...") + return + if message == "stop_playing" \ + and ( + ctx.author.id == self.author.id + or ctx.message.channel.permissions_for( + ctx.message.author + ).administrator is True + ) \ + and self.playing is True: + + await ctx.send('stop') + await self.voice.disconnect() + self.playing = False + return + + if self.playing is True: + await ctx.send("Je suis déja en train de parler," + " merci de réenvoyer ton message" + " quand j'aurais fini.") + return + + user = ctx.author + self.author = user + + if user.voice: + self.playing = True + filename = f"data/tmp/voc/{uuid.uuid1()}.mp3" + lang = [x for x in message.split(" ") if x.startswith("lang=")] + + loading = await ctx.send("*Chargement du message en cours...*") + + if lang: + choice_lang = (lang[0])[5:] + message = f"{user.display_name} à dit: {message.strip(lang[0])}" if len(ctx.author.voice.channel.members) >= 4 else message.strip(lang[0]) + + try: + tts = gTTS( + text=message, + lang=str(choice_lang)) + except ValueError: + tts = gTTS( + text=message, + lang="fr") + await ctx.send("La langue n'est pas supportée," + " le francais a donc été choisi") + else: + message = f"{user.display_name} à dit: {message}" if len(ctx.author.voice.channel.members) >= 4 else message + tts = gTTS(text=message, + lang="fr") + + tts.save(filename) + + self.voice = await user.voice.channel.connect() + self.voice.play(discord.FFmpegPCMAudio(filename)) + counter = 0 + duration = self.get_duration(filename) + while not counter >= duration: + if self.playing: + await loading.edit( + content=f"Lecture du message de {self.author.display_name} en cours : {counter}sec/{duration}sec") + await asyncio.sleep(1) + counter += 1 + else: + break + await self.voice.disconnect() + + await loading.edit(content="Lecture terminée") + self.voice = None + os.remove(filename) + self.playing = False + else: + await ctx.send('Veuillez aller dans un channel vocal.') + + +def setup(bot): + bot.add_cog(Vocal(bot)) diff --git a/init.sh b/init.sh index 6ee2f0a..29a5837 100755 --- a/init.sh +++ b/init.sh @@ -1,3 +1,3 @@ -#pip install -U "https://github.com/Rapptz/discord.py/archive/rewrite.zip#egg=discord.py[voice]" -python3 -m pip install -U discord.py[voice] -python3 -m pip install -r requirements.txt +#pip install -U "https://github.com/Rapptz/discord.py/archive/rewrite.zip#egg=discord.py[voice]" +python3 -m pip install -U discord.py[voice] +python3 -m pip install -r requirements.txt diff --git a/requirements.txt b/requirements.txt index d55b962..0ffeefb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,11 @@ -pymysql -gtts -beautifulsoup4 -lxml==4.2.4 -bs4 -pytz -requests -wikipedia -pillow \ No newline at end of file +pymysql +gtts +beautifulsoup4 +lxml==4.2.4 +bs4 +pytz +requests +wikipedia +pillow +ipwhois +ipinfo \ No newline at end of file diff --git a/texts/ci-info.md b/texts/ci-info.md index af595b3..469c998 100755 --- a/texts/ci-info.md +++ b/texts/ci-info.md @@ -1,11 +1,11 @@ -La carte d'identité est un petit système dans tuxbot permetant de vous démarquer de vos amis en ayant la possibilité d'y renseigner plusieurs informations ! - -**Liste des commandes : ** --> .ci : Affiche l'aide sur les cartes d'identité --> .ci show _pseudo_ : Affiche la carte d'identité de _pseudo_ --> .ci register : Vous enregistre dans la base de donnée des cartes d'identité --> .ci setos _nom de l'os_ : Défini votre système d'exploitation --> .ci setconfig _votre configuration pc_ : Défini la configuration de votre ordinateur --> .ci setcountry : Défini votre pays --> .ci update : Met à jour votre image si vous l'avez changé --> .ci delete : Supprime votre carte d'identité +La carte d'identité est un petit système dans tuxbot permetant de vous démarquer de vos amis en ayant la possibilité d'y renseigner plusieurs informations ! + +**Liste des commandes : ** +-> .ci : Affiche l'aide sur les cartes d'identité +-> .ci show _pseudo_ : Affiche la carte d'identité de _pseudo_ +-> .ci register : Vous enregistre dans la base de donnée des cartes d'identité +-> .ci setos _nom de l'os_ : Défini votre système d'exploitation +-> .ci setconfig _votre configuration pc_ : Défini la configuration de votre ordinateur +-> .ci setcountry : Défini votre pays +-> .ci update : Met à jour votre image si vous l'avez changé +-> .ci delete : Supprime votre carte d'identité diff --git a/texts/clocks.md b/texts/clocks.md index e72f932..a4a9072 100755 --- a/texts/clocks.md +++ b/texts/clocks.md @@ -1,11 +1,11 @@ - -_Pour utiliser les horloges utilisez la commande : **clock ** ville_ --> Montreal (Canada, QC) --> Vancouver (Canada, BC) --> New-York / N-Y (U.S.A.) --> LosAngeles / L-A (U.S.A.) --> Berlin (Allemagne) --> Bern / Zurich (Suisse) --> Paris (France) --> Tokyo (Japon) --> Moscou (Russie) + +_Pour utiliser les horloges utilisez la commande : **clock ** ville_ +-> Montreal (Canada, QC) +-> Vancouver (Canada, BC) +-> New-York / N-Y (U.S.A.) +-> LosAngeles / L-A (U.S.A.) +-> Berlin (Allemagne) +-> Bern / Zurich (Suisse) +-> Paris (France) +-> Tokyo (Japon) +-> Moscou (Russie) diff --git a/texts/help.md b/texts/help.md index af4a900..71fd89c 100755 --- a/texts/help.md +++ b/texts/help.md @@ -1,39 +1,39 @@ -**Commandes utilitaires** --> .afk : Signaler son absence *(commande désactivée)* --> .back : Signaler son retour *(commande désactivée)* --> .clock _ville_: Affiche l'heure et quelques infos sur la ville en question --> .ytdiscover : Découvrir des chaines youtube --> .search _site_ _contenu_ : Fait une recherche sur un site (.search pour plus d'infos) --> .avatar _@pseudo_ : Récupère l'avatar de _@pseudo_ --> .poke _@pseudo_ : Poke _@pseudo_ --> .sondage _question_ | _reponse_ | _reponse_ | _option_ : Créer un sondage avec des réactions --> .sondage : Affiche l'aide pour la commande sondage --> .role _nomdurole_ : Ajoute/Retire le rôle en question --> .iplocalise _IP ou NDD_ : affiche la localisation et le propriétaire de l'ip (ou de l'IP lié a un nom de domaine) --> .iplocalise _IP ou NDD_ **ipv6**: affiche la localisation et le propriétaire de l'ip en forçant sur l'IPv6 (ou de l'IP lié a un nom de domaine) --> .getheaders _IP ou NDD_ : affiche les en-têtes (headers) d'une IP/Nom de domaine via HTTP/HTTPS/FTP --> .btcprice : Affiche le prix du bitcoin -[split] -**Commandes Funs** --> .joke : Affiche une blague aléatoire --> .ethylotest : Simule un ethylotest détraqué --> .pokemon : Lance un combat de pokémons --> .coin : Simule un pile ou face --> .randomcat : Affiche des image de chats :3 -[split] -**Commandes Carte d'Identité** --> .ci : Affiche l'aide sur les cartes d'identité --> .ci show _pseudo_ : Affiche la carte d'identité de _pseudo_ --> .ci register : Vous enregistre dans la base de donnée des cartes d'identité --> .ci setos _nom de l'os_ : Défini le système d'exploitation --> .ci setconfig _votre configuration pc_ : Défini la configuration de votre ordinateur --> .ci setcountry : Défini votre pays --> .ci update : Met à jour votre image si vous l'avez changé :wink: --> .ci delete : Supprime votre carte d'identité **a tous jamais** -[split] -**Commandes diverses** : --> .info : Affiche des informations sur le bot --> .help : Affiche ce message --> .clock : Affiche la liste des horloges des villes --> .ping : Ping le bot --> .git : Affiche le repos Gitea du Bot :heart: +**Commandes utilitaires** +-> .afk : Signaler son absence *(commande désactivée)* +-> .back : Signaler son retour *(commande désactivée)* +-> .clock _ville_: Affiche l'heure et quelques infos sur la ville en question +-> .ytdiscover : Découvrir des chaines youtube +-> .search _site_ _contenu_ : Fait une recherche sur un site (.search pour plus d'infos) +-> .avatar _@pseudo_ : Récupère l'avatar de _@pseudo_ +-> .poke _@pseudo_ : Poke _@pseudo_ +-> .sondage _question_ | _reponse_ | _reponse_ | _option_ : Créer un sondage avec des réactions +-> .sondage : Affiche l'aide pour la commande sondage +-> .role _nomdurole_ : Ajoute/Retire le rôle en question +-> .iplocalise _IP ou NDD_ : affiche la localisation et le propriétaire de l'ip (ou de l'IP lié a un nom de domaine) +-> .iplocalise _IP ou NDD_ **ipv6**: affiche la localisation et le propriétaire de l'ip en forçant sur l'IPv6 (ou de l'IP lié a un nom de domaine) +-> .getheaders _IP ou NDD_ : affiche les en-têtes (headers) d'une IP/Nom de domaine via HTTP/HTTPS/FTP +-> .btcprice : Affiche le prix du bitcoin +[split] +**Commandes Funs** +-> .joke : Affiche une blague aléatoire +-> .ethylotest : Simule un ethylotest détraqué +-> .pokemon : Lance un combat de pokémons +-> .coin : Simule un pile ou face +-> .randomcat : Affiche des image de chats :3 +[split] +**Commandes Carte d'Identité** +-> .ci : Affiche l'aide sur les cartes d'identité +-> .ci show _pseudo_ : Affiche la carte d'identité de _pseudo_ +-> .ci register : Vous enregistre dans la base de donnée des cartes d'identité +-> .ci setos _nom de l'os_ : Défini le système d'exploitation +-> .ci setconfig _votre configuration pc_ : Défini la configuration de votre ordinateur +-> .ci setcountry : Défini votre pays +-> .ci update : Met à jour votre image si vous l'avez changé :wink: +-> .ci delete : Supprime votre carte d'identité **a tous jamais** +[split] +**Commandes diverses** : +-> .info : Affiche des informations sur le bot +-> .help : Affiche ce message +-> .clock : Affiche la liste des horloges des villes +-> .ping : Ping le bot +-> .git : Affiche le repos Gitea du Bot :heart: diff --git a/texts/info.md b/texts/info.md index 10d096d..0797a40 100755 --- a/texts/info.md +++ b/texts/info.md @@ -1,24 +1,24 @@ - -:tools: **Développement** : - └> Outout : [outout.xyz](https://outout.xyz/) - └> Romain : [son github](http://git.gnous.eu/Romain) - └> Langage : [Python3](http://www.python.org/) - └> Api : [discord.py {3}](https://github.com/Rapptz/discord.py) - └> Discord Api : [{4}]({4}) - └> En se basant sur : [RobotDanny](https://github.com/Rapptz/RoboDanny) - -:desktop: **Hébergé sur "{2}"**: - └> OS : {0} - └> Version : {1} - -:telephone: **Contact** : - └> Discord : Outout#8406 - └> Twitter : [@outoutxyz](https://twitter.com/outouxyz) - └> Courriel : [mael@gnous.eu](mailto:mael@gnous.eu) - └> Discord : Romain#5117 - - -:link: **Serveur** : - └> Serveur GnousEU : [rejoindre](https://discord.gg/NFW3EeS) - - + +:tools: **Développement** : + └> Outout : [outout.xyz](https://outout.xyz/) + └> Romain : [son github](http://git.gnous.eu/Romain) + └> Langage : [Python3](http://www.python.org/) + └> Api : [discord.py {3}](https://github.com/Rapptz/discord.py) + └> Discord Api : [{4}]({4}) + └> En se basant sur : [RobotDanny](https://github.com/Rapptz/RoboDanny) + +:desktop: **Hébergé sur "{2}"**: + └> OS : {0} + └> Version : {1} + +:telephone: **Contact** : + └> Discord : Outout#8406 + └> Twitter : [@outoutxyz](https://twitter.com/outouxyz) + └> Courriel : [mael@gnous.eu](mailto:mael@gnous.eu) + └> Discord : Romain#5117 + + +:link: **Serveur** : + └> Serveur GnousEU : [rejoindre](https://discord.gg/NFW3EeS) + + diff --git a/texts/jokes.json b/texts/jokes.json index 305de47..40c3f56 100755 --- a/texts/jokes.json +++ b/texts/jokes.json @@ -1,15 +1,15 @@ -{ - "1": {"content": "Les hyperboles sa sert à manger des hyper-soupes :3 (Lawl!)", "author": "Crumble14 (bukkit.fr)"}, - "2": {"content": "Le comble de Windows, c’est que pour l’arrêter, il faut cliquer sur démarrer.", "author": "Keke142 (bukkit.fr)"}, - "3": {"content": "Chrome: On est le 8 avril 2016 13h02 \n Safari: On est le 8 avril 2016 13h02 \n Internet Explorer: On est le... **[Internet Explorer a cessé de fonctionner, veuillez redémarrer votre machine]**", "author": "NyoSan"}, - "4": {"content": "Il y a 10 types de personnes dans le monde, ceux qui comprennent le binaire et les autres.", "author": "Dartasen (bukkit.fr)"}, - "5": {"content": "C'est une requête SQL qui rentre dans un bar et qui s'adresse à deux tables \"Puis-je vous joindre ?\".\"", "author": "Dartasen (bukkit.fr)"}, - "6": {"content": "Combien de développeurs faut-il pour remplacer une ampoule grillée ? Aucun, c'est un problème Hardware.", "author": "Dartasen (bukkit.fr)"}, - "7": {"content": "Tu sais que tu as affaire à un développeur quand ça ne le gêne pas d'avoir un String dans l'Array.", "author": "Dartasen (bukkit.fr)"}, - "8": {"content": "Pourquoi y'a pas d'adresse windows ou linux ? Si y'a l'addresse mac !", "author": "Antho"}, - "9": {"content": "Les appareils apple ont ils une adresse personnalisée ?", "author": "Outout"}, - "10": {"content": "Le 1er janvier 1970 c'est le jour où il y a eu le plus de plantages. (cf : http://bit.ly/2rArLVe)", "author": "NyoSan"}, - "11": {"content": "Pourquoi est-ce que les girafes aiment magasiner à bas prix? Tout est une question de cou.", "author": "Maxx_Qc (bukkit.fr)"}, - "12": {"content": "``Même éteint le hackeur peut pirater l'ordi`` \"Le SuperGeek tournant sous Ubuntu (ou Windows)\"", "author": "Outout"}, - "13": {"content": "Trois ingénieurs (1 chimiste, 1 électronicien, 1 Microsoft) dans un bus roulant dans un désert. \n\n Le bus « tombe en panne » sans raison apparente, et voila les 3 gars à discuter. \n L’électronicien : je pourrais regarder les circuits et voir si quelque chose cloche. \n Le chimiste : on devrait vérifier l'essence avant. \n L’ingé Microsoft : non, on remonte dans le bus, on ferme toutes les fenêtres, et logiquement ça devrait redémarrer.", "author": "Internet"} +{ + "1": {"content": "Les hyperboles sa sert à manger des hyper-soupes :3 (Lawl!)", "author": "Crumble14 (bukkit.fr)"}, + "2": {"content": "Le comble de Windows, c’est que pour l’arrêter, il faut cliquer sur démarrer.", "author": "Keke142 (bukkit.fr)"}, + "3": {"content": "Chrome: On est le 8 avril 2016 13h02 \n Safari: On est le 8 avril 2016 13h02 \n Internet Explorer: On est le... **[Internet Explorer a cessé de fonctionner, veuillez redémarrer votre machine]**", "author": "NyoSan"}, + "4": {"content": "Il y a 10 types de personnes dans le monde, ceux qui comprennent le binaire et les autres.", "author": "Dartasen (bukkit.fr)"}, + "5": {"content": "C'est une requête SQL qui rentre dans un bar et qui s'adresse à deux tables \"Puis-je vous joindre ?\".\"", "author": "Dartasen (bukkit.fr)"}, + "6": {"content": "Combien de développeurs faut-il pour remplacer une ampoule grillée ? Aucun, c'est un problème Hardware.", "author": "Dartasen (bukkit.fr)"}, + "7": {"content": "Tu sais que tu as affaire à un développeur quand ça ne le gêne pas d'avoir un String dans l'Array.", "author": "Dartasen (bukkit.fr)"}, + "8": {"content": "Pourquoi y'a pas d'adresse windows ou linux ? Si y'a l'addresse mac !", "author": "Antho"}, + "9": {"content": "Les appareils apple ont ils une adresse personnalisée ?", "author": "Outout"}, + "10": {"content": "Le 1er janvier 1970 c'est le jour où il y a eu le plus de plantages. (cf : http://bit.ly/2rArLVe)", "author": "NyoSan"}, + "11": {"content": "Pourquoi est-ce que les girafes aiment magasiner à bas prix? Tout est une question de cou.", "author": "Maxx_Qc (bukkit.fr)"}, + "12": {"content": "``Même éteint le hackeur peut pirater l'ordi`` \"Le SuperGeek tournant sous Ubuntu (ou Windows)\"", "author": "Outout"}, + "13": {"content": "Trois ingénieurs (1 chimiste, 1 électronicien, 1 Microsoft) dans un bus roulant dans un désert. \n\n Le bus « tombe en panne » sans raison apparente, et voila les 3 gars à discuter. \n L’électronicien : je pourrais regarder les circuits et voir si quelque chose cloche. \n Le chimiste : on devrait vérifier l'essence avant. \n L’ingé Microsoft : non, on remonte dans le bus, on ferme toutes les fenêtres, et logiquement ça devrait redémarrer.", "author": "Internet"} } \ No newline at end of file diff --git a/texts/passport-info.md b/texts/passport-info.md index c3b128c..5185076 100755 --- a/texts/passport-info.md +++ b/texts/passport-info.md @@ -1,9 +1,9 @@ -Le passeport est un petit système dans tuxbot permetant de vous démarquer de vos amis en ayant la possibilité d'y renseigner plusieurs informations ! - -**Liste des commandes : ** --> .passeport : Affiche l'aide sur les cartes d'identité --> .passeport show _pseudo_ : Affiche le passeport de _pseudo_ --> .passeport config : Vous envois un message privé afin de configurer votre passeport --> .passeport background _url_ : Défini _url_ comme étant le fond d'écran de votre passeport --> .passeport thème : Definie le theme de votre passeport (`.passeport preview` envoi une image avec les 2 thèmes pour comparer) --> .passeport delete : Supprime les informations de votre carte passeport +Le passeport est un petit système dans tuxbot permetant de vous démarquer de vos amis en ayant la possibilité d'y renseigner plusieurs informations ! + +**Liste des commandes : ** +-> .passeport : Affiche l'aide sur les cartes d'identité +-> .passeport show _pseudo_ : Affiche le passeport de _pseudo_ +-> .passeport config : Vous envois un message privé afin de configurer votre passeport +-> .passeport background _url_ : Défini _url_ comme étant le fond d'écran de votre passeport +-> .passeport thème : Definie le theme de votre passeport (`.passeport preview` envoi une image avec les 2 thèmes pour comparer) +-> .passeport delete : Supprime les informations de votre carte passeport diff --git a/texts/pokemons.json b/texts/pokemons.json index 27f4b83..a00c3e8 100755 --- a/texts/pokemons.json +++ b/texts/pokemons.json @@ -1 +1 @@ -[{"Number":"001","Name":"Bulbasaur","Generation":"Generation I","About":"Bulbasaur can be seen napping in bright sunlight. There is a seed on its back. By soaking up the sun's rays, the seed grows progressively larger.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12},{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Seed Bomb","Type":"Grass","Damage":40},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"6.04kg","Maximum":"7.76kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"3km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"118 attack points.","Base Defense":"118 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Bulbasaur candies"},"Next evolution(s)":[{"Number":2,"Name":"Ivysaur"},{"Number":3,"Name":"Venusaur"}],"MaxCP":951,"MaxHP":1071},{"Number":"002","Name":"Ivysaur","Generation":"Generation I","About":"There is a bud on this Pokémon's back. To support its weight, Ivysaur's legs and trunk grow thick and strong. If it starts spending more time lying in the sunlight, it's a sign that the bud will bloom into a large flower soon.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Razor Leaf","Type":"Grass","Damage":15},{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"11.38kg","Maximum":"14.63kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"151 attack points.","Base Defense":"151 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":1,"Name":"Bulbasaur"}],"Next Evolution Requirements":{"Amount":100,"Name":"Bulbasaur candies"},"Next evolution(s)":[{"Number":3,"Name":"Venusaur"}],"MaxCP":1483,"MaxHP":1632},{"Number":"003","Name":"Venusaur","Generation":"Generation I","About":"There is a large flower on Venusaur's back. The flower is said to take on vivid colors if it gets plenty of nutrition and sunlight. The flower's aroma soothes the emotions of people.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Razor Leaf","Type":"Grass","Damage":15},{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Petal Blizzard","Type":"Grass","Damage":65},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"87.5kg","Maximum":"112.5kg"},"Height":{"Minimum":"1.75m","Maximum":"2.25m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"198 attack points.","Base Defense":"198 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":1,"Name":"Bulbasaur"},{"Number":2,"Name":"Ivysaur"}],"MaxCP":2392,"MaxHP":2580},{"Number":"004","Name":"Charmander","Generation":"Generation I","About":"The flame that burns at the tip of its tail is an indication of its emotions. The flame wavers when Charmander is enjoying itself. If the Pokémon becomes enraged, the flame burns fiercely.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Flame Burst","Type":"Fire","Damage":30},{"Name":"Flame Charge","Type":"Fire","Damage":25},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"7.44kg","Maximum":"9.56kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Medium)","Base Stamina":"78 stamina points.","Base Attack":"116 attack points.","Base Defense":"96 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Charmander candies"},"Next evolution(s)":[{"Number":5,"Name":"Charmeleon"},{"Number":6,"Name":"Charizard"}],"MaxCP":841,"MaxHP":955},{"Number":"005","Name":"Charmeleon","Generation":"Generation I","About":"Charmeleon mercilessly destroys its foes using its sharp claws. If it encounters a strong foe, it turns aggressive. In this excited state, the flame at the tip of its tail flares with a bluish white color.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Fire Punch","Type":"Fire","Damage":40},{"Name":"Flame Burst","Type":"Fire","Damage":30},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"16.63kg","Maximum":"21.38kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"3km (Medium)","Base Stamina":"116 stamina points.","Base Attack":"158 attack points.","Base Defense":"129 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":4,"Name":"Charmander"}],"Next Evolution Requirements":{"Amount":100,"Name":"Charmander candies"},"Next evolution(s)":[{"Number":6,"Name":"Charizard"}],"MaxCP":1411,"MaxHP":1557},{"Number":"006","Name":"Charizard","Generation":"Generation I","About":"Charizard flies around the sky in search of powerful opponents. It breathes fire of such great heat that it melts anything. However, it never turns its fiery breath on any opponent weaker than itself.","Types":["Fire","Flying"],"Resistant":["Fire","Grass","Fighting","Bug","Steel","Fairy"],"Weaknesses":["Water","Electric","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Wing Attack","Type":"Flying","Damage":9}],"Special Attack(s)":[{"Name":"Dragon Claw","Type":"Dragon","Damage":35},{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"79.19kg","Maximum":"101.81kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"3km (Big)","Base Stamina":"156 stamina points.","Base Attack":"223 attack points.","Base Defense":"176 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":4,"Name":"Charmander"},{"Number":5,"Name":"Charmeleon"}],"MaxCP":2413,"MaxHP":2602},{"Number":"007","Name":"Squirtle","Generation":"Generation I","About":"Squirtle's shell is not merely used for protection. The shell's rounded shape and the grooves on its surface help minimize resistance in water, enabling this Pokémon to swim at high speeds.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Aqua Jet","Type":"Water","Damage":25},{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"7.88kg","Maximum":"10.13kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"3km (Medium)","Base Stamina":"88 stamina points.","Base Attack":"94 attack points.","Base Defense":"122 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Squirtle candies"},"Next evolution(s)":[{"Number":8,"Name":"Wartortle"},{"Number":9,"Name":"Blastoise"}],"MaxCP":891,"MaxHP":1008},{"Number":"008","Name":"Wartortle","Generation":"Generation I","About":"Its tail is large and covered with a rich, thick fur. The tail becomes increasingly deeper in color as Wartortle ages. The scratches on its shell are evidence of this Pokémon's toughness as a battler.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Aqua Jet","Type":"Water","Damage":25},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Ice Beam","Type":"Ice","Damage":65}],"Weight":{"Minimum":"19.69kg","Maximum":"25.31kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"118 stamina points.","Base Attack":"126 attack points.","Base Defense":"155 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":7,"Name":"Squirtle"}],"Next Evolution Requirements":{"Amount":100,"Name":"Squirtle candies"},"Next evolution(s)":[{"Number":9,"Name":"Blastoise"}],"MaxCP":1435,"MaxHP":1582},{"Number":"009","Name":"Blastoise","Generation":"Generation I","About":"Blastoise has water spouts that protrude from its shell. The water spouts are very accurate. They can shoot bullets of water with enough accuracy to strike empty cans from a distance of over 160 feet.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Flash Cannon","Type":"Steel","Damage":60},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Ice Beam","Type":"Ice","Damage":65}],"Weight":{"Minimum":"74.81kg","Maximum":"96.19kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Big)","Base Stamina":"158 stamina points.","Base Attack":"171 attack points.","Base Defense":"210 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":7,"Name":"Squirtle"},{"Number":8,"Name":"Wartortle"}],"MaxCP":2355,"MaxHP":2542},{"Number":"010","Name":"Caterpie","Generation":"Generation I","About":"Caterpie has a voracious appetite. It can devour leaves bigger than its body right before your eyes. From its antenna, this Pokémon releases a terrifically strong odor.","Types":["Bug"],"Resistant":["Grass","Fighting","Ground"],"Weaknesses":["Fire","Flying","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"2.54kg","Maximum":"3.26kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Shoulder)","Base Stamina":"90 stamina points.","Base Attack":"55 attack points.","Base Defense":"62 defense points.","Base Flee Rate":"20% chance to flee.","Next Evolution Requirements":{"Amount":12,"Name":"Caterpie candies"},"Next evolution(s)":[{"Number":11,"Name":"Metapod"},{"Number":12,"Name":"Butterfree"}],"MaxCP":367,"MaxHP":443},{"Number":"011","Name":"Metapod","Generation":"Generation I","About":"The shell covering this Pokémon’s body is as hard as an iron slab. Metapod does not move very much. It stays still because it is preparing its soft innards for evolution inside the hard shell.","Types":["Bug"],"Resistant":["Grass","Fighting","Ground"],"Weaknesses":["Fire","Flying","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"8.66kg","Maximum":"11.14kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"45 attack points.","Base Defense":"94 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":10,"Name":"Caterpie"}],"Next Evolution Requirements":{"Amount":50,"Name":"Caterpie candies"},"Next evolution(s)":[{"Number":12,"Name":"Butterfree"}],"MaxCP":397,"MaxHP":477},{"Number":"012","Name":"Butterfree","Generation":"Generation I","About":"Butterfree has a superior ability to search for delicious honey from flowers. It can even search out, extract, and carry honey from flowers that are blooming over six miles from its nest.","Types":["Bug","Flying"],"Resistant":["Grass","Fighting","Ground","Bug"],"Weaknesses":["Fire","Electric","Ice","Flying","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Confusion","Type":"Psychic","Damage":15}],"Special Attack(s)":[{"Name":"Bug Buzz","Type":"Bug","Damage":75},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Signal Beam","Type":"Bug","Damage":45}],"Weight":{"Minimum":"28kg","Maximum":"36kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"1km (Flying)","Base Stamina":"120 stamina points.","Base Attack":"167 attack points.","Base Defense":"151 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":10,"Name":"Caterpie"},{"Number":11,"Name":"Metapod"}],"MaxCP":1315,"MaxHP":1454},{"Number":"013","Name":"Weedle","Generation":"Generation I","About":"Weedle has an extremely acute sense of smell. It is capable of distinguishing its favorite kinds of leaves from those it dislikes just by sniffing with its big red proboscis (nose).","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"2.8kg","Maximum":"3.6kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Shoulder)","Base Stamina":"80 stamina points.","Base Attack":"63 attack points.","Base Defense":"55 defense points.","Base Flee Rate":"20% chance to flee.","Next Evolution Requirements":{"Amount":12,"Name":"Weedle candies"},"Next evolution(s)":[{"Number":14,"Name":"Kakuna"},{"Number":15,"Name":"Beedrill"}],"MaxCP":372,"MaxHP":449},{"Number":"014","Name":"Kakuna","Generation":"Generation I","About":"Kakuna remains virtually immobile as it clings to a tree. However, on the inside, it is extremely busy as it prepares for its coming evolution. This is evident from how hot the shell becomes to the touch.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"8.75kg","Maximum":"11.25kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"1km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"46 attack points.","Base Defense":"86 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":13,"Name":"Weedle"}],"Next Evolution Requirements":{"Amount":50,"Name":"Weedle candies"},"Next evolution(s)":[{"Number":15,"Name":"Beedrill"}],"MaxCP":405,"MaxHP":485},{"Number":"015","Name":"Beedrill","Generation":"Generation I","About":"Beedrill is extremely territorial. No one should ever approach its nest—this is for their own safety. If angered, they will attack in a furious swarm.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"25.81kg","Maximum":"33.19kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"1km (Flying)","Base Stamina":"130 stamina points.","Base Attack":"169 attack points.","Base Defense":"150 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":13,"Name":"Weedle"},{"Number":14,"Name":"Kakuna"}],"MaxCP":1301,"MaxHP":1439},{"Number":"016","Name":"Pidgey","Generation":"Generation I","About":"Pidgey has an extremely sharp sense of direction. It is capable of unerringly returning home to its nest, however far it may be removed from its familiar surroundings.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Twister","Type":"Dragon","Damage":25}],"Weight":{"Minimum":"1.57kg","Maximum":"2.02kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Shoulder)","Base Stamina":"80 stamina points.","Base Attack":"85 attack points.","Base Defense":"76 defense points.","Base Flee Rate":"20% chance to flee.","Next Evolution Requirements":{"Amount":12,"Name":"Pidgey candies"},"Next evolution(s)":[{"Number":17,"Name":"Pidgeotto"},{"Number":18,"Name":"Pidgeot"}],"MaxCP":585,"MaxHP":679},{"Number":"017","Name":"Pidgeotto","Generation":"Generation I","About":"Pidgeotto claims a large area as its own territory. This Pokémon flies around, patrolling its living space. If its territory is violated, it shows no mercy in thoroughly punishing the foe with its sharp claws.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Steel Wing","Type":"Steel","Damage":15},{"Name":"Wing Attack","Type":"Flying","Damage":9}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Twister","Type":"Dragon","Damage":25}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"1km (Flying)","Base Stamina":"126 stamina points.","Base Attack":"117 attack points.","Base Defense":"108 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":16,"Name":"Pidgey"}],"Next Evolution Requirements":{"Amount":50,"Name":"Pidgey candies"},"Next evolution(s)":[{"Number":18,"Name":"Pidgeot"}],"MaxCP":1096,"MaxHP":1223},{},{"Number":"019","Name":"Rattata","Generation":"Generation I","About":"Rattata is cautious in the extreme. Even while it is asleep, it constantly listens by moving its ears around. It is not picky about where it lives—it will make its nest anywhere.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Hyper Fang","Type":"Normal","Damage":35}],"Weight":{"Minimum":"3.06kg","Maximum":"3.94kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"103 attack points.","Base Defense":"70 defense points.","Base Flee Rate":"20% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Rattata candies"},"Next evolution(s)":[{"Number":20,"Name":"Raticate"}],"MaxCP":493,"MaxHP":581},{"Number":"020","Name":"Raticate","Generation":"Generation I","About":"Raticate’s sturdy fangs grow steadily. To keep them ground down, it gnaws on rocks and logs. It may even chew on the walls of houses.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Quick Attack","Type":"Normal","Damage":10}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Hyper Fang","Type":"Normal","Damage":35}],"Weight":{"Minimum":"16.19kg","Maximum":"20.81kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"161 attack points.","Base Defense":"144 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":19,"Name":"Rattata"}],"MaxCP":1304,"MaxHP":1444},{"Number":"021","Name":"Spearow","Generation":"Generation I","About":"Spearow has a very loud cry that can be heard over half a mile away. If its high, keening cry is heard echoing all around, it is a sign that they are warning each other of danger.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Quick Attack","Type":"Normal","Damage":10}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Drill Peck","Type":"Flying","Damage":40},{"Name":"Twister","Type":"Dragon","Damage":25}],"Weight":{"Minimum":"1.75kg","Maximum":"2.25kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Shoulder)","Base Stamina":"80 stamina points.","Base Attack":"112 attack points.","Base Defense":"61 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Spearow candies"},"Next evolution(s)":[{"Number":22,"Name":"Fearow"}],"MaxCP":591,"MaxHP":686},{"Number":"022","Name":"Fearow","Generation":"Generation I","About":"Fearow is recognized by its long neck and elongated beak. They are conveniently shaped for catching prey in soil or water. It deftly moves its long and skinny beak to pluck prey.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Steel Wing","Type":"Steel","Damage":15}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Drill Run","Type":"Ground","Damage":50},{"Name":"Twister","Type":"Dragon","Damage":25}],"Weight":{"Minimum":"33.25kg","Maximum":"42.75kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"1km (Flying)","Base Stamina":"130 stamina points.","Base Attack":"182 attack points.","Base Defense":"135 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":21,"Name":"Spearow"}],"MaxCP":1592,"MaxHP":1746},{"Number":"023","Name":"Ekans","Generation":"Generation I","About":"Ekans curls itself up in a spiral while it rests. Assuming this position allows it to quickly respond to a threat from any direction with a glare from its upraised head.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Gunk Shot","Type":"Poison","Damage":65},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Wrap","Type":"Normal","Damage":25}],"Weight":{"Minimum":"6.04kg","Maximum":"7.76kg"},"Height":{"Minimum":"1.75m","Maximum":"2.25m"},"Buddy Distance":"3km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"110 attack points.","Base Defense":"102 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Ekans candies"},"Next evolution(s)":[{"Number":24,"Name":"Arbok"}],"MaxCP":718,"MaxHP":824},{"Number":"024","Name":"Arbok","Generation":"Generation I","About":"This Pokémon is terrifically strong in order to constrict things with its body. It can even flatten steel oil drums. Once Arbok wraps its body around its foe, escaping its crunching embrace is impossible.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Bite","Type":"Dark","Damage":6}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Gunk Shot","Type":"Poison","Damage":65},{"Name":"Sludge Wave","Type":"Poison","Damage":70}],"Weight":{"Minimum":"56.88kg","Maximum":"73.13kg"},"Height":{"Minimum":"3.06m","Maximum":"3.94m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"167 attack points.","Base Defense":"158 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":23,"Name":"Ekans"}],"MaxCP":1611,"MaxHP":1767},{"Number":"025","Name":"Pikachu","Generation":"Generation I","About":"Whenever Pikachu comes across something new, it blasts it with a jolt of electricity. If you come across a blackened berry, it's evidence that this Pokémon mistook the intensity of its charge.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Thunder","Type":"Electric","Damage":100},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"5.25kg","Maximum":"6.75kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"1km (Shoulder)","Base Stamina":"70 stamina points.","Base Attack":"112 attack points.","Base Defense":"101 defense points.","Base Flee Rate":"10% chance to flee.","Previous evolution(s)":[{"Number":172,"Name":"Pichu"}],"Next Evolution Requirements":{"Amount":50,"Name":"Pikachu candies"},"Next evolution(s)":[{"Number":26,"Name":"Raichu"}],"MaxCP":777,"MaxHP":887},{"Number":"026","Name":"Raichu","Generation":"Generation I","About":"If the electrical sacs become excessively charged, Raichu plants its tail in the ground and discharges. Scorched patches of ground will be found near this Pokémon's nest.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Thunder","Type":"Electric","Damage":100},{"Name":"Thunder Punch","Type":"Electric","Damage":40}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"193 attack points.","Base Defense":"165 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":172,"Name":"Pichu"},{"Number":25,"Name":"Pikachu"}],"MaxCP":1859,"MaxHP":2028},{"Number":"027","Name":"Sandshrew","Generation":"Generation I","About":"Sandshrew's body is configured to absorb water without waste, enabling it to survive in an arid desert. This Pokémon curls up to protect itself from its enemies.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Mud Shot","Type":"Ground","Damage":6},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Rock Slide","Type":"Rock","Damage":50},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"10.5kg","Maximum":"13.5kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"126 attack points.","Base Defense":"145 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Sandshrew candies"},"Next evolution(s)":[{"Number":28,"Name":"Sandslash"}],"MaxCP":695,"MaxHP":798},{"Number":"028","Name":"Sandslash","Generation":"Generation I","About":"Sandslash's body is covered by tough spikes, which are hardened sections of its hide. Once a year, the old spikes fall out, to be replaced with new spikes that grow out from beneath the old ones.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Metal Claw","Type":"Steel","Damage":8},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Bulldoze","Type":"Ground","Damage":35},{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"25.81kg","Maximum":"33.19kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"182 attack points.","Base Defense":"202 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":27,"Name":"Sandshrew"}],"MaxCP":1654,"MaxHP":1810},{"Number":"029","Name":"Nidoran ♀","Generation":"Generation I","About":"Nidoran♀ has barbs that secrete a powerful poison. They are thought to have developed as protection for this small-bodied Pokémon. When enraged, it releases a horrible toxin from its horn.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Poison Fang","Type":"Poison","Damage":25},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"6.13kg","Maximum":"7.88kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"86 attack points.","Base Defense":"94 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Nidoran Female candies"},"Next evolution(s)":[{"Number":30,"Name":"Nidorina"},{"Number":31,"Name":"Nidoqueen"}],"MaxCP":768,"MaxHP":876},{"Number":"030","Name":"Nidorina","Generation":"Generation I","About":"When Nidorina are with their friends or family, they keep their barbs tucked away to prevent hurting each other. This Pokémon appears to become nervous if separated from the others.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Poison Fang","Type":"Poison","Damage":25},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"17.5kg","Maximum":"22.5kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"117 attack points.","Base Defense":"126 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":29,"Name":"Nidoran"}],"Next Evolution Requirements":{"Amount":100,"Name":"Nidoran Female candies"},"Next evolution(s)":[{"Number":31,"Name":"Nidoqueen"}],"MaxCP":1267,"MaxHP":1404},{"Number":"031","Name":"Nidoqueen","Generation":"Generation I","About":"Nidoqueen's body is encased in extremely hard scales. It is adept at sending foes flying with harsh tackles. This Pokémon is at its strongest when it is defending its young.","Types":["Poison","Ground"],"Resistant":["Electric","Fighting","Poison","Bug","Rock","Fairy"],"Weaknesses":["Water","Ice","Ground","Psychic"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Sludge Wave","Type":"Poison","Damage":70},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"52.5kg","Maximum":"67.5kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Big)","Base Stamina":"180 stamina points.","Base Attack":"180 attack points.","Base Defense":"174 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":29,"Name":"Nidoran"},{"Number":30,"Name":"Nidorina"}],"MaxCP":2301,"MaxHP":2485},{"Number":"032","Name":"Nidoran ♂","Generation":"Generation I","About":"Nidoran♂ has developed muscles for moving its ears. Thanks to them, the ears can be freely moved in any direction. Even the slightest sound does not escape this Pokémon's notice.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Horn Attack","Type":"Normal","Damage":25},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"7.88kg","Maximum":"10.13kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"3km (Medium)","Base Stamina":"92 stamina points.","Base Attack":"105 attack points.","Base Defense":"76 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Nidoran Male candies"},"Next evolution(s)":[{"Number":33,"Name":"Nidorino"},{"Number":34,"Name":"Nidoking"}],"MaxCP":737,"MaxHP":843},{"Number":"033","Name":"Nidorino","Generation":"Generation I","About":"Nidorino has a horn that is harder than a diamond. If it senses a hostile presence, all the barbs on its back bristle up at once, and it challenges the foe with all its might.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Poison Jab","Type":"Poison","Damage":12},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Horn Attack","Type":"Normal","Damage":25},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"17.06kg","Maximum":"21.94kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"3km (Medium)","Base Stamina":"122 stamina points.","Base Attack":"137 attack points.","Base Defense":"112 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":32,"Name":"Nidoran"}],"Next Evolution Requirements":{"Amount":100,"Name":"Nidoran Male candies"},"Next evolution(s)":[{"Number":34,"Name":"Nidoking"}],"MaxCP":1236,"MaxHP":1372},{"Number":"034","Name":"Nidoking","Generation":"Generation I","About":"Nidoking's thick tail packs enormously destructive power. With one swing, it can topple a metal transmission tower. Once this Pokémon goes on a rampage, there is no stopping it.","Types":["Poison","Ground"],"Resistant":["Electric","Fighting","Poison","Bug","Rock","Fairy"],"Weaknesses":["Water","Ice","Ground","Psychic"],"Fast Attack(s)":[{"Name":"Fury Cutter","Type":"Bug","Damage":3},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Megahorn","Type":"Bug","Damage":80},{"Name":"Sludge Wave","Type":"Poison","Damage":70}],"Weight":{"Minimum":"54.25kg","Maximum":"69.75kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"3km (Big)","Base Stamina":"162 stamina points.","Base Attack":"204 attack points.","Base Defense":"157 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":32,"Name":"Nidoran"},{"Number":33,"Name":"Nidorino"}],"MaxCP":2291,"MaxHP":2475},{"Number":"035","Name":"Clefairy","Generation":"Generation I","About":"On every night of a full moon, groups of this Pokémon come out to play. When dawn arrives, the tired Clefairy return to their quiet mountain retreats and go to sleep nestled up against each other.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Pound","Type":"Normal","Damage":7},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Disarming Voice","Type":"Fairy","Damage":25},{"Name":"Moonblast","Type":"Fairy","Damage":85}],"Weight":{"Minimum":"6.56kg","Maximum":"8.44kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"107 attack points.","Base Defense":"116 defense points.","Base Flee Rate":"10% chance to flee.","Previous evolution(s)":[{"Number":173,"Name":"Cleffa"}],"Next Evolution Requirements":{"Amount":50,"Name":"Clefairy candies"},"Next evolution(s)":[{"Number":36,"Name":"Clefable"}],"MaxCP":1074,"MaxHP":1200},{"Number":"036","Name":"Clefable","Generation":"Generation I","About":"Clefable moves by skipping lightly as if it were flying using its wings. Its bouncy step even lets it walk on water. It is known to take strolls on lakes on quiet, moonlit nights.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Pound","Type":"Normal","Damage":7},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Moonblast","Type":"Fairy","Damage":85},{"Name":"Psychic","Type":"Psychic","Damage":55}],"Weight":{"Minimum":"35kg","Maximum":"45kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"1km (Big)","Base Stamina":"190 stamina points.","Base Attack":"178 attack points.","Base Defense":"171 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":173,"Name":"Cleffa"},{"Number":35,"Name":"Clefairy"}],"MaxCP":2217,"MaxHP":2397},{"Number":"037","Name":"Vulpix","Generation":"Generation I","About":"At the time of its birth, Vulpix has one white tail. The tail separates into six if this Pokémon receives plenty of love from its trainer. The six tails become magnificently curled.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Quick Attack","Type":"Normal","Damage":10}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Flame Charge","Type":"Fire","Damage":25},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"8.66kg","Maximum":"11.14kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Medium)","Base Stamina":"76 stamina points.","Base Attack":"96 attack points.","Base Defense":"122 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Vulpi"},"Next evolution(s)":[{"Number":38,"Name":"Ninetales"}],"MaxCP":725,"MaxHP":831},{"Number":"038","Name":"Ninetales","Generation":"Generation I","About":"Ninetales casts a sinister light from its bright red eyes to gain total control over its foe's mind. This Pokémon is said to live for one thousand years.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Feint Attack","Type":"Dark","Damage":12}],"Special Attack(s)":[{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flamethrower","Type":"Fire","Damage":55},{"Name":"Heat Wave","Type":"Fire","Damage":80}],"Weight":{"Minimum":"17.41kg","Maximum":"22.39kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"3km (Big)","Base Stamina":"146 stamina points.","Base Attack":"169 attack points.","Base Defense":"204 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":37,"Name":"Vulpix"}],"MaxCP":2015,"MaxHP":2188},{"Number":"039","Name":"Jigglypuff","Generation":"Generation I","About":"Jigglypuff's vocal cords can freely adjust the wavelength of its voice. This Pokémon uses this ability to sing at precisely the right wavelength to make its foes most drowsy.","Types":["Normal","Fairy"],"Resistant":["Bug","Ghost","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Feint Attack","Type":"Dark","Damage":12},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Disarming Voice","Type":"Fairy","Damage":25}],"Weight":{"Minimum":"4.81kg","Maximum":"6.19kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"1km (Medium)","Base Stamina":"230 stamina points.","Base Attack":"80 attack points.","Base Defense":"44 defense points.","Base Flee Rate":"10% chance to flee.","Previous evolution(s)":[{"Number":174,"Name":"Igglybuff"}],"Next Evolution Requirements":{"Amount":50,"Name":"Jigglypuff candies"},"Next evolution(s)":[{"Number":40,"Name":"Wigglytuff"}],"MaxCP":796,"MaxHP":917},{"Number":"040","Name":"Wigglytuff","Generation":"Generation I","About":"Wigglytuff has large, saucerlike eyes. The surfaces of its eyes are always covered with a thin layer of tears. If any dust gets in this Pokémon's eyes, it is quickly washed away.","Types":["Normal","Fairy"],"Resistant":["Bug","Ghost","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Feint Attack","Type":"Dark","Damage":12},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Play Rough","Type":"Fairy","Damage":55}],"Weight":{"Minimum":"10.5kg","Maximum":"13.5kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"1km (Big)","Base Stamina":"280 stamina points.","Base Attack":"156 attack points.","Base Defense":"93 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":174,"Name":"Igglybuff"},{"Number":39,"Name":"Jigglypuff"}],"MaxCP":1997,"MaxHP":2177},{"Number":"041","Name":"Zubat","Generation":"Generation I","About":"Zubat remains quietly unmoving in a dark spot during the bright daylight hours. It does so because prolonged exposure to the sun causes its body to become slightly burned.","Types":["Poison","Flying"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Electric","Ice","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Quick Attack","Type":"Normal","Damage":10}],"Special Attack(s)":[{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Poison Fang","Type":"Poison","Damage":25},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"6.56kg","Maximum":"8.44kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"1km (Flying)","Base Stamina":"80 stamina points.","Base Attack":"83 attack points.","Base Defense":"76 defense points.","Base Flee Rate":"20% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Zubat candies"},"Next evolution(s)":[{"Number":42,"Name":"Golbat"},{"Number":169,"Name":"Crobat"}],"MaxCP":550,"MaxHP":642},{"Number":"042","Name":"Golbat","Generation":"Generation I","About":"Golbat loves to drink the blood of living things. It is particularly active in the pitch black of night. This Pokémon flits around in the night skies, seeking fresh blood.","Types":["Poison","Flying"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Electric","Ice","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Wing Attack","Type":"Flying","Damage":9}],"Special Attack(s)":[{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Ominous Wind","Type":"Ghost","Damage":30},{"Name":"Poison Fang","Type":"Poison","Damage":25}],"Weight":{"Minimum":"48.13kg","Maximum":"61.88kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"1km (Flying)","Base Stamina":"150 stamina points.","Base Attack":"161 attack points.","Base Defense":"153 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":41,"Name":"Zubat"}],"Next evolution(s)":[{"Number":169,"Name":"Crobat"}],"MaxCP":1760,"MaxHP":1921},{"Number":"043","Name":"Oddish","Generation":"Generation I","About":"During the daytime, Oddish buries itself in soil to absorb nutrients from the ground using its entire body. The more fertile the soil, the glossier its leaves become.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Razor Leaf","Type":"Grass","Damage":15}],"Special Attack(s)":[{"Name":"Moonblast","Type":"Fairy","Damage":85},{"Name":"Seed Bomb","Type":"Grass","Damage":40},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"4.73kg","Maximum":"6.08kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"3km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"131 attack points.","Base Defense":"116 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Oddish candies"},"Next evolution(s)":[{"Number":44,"Name":"Gloom"},{"Number":45,"Name":"Vileplume"},{"Number":182,"Name":"Bellossom"}],"MaxCP":1023,"MaxHP":1148},{"Number":"044","Name":"Gloom","Generation":"Generation I","About":"Gloom releases a foul fragrance from the pistil of its flower. When faced with danger, the stench worsens. If this Pokémon is feeling calm and secure, it does not release its usual stinky aroma.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Razor Leaf","Type":"Grass","Damage":15}],"Special Attack(s)":[{"Name":"Moonblast","Type":"Fairy","Damage":85},{"Name":"Petal Blizzard","Type":"Grass","Damage":65},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"7.53kg","Maximum":"9.68kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"153 attack points.","Base Defense":"139 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":43,"Name":"Oddish"}],"Next Evolution Requirements":{"Amount":100,"Name":"Oddish candies"},"Next evolution(s)":[{"Number":45,"Name":"Vileplume"},{"Number":182,"Name":"Bellossom"}],"MaxCP":1537,"MaxHP":1689},{"Number":"045","Name":"Vileplume","Generation":"Generation I","About":"Vileplume's toxic pollen triggers atrocious allergy attacks. That's why it is advisable never to approach any attractive flowers in a jungle, however pretty they may be.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Razor Leaf","Type":"Grass","Damage":15}],"Special Attack(s)":[{"Name":"Moonblast","Type":"Fairy","Damage":85},{"Name":"Petal Blizzard","Type":"Grass","Damage":65},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"16.28kg","Maximum":"20.93kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Big)","Base Stamina":"150 stamina points.","Base Attack":"202 attack points.","Base Defense":"170 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":43,"Name":"Oddish"},{"Number":44,"Name":"Gloom"}],"MaxCP":2307,"MaxHP":2492},{"Number":"046","Name":"Paras","Generation":"Generation I","About":"Paras has parasitic mushrooms growing on its back called tochukaso. They grow large by drawing nutrients from this Bug Pokémon host. They are highly valued as a medicine for extending life.","Types":["Bug","Grass"],"Resistant":["Water","Electric","Grass","Fighting","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Cross Poison","Type":"Poison","Damage":25},{"Name":"Seed Bomb","Type":"Grass","Damage":40},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"4.73kg","Maximum":"6.08kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"3km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"121 attack points.","Base Defense":"99 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Paras candies"},"Next evolution(s)":[{"Number":47,"Name":"Parasect"}],"MaxCP":804,"MaxHP":916},{"Number":"047","Name":"Parasect","Generation":"Generation I","About":"Parasect is known to infest large trees en masse and drain nutrients from the lower trunk and roots. When an infested tree dies, they move onto another tree all at once.","Types":["Bug","Grass"],"Resistant":["Water","Electric","Grass","Fighting","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Fury Cutter","Type":"Bug","Damage":3}],"Special Attack(s)":[{"Name":"Cross Poison","Type":"Poison","Damage":25},{"Name":"Solar Beam","Type":"Grass","Damage":120},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"25.81kg","Maximum":"33.19kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"165 attack points.","Base Defense":"146 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":46,"Name":"Paras"}],"MaxCP":1592,"MaxHP":1747},{"Number":"048","Name":"Venonat","Generation":"Generation I","About":"Venonat is said to have evolved with a coat of thin, stiff hair that covers its entire body for protection. It possesses large eyes that never fail to spot even miniscule prey.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Confusion","Type":"Psychic","Damage":15}],"Special Attack(s)":[{"Name":"Poison Fang","Type":"Poison","Damage":25},{"Name":"Psybeam","Type":"Psychic","Damage":40},{"Name":"Signal Beam","Type":"Bug","Damage":45}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"100 attack points.","Base Defense":"102 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Venonat candies"},"Next evolution(s)":[{"Number":49,"Name":"Venomoth"}],"MaxCP":912,"MaxHP":1029},{"Number":"049","Name":"Venomoth","Generation":"Generation I","About":"Venomoth is nocturnal—it is a Pokémon that only becomes active at night. Its favorite prey are small insects that gather around streetlights, attracted by the light in the darkness.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Confusion","Type":"Psychic","Damage":15}],"Special Attack(s)":[{"Name":"Bug Buzz","Type":"Bug","Damage":75},{"Name":"Poison Fang","Type":"Poison","Damage":25},{"Name":"Psychic","Type":"Psychic","Damage":55}],"Weight":{"Minimum":"10.94kg","Maximum":"14.06kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"3km (Flying)","Base Stamina":"140 stamina points.","Base Attack":"179 attack points.","Base Defense":"150 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":48,"Name":"Venonat"}],"MaxCP":1730,"MaxHP":1890},{"Number":"050","Name":"Diglett","Generation":"Generation I","About":"Diglett are raised in most farms. The reason is simple—wherever this Pokémon burrows, the soil is left perfectly tilled for planting crops. This soil is made ideal for growing delicious vegetables.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Mud Bomb","Type":"Ground","Damage":30},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"0.7kg","Maximum":"0.9kg"},"Height":{"Minimum":"0.18m","Maximum":"0.23m"},"Buddy Distance":"3km (Medium)","Base Stamina":"20 stamina points.","Base Attack":"109 attack points.","Base Defense":"88 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Diglett candies"},"Next evolution(s)":[{"Number":51,"Name":"Dugtrio"}],"MaxCP":365,"MaxHP":456},{"Number":"051","Name":"Dugtrio","Generation":"Generation I","About":"Dugtrio are actually triplets that emerged from one body. As a result, each triplet thinks exactly like the other two triplets. They work cooperatively to burrow endlessly.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Sucker Punch","Type":"Dark","Damage":7}],"Special Attack(s)":[{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Mud Bomb","Type":"Ground","Damage":30},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"29.14kg","Maximum":"37.46kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"3km (Big)","Base Stamina":"70 stamina points.","Base Attack":"167 attack points.","Base Defense":"147 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":50,"Name":"Diglett"}],"MaxCP":1038,"MaxHP":1168},{"Number":"052","Name":"Meowth","Generation":"Generation I","About":"Meowth withdraws its sharp claws into its paws to slinkily sneak about without making any incriminating footsteps. For some reason, this Pokémon loves shiny coins that glitter with light.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Night Slash","Type":"Dark","Damage":30}],"Weight":{"Minimum":"3.67kg","Maximum":"4.72kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"92 attack points.","Base Defense":"81 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Meowth candies"},"Next evolution(s)":[{"Number":53,"Name":"Persian"}],"MaxCP":656,"MaxHP":756},{"Number":"053","Name":"Persian","Generation":"Generation I","About":"Persian has six bold whiskers that give it a look of toughness. The whiskers sense air movements to determine what is in the Pokémon's surrounding vicinity. It becomes docile if grabbed by the whiskers.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Feint Attack","Type":"Dark","Damage":12},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Night Slash","Type":"Dark","Damage":30},{"Name":"Play Rough","Type":"Fairy","Damage":55},{"Name":"Power Gem","Type":"Rock","Damage":40}],"Weight":{"Minimum":"28kg","Maximum":"36kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"150 attack points.","Base Defense":"139 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":52,"Name":"Meowth"}],"MaxCP":1483,"MaxHP":1631},{"Number":"054","Name":"Psyduck","Generation":"Generation I","About":"Psyduck uses a mysterious power. When it does so, this Pokémon generates brain waves that are supposedly only seen in sleepers. This discovery spurred controversy among scholars.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Water Gun","Type":"Water","Damage":6},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Psybeam","Type":"Psychic","Damage":40}],"Weight":{"Minimum":"17.15kg","Maximum":"22.05kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"122 attack points.","Base Defense":"96 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Psyduck candies"},"Next evolution(s)":[{"Number":55,"Name":"Golduck"}],"MaxCP":987,"MaxHP":1109},{"Number":"055","Name":"Golduck","Generation":"Generation I","About":"The webbed flippers on its forelegs and hind legs and the streamlined body of Golduck give it frightening speed. The Pokémon is definitely much faster than even the most athletic swimmer.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Ice Beam","Type":"Ice","Damage":65},{"Name":"Psychic","Type":"Psychic","Damage":55}],"Weight":{"Minimum":"67.02kg","Maximum":"86.17kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"191 attack points.","Base Defense":"163 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":54,"Name":"Psyduck"}],"MaxCP":2206,"MaxHP":2386},{"Number":"056","Name":"Mankey","Generation":"Generation I","About":"When Mankey starts shaking and its nasal breathing turns rough, it's a sure sign that it is becoming angry. However, because it goes into a towering rage almost instantly, it is impossible for anyone to flee its wrath.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Karate Chop","Type":"Fighting","Damage":6},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Low Sweep","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"24.5kg","Maximum":"31.5kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"3km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"148 attack points.","Base Defense":"87 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Mankey candies"},"Next evolution(s)":[{"Number":57,"Name":"Primeape"}],"MaxCP":769,"MaxHP":878},{"Number":"057","Name":"Primeape","Generation":"Generation I","About":"When Primeape becomes furious, its blood circulation is boosted. In turn, its muscles are made even stronger. However, it also becomes much less intelligent at the same time.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Karate Chop","Type":"Fighting","Damage":6},{"Name":"Low Kick","Type":"Fighting","Damage":5}],"Special Attack(s)":[{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Low Sweep","Type":"Fighting","Damage":30},{"Name":"Night Slash","Type":"Dark","Damage":30}],"Weight":{"Minimum":"28kg","Maximum":"36kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"207 attack points.","Base Defense":"144 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":56,"Name":"Mankey"}],"MaxCP":1704,"MaxHP":1864},{"Number":"058","Name":"Growlithe","Generation":"Generation I","About":"Growlithe has a superb sense of smell. Once it smells anything, this Pokémon won't forget the scent, no matter what. It uses its advanced olfactory sense to determine the emotions of other living things.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Ember","Type":"Fire","Damage":10}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Flame Wheel","Type":"Fire","Damage":40},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"16.63kg","Maximum":"21.38kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"3km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"136 attack points.","Base Defense":"96 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Growlithe candies"},"Next evolution(s)":[{"Number":59,"Name":"Arcanine"}],"MaxCP":1199,"MaxHP":1335},{"Number":"059","Name":"Arcanine","Generation":"Generation I","About":"Arcanine is known for its high speed. It is said to be capable of running over 6,200 miles in a single day and night. The fire that blazes wildly within this Pokémon's body is its source of power.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Fire Fang","Type":"Fire","Damage":10}],"Special Attack(s)":[{"Name":"Bulldoze","Type":"Ground","Damage":35},{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"135.63kg","Maximum":"174.38kg"},"Height":{"Minimum":"1.66m","Maximum":"2.14m"},"Buddy Distance":"3km (Big)","Base Stamina":"180 stamina points.","Base Attack":"227 attack points.","Base Defense":"166 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":58,"Name":"Growlithe"}],"MaxCP":2781,"MaxHP":2983},{"Number":"060","Name":"Poliwag","Generation":"Generation I","About":"Poliwag has a very thin skin. It is possible to see the Pokémon's spiral innards right through the skin. Despite its thinness, however, the skin is also very flexible. Even sharp fangs bounce right off it.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Mud Bomb","Type":"Ground","Damage":30}],"Weight":{"Minimum":"10.85kg","Maximum":"13.95kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"101 attack points.","Base Defense":"82 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Poliwag candies"},"Next evolution(s)":[{"Number":61,"Name":"Poliwhirl"},{"Number":62,"Name":"Poliwrath"},{"Number":186,"Name":"Politoed"}],"MaxCP":693,"MaxHP":795},{"Number":"061","Name":"Poliwhirl","Generation":"Generation I","About":"The surface of Poliwhirl's body is always wet and slick with an oily fluid. Because of this greasy covering, it can easily slip and slide out of the clutches of any enemy in battle.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Mud Bomb","Type":"Ground","Damage":30},{"Name":"Scald","Type":"Water","Damage":55}],"Weight":{"Minimum":"17.5kg","Maximum":"22.5kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"130 attack points.","Base Defense":"130 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":60,"Name":"Poliwag"}],"Next Evolution Requirements":{"Amount":100,"Name":"Poliwag candies"},"Next evolution(s)":[{"Number":62,"Name":"Poliwrath"},{"Number":186,"Name":"Politoed"}],"MaxCP":1206,"MaxHP":1340},{"Number":"062","Name":"Poliwrath","Generation":"Generation I","About":"Poliwrath's highly developed, brawny muscles never grow fatigued, however much it exercises. It is so tirelessly strong, this Pokémon can swim back and forth across the ocean without effort.","Types":["Water","Fighting"],"Resistant":["Fire","Water","Ice","Bug","Rock","Dark","Steel"],"Weaknesses":["Electric","Grass","Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Ice Punch","Type":"Ice","Damage":45},{"Name":"Submission","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"47.25kg","Maximum":"60.75kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Big)","Base Stamina":"180 stamina points.","Base Attack":"182 attack points.","Base Defense":"187 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":60,"Name":"Poliwag"},{"Number":61,"Name":"Poliwhirl"}],"MaxCP":2321,"MaxHP":2505},{"Number":"063","Name":"Abra","Generation":"Generation I","About":"Abra sleeps for eighteen hours a day. However, it can sense the presence of foes even while it is sleeping. In such a situation, this Pokémon immediately teleports to safety.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Psyshock","Type":"Psychic","Damage":40},{"Name":"Shadow Ball","Type":"Ghost","Damage":45},{"Name":"Signal Beam","Type":"Bug","Damage":45}],"Weight":{"Minimum":"17.06kg","Maximum":"21.94kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"3km (Medium)","Base Stamina":"50 stamina points.","Base Attack":"195 attack points.","Base Defense":"103 defense points.","Base Flee Rate":"99% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Abra candies"},"Next evolution(s)":[{"Number":64,"Name":"Kadabra"},{"Number":65,"Name":"Alakazam"}],"MaxCP":508,"MaxHP":600},{"Number":"064","Name":"Kadabra","Generation":"Generation I","About":"Kadabra emits a peculiar alpha wave if it develops a headache. Only those people with a particularly strong psyche can hope to become a trainer of this Pokémon.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Psycho Cut","Type":"Psychic","Damage":7}],"Special Attack(s)":[{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Psybeam","Type":"Psychic","Damage":40},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"49.44kg","Maximum":"63.56kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Big)","Base Stamina":"80 stamina points.","Base Attack":"232 attack points.","Base Defense":"138 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":63,"Name":"Abra"}],"Next Evolution Requirements":{"Amount":100,"Name":"Abra candies"},"Next evolution(s)":[{"Number":65,"Name":"Alakazam"}],"MaxCP":1005,"MaxHP":1131},{"Number":"065","Name":"Alakazam","Generation":"Generation I","About":"Alakazam's brain continually grows, making its head far too heavy to support with its neck. This Pokémon holds its head up using its psychokinetic power instead.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Psycho Cut","Type":"Psychic","Damage":7}],"Special Attack(s)":[{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"42kg","Maximum":"54kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"3km (Big)","Base Stamina":"110 stamina points.","Base Attack":"271 attack points.","Base Defense":"194 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":63,"Name":"Abra"},{"Number":64,"Name":"Kadabra"}],"MaxCP":1654,"MaxHP":1813},{"Number":"066","Name":"Machop","Generation":"Generation I","About":"Machop's muscles are special—they never get sore no matter how much they are used in exercise. This Pokémon has sufficient power to hurl a hundred adult humans.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Karate Chop","Type":"Fighting","Damage":6},{"Name":"Low Kick","Type":"Fighting","Damage":5}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Low Sweep","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"17.06kg","Maximum":"21.94kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"137 attack points.","Base Defense":"88 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Machop candies"},"Next evolution(s)":[{"Number":67,"Name":"Machoke"},{"Number":68,"Name":"Machamp"}],"MaxCP":968,"MaxHP":1089},{"Number":"067","Name":"Machoke","Generation":"Generation I","About":"Machoke's thoroughly toned muscles possess the hardness of steel. This Pokémon has so much strength, it can easily hold aloft a sumo wrestler on just one finger.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Karate Chop","Type":"Fighting","Damage":6},{"Name":"Low Kick","Type":"Fighting","Damage":5}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Submission","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"61.69kg","Maximum":"79.31kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"177 attack points.","Base Defense":"130 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":66,"Name":"Machop"}],"Next Evolution Requirements":{"Amount":100,"Name":"Machop candies"},"Next evolution(s)":[{"Number":68,"Name":"Machamp"}],"MaxCP":1606,"MaxHP":1760},{"Number":"068","Name":"Machamp","Generation":"Generation I","About":"Machamp has the power to hurl anything aside. However, trying to do any work requiring care and dexterity causes its arms to get tangled. This Pokémon tends to leap into action before it thinks.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Bullet Punch","Type":"Steel","Damage":10},{"Name":"Karate Chop","Type":"Fighting","Damage":6}],"Special Attack(s)":[{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Stone Edge","Type":"Rock","Damage":80},{"Name":"Submission","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"113.75kg","Maximum":"146.25kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Big)","Base Stamina":"180 stamina points.","Base Attack":"234 attack points.","Base Defense":"162 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":66,"Name":"Machop"},{"Number":67,"Name":"Machoke"}],"MaxCP":2406,"MaxHP":2594},{"Number":"069","Name":"Bellsprout","Generation":"Generation I","About":"Bellsprout's thin and flexible body lets it bend and sway to avoid any attack, however strong it may be. From its mouth, this Pokémon spits a corrosive fluid that melts even iron.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Wrap","Type":"Normal","Damage":25}],"Weight":{"Minimum":"3.5kg","Maximum":"4.5kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"3km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"139 attack points.","Base Defense":"64 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Bellsprout candies"},"Next evolution(s)":[{"Number":70,"Name":"Weepinbell"},{"Number":71,"Name":"Victreebel"}],"MaxCP":990,"MaxHP":1117},{"Number":"070","Name":"Weepinbell","Generation":"Generation I","About":"Weepinbell has a large hook on its rear end. At night, the Pokémon hooks on to a tree branch and goes to sleep. If it moves around in its sleep, it may wake up to find itself on the ground.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Razor Leaf","Type":"Grass","Damage":15}],"Special Attack(s)":[{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Seed Bomb","Type":"Grass","Damage":40},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"5.6kg","Maximum":"7.2kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"172 attack points.","Base Defense":"95 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":69,"Name":"Bellsprout"}],"Next Evolution Requirements":{"Amount":100,"Name":"Bellsprout candies"},"Next evolution(s)":[{"Number":71,"Name":"Victreebel"}],"MaxCP":1567,"MaxHP":1723},{"Number":"071","Name":"Victreebel","Generation":"Generation I","About":"Victreebel has a long vine that extends from its head. This vine is waved and flicked about as if it were an animal to attract prey. When an unsuspecting prey draws near, this Pokémon swallows it whole.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Razor Leaf","Type":"Grass","Damage":15}],"Special Attack(s)":[{"Name":"Leaf Blade","Type":"Grass","Damage":55},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"13.56kg","Maximum":"17.44kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"207 attack points.","Base Defense":"138 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":69,"Name":"Bellsprout"},{"Number":70,"Name":"Weepinbell"}],"MaxCP":2342,"MaxHP":2530},{"Number":"072","Name":"Tentacool","Generation":"Generation I","About":"Tentacool's body is largely composed of water. If it is removed from the sea, it dries up like parchment. If this Pokémon happens to become dehydrated, put it back into the sea.","Types":["Water","Poison"],"Resistant":["Fire","Water","Ice","Fighting","Poison","Bug","Steel","Fairy"],"Weaknesses":["Electric","Ground","Psychic"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Water Pulse","Type":"Water","Damage":35},{"Name":"Wrap","Type":"Normal","Damage":25}],"Weight":{"Minimum":"39.81kg","Maximum":"51.19kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"3km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"97 attack points.","Base Defense":"182 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Tentacool candies"},"Next evolution(s)":[{"Number":73,"Name":"Tentacruel"}],"MaxCP":794,"MaxHP":905},{"Number":"073","Name":"Tentacruel","Generation":"Generation I","About":"Tentacruel has large red orbs on its head. The orbs glow before lashing the vicinity with a harsh ultrasonic blast. This Pokémon's outburst creates rough waves around it.","Types":["Water","Poison"],"Resistant":["Fire","Water","Ice","Fighting","Poison","Bug","Steel","Fairy"],"Weaknesses":["Electric","Ground","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Sludge Wave","Type":"Poison","Damage":70}],"Weight":{"Minimum":"48.13kg","Maximum":"61.88kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"166 attack points.","Base Defense":"237 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":72,"Name":"Tentacool"}],"MaxCP":2046,"MaxHP":2220},{"Number":"074","Name":"Geodude","Generation":"Generation I","About":"The longer a Geodude lives, the more its edges are chipped and worn away, making it more rounded in appearance. However, this Pokémon's heart will remain hard, craggy, and rough always.","Types":["Rock","Ground"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Rock Throw","Type":"Rock","Damage":12},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Rock Slide","Type":"Rock","Damage":50},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"17.5kg","Maximum":"22.5kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"1km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"132 attack points.","Base Defense":"163 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Geodude candies"},"Next evolution(s)":[{"Number":75,"Name":"Graveler"},{"Number":76,"Name":"Golem"}],"MaxCP":742,"MaxHP":849},{"Number":"075","Name":"Graveler","Generation":"Generation I","About":"Graveler grows by feeding on rocks. Apparently, it prefers to eat rocks that are covered in moss. This Pokémon eats its way through a ton of rocks on a daily basis.","Types":["Rock","Ground"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Throw","Type":"Rock","Damage":12}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Rock Slide","Type":"Rock","Damage":50},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"91.88kg","Maximum":"118.13kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"1km (Big)","Base Stamina":"110 stamina points.","Base Attack":"164 attack points.","Base Defense":"196 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":74,"Name":"Geodude"}],"Next Evolution Requirements":{"Amount":100,"Name":"Geodude candies"},"Next evolution(s)":[{"Number":76,"Name":"Golem"}],"MaxCP":1294,"MaxHP":1433},{"Number":"076","Name":"Golem","Generation":"Generation I","About":"Golem live up on mountains. If there is a large earthquake, these Pokémon will come rolling down off the mountains en masse to the foothills below.","Types":["Rock","Ground"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Throw","Type":"Rock","Damage":12}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"262.5kg","Maximum":"337.5kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Big)","Base Stamina":"160 stamina points.","Base Attack":"211 attack points.","Base Defense":"229 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":74,"Name":"Geodude"},{"Number":75,"Name":"Graveler"}],"MaxCP":2126,"MaxHP":2303},{"Number":"077","Name":"Ponyta","Generation":"Generation I","About":"Ponyta is very weak at birth. It can barely stand up. This Pokémon becomes stronger by stumbling and falling to keep up with its parent.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flame Charge","Type":"Fire","Damage":25},{"Name":"Flame Wheel","Type":"Fire","Damage":40}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"170 attack points.","Base Defense":"132 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Ponyta candies"},"Next evolution(s)":[{"Number":78,"Name":"Rapidash"}],"MaxCP":1370,"MaxHP":1516},{"Number":"078","Name":"Rapidash","Generation":"Generation I","About":"Rapidash usually can be seen casually cantering in the fields and plains. However, when this Pokémon turns serious, its fiery manes flare and blaze as it gallops its way up to 150 mph.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Low Kick","Type":"Fighting","Damage":5}],"Special Attack(s)":[{"Name":"Drill Run","Type":"Ground","Damage":50},{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Heat Wave","Type":"Fire","Damage":80}],"Weight":{"Minimum":"83.13kg","Maximum":"106.88kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"207 attack points.","Base Defense":"167 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":77,"Name":"Ponyta"}],"MaxCP":2024,"MaxHP":2199},{"Number":"079","Name":"Slowpoke","Generation":"Generation I","About":"Slowpoke uses its tail to catch prey by dipping it in water at the side of a river. However, this Pokémon often forgets what it's doing and often spends entire days just loafing at water's edge.","Types":["Water","Psychic"],"Resistant":["Fire","Water","Ice","Fighting","Psychic","Steel"],"Weaknesses":["Electric","Grass","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Psyshock","Type":"Psychic","Damage":40},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"31.5kg","Maximum":"40.5kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"109 attack points.","Base Defense":"109 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Slowpoke candies"},"Next evolution(s)":[{"Number":80,"Name":"Slowbro"},{"Number":199,"Name":"Slowking"}],"MaxCP":1089,"MaxHP":1218},{"Number":"080","Name":"Slowbro","Generation":"Generation I","About":"Slowbro's tail has a Shellder firmly attached with a bite. As a result, the tail can't be used for fishing anymore. This causes Slowbro to grudgingly swim and catch prey instead.","Types":["Water","Psychic"],"Resistant":["Fire","Water","Ice","Fighting","Psychic","Steel"],"Weaknesses":["Electric","Grass","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Ice Beam","Type":"Ice","Damage":65},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"68.69kg","Maximum":"88.31kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Big)","Base Stamina":"190 stamina points.","Base Attack":"177 attack points.","Base Defense":"194 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":79,"Name":"Slowpoke"}],"MaxCP":2409,"MaxHP":2597},{"Number":"081","Name":"Magnemite","Generation":"Generation I","About":"Magnemite attaches itself to power lines to feed on electricity. If your house has a power outage, check your circuit breakers. You may find a large number of this Pokémon clinging to the breaker box.","Types":["Electric","Steel"],"Resistant":["Normal","Electric","Grass","Ice","Poison","Flying","Psychic","Bug","Rock","Dragon","Steel","Fairy"],"Weaknesses":["Fire","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Magnet Bomb","Type":"Steel","Damage":30},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"5.25kg","Maximum":"6.75kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"3km (Flying)","Base Stamina":"50 stamina points.","Base Attack":"165 attack points.","Base Defense":"128 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Magnemite candies"},"Next evolution(s)":[{"Number":82,"Name":"Magneton"}],"MaxCP":774,"MaxHP":890},{"Number":"082","Name":"Magneton","Generation":"Generation I","About":"Magneton emits a powerful magnetic force that is fatal to mechanical devices. As a result, large cities sound sirens to warn citizens of large-scale outbreaks of this Pokémon.","Types":["Electric","Steel"],"Resistant":["Normal","Electric","Grass","Ice","Poison","Flying","Psychic","Bug","Rock","Dragon","Steel","Fairy"],"Weaknesses":["Fire","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Flash Cannon","Type":"Steel","Damage":60},{"Name":"Magnet Bomb","Type":"Steel","Damage":30}],"Weight":{"Minimum":"52.5kg","Maximum":"67.5kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"100 stamina points.","Base Attack":"223 attack points.","Base Defense":"182 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":81,"Name":"Magnemite"}],"MaxCP":1715,"MaxHP":1879},{"Number":"083","Name":"Farfetchd","Generation":"Generation I","About":"Farfetch'd is always seen with a stalk from a plant of some sort. Apparently, there are good stalks and bad stalks. This Pokémon has been known to fight with others over stalks.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Cut","Type":"Normal","Damage":12},{"Name":"Fury Cutter","Type":"Bug","Damage":3}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Leaf Blade","Type":"Grass","Damage":55}],"Weight":{"Minimum":"13.13kg","Maximum":"16.88kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"104 stamina points.","Base Attack":"124 attack points.","Base Defense":"118 defense points.","Base Flee Rate":"9% chance to flee.","Common Capture Area":"Early reports that this Pokèmon is likely to be found in: Asia or hatched from an Egg in that geographic area.","Asia":"Common Capture Area","MaxCP":1133,"MaxHP":1263},{"Number":"084","Name":"Doduo","Generation":"Generation I","About":"Doduo's two heads never sleep at the same time. Its two heads take turns sleeping, so one head can always keep watch for enemies while the other one sleeps.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Quick Attack","Type":"Normal","Damage":10}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Drill Peck","Type":"Flying","Damage":40},{"Name":"Swift","Type":"Normal","Damage":30}],"Weight":{"Minimum":"34.3kg","Maximum":"44.1kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"3km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"158 attack points.","Base Defense":"88 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Doduo candies"},"Next evolution(s)":[{"Number":85,"Name":"Dodrio"}],"MaxCP":746,"MaxHP":855},{"Number":"085","Name":"Dodrio","Generation":"Generation I","About":"Watch out if Dodrio's three heads are looking in three separate directions. It's a sure sign that it is on its guard. Don't go near this Pokémon if it's being wary-it may decide to peck you.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Feint Attack","Type":"Dark","Damage":12},{"Name":"Steel Wing","Type":"Steel","Damage":15}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Drill Peck","Type":"Flying","Damage":40}],"Weight":{"Minimum":"74.55kg","Maximum":"95.85kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"218 attack points.","Base Defense":"145 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":84,"Name":"Doduo"}],"MaxCP":1677,"MaxHP":1836},{"Number":"086","Name":"Seel","Generation":"Generation I","About":"Seel hunts for prey in the frigid sea underneath sheets of ice. When it needs to breathe, it punches a hole through the ice with the sharply protruding section of its head.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Ice Shard","Type":"Ice","Damage":15},{"Name":"Lick","Type":"Ghost","Damage":5}],"Special Attack(s)":[{"Name":"Aqua Jet","Type":"Water","Damage":25},{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Icy Wind","Type":"Ice","Damage":25}],"Weight":{"Minimum":"78.75kg","Maximum":"101.25kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"3km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"85 attack points.","Base Defense":"128 defense points.","Base Flee Rate":"9% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Seel candies"},"Next evolution(s)":[{"Number":87,"Name":"Dewgong"}],"MaxCP":985,"MaxHP":1107},{"Number":"087","Name":"Dewgong","Generation":"Generation I","About":"Dewgong loves to snooze on bitterly cold ice. The sight of this Pokémon sleeping on a glacier was mistakenly thought to be a mermaid by a mariner long ago.","Types":["Water","Ice"],"Resistant":["Water","Ice"],"Weaknesses":["Electric","Grass","Fighting","Rock"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9},{"Name":"Ice Shard","Type":"Ice","Damage":15}],"Special Attack(s)":[{"Name":"Aqua Jet","Type":"Water","Damage":25},{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Icy Wind","Type":"Ice","Damage":25}],"Weight":{"Minimum":"105kg","Maximum":"135kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"3km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"139 attack points.","Base Defense":"184 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":86,"Name":"Seel"}],"MaxCP":1975,"MaxHP":2145},{"Number":"088","Name":"Grimer","Generation":"Generation I","About":"Grimer's sludgy and rubbery body can be forced through any opening, however small it may be. This Pokémon enters sewer pipes to drink filthy wastewater.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Mud Bomb","Type":"Ground","Damage":30},{"Name":"Sludge","Type":"Poison","Damage":30},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"135 attack points.","Base Defense":"90 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Grimer candies"},"Next evolution(s)":[{"Number":89,"Name":"Muk"}],"MaxCP":1152,"MaxHP":1284},{"Number":"089","Name":"Muk","Generation":"Generation I","About":"From Muk's body seeps a foul fluid that gives off a nose-bendingly horrible stench. Just one drop of this Pokémon's body fluid can turn a pool stagnant and rancid.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Lick","Type":"Ghost","Damage":5},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Gunk Shot","Type":"Poison","Damage":65},{"Name":"Sludge Wave","Type":"Poison","Damage":70}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Big)","Base Stamina":"210 stamina points.","Base Attack":"190 attack points.","Base Defense":"184 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":88,"Name":"Grimer"}],"MaxCP":2414,"MaxHP":2602},{"Number":"090","Name":"Shellder","Generation":"Generation I","About":"At night, this Pokémon uses its broad tongue to burrow a hole in the seafloor sand and then sleep in it. While it is sleeping, Shellder closes its shell, but leaves its tongue hanging out.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Ice Shard","Type":"Ice","Damage":15},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Icy Wind","Type":"Ice","Damage":25},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"3.5kg","Maximum":"4.5kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"3km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"116 attack points.","Base Defense":"168 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Shellder candies"},"Next evolution(s)":[{"Number":91,"Name":"Cloyster"}],"MaxCP":715,"MaxHP":822},{"Number":"091","Name":"Cloyster","Generation":"Generation I","About":"Cloyster is capable of swimming in the sea. It does so by swallowing water, then jetting it out toward the rear. This Pokémon shoots spikes from its shell using the same system.","Types":["Water","Ice"],"Resistant":["Water","Ice"],"Weaknesses":["Electric","Grass","Fighting","Rock"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9},{"Name":"Ice Shard","Type":"Ice","Damage":15}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Icy Wind","Type":"Ice","Damage":25}],"Weight":{"Minimum":"115.94kg","Maximum":"149.06kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"3km (Big)","Base Stamina":"100 stamina points.","Base Attack":"186 attack points.","Base Defense":"323 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":90,"Name":"Shellder"}],"MaxCP":1879,"MaxHP":2052},{"Number":"092","Name":"Gastly","Generation":"Generation I","About":"Gastly is largely composed of gaseous matter. When exposed to a strong wind, the gaseous body quickly dwindles away. Groups of this Pokémon cluster under the eaves of houses to escape the ravages of wind.","Types":["Ghost","Poison"],"Resistant":["Normal","Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Lick","Type":"Ghost","Damage":5},{"Name":"Sucker Punch","Type":"Dark","Damage":7}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Ominous Wind","Type":"Ghost","Damage":30},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"0.09kg","Maximum":"0.11kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Flying)","Base Stamina":"60 stamina points.","Base Attack":"186 attack points.","Base Defense":"70 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Gastly candies"},"Next evolution(s)":[{"Number":93,"Name":"Haunter"},{"Number":94,"Name":"Gengar"}],"MaxCP":696,"MaxHP":804},{"Number":"093","Name":"Haunter","Generation":"Generation I","About":"Haunter is a dangerous Pokémon. If one beckons you while floating in darkness, you must never approach it. This Pokémon will try to lick you with its tongue and steal your life away.","Types":["Ghost","Poison"],"Resistant":["Normal","Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Lick","Type":"Ghost","Damage":5},{"Name":"Shadow Claw","Type":"Ghost","Damage":11}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Shadow Ball","Type":"Ghost","Damage":45},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"0.09kg","Maximum":"0.11kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Flying)","Base Stamina":"90 stamina points.","Base Attack":"223 attack points.","Base Defense":"112 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":92,"Name":"Gastly"}],"Next Evolution Requirements":{"Amount":100,"Name":"Gastly candies"},"Next evolution(s)":[{"Number":94,"Name":"Gengar"}],"MaxCP":1240,"MaxHP":1380},{"Number":"094","Name":"Gengar","Generation":"Generation I","About":"Sometimes, on a dark night, your shadow thrown by a streetlight will suddenly and startlingly overtake you. It is actually a Gengar running past you, pretending to be your shadow.","Types":["Ghost","Poison"],"Resistant":["Normal","Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Shadow Claw","Type":"Ghost","Damage":11},{"Name":"Sucker Punch","Type":"Dark","Damage":7}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Shadow Ball","Type":"Ghost","Damage":45},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"35.44kg","Maximum":"45.56kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"261 attack points.","Base Defense":"156 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":92,"Name":"Gastly"},{"Number":93,"Name":"Haunter"}],"MaxCP":1907,"MaxHP":2078},{"Number":"095","Name":"Onix","Generation":"Generation I","About":"Onix has a magnet in its brain. It acts as a compass so that this Pokémon does not lose direction while it is tunneling. As it grows older, its body becomes increasingly rounder and smoother.","Types":["Rock","Ground"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Rock Throw","Type":"Rock","Damage":12},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Iron Head","Type":"Steel","Damage":30},{"Name":"Rock Slide","Type":"Rock","Damage":50},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"183.75kg","Maximum":"236.25kg"},"Height":{"Minimum":"7.7m","Maximum":"9.9m"},"Buddy Distance":"5km (Big)","Base Stamina":"70 stamina points.","Base Attack":"85 attack points.","Base Defense":"288 defense points.","Base Flee Rate":"9% chance to flee.","Next evolution(s)":[{"Number":208,"Name":"Steelix"}],"MaxCP":745,"MaxHP":857},{"Number":"096","Name":"Drowzee","Generation":"Generation I","About":"If your nose becomes itchy while you are sleeping, it's a sure sign that one of these Pokémon is standing above your pillow and trying to eat you dream through your nostrils.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Psybeam","Type":"Psychic","Damage":40},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Psyshock","Type":"Psychic","Damage":40}],"Weight":{"Minimum":"28.35kg","Maximum":"36.45kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"89 attack points.","Base Defense":"158 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Drowzee candies"},"Next evolution(s)":[{"Number":97,"Name":"Hypno"}],"MaxCP":955,"MaxHP":1075},{"Number":"097","Name":"Hypno","Generation":"Generation I","About":"Hypno holds a pendulum in its hand. The arcing movement and glitter of the pendulum lull the foe into a deep state of hypnosis. While this Pokémon searches for prey, it polishes the pendulum.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Psyshock","Type":"Psychic","Damage":40},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"66.15kg","Maximum":"85.05kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Big)","Base Stamina":"170 stamina points.","Base Attack":"144 attack points.","Base Defense":"215 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":96,"Name":"Drowzee"}],"MaxCP":2012,"MaxHP":2184},{"Number":"098","Name":"Krabby","Generation":"Generation I","About":"Krabby live on beaches, burrowed inside holes dug into the sand. On sandy beaches with little in the way of food, these Pokémon can be seen squabbling with each other over territory.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Vice Grip","Type":"Normal","Damage":25},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"5.69kg","Maximum":"7.31kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"181 attack points.","Base Defense":"156 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Krabby candies"},"Next evolution(s)":[{"Number":99,"Name":"Kingler"}],"MaxCP":686,"MaxHP":792},{"Number":"099","Name":"Kingler","Generation":"Generation I","About":"Kingler has an enormous, oversized claw. It waves this huge claw in the air to communicate with others. However, because the claw is so heavy, the Pokémon quickly tires.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Metal Claw","Type":"Steel","Damage":8},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Vice Grip","Type":"Normal","Damage":25},{"Name":"Water Pulse","Type":"Water","Damage":35},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"52.5kg","Maximum":"67.5kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Big)","Base Stamina":"110 stamina points.","Base Attack":"240 attack points.","Base Defense":"214 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":98,"Name":"Krabby"}],"MaxCP":1663,"MaxHP":1823},{"Number":"100","Name":"Voltorb","Generation":"Generation I","About":"Voltorb was first sighted at a company that manufactures Poké Balls. The link between that sighting and the fact that this Pokémon looks very similar to a Poké Ball remains a mystery.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Signal Beam","Type":"Bug","Damage":45},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"9.1kg","Maximum":"11.7kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"3km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"109 attack points.","Base Defense":"114 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Voltorb candies"},"Next evolution(s)":[{"Number":101,"Name":"Electrode"}],"MaxCP":733,"MaxHP":839},{"Number":"101","Name":"Electrode","Generation":"Generation I","About":"Electrode eats electricity in the atmosphere. On days when lightning strikes, you can see this Pokémon exploding all over the place from eating too much electricity.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"58.27kg","Maximum":"74.92kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"173 attack points.","Base Defense":"179 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":100,"Name":"Voltorb"}],"MaxCP":1496,"MaxHP":1646},{"Number":"102","Name":"Exeggcute","Generation":"Generation I","About":"This Pokémon consists of six eggs that form a closely knit cluster. The six eggs attract each other and spin around. When cracks increasingly appear on the eggs, Exeggcute is close to evolution.","Types":["Grass","Psychic"],"Resistant":["Water","Electric","Grass","Fighting","Ground","Psychic"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Seed Bomb","Type":"Grass","Damage":40}],"Weight":{"Minimum":"2.19kg","Maximum":"2.81kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"107 attack points.","Base Defense":"140 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"E"},"Next evolution(s)":[{"Number":103,"Name":"Exeggutor"}],"MaxCP":978,"MaxHP":1099},{"Number":"103","Name":"Exeggutor","Generation":"Generation I","About":"Exeggutor originally came from the tropics. Its heads steadily grow larger from exposure to strong sunlight. It is said that when the heads fall off, they group together to form Exeggcute.","Types":["Grass","Psychic"],"Resistant":["Water","Electric","Grass","Fighting","Ground","Psychic"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Seed Bomb","Type":"Grass","Damage":40},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"105kg","Maximum":"135kg"},"Height":{"Minimum":"1.75m","Maximum":"2.25m"},"Buddy Distance":"3km (Big)","Base Stamina":"190 stamina points.","Base Attack":"233 attack points.","Base Defense":"158 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":102,"Name":"Exeggcute"}],"MaxCP":2752,"MaxHP":2955},{"Number":"104","Name":"Cubone","Generation":"Generation I","About":"Cubone pines for the mother it will never see again. Seeing a likeness of its mother in the full moon, it cries. The stains on the skull the Pokémon wears are made by the tears it sheds.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Bone Club","Type":"Ground","Damage":25},{"Name":"Bulldoze","Type":"Ground","Damage":35},{"Name":"Dig","Type":"Ground","Damage":70}],"Weight":{"Minimum":"5.69kg","Maximum":"7.31kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"90 attack points.","Base Defense":"165 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Cubone candies"},"Next evolution(s)":[{"Number":105,"Name":"Marowak"}],"MaxCP":889,"MaxHP":1006},{"Number":"105","Name":"Marowak","Generation":"Generation I","About":"Marowak is the evolved form of a Cubone that has overcome its sadness at the loss of its mother and grown tough. This Pokémon's tempered and hardened spirit is not easily broken.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Bone Club","Type":"Ground","Damage":25},{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Earthquake","Type":"Ground","Damage":100}],"Weight":{"Minimum":"39.38kg","Maximum":"50.63kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"144 attack points.","Base Defense":"200 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":104,"Name":"Cubone"}],"MaxCP":1505,"MaxHP":1656},{"Number":"106","Name":"Hitmonlee","Generation":"Generation I","About":"Hitmonlee's legs freely contract and stretch. Using these springlike legs, it bowls over foes with devastating kicks. After battle, it rubs down its legs and loosens the muscles to overcome fatigue.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Low Kick","Type":"Fighting","Damage":5},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Low Sweep","Type":"Fighting","Damage":30},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"43.57kg","Maximum":"56.02kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"5km (Big)","Base Stamina":"100 stamina points.","Base Attack":"224 attack points.","Base Defense":"211 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":236,"Name":"Tyrogue"}],"MaxCP":1349,"MaxHP":1492},{"Number":"107","Name":"Hitmonchan","Generation":"Generation I","About":"Hitmonchan is said to possess the spirit of a boxer who had been working toward a world championship. This Pokémon has an indomitable spirit and will never give up in the face of adversity.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Bullet Punch","Type":"Steel","Damage":10},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Fire Punch","Type":"Fire","Damage":40},{"Name":"Ice Punch","Type":"Ice","Damage":45},{"Name":"Thunder Punch","Type":"Electric","Damage":40}],"Weight":{"Minimum":"43.93kg","Maximum":"56.48kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"5km (Big)","Base Stamina":"100 stamina points.","Base Attack":"193 attack points.","Base Defense":"212 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":236,"Name":"Tyrogue"}],"MaxCP":1370,"MaxHP":1516},{"Number":"108","Name":"Lickitung","Generation":"Generation I","About":"Whenever Lickitung comes across something new, it will unfailingly give it a lick. It does so because it memorizes things by texture and by taste. It is somewhat put off by sour things.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Lick","Type":"Ghost","Damage":5},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Stomp","Type":"Normal","Damage":30}],"Weight":{"Minimum":"57.31kg","Maximum":"73.69kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"108 attack points.","Base Defense":"137 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":1477,"MaxHP":1626},{"Number":"109","Name":"Koffing","Generation":"Generation I","About":"If Koffing becomes agitated, it raises the toxicity of its internal gases and then jets them out from all over its body. This Pokémon may also overinflate its round body, then explode.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Sludge","Type":"Poison","Damage":30},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"0.88kg","Maximum":"1.13kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Big)","Base Stamina":"80 stamina points.","Base Attack":"119 attack points.","Base Defense":"164 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Koffing candies"},"Next evolution(s)":[{"Number":110,"Name":"Weezing"}],"MaxCP":1025,"MaxHP":1151},{"Number":"110","Name":"Weezing","Generation":"Generation I","About":"Weezing loves the gases given off by rotted kitchen garbage. This Pokémon will find a dirty, unkempt house and make it its home. At night, when the people in the house are asleep, it will go through the trash.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Shadow Ball","Type":"Ghost","Damage":45},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"8.31kg","Maximum":"10.69kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"174 attack points.","Base Defense":"221 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":109,"Name":"Koffing"}],"MaxCP":2073,"MaxHP":2250},{"Number":"111","Name":"Rhyhorn","Generation":"Generation I","About":"Rhyhorn runs in a straight line, smashing everything in its path. It is not bothered even if it rushes headlong into a block of steel. This Pokémon may feel some pain from the collision the next day, however.","Types":["Ground","Rock"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Bulldoze","Type":"Ground","Damage":35},{"Name":"Horn Attack","Type":"Normal","Damage":25},{"Name":"Stomp","Type":"Normal","Damage":30}],"Weight":{"Minimum":"100.63kg","Maximum":"129.38kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"140 attack points.","Base Defense":"157 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Rhyhorn candies"},"Next evolution(s)":[{"Number":112,"Name":"Rhydon"}],"MaxCP":1055,"MaxHP":1182},{"Number":"112","Name":"Rhydon","Generation":"Generation I","About":"Rhydon's horn can crush even uncut diamonds. One sweeping blow of its tail can topple a building. This Pokémon's hide is extremely tough. Even direct cannon hits don't leave a scratch.","Types":["Ground","Rock"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Megahorn","Type":"Bug","Damage":80},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"105kg","Maximum":"135kg"},"Height":{"Minimum":"1.66m","Maximum":"2.14m"},"Buddy Distance":"3km (Big)","Base Stamina":"210 stamina points.","Base Attack":"222 attack points.","Base Defense":"206 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":111,"Name":"Rhyhorn"}],"MaxCP":2068,"MaxHP":2243},{"Number":"113","Name":"Chansey","Generation":"Generation I","About":"Chansey lays nutritionally excellent eggs on an everyday basis. The eggs are so delicious, they are easily and eagerly devoured by even those people who have lost their appetite.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Pound","Type":"Normal","Damage":7},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Psychic","Type":"Psychic","Damage":55}],"Weight":{"Minimum":"30.27kg","Maximum":"38.92kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"5km (Big)","Base Stamina":"500 stamina points.","Base Attack":"60 attack points.","Base Defense":"176 defense points.","Base Flee Rate":"9% chance to flee.","Next evolution(s)":[{"Number":242,"Name":"Blissey"}],"MaxCP":549,"MaxHP":675},{"Number":"114","Name":"Tangela","Generation":"Generation I","About":"Tangela's vines snap off easily if they are grabbed. This happens without pain, allowing it to make a quick getaway. The lost vines are replaced by newly grown vines the very next day.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"30.63kg","Maximum":"39.38kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"183 attack points.","Base Defense":"205 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":1586,"MaxHP":1739},{"Number":"115","Name":"Kangaskhan","Generation":"Generation I","About":"If you come across a young Kangaskhan playing by itself, you must never disturb it or attempt to catch it. The baby Pokémon's parent is sure to be in the area, and it will become violently enraged at you.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Low Kick","Type":"Fighting","Damage":5},{"Name":"Mud Slap","Type":"Ground","Damage":15}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Stomp","Type":"Normal","Damage":30}],"Weight":{"Minimum":"70kg","Maximum":"90kg"},"Height":{"Minimum":"1.93m","Maximum":"2.48m"},"Buddy Distance":"3km (Big)","Base Stamina":"210 stamina points.","Base Attack":"181 attack points.","Base Defense":"165 defense points.","Base Flee Rate":"9% chance to flee.","Common Capture Area":"Early reports that this Pokèmon is likely to be found in: Australia, New Zealand or hatched from an Egg in that geographic area.","Australia, New Zealand":"Common Capture Area","MaxCP":1875,"MaxHP":2043},{"Number":"116","Name":"Horsea","Generation":"Generation I","About":"Horsea eats small insects and moss off of rocks. If the ocean current turns fast, this Pokémon anchors itself by wrapping its tail around rocks or coral to prevent being washed away.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Flash Cannon","Type":"Steel","Damage":60}],"Weight":{"Minimum":"7kg","Maximum":"9kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"129 attack points.","Base Defense":"125 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Horsea candies"},"Next evolution(s)":[{"Number":117,"Name":"Seadra"},{"Number":230,"Name":"Kingdra"}],"MaxCP":688,"MaxHP":794},{"Number":"117","Name":"Seadra","Generation":"Generation I","About":"Seadra sleeps after wriggling itself between the branches of coral. Those trying to harvest coral are occasionally stung by this Pokémon's poison barbs if they fail to notice it.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Dragon Breath","Type":"Dragon","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Hydro Pump","Type":"Water","Damage":90}],"Weight":{"Minimum":"21.88kg","Maximum":"28.13kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Big)","Base Stamina":"110 stamina points.","Base Attack":"187 attack points.","Base Defense":"182 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":116,"Name":"Horsea"}],"Next evolution(s)":[{"Number":230,"Name":"Kingdra"}],"MaxCP":1559,"MaxHP":1713},{"Number":"118","Name":"Goldeen","Generation":"Generation I","About":"Goldeen is a very beautiful Pokémon with fins that billow elegantly in water. However, don't let your guard down around this Pokémon—it could ram you powerfully with its horn.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Mud Shot","Type":"Ground","Damage":6},{"Name":"Peck","Type":"Flying","Damage":10}],"Special Attack(s)":[{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Horn Attack","Type":"Normal","Damage":25},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"13.13kg","Maximum":"16.88kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"123 attack points.","Base Defense":"115 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Goldeen candies"},"Next evolution(s)":[{"Number":119,"Name":"Seaking"}],"MaxCP":851,"MaxHP":965},{"Number":"119","Name":"Seaking","Generation":"Generation I","About":"In the autumn, Seaking males can be seen performing courtship dances in riverbeds to woo females. During this season, this Pokémon's body coloration is at its most beautiful.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Drill Run","Type":"Ground","Damage":50},{"Name":"Icy Wind","Type":"Ice","Damage":25},{"Name":"Megahorn","Type":"Bug","Damage":80}],"Weight":{"Minimum":"34.13kg","Maximum":"43.88kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"175 attack points.","Base Defense":"154 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":118,"Name":"Goldeen"}],"MaxCP":1877,"MaxHP":2043},{"Number":"120","Name":"Staryu","Generation":"Generation I","About":"Staryu's center section has an organ called the core that shines bright red. If you go to a beach toward the end of summer, the glowing cores of these Pokémon look like the stars in the sky.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Power Gem","Type":"Rock","Damage":40},{"Name":"Swift","Type":"Normal","Damage":30}],"Weight":{"Minimum":"30.19kg","Maximum":"38.81kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"137 attack points.","Base Defense":"112 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Staryu candies"},"Next evolution(s)":[{"Number":121,"Name":"Starmie"}],"MaxCP":821,"MaxHP":937},{"Number":"121","Name":"Starmie","Generation":"Generation I","About":"Starmie's center section-the core-glows brightly in seven colors. Because of its luminous nature, this Pokémon has been given the nickname the gem of the sea.\"\"","Types":["Water","Psychic"],"Resistant":["Fire","Water","Ice","Fighting","Psychic","Steel"],"Weaknesses":["Electric","Grass","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Power Gem","Type":"Rock","Damage":40},{"Name":"Psychic","Type":"Psychic","Damage":55}],"Weight":{"Minimum":"70kg","Maximum":"90kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"210 attack points.","Base Defense":"184 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":120,"Name":"Staryu"}],"MaxCP":2007,"MaxHP":2182},{"Number":"122","Name":"Mr Mime","Generation":"Generation I","About":"Mr. Mime is a master of pantomime. Its gestures and motions convince watchers that something unseeable actually exists. Once the watchers are convinced, the unseeable thing exists as if it were real.","Types":["Psychic","Fairy"],"Resistant":["Fighting","Psychic","Dragon"],"Weaknesses":["Poison","Ghost","Steel"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Psybeam","Type":"Psychic","Damage":40},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"47.69kg","Maximum":"61.31kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"5km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"192 attack points.","Base Defense":"233 defense points.","Base Flee Rate":"9% chance to flee.","Common Capture Area":"Early reports that this Pokèmon is likely to be found in: Western Europe or hatched from an Egg in that geographic area.","Western Europe":"Common Capture Area","MaxCP":1345,"MaxHP":1494},{"Number":"123","Name":"Scyther","Generation":"Generation I","About":"Scyther is blindingly fast. Its blazing speed enhances the effectiveness of the twin scythes on its forearms. This Pokémon's scythes are so effective, they can slice through thick logs in one wicked stroke.","Types":["Bug","Flying"],"Resistant":["Grass","Fighting","Ground","Bug"],"Weaknesses":["Fire","Electric","Ice","Flying","Rock"],"Fast Attack(s)":[{"Name":"Fury Cutter","Type":"Bug","Damage":3},{"Name":"Steel Wing","Type":"Steel","Damage":15}],"Special Attack(s)":[{"Name":"Bug Buzz","Type":"Bug","Damage":75},{"Name":"Night Slash","Type":"Dark","Damage":30},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"49kg","Maximum":"63kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"5km (Big)","Base Stamina":"140 stamina points.","Base Attack":"218 attack points.","Base Defense":"170 defense points.","Base Flee Rate":"9% chance to flee.","Next evolution(s)":[{"Number":212,"Name":"Scizor"}],"MaxCP":1905,"MaxHP":2073},{"Number":"124","Name":"Jynx","Generation":"Generation I","About":"Jynx walks rhythmically, swaying and shaking its hips as if it were dancing. Its motions are so bouncingly alluring, people seeing it are compelled to shake their hips without giving any thought to what they are doing.","Types":["Ice","Psychic"],"Resistant":["Ice","Psychic"],"Weaknesses":["Fire","Bug","Rock","Ghost","Dark","Steel"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Draining Kiss","Type":"Fairy","Damage":25},{"Name":"Ice Punch","Type":"Ice","Damage":45},{"Name":"Psyshock","Type":"Psychic","Damage":40}],"Weight":{"Minimum":"35.52kg","Maximum":"45.67kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"5km (Big)","Base Stamina":"130 stamina points.","Base Attack":"223 attack points.","Base Defense":"182 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":238,"Name":"Smoochum"}],"MaxCP":1563,"MaxHP":1716},{"Number":"125","Name":"Electabuzz","Generation":"Generation I","About":"When a storm arrives, gangs of this Pokémon compete with each other to scale heights that are likely to be stricken by lightning bolts. Some towns use Electabuzz in place of lightning rods.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Low Kick","Type":"Fighting","Damage":5},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Thunder","Type":"Electric","Damage":100},{"Name":"Thunder Punch","Type":"Electric","Damage":40},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"5km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"198 attack points.","Base Defense":"173 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":239,"Name":"Elekid"}],"MaxCP":1947,"MaxHP":2119},{"Number":"126","Name":"Magmar","Generation":"Generation I","About":"In battle, Magmar blows out intensely hot flames from all over its body to intimidate its opponent. This Pokémon's fiery bursts create heat waves that ignite grass and trees in its surroundings.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Karate Chop","Type":"Fighting","Damage":6}],"Special Attack(s)":[{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Fire Punch","Type":"Fire","Damage":40},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"38.94kg","Maximum":"50.06kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"5km (Big)","Base Stamina":"130 stamina points.","Base Attack":"206 attack points.","Base Defense":"169 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":240,"Name":"Magby"}],"MaxCP":2086,"MaxHP":2265},{"Number":"127","Name":"Pinsir","Generation":"Generation I","About":"Pinsir is astoundingly strong. It can grip a foe weighing twice its weight in its horns and easily lift it. This Pokémon's movements turn sluggish in cold places.","Types":["Bug"],"Resistant":["Grass","Fighting","Ground"],"Weaknesses":["Fire","Flying","Rock"],"Fast Attack(s)":[{"Name":"Fury Cutter","Type":"Bug","Damage":3},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Submission","Type":"Fighting","Damage":30},{"Name":"Vice Grip","Type":"Normal","Damage":25},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"48.13kg","Maximum":"61.88kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"5km (Big)","Base Stamina":"130 stamina points.","Base Attack":"238 attack points.","Base Defense":"197 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":1950,"MaxHP":2121},{"Number":"128","Name":"Tauros","Generation":"Generation I","About":"This Pokémon is not satisfied unless it is rampaging at all times. If there is no opponent for Tauros to battle, it will charge at thick trees and knock them down to calm itself.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Horn Attack","Type":"Normal","Damage":25},{"Name":"Iron Head","Type":"Steel","Damage":30}],"Weight":{"Minimum":"77.35kg","Maximum":"99.45kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"3km (Big)","Base Stamina":"150 stamina points.","Base Attack":"198 attack points.","Base Defense":"197 defense points.","Base Flee Rate":"9% chance to flee.","Common Capture Area":"Early reports that this Pokèmon is likely to be found in: North America or hatched from an Egg in that geographic area.","North America":"Common Capture Area","MaxCP":1686,"MaxHP":1844},{"Number":"129","Name":"Magikarp","Generation":"Generation I","About":"Magikarp is a pathetic excuse for a Pokémon that is only capable of flopping and splashing. This behavior prompted scientists to undertake research into it.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Splash","Type":"Water","Damage":0}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"8.75kg","Maximum":"11.25kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"1km (Medium)","Base Stamina":"40 stamina points.","Base Attack":"29 attack points.","Base Defense":"102 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":400,"Name":"Magikarp candies"},"Next evolution(s)":[{"Number":130,"Name":"Gyarados"}],"MaxCP":203,"MaxHP":262},{"Number":"130","Name":"Gyarados","Generation":"Generation I","About":"When Magikarp evolves into Gyarados, its brain cells undergo a structural transformation. It is said that this transformation is to blame for this Pokémon's wildly violent nature.","Types":["Water","Flying"],"Resistant":["Fire","Water","Fighting","Ground","Bug","Steel"],"Weaknesses":["Electric","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6}],"Special Attack(s)":[{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Twister","Type":"Dragon","Damage":25}],"Weight":{"Minimum":"205.63kg","Maximum":"264.38kg"},"Height":{"Minimum":"5.69m","Maximum":"7.31m"},"Buddy Distance":"1km (Big)","Base Stamina":"190 stamina points.","Base Attack":"237 attack points.","Base Defense":"197 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":129,"Name":"Magikarp"}],"MaxCP":2498,"MaxHP":2688},{"Number":"131","Name":"Lapras","Generation":"Generation I","About":"People have driven Lapras almost to the point of extinction. In the evenings, this Pokémon is said to sing plaintively as it seeks what few others of its kind still remain.","Types":["Water","Ice"],"Resistant":["Water","Ice"],"Weaknesses":["Electric","Grass","Fighting","Rock"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9},{"Name":"Ice Shard","Type":"Ice","Damage":15}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Ice Beam","Type":"Ice","Damage":65}],"Weight":{"Minimum":"192.5kg","Maximum":"247.5kg"},"Height":{"Minimum":"2.19m","Maximum":"2.81m"},"Buddy Distance":"5km (Big)","Base Stamina":"260 stamina points.","Base Attack":"186 attack points.","Base Defense":"190 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":2777,"MaxHP":2980},{"Number":"132","Name":"Ditto","Generation":"Generation I","About":"Ditto rearranges its cell structure to transform itself into other shapes. However, if it tries to transform itself into something by relying on its memory, this Pokémon manages to get details wrong.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Transform","Type":"Normal","Damage":0}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"3.5kg","Maximum":"4.5kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"3km (Medium)","Base Stamina":"96 stamina points.","Base Attack":"91 attack points.","Base Defense":"91 defense points.","Base Flee Rate":"10% chance to flee.","MaxCP":809,"MaxHP":919},{"Number":"133","Name":"Eevee","Generation":"Generation I","About":"Eevee has an unstable genetic makeup that suddenly mutates due to the environment in which it lives. Radiation from various stones causes this Pokémon to evolve.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Swift","Type":"Normal","Damage":30}],"Weight":{"Minimum":"5.69kg","Maximum":"7.31kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"5km (Shoulder)","Base Stamina":"110 stamina points.","Base Attack":"104 attack points.","Base Defense":"121 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Eevee candies"},"Next evolution(s)":[{"Number":134,"Name":"Vaporeon"},{"Number":135,"Name":"Jolteon"},{"Number":136,"Name":"Flareon"},{"Number":196,"Name":"Espeon"},{"Number":197,"Name":"Umbreon"}],"MaxCP":957,"MaxHP":1077},{"Number":"134","Name":"Vaporeon","Generation":"Generation I","About":"Vaporeon underwent a spontaneous mutation and grew fins and gills that allow it to live underwater. This Pokémon has the ability to freely control water.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"25.38kg","Maximum":"32.63kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"5km (Medium)","Base Stamina":"260 stamina points.","Base Attack":"205 attack points.","Base Defense":"177 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":133,"Name":"Eevee"}],"MaxCP":2618,"MaxHP":2816},{"Number":"135","Name":"Jolteon","Generation":"Generation I","About":"Jolteon's cells generate a low level of electricity. This power is amplified by the static electricity of its fur, enabling the Pokémon to drop thunderbolts. The bristling fur is made of electrically charged needles.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Thunder","Type":"Electric","Damage":100},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"21.44kg","Maximum":"27.56kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"5km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"232 attack points.","Base Defense":"201 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":133,"Name":"Eevee"}],"MaxCP":1968,"MaxHP":2140},{"Number":"136","Name":"Flareon","Generation":"Generation I","About":"Flareon's fluffy fur has a functional purpose-it releases heat into the air so that its body does not get excessively hot. This Pokémon's body temperature can rise to a maximum of 1,650 degrees Fahrenheit.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10}],"Special Attack(s)":[{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flamethrower","Type":"Fire","Damage":55},{"Name":"Heat Wave","Type":"Fire","Damage":80}],"Weight":{"Minimum":"21.88kg","Maximum":"28.13kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"5km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"246 attack points.","Base Defense":"204 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":133,"Name":"Eevee"}],"MaxCP":2448,"MaxHP":2643},{"Number":"137","Name":"Porygon","Generation":"Generation I","About":"Porygon is capable of reverting itself entirely back to program data and entering cyberspace. This Pokémon is copy-protected so it cannot be duplicated by copying.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Psybeam","Type":"Psychic","Damage":40},{"Name":"Signal Beam","Type":"Bug","Damage":45}],"Weight":{"Minimum":"31.94kg","Maximum":"41.06kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"153 attack points.","Base Defense":"139 defense points.","Base Flee Rate":"9% chance to flee.","Next evolution(s)":[{"Number":233,"Name":"Porygon2"}],"MaxCP":1540,"MaxHP":1691},{"Number":"138","Name":"Omanyte","Generation":"Generation I","About":"Omanyte is one of the ancient and long-since-extinct Pokémon that have been regenerated from fossils by people. If attacked by an enemy, it withdraws itself inside its hard shell.","Types":["Rock","Water"],"Resistant":["Normal","Fire","Ice","Poison","Flying"],"Weaknesses":["Electric","Grass","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Mud Shot","Type":"Ground","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Brine","Type":"Water","Damage":25},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"6.56kg","Maximum":"8.44kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"5km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"155 attack points.","Base Defense":"174 defense points.","Base Flee Rate":"9% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Omanyte candies"},"Next evolution(s)":[{"Number":139,"Name":"Omastar"}],"MaxCP":992,"MaxHP":1119},{},{"Number":"140","Name":"Kabuto","Generation":"Generation I","About":"Kabuto is a Pokémon that has been regenerated from a fossil. However, in extremely rare cases, living examples have been discovered. The Pokémon has not changed at all for 300 million years.","Types":["Rock","Water"],"Resistant":["Normal","Fire","Ice","Poison","Flying"],"Weaknesses":["Electric","Grass","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Mud Shot","Type":"Ground","Damage":6},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Aqua Jet","Type":"Water","Damage":25},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"10.06kg","Maximum":"12.94kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"5km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"148 attack points.","Base Defense":"162 defense points.","Base Flee Rate":"9% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Kabuto candies"},"Next evolution(s)":[{"Number":141,"Name":"Kabutops"}],"MaxCP":975,"MaxHP":1104},{"Number":"141","Name":"Kabutops","Generation":"Generation I","About":"Kabutops swam underwater to hunt for its prey in ancient times. The Pokémon was apparently evolving from being a water-dweller to living on land as evident from the beginnings of change in its gills and legs.","Types":["Rock","Water"],"Resistant":["Normal","Fire","Ice","Poison","Flying"],"Weaknesses":["Electric","Grass","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Fury Cutter","Type":"Bug","Damage":3},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Stone Edge","Type":"Rock","Damage":80},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"35.44kg","Maximum":"45.56kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"5km (Big)","Base Stamina":"120 stamina points.","Base Attack":"220 attack points.","Base Defense":"203 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":140,"Name":"Kabuto"}],"MaxCP":1957,"MaxHP":2130},{"Number":"142","Name":"Aerodactyl","Generation":"Generation I","About":"Aerodactyl is a Pokémon from the age of dinosaurs. It was regenerated from genetic material extracted from amber. It is imagined to have been the king of the skies in ancient times.","Types":["Rock","Flying"],"Resistant":["Normal","Fire","Poison","Flying","Bug"],"Weaknesses":["Water","Electric","Ice","Rock","Steel"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Steel Wing","Type":"Steel","Damage":15}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Iron Head","Type":"Steel","Damage":30}],"Weight":{"Minimum":"51.63kg","Maximum":"66.38kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"5km (Big)","Base Stamina":"160 stamina points.","Base Attack":"221 attack points.","Base Defense":"164 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":1994,"MaxHP":2165},{"Number":"143","Name":"Snorlax","Generation":"Generation I","About":"Snorlax's typical day consists of nothing more than eating and sleeping. It is such a docile Pokémon that there are children who use its expansive belly as a place to play.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Lick","Type":"Ghost","Damage":5},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Hyper Beam","Type":"Normal","Damage":120}],"Weight":{"Minimum":"402.5kg","Maximum":"517.5kg"},"Height":{"Minimum":"1.84m","Maximum":"2.36m"},"Buddy Distance":"5km (Big)","Base Stamina":"320 stamina points.","Base Attack":"190 attack points.","Base Defense":"190 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":2901,"MaxHP":3112},{"Number":"144","Name":"Articuno","Generation":"Generation I","About":"Articuno is a legendary bird Pokémon that can control ice. The flapping of its wings chills the air. As a result, it is said that when this Pokémon flies, snow will fall.","Types":["Ice","Flying"],"Resistant":["Grass","Ground","Bug"],"Weaknesses":["Fire","Electric","Rock","Steel"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Ice Beam","Type":"Ice","Damage":65},{"Name":"Icy Wind","Type":"Ice","Damage":25}],"Weight":{"Minimum":"48.48kg","Maximum":"62.33kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"5km (Flying)","Base Stamina":"180 stamina points.","Base Attack":"192 attack points.","Base Defense":"249 defense points.","Base Flee Rate":"10% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class","MaxCP":2776,"MaxHP":2978},{"Number":"145","Name":"Zapdos","Generation":"Generation I","About":"Zapdos is a legendary bird Pokémon that has the ability to control electricity. It usually lives in thunderclouds. The Pokémon gains power if it is stricken by lightning bolts.","Types":["Electric","Flying"],"Resistant":["Grass","Fighting","Flying","Bug","Steel"],"Weaknesses":["Ice","Rock"],"Fast Attack(s)":[{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Thunder","Type":"Electric","Damage":100},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"46.02kg","Maximum":"59.17kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"5km (Flying)","Base Stamina":"180 stamina points.","Base Attack":"253 attack points.","Base Defense":"188 defense points.","Base Flee Rate":"10% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class","MaxCP":2907,"MaxHP":3114},{"Number":"146","Name":"Moltres","Generation":"Generation I","About":"Moltres is a legendary bird Pokémon that has the ability to control fire. If this Pokémon is injured, it is said to dip its body in the molten magma of a volcano to burn and heal itself.","Types":["Fire","Flying"],"Resistant":["Fire","Grass","Fighting","Bug","Steel","Fairy"],"Weaknesses":["Water","Electric","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10}],"Special Attack(s)":[{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flamethrower","Type":"Fire","Damage":55},{"Name":"Heat Wave","Type":"Fire","Damage":80}],"Weight":{"Minimum":"52.5kg","Maximum":"67.5kg"},"Height":{"Minimum":"1.75m","Maximum":"2.25m"},"Buddy Distance":"5km (Big)","Base Stamina":"180 stamina points.","Base Attack":"251 attack points.","Base Defense":"184 defense points.","Base Flee Rate":"10% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class","MaxCP":3028,"MaxHP":3240},{"Number":"147","Name":"Dratini","Generation":"Generation I","About":"Dratini continually molts and sloughs off its old skin. It does so because the life energy within its body steadily builds to reach uncontrollable levels.","Types":["Dragon"],"Resistant":["Fire","Water","Electric","Grass"],"Weaknesses":["Ice","Dragon","Fairy"],"Fast Attack(s)":[{"Name":"Dragon Breath","Type":"Dragon","Damage":6}],"Special Attack(s)":[{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Twister","Type":"Dragon","Damage":25},{"Name":"Wrap","Type":"Normal","Damage":25}],"Weight":{"Minimum":"2.89kg","Maximum":"3.71kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"5km (Medium)","Base Stamina":"82 stamina points.","Base Attack":"119 attack points.","Base Defense":"94 defense points.","Base Flee Rate":"9% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Dratini candies"},"Next evolution(s)":[{"Number":148,"Name":"Dragonair"},{"Number":149,"Name":"Dragonite"}],"MaxCP":867,"MaxHP":983},{"Number":"148","Name":"Dragonair","Generation":"Generation I","About":"Dragonair stores an enormous amount of energy inside its body. It is said to alter weather conditions in its vicinity by discharging energy from its crystals on its neck and tail.","Types":["Dragon"],"Resistant":["Fire","Water","Electric","Grass"],"Weaknesses":["Ice","Dragon","Fairy"],"Fast Attack(s)":[{"Name":"Dragon Breath","Type":"Dragon","Damage":6}],"Special Attack(s)":[{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Wrap","Type":"Normal","Damage":25}],"Weight":{"Minimum":"14.44kg","Maximum":"18.56kg"},"Height":{"Minimum":"3.5m","Maximum":"4.5m"},"Buddy Distance":"5km (Big)","Base Stamina":"122 stamina points.","Base Attack":"163 attack points.","Base Defense":"138 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":147,"Name":"Dratini"}],"Next Evolution Requirements":{"Amount":100,"Name":"Dratini candies"},"Next evolution(s)":[{"Number":149,"Name":"Dragonite"}],"MaxCP":1593,"MaxHP":1747},{"Number":"149","Name":"Dragonite","Generation":"Generation I","About":"Dragonite is capable of circling the globe in just 16 hours. It is a kindhearted Pokémon that leads lost and foundering ships in a storm to the safety of land.","Types":["Dragon","Flying"],"Resistant":["Fire","Water","Grass","Fighting","Ground","Bug"],"Weaknesses":["Ice","Rock","Dragon","Fairy"],"Fast Attack(s)":[{"Name":"Dragon Breath","Type":"Dragon","Damage":6},{"Name":"Steel Wing","Type":"Steel","Damage":15}],"Special Attack(s)":[{"Name":"Dragon Claw","Type":"Dragon","Damage":35},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Hyper Beam","Type":"Normal","Damage":120}],"Weight":{"Minimum":"183.75kg","Maximum":"236.25kg"},"Height":{"Minimum":"1.93m","Maximum":"2.48m"},"Buddy Distance":"5km (Big)","Base Stamina":"182 stamina points.","Base Attack":"263 attack points.","Base Defense":"201 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":147,"Name":"Dratini"},{"Number":148,"Name":"Dragonair"}],"MaxCP":3280,"MaxHP":3500},{"Number":"150","Name":"Mewtwo","Generation":"Generation I","About":"Mewtwo is a Pokémon that was created by genetic manipulation. However, even though the scientific power of humans created this Pokémon's body, they failed to endow Mewtwo with a compassionate heart","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Psycho Cut","Type":"Psychic","Damage":7}],"Special Attack(s)":[{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"106.75kg","Maximum":"137.25kg"},"Height":{"Minimum":"1.75m","Maximum":"2.25m"},"Buddy Distance":"5km (Big)","Base Stamina":"212 stamina points.","Base Attack":"330 attack points.","Base Defense":"200 defense points.","Base Flee Rate":"10% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class","MaxCP":3904,"MaxHP":4144},{"Number":"151","Name":"Mew","Generation":"Generation I","About":"Mew is said to possess the genetic composition of all Pokémon. It is capable of making itself invisible at will, so it entirely avoids notice even if it approaches people.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Solar Beam","Type":"Grass","Damage":120},{"Name":"Thunder","Type":"Electric","Damage":100}],"Weight":{"Minimum":"3.5kg","Maximum":"4.5kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"5km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"210 attack points.","Base Defense":"210 defense points.","Base Flee Rate":"10% chance to flee.","Pokèmon Class":"This is a MYTHIC Pokèmon.","MYTHIC":"Pokèmon Class","MaxCP":3087,"MaxHP":3299},{"Number":"152","Name":"Chikorita","Generation":"Generation II","About":"In battle, Chikorita waves its leaf around to keep the foe at bay. However, a sweet fragrance also wafts from the leaf, becalming the battling Pokémon and creating a cozy, friendly atmosphere all around.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Razor Leaf","Type":"Grass","Damage":15},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"5.6kg","Maximum":"7.2kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"1km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"92 attack points.","Base Defense":"122 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Chikorita candies"},"Next evolution(s)":[{"Number":153,"Name":"Bayleef"},{"Number":154,"Name":"Meganium"}]},{"Number":"153","Name":"Bayleef","Generation":"Generation II","About":"Bayleef's neck is ringed by curled-up leaves. Inside each tubular leaf is a small shoot of a tree. The fragrance of this shoot makes people peppy.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Razor Leaf","Type":"Grass","Damage":15},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"13.83kg","Maximum":"17.78kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"122 attack points.","Base Defense":"155 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":152,"Name":"Chikorita"}],"Next Evolution Requirements":{"Amount":100,"Name":"Chikorita candies"},"Next evolution(s)":[{"Number":154,"Name":"Meganium"}]},{"Number":"154","Name":"Meganium","Generation":"Generation II","About":"The fragrance of Meganium's flower soothes and calms emotions. In battle, this Pokémon gives off more of its becalming scent to blunt the foe's fighting spirit.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Razor Leaf","Type":"Grass","Damage":15},{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"87.94kg","Maximum":"113.06kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"1km (Medium)","Base Stamina":"160 stamina points.","Base Attack":"168 attack points.","Base Defense":"202 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":152,"Name":"Chikorita"},{"Number":153,"Name":"Bayleef"}]},{"Number":"155","Name":"Cyndaquil","Generation":"Generation II","About":"Cyndaquil protects itself by flaring up the flames on its back. The flames are vigorous if the Pokémon is angry. However, if it is tired, the flames splutter fitfully with incomplete combustion.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"6.91kg","Maximum":"8.89kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"78 stamina points.","Base Attack":"116 attack points.","Base Defense":"96 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":156,"Name":"Quilava"},{"Number":157,"Name":"Typhlosion"}]},{"Number":"156","Name":"Quilava","Generation":"Generation II","About":"Quilava keeps its foes at bay with the intensity of its flames and gusts of superheated air. This Pokémon applies its outstanding nimbleness to dodge attacks even while scorching the foe with flames.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"16.63kg","Maximum":"21.38kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"1km (Medium)","Base Stamina":"116 stamina points.","Base Attack":"158 attack points.","Base Defense":"129 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":155,"Name":"Cyndaquil"}],"Next evolution(s)":[{"Number":157,"Name":"Typhlosion"}]},{"Number":"157","Name":"Typhlosion","Generation":"Generation II","About":"Typhlosion obscures itself behind a shimmering heat haze that it creates using its intensely hot flames. This Pokémon creates blazing explosive blasts that burn everything to cinders.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Shadow Claw","Type":"Ghost","Damage":11}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"69.56kg","Maximum":"89.44kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"1km (Medium)","Base Stamina":"156 stamina points.","Base Attack":"223 attack points.","Base Defense":"176 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":155,"Name":"Cyndaquil"},{"Number":156,"Name":"Quilava"}]},{"Number":"158","Name":"Totodile","Generation":"Generation II","About":"Despite the smallness of its body, Totodile's jaws are very powerful. While the Pokémon may think it is just playfully nipping, its bite has enough power to cause serious injury.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Scratch","Type":"Normal","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"8.31kg","Maximum":"10.69kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"117 attack points.","Base Defense":"116 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":159,"Name":"Croconaw"},{"Number":160,"Name":"Feraligatr"}]},{"Number":"159","Name":"Croconaw","Generation":"Generation II","About":"Once Croconaw has clamped its jaws on its foe, it will absolutely not let go. Because the tips of its fangs are forked back like barbed fishhooks, they become impossible to remove when they have sunk in.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Scratch","Type":"Normal","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"21.88kg","Maximum":"28.13kg"},"Height":{"Minimum":"0.95m","Maximum":"1.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"150 attack points.","Base Defense":"151 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":158,"Name":"Totodile"}],"Next evolution(s)":[{"Number":160,"Name":"Feraligatr"}]},{"Number":"160","Name":"Feraligatr","Generation":"Generation II","About":"Feraligatr intimidates its foes by opening its huge mouth. In battle, it will kick the ground hard with its thick and powerful hind legs to charge at the foe at an incredible speed.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"77.7kg","Maximum":"99.9kg"},"Height":{"Minimum":"2.02m","Maximum":"2.6m"},"Buddy Distance":"1km (Medium)","Base Stamina":"170 stamina points.","Base Attack":"205 attack points.","Base Defense":"197 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":158,"Name":"Totodile"},{"Number":159,"Name":"Croconaw"}]},{"Number":"161","Name":"Sentret","Generation":"Generation II","About":"When Sentret sleeps, it does so while another stands guard. The sentry wakes the others at the first sign of danger. When this Pokémon becomes separated from its pack, it becomes incapable of sleep due to fear.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"5.25kg","Maximum":"6.75kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"79 attack points.","Base Defense":"77 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":162,"Name":"Furret"}]},{"Number":"162","Name":"Furret","Generation":"Generation II","About":"Furret has a very slim build. When under attack, it can slickly squirm through narrow spaces and get away. In spite of its short limbs, this Pokémon is very nimble and fleet.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Sucker Punch","Type":"Dark","Damage":7}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"28.44kg","Maximum":"36.56kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"1km (Medium)","Base Stamina":"170 stamina points.","Base Attack":"148 attack points.","Base Defense":"130 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":161,"Name":"Sentret"}]},{"Number":"163","Name":"Hoothoot","Generation":"Generation II","About":"Hoothoot has an internal organ that senses and tracks the earth's rotation. Using this special organ, this Pokémon begins hooting at precisely the same time every day.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"18.55kg","Maximum":"23.85kg"},"Height":{"Minimum":"0.62m","Maximum":"0.8m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"67 attack points.","Base Defense":"101 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":164,"Name":"Noctowl"}]},{"Number":"164","Name":"Noctowl","Generation":"Generation II","About":"Noctowl never fails at catching prey in darkness. This Pokémon owes its success to its superior vision that allows it to see in minimal light, and to its soft, supple wings that make no sound in flight.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"35.7kg","Maximum":"45.9kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"145 attack points.","Base Defense":"179 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":163,"Name":"Hoothoot"}]},{"Number":"165","Name":"Ledyba","Generation":"Generation II","About":"Ledyba secretes an aromatic fluid from where its legs join its body. This fluid is used for communicating with others. This Pokémon conveys its feelings to others by altering the fluid's scent.","Types":["Bug","Flying"],"Resistant":["Grass","Fighting","Ground","Bug"],"Weaknesses":["Fire","Electric","Ice","Flying","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"9.45kg","Maximum":"12.15kg"},"Height":{"Minimum":"0.87m","Maximum":"1.11m"},"Buddy Distance":"1km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"72 attack points.","Base Defense":"142 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":166,"Name":"Ledian"}]},{"Number":"166","Name":"Ledian","Generation":"Generation II","About":"It is said that in lands with clean air, where the stars fill the sky, there live Ledian in countless numbers. There is a good reason for this—the Pokémon uses the light of the stars as its energy.","Types":["Bug","Flying"],"Resistant":["Grass","Fighting","Ground","Bug"],"Weaknesses":["Fire","Electric","Ice","Flying","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"31.15kg","Maximum":"40.05kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"107 attack points.","Base Defense":"209 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":165,"Name":"Ledyba"}]},{"Number":"167","Name":"Spinarak","Generation":"Generation II","About":"The web spun by Spinarak can be considered its second nervous system. It is said that this Pokémon can determine what kind of prey is touching its web just by the tiny vibrations it feels through the web's strands.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"7.44kg","Maximum":"9.56kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"105 attack points.","Base Defense":"73 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":168,"Name":"Ariados"}]},{"Number":"168","Name":"Ariados","Generation":"Generation II","About":"Ariados's feet are tipped with tiny hooked claws that enable it to scuttle on ceilings and vertical walls. This Pokémon constricts the foe with thin and strong silk webbing.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"29.31kg","Maximum":"37.69kg"},"Height":{"Minimum":"0.95m","Maximum":"1.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"161 attack points.","Base Defense":"128 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":167,"Name":"Spinarak"}]},{"Number":"169","Name":"Crobat","Generation":"Generation II","About":"If this Pokémon is flying by fluttering only a pair of wings on either the forelegs or hind legs, it's proof that Crobat has been flying a long distance. It switches the wings it uses if it is tired.","Types":["Poison","Flying"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Electric","Ice","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Wing Attack","Type":"Flying","Damage":9}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"65.63kg","Maximum":"84.38kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"1km (Medium)","Base Stamina":"170 stamina points.","Base Attack":"194 attack points.","Base Defense":"178 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":41,"Name":"Zubat"},{"Number":42,"Name":"Golbat"}]},{"Number":"170","Name":"Chinchou","Generation":"Generation II","About":"Chinchou lets loose positive and negative electrical charges from its two antennas to make its prey faint. This Pokémon flashes its electric lights to exchange signals with others.","Types":["Water","Electric"],"Resistant":["Fire","Water","Ice","Flying","Steel"],"Weaknesses":["Grass","Ground"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Spark","Type":"Electric","Damage":7}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"10.5kg","Maximum":"13.5kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"106 attack points.","Base Defense":"106 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":171,"Name":"Lanturn"}]},{"Number":"171","Name":"Lanturn","Generation":"Generation II","About":"Lanturn is nicknamed “the deep-sea star for its illuminated antenna. This Pokémon produces light by causing a chemical reaction between bacteria and its bodily fluids inside the antenna.\"","Types":["Water","Electric"],"Resistant":["Fire","Water","Ice","Flying","Steel"],"Weaknesses":["Grass","Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"19.69kg","Maximum":"25.31kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"250 stamina points.","Base Attack":"146 attack points.","Base Defense":"146 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":170,"Name":"Chinchou"}]},{"Number":"172","Name":"Pichu","Generation":"Generation II","About":"Pichu charges itself with electricity more easily on days with thunderclouds or when the air is very dry. You can hear the crackling of static electricity coming off this Pokémon.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Disarming Voice","Type":"Fairy","Damage":25},{"Name":"Thunder Punch","Type":"Electric","Damage":40},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"1.75kg","Maximum":"2.25kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"40 stamina points.","Base Attack":"77 attack points.","Base Defense":"63 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Pikachu candies"},"Next evolution(s)":[{"Number":25,"Name":"Pikachu"},{"Number":26,"Name":"Raichu"}]},{"Number":"173","Name":"Cleffa","Generation":"Generation II","About":"On nights with many shooting stars, Cleffa can be seen dancing in a ring. They dance through the night and stop only at the break of day, when these Pokémon quench their thirst with the morning dew.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Pound","Type":"Normal","Damage":7},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Signal Beam","Type":"Bug","Damage":45}],"Weight":{"Minimum":"2.63kg","Maximum":"3.38kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"75 attack points.","Base Defense":"91 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Clefairy candies"},"Next evolution(s)":[{"Number":35,"Name":"Clefairy"},{"Number":36,"Name":"Clefable"}]},{"Number":"174","Name":"Igglybuff","Generation":"Generation II","About":"Igglybuff's vocal cords are not sufficiently developed. It would hurt its throat if it were to sing too much. This Pokémon gargles with freshwater from a clean stream.","Types":["Normal","Fairy"],"Resistant":["Bug","Ghost","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Feint Attack","Type":"Dark","Damage":12},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"0.88kg","Maximum":"1.13kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"69 attack points.","Base Defense":"34 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Jigglypuff candies"},"Next evolution(s)":[{"Number":39,"Name":"Jigglypuff"},{"Number":40,"Name":"Wigglytuff"}]},{"Number":"175","Name":"Togepi","Generation":"Generation II","About":"As its energy, Togepi uses the positive emotions of compassion and pleasure exuded by people and Pokémon. This Pokémon stores up feelings of happiness inside its shell, then shares them with others.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Psyshock","Type":"Psychic","Damage":40}],"Weight":{"Minimum":"1.31kg","Maximum":"1.69kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"5km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"67 attack points.","Base Defense":"116 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Togepi candies"},"Next evolution(s)":[{"Number":176,"Name":"Togetic"}]},{"Number":"176","Name":"Togetic","Generation":"Generation II","About":"Togetic is said to be a Pokémon that brings good fortune. When the Pokémon spots someone who is pure of heart, it is said to appear and share its happiness with that person.","Types":["Fairy","Flying"],"Resistant":["Grass","Fighting","Ground","Bug","Dragon","Dark"],"Weaknesses":["Electric","Ice","Poison","Rock","Steel"],"Fast Attack(s)":[{"Name":"Steel Wing","Type":"Steel","Damage":15},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55}],"Weight":{"Minimum":"2.8kg","Maximum":"3.6kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"5km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"139 attack points.","Base Defense":"191 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":175,"Name":"Togepi"}]},{"Number":"177","Name":"Natu","Generation":"Generation II","About":"Natu cannot fly because its wings are not yet fully grown. If your eyes meet with this Pokémon's eyes, it will stare back intently at you. But if you move even slightly, it will hop away to safety.","Types":["Psychic","Flying"],"Resistant":["Grass","Fighting","Ground","Psychic"],"Weaknesses":["Electric","Ice","Rock","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"1.75kg","Maximum":"2.25kg"},"Height":{"Minimum":"0.18m","Maximum":"0.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"134 attack points.","Base Defense":"89 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":178,"Name":"Xatu"}]},{"Number":"178","Name":"Xatu","Generation":"Generation II","About":"Xatu stands rooted and still in one spot all day long. People believe that this Pokémon does so out of fear of the terrible things it has foreseen in the future.","Types":["Psychic","Flying"],"Resistant":["Grass","Fighting","Ground","Psychic"],"Weaknesses":["Electric","Ice","Rock","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"13.13kg","Maximum":"16.88kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"192 attack points.","Base Defense":"146 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":177,"Name":"Natu"}]},{"Number":"179","Name":"Mareep","Generation":"Generation II","About":"Mareep's fluffy coat of wool rubs together and builds a static charge. The more static electricity is charged, the more brightly the lightbulb at the tip of its tail glows.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"6.83kg","Maximum":"8.78kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"114 attack points.","Base Defense":"82 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":180,"Name":"Flaaffy"},{"Number":181,"Name":"Ampharos"}]},{"Number":"180","Name":"Flaaffy","Generation":"Generation II","About":"Flaaffy's wool quality changes so that it can generate a high amount of static electricity with a small amount of wool. The bare and slick parts of its hide are shielded against electricity.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"11.64kg","Maximum":"14.96kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"145 attack points.","Base Defense":"112 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":179,"Name":"Mareep"}],"Next evolution(s)":[{"Number":181,"Name":"Ampharos"}]},{"Number":"181","Name":"Ampharos","Generation":"Generation II","About":"Ampharos gives off so much light that it can be seen even from space. People in the old days used the light of this Pokémon to send signals back and forth with others far away.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"53.81kg","Maximum":"69.19kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"211 attack points.","Base Defense":"172 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":179,"Name":"Mareep"},{"Number":180,"Name":"Flaaffy"}]},{"Number":"182","Name":"Bellossom","Generation":"Generation II","About":"When Bellossom gets exposed to plenty of sunlight, the leaves ringing its body begin to spin around. This Pokémon's dancing is renowned in the southern lands.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"5.08kg","Maximum":"6.53kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"169 attack points.","Base Defense":"189 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":43,"Name":"Oddish"},{"Number":44,"Name":"Gloom"}]},{"Number":"183","Name":"Marill","Generation":"Generation II","About":"Marill's oil-filled tail acts much like a life preserver. If you see just its tail bobbing on the water's surface, it's a sure indication that this Pokémon is diving beneath the water to feed on aquatic plants.","Types":["Water","Fairy"],"Resistant":["Fire","Water","Ice","Fighting","Bug","Dragon","Dark"],"Weaknesses":["Electric","Grass","Poison"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"7.44kg","Maximum":"9.56kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"37 attack points.","Base Defense":"93 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":184,"Name":"Azumarill"}]},{"Number":"184","Name":"Azumarill","Generation":"Generation II","About":"Azumarill's long ears are indispensable sensors. By focusing its hearing, this Pokémon can identify what kinds of prey are around, even in rough and fast-running rivers.","Types":["Water","Fairy"],"Resistant":["Fire","Water","Ice","Fighting","Bug","Dragon","Dark"],"Weaknesses":["Electric","Grass","Poison"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"24.94kg","Maximum":"32.06kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"112 attack points.","Base Defense":"152 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":183,"Name":"Marill"}]},{"Number":"185","Name":"Sudowoodo","Generation":"Generation II","About":"Sudowoodo camouflages itself as a tree to avoid being attacked by enemies. However, because its hands remain green throughout the year, the Pokémon is easily identified as a fake during the winter.","Types":["Rock"],"Resistant":["Normal","Fire","Poison","Flying"],"Weaknesses":["Water","Grass","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"33.25kg","Maximum":"42.75kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"167 attack points.","Base Defense":"198 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"186","Name":"Politoed","Generation":"Generation II","About":"The curled hair on Politoed's head is proof of its status as a king. It is said that the longer and more curled the hair, the more respect this Pokémon earns from its peers.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"29.66kg","Maximum":"38.14kg"},"Height":{"Minimum":"9.54m","Maximum":"12.26m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"174 attack points.","Base Defense":"192 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":60,"Name":"Poliwag"},{"Number":61,"Name":"Poliwhirl"}]},{"Number":"187","Name":"Hoppip","Generation":"Generation II","About":"This Pokémon drifts and floats with the wind. If it senses the approach of strong winds, Hoppip links its leaves with other Hoppip to prepare against being blown away.","Types":["Grass","Flying"],"Resistant":["Water","Grass","Fighting","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"0.44kg","Maximum":"0.56kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"67 attack points.","Base Defense":"101 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":188,"Name":"Skiploom"},{"Number":189,"Name":"Jumpluff"}]},{"Number":"188","Name":"Skiploom","Generation":"Generation II","About":"Skiploom's flower blossoms when the temperature rises above 64 degrees Fahrenheit. How much the flower opens depends on the temperature. For that reason, this Pokémon is sometimes used as a thermometer.","Types":["Grass","Flying"],"Resistant":["Water","Grass","Fighting","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"0.88kg","Maximum":"1.13kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"91 attack points.","Base Defense":"127 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":187,"Name":"Hoppip"}],"Next evolution(s)":[{"Number":189,"Name":"Jumpluff"}]},{"Number":"189","Name":"Jumpluff","Generation":"Generation II","About":"Jumpluff rides warm southern winds to cross the sea and fly to foreign lands. The Pokémon descends to the ground when it encounters cold air while it is floating.","Types":["Grass","Flying"],"Resistant":["Water","Grass","Fighting","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"2.63kg","Maximum":"3.38kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"118 attack points.","Base Defense":"197 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":187,"Name":"Hoppip"},{"Number":188,"Name":"Skiploom"}]},{"Number":"190","Name":"Aipom","Generation":"Generation II","About":"Aipom's tail ends in a hand-like appendage that can be cleverly manipulated. However, because the Pokémon uses its tail so much, its real hands have become rather clumsy.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"10.06kg","Maximum":"12.94kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"136 attack points.","Base Defense":"112 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"191","Name":"Sunkern","Generation":"Generation II","About":"Sunkern tries to move as little as it possibly can. It does so because it tries to conserve all the nutrients it has stored in its body for its evolution. It will not eat a thing, subsisting only on morning dew.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"1.57kg","Maximum":"2.02kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"55 attack points.","Base Defense":"55 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":192,"Name":"Sunflora"}]},{"Number":"192","Name":"Sunflora","Generation":"Generation II","About":"Sunflora converts solar energy into nutrition. It moves around actively in the daytime when it is warm. It stops moving as soon as the sun goes down for the night.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"7.44kg","Maximum":"9.56kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"185 attack points.","Base Defense":"148 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":191,"Name":"Sunkern"}]},{"Number":"193","Name":"Yanma","Generation":"Generation II","About":"Yanma is capable of seeing 360 degrees without having to move its eyes. It is a great flier that is adept at making sudden stops and turning midair. This Pokémon uses its flying ability to quickly chase down targeted prey.","Types":["Bug","Flying"],"Resistant":["Grass","Fighting","Ground","Bug"],"Weaknesses":["Fire","Electric","Ice","Flying","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"33.25kg","Maximum":"42.75kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"154 attack points.","Base Defense":"94 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"194","Name":"Wooper","Generation":"Generation II","About":"Wooper usually lives in water. However, it occasionally comes out onto land in search of food. On land, it coats its body with a gooey, toxic film.","Types":["Water","Ground"],"Resistant":["Fire","Poison","Rock","Steel"],"Weaknesses":["Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"7.44kg","Maximum":"9.56kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"75 attack points.","Base Defense":"75 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":195,"Name":"Quagsire"}]},{"Number":"195","Name":"Quagsire","Generation":"Generation II","About":"Quagsire hunts for food by leaving its mouth wide open in water and waiting for its prey to blunder in unaware. Because the Pokémon does not move, it does not get very hungry.","Types":["Water","Ground"],"Resistant":["Fire","Poison","Rock","Steel"],"Weaknesses":["Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"65.63kg","Maximum":"84.38kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"190 stamina points.","Base Attack":"152 attack points.","Base Defense":"152 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":194,"Name":"Wooper"}]},{"Number":"196","Name":"Espeon","Generation":"Generation II","About":"Espeon is extremely loyal to any Trainer it considers to be worthy. It is said that this Pokémon developed its precognitive powers to protect its Trainer from harm.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"23.19kg","Maximum":"29.81kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"5km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"261 attack points.","Base Defense":"194 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":133,"Name":"Eevee"}]},{"Number":"197","Name":"Umbreon","Generation":"Generation II","About":"Umbreon evolved as a result of exposure to the moon's waves. It hides silently in darkness and waits for its foes to make a move. The rings on its body glow when it leaps to attack.","Types":["Dark"],"Resistant":["Psychic","Ghost","Dark"],"Weaknesses":["Fighting","Bug","Fairy"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Feint Attack","Type":"Dark","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"23.63kg","Maximum":"30.38kg"},"Height":{"Minimum":"0.87m","Maximum":"1.11m"},"Buddy Distance":"5km (Medium)","Base Stamina":"190 stamina points.","Base Attack":"126 attack points.","Base Defense":"250 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":133,"Name":"Eevee"}]},{"Number":"198","Name":"Murkrow","Generation":"Generation II","About":"Murkrow was feared and loathed as the alleged bearer of ill fortune. This Pokémon shows strong interest in anything that sparkles or glitters. It will even try to steal rings from women.","Types":["Dark","Flying"],"Resistant":["Grass","Ground","Psychic","Ghost","Dark"],"Weaknesses":["Electric","Ice","Rock","Fairy"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"1.84kg","Maximum":"2.36kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"175 attack points.","Base Defense":"87 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"199","Name":"Slowking","Generation":"Generation II","About":"Slowking undertakes research every day in an effort to solve the mysteries of the world. However, this Pokémon apparently forgets everything it has learned if the Shellder on its head comes off.","Types":["Water","Psychic"],"Resistant":["Fire","Water","Ice","Fighting","Psychic","Steel"],"Weaknesses":["Electric","Grass","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"69.56kg","Maximum":"89.44kg"},"Height":{"Minimum":"1.76m","Maximum":"2.26m"},"Buddy Distance":"1km (Medium)","Base Stamina":"190 stamina points.","Base Attack":"177 attack points.","Base Defense":"194 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":79,"Name":"Slowpoke"}]},{"Number":"200","Name":"Misdreavus","Generation":"Generation II","About":"Misdreavus frightens people with a creepy, sobbing cry. The Pokémon apparently uses its red spheres to absorb the fearful feelings of foes and turn them into nutrition.","Types":["Ghost"],"Resistant":["Normal","Fighting","Poison","Bug"],"Weaknesses":["Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"0.88kg","Maximum":"1.13kg"},"Height":{"Minimum":"0.62m","Maximum":"0.8m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"167 attack points.","Base Defense":"167 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"201","Name":"Unown","Generation":"Generation II","About":"This Pokémon is shaped like ancient writing. It is a mystery as to which came first, the ancient writings or the various Unown. Research into this topic is ongoing but nothing is known.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"4.38kg","Maximum":"5.63kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"96 stamina points.","Base Attack":"136 attack points.","Base Defense":"91 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"202","Name":"Wobbuffet","Generation":"Generation II","About":"If two or more Wobbuffet meet, they will turn competitive and try to outdo each other's endurance. However, they may try to see which one can endure the longest without food. Trainers need to beware of this habit.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"24.94kg","Maximum":"32.06kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"380 stamina points.","Base Attack":"60 attack points.","Base Defense":"106 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"203","Name":"Girafarig","Generation":"Generation II","About":"Girafarig's rear head also has a brain, but it is small. The rear head attacks in response to smells and sounds. Approaching this Pokémon from behind can cause the rear head to suddenly lash out and bite.","Types":["Normal","Psychic"],"Resistant":["Psychic"],"Weaknesses":["Bug","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"36.31kg","Maximum":"46.69kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"182 attack points.","Base Defense":"133 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"204","Name":"Pineco","Generation":"Generation II","About":"Pineco hangs from a tree branch and patiently waits for prey to come along. If the Pokémon is disturbed while eating by someone shaking its tree, it drops down to the ground and explodes with no warning.","Types":["Bug"],"Resistant":["Grass","Fighting","Ground"],"Weaknesses":["Fire","Flying","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"6.3kg","Maximum":"8.1kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"108 attack points.","Base Defense":"146 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":205,"Name":"Forretress"}]},{"Number":"205","Name":"Forretress","Generation":"Generation II","About":"Forretress conceals itself inside its hardened steel shell. The shell is opened when the Pokémon is catching prey, but it does so at such a quick pace that the shell's inside cannot be seen.","Types":["Bug","Steel"],"Resistant":["Normal","Grass","Ice","Poison","Psychic","Bug","Dragon","Steel","Fairy"],"Weaknesses":["Fire"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"110.08kg","Maximum":"141.53kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"161 attack points.","Base Defense":"242 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":204,"Name":"Pineco"}]},{"Number":"206","Name":"Dunsparce","Generation":"Generation II","About":"Dunsparce has a drill for its tail. It uses this tail to burrow into the ground backward. This Pokémon is known to make its nest in complex shapes deep under the ground.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"12.25kg","Maximum":"15.75kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"131 attack points.","Base Defense":"131 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"207","Name":"Gligar","Generation":"Generation II","About":"Gligar glides through the air without a sound as if it were sliding. This Pokémon hangs on to the face of its foe using its clawed hind legs and the large pincers on its forelegs, then injects the prey with its poison barb.","Types":["Ground","Flying"],"Resistant":["Fighting","Poison","Ground","Bug"],"Weaknesses":["Water","Ice"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"56.7kg","Maximum":"72.9kg"},"Height":{"Minimum":"0.95m","Maximum":"1.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"143 attack points.","Base Defense":"204 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"208","Name":"Steelix","Generation":"Generation II","About":"Steelix lives even further underground than Onix. This Pokémon is known to dig toward the earth's core. There are records of this Pokémon reaching a depth of over six-tenths of a mile underground.","Types":["Steel","Ground"],"Resistant":["Normal","Electric","Poison","Flying","Psychic","Bug","Rock","Dragon","Steel","Fairy"],"Weaknesses":["Fire","Water","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"350kg","Maximum":"450kg"},"Height":{"Minimum":"8.04m","Maximum":"10.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"148 attack points.","Base Defense":"333 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":95,"Name":"Onix"}]},{"Number":"209","Name":"Snubbull","Generation":"Generation II","About":"By baring its fangs and making a scary face, Snubbull sends smaller Pokémon scurrying away in terror. However, this Pokémon seems a little sad at making its foes flee.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"6.83kg","Maximum":"8.78kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"137 attack points.","Base Defense":"89 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":210,"Name":"Granbull"}]},{"Number":"210","Name":"Granbull","Generation":"Generation II","About":"Granbull has a particularly well-developed lower jaw. The enormous fangs are heavy, causing the Pokémon to tip its head back for balance. Unless it is startled, it will not try to bite indiscriminately.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"42.61kg","Maximum":"54.79kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"212 attack points.","Base Defense":"137 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":209,"Name":"Snubbull"}]},{"Number":"211","Name":"Qwilfish","Generation":"Generation II","About":"Qwilfish sucks in water, inflating itself. This Pokémon uses the pressure of the water it swallowed to shoot toxic quills all at once from all over its body. It finds swimming somewhat challenging.","Types":["Water","Poison"],"Resistant":["Fire","Water","Ice","Fighting","Poison","Bug","Steel","Fairy"],"Weaknesses":["Electric","Ground","Psychic"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"3.41kg","Maximum":"4.39kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"184 attack points.","Base Defense":"148 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"212","Name":"Scizor","Generation":"Generation II","About":"Scizor has a body with the hardness of steel. It is not easily fazed by ordinary sorts of attacks. This Pokémon flaps its wings to regulate its body temperature.","Types":["Bug","Steel"],"Resistant":["Normal","Grass","Ice","Poison","Psychic","Bug","Dragon","Steel","Fairy"],"Weaknesses":["Fire"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"109.38kg","Maximum":"140.63kg"},"Height":{"Minimum":"1.76m","Maximum":"2.26m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"236 attack points.","Base Defense":"191 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":123,"Name":"Scyther"}]},{"Number":"213","Name":"Shuckle","Generation":"Generation II","About":"Shuckle quietly hides itself under rocks, keeping its body concealed inside its hard shell while eating berries it has stored away. The berries mix with its body fluids to become a juice.","Types":["Bug","Rock"],"Resistant":["Normal","Poison"],"Weaknesses":["Water","Rock","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"17.94kg","Maximum":"23.06kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"40 stamina points.","Base Attack":"17 attack points.","Base Defense":"396 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"214","Name":"Heracross","Generation":"Generation II","About":"Heracross charges in a straight line at its foe, slips beneath the foe's grasp, and then scoops up and hurls the opponent with its mighty horn. This Pokémon even has enough power to topple a massive tree.","Types":["Bug","Fighting"],"Resistant":["Grass","Fighting","Ground","Bug","Dark"],"Weaknesses":["Fire","Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"47.25kg","Maximum":"60.75kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"160 stamina points.","Base Attack":"234 attack points.","Base Defense":"189 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"215","Name":"Sneasel","Generation":"Generation II","About":"Sneasel scales trees by punching its hooked claws into the bark. This Pokémon seeks out unguarded nests and steals eggs for food while the parents are away.","Types":["Dark","Ice"],"Resistant":["Ice","Psychic","Ghost","Dark"],"Weaknesses":["Fire","Fighting","Bug","Rock","Steel","Fairy"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"24.5kg","Maximum":"31.5kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"189 attack points.","Base Defense":"157 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"216","Name":"Teddiursa","Generation":"Generation II","About":"This Pokémon likes to lick its palms that are sweetened by being soaked in honey. Teddiursa concocts its own honey by blending fruits and pollen collected by Beedrill.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"7.7kg","Maximum":"9.9kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"142 attack points.","Base Defense":"93 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":217,"Name":"Ursaring"}]},{"Number":"217","Name":"Ursaring","Generation":"Generation II","About":"In the forests inhabited by Ursaring, it is said that there are many streams and towering trees where they gather food. This Pokémon walks through its forest gathering food every day.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"110.08kg","Maximum":"141.53kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"236 attack points.","Base Defense":"144 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":216,"Name":"Teddiursa"}]},{"Number":"218","Name":"Slugma","Generation":"Generation II","About":"Molten magma courses throughout Slugma's circulatory system. If this Pokémon is chilled, the magma cools and hardens. Its body turns brittle and chunks fall off, reducing its size.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"30.63kg","Maximum":"39.38kg"},"Height":{"Minimum":"0.62m","Maximum":"0.8m"},"Buddy Distance":"1km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"118 attack points.","Base Defense":"71 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":219,"Name":"Magcargo"}]},{"Number":"219","Name":"Magcargo","Generation":"Generation II","About":"Magcargo's shell is actually its skin that hardened as a result of cooling. Its shell is very brittle and fragile—just touching it causes it to crumble apart. This Pokémon returns to its original size by dipping itself in magma.","Types":["Fire","Rock"],"Resistant":["Normal","Fire","Ice","Poison","Flying","Bug","Fairy"],"Weaknesses":["Water","Fighting","Ground","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"48.13kg","Maximum":"61.88kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"139 attack points.","Base Defense":"209 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":218,"Name":"Slugma"}]},{"Number":"220","Name":"Swinub","Generation":"Generation II","About":"Swinub roots for food by rubbing its snout against the ground. Its favorite food is a mushroom that grows under the cover of dead grass. This Pokémon occasionally roots out hot springs.","Types":["Ice","Ground"],"Resistant":["Electric","Poison"],"Weaknesses":["Fire","Water","Grass","Fighting","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"5.69kg","Maximum":"7.31kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"90 attack points.","Base Defense":"74 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":221,"Name":"Piloswine"}]},{"Number":"221","Name":"Piloswine","Generation":"Generation II","About":"Piloswine is covered by a thick coat of long hair that enables it to endure the freezing cold. This Pokémon uses its tusks to dig up food that has been buried under ice.","Types":["Ice","Ground"],"Resistant":["Electric","Poison"],"Weaknesses":["Fire","Water","Grass","Fighting","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"48.82kg","Maximum":"62.77kg"},"Height":{"Minimum":"0.95m","Maximum":"1.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"181 attack points.","Base Defense":"147 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":220,"Name":"Swinub"}]},{"Number":"222","Name":"Corsola","Generation":"Generation II","About":"Corsola's branches glitter very beautifully in seven colors when they catch sunlight. If any branch breaks off, this Pokémon grows it back in just one night.","Types":["Water","Rock"],"Resistant":["Normal","Fire","Ice","Poison","Flying"],"Weaknesses":["Electric","Grass","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"4.38kg","Maximum":"5.63kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"118 attack points.","Base Defense":"156 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"223","Name":"Remoraid","Generation":"Generation II","About":"Remoraid sucks in water, then expels it at high velocity using its abdominal muscles to shoot down flying prey. When evolution draws near, this Pokémon travels downstream from rivers.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"10.5kg","Maximum":"13.5kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"127 attack points.","Base Defense":"69 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":224,"Name":"Octillery"}]},{"Number":"224","Name":"Octillery","Generation":"Generation II","About":"Octillery grabs onto its foe using its tentacles. This Pokémon tries to immobilize it before delivering the finishing blow. If the foe turns out to be too strong, Octillery spews ink to escape.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"24.94kg","Maximum":"32.06kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"197 attack points.","Base Defense":"141 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":223,"Name":"Remoraid"}]},{"Number":"225","Name":"Delibird","Generation":"Generation II","About":"Delibird carries its food bundled up in its tail. There once was a famous explorer who managed to reach the peak of the world's highest mountain, thanks to one of these Pokémon sharing its food.","Types":["Ice","Flying"],"Resistant":["Grass","Ground","Bug"],"Weaknesses":["Fire","Electric","Rock","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"14kg","Maximum":"18kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"1km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"128 attack points.","Base Defense":"90 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"226","Name":"Mantine","Generation":"Generation II","About":"On sunny days, schools of Mantine can be seen elegantly leaping over the sea's waves. This Pokémon is not bothered by the Remoraid that hitches rides.","Types":["Water","Flying"],"Resistant":["Fire","Water","Fighting","Ground","Bug","Steel"],"Weaknesses":["Electric","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"192.5kg","Maximum":"247.5kg"},"Height":{"Minimum":"1.85m","Maximum":"2.37m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"148 attack points.","Base Defense":"260 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"227","Name":"Skarmory","Generation":"Generation II","About":"Skarmory is entirely encased in hard, protective armor. This Pokémon flies at close to 190 mph. It slashes foes with its wings that possess swordlike cutting edges.","Types":["Steel","Flying"],"Resistant":["Normal","Grass","Poison","Flying","Psychic","Bug","Dragon","Steel","Fairy"],"Weaknesses":["Fire","Electric"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"44.19kg","Maximum":"56.81kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"148 attack points.","Base Defense":"260 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"228","Name":"Houndour","Generation":"Generation II","About":"Houndour hunt as a coordinated pack. They communicate with each other using a variety of cries to corner their prey. This Pokémon's remarkable teamwork is unparalleled.","Types":["Dark","Fire"],"Resistant":["Fire","Grass","Ice","Psychic","Ghost","Dark","Steel"],"Weaknesses":["Water","Fighting","Ground","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"9.45kg","Maximum":"12.15kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"152 attack points.","Base Defense":"93 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":229,"Name":"Houndoom"}]},{"Number":"229","Name":"Houndoom","Generation":"Generation II","About":"In a Houndoom pack, the one with its horns raked sharply toward the back serves a leadership role. These Pokémon choose their leader by fighting among themselves.","Types":["Dark","Fire"],"Resistant":["Fire","Grass","Ice","Psychic","Ghost","Dark","Steel"],"Weaknesses":["Water","Fighting","Ground","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"30.63kg","Maximum":"39.38kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"224 attack points.","Base Defense":"159 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":228,"Name":"Houndour"}]},{"Number":"230","Name":"Kingdra","Generation":"Generation II","About":"Kingdra lives at extreme ocean depths that are otherwise uninhabited. It has long been believed that the yawning of this Pokémon creates spiraling ocean currents.","Types":["Water","Dragon"],"Resistant":["Fire","Water","Steel"],"Weaknesses":["Dragon","Fairy"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"133kg","Maximum":"171kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"194 attack points.","Base Defense":"194 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":116,"Name":"Horsea"},{"Number":117,"Name":"Seadra"}]},{"Number":"231","Name":"Phanpy","Generation":"Generation II","About":"For its nest, Phanpy digs a vertical pit in the ground at the edge of a river. It marks the area around its nest with its trunk to let the others know that the area has been claimed.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"29.31kg","Maximum":"37.69kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"107 attack points.","Base Defense":"107 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":232,"Name":"Donphan"}]},{"Number":"232","Name":"Donphan","Generation":"Generation II","About":"Donphan's favorite attack is curling its body into a ball, then charging at its foe while rolling at high speed. Once it starts rolling, this Pokémon can't stop very easily.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"105kg","Maximum":"135kg"},"Height":{"Minimum":"0.95m","Maximum":"1.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"214 attack points.","Base Defense":"214 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":231,"Name":"Phanpy"}]},{"Number":"233","Name":"Porygon2","Generation":"Generation II","About":"Porygon2 was created by humans using the power of science. The man-made Pokémon has been endowed with artificial intelligence that enables it to learn new gestures and emotions on its own.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"28.44kg","Maximum":"36.56kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"170 stamina points.","Base Attack":"198 attack points.","Base Defense":"183 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":137,"Name":"Porygon"}]},{"Number":"234","Name":"Stantler","Generation":"Generation II","About":"Stantler's magnificent antlers were traded at high prices as works of art. As a result, this Pokémon was hunted close to extinction by those who were after the priceless antlers.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"62.3kg","Maximum":"80.1kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"146 stamina points.","Base Attack":"192 attack points.","Base Defense":"132 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"235","Name":"Smeargle","Generation":"Generation II","About":"Smeargle marks the boundaries of its territory using a body fluid that leaks out from the tip of its tail. Over 5,000 different marks left by this Pokémon have been found.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"50.75kg","Maximum":"65.25kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"40 attack points.","Base Defense":"88 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"236","Name":"Tyrogue","Generation":"Generation II","About":"Tyrogue becomes stressed out if it does not get to train every day. When raising this Pokémon, the Trainer must establish and uphold various training methods.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Low Kick","Type":"Fighting","Damage":5},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Low Sweep","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"18.38kg","Maximum":"23.63kg"},"Height":{"Minimum":"0.62m","Maximum":"0.8m"},"Buddy Distance":"5km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"64 attack points.","Base Defense":"64 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Tyrogue candies"},"Next evolution(s)":[{"Number":106,"Name":"Hitmonlee"},{"Number":107,"Name":"Hitmonchan"},{"Number":237,"Name":"Hitmontop"}]},{"Number":"237","Name":"Hitmontop","Generation":"Generation II","About":"Hitmontop spins on its head at high speed, all the while delivering kicks. This technique is a remarkable mix of both offense and defense at the same time. The Pokémon travels faster spinning than it does walking.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"42kg","Maximum":"54kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"5km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"173 attack points.","Base Defense":"214 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":236,"Name":"Tyrogue"}]},{"Number":"238","Name":"Smoochum","Generation":"Generation II","About":"Smoochum actively runs about, but also falls quite often. Whenever the chance arrives, it will look for its reflection to make sure its face hasn't become dirty.","Types":["Ice","Psychic"],"Resistant":["Ice","Psychic"],"Weaknesses":["Fire","Bug","Rock","Ghost","Dark","Steel"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Ice Beam","Type":"Ice","Damage":65},{"Name":"Ice Punch","Type":"Ice","Damage":45},{"Name":"Psyshock","Type":"Psychic","Damage":40}],"Weight":{"Minimum":"5.25kg","Maximum":"6.75kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"5km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"153 attack points.","Base Defense":"116 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Jyn"},"Next evolution(s)":[{"Number":124,"Name":"Jynx"}]},{"Number":"239","Name":"Elekid","Generation":"Generation II","About":"Elekid stores electricity in its body. If it touches metal and accidentally discharges all its built-up electricity, this Pokémon begins swinging its arms in circles to recharge itself.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Low Kick","Type":"Fighting","Damage":5},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Thunder Punch","Type":"Electric","Damage":40},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"20.56kg","Maximum":"26.44kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"5km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"135 attack points.","Base Defense":"110 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Electabuzz candies"},"Next evolution(s)":[{"Number":125,"Name":"Electabuzz"}]},{"Number":"240","Name":"Magby","Generation":"Generation II","About":"Magby's state of health is determined by observing the fire it breathes. If the Pokémon is spouting yellow flames from its mouth, it is in good health. When it is fatigued, black smoke will be mixed in with the flames.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Karate Chop","Type":"Fighting","Damage":6}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Fire Punch","Type":"Fire","Damage":40},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"18.72kg","Maximum":"24.07kg"},"Height":{"Minimum":"0.62m","Maximum":"0.8m"},"Buddy Distance":"5km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"151 attack points.","Base Defense":"108 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Magmar candies"},"Next evolution(s)":[{"Number":126,"Name":"Magmar"}]},{"Number":"241","Name":"Miltank","Generation":"Generation II","About":"Miltank gives over five gallons of milk on a daily basis. Its sweet milk is enjoyed by children and grown-ups alike. People who can't drink milk turn it into yogurt and eat it instead.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"66.06kg","Maximum":"84.94kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"190 stamina points.","Base Attack":"157 attack points.","Base Defense":"211 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"242","Name":"Blissey","Generation":"Generation II","About":"Blissey senses sadness with its fluffy coat of fur. If it does so, this Pokémon will rush over to a sad person, no matter how far away, to share a Lucky Egg that brings a smile to any face.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"40.95kg","Maximum":"52.65kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"510 stamina points.","Base Attack":"129 attack points.","Base Defense":"229 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":113,"Name":"Chansey"}]},{"Number":"243","Name":"Raikou","Generation":"Generation II","About":"Raikou embodies the speed of lightning. The roars of this Pokémon send shock waves shuddering through the air and shake the ground as if lightning bolts had come crashing down.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"155.75kg","Maximum":"200.25kg"},"Height":{"Minimum":"1.67m","Maximum":"2.15m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"241 attack points.","Base Defense":"210 defense points.","Base Flee Rate":"5% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class"},{"Number":"244","Name":"Entei","Generation":"Generation II","About":"Entei embodies the passion of magma. This Pokémon is thought to have been born in the eruption of a volcano. It sends up massive bursts of fire that utterly consume all that they touch.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"173.25kg","Maximum":"222.75kg"},"Height":{"Minimum":"1.85m","Maximum":"2.37m"},"Buddy Distance":"1km (Medium)","Base Stamina":"230 stamina points.","Base Attack":"235 attack points.","Base Defense":"176 defense points.","Base Flee Rate":"5% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class"},{"Number":"245","Name":"Suicune","Generation":"Generation II","About":"Suicune embodies the compassion of a pure spring of water. It runs across the land with gracefulness. This Pokémon has the power to purify dirty water.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"163.63kg","Maximum":"210.38kg"},"Height":{"Minimum":"1.76m","Maximum":"2.26m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"180 attack points.","Base Defense":"235 defense points.","Base Flee Rate":"5% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class"},{},{},{},{"Number":"249","Name":"Lugia","Generation":"Generation II","About":"Lugia's wings pack devastating power—a light fluttering of its wings can blow apart regular houses. As a result, this Pokémon chooses to live out of sight deep under the sea.","Types":["Psychic","Flying"],"Resistant":["Grass","Fighting","Ground","Psychic"],"Weaknesses":["Electric","Ice","Rock","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"189kg","Maximum":"243kg"},"Height":{"Minimum":"4.56m","Maximum":"5.86m"},"Buddy Distance":"1km (Medium)","Base Stamina":"212 stamina points.","Base Attack":"193 attack points.","Base Defense":"323 defense points.","Base Flee Rate":"5% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class"},{},{"Number":"251","Name":"Celebi","Generation":"Generation II","About":"This Pokémon came from the future by crossing over time. It is thought that so long as Celebi appears, a bright and shining future awaits us.","Types":["Psychic","Grass"],"Resistant":["Water","Electric","Grass","Fighting","Ground","Psychic"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"4.38kg","Maximum":"5.63kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"210 attack points.","Base Defense":"210 defense points.","Base Flee Rate":"5% chance to flee.","Pokèmon Class":"This is a MYTHIC Pokèmon.","MYTHIC":"Pokèmon Class"}] +[{"Number":"001","Name":"Bulbasaur","Generation":"Generation I","About":"Bulbasaur can be seen napping in bright sunlight. There is a seed on its back. By soaking up the sun's rays, the seed grows progressively larger.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12},{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Seed Bomb","Type":"Grass","Damage":40},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"6.04kg","Maximum":"7.76kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"3km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"118 attack points.","Base Defense":"118 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Bulbasaur candies"},"Next evolution(s)":[{"Number":2,"Name":"Ivysaur"},{"Number":3,"Name":"Venusaur"}],"MaxCP":951,"MaxHP":1071},{"Number":"002","Name":"Ivysaur","Generation":"Generation I","About":"There is a bud on this Pokémon's back. To support its weight, Ivysaur's legs and trunk grow thick and strong. If it starts spending more time lying in the sunlight, it's a sign that the bud will bloom into a large flower soon.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Razor Leaf","Type":"Grass","Damage":15},{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"11.38kg","Maximum":"14.63kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"151 attack points.","Base Defense":"151 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":1,"Name":"Bulbasaur"}],"Next Evolution Requirements":{"Amount":100,"Name":"Bulbasaur candies"},"Next evolution(s)":[{"Number":3,"Name":"Venusaur"}],"MaxCP":1483,"MaxHP":1632},{"Number":"003","Name":"Venusaur","Generation":"Generation I","About":"There is a large flower on Venusaur's back. The flower is said to take on vivid colors if it gets plenty of nutrition and sunlight. The flower's aroma soothes the emotions of people.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Razor Leaf","Type":"Grass","Damage":15},{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Petal Blizzard","Type":"Grass","Damage":65},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"87.5kg","Maximum":"112.5kg"},"Height":{"Minimum":"1.75m","Maximum":"2.25m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"198 attack points.","Base Defense":"198 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":1,"Name":"Bulbasaur"},{"Number":2,"Name":"Ivysaur"}],"MaxCP":2392,"MaxHP":2580},{"Number":"004","Name":"Charmander","Generation":"Generation I","About":"The flame that burns at the tip of its tail is an indication of its emotions. The flame wavers when Charmander is enjoying itself. If the Pokémon becomes enraged, the flame burns fiercely.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Flame Burst","Type":"Fire","Damage":30},{"Name":"Flame Charge","Type":"Fire","Damage":25},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"7.44kg","Maximum":"9.56kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Medium)","Base Stamina":"78 stamina points.","Base Attack":"116 attack points.","Base Defense":"96 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Charmander candies"},"Next evolution(s)":[{"Number":5,"Name":"Charmeleon"},{"Number":6,"Name":"Charizard"}],"MaxCP":841,"MaxHP":955},{"Number":"005","Name":"Charmeleon","Generation":"Generation I","About":"Charmeleon mercilessly destroys its foes using its sharp claws. If it encounters a strong foe, it turns aggressive. In this excited state, the flame at the tip of its tail flares with a bluish white color.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Fire Punch","Type":"Fire","Damage":40},{"Name":"Flame Burst","Type":"Fire","Damage":30},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"16.63kg","Maximum":"21.38kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"3km (Medium)","Base Stamina":"116 stamina points.","Base Attack":"158 attack points.","Base Defense":"129 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":4,"Name":"Charmander"}],"Next Evolution Requirements":{"Amount":100,"Name":"Charmander candies"},"Next evolution(s)":[{"Number":6,"Name":"Charizard"}],"MaxCP":1411,"MaxHP":1557},{"Number":"006","Name":"Charizard","Generation":"Generation I","About":"Charizard flies around the sky in search of powerful opponents. It breathes fire of such great heat that it melts anything. However, it never turns its fiery breath on any opponent weaker than itself.","Types":["Fire","Flying"],"Resistant":["Fire","Grass","Fighting","Bug","Steel","Fairy"],"Weaknesses":["Water","Electric","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Wing Attack","Type":"Flying","Damage":9}],"Special Attack(s)":[{"Name":"Dragon Claw","Type":"Dragon","Damage":35},{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"79.19kg","Maximum":"101.81kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"3km (Big)","Base Stamina":"156 stamina points.","Base Attack":"223 attack points.","Base Defense":"176 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":4,"Name":"Charmander"},{"Number":5,"Name":"Charmeleon"}],"MaxCP":2413,"MaxHP":2602},{"Number":"007","Name":"Squirtle","Generation":"Generation I","About":"Squirtle's shell is not merely used for protection. The shell's rounded shape and the grooves on its surface help minimize resistance in water, enabling this Pokémon to swim at high speeds.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Aqua Jet","Type":"Water","Damage":25},{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"7.88kg","Maximum":"10.13kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"3km (Medium)","Base Stamina":"88 stamina points.","Base Attack":"94 attack points.","Base Defense":"122 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Squirtle candies"},"Next evolution(s)":[{"Number":8,"Name":"Wartortle"},{"Number":9,"Name":"Blastoise"}],"MaxCP":891,"MaxHP":1008},{"Number":"008","Name":"Wartortle","Generation":"Generation I","About":"Its tail is large and covered with a rich, thick fur. The tail becomes increasingly deeper in color as Wartortle ages. The scratches on its shell are evidence of this Pokémon's toughness as a battler.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Aqua Jet","Type":"Water","Damage":25},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Ice Beam","Type":"Ice","Damage":65}],"Weight":{"Minimum":"19.69kg","Maximum":"25.31kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"118 stamina points.","Base Attack":"126 attack points.","Base Defense":"155 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":7,"Name":"Squirtle"}],"Next Evolution Requirements":{"Amount":100,"Name":"Squirtle candies"},"Next evolution(s)":[{"Number":9,"Name":"Blastoise"}],"MaxCP":1435,"MaxHP":1582},{"Number":"009","Name":"Blastoise","Generation":"Generation I","About":"Blastoise has water spouts that protrude from its shell. The water spouts are very accurate. They can shoot bullets of water with enough accuracy to strike empty cans from a distance of over 160 feet.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Flash Cannon","Type":"Steel","Damage":60},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Ice Beam","Type":"Ice","Damage":65}],"Weight":{"Minimum":"74.81kg","Maximum":"96.19kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Big)","Base Stamina":"158 stamina points.","Base Attack":"171 attack points.","Base Defense":"210 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":7,"Name":"Squirtle"},{"Number":8,"Name":"Wartortle"}],"MaxCP":2355,"MaxHP":2542},{"Number":"010","Name":"Caterpie","Generation":"Generation I","About":"Caterpie has a voracious appetite. It can devour leaves bigger than its body right before your eyes. From its antenna, this Pokémon releases a terrifically strong odor.","Types":["Bug"],"Resistant":["Grass","Fighting","Ground"],"Weaknesses":["Fire","Flying","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"2.54kg","Maximum":"3.26kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Shoulder)","Base Stamina":"90 stamina points.","Base Attack":"55 attack points.","Base Defense":"62 defense points.","Base Flee Rate":"20% chance to flee.","Next Evolution Requirements":{"Amount":12,"Name":"Caterpie candies"},"Next evolution(s)":[{"Number":11,"Name":"Metapod"},{"Number":12,"Name":"Butterfree"}],"MaxCP":367,"MaxHP":443},{"Number":"011","Name":"Metapod","Generation":"Generation I","About":"The shell covering this Pokémon’s body is as hard as an iron slab. Metapod does not move very much. It stays still because it is preparing its soft innards for evolution inside the hard shell.","Types":["Bug"],"Resistant":["Grass","Fighting","Ground"],"Weaknesses":["Fire","Flying","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"8.66kg","Maximum":"11.14kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"45 attack points.","Base Defense":"94 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":10,"Name":"Caterpie"}],"Next Evolution Requirements":{"Amount":50,"Name":"Caterpie candies"},"Next evolution(s)":[{"Number":12,"Name":"Butterfree"}],"MaxCP":397,"MaxHP":477},{"Number":"012","Name":"Butterfree","Generation":"Generation I","About":"Butterfree has a superior ability to search for delicious honey from flowers. It can even search out, extract, and carry honey from flowers that are blooming over six miles from its nest.","Types":["Bug","Flying"],"Resistant":["Grass","Fighting","Ground","Bug"],"Weaknesses":["Fire","Electric","Ice","Flying","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Confusion","Type":"Psychic","Damage":15}],"Special Attack(s)":[{"Name":"Bug Buzz","Type":"Bug","Damage":75},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Signal Beam","Type":"Bug","Damage":45}],"Weight":{"Minimum":"28kg","Maximum":"36kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"1km (Flying)","Base Stamina":"120 stamina points.","Base Attack":"167 attack points.","Base Defense":"151 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":10,"Name":"Caterpie"},{"Number":11,"Name":"Metapod"}],"MaxCP":1315,"MaxHP":1454},{"Number":"013","Name":"Weedle","Generation":"Generation I","About":"Weedle has an extremely acute sense of smell. It is capable of distinguishing its favorite kinds of leaves from those it dislikes just by sniffing with its big red proboscis (nose).","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"2.8kg","Maximum":"3.6kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Shoulder)","Base Stamina":"80 stamina points.","Base Attack":"63 attack points.","Base Defense":"55 defense points.","Base Flee Rate":"20% chance to flee.","Next Evolution Requirements":{"Amount":12,"Name":"Weedle candies"},"Next evolution(s)":[{"Number":14,"Name":"Kakuna"},{"Number":15,"Name":"Beedrill"}],"MaxCP":372,"MaxHP":449},{"Number":"014","Name":"Kakuna","Generation":"Generation I","About":"Kakuna remains virtually immobile as it clings to a tree. However, on the inside, it is extremely busy as it prepares for its coming evolution. This is evident from how hot the shell becomes to the touch.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"8.75kg","Maximum":"11.25kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"1km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"46 attack points.","Base Defense":"86 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":13,"Name":"Weedle"}],"Next Evolution Requirements":{"Amount":50,"Name":"Weedle candies"},"Next evolution(s)":[{"Number":15,"Name":"Beedrill"}],"MaxCP":405,"MaxHP":485},{"Number":"015","Name":"Beedrill","Generation":"Generation I","About":"Beedrill is extremely territorial. No one should ever approach its nest—this is for their own safety. If angered, they will attack in a furious swarm.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"25.81kg","Maximum":"33.19kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"1km (Flying)","Base Stamina":"130 stamina points.","Base Attack":"169 attack points.","Base Defense":"150 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":13,"Name":"Weedle"},{"Number":14,"Name":"Kakuna"}],"MaxCP":1301,"MaxHP":1439},{"Number":"016","Name":"Pidgey","Generation":"Generation I","About":"Pidgey has an extremely sharp sense of direction. It is capable of unerringly returning home to its nest, however far it may be removed from its familiar surroundings.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Twister","Type":"Dragon","Damage":25}],"Weight":{"Minimum":"1.57kg","Maximum":"2.02kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Shoulder)","Base Stamina":"80 stamina points.","Base Attack":"85 attack points.","Base Defense":"76 defense points.","Base Flee Rate":"20% chance to flee.","Next Evolution Requirements":{"Amount":12,"Name":"Pidgey candies"},"Next evolution(s)":[{"Number":17,"Name":"Pidgeotto"},{"Number":18,"Name":"Pidgeot"}],"MaxCP":585,"MaxHP":679},{"Number":"017","Name":"Pidgeotto","Generation":"Generation I","About":"Pidgeotto claims a large area as its own territory. This Pokémon flies around, patrolling its living space. If its territory is violated, it shows no mercy in thoroughly punishing the foe with its sharp claws.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Steel Wing","Type":"Steel","Damage":15},{"Name":"Wing Attack","Type":"Flying","Damage":9}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Twister","Type":"Dragon","Damage":25}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"1km (Flying)","Base Stamina":"126 stamina points.","Base Attack":"117 attack points.","Base Defense":"108 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":16,"Name":"Pidgey"}],"Next Evolution Requirements":{"Amount":50,"Name":"Pidgey candies"},"Next evolution(s)":[{"Number":18,"Name":"Pidgeot"}],"MaxCP":1096,"MaxHP":1223},{},{"Number":"019","Name":"Rattata","Generation":"Generation I","About":"Rattata is cautious in the extreme. Even while it is asleep, it constantly listens by moving its ears around. It is not picky about where it lives—it will make its nest anywhere.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Hyper Fang","Type":"Normal","Damage":35}],"Weight":{"Minimum":"3.06kg","Maximum":"3.94kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"103 attack points.","Base Defense":"70 defense points.","Base Flee Rate":"20% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Rattata candies"},"Next evolution(s)":[{"Number":20,"Name":"Raticate"}],"MaxCP":493,"MaxHP":581},{"Number":"020","Name":"Raticate","Generation":"Generation I","About":"Raticate’s sturdy fangs grow steadily. To keep them ground down, it gnaws on rocks and logs. It may even chew on the walls of houses.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Quick Attack","Type":"Normal","Damage":10}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Hyper Fang","Type":"Normal","Damage":35}],"Weight":{"Minimum":"16.19kg","Maximum":"20.81kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"161 attack points.","Base Defense":"144 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":19,"Name":"Rattata"}],"MaxCP":1304,"MaxHP":1444},{"Number":"021","Name":"Spearow","Generation":"Generation I","About":"Spearow has a very loud cry that can be heard over half a mile away. If its high, keening cry is heard echoing all around, it is a sign that they are warning each other of danger.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Quick Attack","Type":"Normal","Damage":10}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Drill Peck","Type":"Flying","Damage":40},{"Name":"Twister","Type":"Dragon","Damage":25}],"Weight":{"Minimum":"1.75kg","Maximum":"2.25kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Shoulder)","Base Stamina":"80 stamina points.","Base Attack":"112 attack points.","Base Defense":"61 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Spearow candies"},"Next evolution(s)":[{"Number":22,"Name":"Fearow"}],"MaxCP":591,"MaxHP":686},{"Number":"022","Name":"Fearow","Generation":"Generation I","About":"Fearow is recognized by its long neck and elongated beak. They are conveniently shaped for catching prey in soil or water. It deftly moves its long and skinny beak to pluck prey.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Steel Wing","Type":"Steel","Damage":15}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Drill Run","Type":"Ground","Damage":50},{"Name":"Twister","Type":"Dragon","Damage":25}],"Weight":{"Minimum":"33.25kg","Maximum":"42.75kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"1km (Flying)","Base Stamina":"130 stamina points.","Base Attack":"182 attack points.","Base Defense":"135 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":21,"Name":"Spearow"}],"MaxCP":1592,"MaxHP":1746},{"Number":"023","Name":"Ekans","Generation":"Generation I","About":"Ekans curls itself up in a spiral while it rests. Assuming this position allows it to quickly respond to a threat from any direction with a glare from its upraised head.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Gunk Shot","Type":"Poison","Damage":65},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Wrap","Type":"Normal","Damage":25}],"Weight":{"Minimum":"6.04kg","Maximum":"7.76kg"},"Height":{"Minimum":"1.75m","Maximum":"2.25m"},"Buddy Distance":"3km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"110 attack points.","Base Defense":"102 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Ekans candies"},"Next evolution(s)":[{"Number":24,"Name":"Arbok"}],"MaxCP":718,"MaxHP":824},{"Number":"024","Name":"Arbok","Generation":"Generation I","About":"This Pokémon is terrifically strong in order to constrict things with its body. It can even flatten steel oil drums. Once Arbok wraps its body around its foe, escaping its crunching embrace is impossible.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Bite","Type":"Dark","Damage":6}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Gunk Shot","Type":"Poison","Damage":65},{"Name":"Sludge Wave","Type":"Poison","Damage":70}],"Weight":{"Minimum":"56.88kg","Maximum":"73.13kg"},"Height":{"Minimum":"3.06m","Maximum":"3.94m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"167 attack points.","Base Defense":"158 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":23,"Name":"Ekans"}],"MaxCP":1611,"MaxHP":1767},{"Number":"025","Name":"Pikachu","Generation":"Generation I","About":"Whenever Pikachu comes across something new, it blasts it with a jolt of electricity. If you come across a blackened berry, it's evidence that this Pokémon mistook the intensity of its charge.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Thunder","Type":"Electric","Damage":100},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"5.25kg","Maximum":"6.75kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"1km (Shoulder)","Base Stamina":"70 stamina points.","Base Attack":"112 attack points.","Base Defense":"101 defense points.","Base Flee Rate":"10% chance to flee.","Previous evolution(s)":[{"Number":172,"Name":"Pichu"}],"Next Evolution Requirements":{"Amount":50,"Name":"Pikachu candies"},"Next evolution(s)":[{"Number":26,"Name":"Raichu"}],"MaxCP":777,"MaxHP":887},{"Number":"026","Name":"Raichu","Generation":"Generation I","About":"If the electrical sacs become excessively charged, Raichu plants its tail in the ground and discharges. Scorched patches of ground will be found near this Pokémon's nest.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Thunder","Type":"Electric","Damage":100},{"Name":"Thunder Punch","Type":"Electric","Damage":40}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"193 attack points.","Base Defense":"165 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":172,"Name":"Pichu"},{"Number":25,"Name":"Pikachu"}],"MaxCP":1859,"MaxHP":2028},{"Number":"027","Name":"Sandshrew","Generation":"Generation I","About":"Sandshrew's body is configured to absorb water without waste, enabling it to survive in an arid desert. This Pokémon curls up to protect itself from its enemies.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Mud Shot","Type":"Ground","Damage":6},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Rock Slide","Type":"Rock","Damage":50},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"10.5kg","Maximum":"13.5kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"126 attack points.","Base Defense":"145 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Sandshrew candies"},"Next evolution(s)":[{"Number":28,"Name":"Sandslash"}],"MaxCP":695,"MaxHP":798},{"Number":"028","Name":"Sandslash","Generation":"Generation I","About":"Sandslash's body is covered by tough spikes, which are hardened sections of its hide. Once a year, the old spikes fall out, to be replaced with new spikes that grow out from beneath the old ones.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Metal Claw","Type":"Steel","Damage":8},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Bulldoze","Type":"Ground","Damage":35},{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"25.81kg","Maximum":"33.19kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"182 attack points.","Base Defense":"202 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":27,"Name":"Sandshrew"}],"MaxCP":1654,"MaxHP":1810},{"Number":"029","Name":"Nidoran ♀","Generation":"Generation I","About":"Nidoran♀ has barbs that secrete a powerful poison. They are thought to have developed as protection for this small-bodied Pokémon. When enraged, it releases a horrible toxin from its horn.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Poison Fang","Type":"Poison","Damage":25},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"6.13kg","Maximum":"7.88kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"86 attack points.","Base Defense":"94 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Nidoran Female candies"},"Next evolution(s)":[{"Number":30,"Name":"Nidorina"},{"Number":31,"Name":"Nidoqueen"}],"MaxCP":768,"MaxHP":876},{"Number":"030","Name":"Nidorina","Generation":"Generation I","About":"When Nidorina are with their friends or family, they keep their barbs tucked away to prevent hurting each other. This Pokémon appears to become nervous if separated from the others.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Poison Fang","Type":"Poison","Damage":25},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"17.5kg","Maximum":"22.5kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"117 attack points.","Base Defense":"126 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":29,"Name":"Nidoran"}],"Next Evolution Requirements":{"Amount":100,"Name":"Nidoran Female candies"},"Next evolution(s)":[{"Number":31,"Name":"Nidoqueen"}],"MaxCP":1267,"MaxHP":1404},{"Number":"031","Name":"Nidoqueen","Generation":"Generation I","About":"Nidoqueen's body is encased in extremely hard scales. It is adept at sending foes flying with harsh tackles. This Pokémon is at its strongest when it is defending its young.","Types":["Poison","Ground"],"Resistant":["Electric","Fighting","Poison","Bug","Rock","Fairy"],"Weaknesses":["Water","Ice","Ground","Psychic"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Sludge Wave","Type":"Poison","Damage":70},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"52.5kg","Maximum":"67.5kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Big)","Base Stamina":"180 stamina points.","Base Attack":"180 attack points.","Base Defense":"174 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":29,"Name":"Nidoran"},{"Number":30,"Name":"Nidorina"}],"MaxCP":2301,"MaxHP":2485},{"Number":"032","Name":"Nidoran ♂","Generation":"Generation I","About":"Nidoran♂ has developed muscles for moving its ears. Thanks to them, the ears can be freely moved in any direction. Even the slightest sound does not escape this Pokémon's notice.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Horn Attack","Type":"Normal","Damage":25},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"7.88kg","Maximum":"10.13kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"3km (Medium)","Base Stamina":"92 stamina points.","Base Attack":"105 attack points.","Base Defense":"76 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Nidoran Male candies"},"Next evolution(s)":[{"Number":33,"Name":"Nidorino"},{"Number":34,"Name":"Nidoking"}],"MaxCP":737,"MaxHP":843},{"Number":"033","Name":"Nidorino","Generation":"Generation I","About":"Nidorino has a horn that is harder than a diamond. If it senses a hostile presence, all the barbs on its back bristle up at once, and it challenges the foe with all its might.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Poison Jab","Type":"Poison","Damage":12},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Horn Attack","Type":"Normal","Damage":25},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"17.06kg","Maximum":"21.94kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"3km (Medium)","Base Stamina":"122 stamina points.","Base Attack":"137 attack points.","Base Defense":"112 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":32,"Name":"Nidoran"}],"Next Evolution Requirements":{"Amount":100,"Name":"Nidoran Male candies"},"Next evolution(s)":[{"Number":34,"Name":"Nidoking"}],"MaxCP":1236,"MaxHP":1372},{"Number":"034","Name":"Nidoking","Generation":"Generation I","About":"Nidoking's thick tail packs enormously destructive power. With one swing, it can topple a metal transmission tower. Once this Pokémon goes on a rampage, there is no stopping it.","Types":["Poison","Ground"],"Resistant":["Electric","Fighting","Poison","Bug","Rock","Fairy"],"Weaknesses":["Water","Ice","Ground","Psychic"],"Fast Attack(s)":[{"Name":"Fury Cutter","Type":"Bug","Damage":3},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Megahorn","Type":"Bug","Damage":80},{"Name":"Sludge Wave","Type":"Poison","Damage":70}],"Weight":{"Minimum":"54.25kg","Maximum":"69.75kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"3km (Big)","Base Stamina":"162 stamina points.","Base Attack":"204 attack points.","Base Defense":"157 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":32,"Name":"Nidoran"},{"Number":33,"Name":"Nidorino"}],"MaxCP":2291,"MaxHP":2475},{"Number":"035","Name":"Clefairy","Generation":"Generation I","About":"On every night of a full moon, groups of this Pokémon come out to play. When dawn arrives, the tired Clefairy return to their quiet mountain retreats and go to sleep nestled up against each other.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Pound","Type":"Normal","Damage":7},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Disarming Voice","Type":"Fairy","Damage":25},{"Name":"Moonblast","Type":"Fairy","Damage":85}],"Weight":{"Minimum":"6.56kg","Maximum":"8.44kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"107 attack points.","Base Defense":"116 defense points.","Base Flee Rate":"10% chance to flee.","Previous evolution(s)":[{"Number":173,"Name":"Cleffa"}],"Next Evolution Requirements":{"Amount":50,"Name":"Clefairy candies"},"Next evolution(s)":[{"Number":36,"Name":"Clefable"}],"MaxCP":1074,"MaxHP":1200},{"Number":"036","Name":"Clefable","Generation":"Generation I","About":"Clefable moves by skipping lightly as if it were flying using its wings. Its bouncy step even lets it walk on water. It is known to take strolls on lakes on quiet, moonlit nights.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Pound","Type":"Normal","Damage":7},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Moonblast","Type":"Fairy","Damage":85},{"Name":"Psychic","Type":"Psychic","Damage":55}],"Weight":{"Minimum":"35kg","Maximum":"45kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"1km (Big)","Base Stamina":"190 stamina points.","Base Attack":"178 attack points.","Base Defense":"171 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":173,"Name":"Cleffa"},{"Number":35,"Name":"Clefairy"}],"MaxCP":2217,"MaxHP":2397},{"Number":"037","Name":"Vulpix","Generation":"Generation I","About":"At the time of its birth, Vulpix has one white tail. The tail separates into six if this Pokémon receives plenty of love from its trainer. The six tails become magnificently curled.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Quick Attack","Type":"Normal","Damage":10}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Flame Charge","Type":"Fire","Damage":25},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"8.66kg","Maximum":"11.14kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Medium)","Base Stamina":"76 stamina points.","Base Attack":"96 attack points.","Base Defense":"122 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Vulpi"},"Next evolution(s)":[{"Number":38,"Name":"Ninetales"}],"MaxCP":725,"MaxHP":831},{"Number":"038","Name":"Ninetales","Generation":"Generation I","About":"Ninetales casts a sinister light from its bright red eyes to gain total control over its foe's mind. This Pokémon is said to live for one thousand years.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Feint Attack","Type":"Dark","Damage":12}],"Special Attack(s)":[{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flamethrower","Type":"Fire","Damage":55},{"Name":"Heat Wave","Type":"Fire","Damage":80}],"Weight":{"Minimum":"17.41kg","Maximum":"22.39kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"3km (Big)","Base Stamina":"146 stamina points.","Base Attack":"169 attack points.","Base Defense":"204 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":37,"Name":"Vulpix"}],"MaxCP":2015,"MaxHP":2188},{"Number":"039","Name":"Jigglypuff","Generation":"Generation I","About":"Jigglypuff's vocal cords can freely adjust the wavelength of its voice. This Pokémon uses this ability to sing at precisely the right wavelength to make its foes most drowsy.","Types":["Normal","Fairy"],"Resistant":["Bug","Ghost","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Feint Attack","Type":"Dark","Damage":12},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Disarming Voice","Type":"Fairy","Damage":25}],"Weight":{"Minimum":"4.81kg","Maximum":"6.19kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"1km (Medium)","Base Stamina":"230 stamina points.","Base Attack":"80 attack points.","Base Defense":"44 defense points.","Base Flee Rate":"10% chance to flee.","Previous evolution(s)":[{"Number":174,"Name":"Igglybuff"}],"Next Evolution Requirements":{"Amount":50,"Name":"Jigglypuff candies"},"Next evolution(s)":[{"Number":40,"Name":"Wigglytuff"}],"MaxCP":796,"MaxHP":917},{"Number":"040","Name":"Wigglytuff","Generation":"Generation I","About":"Wigglytuff has large, saucerlike eyes. The surfaces of its eyes are always covered with a thin layer of tears. If any dust gets in this Pokémon's eyes, it is quickly washed away.","Types":["Normal","Fairy"],"Resistant":["Bug","Ghost","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Feint Attack","Type":"Dark","Damage":12},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Play Rough","Type":"Fairy","Damage":55}],"Weight":{"Minimum":"10.5kg","Maximum":"13.5kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"1km (Big)","Base Stamina":"280 stamina points.","Base Attack":"156 attack points.","Base Defense":"93 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":174,"Name":"Igglybuff"},{"Number":39,"Name":"Jigglypuff"}],"MaxCP":1997,"MaxHP":2177},{"Number":"041","Name":"Zubat","Generation":"Generation I","About":"Zubat remains quietly unmoving in a dark spot during the bright daylight hours. It does so because prolonged exposure to the sun causes its body to become slightly burned.","Types":["Poison","Flying"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Electric","Ice","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Quick Attack","Type":"Normal","Damage":10}],"Special Attack(s)":[{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Poison Fang","Type":"Poison","Damage":25},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"6.56kg","Maximum":"8.44kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"1km (Flying)","Base Stamina":"80 stamina points.","Base Attack":"83 attack points.","Base Defense":"76 defense points.","Base Flee Rate":"20% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Zubat candies"},"Next evolution(s)":[{"Number":42,"Name":"Golbat"},{"Number":169,"Name":"Crobat"}],"MaxCP":550,"MaxHP":642},{"Number":"042","Name":"Golbat","Generation":"Generation I","About":"Golbat loves to drink the blood of living things. It is particularly active in the pitch black of night. This Pokémon flits around in the night skies, seeking fresh blood.","Types":["Poison","Flying"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Electric","Ice","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Wing Attack","Type":"Flying","Damage":9}],"Special Attack(s)":[{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Ominous Wind","Type":"Ghost","Damage":30},{"Name":"Poison Fang","Type":"Poison","Damage":25}],"Weight":{"Minimum":"48.13kg","Maximum":"61.88kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"1km (Flying)","Base Stamina":"150 stamina points.","Base Attack":"161 attack points.","Base Defense":"153 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":41,"Name":"Zubat"}],"Next evolution(s)":[{"Number":169,"Name":"Crobat"}],"MaxCP":1760,"MaxHP":1921},{"Number":"043","Name":"Oddish","Generation":"Generation I","About":"During the daytime, Oddish buries itself in soil to absorb nutrients from the ground using its entire body. The more fertile the soil, the glossier its leaves become.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Razor Leaf","Type":"Grass","Damage":15}],"Special Attack(s)":[{"Name":"Moonblast","Type":"Fairy","Damage":85},{"Name":"Seed Bomb","Type":"Grass","Damage":40},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"4.73kg","Maximum":"6.08kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"3km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"131 attack points.","Base Defense":"116 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Oddish candies"},"Next evolution(s)":[{"Number":44,"Name":"Gloom"},{"Number":45,"Name":"Vileplume"},{"Number":182,"Name":"Bellossom"}],"MaxCP":1023,"MaxHP":1148},{"Number":"044","Name":"Gloom","Generation":"Generation I","About":"Gloom releases a foul fragrance from the pistil of its flower. When faced with danger, the stench worsens. If this Pokémon is feeling calm and secure, it does not release its usual stinky aroma.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Razor Leaf","Type":"Grass","Damage":15}],"Special Attack(s)":[{"Name":"Moonblast","Type":"Fairy","Damage":85},{"Name":"Petal Blizzard","Type":"Grass","Damage":65},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"7.53kg","Maximum":"9.68kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"153 attack points.","Base Defense":"139 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":43,"Name":"Oddish"}],"Next Evolution Requirements":{"Amount":100,"Name":"Oddish candies"},"Next evolution(s)":[{"Number":45,"Name":"Vileplume"},{"Number":182,"Name":"Bellossom"}],"MaxCP":1537,"MaxHP":1689},{"Number":"045","Name":"Vileplume","Generation":"Generation I","About":"Vileplume's toxic pollen triggers atrocious allergy attacks. That's why it is advisable never to approach any attractive flowers in a jungle, however pretty they may be.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Razor Leaf","Type":"Grass","Damage":15}],"Special Attack(s)":[{"Name":"Moonblast","Type":"Fairy","Damage":85},{"Name":"Petal Blizzard","Type":"Grass","Damage":65},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"16.28kg","Maximum":"20.93kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Big)","Base Stamina":"150 stamina points.","Base Attack":"202 attack points.","Base Defense":"170 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":43,"Name":"Oddish"},{"Number":44,"Name":"Gloom"}],"MaxCP":2307,"MaxHP":2492},{"Number":"046","Name":"Paras","Generation":"Generation I","About":"Paras has parasitic mushrooms growing on its back called tochukaso. They grow large by drawing nutrients from this Bug Pokémon host. They are highly valued as a medicine for extending life.","Types":["Bug","Grass"],"Resistant":["Water","Electric","Grass","Fighting","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Cross Poison","Type":"Poison","Damage":25},{"Name":"Seed Bomb","Type":"Grass","Damage":40},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"4.73kg","Maximum":"6.08kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"3km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"121 attack points.","Base Defense":"99 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Paras candies"},"Next evolution(s)":[{"Number":47,"Name":"Parasect"}],"MaxCP":804,"MaxHP":916},{"Number":"047","Name":"Parasect","Generation":"Generation I","About":"Parasect is known to infest large trees en masse and drain nutrients from the lower trunk and roots. When an infested tree dies, they move onto another tree all at once.","Types":["Bug","Grass"],"Resistant":["Water","Electric","Grass","Fighting","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Fury Cutter","Type":"Bug","Damage":3}],"Special Attack(s)":[{"Name":"Cross Poison","Type":"Poison","Damage":25},{"Name":"Solar Beam","Type":"Grass","Damage":120},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"25.81kg","Maximum":"33.19kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"165 attack points.","Base Defense":"146 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":46,"Name":"Paras"}],"MaxCP":1592,"MaxHP":1747},{"Number":"048","Name":"Venonat","Generation":"Generation I","About":"Venonat is said to have evolved with a coat of thin, stiff hair that covers its entire body for protection. It possesses large eyes that never fail to spot even miniscule prey.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Confusion","Type":"Psychic","Damage":15}],"Special Attack(s)":[{"Name":"Poison Fang","Type":"Poison","Damage":25},{"Name":"Psybeam","Type":"Psychic","Damage":40},{"Name":"Signal Beam","Type":"Bug","Damage":45}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"100 attack points.","Base Defense":"102 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Venonat candies"},"Next evolution(s)":[{"Number":49,"Name":"Venomoth"}],"MaxCP":912,"MaxHP":1029},{"Number":"049","Name":"Venomoth","Generation":"Generation I","About":"Venomoth is nocturnal—it is a Pokémon that only becomes active at night. Its favorite prey are small insects that gather around streetlights, attracted by the light in the darkness.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Confusion","Type":"Psychic","Damage":15}],"Special Attack(s)":[{"Name":"Bug Buzz","Type":"Bug","Damage":75},{"Name":"Poison Fang","Type":"Poison","Damage":25},{"Name":"Psychic","Type":"Psychic","Damage":55}],"Weight":{"Minimum":"10.94kg","Maximum":"14.06kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"3km (Flying)","Base Stamina":"140 stamina points.","Base Attack":"179 attack points.","Base Defense":"150 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":48,"Name":"Venonat"}],"MaxCP":1730,"MaxHP":1890},{"Number":"050","Name":"Diglett","Generation":"Generation I","About":"Diglett are raised in most farms. The reason is simple—wherever this Pokémon burrows, the soil is left perfectly tilled for planting crops. This soil is made ideal for growing delicious vegetables.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Mud Bomb","Type":"Ground","Damage":30},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"0.7kg","Maximum":"0.9kg"},"Height":{"Minimum":"0.18m","Maximum":"0.23m"},"Buddy Distance":"3km (Medium)","Base Stamina":"20 stamina points.","Base Attack":"109 attack points.","Base Defense":"88 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Diglett candies"},"Next evolution(s)":[{"Number":51,"Name":"Dugtrio"}],"MaxCP":365,"MaxHP":456},{"Number":"051","Name":"Dugtrio","Generation":"Generation I","About":"Dugtrio are actually triplets that emerged from one body. As a result, each triplet thinks exactly like the other two triplets. They work cooperatively to burrow endlessly.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Sucker Punch","Type":"Dark","Damage":7}],"Special Attack(s)":[{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Mud Bomb","Type":"Ground","Damage":30},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"29.14kg","Maximum":"37.46kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"3km (Big)","Base Stamina":"70 stamina points.","Base Attack":"167 attack points.","Base Defense":"147 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":50,"Name":"Diglett"}],"MaxCP":1038,"MaxHP":1168},{"Number":"052","Name":"Meowth","Generation":"Generation I","About":"Meowth withdraws its sharp claws into its paws to slinkily sneak about without making any incriminating footsteps. For some reason, this Pokémon loves shiny coins that glitter with light.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Night Slash","Type":"Dark","Damage":30}],"Weight":{"Minimum":"3.67kg","Maximum":"4.72kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"92 attack points.","Base Defense":"81 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Meowth candies"},"Next evolution(s)":[{"Number":53,"Name":"Persian"}],"MaxCP":656,"MaxHP":756},{"Number":"053","Name":"Persian","Generation":"Generation I","About":"Persian has six bold whiskers that give it a look of toughness. The whiskers sense air movements to determine what is in the Pokémon's surrounding vicinity. It becomes docile if grabbed by the whiskers.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Feint Attack","Type":"Dark","Damage":12},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Night Slash","Type":"Dark","Damage":30},{"Name":"Play Rough","Type":"Fairy","Damage":55},{"Name":"Power Gem","Type":"Rock","Damage":40}],"Weight":{"Minimum":"28kg","Maximum":"36kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"150 attack points.","Base Defense":"139 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":52,"Name":"Meowth"}],"MaxCP":1483,"MaxHP":1631},{"Number":"054","Name":"Psyduck","Generation":"Generation I","About":"Psyduck uses a mysterious power. When it does so, this Pokémon generates brain waves that are supposedly only seen in sleepers. This discovery spurred controversy among scholars.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Water Gun","Type":"Water","Damage":6},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Psybeam","Type":"Psychic","Damage":40}],"Weight":{"Minimum":"17.15kg","Maximum":"22.05kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"122 attack points.","Base Defense":"96 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Psyduck candies"},"Next evolution(s)":[{"Number":55,"Name":"Golduck"}],"MaxCP":987,"MaxHP":1109},{"Number":"055","Name":"Golduck","Generation":"Generation I","About":"The webbed flippers on its forelegs and hind legs and the streamlined body of Golduck give it frightening speed. The Pokémon is definitely much faster than even the most athletic swimmer.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Ice Beam","Type":"Ice","Damage":65},{"Name":"Psychic","Type":"Psychic","Damage":55}],"Weight":{"Minimum":"67.02kg","Maximum":"86.17kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"191 attack points.","Base Defense":"163 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":54,"Name":"Psyduck"}],"MaxCP":2206,"MaxHP":2386},{"Number":"056","Name":"Mankey","Generation":"Generation I","About":"When Mankey starts shaking and its nasal breathing turns rough, it's a sure sign that it is becoming angry. However, because it goes into a towering rage almost instantly, it is impossible for anyone to flee its wrath.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Karate Chop","Type":"Fighting","Damage":6},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Low Sweep","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"24.5kg","Maximum":"31.5kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"3km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"148 attack points.","Base Defense":"87 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Mankey candies"},"Next evolution(s)":[{"Number":57,"Name":"Primeape"}],"MaxCP":769,"MaxHP":878},{"Number":"057","Name":"Primeape","Generation":"Generation I","About":"When Primeape becomes furious, its blood circulation is boosted. In turn, its muscles are made even stronger. However, it also becomes much less intelligent at the same time.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Karate Chop","Type":"Fighting","Damage":6},{"Name":"Low Kick","Type":"Fighting","Damage":5}],"Special Attack(s)":[{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Low Sweep","Type":"Fighting","Damage":30},{"Name":"Night Slash","Type":"Dark","Damage":30}],"Weight":{"Minimum":"28kg","Maximum":"36kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"207 attack points.","Base Defense":"144 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":56,"Name":"Mankey"}],"MaxCP":1704,"MaxHP":1864},{"Number":"058","Name":"Growlithe","Generation":"Generation I","About":"Growlithe has a superb sense of smell. Once it smells anything, this Pokémon won't forget the scent, no matter what. It uses its advanced olfactory sense to determine the emotions of other living things.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Ember","Type":"Fire","Damage":10}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Flame Wheel","Type":"Fire","Damage":40},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"16.63kg","Maximum":"21.38kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"3km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"136 attack points.","Base Defense":"96 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Growlithe candies"},"Next evolution(s)":[{"Number":59,"Name":"Arcanine"}],"MaxCP":1199,"MaxHP":1335},{"Number":"059","Name":"Arcanine","Generation":"Generation I","About":"Arcanine is known for its high speed. It is said to be capable of running over 6,200 miles in a single day and night. The fire that blazes wildly within this Pokémon's body is its source of power.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Fire Fang","Type":"Fire","Damage":10}],"Special Attack(s)":[{"Name":"Bulldoze","Type":"Ground","Damage":35},{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"135.63kg","Maximum":"174.38kg"},"Height":{"Minimum":"1.66m","Maximum":"2.14m"},"Buddy Distance":"3km (Big)","Base Stamina":"180 stamina points.","Base Attack":"227 attack points.","Base Defense":"166 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":58,"Name":"Growlithe"}],"MaxCP":2781,"MaxHP":2983},{"Number":"060","Name":"Poliwag","Generation":"Generation I","About":"Poliwag has a very thin skin. It is possible to see the Pokémon's spiral innards right through the skin. Despite its thinness, however, the skin is also very flexible. Even sharp fangs bounce right off it.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Mud Bomb","Type":"Ground","Damage":30}],"Weight":{"Minimum":"10.85kg","Maximum":"13.95kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"101 attack points.","Base Defense":"82 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Poliwag candies"},"Next evolution(s)":[{"Number":61,"Name":"Poliwhirl"},{"Number":62,"Name":"Poliwrath"},{"Number":186,"Name":"Politoed"}],"MaxCP":693,"MaxHP":795},{"Number":"061","Name":"Poliwhirl","Generation":"Generation I","About":"The surface of Poliwhirl's body is always wet and slick with an oily fluid. Because of this greasy covering, it can easily slip and slide out of the clutches of any enemy in battle.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Mud Bomb","Type":"Ground","Damage":30},{"Name":"Scald","Type":"Water","Damage":55}],"Weight":{"Minimum":"17.5kg","Maximum":"22.5kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"130 attack points.","Base Defense":"130 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":60,"Name":"Poliwag"}],"Next Evolution Requirements":{"Amount":100,"Name":"Poliwag candies"},"Next evolution(s)":[{"Number":62,"Name":"Poliwrath"},{"Number":186,"Name":"Politoed"}],"MaxCP":1206,"MaxHP":1340},{"Number":"062","Name":"Poliwrath","Generation":"Generation I","About":"Poliwrath's highly developed, brawny muscles never grow fatigued, however much it exercises. It is so tirelessly strong, this Pokémon can swim back and forth across the ocean without effort.","Types":["Water","Fighting"],"Resistant":["Fire","Water","Ice","Bug","Rock","Dark","Steel"],"Weaknesses":["Electric","Grass","Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Ice Punch","Type":"Ice","Damage":45},{"Name":"Submission","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"47.25kg","Maximum":"60.75kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Big)","Base Stamina":"180 stamina points.","Base Attack":"182 attack points.","Base Defense":"187 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":60,"Name":"Poliwag"},{"Number":61,"Name":"Poliwhirl"}],"MaxCP":2321,"MaxHP":2505},{"Number":"063","Name":"Abra","Generation":"Generation I","About":"Abra sleeps for eighteen hours a day. However, it can sense the presence of foes even while it is sleeping. In such a situation, this Pokémon immediately teleports to safety.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Psyshock","Type":"Psychic","Damage":40},{"Name":"Shadow Ball","Type":"Ghost","Damage":45},{"Name":"Signal Beam","Type":"Bug","Damage":45}],"Weight":{"Minimum":"17.06kg","Maximum":"21.94kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"3km (Medium)","Base Stamina":"50 stamina points.","Base Attack":"195 attack points.","Base Defense":"103 defense points.","Base Flee Rate":"99% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Abra candies"},"Next evolution(s)":[{"Number":64,"Name":"Kadabra"},{"Number":65,"Name":"Alakazam"}],"MaxCP":508,"MaxHP":600},{"Number":"064","Name":"Kadabra","Generation":"Generation I","About":"Kadabra emits a peculiar alpha wave if it develops a headache. Only those people with a particularly strong psyche can hope to become a trainer of this Pokémon.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Psycho Cut","Type":"Psychic","Damage":7}],"Special Attack(s)":[{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Psybeam","Type":"Psychic","Damage":40},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"49.44kg","Maximum":"63.56kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Big)","Base Stamina":"80 stamina points.","Base Attack":"232 attack points.","Base Defense":"138 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":63,"Name":"Abra"}],"Next Evolution Requirements":{"Amount":100,"Name":"Abra candies"},"Next evolution(s)":[{"Number":65,"Name":"Alakazam"}],"MaxCP":1005,"MaxHP":1131},{"Number":"065","Name":"Alakazam","Generation":"Generation I","About":"Alakazam's brain continually grows, making its head far too heavy to support with its neck. This Pokémon holds its head up using its psychokinetic power instead.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Psycho Cut","Type":"Psychic","Damage":7}],"Special Attack(s)":[{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"42kg","Maximum":"54kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"3km (Big)","Base Stamina":"110 stamina points.","Base Attack":"271 attack points.","Base Defense":"194 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":63,"Name":"Abra"},{"Number":64,"Name":"Kadabra"}],"MaxCP":1654,"MaxHP":1813},{"Number":"066","Name":"Machop","Generation":"Generation I","About":"Machop's muscles are special—they never get sore no matter how much they are used in exercise. This Pokémon has sufficient power to hurl a hundred adult humans.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Karate Chop","Type":"Fighting","Damage":6},{"Name":"Low Kick","Type":"Fighting","Damage":5}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Low Sweep","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"17.06kg","Maximum":"21.94kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"137 attack points.","Base Defense":"88 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Machop candies"},"Next evolution(s)":[{"Number":67,"Name":"Machoke"},{"Number":68,"Name":"Machamp"}],"MaxCP":968,"MaxHP":1089},{"Number":"067","Name":"Machoke","Generation":"Generation I","About":"Machoke's thoroughly toned muscles possess the hardness of steel. This Pokémon has so much strength, it can easily hold aloft a sumo wrestler on just one finger.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Karate Chop","Type":"Fighting","Damage":6},{"Name":"Low Kick","Type":"Fighting","Damage":5}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Submission","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"61.69kg","Maximum":"79.31kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"177 attack points.","Base Defense":"130 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":66,"Name":"Machop"}],"Next Evolution Requirements":{"Amount":100,"Name":"Machop candies"},"Next evolution(s)":[{"Number":68,"Name":"Machamp"}],"MaxCP":1606,"MaxHP":1760},{"Number":"068","Name":"Machamp","Generation":"Generation I","About":"Machamp has the power to hurl anything aside. However, trying to do any work requiring care and dexterity causes its arms to get tangled. This Pokémon tends to leap into action before it thinks.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Bullet Punch","Type":"Steel","Damage":10},{"Name":"Karate Chop","Type":"Fighting","Damage":6}],"Special Attack(s)":[{"Name":"Cross Chop","Type":"Fighting","Damage":60},{"Name":"Stone Edge","Type":"Rock","Damage":80},{"Name":"Submission","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"113.75kg","Maximum":"146.25kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Big)","Base Stamina":"180 stamina points.","Base Attack":"234 attack points.","Base Defense":"162 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":66,"Name":"Machop"},{"Number":67,"Name":"Machoke"}],"MaxCP":2406,"MaxHP":2594},{"Number":"069","Name":"Bellsprout","Generation":"Generation I","About":"Bellsprout's thin and flexible body lets it bend and sway to avoid any attack, however strong it may be. From its mouth, this Pokémon spits a corrosive fluid that melts even iron.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Wrap","Type":"Normal","Damage":25}],"Weight":{"Minimum":"3.5kg","Maximum":"4.5kg"},"Height":{"Minimum":"0.61m","Maximum":"0.79m"},"Buddy Distance":"3km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"139 attack points.","Base Defense":"64 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Bellsprout candies"},"Next evolution(s)":[{"Number":70,"Name":"Weepinbell"},{"Number":71,"Name":"Victreebel"}],"MaxCP":990,"MaxHP":1117},{"Number":"070","Name":"Weepinbell","Generation":"Generation I","About":"Weepinbell has a large hook on its rear end. At night, the Pokémon hooks on to a tree branch and goes to sleep. If it moves around in its sleep, it may wake up to find itself on the ground.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Razor Leaf","Type":"Grass","Damage":15}],"Special Attack(s)":[{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Seed Bomb","Type":"Grass","Damage":40},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"5.6kg","Maximum":"7.2kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"172 attack points.","Base Defense":"95 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":69,"Name":"Bellsprout"}],"Next Evolution Requirements":{"Amount":100,"Name":"Bellsprout candies"},"Next evolution(s)":[{"Number":71,"Name":"Victreebel"}],"MaxCP":1567,"MaxHP":1723},{"Number":"071","Name":"Victreebel","Generation":"Generation I","About":"Victreebel has a long vine that extends from its head. This vine is waved and flicked about as if it were an animal to attract prey. When an unsuspecting prey draws near, this Pokémon swallows it whole.","Types":["Grass","Poison"],"Resistant":["Water","Electric","Grass","Fighting","Fairy"],"Weaknesses":["Fire","Ice","Flying","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Razor Leaf","Type":"Grass","Damage":15}],"Special Attack(s)":[{"Name":"Leaf Blade","Type":"Grass","Damage":55},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"13.56kg","Maximum":"17.44kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"207 attack points.","Base Defense":"138 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":69,"Name":"Bellsprout"},{"Number":70,"Name":"Weepinbell"}],"MaxCP":2342,"MaxHP":2530},{"Number":"072","Name":"Tentacool","Generation":"Generation I","About":"Tentacool's body is largely composed of water. If it is removed from the sea, it dries up like parchment. If this Pokémon happens to become dehydrated, put it back into the sea.","Types":["Water","Poison"],"Resistant":["Fire","Water","Ice","Fighting","Poison","Bug","Steel","Fairy"],"Weaknesses":["Electric","Ground","Psychic"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Water Pulse","Type":"Water","Damage":35},{"Name":"Wrap","Type":"Normal","Damage":25}],"Weight":{"Minimum":"39.81kg","Maximum":"51.19kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"3km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"97 attack points.","Base Defense":"182 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Tentacool candies"},"Next evolution(s)":[{"Number":73,"Name":"Tentacruel"}],"MaxCP":794,"MaxHP":905},{"Number":"073","Name":"Tentacruel","Generation":"Generation I","About":"Tentacruel has large red orbs on its head. The orbs glow before lashing the vicinity with a harsh ultrasonic blast. This Pokémon's outburst creates rough waves around it.","Types":["Water","Poison"],"Resistant":["Fire","Water","Ice","Fighting","Poison","Bug","Steel","Fairy"],"Weaknesses":["Electric","Ground","Psychic"],"Fast Attack(s)":[{"Name":"Acid","Type":"Poison","Damage":10},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Sludge Wave","Type":"Poison","Damage":70}],"Weight":{"Minimum":"48.13kg","Maximum":"61.88kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"166 attack points.","Base Defense":"237 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":72,"Name":"Tentacool"}],"MaxCP":2046,"MaxHP":2220},{"Number":"074","Name":"Geodude","Generation":"Generation I","About":"The longer a Geodude lives, the more its edges are chipped and worn away, making it more rounded in appearance. However, this Pokémon's heart will remain hard, craggy, and rough always.","Types":["Rock","Ground"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Rock Throw","Type":"Rock","Damage":12},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Rock Slide","Type":"Rock","Damage":50},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"17.5kg","Maximum":"22.5kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"1km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"132 attack points.","Base Defense":"163 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Geodude candies"},"Next evolution(s)":[{"Number":75,"Name":"Graveler"},{"Number":76,"Name":"Golem"}],"MaxCP":742,"MaxHP":849},{"Number":"075","Name":"Graveler","Generation":"Generation I","About":"Graveler grows by feeding on rocks. Apparently, it prefers to eat rocks that are covered in moss. This Pokémon eats its way through a ton of rocks on a daily basis.","Types":["Rock","Ground"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Throw","Type":"Rock","Damage":12}],"Special Attack(s)":[{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Rock Slide","Type":"Rock","Damage":50},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"91.88kg","Maximum":"118.13kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"1km (Big)","Base Stamina":"110 stamina points.","Base Attack":"164 attack points.","Base Defense":"196 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":74,"Name":"Geodude"}],"Next Evolution Requirements":{"Amount":100,"Name":"Geodude candies"},"Next evolution(s)":[{"Number":76,"Name":"Golem"}],"MaxCP":1294,"MaxHP":1433},{"Number":"076","Name":"Golem","Generation":"Generation I","About":"Golem live up on mountains. If there is a large earthquake, these Pokémon will come rolling down off the mountains en masse to the foothills below.","Types":["Rock","Ground"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Throw","Type":"Rock","Damage":12}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"262.5kg","Maximum":"337.5kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Big)","Base Stamina":"160 stamina points.","Base Attack":"211 attack points.","Base Defense":"229 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":74,"Name":"Geodude"},{"Number":75,"Name":"Graveler"}],"MaxCP":2126,"MaxHP":2303},{"Number":"077","Name":"Ponyta","Generation":"Generation I","About":"Ponyta is very weak at birth. It can barely stand up. This Pokémon becomes stronger by stumbling and falling to keep up with its parent.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flame Charge","Type":"Fire","Damage":25},{"Name":"Flame Wheel","Type":"Fire","Damage":40}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"170 attack points.","Base Defense":"132 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Ponyta candies"},"Next evolution(s)":[{"Number":78,"Name":"Rapidash"}],"MaxCP":1370,"MaxHP":1516},{"Number":"078","Name":"Rapidash","Generation":"Generation I","About":"Rapidash usually can be seen casually cantering in the fields and plains. However, when this Pokémon turns serious, its fiery manes flare and blaze as it gallops its way up to 150 mph.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Low Kick","Type":"Fighting","Damage":5}],"Special Attack(s)":[{"Name":"Drill Run","Type":"Ground","Damage":50},{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Heat Wave","Type":"Fire","Damage":80}],"Weight":{"Minimum":"83.13kg","Maximum":"106.88kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"207 attack points.","Base Defense":"167 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":77,"Name":"Ponyta"}],"MaxCP":2024,"MaxHP":2199},{"Number":"079","Name":"Slowpoke","Generation":"Generation I","About":"Slowpoke uses its tail to catch prey by dipping it in water at the side of a river. However, this Pokémon often forgets what it's doing and often spends entire days just loafing at water's edge.","Types":["Water","Psychic"],"Resistant":["Fire","Water","Ice","Fighting","Psychic","Steel"],"Weaknesses":["Electric","Grass","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Psyshock","Type":"Psychic","Damage":40},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"31.5kg","Maximum":"40.5kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"109 attack points.","Base Defense":"109 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Slowpoke candies"},"Next evolution(s)":[{"Number":80,"Name":"Slowbro"},{"Number":199,"Name":"Slowking"}],"MaxCP":1089,"MaxHP":1218},{"Number":"080","Name":"Slowbro","Generation":"Generation I","About":"Slowbro's tail has a Shellder firmly attached with a bite. As a result, the tail can't be used for fishing anymore. This causes Slowbro to grudgingly swim and catch prey instead.","Types":["Water","Psychic"],"Resistant":["Fire","Water","Ice","Fighting","Psychic","Steel"],"Weaknesses":["Electric","Grass","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Ice Beam","Type":"Ice","Damage":65},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"68.69kg","Maximum":"88.31kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Big)","Base Stamina":"190 stamina points.","Base Attack":"177 attack points.","Base Defense":"194 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":79,"Name":"Slowpoke"}],"MaxCP":2409,"MaxHP":2597},{"Number":"081","Name":"Magnemite","Generation":"Generation I","About":"Magnemite attaches itself to power lines to feed on electricity. If your house has a power outage, check your circuit breakers. You may find a large number of this Pokémon clinging to the breaker box.","Types":["Electric","Steel"],"Resistant":["Normal","Electric","Grass","Ice","Poison","Flying","Psychic","Bug","Rock","Dragon","Steel","Fairy"],"Weaknesses":["Fire","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Magnet Bomb","Type":"Steel","Damage":30},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"5.25kg","Maximum":"6.75kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"3km (Flying)","Base Stamina":"50 stamina points.","Base Attack":"165 attack points.","Base Defense":"128 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Magnemite candies"},"Next evolution(s)":[{"Number":82,"Name":"Magneton"}],"MaxCP":774,"MaxHP":890},{"Number":"082","Name":"Magneton","Generation":"Generation I","About":"Magneton emits a powerful magnetic force that is fatal to mechanical devices. As a result, large cities sound sirens to warn citizens of large-scale outbreaks of this Pokémon.","Types":["Electric","Steel"],"Resistant":["Normal","Electric","Grass","Ice","Poison","Flying","Psychic","Bug","Rock","Dragon","Steel","Fairy"],"Weaknesses":["Fire","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Flash Cannon","Type":"Steel","Damage":60},{"Name":"Magnet Bomb","Type":"Steel","Damage":30}],"Weight":{"Minimum":"52.5kg","Maximum":"67.5kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"100 stamina points.","Base Attack":"223 attack points.","Base Defense":"182 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":81,"Name":"Magnemite"}],"MaxCP":1715,"MaxHP":1879},{"Number":"083","Name":"Farfetchd","Generation":"Generation I","About":"Farfetch'd is always seen with a stalk from a plant of some sort. Apparently, there are good stalks and bad stalks. This Pokémon has been known to fight with others over stalks.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Cut","Type":"Normal","Damage":12},{"Name":"Fury Cutter","Type":"Bug","Damage":3}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Leaf Blade","Type":"Grass","Damage":55}],"Weight":{"Minimum":"13.13kg","Maximum":"16.88kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"104 stamina points.","Base Attack":"124 attack points.","Base Defense":"118 defense points.","Base Flee Rate":"9% chance to flee.","Common Capture Area":"Early reports that this Pokèmon is likely to be found in: Asia or hatched from an Egg in that geographic area.","Asia":"Common Capture Area","MaxCP":1133,"MaxHP":1263},{"Number":"084","Name":"Doduo","Generation":"Generation I","About":"Doduo's two heads never sleep at the same time. Its two heads take turns sleeping, so one head can always keep watch for enemies while the other one sleeps.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Quick Attack","Type":"Normal","Damage":10}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Drill Peck","Type":"Flying","Damage":40},{"Name":"Swift","Type":"Normal","Damage":30}],"Weight":{"Minimum":"34.3kg","Maximum":"44.1kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"3km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"158 attack points.","Base Defense":"88 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Doduo candies"},"Next evolution(s)":[{"Number":85,"Name":"Dodrio"}],"MaxCP":746,"MaxHP":855},{"Number":"085","Name":"Dodrio","Generation":"Generation I","About":"Watch out if Dodrio's three heads are looking in three separate directions. It's a sure sign that it is on its guard. Don't go near this Pokémon if it's being wary-it may decide to peck you.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Feint Attack","Type":"Dark","Damage":12},{"Name":"Steel Wing","Type":"Steel","Damage":15}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Air Cutter","Type":"Flying","Damage":30},{"Name":"Drill Peck","Type":"Flying","Damage":40}],"Weight":{"Minimum":"74.55kg","Maximum":"95.85kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"218 attack points.","Base Defense":"145 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":84,"Name":"Doduo"}],"MaxCP":1677,"MaxHP":1836},{"Number":"086","Name":"Seel","Generation":"Generation I","About":"Seel hunts for prey in the frigid sea underneath sheets of ice. When it needs to breathe, it punches a hole through the ice with the sharply protruding section of its head.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Ice Shard","Type":"Ice","Damage":15},{"Name":"Lick","Type":"Ghost","Damage":5}],"Special Attack(s)":[{"Name":"Aqua Jet","Type":"Water","Damage":25},{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Icy Wind","Type":"Ice","Damage":25}],"Weight":{"Minimum":"78.75kg","Maximum":"101.25kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"3km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"85 attack points.","Base Defense":"128 defense points.","Base Flee Rate":"9% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Seel candies"},"Next evolution(s)":[{"Number":87,"Name":"Dewgong"}],"MaxCP":985,"MaxHP":1107},{"Number":"087","Name":"Dewgong","Generation":"Generation I","About":"Dewgong loves to snooze on bitterly cold ice. The sight of this Pokémon sleeping on a glacier was mistakenly thought to be a mermaid by a mariner long ago.","Types":["Water","Ice"],"Resistant":["Water","Ice"],"Weaknesses":["Electric","Grass","Fighting","Rock"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9},{"Name":"Ice Shard","Type":"Ice","Damage":15}],"Special Attack(s)":[{"Name":"Aqua Jet","Type":"Water","Damage":25},{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Icy Wind","Type":"Ice","Damage":25}],"Weight":{"Minimum":"105kg","Maximum":"135kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"3km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"139 attack points.","Base Defense":"184 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":86,"Name":"Seel"}],"MaxCP":1975,"MaxHP":2145},{"Number":"088","Name":"Grimer","Generation":"Generation I","About":"Grimer's sludgy and rubbery body can be forced through any opening, however small it may be. This Pokémon enters sewer pipes to drink filthy wastewater.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Mud Bomb","Type":"Ground","Damage":30},{"Name":"Sludge","Type":"Poison","Damage":30},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"135 attack points.","Base Defense":"90 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Grimer candies"},"Next evolution(s)":[{"Number":89,"Name":"Muk"}],"MaxCP":1152,"MaxHP":1284},{"Number":"089","Name":"Muk","Generation":"Generation I","About":"From Muk's body seeps a foul fluid that gives off a nose-bendingly horrible stench. Just one drop of this Pokémon's body fluid can turn a pool stagnant and rancid.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Lick","Type":"Ghost","Damage":5},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Gunk Shot","Type":"Poison","Damage":65},{"Name":"Sludge Wave","Type":"Poison","Damage":70}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Big)","Base Stamina":"210 stamina points.","Base Attack":"190 attack points.","Base Defense":"184 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":88,"Name":"Grimer"}],"MaxCP":2414,"MaxHP":2602},{"Number":"090","Name":"Shellder","Generation":"Generation I","About":"At night, this Pokémon uses its broad tongue to burrow a hole in the seafloor sand and then sleep in it. While it is sleeping, Shellder closes its shell, but leaves its tongue hanging out.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Ice Shard","Type":"Ice","Damage":15},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Icy Wind","Type":"Ice","Damage":25},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"3.5kg","Maximum":"4.5kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"3km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"116 attack points.","Base Defense":"168 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Shellder candies"},"Next evolution(s)":[{"Number":91,"Name":"Cloyster"}],"MaxCP":715,"MaxHP":822},{"Number":"091","Name":"Cloyster","Generation":"Generation I","About":"Cloyster is capable of swimming in the sea. It does so by swallowing water, then jetting it out toward the rear. This Pokémon shoots spikes from its shell using the same system.","Types":["Water","Ice"],"Resistant":["Water","Ice"],"Weaknesses":["Electric","Grass","Fighting","Rock"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9},{"Name":"Ice Shard","Type":"Ice","Damage":15}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Icy Wind","Type":"Ice","Damage":25}],"Weight":{"Minimum":"115.94kg","Maximum":"149.06kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"3km (Big)","Base Stamina":"100 stamina points.","Base Attack":"186 attack points.","Base Defense":"323 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":90,"Name":"Shellder"}],"MaxCP":1879,"MaxHP":2052},{"Number":"092","Name":"Gastly","Generation":"Generation I","About":"Gastly is largely composed of gaseous matter. When exposed to a strong wind, the gaseous body quickly dwindles away. Groups of this Pokémon cluster under the eaves of houses to escape the ravages of wind.","Types":["Ghost","Poison"],"Resistant":["Normal","Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Lick","Type":"Ghost","Damage":5},{"Name":"Sucker Punch","Type":"Dark","Damage":7}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Ominous Wind","Type":"Ghost","Damage":30},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"0.09kg","Maximum":"0.11kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Flying)","Base Stamina":"60 stamina points.","Base Attack":"186 attack points.","Base Defense":"70 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Gastly candies"},"Next evolution(s)":[{"Number":93,"Name":"Haunter"},{"Number":94,"Name":"Gengar"}],"MaxCP":696,"MaxHP":804},{"Number":"093","Name":"Haunter","Generation":"Generation I","About":"Haunter is a dangerous Pokémon. If one beckons you while floating in darkness, you must never approach it. This Pokémon will try to lick you with its tongue and steal your life away.","Types":["Ghost","Poison"],"Resistant":["Normal","Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Lick","Type":"Ghost","Damage":5},{"Name":"Shadow Claw","Type":"Ghost","Damage":11}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Shadow Ball","Type":"Ghost","Damage":45},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"0.09kg","Maximum":"0.11kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Flying)","Base Stamina":"90 stamina points.","Base Attack":"223 attack points.","Base Defense":"112 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":92,"Name":"Gastly"}],"Next Evolution Requirements":{"Amount":100,"Name":"Gastly candies"},"Next evolution(s)":[{"Number":94,"Name":"Gengar"}],"MaxCP":1240,"MaxHP":1380},{"Number":"094","Name":"Gengar","Generation":"Generation I","About":"Sometimes, on a dark night, your shadow thrown by a streetlight will suddenly and startlingly overtake you. It is actually a Gengar running past you, pretending to be your shadow.","Types":["Ghost","Poison"],"Resistant":["Normal","Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Shadow Claw","Type":"Ghost","Damage":11},{"Name":"Sucker Punch","Type":"Dark","Damage":7}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Shadow Ball","Type":"Ghost","Damage":45},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"35.44kg","Maximum":"45.56kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"261 attack points.","Base Defense":"156 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":92,"Name":"Gastly"},{"Number":93,"Name":"Haunter"}],"MaxCP":1907,"MaxHP":2078},{"Number":"095","Name":"Onix","Generation":"Generation I","About":"Onix has a magnet in its brain. It acts as a compass so that this Pokémon does not lose direction while it is tunneling. As it grows older, its body becomes increasingly rounder and smoother.","Types":["Rock","Ground"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Rock Throw","Type":"Rock","Damage":12},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Iron Head","Type":"Steel","Damage":30},{"Name":"Rock Slide","Type":"Rock","Damage":50},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"183.75kg","Maximum":"236.25kg"},"Height":{"Minimum":"7.7m","Maximum":"9.9m"},"Buddy Distance":"5km (Big)","Base Stamina":"70 stamina points.","Base Attack":"85 attack points.","Base Defense":"288 defense points.","Base Flee Rate":"9% chance to flee.","Next evolution(s)":[{"Number":208,"Name":"Steelix"}],"MaxCP":745,"MaxHP":857},{"Number":"096","Name":"Drowzee","Generation":"Generation I","About":"If your nose becomes itchy while you are sleeping, it's a sure sign that one of these Pokémon is standing above your pillow and trying to eat you dream through your nostrils.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Psybeam","Type":"Psychic","Damage":40},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Psyshock","Type":"Psychic","Damage":40}],"Weight":{"Minimum":"28.35kg","Maximum":"36.45kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"89 attack points.","Base Defense":"158 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Drowzee candies"},"Next evolution(s)":[{"Number":97,"Name":"Hypno"}],"MaxCP":955,"MaxHP":1075},{"Number":"097","Name":"Hypno","Generation":"Generation I","About":"Hypno holds a pendulum in its hand. The arcing movement and glitter of the pendulum lull the foe into a deep state of hypnosis. While this Pokémon searches for prey, it polishes the pendulum.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Psyshock","Type":"Psychic","Damage":40},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"66.15kg","Maximum":"85.05kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"3km (Big)","Base Stamina":"170 stamina points.","Base Attack":"144 attack points.","Base Defense":"215 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":96,"Name":"Drowzee"}],"MaxCP":2012,"MaxHP":2184},{"Number":"098","Name":"Krabby","Generation":"Generation I","About":"Krabby live on beaches, burrowed inside holes dug into the sand. On sandy beaches with little in the way of food, these Pokémon can be seen squabbling with each other over territory.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Vice Grip","Type":"Normal","Damage":25},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"5.69kg","Maximum":"7.31kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"181 attack points.","Base Defense":"156 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Krabby candies"},"Next evolution(s)":[{"Number":99,"Name":"Kingler"}],"MaxCP":686,"MaxHP":792},{"Number":"099","Name":"Kingler","Generation":"Generation I","About":"Kingler has an enormous, oversized claw. It waves this huge claw in the air to communicate with others. However, because the claw is so heavy, the Pokémon quickly tires.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Metal Claw","Type":"Steel","Damage":8},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Vice Grip","Type":"Normal","Damage":25},{"Name":"Water Pulse","Type":"Water","Damage":35},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"52.5kg","Maximum":"67.5kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Big)","Base Stamina":"110 stamina points.","Base Attack":"240 attack points.","Base Defense":"214 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":98,"Name":"Krabby"}],"MaxCP":1663,"MaxHP":1823},{"Number":"100","Name":"Voltorb","Generation":"Generation I","About":"Voltorb was first sighted at a company that manufactures Poké Balls. The link between that sighting and the fact that this Pokémon looks very similar to a Poké Ball remains a mystery.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Signal Beam","Type":"Bug","Damage":45},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"9.1kg","Maximum":"11.7kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"3km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"109 attack points.","Base Defense":"114 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Voltorb candies"},"Next evolution(s)":[{"Number":101,"Name":"Electrode"}],"MaxCP":733,"MaxHP":839},{"Number":"101","Name":"Electrode","Generation":"Generation I","About":"Electrode eats electricity in the atmosphere. On days when lightning strikes, you can see this Pokémon exploding all over the place from eating too much electricity.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"58.27kg","Maximum":"74.92kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"173 attack points.","Base Defense":"179 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":100,"Name":"Voltorb"}],"MaxCP":1496,"MaxHP":1646},{"Number":"102","Name":"Exeggcute","Generation":"Generation I","About":"This Pokémon consists of six eggs that form a closely knit cluster. The six eggs attract each other and spin around. When cracks increasingly appear on the eggs, Exeggcute is close to evolution.","Types":["Grass","Psychic"],"Resistant":["Water","Electric","Grass","Fighting","Ground","Psychic"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Seed Bomb","Type":"Grass","Damage":40}],"Weight":{"Minimum":"2.19kg","Maximum":"2.81kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"107 attack points.","Base Defense":"140 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"E"},"Next evolution(s)":[{"Number":103,"Name":"Exeggutor"}],"MaxCP":978,"MaxHP":1099},{"Number":"103","Name":"Exeggutor","Generation":"Generation I","About":"Exeggutor originally came from the tropics. Its heads steadily grow larger from exposure to strong sunlight. It is said that when the heads fall off, they group together to form Exeggcute.","Types":["Grass","Psychic"],"Resistant":["Water","Electric","Grass","Fighting","Ground","Psychic"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Seed Bomb","Type":"Grass","Damage":40},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"105kg","Maximum":"135kg"},"Height":{"Minimum":"1.75m","Maximum":"2.25m"},"Buddy Distance":"3km (Big)","Base Stamina":"190 stamina points.","Base Attack":"233 attack points.","Base Defense":"158 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":102,"Name":"Exeggcute"}],"MaxCP":2752,"MaxHP":2955},{"Number":"104","Name":"Cubone","Generation":"Generation I","About":"Cubone pines for the mother it will never see again. Seeing a likeness of its mother in the full moon, it cries. The stains on the skull the Pokémon wears are made by the tears it sheds.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Bone Club","Type":"Ground","Damage":25},{"Name":"Bulldoze","Type":"Ground","Damage":35},{"Name":"Dig","Type":"Ground","Damage":70}],"Weight":{"Minimum":"5.69kg","Maximum":"7.31kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"90 attack points.","Base Defense":"165 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Cubone candies"},"Next evolution(s)":[{"Number":105,"Name":"Marowak"}],"MaxCP":889,"MaxHP":1006},{"Number":"105","Name":"Marowak","Generation":"Generation I","About":"Marowak is the evolved form of a Cubone that has overcome its sadness at the loss of its mother and grown tough. This Pokémon's tempered and hardened spirit is not easily broken.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Bone Club","Type":"Ground","Damage":25},{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Earthquake","Type":"Ground","Damage":100}],"Weight":{"Minimum":"39.38kg","Maximum":"50.63kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"144 attack points.","Base Defense":"200 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":104,"Name":"Cubone"}],"MaxCP":1505,"MaxHP":1656},{"Number":"106","Name":"Hitmonlee","Generation":"Generation I","About":"Hitmonlee's legs freely contract and stretch. Using these springlike legs, it bowls over foes with devastating kicks. After battle, it rubs down its legs and loosens the muscles to overcome fatigue.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Low Kick","Type":"Fighting","Damage":5},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Low Sweep","Type":"Fighting","Damage":30},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"43.57kg","Maximum":"56.02kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"5km (Big)","Base Stamina":"100 stamina points.","Base Attack":"224 attack points.","Base Defense":"211 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":236,"Name":"Tyrogue"}],"MaxCP":1349,"MaxHP":1492},{"Number":"107","Name":"Hitmonchan","Generation":"Generation I","About":"Hitmonchan is said to possess the spirit of a boxer who had been working toward a world championship. This Pokémon has an indomitable spirit and will never give up in the face of adversity.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Bullet Punch","Type":"Steel","Damage":10},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Fire Punch","Type":"Fire","Damage":40},{"Name":"Ice Punch","Type":"Ice","Damage":45},{"Name":"Thunder Punch","Type":"Electric","Damage":40}],"Weight":{"Minimum":"43.93kg","Maximum":"56.48kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"5km (Big)","Base Stamina":"100 stamina points.","Base Attack":"193 attack points.","Base Defense":"212 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":236,"Name":"Tyrogue"}],"MaxCP":1370,"MaxHP":1516},{"Number":"108","Name":"Lickitung","Generation":"Generation I","About":"Whenever Lickitung comes across something new, it will unfailingly give it a lick. It does so because it memorizes things by texture and by taste. It is somewhat put off by sour things.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Lick","Type":"Ghost","Damage":5},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Stomp","Type":"Normal","Damage":30}],"Weight":{"Minimum":"57.31kg","Maximum":"73.69kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"108 attack points.","Base Defense":"137 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":1477,"MaxHP":1626},{"Number":"109","Name":"Koffing","Generation":"Generation I","About":"If Koffing becomes agitated, it raises the toxicity of its internal gases and then jets them out from all over its body. This Pokémon may also overinflate its round body, then explode.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Sludge","Type":"Poison","Damage":30},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"0.88kg","Maximum":"1.13kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Big)","Base Stamina":"80 stamina points.","Base Attack":"119 attack points.","Base Defense":"164 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Koffing candies"},"Next evolution(s)":[{"Number":110,"Name":"Weezing"}],"MaxCP":1025,"MaxHP":1151},{"Number":"110","Name":"Weezing","Generation":"Generation I","About":"Weezing loves the gases given off by rotted kitchen garbage. This Pokémon will find a dirty, unkempt house and make it its home. At night, when the people in the house are asleep, it will go through the trash.","Types":["Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Ground","Psychic"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Dark Pulse","Type":"Dark","Damage":45},{"Name":"Shadow Ball","Type":"Ghost","Damage":45},{"Name":"Sludge Bomb","Type":"Poison","Damage":55}],"Weight":{"Minimum":"8.31kg","Maximum":"10.69kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"174 attack points.","Base Defense":"221 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":109,"Name":"Koffing"}],"MaxCP":2073,"MaxHP":2250},{"Number":"111","Name":"Rhyhorn","Generation":"Generation I","About":"Rhyhorn runs in a straight line, smashing everything in its path. It is not bothered even if it rushes headlong into a block of steel. This Pokémon may feel some pain from the collision the next day, however.","Types":["Ground","Rock"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Bulldoze","Type":"Ground","Damage":35},{"Name":"Horn Attack","Type":"Normal","Damage":25},{"Name":"Stomp","Type":"Normal","Damage":30}],"Weight":{"Minimum":"100.63kg","Maximum":"129.38kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"140 attack points.","Base Defense":"157 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Rhyhorn candies"},"Next evolution(s)":[{"Number":112,"Name":"Rhydon"}],"MaxCP":1055,"MaxHP":1182},{"Number":"112","Name":"Rhydon","Generation":"Generation I","About":"Rhydon's horn can crush even uncut diamonds. One sweeping blow of its tail can topple a building. This Pokémon's hide is extremely tough. Even direct cannon hits don't leave a scratch.","Types":["Ground","Rock"],"Resistant":["Normal","Fire","Electric","Poison","Flying","Rock"],"Weaknesses":["Water","Grass","Ice","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Mud Slap","Type":"Ground","Damage":15},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Megahorn","Type":"Bug","Damage":80},{"Name":"Stone Edge","Type":"Rock","Damage":80}],"Weight":{"Minimum":"105kg","Maximum":"135kg"},"Height":{"Minimum":"1.66m","Maximum":"2.14m"},"Buddy Distance":"3km (Big)","Base Stamina":"210 stamina points.","Base Attack":"222 attack points.","Base Defense":"206 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":111,"Name":"Rhyhorn"}],"MaxCP":2068,"MaxHP":2243},{"Number":"113","Name":"Chansey","Generation":"Generation I","About":"Chansey lays nutritionally excellent eggs on an everyday basis. The eggs are so delicious, they are easily and eagerly devoured by even those people who have lost their appetite.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Pound","Type":"Normal","Damage":7},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Psychic","Type":"Psychic","Damage":55}],"Weight":{"Minimum":"30.27kg","Maximum":"38.92kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"5km (Big)","Base Stamina":"500 stamina points.","Base Attack":"60 attack points.","Base Defense":"176 defense points.","Base Flee Rate":"9% chance to flee.","Next evolution(s)":[{"Number":242,"Name":"Blissey"}],"MaxCP":549,"MaxHP":675},{"Number":"114","Name":"Tangela","Generation":"Generation I","About":"Tangela's vines snap off easily if they are grabbed. This happens without pain, allowing it to make a quick getaway. The lost vines are replaced by newly grown vines the very next day.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Power Whip","Type":"Grass","Damage":70},{"Name":"Sludge Bomb","Type":"Poison","Damage":55},{"Name":"Solar Beam","Type":"Grass","Damage":120}],"Weight":{"Minimum":"30.63kg","Maximum":"39.38kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"3km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"183 attack points.","Base Defense":"205 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":1586,"MaxHP":1739},{"Number":"115","Name":"Kangaskhan","Generation":"Generation I","About":"If you come across a young Kangaskhan playing by itself, you must never disturb it or attempt to catch it. The baby Pokémon's parent is sure to be in the area, and it will become violently enraged at you.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Low Kick","Type":"Fighting","Damage":5},{"Name":"Mud Slap","Type":"Ground","Damage":15}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Stomp","Type":"Normal","Damage":30}],"Weight":{"Minimum":"70kg","Maximum":"90kg"},"Height":{"Minimum":"1.93m","Maximum":"2.48m"},"Buddy Distance":"3km (Big)","Base Stamina":"210 stamina points.","Base Attack":"181 attack points.","Base Defense":"165 defense points.","Base Flee Rate":"9% chance to flee.","Common Capture Area":"Early reports that this Pokèmon is likely to be found in: Australia, New Zealand or hatched from an Egg in that geographic area.","Australia, New Zealand":"Common Capture Area","MaxCP":1875,"MaxHP":2043},{"Number":"116","Name":"Horsea","Generation":"Generation I","About":"Horsea eats small insects and moss off of rocks. If the ocean current turns fast, this Pokémon anchors itself by wrapping its tail around rocks or coral to prevent being washed away.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Flash Cannon","Type":"Steel","Damage":60}],"Weight":{"Minimum":"7kg","Maximum":"9kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"3km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"129 attack points.","Base Defense":"125 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Horsea candies"},"Next evolution(s)":[{"Number":117,"Name":"Seadra"},{"Number":230,"Name":"Kingdra"}],"MaxCP":688,"MaxHP":794},{"Number":"117","Name":"Seadra","Generation":"Generation I","About":"Seadra sleeps after wriggling itself between the branches of coral. Those trying to harvest coral are occasionally stung by this Pokémon's poison barbs if they fail to notice it.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Dragon Breath","Type":"Dragon","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Hydro Pump","Type":"Water","Damage":90}],"Weight":{"Minimum":"21.88kg","Maximum":"28.13kg"},"Height":{"Minimum":"1.05m","Maximum":"1.35m"},"Buddy Distance":"3km (Big)","Base Stamina":"110 stamina points.","Base Attack":"187 attack points.","Base Defense":"182 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":116,"Name":"Horsea"}],"Next evolution(s)":[{"Number":230,"Name":"Kingdra"}],"MaxCP":1559,"MaxHP":1713},{"Number":"118","Name":"Goldeen","Generation":"Generation I","About":"Goldeen is a very beautiful Pokémon with fins that billow elegantly in water. However, don't let your guard down around this Pokémon—it could ram you powerfully with its horn.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Mud Shot","Type":"Ground","Damage":6},{"Name":"Peck","Type":"Flying","Damage":10}],"Special Attack(s)":[{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Horn Attack","Type":"Normal","Damage":25},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"13.13kg","Maximum":"16.88kg"},"Height":{"Minimum":"0.53m","Maximum":"0.68m"},"Buddy Distance":"3km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"123 attack points.","Base Defense":"115 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Goldeen candies"},"Next evolution(s)":[{"Number":119,"Name":"Seaking"}],"MaxCP":851,"MaxHP":965},{"Number":"119","Name":"Seaking","Generation":"Generation I","About":"In the autumn, Seaking males can be seen performing courtship dances in riverbeds to woo females. During this season, this Pokémon's body coloration is at its most beautiful.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Poison Jab","Type":"Poison","Damage":12}],"Special Attack(s)":[{"Name":"Drill Run","Type":"Ground","Damage":50},{"Name":"Icy Wind","Type":"Ice","Damage":25},{"Name":"Megahorn","Type":"Bug","Damage":80}],"Weight":{"Minimum":"34.13kg","Maximum":"43.88kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"3km (Big)","Base Stamina":"160 stamina points.","Base Attack":"175 attack points.","Base Defense":"154 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":118,"Name":"Goldeen"}],"MaxCP":1877,"MaxHP":2043},{"Number":"120","Name":"Staryu","Generation":"Generation I","About":"Staryu's center section has an organ called the core that shines bright red. If you go to a beach toward the end of summer, the glowing cores of these Pokémon look like the stars in the sky.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Bubble Beam","Type":"Water","Damage":30},{"Name":"Power Gem","Type":"Rock","Damage":40},{"Name":"Swift","Type":"Normal","Damage":30}],"Weight":{"Minimum":"30.19kg","Maximum":"38.81kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"137 attack points.","Base Defense":"112 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Staryu candies"},"Next evolution(s)":[{"Number":121,"Name":"Starmie"}],"MaxCP":821,"MaxHP":937},{"Number":"121","Name":"Starmie","Generation":"Generation I","About":"Starmie's center section-the core-glows brightly in seven colors. Because of its luminous nature, this Pokémon has been given the nickname the gem of the sea.\"\"","Types":["Water","Psychic"],"Resistant":["Fire","Water","Ice","Fighting","Psychic","Steel"],"Weaknesses":["Electric","Grass","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Power Gem","Type":"Rock","Damage":40},{"Name":"Psychic","Type":"Psychic","Damage":55}],"Weight":{"Minimum":"70kg","Maximum":"90kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"3km (Big)","Base Stamina":"120 stamina points.","Base Attack":"210 attack points.","Base Defense":"184 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":120,"Name":"Staryu"}],"MaxCP":2007,"MaxHP":2182},{"Number":"122","Name":"Mr Mime","Generation":"Generation I","About":"Mr. Mime is a master of pantomime. Its gestures and motions convince watchers that something unseeable actually exists. Once the watchers are convinced, the unseeable thing exists as if it were real.","Types":["Psychic","Fairy"],"Resistant":["Fighting","Psychic","Dragon"],"Weaknesses":["Poison","Ghost","Steel"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Psybeam","Type":"Psychic","Damage":40},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"47.69kg","Maximum":"61.31kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"5km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"192 attack points.","Base Defense":"233 defense points.","Base Flee Rate":"9% chance to flee.","Common Capture Area":"Early reports that this Pokèmon is likely to be found in: Western Europe or hatched from an Egg in that geographic area.","Western Europe":"Common Capture Area","MaxCP":1345,"MaxHP":1494},{"Number":"123","Name":"Scyther","Generation":"Generation I","About":"Scyther is blindingly fast. Its blazing speed enhances the effectiveness of the twin scythes on its forearms. This Pokémon's scythes are so effective, they can slice through thick logs in one wicked stroke.","Types":["Bug","Flying"],"Resistant":["Grass","Fighting","Ground","Bug"],"Weaknesses":["Fire","Electric","Ice","Flying","Rock"],"Fast Attack(s)":[{"Name":"Fury Cutter","Type":"Bug","Damage":3},{"Name":"Steel Wing","Type":"Steel","Damage":15}],"Special Attack(s)":[{"Name":"Bug Buzz","Type":"Bug","Damage":75},{"Name":"Night Slash","Type":"Dark","Damage":30},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"49kg","Maximum":"63kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"5km (Big)","Base Stamina":"140 stamina points.","Base Attack":"218 attack points.","Base Defense":"170 defense points.","Base Flee Rate":"9% chance to flee.","Next evolution(s)":[{"Number":212,"Name":"Scizor"}],"MaxCP":1905,"MaxHP":2073},{"Number":"124","Name":"Jynx","Generation":"Generation I","About":"Jynx walks rhythmically, swaying and shaking its hips as if it were dancing. Its motions are so bouncingly alluring, people seeing it are compelled to shake their hips without giving any thought to what they are doing.","Types":["Ice","Psychic"],"Resistant":["Ice","Psychic"],"Weaknesses":["Fire","Bug","Rock","Ghost","Dark","Steel"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Draining Kiss","Type":"Fairy","Damage":25},{"Name":"Ice Punch","Type":"Ice","Damage":45},{"Name":"Psyshock","Type":"Psychic","Damage":40}],"Weight":{"Minimum":"35.52kg","Maximum":"45.67kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"5km (Big)","Base Stamina":"130 stamina points.","Base Attack":"223 attack points.","Base Defense":"182 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":238,"Name":"Smoochum"}],"MaxCP":1563,"MaxHP":1716},{"Number":"125","Name":"Electabuzz","Generation":"Generation I","About":"When a storm arrives, gangs of this Pokémon compete with each other to scale heights that are likely to be stricken by lightning bolts. Some towns use Electabuzz in place of lightning rods.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Low Kick","Type":"Fighting","Damage":5},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Thunder","Type":"Electric","Damage":100},{"Name":"Thunder Punch","Type":"Electric","Damage":40},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"26.25kg","Maximum":"33.75kg"},"Height":{"Minimum":"0.96m","Maximum":"1.24m"},"Buddy Distance":"5km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"198 attack points.","Base Defense":"173 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":239,"Name":"Elekid"}],"MaxCP":1947,"MaxHP":2119},{"Number":"126","Name":"Magmar","Generation":"Generation I","About":"In battle, Magmar blows out intensely hot flames from all over its body to intimidate its opponent. This Pokémon's fiery bursts create heat waves that ignite grass and trees in its surroundings.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Karate Chop","Type":"Fighting","Damage":6}],"Special Attack(s)":[{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Fire Punch","Type":"Fire","Damage":40},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"38.94kg","Maximum":"50.06kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"5km (Big)","Base Stamina":"130 stamina points.","Base Attack":"206 attack points.","Base Defense":"169 defense points.","Base Flee Rate":"9% chance to flee.","Previous evolution(s)":[{"Number":240,"Name":"Magby"}],"MaxCP":2086,"MaxHP":2265},{"Number":"127","Name":"Pinsir","Generation":"Generation I","About":"Pinsir is astoundingly strong. It can grip a foe weighing twice its weight in its horns and easily lift it. This Pokémon's movements turn sluggish in cold places.","Types":["Bug"],"Resistant":["Grass","Fighting","Ground"],"Weaknesses":["Fire","Flying","Rock"],"Fast Attack(s)":[{"Name":"Fury Cutter","Type":"Bug","Damage":3},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Submission","Type":"Fighting","Damage":30},{"Name":"Vice Grip","Type":"Normal","Damage":25},{"Name":"X Scissor","Type":"Bug","Damage":35}],"Weight":{"Minimum":"48.13kg","Maximum":"61.88kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"5km (Big)","Base Stamina":"130 stamina points.","Base Attack":"238 attack points.","Base Defense":"197 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":1950,"MaxHP":2121},{"Number":"128","Name":"Tauros","Generation":"Generation I","About":"This Pokémon is not satisfied unless it is rampaging at all times. If there is no opponent for Tauros to battle, it will charge at thick trees and knock them down to calm itself.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Horn Attack","Type":"Normal","Damage":25},{"Name":"Iron Head","Type":"Steel","Damage":30}],"Weight":{"Minimum":"77.35kg","Maximum":"99.45kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"3km (Big)","Base Stamina":"150 stamina points.","Base Attack":"198 attack points.","Base Defense":"197 defense points.","Base Flee Rate":"9% chance to flee.","Common Capture Area":"Early reports that this Pokèmon is likely to be found in: North America or hatched from an Egg in that geographic area.","North America":"Common Capture Area","MaxCP":1686,"MaxHP":1844},{"Number":"129","Name":"Magikarp","Generation":"Generation I","About":"Magikarp is a pathetic excuse for a Pokémon that is only capable of flopping and splashing. This behavior prompted scientists to undertake research into it.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Splash","Type":"Water","Damage":0}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"8.75kg","Maximum":"11.25kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"1km (Medium)","Base Stamina":"40 stamina points.","Base Attack":"29 attack points.","Base Defense":"102 defense points.","Base Flee Rate":"15% chance to flee.","Next Evolution Requirements":{"Amount":400,"Name":"Magikarp candies"},"Next evolution(s)":[{"Number":130,"Name":"Gyarados"}],"MaxCP":203,"MaxHP":262},{"Number":"130","Name":"Gyarados","Generation":"Generation I","About":"When Magikarp evolves into Gyarados, its brain cells undergo a structural transformation. It is said that this transformation is to blame for this Pokémon's wildly violent nature.","Types":["Water","Flying"],"Resistant":["Fire","Water","Fighting","Ground","Bug","Steel"],"Weaknesses":["Electric","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6}],"Special Attack(s)":[{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Twister","Type":"Dragon","Damage":25}],"Weight":{"Minimum":"205.63kg","Maximum":"264.38kg"},"Height":{"Minimum":"5.69m","Maximum":"7.31m"},"Buddy Distance":"1km (Big)","Base Stamina":"190 stamina points.","Base Attack":"237 attack points.","Base Defense":"197 defense points.","Base Flee Rate":"7% chance to flee.","Previous evolution(s)":[{"Number":129,"Name":"Magikarp"}],"MaxCP":2498,"MaxHP":2688},{"Number":"131","Name":"Lapras","Generation":"Generation I","About":"People have driven Lapras almost to the point of extinction. In the evenings, this Pokémon is said to sing plaintively as it seeks what few others of its kind still remain.","Types":["Water","Ice"],"Resistant":["Water","Ice"],"Weaknesses":["Electric","Grass","Fighting","Rock"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9},{"Name":"Ice Shard","Type":"Ice","Damage":15}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Ice Beam","Type":"Ice","Damage":65}],"Weight":{"Minimum":"192.5kg","Maximum":"247.5kg"},"Height":{"Minimum":"2.19m","Maximum":"2.81m"},"Buddy Distance":"5km (Big)","Base Stamina":"260 stamina points.","Base Attack":"186 attack points.","Base Defense":"190 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":2777,"MaxHP":2980},{"Number":"132","Name":"Ditto","Generation":"Generation I","About":"Ditto rearranges its cell structure to transform itself into other shapes. However, if it tries to transform itself into something by relying on its memory, this Pokémon manages to get details wrong.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Transform","Type":"Normal","Damage":0}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"3.5kg","Maximum":"4.5kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"3km (Medium)","Base Stamina":"96 stamina points.","Base Attack":"91 attack points.","Base Defense":"91 defense points.","Base Flee Rate":"10% chance to flee.","MaxCP":809,"MaxHP":919},{"Number":"133","Name":"Eevee","Generation":"Generation I","About":"Eevee has an unstable genetic makeup that suddenly mutates due to the environment in which it lives. Radiation from various stones causes this Pokémon to evolve.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Dig","Type":"Ground","Damage":70},{"Name":"Swift","Type":"Normal","Damage":30}],"Weight":{"Minimum":"5.69kg","Maximum":"7.31kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"5km (Shoulder)","Base Stamina":"110 stamina points.","Base Attack":"104 attack points.","Base Defense":"121 defense points.","Base Flee Rate":"10% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Eevee candies"},"Next evolution(s)":[{"Number":134,"Name":"Vaporeon"},{"Number":135,"Name":"Jolteon"},{"Number":136,"Name":"Flareon"},{"Number":196,"Name":"Espeon"},{"Number":197,"Name":"Umbreon"}],"MaxCP":957,"MaxHP":1077},{"Number":"134","Name":"Vaporeon","Generation":"Generation I","About":"Vaporeon underwent a spontaneous mutation and grew fins and gills that allow it to live underwater. This Pokémon has the ability to freely control water.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Hydro Pump","Type":"Water","Damage":90},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"25.38kg","Maximum":"32.63kg"},"Height":{"Minimum":"0.88m","Maximum":"1.13m"},"Buddy Distance":"5km (Medium)","Base Stamina":"260 stamina points.","Base Attack":"205 attack points.","Base Defense":"177 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":133,"Name":"Eevee"}],"MaxCP":2618,"MaxHP":2816},{"Number":"135","Name":"Jolteon","Generation":"Generation I","About":"Jolteon's cells generate a low level of electricity. This power is amplified by the static electricity of its fur, enabling the Pokémon to drop thunderbolts. The bristling fur is made of electrically charged needles.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Thunder","Type":"Electric","Damage":100},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"21.44kg","Maximum":"27.56kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"5km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"232 attack points.","Base Defense":"201 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":133,"Name":"Eevee"}],"MaxCP":1968,"MaxHP":2140},{"Number":"136","Name":"Flareon","Generation":"Generation I","About":"Flareon's fluffy fur has a functional purpose-it releases heat into the air so that its body does not get excessively hot. This Pokémon's body temperature can rise to a maximum of 1,650 degrees Fahrenheit.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10}],"Special Attack(s)":[{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flamethrower","Type":"Fire","Damage":55},{"Name":"Heat Wave","Type":"Fire","Damage":80}],"Weight":{"Minimum":"21.88kg","Maximum":"28.13kg"},"Height":{"Minimum":"0.79m","Maximum":"1.01m"},"Buddy Distance":"5km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"246 attack points.","Base Defense":"204 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":133,"Name":"Eevee"}],"MaxCP":2448,"MaxHP":2643},{"Number":"137","Name":"Porygon","Generation":"Generation I","About":"Porygon is capable of reverting itself entirely back to program data and entering cyberspace. This Pokémon is copy-protected so it cannot be duplicated by copying.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Psybeam","Type":"Psychic","Damage":40},{"Name":"Signal Beam","Type":"Bug","Damage":45}],"Weight":{"Minimum":"31.94kg","Maximum":"41.06kg"},"Height":{"Minimum":"0.7m","Maximum":"0.9m"},"Buddy Distance":"3km (Big)","Base Stamina":"130 stamina points.","Base Attack":"153 attack points.","Base Defense":"139 defense points.","Base Flee Rate":"9% chance to flee.","Next evolution(s)":[{"Number":233,"Name":"Porygon2"}],"MaxCP":1540,"MaxHP":1691},{"Number":"138","Name":"Omanyte","Generation":"Generation I","About":"Omanyte is one of the ancient and long-since-extinct Pokémon that have been regenerated from fossils by people. If attacked by an enemy, it withdraws itself inside its hard shell.","Types":["Rock","Water"],"Resistant":["Normal","Fire","Ice","Poison","Flying"],"Weaknesses":["Electric","Grass","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Mud Shot","Type":"Ground","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Brine","Type":"Water","Damage":25},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"6.56kg","Maximum":"8.44kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"5km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"155 attack points.","Base Defense":"174 defense points.","Base Flee Rate":"9% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Omanyte candies"},"Next evolution(s)":[{"Number":139,"Name":"Omastar"}],"MaxCP":992,"MaxHP":1119},{},{"Number":"140","Name":"Kabuto","Generation":"Generation I","About":"Kabuto is a Pokémon that has been regenerated from a fossil. However, in extremely rare cases, living examples have been discovered. The Pokémon has not changed at all for 300 million years.","Types":["Rock","Water"],"Resistant":["Normal","Fire","Ice","Poison","Flying"],"Weaknesses":["Electric","Grass","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Mud Shot","Type":"Ground","Damage":6},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Aqua Jet","Type":"Water","Damage":25},{"Name":"Rock Tomb","Type":"Rock","Damage":30}],"Weight":{"Minimum":"10.06kg","Maximum":"12.94kg"},"Height":{"Minimum":"0.44m","Maximum":"0.56m"},"Buddy Distance":"5km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"148 attack points.","Base Defense":"162 defense points.","Base Flee Rate":"9% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Kabuto candies"},"Next evolution(s)":[{"Number":141,"Name":"Kabutops"}],"MaxCP":975,"MaxHP":1104},{"Number":"141","Name":"Kabutops","Generation":"Generation I","About":"Kabutops swam underwater to hunt for its prey in ancient times. The Pokémon was apparently evolving from being a water-dweller to living on land as evident from the beginnings of change in its gills and legs.","Types":["Rock","Water"],"Resistant":["Normal","Fire","Ice","Poison","Flying"],"Weaknesses":["Electric","Grass","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Fury Cutter","Type":"Bug","Damage":3},{"Name":"Mud Shot","Type":"Ground","Damage":6}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Stone Edge","Type":"Rock","Damage":80},{"Name":"Water Pulse","Type":"Water","Damage":35}],"Weight":{"Minimum":"35.44kg","Maximum":"45.56kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"5km (Big)","Base Stamina":"120 stamina points.","Base Attack":"220 attack points.","Base Defense":"203 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":140,"Name":"Kabuto"}],"MaxCP":1957,"MaxHP":2130},{"Number":"142","Name":"Aerodactyl","Generation":"Generation I","About":"Aerodactyl is a Pokémon from the age of dinosaurs. It was regenerated from genetic material extracted from amber. It is imagined to have been the king of the skies in ancient times.","Types":["Rock","Flying"],"Resistant":["Normal","Fire","Poison","Flying","Bug"],"Weaknesses":["Water","Electric","Ice","Rock","Steel"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Steel Wing","Type":"Steel","Damage":15}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Iron Head","Type":"Steel","Damage":30}],"Weight":{"Minimum":"51.63kg","Maximum":"66.38kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"5km (Big)","Base Stamina":"160 stamina points.","Base Attack":"221 attack points.","Base Defense":"164 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":1994,"MaxHP":2165},{"Number":"143","Name":"Snorlax","Generation":"Generation I","About":"Snorlax's typical day consists of nothing more than eating and sleeping. It is such a docile Pokémon that there are children who use its expansive belly as a place to play.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Lick","Type":"Ghost","Damage":5},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Hyper Beam","Type":"Normal","Damage":120}],"Weight":{"Minimum":"402.5kg","Maximum":"517.5kg"},"Height":{"Minimum":"1.84m","Maximum":"2.36m"},"Buddy Distance":"5km (Big)","Base Stamina":"320 stamina points.","Base Attack":"190 attack points.","Base Defense":"190 defense points.","Base Flee Rate":"9% chance to flee.","MaxCP":2901,"MaxHP":3112},{"Number":"144","Name":"Articuno","Generation":"Generation I","About":"Articuno is a legendary bird Pokémon that can control ice. The flapping of its wings chills the air. As a result, it is said that when this Pokémon flies, snow will fall.","Types":["Ice","Flying"],"Resistant":["Grass","Ground","Bug"],"Weaknesses":["Fire","Electric","Rock","Steel"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Ice Beam","Type":"Ice","Damage":65},{"Name":"Icy Wind","Type":"Ice","Damage":25}],"Weight":{"Minimum":"48.48kg","Maximum":"62.33kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"5km (Flying)","Base Stamina":"180 stamina points.","Base Attack":"192 attack points.","Base Defense":"249 defense points.","Base Flee Rate":"10% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class","MaxCP":2776,"MaxHP":2978},{"Number":"145","Name":"Zapdos","Generation":"Generation I","About":"Zapdos is a legendary bird Pokémon that has the ability to control electricity. It usually lives in thunderclouds. The Pokémon gains power if it is stricken by lightning bolts.","Types":["Electric","Flying"],"Resistant":["Grass","Fighting","Flying","Bug","Steel"],"Weaknesses":["Ice","Rock"],"Fast Attack(s)":[{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Thunder","Type":"Electric","Damage":100},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"46.02kg","Maximum":"59.17kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"5km (Flying)","Base Stamina":"180 stamina points.","Base Attack":"253 attack points.","Base Defense":"188 defense points.","Base Flee Rate":"10% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class","MaxCP":2907,"MaxHP":3114},{"Number":"146","Name":"Moltres","Generation":"Generation I","About":"Moltres is a legendary bird Pokémon that has the ability to control fire. If this Pokémon is injured, it is said to dip its body in the molten magma of a volcano to burn and heal itself.","Types":["Fire","Flying"],"Resistant":["Fire","Grass","Fighting","Bug","Steel","Fairy"],"Weaknesses":["Water","Electric","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10}],"Special Attack(s)":[{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Flamethrower","Type":"Fire","Damage":55},{"Name":"Heat Wave","Type":"Fire","Damage":80}],"Weight":{"Minimum":"52.5kg","Maximum":"67.5kg"},"Height":{"Minimum":"1.75m","Maximum":"2.25m"},"Buddy Distance":"5km (Big)","Base Stamina":"180 stamina points.","Base Attack":"251 attack points.","Base Defense":"184 defense points.","Base Flee Rate":"10% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class","MaxCP":3028,"MaxHP":3240},{"Number":"147","Name":"Dratini","Generation":"Generation I","About":"Dratini continually molts and sloughs off its old skin. It does so because the life energy within its body steadily builds to reach uncontrollable levels.","Types":["Dragon"],"Resistant":["Fire","Water","Electric","Grass"],"Weaknesses":["Ice","Dragon","Fairy"],"Fast Attack(s)":[{"Name":"Dragon Breath","Type":"Dragon","Damage":6}],"Special Attack(s)":[{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Twister","Type":"Dragon","Damage":25},{"Name":"Wrap","Type":"Normal","Damage":25}],"Weight":{"Minimum":"2.89kg","Maximum":"3.71kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"5km (Medium)","Base Stamina":"82 stamina points.","Base Attack":"119 attack points.","Base Defense":"94 defense points.","Base Flee Rate":"9% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Dratini candies"},"Next evolution(s)":[{"Number":148,"Name":"Dragonair"},{"Number":149,"Name":"Dragonite"}],"MaxCP":867,"MaxHP":983},{"Number":"148","Name":"Dragonair","Generation":"Generation I","About":"Dragonair stores an enormous amount of energy inside its body. It is said to alter weather conditions in its vicinity by discharging energy from its crystals on its neck and tail.","Types":["Dragon"],"Resistant":["Fire","Water","Electric","Grass"],"Weaknesses":["Ice","Dragon","Fairy"],"Fast Attack(s)":[{"Name":"Dragon Breath","Type":"Dragon","Damage":6}],"Special Attack(s)":[{"Name":"Aqua Tail","Type":"Water","Damage":45},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Wrap","Type":"Normal","Damage":25}],"Weight":{"Minimum":"14.44kg","Maximum":"18.56kg"},"Height":{"Minimum":"3.5m","Maximum":"4.5m"},"Buddy Distance":"5km (Big)","Base Stamina":"122 stamina points.","Base Attack":"163 attack points.","Base Defense":"138 defense points.","Base Flee Rate":"6% chance to flee.","Previous evolution(s)":[{"Number":147,"Name":"Dratini"}],"Next Evolution Requirements":{"Amount":100,"Name":"Dratini candies"},"Next evolution(s)":[{"Number":149,"Name":"Dragonite"}],"MaxCP":1593,"MaxHP":1747},{"Number":"149","Name":"Dragonite","Generation":"Generation I","About":"Dragonite is capable of circling the globe in just 16 hours. It is a kindhearted Pokémon that leads lost and foundering ships in a storm to the safety of land.","Types":["Dragon","Flying"],"Resistant":["Fire","Water","Grass","Fighting","Ground","Bug"],"Weaknesses":["Ice","Rock","Dragon","Fairy"],"Fast Attack(s)":[{"Name":"Dragon Breath","Type":"Dragon","Damage":6},{"Name":"Steel Wing","Type":"Steel","Damage":15}],"Special Attack(s)":[{"Name":"Dragon Claw","Type":"Dragon","Damage":35},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Hyper Beam","Type":"Normal","Damage":120}],"Weight":{"Minimum":"183.75kg","Maximum":"236.25kg"},"Height":{"Minimum":"1.93m","Maximum":"2.48m"},"Buddy Distance":"5km (Big)","Base Stamina":"182 stamina points.","Base Attack":"263 attack points.","Base Defense":"201 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":147,"Name":"Dratini"},{"Number":148,"Name":"Dragonair"}],"MaxCP":3280,"MaxHP":3500},{"Number":"150","Name":"Mewtwo","Generation":"Generation I","About":"Mewtwo is a Pokémon that was created by genetic manipulation. However, even though the scientific power of humans created this Pokémon's body, they failed to endow Mewtwo with a compassionate heart","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Psycho Cut","Type":"Psychic","Damage":7}],"Special Attack(s)":[{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"106.75kg","Maximum":"137.25kg"},"Height":{"Minimum":"1.75m","Maximum":"2.25m"},"Buddy Distance":"5km (Big)","Base Stamina":"212 stamina points.","Base Attack":"330 attack points.","Base Defense":"200 defense points.","Base Flee Rate":"10% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class","MaxCP":3904,"MaxHP":4144},{"Number":"151","Name":"Mew","Generation":"Generation I","About":"Mew is said to possess the genetic composition of all Pokémon. It is capable of making itself invisible at will, so it entirely avoids notice even if it approaches people.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Blizzard","Type":"Ice","Damage":100},{"Name":"Dragon Pulse","Type":"Dragon","Damage":65},{"Name":"Earthquake","Type":"Ground","Damage":100},{"Name":"Fire Blast","Type":"Fire","Damage":100},{"Name":"Hyper Beam","Type":"Normal","Damage":120},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Solar Beam","Type":"Grass","Damage":120},{"Name":"Thunder","Type":"Electric","Damage":100}],"Weight":{"Minimum":"3.5kg","Maximum":"4.5kg"},"Height":{"Minimum":"0.35m","Maximum":"0.45m"},"Buddy Distance":"5km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"210 attack points.","Base Defense":"210 defense points.","Base Flee Rate":"10% chance to flee.","Pokèmon Class":"This is a MYTHIC Pokèmon.","MYTHIC":"Pokèmon Class","MaxCP":3087,"MaxHP":3299},{"Number":"152","Name":"Chikorita","Generation":"Generation II","About":"In battle, Chikorita waves its leaf around to keep the foe at bay. However, a sweet fragrance also wafts from the leaf, becalming the battling Pokémon and creating a cozy, friendly atmosphere all around.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Razor Leaf","Type":"Grass","Damage":15},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"5.6kg","Maximum":"7.2kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"1km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"92 attack points.","Base Defense":"122 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Chikorita candies"},"Next evolution(s)":[{"Number":153,"Name":"Bayleef"},{"Number":154,"Name":"Meganium"}]},{"Number":"153","Name":"Bayleef","Generation":"Generation II","About":"Bayleef's neck is ringed by curled-up leaves. Inside each tubular leaf is a small shoot of a tree. The fragrance of this shoot makes people peppy.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Razor Leaf","Type":"Grass","Damage":15},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"13.83kg","Maximum":"17.78kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"122 attack points.","Base Defense":"155 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":152,"Name":"Chikorita"}],"Next Evolution Requirements":{"Amount":100,"Name":"Chikorita candies"},"Next evolution(s)":[{"Number":154,"Name":"Meganium"}]},{"Number":"154","Name":"Meganium","Generation":"Generation II","About":"The fragrance of Meganium's flower soothes and calms emotions. In battle, this Pokémon gives off more of its becalming scent to blunt the foe's fighting spirit.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Razor Leaf","Type":"Grass","Damage":15},{"Name":"Vine Whip","Type":"Grass","Damage":7}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"87.94kg","Maximum":"113.06kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"1km (Medium)","Base Stamina":"160 stamina points.","Base Attack":"168 attack points.","Base Defense":"202 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":152,"Name":"Chikorita"},{"Number":153,"Name":"Bayleef"}]},{"Number":"155","Name":"Cyndaquil","Generation":"Generation II","About":"Cyndaquil protects itself by flaring up the flames on its back. The flames are vigorous if the Pokémon is angry. However, if it is tired, the flames splutter fitfully with incomplete combustion.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"6.91kg","Maximum":"8.89kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"78 stamina points.","Base Attack":"116 attack points.","Base Defense":"96 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":156,"Name":"Quilava"},{"Number":157,"Name":"Typhlosion"}]},{"Number":"156","Name":"Quilava","Generation":"Generation II","About":"Quilava keeps its foes at bay with the intensity of its flames and gusts of superheated air. This Pokémon applies its outstanding nimbleness to dodge attacks even while scorching the foe with flames.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"16.63kg","Maximum":"21.38kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"1km (Medium)","Base Stamina":"116 stamina points.","Base Attack":"158 attack points.","Base Defense":"129 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":155,"Name":"Cyndaquil"}],"Next evolution(s)":[{"Number":157,"Name":"Typhlosion"}]},{"Number":"157","Name":"Typhlosion","Generation":"Generation II","About":"Typhlosion obscures itself behind a shimmering heat haze that it creates using its intensely hot flames. This Pokémon creates blazing explosive blasts that burn everything to cinders.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Shadow Claw","Type":"Ghost","Damage":11}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"69.56kg","Maximum":"89.44kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"1km (Medium)","Base Stamina":"156 stamina points.","Base Attack":"223 attack points.","Base Defense":"176 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":155,"Name":"Cyndaquil"},{"Number":156,"Name":"Quilava"}]},{"Number":"158","Name":"Totodile","Generation":"Generation II","About":"Despite the smallness of its body, Totodile's jaws are very powerful. While the Pokémon may think it is just playfully nipping, its bite has enough power to cause serious injury.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Scratch","Type":"Normal","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"8.31kg","Maximum":"10.69kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"117 attack points.","Base Defense":"116 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":159,"Name":"Croconaw"},{"Number":160,"Name":"Feraligatr"}]},{"Number":"159","Name":"Croconaw","Generation":"Generation II","About":"Once Croconaw has clamped its jaws on its foe, it will absolutely not let go. Because the tips of its fangs are forked back like barbed fishhooks, they become impossible to remove when they have sunk in.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Scratch","Type":"Normal","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"21.88kg","Maximum":"28.13kg"},"Height":{"Minimum":"0.95m","Maximum":"1.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"150 attack points.","Base Defense":"151 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":158,"Name":"Totodile"}],"Next evolution(s)":[{"Number":160,"Name":"Feraligatr"}]},{"Number":"160","Name":"Feraligatr","Generation":"Generation II","About":"Feraligatr intimidates its foes by opening its huge mouth. In battle, it will kick the ground hard with its thick and powerful hind legs to charge at the foe at an incredible speed.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"77.7kg","Maximum":"99.9kg"},"Height":{"Minimum":"2.02m","Maximum":"2.6m"},"Buddy Distance":"1km (Medium)","Base Stamina":"170 stamina points.","Base Attack":"205 attack points.","Base Defense":"197 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":158,"Name":"Totodile"},{"Number":159,"Name":"Croconaw"}]},{"Number":"161","Name":"Sentret","Generation":"Generation II","About":"When Sentret sleeps, it does so while another stands guard. The sentry wakes the others at the first sign of danger. When this Pokémon becomes separated from its pack, it becomes incapable of sleep due to fear.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Scratch","Type":"Normal","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"5.25kg","Maximum":"6.75kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"79 attack points.","Base Defense":"77 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":162,"Name":"Furret"}]},{"Number":"162","Name":"Furret","Generation":"Generation II","About":"Furret has a very slim build. When under attack, it can slickly squirm through narrow spaces and get away. In spite of its short limbs, this Pokémon is very nimble and fleet.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Sucker Punch","Type":"Dark","Damage":7}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"28.44kg","Maximum":"36.56kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"1km (Medium)","Base Stamina":"170 stamina points.","Base Attack":"148 attack points.","Base Defense":"130 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":161,"Name":"Sentret"}]},{"Number":"163","Name":"Hoothoot","Generation":"Generation II","About":"Hoothoot has an internal organ that senses and tracks the earth's rotation. Using this special organ, this Pokémon begins hooting at precisely the same time every day.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"18.55kg","Maximum":"23.85kg"},"Height":{"Minimum":"0.62m","Maximum":"0.8m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"67 attack points.","Base Defense":"101 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":164,"Name":"Noctowl"}]},{"Number":"164","Name":"Noctowl","Generation":"Generation II","About":"Noctowl never fails at catching prey in darkness. This Pokémon owes its success to its superior vision that allows it to see in minimal light, and to its soft, supple wings that make no sound in flight.","Types":["Normal","Flying"],"Resistant":["Grass","Ground","Bug","Ghost"],"Weaknesses":["Electric","Ice","Rock"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"35.7kg","Maximum":"45.9kg"},"Height":{"Minimum":"1.4m","Maximum":"1.8m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"145 attack points.","Base Defense":"179 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":163,"Name":"Hoothoot"}]},{"Number":"165","Name":"Ledyba","Generation":"Generation II","About":"Ledyba secretes an aromatic fluid from where its legs join its body. This fluid is used for communicating with others. This Pokémon conveys its feelings to others by altering the fluid's scent.","Types":["Bug","Flying"],"Resistant":["Grass","Fighting","Ground","Bug"],"Weaknesses":["Fire","Electric","Ice","Flying","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"9.45kg","Maximum":"12.15kg"},"Height":{"Minimum":"0.87m","Maximum":"1.11m"},"Buddy Distance":"1km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"72 attack points.","Base Defense":"142 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":166,"Name":"Ledian"}]},{"Number":"166","Name":"Ledian","Generation":"Generation II","About":"It is said that in lands with clean air, where the stars fill the sky, there live Ledian in countless numbers. There is a good reason for this—the Pokémon uses the light of the stars as its energy.","Types":["Bug","Flying"],"Resistant":["Grass","Fighting","Ground","Bug"],"Weaknesses":["Fire","Electric","Ice","Flying","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"31.15kg","Maximum":"40.05kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"107 attack points.","Base Defense":"209 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":165,"Name":"Ledyba"}]},{"Number":"167","Name":"Spinarak","Generation":"Generation II","About":"The web spun by Spinarak can be considered its second nervous system. It is said that this Pokémon can determine what kind of prey is touching its web just by the tiny vibrations it feels through the web's strands.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"7.44kg","Maximum":"9.56kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"105 attack points.","Base Defense":"73 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":168,"Name":"Ariados"}]},{"Number":"168","Name":"Ariados","Generation":"Generation II","About":"Ariados's feet are tipped with tiny hooked claws that enable it to scuttle on ceilings and vertical walls. This Pokémon constricts the foe with thin and strong silk webbing.","Types":["Bug","Poison"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Fire","Flying","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bug Bite","Type":"Bug","Damage":5},{"Name":"Poison Sting","Type":"Poison","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"29.31kg","Maximum":"37.69kg"},"Height":{"Minimum":"0.95m","Maximum":"1.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"161 attack points.","Base Defense":"128 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":167,"Name":"Spinarak"}]},{"Number":"169","Name":"Crobat","Generation":"Generation II","About":"If this Pokémon is flying by fluttering only a pair of wings on either the forelegs or hind legs, it's proof that Crobat has been flying a long distance. It switches the wings it uses if it is tired.","Types":["Poison","Flying"],"Resistant":["Grass","Fighting","Poison","Bug","Fairy"],"Weaknesses":["Electric","Ice","Psychic","Rock"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Wing Attack","Type":"Flying","Damage":9}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"65.63kg","Maximum":"84.38kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"1km (Medium)","Base Stamina":"170 stamina points.","Base Attack":"194 attack points.","Base Defense":"178 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":41,"Name":"Zubat"},{"Number":42,"Name":"Golbat"}]},{"Number":"170","Name":"Chinchou","Generation":"Generation II","About":"Chinchou lets loose positive and negative electrical charges from its two antennas to make its prey faint. This Pokémon flashes its electric lights to exchange signals with others.","Types":["Water","Electric"],"Resistant":["Fire","Water","Ice","Flying","Steel"],"Weaknesses":["Grass","Ground"],"Fast Attack(s)":[{"Name":"Bubble","Type":"Water","Damage":25},{"Name":"Spark","Type":"Electric","Damage":7}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"10.5kg","Maximum":"13.5kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"106 attack points.","Base Defense":"106 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":171,"Name":"Lanturn"}]},{"Number":"171","Name":"Lanturn","Generation":"Generation II","About":"Lanturn is nicknamed “the deep-sea star for its illuminated antenna. This Pokémon produces light by causing a chemical reaction between bacteria and its bodily fluids inside the antenna.\"","Types":["Water","Electric"],"Resistant":["Fire","Water","Ice","Flying","Steel"],"Weaknesses":["Grass","Ground"],"Fast Attack(s)":[{"Name":"Spark","Type":"Electric","Damage":7},{"Name":"Water Gun","Type":"Water","Damage":6}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"19.69kg","Maximum":"25.31kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"250 stamina points.","Base Attack":"146 attack points.","Base Defense":"146 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":170,"Name":"Chinchou"}]},{"Number":"172","Name":"Pichu","Generation":"Generation II","About":"Pichu charges itself with electricity more easily on days with thunderclouds or when the air is very dry. You can hear the crackling of static electricity coming off this Pokémon.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Quick Attack","Type":"Normal","Damage":10},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Disarming Voice","Type":"Fairy","Damage":25},{"Name":"Thunder Punch","Type":"Electric","Damage":40},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"1.75kg","Maximum":"2.25kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"40 stamina points.","Base Attack":"77 attack points.","Base Defense":"63 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Pikachu candies"},"Next evolution(s)":[{"Number":25,"Name":"Pikachu"},{"Number":26,"Name":"Raichu"}]},{"Number":"173","Name":"Cleffa","Generation":"Generation II","About":"On nights with many shooting stars, Cleffa can be seen dancing in a ring. They dance through the night and stop only at the break of day, when these Pokémon quench their thirst with the morning dew.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Pound","Type":"Normal","Damage":7},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Signal Beam","Type":"Bug","Damage":45}],"Weight":{"Minimum":"2.63kg","Maximum":"3.38kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"75 attack points.","Base Defense":"91 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Clefairy candies"},"Next evolution(s)":[{"Number":35,"Name":"Clefairy"},{"Number":36,"Name":"Clefable"}]},{"Number":"174","Name":"Igglybuff","Generation":"Generation II","About":"Igglybuff's vocal cords are not sufficiently developed. It would hurt its throat if it were to sing too much. This Pokémon gargles with freshwater from a clean stream.","Types":["Normal","Fairy"],"Resistant":["Bug","Ghost","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Feint Attack","Type":"Dark","Damage":12},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Psychic","Type":"Psychic","Damage":55},{"Name":"Shadow Ball","Type":"Ghost","Damage":45}],"Weight":{"Minimum":"0.88kg","Maximum":"1.13kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"69 attack points.","Base Defense":"34 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Jigglypuff candies"},"Next evolution(s)":[{"Number":39,"Name":"Jigglypuff"},{"Number":40,"Name":"Wigglytuff"}]},{"Number":"175","Name":"Togepi","Generation":"Generation II","About":"As its energy, Togepi uses the positive emotions of compassion and pleasure exuded by people and Pokémon. This Pokémon stores up feelings of happiness inside its shell, then shares them with others.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55},{"Name":"Psyshock","Type":"Psychic","Damage":40}],"Weight":{"Minimum":"1.31kg","Maximum":"1.69kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"5km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"67 attack points.","Base Defense":"116 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":50,"Name":"Togepi candies"},"Next evolution(s)":[{"Number":176,"Name":"Togetic"}]},{"Number":"176","Name":"Togetic","Generation":"Generation II","About":"Togetic is said to be a Pokémon that brings good fortune. When the Pokémon spots someone who is pure of heart, it is said to appear and share its happiness with that person.","Types":["Fairy","Flying"],"Resistant":["Grass","Fighting","Ground","Bug","Dragon","Dark"],"Weaknesses":["Electric","Ice","Poison","Rock","Steel"],"Fast Attack(s)":[{"Name":"Steel Wing","Type":"Steel","Damage":15},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Aerial Ace","Type":"Flying","Damage":30},{"Name":"Ancient Power","Type":"Rock","Damage":35},{"Name":"Dazzling Gleam","Type":"Fairy","Damage":55}],"Weight":{"Minimum":"2.8kg","Maximum":"3.6kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"5km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"139 attack points.","Base Defense":"191 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":175,"Name":"Togepi"}]},{"Number":"177","Name":"Natu","Generation":"Generation II","About":"Natu cannot fly because its wings are not yet fully grown. If your eyes meet with this Pokémon's eyes, it will stare back intently at you. But if you move even slightly, it will hop away to safety.","Types":["Psychic","Flying"],"Resistant":["Grass","Fighting","Ground","Psychic"],"Weaknesses":["Electric","Ice","Rock","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Peck","Type":"Flying","Damage":10}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"1.75kg","Maximum":"2.25kg"},"Height":{"Minimum":"0.18m","Maximum":"0.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"134 attack points.","Base Defense":"89 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":178,"Name":"Xatu"}]},{"Number":"178","Name":"Xatu","Generation":"Generation II","About":"Xatu stands rooted and still in one spot all day long. People believe that this Pokémon does so out of fear of the terrible things it has foreseen in the future.","Types":["Psychic","Flying"],"Resistant":["Grass","Fighting","Ground","Psychic"],"Weaknesses":["Electric","Ice","Rock","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"13.13kg","Maximum":"16.88kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"192 attack points.","Base Defense":"146 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":177,"Name":"Natu"}]},{"Number":"179","Name":"Mareep","Generation":"Generation II","About":"Mareep's fluffy coat of wool rubs together and builds a static charge. The more static electricity is charged, the more brightly the lightbulb at the tip of its tail glows.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"6.83kg","Maximum":"8.78kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"114 attack points.","Base Defense":"82 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":180,"Name":"Flaaffy"},{"Number":181,"Name":"Ampharos"}]},{"Number":"180","Name":"Flaaffy","Generation":"Generation II","About":"Flaaffy's wool quality changes so that it can generate a high amount of static electricity with a small amount of wool. The bare and slick parts of its hide are shielded against electricity.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"11.64kg","Maximum":"14.96kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"145 attack points.","Base Defense":"112 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":179,"Name":"Mareep"}],"Next evolution(s)":[{"Number":181,"Name":"Ampharos"}]},{"Number":"181","Name":"Ampharos","Generation":"Generation II","About":"Ampharos gives off so much light that it can be seen even from space. People in the old days used the light of this Pokémon to send signals back and forth with others far away.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"53.81kg","Maximum":"69.19kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"211 attack points.","Base Defense":"172 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":179,"Name":"Mareep"},{"Number":180,"Name":"Flaaffy"}]},{"Number":"182","Name":"Bellossom","Generation":"Generation II","About":"When Bellossom gets exposed to plenty of sunlight, the leaves ringing its body begin to spin around. This Pokémon's dancing is renowned in the southern lands.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"5.08kg","Maximum":"6.53kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"169 attack points.","Base Defense":"189 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":43,"Name":"Oddish"},{"Number":44,"Name":"Gloom"}]},{"Number":"183","Name":"Marill","Generation":"Generation II","About":"Marill's oil-filled tail acts much like a life preserver. If you see just its tail bobbing on the water's surface, it's a sure indication that this Pokémon is diving beneath the water to feed on aquatic plants.","Types":["Water","Fairy"],"Resistant":["Fire","Water","Ice","Fighting","Bug","Dragon","Dark"],"Weaknesses":["Electric","Grass","Poison"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"7.44kg","Maximum":"9.56kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"37 attack points.","Base Defense":"93 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":184,"Name":"Azumarill"}]},{"Number":"184","Name":"Azumarill","Generation":"Generation II","About":"Azumarill's long ears are indispensable sensors. By focusing its hearing, this Pokémon can identify what kinds of prey are around, even in rough and fast-running rivers.","Types":["Water","Fairy"],"Resistant":["Fire","Water","Ice","Fighting","Bug","Dragon","Dark"],"Weaknesses":["Electric","Grass","Poison"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"24.94kg","Maximum":"32.06kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"112 attack points.","Base Defense":"152 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":183,"Name":"Marill"}]},{"Number":"185","Name":"Sudowoodo","Generation":"Generation II","About":"Sudowoodo camouflages itself as a tree to avoid being attacked by enemies. However, because its hands remain green throughout the year, the Pokémon is easily identified as a fake during the winter.","Types":["Rock"],"Resistant":["Normal","Fire","Poison","Flying"],"Weaknesses":["Water","Grass","Fighting","Ground","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"33.25kg","Maximum":"42.75kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"167 attack points.","Base Defense":"198 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"186","Name":"Politoed","Generation":"Generation II","About":"The curled hair on Politoed's head is proof of its status as a king. It is said that the longer and more curled the hair, the more respect this Pokémon earns from its peers.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"29.66kg","Maximum":"38.14kg"},"Height":{"Minimum":"9.54m","Maximum":"12.26m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"174 attack points.","Base Defense":"192 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":60,"Name":"Poliwag"},{"Number":61,"Name":"Poliwhirl"}]},{"Number":"187","Name":"Hoppip","Generation":"Generation II","About":"This Pokémon drifts and floats with the wind. If it senses the approach of strong winds, Hoppip links its leaves with other Hoppip to prepare against being blown away.","Types":["Grass","Flying"],"Resistant":["Water","Grass","Fighting","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"0.44kg","Maximum":"0.56kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"67 attack points.","Base Defense":"101 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":188,"Name":"Skiploom"},{"Number":189,"Name":"Jumpluff"}]},{"Number":"188","Name":"Skiploom","Generation":"Generation II","About":"Skiploom's flower blossoms when the temperature rises above 64 degrees Fahrenheit. How much the flower opens depends on the temperature. For that reason, this Pokémon is sometimes used as a thermometer.","Types":["Grass","Flying"],"Resistant":["Water","Grass","Fighting","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"0.88kg","Maximum":"1.13kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"91 attack points.","Base Defense":"127 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":187,"Name":"Hoppip"}],"Next evolution(s)":[{"Number":189,"Name":"Jumpluff"}]},{"Number":"189","Name":"Jumpluff","Generation":"Generation II","About":"Jumpluff rides warm southern winds to cross the sea and fly to foreign lands. The Pokémon descends to the ground when it encounters cold air while it is floating.","Types":["Grass","Flying"],"Resistant":["Water","Grass","Fighting","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"2.63kg","Maximum":"3.38kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"118 attack points.","Base Defense":"197 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":187,"Name":"Hoppip"},{"Number":188,"Name":"Skiploom"}]},{"Number":"190","Name":"Aipom","Generation":"Generation II","About":"Aipom's tail ends in a hand-like appendage that can be cleverly manipulated. However, because the Pokémon uses its tail so much, its real hands have become rather clumsy.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"10.06kg","Maximum":"12.94kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"136 attack points.","Base Defense":"112 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"191","Name":"Sunkern","Generation":"Generation II","About":"Sunkern tries to move as little as it possibly can. It does so because it tries to conserve all the nutrients it has stored in its body for its evolution. It will not eat a thing, subsisting only on morning dew.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"1.57kg","Maximum":"2.02kg"},"Height":{"Minimum":"0.26m","Maximum":"0.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"60 stamina points.","Base Attack":"55 attack points.","Base Defense":"55 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":192,"Name":"Sunflora"}]},{"Number":"192","Name":"Sunflora","Generation":"Generation II","About":"Sunflora converts solar energy into nutrition. It moves around actively in the daytime when it is warm. It stops moving as soon as the sun goes down for the night.","Types":["Grass"],"Resistant":["Water","Electric","Grass","Ground"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"7.44kg","Maximum":"9.56kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"185 attack points.","Base Defense":"148 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":191,"Name":"Sunkern"}]},{"Number":"193","Name":"Yanma","Generation":"Generation II","About":"Yanma is capable of seeing 360 degrees without having to move its eyes. It is a great flier that is adept at making sudden stops and turning midair. This Pokémon uses its flying ability to quickly chase down targeted prey.","Types":["Bug","Flying"],"Resistant":["Grass","Fighting","Ground","Bug"],"Weaknesses":["Fire","Electric","Ice","Flying","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"33.25kg","Maximum":"42.75kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"154 attack points.","Base Defense":"94 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"194","Name":"Wooper","Generation":"Generation II","About":"Wooper usually lives in water. However, it occasionally comes out onto land in search of food. On land, it coats its body with a gooey, toxic film.","Types":["Water","Ground"],"Resistant":["Fire","Poison","Rock","Steel"],"Weaknesses":["Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"7.44kg","Maximum":"9.56kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"75 attack points.","Base Defense":"75 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":195,"Name":"Quagsire"}]},{"Number":"195","Name":"Quagsire","Generation":"Generation II","About":"Quagsire hunts for food by leaving its mouth wide open in water and waiting for its prey to blunder in unaware. Because the Pokémon does not move, it does not get very hungry.","Types":["Water","Ground"],"Resistant":["Fire","Poison","Rock","Steel"],"Weaknesses":["Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"65.63kg","Maximum":"84.38kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"190 stamina points.","Base Attack":"152 attack points.","Base Defense":"152 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":194,"Name":"Wooper"}]},{"Number":"196","Name":"Espeon","Generation":"Generation II","About":"Espeon is extremely loyal to any Trainer it considers to be worthy. It is said that this Pokémon developed its precognitive powers to protect its Trainer from harm.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Confusion","Type":"Psychic","Damage":15},{"Name":"Zen Headbutt","Type":"Psychic","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"23.19kg","Maximum":"29.81kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"5km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"261 attack points.","Base Defense":"194 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":133,"Name":"Eevee"}]},{"Number":"197","Name":"Umbreon","Generation":"Generation II","About":"Umbreon evolved as a result of exposure to the moon's waves. It hides silently in darkness and waits for its foes to make a move. The rings on its body glow when it leaps to attack.","Types":["Dark"],"Resistant":["Psychic","Ghost","Dark"],"Weaknesses":["Fighting","Bug","Fairy"],"Fast Attack(s)":[{"Name":"Bite","Type":"Dark","Damage":6},{"Name":"Feint Attack","Type":"Dark","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"23.63kg","Maximum":"30.38kg"},"Height":{"Minimum":"0.87m","Maximum":"1.11m"},"Buddy Distance":"5km (Medium)","Base Stamina":"190 stamina points.","Base Attack":"126 attack points.","Base Defense":"250 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":133,"Name":"Eevee"}]},{"Number":"198","Name":"Murkrow","Generation":"Generation II","About":"Murkrow was feared and loathed as the alleged bearer of ill fortune. This Pokémon shows strong interest in anything that sparkles or glitters. It will even try to steal rings from women.","Types":["Dark","Flying"],"Resistant":["Grass","Ground","Psychic","Ghost","Dark"],"Weaknesses":["Electric","Ice","Rock","Fairy"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"1.84kg","Maximum":"2.36kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"175 attack points.","Base Defense":"87 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"199","Name":"Slowking","Generation":"Generation II","About":"Slowking undertakes research every day in an effort to solve the mysteries of the world. However, this Pokémon apparently forgets everything it has learned if the Shellder on its head comes off.","Types":["Water","Psychic"],"Resistant":["Fire","Water","Ice","Fighting","Psychic","Steel"],"Weaknesses":["Electric","Grass","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"69.56kg","Maximum":"89.44kg"},"Height":{"Minimum":"1.76m","Maximum":"2.26m"},"Buddy Distance":"1km (Medium)","Base Stamina":"190 stamina points.","Base Attack":"177 attack points.","Base Defense":"194 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":79,"Name":"Slowpoke"}]},{"Number":"200","Name":"Misdreavus","Generation":"Generation II","About":"Misdreavus frightens people with a creepy, sobbing cry. The Pokémon apparently uses its red spheres to absorb the fearful feelings of foes and turn them into nutrition.","Types":["Ghost"],"Resistant":["Normal","Fighting","Poison","Bug"],"Weaknesses":["Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"0.88kg","Maximum":"1.13kg"},"Height":{"Minimum":"0.62m","Maximum":"0.8m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"167 attack points.","Base Defense":"167 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"201","Name":"Unown","Generation":"Generation II","About":"This Pokémon is shaped like ancient writing. It is a mystery as to which came first, the ancient writings or the various Unown. Research into this topic is ongoing but nothing is known.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"4.38kg","Maximum":"5.63kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"96 stamina points.","Base Attack":"136 attack points.","Base Defense":"91 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"202","Name":"Wobbuffet","Generation":"Generation II","About":"If two or more Wobbuffet meet, they will turn competitive and try to outdo each other's endurance. However, they may try to see which one can endure the longest without food. Trainers need to beware of this habit.","Types":["Psychic"],"Resistant":["Fighting","Psychic"],"Weaknesses":["Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"24.94kg","Maximum":"32.06kg"},"Height":{"Minimum":"1.14m","Maximum":"1.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"380 stamina points.","Base Attack":"60 attack points.","Base Defense":"106 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"203","Name":"Girafarig","Generation":"Generation II","About":"Girafarig's rear head also has a brain, but it is small. The rear head attacks in response to smells and sounds. Approaching this Pokémon from behind can cause the rear head to suddenly lash out and bite.","Types":["Normal","Psychic"],"Resistant":["Psychic"],"Weaknesses":["Bug","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"36.31kg","Maximum":"46.69kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"182 attack points.","Base Defense":"133 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"204","Name":"Pineco","Generation":"Generation II","About":"Pineco hangs from a tree branch and patiently waits for prey to come along. If the Pokémon is disturbed while eating by someone shaking its tree, it drops down to the ground and explodes with no warning.","Types":["Bug"],"Resistant":["Grass","Fighting","Ground"],"Weaknesses":["Fire","Flying","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"6.3kg","Maximum":"8.1kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"108 attack points.","Base Defense":"146 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":205,"Name":"Forretress"}]},{"Number":"205","Name":"Forretress","Generation":"Generation II","About":"Forretress conceals itself inside its hardened steel shell. The shell is opened when the Pokémon is catching prey, but it does so at such a quick pace that the shell's inside cannot be seen.","Types":["Bug","Steel"],"Resistant":["Normal","Grass","Ice","Poison","Psychic","Bug","Dragon","Steel","Fairy"],"Weaknesses":["Fire"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"110.08kg","Maximum":"141.53kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"161 attack points.","Base Defense":"242 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":204,"Name":"Pineco"}]},{"Number":"206","Name":"Dunsparce","Generation":"Generation II","About":"Dunsparce has a drill for its tail. It uses this tail to burrow into the ground backward. This Pokémon is known to make its nest in complex shapes deep under the ground.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"12.25kg","Maximum":"15.75kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"131 attack points.","Base Defense":"131 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"207","Name":"Gligar","Generation":"Generation II","About":"Gligar glides through the air without a sound as if it were sliding. This Pokémon hangs on to the face of its foe using its clawed hind legs and the large pincers on its forelegs, then injects the prey with its poison barb.","Types":["Ground","Flying"],"Resistant":["Fighting","Poison","Ground","Bug"],"Weaknesses":["Water","Ice"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"56.7kg","Maximum":"72.9kg"},"Height":{"Minimum":"0.95m","Maximum":"1.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"143 attack points.","Base Defense":"204 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"208","Name":"Steelix","Generation":"Generation II","About":"Steelix lives even further underground than Onix. This Pokémon is known to dig toward the earth's core. There are records of this Pokémon reaching a depth of over six-tenths of a mile underground.","Types":["Steel","Ground"],"Resistant":["Normal","Electric","Poison","Flying","Psychic","Bug","Rock","Dragon","Steel","Fairy"],"Weaknesses":["Fire","Water","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"350kg","Maximum":"450kg"},"Height":{"Minimum":"8.04m","Maximum":"10.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"148 attack points.","Base Defense":"333 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":95,"Name":"Onix"}]},{"Number":"209","Name":"Snubbull","Generation":"Generation II","About":"By baring its fangs and making a scary face, Snubbull sends smaller Pokémon scurrying away in terror. However, this Pokémon seems a little sad at making its foes flee.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"6.83kg","Maximum":"8.78kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"137 attack points.","Base Defense":"89 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":210,"Name":"Granbull"}]},{"Number":"210","Name":"Granbull","Generation":"Generation II","About":"Granbull has a particularly well-developed lower jaw. The enormous fangs are heavy, causing the Pokémon to tip its head back for balance. Unless it is startled, it will not try to bite indiscriminately.","Types":["Fairy"],"Resistant":["Fighting","Bug","Dragon","Dark"],"Weaknesses":["Poison","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"42.61kg","Maximum":"54.79kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"212 attack points.","Base Defense":"137 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":209,"Name":"Snubbull"}]},{"Number":"211","Name":"Qwilfish","Generation":"Generation II","About":"Qwilfish sucks in water, inflating itself. This Pokémon uses the pressure of the water it swallowed to shoot toxic quills all at once from all over its body. It finds swimming somewhat challenging.","Types":["Water","Poison"],"Resistant":["Fire","Water","Ice","Fighting","Poison","Bug","Steel","Fairy"],"Weaknesses":["Electric","Ground","Psychic"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"3.41kg","Maximum":"4.39kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"184 attack points.","Base Defense":"148 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"212","Name":"Scizor","Generation":"Generation II","About":"Scizor has a body with the hardness of steel. It is not easily fazed by ordinary sorts of attacks. This Pokémon flaps its wings to regulate its body temperature.","Types":["Bug","Steel"],"Resistant":["Normal","Grass","Ice","Poison","Psychic","Bug","Dragon","Steel","Fairy"],"Weaknesses":["Fire"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"109.38kg","Maximum":"140.63kg"},"Height":{"Minimum":"1.76m","Maximum":"2.26m"},"Buddy Distance":"1km (Medium)","Base Stamina":"140 stamina points.","Base Attack":"236 attack points.","Base Defense":"191 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":123,"Name":"Scyther"}]},{"Number":"213","Name":"Shuckle","Generation":"Generation II","About":"Shuckle quietly hides itself under rocks, keeping its body concealed inside its hard shell while eating berries it has stored away. The berries mix with its body fluids to become a juice.","Types":["Bug","Rock"],"Resistant":["Normal","Poison"],"Weaknesses":["Water","Rock","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"17.94kg","Maximum":"23.06kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"40 stamina points.","Base Attack":"17 attack points.","Base Defense":"396 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"214","Name":"Heracross","Generation":"Generation II","About":"Heracross charges in a straight line at its foe, slips beneath the foe's grasp, and then scoops up and hurls the opponent with its mighty horn. This Pokémon even has enough power to topple a massive tree.","Types":["Bug","Fighting"],"Resistant":["Grass","Fighting","Ground","Bug","Dark"],"Weaknesses":["Fire","Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"47.25kg","Maximum":"60.75kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"160 stamina points.","Base Attack":"234 attack points.","Base Defense":"189 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"215","Name":"Sneasel","Generation":"Generation II","About":"Sneasel scales trees by punching its hooked claws into the bark. This Pokémon seeks out unguarded nests and steals eggs for food while the parents are away.","Types":["Dark","Ice"],"Resistant":["Ice","Psychic","Ghost","Dark"],"Weaknesses":["Fire","Fighting","Bug","Rock","Steel","Fairy"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"24.5kg","Maximum":"31.5kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"189 attack points.","Base Defense":"157 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"216","Name":"Teddiursa","Generation":"Generation II","About":"This Pokémon likes to lick its palms that are sweetened by being soaked in honey. Teddiursa concocts its own honey by blending fruits and pollen collected by Beedrill.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"7.7kg","Maximum":"9.9kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"120 stamina points.","Base Attack":"142 attack points.","Base Defense":"93 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":217,"Name":"Ursaring"}]},{"Number":"217","Name":"Ursaring","Generation":"Generation II","About":"In the forests inhabited by Ursaring, it is said that there are many streams and towering trees where they gather food. This Pokémon walks through its forest gathering food every day.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"110.08kg","Maximum":"141.53kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"236 attack points.","Base Defense":"144 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":216,"Name":"Teddiursa"}]},{"Number":"218","Name":"Slugma","Generation":"Generation II","About":"Molten magma courses throughout Slugma's circulatory system. If this Pokémon is chilled, the magma cools and hardens. Its body turns brittle and chunks fall off, reducing its size.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"30.63kg","Maximum":"39.38kg"},"Height":{"Minimum":"0.62m","Maximum":"0.8m"},"Buddy Distance":"1km (Medium)","Base Stamina":"80 stamina points.","Base Attack":"118 attack points.","Base Defense":"71 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":219,"Name":"Magcargo"}]},{"Number":"219","Name":"Magcargo","Generation":"Generation II","About":"Magcargo's shell is actually its skin that hardened as a result of cooling. Its shell is very brittle and fragile—just touching it causes it to crumble apart. This Pokémon returns to its original size by dipping itself in magma.","Types":["Fire","Rock"],"Resistant":["Normal","Fire","Ice","Poison","Flying","Bug","Fairy"],"Weaknesses":["Water","Fighting","Ground","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"48.13kg","Maximum":"61.88kg"},"Height":{"Minimum":"0.69m","Maximum":"0.89m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"139 attack points.","Base Defense":"209 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":218,"Name":"Slugma"}]},{"Number":"220","Name":"Swinub","Generation":"Generation II","About":"Swinub roots for food by rubbing its snout against the ground. Its favorite food is a mushroom that grows under the cover of dead grass. This Pokémon occasionally roots out hot springs.","Types":["Ice","Ground"],"Resistant":["Electric","Poison"],"Weaknesses":["Fire","Water","Grass","Fighting","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"5.69kg","Maximum":"7.31kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"1km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"90 attack points.","Base Defense":"74 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":221,"Name":"Piloswine"}]},{"Number":"221","Name":"Piloswine","Generation":"Generation II","About":"Piloswine is covered by a thick coat of long hair that enables it to endure the freezing cold. This Pokémon uses its tusks to dig up food that has been buried under ice.","Types":["Ice","Ground"],"Resistant":["Electric","Poison"],"Weaknesses":["Fire","Water","Grass","Fighting","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"48.82kg","Maximum":"62.77kg"},"Height":{"Minimum":"0.95m","Maximum":"1.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"181 attack points.","Base Defense":"147 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":220,"Name":"Swinub"}]},{"Number":"222","Name":"Corsola","Generation":"Generation II","About":"Corsola's branches glitter very beautifully in seven colors when they catch sunlight. If any branch breaks off, this Pokémon grows it back in just one night.","Types":["Water","Rock"],"Resistant":["Normal","Fire","Ice","Poison","Flying"],"Weaknesses":["Electric","Grass","Fighting","Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"4.38kg","Maximum":"5.63kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"118 attack points.","Base Defense":"156 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"223","Name":"Remoraid","Generation":"Generation II","About":"Remoraid sucks in water, then expels it at high velocity using its abdominal muscles to shoot down flying prey. When evolution draws near, this Pokémon travels downstream from rivers.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"10.5kg","Maximum":"13.5kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"127 attack points.","Base Defense":"69 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":224,"Name":"Octillery"}]},{"Number":"224","Name":"Octillery","Generation":"Generation II","About":"Octillery grabs onto its foe using its tentacles. This Pokémon tries to immobilize it before delivering the finishing blow. If the foe turns out to be too strong, Octillery spews ink to escape.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"24.94kg","Maximum":"32.06kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"197 attack points.","Base Defense":"141 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":223,"Name":"Remoraid"}]},{"Number":"225","Name":"Delibird","Generation":"Generation II","About":"Delibird carries its food bundled up in its tail. There once was a famous explorer who managed to reach the peak of the world's highest mountain, thanks to one of these Pokémon sharing its food.","Types":["Ice","Flying"],"Resistant":["Grass","Ground","Bug"],"Weaknesses":["Fire","Electric","Rock","Steel"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"14kg","Maximum":"18kg"},"Height":{"Minimum":"0.78m","Maximum":"1m"},"Buddy Distance":"1km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"128 attack points.","Base Defense":"90 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"226","Name":"Mantine","Generation":"Generation II","About":"On sunny days, schools of Mantine can be seen elegantly leaping over the sea's waves. This Pokémon is not bothered by the Remoraid that hitches rides.","Types":["Water","Flying"],"Resistant":["Fire","Water","Fighting","Ground","Bug","Steel"],"Weaknesses":["Electric","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"192.5kg","Maximum":"247.5kg"},"Height":{"Minimum":"1.85m","Maximum":"2.37m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"148 attack points.","Base Defense":"260 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"227","Name":"Skarmory","Generation":"Generation II","About":"Skarmory is entirely encased in hard, protective armor. This Pokémon flies at close to 190 mph. It slashes foes with its wings that possess swordlike cutting edges.","Types":["Steel","Flying"],"Resistant":["Normal","Grass","Poison","Flying","Psychic","Bug","Dragon","Steel","Fairy"],"Weaknesses":["Fire","Electric"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"44.19kg","Maximum":"56.81kg"},"Height":{"Minimum":"1.49m","Maximum":"1.91m"},"Buddy Distance":"1km (Medium)","Base Stamina":"130 stamina points.","Base Attack":"148 attack points.","Base Defense":"260 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"228","Name":"Houndour","Generation":"Generation II","About":"Houndour hunt as a coordinated pack. They communicate with each other using a variety of cries to corner their prey. This Pokémon's remarkable teamwork is unparalleled.","Types":["Dark","Fire"],"Resistant":["Fire","Grass","Ice","Psychic","Ghost","Dark","Steel"],"Weaknesses":["Water","Fighting","Ground","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"9.45kg","Maximum":"12.15kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"152 attack points.","Base Defense":"93 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":229,"Name":"Houndoom"}]},{"Number":"229","Name":"Houndoom","Generation":"Generation II","About":"In a Houndoom pack, the one with its horns raked sharply toward the back serves a leadership role. These Pokémon choose their leader by fighting among themselves.","Types":["Dark","Fire"],"Resistant":["Fire","Grass","Ice","Psychic","Ghost","Dark","Steel"],"Weaknesses":["Water","Fighting","Ground","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"30.63kg","Maximum":"39.38kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"224 attack points.","Base Defense":"159 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":228,"Name":"Houndour"}]},{"Number":"230","Name":"Kingdra","Generation":"Generation II","About":"Kingdra lives at extreme ocean depths that are otherwise uninhabited. It has long been believed that the yawning of this Pokémon creates spiraling ocean currents.","Types":["Water","Dragon"],"Resistant":["Fire","Water","Steel"],"Weaknesses":["Dragon","Fairy"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"133kg","Maximum":"171kg"},"Height":{"Minimum":"1.57m","Maximum":"2.02m"},"Buddy Distance":"1km (Medium)","Base Stamina":"150 stamina points.","Base Attack":"194 attack points.","Base Defense":"194 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":116,"Name":"Horsea"},{"Number":117,"Name":"Seadra"}]},{"Number":"231","Name":"Phanpy","Generation":"Generation II","About":"For its nest, Phanpy digs a vertical pit in the ground at the edge of a river. It marks the area around its nest with its trunk to let the others know that the area has been claimed.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"29.31kg","Maximum":"37.69kg"},"Height":{"Minimum":"0.45m","Maximum":"0.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"107 attack points.","Base Defense":"107 defense points.","Base Flee Rate":"5% chance to flee.","Next evolution(s)":[{"Number":232,"Name":"Donphan"}]},{"Number":"232","Name":"Donphan","Generation":"Generation II","About":"Donphan's favorite attack is curling its body into a ball, then charging at its foe while rolling at high speed. Once it starts rolling, this Pokémon can't stop very easily.","Types":["Ground"],"Resistant":["Electric","Poison","Rock"],"Weaknesses":["Water","Grass","Ice"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"105kg","Maximum":"135kg"},"Height":{"Minimum":"0.95m","Maximum":"1.23m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"214 attack points.","Base Defense":"214 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":231,"Name":"Phanpy"}]},{"Number":"233","Name":"Porygon2","Generation":"Generation II","About":"Porygon2 was created by humans using the power of science. The man-made Pokémon has been endowed with artificial intelligence that enables it to learn new gestures and emotions on its own.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"28.44kg","Maximum":"36.56kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"170 stamina points.","Base Attack":"198 attack points.","Base Defense":"183 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":137,"Name":"Porygon"}]},{"Number":"234","Name":"Stantler","Generation":"Generation II","About":"Stantler's magnificent antlers were traded at high prices as works of art. As a result, this Pokémon was hunted close to extinction by those who were after the priceless antlers.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"62.3kg","Maximum":"80.1kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"1km (Medium)","Base Stamina":"146 stamina points.","Base Attack":"192 attack points.","Base Defense":"132 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"235","Name":"Smeargle","Generation":"Generation II","About":"Smeargle marks the boundaries of its territory using a body fluid that leaks out from the tip of its tail. Over 5,000 different marks left by this Pokémon have been found.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"50.75kg","Maximum":"65.25kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"110 stamina points.","Base Attack":"40 attack points.","Base Defense":"88 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"236","Name":"Tyrogue","Generation":"Generation II","About":"Tyrogue becomes stressed out if it does not get to train every day. When raising this Pokémon, the Trainer must establish and uphold various training methods.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Low Kick","Type":"Fighting","Damage":5},{"Name":"Rock Smash","Type":"Fighting","Damage":15}],"Special Attack(s)":[{"Name":"Body Slam","Type":"Normal","Damage":40},{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Low Sweep","Type":"Fighting","Damage":30}],"Weight":{"Minimum":"18.38kg","Maximum":"23.63kg"},"Height":{"Minimum":"0.62m","Maximum":"0.8m"},"Buddy Distance":"5km (Medium)","Base Stamina":"70 stamina points.","Base Attack":"64 attack points.","Base Defense":"64 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Tyrogue candies"},"Next evolution(s)":[{"Number":106,"Name":"Hitmonlee"},{"Number":107,"Name":"Hitmonchan"},{"Number":237,"Name":"Hitmontop"}]},{"Number":"237","Name":"Hitmontop","Generation":"Generation II","About":"Hitmontop spins on its head at high speed, all the while delivering kicks. This technique is a remarkable mix of both offense and defense at the same time. The Pokémon travels faster spinning than it does walking.","Types":["Fighting"],"Resistant":["Bug","Rock","Dark"],"Weaknesses":["Flying","Psychic","Fairy"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"42kg","Maximum":"54kg"},"Height":{"Minimum":"1.22m","Maximum":"1.57m"},"Buddy Distance":"5km (Medium)","Base Stamina":"100 stamina points.","Base Attack":"173 attack points.","Base Defense":"214 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":236,"Name":"Tyrogue"}]},{"Number":"238","Name":"Smoochum","Generation":"Generation II","About":"Smoochum actively runs about, but also falls quite often. Whenever the chance arrives, it will look for its reflection to make sure its face hasn't become dirty.","Types":["Ice","Psychic"],"Resistant":["Ice","Psychic"],"Weaknesses":["Fire","Bug","Rock","Ghost","Dark","Steel"],"Fast Attack(s)":[{"Name":"Frost Breath","Type":"Ice","Damage":9},{"Name":"Pound","Type":"Normal","Damage":7}],"Special Attack(s)":[{"Name":"Ice Beam","Type":"Ice","Damage":65},{"Name":"Ice Punch","Type":"Ice","Damage":45},{"Name":"Psyshock","Type":"Psychic","Damage":40}],"Weight":{"Minimum":"5.25kg","Maximum":"6.75kg"},"Height":{"Minimum":"0.36m","Maximum":"0.46m"},"Buddy Distance":"5km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"153 attack points.","Base Defense":"116 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Jyn"},"Next evolution(s)":[{"Number":124,"Name":"Jynx"}]},{"Number":"239","Name":"Elekid","Generation":"Generation II","About":"Elekid stores electricity in its body. If it touches metal and accidentally discharges all its built-up electricity, this Pokémon begins swinging its arms in circles to recharge itself.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Low Kick","Type":"Fighting","Damage":5},{"Name":"Thunder Shock","Type":"Electric","Damage":5}],"Special Attack(s)":[{"Name":"Discharge","Type":"Electric","Damage":35},{"Name":"Thunder Punch","Type":"Electric","Damage":40},{"Name":"Thunderbolt","Type":"Electric","Damage":55}],"Weight":{"Minimum":"20.56kg","Maximum":"26.44kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"5km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"135 attack points.","Base Defense":"110 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Electabuzz candies"},"Next evolution(s)":[{"Number":125,"Name":"Electabuzz"}]},{"Number":"240","Name":"Magby","Generation":"Generation II","About":"Magby's state of health is determined by observing the fire it breathes. If the Pokémon is spouting yellow flames from its mouth, it is in good health. When it is fatigued, black smoke will be mixed in with the flames.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Ember","Type":"Fire","Damage":10},{"Name":"Karate Chop","Type":"Fighting","Damage":6}],"Special Attack(s)":[{"Name":"Brick Break","Type":"Fighting","Damage":30},{"Name":"Fire Punch","Type":"Fire","Damage":40},{"Name":"Flamethrower","Type":"Fire","Damage":55}],"Weight":{"Minimum":"18.72kg","Maximum":"24.07kg"},"Height":{"Minimum":"0.62m","Maximum":"0.8m"},"Buddy Distance":"5km (Medium)","Base Stamina":"90 stamina points.","Base Attack":"151 attack points.","Base Defense":"108 defense points.","Base Flee Rate":"5% chance to flee.","Next Evolution Requirements":{"Amount":25,"Name":"Magmar candies"},"Next evolution(s)":[{"Number":126,"Name":"Magmar"}]},{"Number":"241","Name":"Miltank","Generation":"Generation II","About":"Miltank gives over five gallons of milk on a daily basis. Its sweet milk is enjoyed by children and grown-ups alike. People who can't drink milk turn it into yogurt and eat it instead.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"66.06kg","Maximum":"84.94kg"},"Height":{"Minimum":"1.04m","Maximum":"1.34m"},"Buddy Distance":"1km (Medium)","Base Stamina":"190 stamina points.","Base Attack":"157 attack points.","Base Defense":"211 defense points.","Base Flee Rate":"5% chance to flee."},{"Number":"242","Name":"Blissey","Generation":"Generation II","About":"Blissey senses sadness with its fluffy coat of fur. If it does so, this Pokémon will rush over to a sad person, no matter how far away, to share a Lucky Egg that brings a smile to any face.","Types":["Normal"],"Resistant":["Ghost"],"Weaknesses":["Fighting"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"40.95kg","Maximum":"52.65kg"},"Height":{"Minimum":"1.31m","Maximum":"1.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"510 stamina points.","Base Attack":"129 attack points.","Base Defense":"229 defense points.","Base Flee Rate":"5% chance to flee.","Previous evolution(s)":[{"Number":113,"Name":"Chansey"}]},{"Number":"243","Name":"Raikou","Generation":"Generation II","About":"Raikou embodies the speed of lightning. The roars of this Pokémon send shock waves shuddering through the air and shake the ground as if lightning bolts had come crashing down.","Types":["Electric"],"Resistant":["Electric","Flying","Steel"],"Weaknesses":["Ground"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"155.75kg","Maximum":"200.25kg"},"Height":{"Minimum":"1.67m","Maximum":"2.15m"},"Buddy Distance":"1km (Medium)","Base Stamina":"180 stamina points.","Base Attack":"241 attack points.","Base Defense":"210 defense points.","Base Flee Rate":"5% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class"},{"Number":"244","Name":"Entei","Generation":"Generation II","About":"Entei embodies the passion of magma. This Pokémon is thought to have been born in the eruption of a volcano. It sends up massive bursts of fire that utterly consume all that they touch.","Types":["Fire"],"Resistant":["Fire","Grass","Ice","Bug","Steel","Fairy"],"Weaknesses":["Water","Ground","Rock"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"173.25kg","Maximum":"222.75kg"},"Height":{"Minimum":"1.85m","Maximum":"2.37m"},"Buddy Distance":"1km (Medium)","Base Stamina":"230 stamina points.","Base Attack":"235 attack points.","Base Defense":"176 defense points.","Base Flee Rate":"5% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class"},{"Number":"245","Name":"Suicune","Generation":"Generation II","About":"Suicune embodies the compassion of a pure spring of water. It runs across the land with gracefulness. This Pokémon has the power to purify dirty water.","Types":["Water"],"Resistant":["Fire","Water","Ice","Steel"],"Weaknesses":["Electric","Grass"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"163.63kg","Maximum":"210.38kg"},"Height":{"Minimum":"1.76m","Maximum":"2.26m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"180 attack points.","Base Defense":"235 defense points.","Base Flee Rate":"5% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class"},{},{},{},{"Number":"249","Name":"Lugia","Generation":"Generation II","About":"Lugia's wings pack devastating power—a light fluttering of its wings can blow apart regular houses. As a result, this Pokémon chooses to live out of sight deep under the sea.","Types":["Psychic","Flying"],"Resistant":["Grass","Fighting","Ground","Psychic"],"Weaknesses":["Electric","Ice","Rock","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"189kg","Maximum":"243kg"},"Height":{"Minimum":"4.56m","Maximum":"5.86m"},"Buddy Distance":"1km (Medium)","Base Stamina":"212 stamina points.","Base Attack":"193 attack points.","Base Defense":"323 defense points.","Base Flee Rate":"5% chance to flee.","Pokèmon Class":"This is a LEGENDARY Pokèmon.","LEGENDARY":"Pokèmon Class"},{},{"Number":"251","Name":"Celebi","Generation":"Generation II","About":"This Pokémon came from the future by crossing over time. It is thought that so long as Celebi appears, a bright and shining future awaits us.","Types":["Psychic","Grass"],"Resistant":["Water","Electric","Grass","Fighting","Ground","Psychic"],"Weaknesses":["Fire","Ice","Poison","Flying","Bug","Ghost","Dark"],"Fast Attack(s)":[{"Name":"Tackle","Type":"Normal","Damage":12}],"Special Attack(s)":[{"Name":"Struggle","Type":"Normal","Damage":15}],"Weight":{"Minimum":"4.38kg","Maximum":"5.63kg"},"Height":{"Minimum":"0.53m","Maximum":"0.69m"},"Buddy Distance":"1km (Medium)","Base Stamina":"200 stamina points.","Base Attack":"210 attack points.","Base Defense":"210 defense points.","Base Flee Rate":"5% chance to flee.","Pokèmon Class":"This is a MYTHIC Pokèmon.","MYTHIC":"Pokèmon Class"}] diff --git a/texts/roles.md b/texts/roles.md index b0dc69b..9299441 100755 --- a/texts/roles.md +++ b/texts/roles.md @@ -1,13 +1,13 @@ - -Pour améliorer l'expérience utilisateur de tout le monde, vous pouvez spécifier la·les distribution·s que vous utilisez via les rôles Discord. - -**Liste des rôles** - └> Arch : pour les utilisateurs de Arch, Manjaro et TuxNVape - └> Debian : pour Debian et ses dérivés (Ubuntu, Kali, etc.) - └> Rhel : pour Red Hat Entreprise Linux et ses dérivés (Fedora, CentOS, etc.) - └> Android : pour Android - └> BSD : pour les systèmes basés sur BSD - -**Commandes** - └> Pour ajouter un rôle : ``.role Nomdurole`` + +Pour améliorer l'expérience utilisateur de tout le monde, vous pouvez spécifier la·les distribution·s que vous utilisez via les rôles Discord. + +**Liste des rôles** + └> Arch : pour les utilisateurs de Arch, Manjaro et TuxNVape + └> Debian : pour Debian et ses dérivés (Ubuntu, Kali, etc.) + └> Rhel : pour Red Hat Entreprise Linux et ses dérivés (Fedora, CentOS, etc.) + └> Android : pour Android + └> BSD : pour les systèmes basés sur BSD + +**Commandes** + └> Pour ajouter un rôle : ``.role Nomdurole`` └> Pour retirer un rôle : ``.role Nomdurole`` \ No newline at end of file diff --git a/texts/rpoll.md b/texts/rpoll.md index b8fd83f..e7419a0 100755 --- a/texts/rpoll.md +++ b/texts/rpoll.md @@ -1,14 +1,14 @@ -**Créez un sondage avec les réactions !** - -**Usage** : -``.sondage | | | `` Vous pouvez utiliser autant de réponses que vous le souhaitez, en plaçant un symbole | entre chaque choix. - -**Exemple**: -``.sondage Quelle est votre couleur préférée ? | Rouge | Vert | Bleu | Autre`` - - -**Definir un temps limite** : -Vous pouvez également utiliser l'option "time" pour définir le temps en secondes pendant lequel le sondage durera. - -**Exemple**: -``.sondage Utilisez vous twitteur ? | Oui | Non | Pas souvent | time=10``. +**Créez un sondage avec les réactions !** + +**Usage** : +``.sondage | | | `` Vous pouvez utiliser autant de réponses que vous le souhaitez, en plaçant un symbole | entre chaque choix. + +**Exemple**: +``.sondage Quelle est votre couleur préférée ? | Rouge | Vert | Bleu | Autre`` + + +**Definir un temps limite** : +Vous pouvez également utiliser l'option "time" pour définir le temps en secondes pendant lequel le sondage durera. + +**Exemple**: +``.sondage Utilisez vous twitteur ? | Oui | Non | Pas souvent | time=10``. diff --git a/texts/search.md b/texts/search.md index 52523d0..68db27c 100755 --- a/texts/search.md +++ b/texts/search.md @@ -1,6 +1,6 @@ - -_Attention ! entrez vos termes de recherche sans espaces !_ -Pour effectuer une recherche utilisez la commande ``.search {site_de_recherche} {termes_recherche}`` --> [**docubuntu**](https://doc.ubuntu-fr.org) : Effectuer une recherche sur un paquet dans la Documentation du site ubuntu-fr.org. --> [**wikipedia**](https://fr.wikipedia.org) : Effectuer une recherche sur l'encyclopédie libre Wikipedia en Français ! --> [**docaur**](https://doc.archlinux.org) : Effectuer une recherche sur la doc ArchLinux ! + +_Attention ! entrez vos termes de recherche sans espaces !_ +Pour effectuer une recherche utilisez la commande ``.search {site_de_recherche} {termes_recherche}`` +-> [**docubuntu**](https://doc.ubuntu-fr.org) : Effectuer une recherche sur un paquet dans la Documentation du site ubuntu-fr.org. +-> [**wikipedia**](https://fr.wikipedia.org) : Effectuer une recherche sur l'encyclopédie libre Wikipedia en Français ! +-> [**docaur**](https://doc.archlinux.org) : Effectuer une recherche sur la doc ArchLinux ! diff --git a/texts/ytb.json b/texts/ytb.json index 4e451aa..6d9abc8 100755 --- a/texts/ytb.json +++ b/texts/ytb.json @@ -1,15 +1,15 @@ -{ - "1": {"name": "KickSama", "desc": "Des dessins annimés sympatiques par un jeune !", "url": "https://www.youtube.com/user/TheKickGuy"}, - "2": {"name": "U=RI", "desc": "Des vidéos interessantes sur l'électricité dont des tutoriels !", "url": "https://www.youtube.com/channel/UCVqx3vXNghSqUcVg2nmegYA"}, - "3": {"name": "Outout", "desc": "Outout, chaine vraiment nul et peu alimenté par mon créateur...", "url": "https://www.youtube.com/channel/UC2XpYyT5X5tq9UQpXdc1JaQ"}, - "4": {"name": "SuperJDay64", "desc": "Des LetsPlay sur Nintendo64 avec beaucoup de plombiers moustachus !", "url": "https://www.youtube.com/channel/UCjkQgODdmhR9I2TatJZtGSQ/"}, - "5": {"name": "Monsieur Plouf", "desc": "Vidéos comiques de critiques de jeux AAA avec un décors assez spécial !", "url": "https://www.youtube.com/channel/UCrt_PUTF9LdJyuDfXweHwuQ"}, - "6": {"name": "MaxEstLa", "desc": "Petite chaîne bien _sympatique_ sur la réaction de vidéos malsaine ! Très éducative x)", "url": "https://www.youtube.com/channel/UCsk9XguwTfgbenCZ4AlIcYQ"}, - "7": {"name": "Met-Hardware", "desc": "Chaine youtube sur l'hardware et des let's play bien sypatique !", "url": "https://www.youtube.com/channel/UC7rse81OttysA1m1yn_f-OA"}, - "8": {"name": "ElectronikHeart", "desc": "~~Test de produits de merde ~~ L'informatique sous un angle différent et agréable", "url": "https://www.youtube.com/user/ElectronikHeart"}, - "9": {"name": "Caljbeut", "desc": "Cartoon Trash ! Dessins annimés par un ancien de l'armée sur la politique et d'autre sujets ! **On est pas la pour rigoler**", "url": "https://www.youtube.com/channel/UCNM-UkIP1BL5jv9ZrN5JMCA"}, - "10": {"name": "Autodisciple", "desc": "Defis, Bitcoins, Geek, la vie quoi ! Sans oublier des défis de 30 Jours !", "url": "https://www.youtube.com/channel/UCDMxcev7u9Nf7KMJuyIm-BA"}, - "11": {"name": "CineAstuces", "desc": "Techniques, metiers du cinema, reportages et autres en rapport avec la cinématographie !", "url": "https://www.youtube.com/channel/UC--84qgkrqqqYivuuXuQIQg"}, - "12": {"name": "Epic Teaching of the History", "desc": "L'Histoire c'est hyper méga giga ultra _(j'ai pas été payé)_ drôle avec RaAak le renard ! ", "url": "https://www.youtube.com/channel/UCHwd4qMCzN4A2r6piZxTl4A"} -} - +{ + "1": {"name": "KickSama", "desc": "Des dessins annimés sympatiques par un jeune !", "url": "https://www.youtube.com/user/TheKickGuy"}, + "2": {"name": "U=RI", "desc": "Des vidéos interessantes sur l'électricité dont des tutoriels !", "url": "https://www.youtube.com/channel/UCVqx3vXNghSqUcVg2nmegYA"}, + "3": {"name": "Outout", "desc": "Outout, chaine vraiment nul et peu alimenté par mon créateur...", "url": "https://www.youtube.com/channel/UC2XpYyT5X5tq9UQpXdc1JaQ"}, + "4": {"name": "SuperJDay64", "desc": "Des LetsPlay sur Nintendo64 avec beaucoup de plombiers moustachus !", "url": "https://www.youtube.com/channel/UCjkQgODdmhR9I2TatJZtGSQ/"}, + "5": {"name": "Monsieur Plouf", "desc": "Vidéos comiques de critiques de jeux AAA avec un décors assez spécial !", "url": "https://www.youtube.com/channel/UCrt_PUTF9LdJyuDfXweHwuQ"}, + "6": {"name": "MaxEstLa", "desc": "Petite chaîne bien _sympatique_ sur la réaction de vidéos malsaine ! Très éducative x)", "url": "https://www.youtube.com/channel/UCsk9XguwTfgbenCZ4AlIcYQ"}, + "7": {"name": "Met-Hardware", "desc": "Chaine youtube sur l'hardware et des let's play bien sypatique !", "url": "https://www.youtube.com/channel/UC7rse81OttysA1m1yn_f-OA"}, + "8": {"name": "ElectronikHeart", "desc": "~~Test de produits de merde ~~ L'informatique sous un angle différent et agréable", "url": "https://www.youtube.com/user/ElectronikHeart"}, + "9": {"name": "Caljbeut", "desc": "Cartoon Trash ! Dessins annimés par un ancien de l'armée sur la politique et d'autre sujets ! **On est pas la pour rigoler**", "url": "https://www.youtube.com/channel/UCNM-UkIP1BL5jv9ZrN5JMCA"}, + "10": {"name": "Autodisciple", "desc": "Defis, Bitcoins, Geek, la vie quoi ! Sans oublier des défis de 30 Jours !", "url": "https://www.youtube.com/channel/UCDMxcev7u9Nf7KMJuyIm-BA"}, + "11": {"name": "CineAstuces", "desc": "Techniques, metiers du cinema, reportages et autres en rapport avec la cinématographie !", "url": "https://www.youtube.com/channel/UC--84qgkrqqqYivuuXuQIQg"}, + "12": {"name": "Epic Teaching of the History", "desc": "L'Histoire c'est hyper méga giga ultra _(j'ai pas été payé)_ drôle avec RaAak le renard ! ", "url": "https://www.youtube.com/channel/UCHwd4qMCzN4A2r6piZxTl4A"} +} +