From 156d79ff32aed8bb7e710c74e602d3744637ec8a Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 18 Jun 2025 01:22:00 +0000 Subject: [PATCH] feat: Add custom addons and flatten repository --- addons/.gitignore | 3 + addons/LICENSE | 661 +++++++++++++++ addons/README.md | 46 + addons/__init__.py | 11 + addons/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 194 bytes .../__pycache__/activitygen.cpython-312.pyc | Bin 0 -> 1343 bytes addons/__pycache__/afk.cpython-312.pyc | Bin 0 -> 8993 bytes addons/__pycache__/animations.cpython-312.pyc | Bin 0 -> 73638 bytes addons/__pycache__/anime.cpython-312.pyc | Bin 0 -> 2456 bytes addons/__pycache__/animechan.cpython-312.pyc | Bin 0 -> 1187 bytes addons/__pycache__/animedb.cpython-312.pyc | Bin 0 -> 1680 bytes addons/__pycache__/antiflood.cpython-312.pyc | Bin 0 -> 7732 bytes addons/__pycache__/asstcmd.cpython-312.pyc | Bin 0 -> 7246 bytes addons/__pycache__/astronomy.cpython-312.pyc | Bin 0 -> 1818 bytes addons/__pycache__/audiotools.cpython-312.pyc | Bin 0 -> 9701 bytes addons/__pycache__/autoban.cpython-312.pyc | Bin 0 -> 3395 bytes .../__pycache__/autocorrect.cpython-312.pyc | Bin 0 -> 2954 bytes addons/__pycache__/autopic.cpython-312.pyc | Bin 0 -> 8630 bytes .../__pycache__/autoprofile.cpython-312.pyc | Bin 0 -> 3304 bytes addons/__pycache__/beautify.cpython-312.pyc | Bin 0 -> 13909 bytes addons/__pycache__/blacklist.cpython-312.pyc | Bin 0 -> 5913 bytes addons/__pycache__/brainfuck.cpython-312.pyc | Bin 0 -> 9738 bytes addons/__pycache__/broadcast.cpython-312.pyc | Bin 0 -> 12357 bytes addons/__pycache__/button.cpython-312.pyc | Bin 0 -> 2591 bytes addons/__pycache__/calculator.cpython-312.pyc | Bin 0 -> 6973 bytes .../__pycache__/channelhacks.cpython-312.pyc | Bin 0 -> 13911 bytes addons/__pycache__/chatbot.cpython-312.pyc | Bin 0 -> 6175 bytes .../__pycache__/cleanaction.cpython-312.pyc | Bin 0 -> 3245 bytes addons/__pycache__/clone.cpython-312.pyc | Bin 0 -> 8871 bytes addons/__pycache__/compressor.cpython-312.pyc | Bin 0 -> 9574 bytes addons/__pycache__/converter.cpython-312.pyc | Bin 0 -> 11104 bytes addons/__pycache__/covid.cpython-312.pyc | Bin 0 -> 1779 bytes addons/__pycache__/echo.cpython-312.pyc | Bin 0 -> 8706 bytes .../__pycache__/encodedecode.cpython-312.pyc | Bin 0 -> 2719 bytes addons/__pycache__/extra.cpython-312.pyc | Bin 0 -> 4233 bytes addons/__pycache__/fakeaction.cpython-312.pyc | Bin 0 -> 1969 bytes addons/__pycache__/fastly.cpython-312.pyc | Bin 0 -> 4294 bytes addons/__pycache__/figlet.cpython-312.pyc | Bin 0 -> 18611 bytes addons/__pycache__/filter.cpython-312.pyc | Bin 0 -> 7700 bytes addons/__pycache__/findsong.cpython-312.pyc | Bin 0 -> 3154 bytes addons/__pycache__/flaticon.cpython-312.pyc | Bin 0 -> 2351 bytes addons/__pycache__/fontgen.cpython-312.pyc | Bin 0 -> 3233 bytes addons/__pycache__/fontsnew.cpython-312.pyc | Bin 0 -> 13561 bytes .../forcesubscribe.cpython-312.pyc | Bin 0 -> 13046 bytes addons/__pycache__/fun.cpython-312.pyc | Bin 0 -> 6497 bytes addons/__pycache__/gdrive.cpython-312.pyc | Bin 0 -> 12576 bytes addons/__pycache__/giftools.cpython-312.pyc | Bin 0 -> 8163 bytes addons/__pycache__/glitch.cpython-312.pyc | Bin 0 -> 2388 bytes .../__pycache__/globaltools.cpython-312.pyc | Bin 0 -> 42204 bytes addons/__pycache__/greetings.cpython-312.pyc | Bin 0 -> 17977 bytes addons/__pycache__/hack.cpython-312.pyc | Bin 0 -> 11764 bytes addons/__pycache__/howto.cpython-312.pyc | Bin 0 -> 1675 bytes addons/__pycache__/imagetools.cpython-312.pyc | Bin 0 -> 16290 bytes addons/__pycache__/imdb.cpython-312.pyc | Bin 0 -> 1565 bytes addons/__pycache__/inlinefun.cpython-312.pyc | Bin 0 -> 7999 bytes addons/__pycache__/limited.cpython-312.pyc | Bin 0 -> 2003 bytes addons/__pycache__/locks.cpython-312.pyc | Bin 0 -> 2055 bytes addons/__pycache__/logo.cpython-312.pyc | Bin 0 -> 4246 bytes addons/__pycache__/memify.cpython-312.pyc | Bin 0 -> 13242 bytes addons/__pycache__/misc.cpython-312.pyc | Bin 0 -> 8603 bytes addons/__pycache__/morsecode.cpython-312.pyc | Bin 0 -> 2090 bytes addons/__pycache__/mute.cpython-312.pyc | Bin 0 -> 14007 bytes addons/__pycache__/ncode.cpython-312.pyc | Bin 0 -> 2615 bytes addons/__pycache__/nightmode.cpython-312.pyc | Bin 0 -> 8237 bytes addons/__pycache__/notes.cpython-312.pyc | Bin 0 -> 8223 bytes addons/__pycache__/nsfwfilter.cpython-312.pyc | Bin 0 -> 10419 bytes addons/__pycache__/ocr.cpython-312.pyc | Bin 0 -> 2300 bytes addons/__pycache__/other.cpython-312.pyc | Bin 0 -> 4964 bytes addons/__pycache__/pdftools.cpython-312.pyc | Bin 0 -> 20814 bytes addons/__pycache__/pokedex.cpython-312.pyc | Bin 0 -> 7113 bytes addons/__pycache__/polls.cpython-312.pyc | Bin 0 -> 3637 bytes .../profanityfilter.cpython-312.pyc | Bin 0 -> 1270 bytes addons/__pycache__/qrcode.cpython-312.pyc | Bin 0 -> 7111 bytes addons/__pycache__/quote.cpython-312.pyc | Bin 0 -> 23846 bytes addons/__pycache__/quotefancy.cpython-312.pyc | Bin 0 -> 1517 bytes addons/__pycache__/random.cpython-312.pyc | Bin 0 -> 4580 bytes addons/__pycache__/resize.cpython-312.pyc | Bin 0 -> 3854 bytes .../__pycache__/schedulemsg.cpython-312.pyc | Bin 0 -> 3110 bytes addons/__pycache__/search.cpython-312.pyc | Bin 0 -> 11036 bytes addons/__pycache__/searchmsgs.cpython-312.pyc | Bin 0 -> 2195 bytes addons/__pycache__/snips.cpython-312.pyc | Bin 0 -> 7792 bytes addons/__pycache__/song.cpython-312.pyc | Bin 0 -> 4131 bytes addons/__pycache__/spam.cpython-312.pyc | Bin 0 -> 5500 bytes .../__pycache__/specialtools.cpython-312.pyc | Bin 0 -> 19156 bytes addons/__pycache__/speechtool.cpython-312.pyc | Bin 0 -> 4921 bytes addons/__pycache__/spellcheck.cpython-312.pyc | Bin 0 -> 1354 bytes .../__pycache__/stickerspam.cpython-312.pyc | Bin 0 -> 2460 bytes .../__pycache__/stickertools.cpython-312.pyc | Bin 0 -> 15174 bytes addons/__pycache__/sticklet.cpython-312.pyc | Bin 0 -> 4335 bytes addons/__pycache__/tag.cpython-312.pyc | Bin 0 -> 2972 bytes addons/__pycache__/taglogger.cpython-312.pyc | Bin 0 -> 17934 bytes addons/__pycache__/test.cpython-312.pyc | Bin 0 -> 3376 bytes addons/__pycache__/totalmsgs.cpython-312.pyc | Bin 0 -> 1759 bytes addons/__pycache__/truthdare.cpython-312.pyc | Bin 0 -> 1897 bytes addons/__pycache__/twitter.cpython-312.pyc | Bin 0 -> 12167 bytes addons/__pycache__/typing.cpython-312.pyc | Bin 0 -> 3487 bytes addons/__pycache__/unsplash.cpython-312.pyc | Bin 0 -> 2344 bytes .../usernamelogger.cpython-312.pyc | Bin 0 -> 4624 bytes addons/__pycache__/videotools.cpython-312.pyc | Bin 0 -> 9085 bytes addons/__pycache__/waifu.cpython-312.pyc | Bin 0 -> 2843 bytes addons/__pycache__/warn.cpython-312.pyc | Bin 0 -> 10942 bytes addons/__pycache__/weather.cpython-312.pyc | Bin 0 -> 11776 bytes addons/__pycache__/webupload.cpython-312.pyc | Bin 0 -> 3990 bytes addons/__pycache__/whichsong.cpython-312.pyc | Bin 0 -> 2270 bytes addons/__pycache__/whisper.cpython-312.pyc | Bin 0 -> 10515 bytes addons/__pycache__/wikipedia.cpython-312.pyc | Bin 0 -> 1415 bytes addons/__pycache__/words.cpython-312.pyc | Bin 0 -> 6722 bytes addons/__pycache__/wreplace.cpython-312.pyc | Bin 0 -> 2166 bytes addons/__pycache__/writer.cpython-312.pyc | Bin 0 -> 5131 bytes addons/__pycache__/youtube.cpython-312.pyc | Bin 0 -> 3982 bytes addons/__pycache__/ziptools.cpython-312.pyc | Bin 0 -> 9789 bytes addons/activitygen.py | 31 + addons/addons.txt | 18 + addons/afk.py | 165 ++++ addons/animations.py | 46 + addons/anime.py | 45 + addons/animechan.py | 25 + addons/animedb.py | 35 + addons/antiflood.py | 144 ++++ addons/asstcmd.py | 129 +++ addons/astronomy.py | 39 + addons/audiotools.py | 163 ++++ addons/autoban.py | 59 ++ addons/autocorrect.py | 59 ++ addons/autopic.py | 156 ++++ addons/autoprofile.py | 82 ++ addons/beautify.py | 197 +++++ addons/blacklist.py | 109 +++ addons/brainfuck.py | 201 +++++ addons/broadcast.py | 216 +++++ addons/button.py | 54 ++ addons/calculator.py | 153 ++++ addons/channelhacks.py | 224 +++++ addons/chatbot.py | 109 +++ addons/cleanaction.py | 60 ++ addons/clone.py | 143 ++++ addons/compressor.py | 177 ++++ addons/converter.py | 196 +++++ addons/covid.py | 39 + addons/echo.py | 145 ++++ addons/encodedecode.py | 53 ++ addons/extra.py | 85 ++ addons/fakeaction.py | 36 + addons/fastly.py | 84 ++ addons/figlet.py | 506 +++++++++++ addons/filter.py | 140 ++++ addons/findsong.py | 41 + addons/flaticon.py | 45 + addons/fontgen.py | 60 ++ addons/fontsnew.py | 517 ++++++++++++ addons/forcesubscribe.py | 229 +++++ addons/fun.py | 123 +++ addons/gdrive.py | 232 +++++ addons/giftools.py | 128 +++ addons/glitch.py | 42 + addons/globaltools.py | 789 ++++++++++++++++++ addons/greetings.py | 354 ++++++++ addons/hack.py | 134 +++ addons/howto.py | 38 + addons/imagetools.py | 292 +++++++ addons/imdb.py | 27 + addons/inline/__init__.py | 1 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 165 bytes .../__pycache__/ghfeeds.cpython-312.pyc | Bin 0 -> 5107 bytes .../inline/__pycache__/imdb.cpython-312.pyc | Bin 0 -> 13329 bytes addons/inline/__pycache__/koo.cpython-312.pyc | Bin 0 -> 4801 bytes .../__pycache__/npmsearch.cpython-312.pyc | Bin 0 -> 2670 bytes .../__pycache__/omgubuntu.cpython-312.pyc | Bin 0 -> 3549 bytes .../inline/__pycache__/pypi.cpython-312.pyc | Bin 0 -> 13003 bytes .../inline/__pycache__/winget.cpython-312.pyc | Bin 0 -> 2875 bytes .../__pycache__/xdasearch.cpython-312.pyc | Bin 0 -> 3294 bytes addons/inline/ghfeeds.py | 111 +++ addons/inline/imdb.py | 295 +++++++ addons/inline/koo.py | 112 +++ addons/inline/npmsearch.py | 49 ++ addons/inline/omgubuntu.py | 72 ++ addons/inline/pypi.py | 287 +++++++ addons/inline/winget.py | 49 ++ addons/inline/xdasearch.py | 66 ++ addons/inlinefun.py | 136 +++ addons/limited.py | 32 + addons/locks.py | 39 + addons/logo.py | 101 +++ addons/memify.py | 339 ++++++++ addons/misc.py | 140 ++++ addons/morsecode.py | 38 + addons/mute.py | 235 ++++++ addons/ncode.py | 53 ++ addons/nightmode.py | 157 ++++ addons/notes.py | 153 ++++ addons/nsfwfilter.py | 206 +++++ addons/ocr.py | 48 ++ addons/other.py | 75 ++ addons/pdftools.py | 351 ++++++++ addons/pokedex.py | 141 ++++ addons/polls.py | 67 ++ addons/profanityfilter.py | 32 + addons/qrcode.py | 109 +++ addons/quote.py | 450 ++++++++++ addons/quotefancy.py | 35 + addons/random.py | 102 +++ addons/resize.py | 64 ++ addons/schedulemsg.py | 53 ++ addons/search.py | 213 +++++ addons/searchmsgs.py | 52 ++ addons/snips.py | 143 ++++ addons/song.py | 82 ++ addons/spam.py | 96 +++ addons/specialtools.py | 391 +++++++++ addons/speechtool.py | 107 +++ addons/spellcheck.py | 33 + addons/stickerspam.py | 54 ++ addons/stickertools.py | 295 +++++++ addons/sticklet.py | 84 ++ addons/tag.py | 76 ++ addons/taglogger.py | 299 +++++++ addons/test.py | 96 +++ addons/totalmsgs.py | 31 + addons/truthdare.py | 43 + addons/twitter.py | 205 +++++ addons/typing.py | 39 + addons/unsplash.py | 36 + addons/usernamelogger.py | 79 ++ addons/videotools.py | 139 +++ addons/waifu.py | 64 ++ addons/warn.py | 215 +++++ addons/weather.py | 176 ++++ addons/webupload.py | 67 ++ addons/whichsong.py | 41 + addons/whisper.py | 204 +++++ addons/wikipedia.py | 32 + addons/words.py | 115 +++ addons/wreplace.py | 42 + addons/writer.py | 86 ++ addons/youtube.py | 85 ++ addons/ziptools.py | 172 ++++ 236 files changed, 15985 insertions(+) create mode 100644 addons/.gitignore create mode 100644 addons/LICENSE create mode 100644 addons/README.md create mode 100644 addons/__init__.py create mode 100644 addons/__pycache__/__init__.cpython-312.pyc create mode 100644 addons/__pycache__/activitygen.cpython-312.pyc create mode 100644 addons/__pycache__/afk.cpython-312.pyc create mode 100644 addons/__pycache__/animations.cpython-312.pyc create mode 100644 addons/__pycache__/anime.cpython-312.pyc create mode 100644 addons/__pycache__/animechan.cpython-312.pyc create mode 100644 addons/__pycache__/animedb.cpython-312.pyc create mode 100644 addons/__pycache__/antiflood.cpython-312.pyc create mode 100644 addons/__pycache__/asstcmd.cpython-312.pyc create mode 100644 addons/__pycache__/astronomy.cpython-312.pyc create mode 100644 addons/__pycache__/audiotools.cpython-312.pyc create mode 100644 addons/__pycache__/autoban.cpython-312.pyc create mode 100644 addons/__pycache__/autocorrect.cpython-312.pyc create mode 100644 addons/__pycache__/autopic.cpython-312.pyc create mode 100644 addons/__pycache__/autoprofile.cpython-312.pyc create mode 100644 addons/__pycache__/beautify.cpython-312.pyc create mode 100644 addons/__pycache__/blacklist.cpython-312.pyc create mode 100644 addons/__pycache__/brainfuck.cpython-312.pyc create mode 100644 addons/__pycache__/broadcast.cpython-312.pyc create mode 100644 addons/__pycache__/button.cpython-312.pyc create mode 100644 addons/__pycache__/calculator.cpython-312.pyc create mode 100644 addons/__pycache__/channelhacks.cpython-312.pyc create mode 100644 addons/__pycache__/chatbot.cpython-312.pyc create mode 100644 addons/__pycache__/cleanaction.cpython-312.pyc create mode 100644 addons/__pycache__/clone.cpython-312.pyc create mode 100644 addons/__pycache__/compressor.cpython-312.pyc create mode 100644 addons/__pycache__/converter.cpython-312.pyc create mode 100644 addons/__pycache__/covid.cpython-312.pyc create mode 100644 addons/__pycache__/echo.cpython-312.pyc create mode 100644 addons/__pycache__/encodedecode.cpython-312.pyc create mode 100644 addons/__pycache__/extra.cpython-312.pyc create mode 100644 addons/__pycache__/fakeaction.cpython-312.pyc create mode 100644 addons/__pycache__/fastly.cpython-312.pyc create mode 100644 addons/__pycache__/figlet.cpython-312.pyc create mode 100644 addons/__pycache__/filter.cpython-312.pyc create mode 100644 addons/__pycache__/findsong.cpython-312.pyc create mode 100644 addons/__pycache__/flaticon.cpython-312.pyc create mode 100644 addons/__pycache__/fontgen.cpython-312.pyc create mode 100644 addons/__pycache__/fontsnew.cpython-312.pyc create mode 100644 addons/__pycache__/forcesubscribe.cpython-312.pyc create mode 100644 addons/__pycache__/fun.cpython-312.pyc create mode 100644 addons/__pycache__/gdrive.cpython-312.pyc create mode 100644 addons/__pycache__/giftools.cpython-312.pyc create mode 100644 addons/__pycache__/glitch.cpython-312.pyc create mode 100644 addons/__pycache__/globaltools.cpython-312.pyc create mode 100644 addons/__pycache__/greetings.cpython-312.pyc create mode 100644 addons/__pycache__/hack.cpython-312.pyc create mode 100644 addons/__pycache__/howto.cpython-312.pyc create mode 100644 addons/__pycache__/imagetools.cpython-312.pyc create mode 100644 addons/__pycache__/imdb.cpython-312.pyc create mode 100644 addons/__pycache__/inlinefun.cpython-312.pyc create mode 100644 addons/__pycache__/limited.cpython-312.pyc create mode 100644 addons/__pycache__/locks.cpython-312.pyc create mode 100644 addons/__pycache__/logo.cpython-312.pyc create mode 100644 addons/__pycache__/memify.cpython-312.pyc create mode 100644 addons/__pycache__/misc.cpython-312.pyc create mode 100644 addons/__pycache__/morsecode.cpython-312.pyc create mode 100644 addons/__pycache__/mute.cpython-312.pyc create mode 100644 addons/__pycache__/ncode.cpython-312.pyc create mode 100644 addons/__pycache__/nightmode.cpython-312.pyc create mode 100644 addons/__pycache__/notes.cpython-312.pyc create mode 100644 addons/__pycache__/nsfwfilter.cpython-312.pyc create mode 100644 addons/__pycache__/ocr.cpython-312.pyc create mode 100644 addons/__pycache__/other.cpython-312.pyc create mode 100644 addons/__pycache__/pdftools.cpython-312.pyc create mode 100644 addons/__pycache__/pokedex.cpython-312.pyc create mode 100644 addons/__pycache__/polls.cpython-312.pyc create mode 100644 addons/__pycache__/profanityfilter.cpython-312.pyc create mode 100644 addons/__pycache__/qrcode.cpython-312.pyc create mode 100644 addons/__pycache__/quote.cpython-312.pyc create mode 100644 addons/__pycache__/quotefancy.cpython-312.pyc create mode 100644 addons/__pycache__/random.cpython-312.pyc create mode 100644 addons/__pycache__/resize.cpython-312.pyc create mode 100644 addons/__pycache__/schedulemsg.cpython-312.pyc create mode 100644 addons/__pycache__/search.cpython-312.pyc create mode 100644 addons/__pycache__/searchmsgs.cpython-312.pyc create mode 100644 addons/__pycache__/snips.cpython-312.pyc create mode 100644 addons/__pycache__/song.cpython-312.pyc create mode 100644 addons/__pycache__/spam.cpython-312.pyc create mode 100644 addons/__pycache__/specialtools.cpython-312.pyc create mode 100644 addons/__pycache__/speechtool.cpython-312.pyc create mode 100644 addons/__pycache__/spellcheck.cpython-312.pyc create mode 100644 addons/__pycache__/stickerspam.cpython-312.pyc create mode 100644 addons/__pycache__/stickertools.cpython-312.pyc create mode 100644 addons/__pycache__/sticklet.cpython-312.pyc create mode 100644 addons/__pycache__/tag.cpython-312.pyc create mode 100644 addons/__pycache__/taglogger.cpython-312.pyc create mode 100644 addons/__pycache__/test.cpython-312.pyc create mode 100644 addons/__pycache__/totalmsgs.cpython-312.pyc create mode 100644 addons/__pycache__/truthdare.cpython-312.pyc create mode 100644 addons/__pycache__/twitter.cpython-312.pyc create mode 100644 addons/__pycache__/typing.cpython-312.pyc create mode 100644 addons/__pycache__/unsplash.cpython-312.pyc create mode 100644 addons/__pycache__/usernamelogger.cpython-312.pyc create mode 100644 addons/__pycache__/videotools.cpython-312.pyc create mode 100644 addons/__pycache__/waifu.cpython-312.pyc create mode 100644 addons/__pycache__/warn.cpython-312.pyc create mode 100644 addons/__pycache__/weather.cpython-312.pyc create mode 100644 addons/__pycache__/webupload.cpython-312.pyc create mode 100644 addons/__pycache__/whichsong.cpython-312.pyc create mode 100644 addons/__pycache__/whisper.cpython-312.pyc create mode 100644 addons/__pycache__/wikipedia.cpython-312.pyc create mode 100644 addons/__pycache__/words.cpython-312.pyc create mode 100644 addons/__pycache__/wreplace.cpython-312.pyc create mode 100644 addons/__pycache__/writer.cpython-312.pyc create mode 100644 addons/__pycache__/youtube.cpython-312.pyc create mode 100644 addons/__pycache__/ziptools.cpython-312.pyc create mode 100644 addons/activitygen.py create mode 100644 addons/addons.txt create mode 100644 addons/afk.py create mode 100644 addons/animations.py create mode 100644 addons/anime.py create mode 100644 addons/animechan.py create mode 100644 addons/animedb.py create mode 100644 addons/antiflood.py create mode 100644 addons/asstcmd.py create mode 100644 addons/astronomy.py create mode 100644 addons/audiotools.py create mode 100644 addons/autoban.py create mode 100644 addons/autocorrect.py create mode 100644 addons/autopic.py create mode 100644 addons/autoprofile.py create mode 100644 addons/beautify.py create mode 100644 addons/blacklist.py create mode 100644 addons/brainfuck.py create mode 100644 addons/broadcast.py create mode 100644 addons/button.py create mode 100644 addons/calculator.py create mode 100644 addons/channelhacks.py create mode 100644 addons/chatbot.py create mode 100644 addons/cleanaction.py create mode 100644 addons/clone.py create mode 100644 addons/compressor.py create mode 100644 addons/converter.py create mode 100644 addons/covid.py create mode 100644 addons/echo.py create mode 100644 addons/encodedecode.py create mode 100644 addons/extra.py create mode 100644 addons/fakeaction.py create mode 100644 addons/fastly.py create mode 100644 addons/figlet.py create mode 100644 addons/filter.py create mode 100644 addons/findsong.py create mode 100644 addons/flaticon.py create mode 100644 addons/fontgen.py create mode 100644 addons/fontsnew.py create mode 100644 addons/forcesubscribe.py create mode 100644 addons/fun.py create mode 100644 addons/gdrive.py create mode 100644 addons/giftools.py create mode 100644 addons/glitch.py create mode 100644 addons/globaltools.py create mode 100644 addons/greetings.py create mode 100644 addons/hack.py create mode 100644 addons/howto.py create mode 100644 addons/imagetools.py create mode 100644 addons/imdb.py create mode 100644 addons/inline/__init__.py create mode 100644 addons/inline/__pycache__/__init__.cpython-312.pyc create mode 100644 addons/inline/__pycache__/ghfeeds.cpython-312.pyc create mode 100644 addons/inline/__pycache__/imdb.cpython-312.pyc create mode 100644 addons/inline/__pycache__/koo.cpython-312.pyc create mode 100644 addons/inline/__pycache__/npmsearch.cpython-312.pyc create mode 100644 addons/inline/__pycache__/omgubuntu.cpython-312.pyc create mode 100644 addons/inline/__pycache__/pypi.cpython-312.pyc create mode 100644 addons/inline/__pycache__/winget.cpython-312.pyc create mode 100644 addons/inline/__pycache__/xdasearch.cpython-312.pyc create mode 100644 addons/inline/ghfeeds.py create mode 100644 addons/inline/imdb.py create mode 100644 addons/inline/koo.py create mode 100644 addons/inline/npmsearch.py create mode 100644 addons/inline/omgubuntu.py create mode 100644 addons/inline/pypi.py create mode 100644 addons/inline/winget.py create mode 100644 addons/inline/xdasearch.py create mode 100644 addons/inlinefun.py create mode 100644 addons/limited.py create mode 100644 addons/locks.py create mode 100644 addons/logo.py create mode 100644 addons/memify.py create mode 100644 addons/misc.py create mode 100644 addons/morsecode.py create mode 100644 addons/mute.py create mode 100644 addons/ncode.py create mode 100644 addons/nightmode.py create mode 100644 addons/notes.py create mode 100644 addons/nsfwfilter.py create mode 100644 addons/ocr.py create mode 100644 addons/other.py create mode 100644 addons/pdftools.py create mode 100644 addons/pokedex.py create mode 100644 addons/polls.py create mode 100644 addons/profanityfilter.py create mode 100644 addons/qrcode.py create mode 100644 addons/quote.py create mode 100644 addons/quotefancy.py create mode 100644 addons/random.py create mode 100644 addons/resize.py create mode 100644 addons/schedulemsg.py create mode 100644 addons/search.py create mode 100644 addons/searchmsgs.py create mode 100644 addons/snips.py create mode 100644 addons/song.py create mode 100644 addons/spam.py create mode 100644 addons/specialtools.py create mode 100644 addons/speechtool.py create mode 100644 addons/spellcheck.py create mode 100644 addons/stickerspam.py create mode 100644 addons/stickertools.py create mode 100644 addons/sticklet.py create mode 100644 addons/tag.py create mode 100644 addons/taglogger.py create mode 100644 addons/test.py create mode 100644 addons/totalmsgs.py create mode 100644 addons/truthdare.py create mode 100644 addons/twitter.py create mode 100644 addons/typing.py create mode 100644 addons/unsplash.py create mode 100644 addons/usernamelogger.py create mode 100644 addons/videotools.py create mode 100644 addons/waifu.py create mode 100644 addons/warn.py create mode 100644 addons/weather.py create mode 100644 addons/webupload.py create mode 100644 addons/whichsong.py create mode 100644 addons/whisper.py create mode 100644 addons/wikipedia.py create mode 100644 addons/words.py create mode 100644 addons/wreplace.py create mode 100644 addons/writer.py create mode 100644 addons/youtube.py create mode 100644 addons/ziptools.py diff --git a/addons/.gitignore b/addons/.gitignore new file mode 100644 index 0000000..dfacaa7 --- /dev/null +++ b/addons/.gitignore @@ -0,0 +1,3 @@ +.vscode/* +__pycache__ +ignore* \ No newline at end of file diff --git a/addons/LICENSE b/addons/LICENSE new file mode 100644 index 0000000..0ad25db --- /dev/null +++ b/addons/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/addons/README.md b/addons/README.md new file mode 100644 index 0000000..f92e6fb --- /dev/null +++ b/addons/README.md @@ -0,0 +1,46 @@ +#

+

+ +# UltroidAddons +Plugins repository for [@TheUltroid](https://github.com/TeamUltroid/Ultroid). + + +# Contributing +If you want to contribute to this repository (adding your plugins/porting from other bots), use the format given below and create a pull request. +โš ๏ธ First check whether the stuff you push works. Also, if the pull request doesn't follow the below format, it will be closed without prior notice. + +```python +# Credits @username (creator of plugin and who ported) + +# Ported from (if ported else skip) + +# Ported for Ultroid < https://github.com/TeamUltroid/Ultroid > +``` + +Kindly do not **steal** others works without credits.
+ +# Example Plugin + Required Import are Automatically Done. + +This Example Works Everywhere. (e.g. Groups, Personal Chats ...) +```python +@ultroid_cmd(pattern="hoi") +async def hello_world_example(event): + # As telethon is an asyncio based lib, you will have to use `async`/`await` Syntax. + await event.reply("Hello **World**.") +``` + +This Example Works Only In Groups. +```python +@ultroid_cmd(pattern="hoi", groups_only=True,) +async def hello_world_example(event): + await event.reply("Hello **World**.") +``` + +If Your plugin need any additional requirements, it can be added to addons.txt

+ +
+ +> For More Information See [The Pypi Page](https://pypi.org/project/py-Ultroid). + +> Made with ๐Ÿ’• by [@TeamUltroid](https://t.me/TeamUltroid). diff --git a/addons/__init__.py b/addons/__init__.py new file mode 100644 index 0000000..adc471f --- /dev/null +++ b/addons/__init__.py @@ -0,0 +1,11 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + + +from plugins import * + +bot = ultroid_bot diff --git a/addons/__pycache__/__init__.cpython-312.pyc b/addons/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f4500e01333b5018e8cfed97255bb115639e416 GIT binary patch literal 194 zcmX@j%ge<81Tn`0GZYya7#@Q-Fu(+5d=>&SrZc24q%h_%tYu4sXOPNY>iQY^xvBc4Nu_xu zrTU=|Rr-l3DfxND`tk9Zd6^~g@p=W7zc_4i^HWN5QtgUBt^>M@p_m^?d|+l|Wc(t; Qz$o^BO|X%7%Q6rR~1d%gB15sFjQsO=UNHC}4Fj!+|25R_DqN{9+7kZ6QtZ#;v&!Mp3u zt`pgDz)%E5AQ3o_NKh$o3Ti8Hgd6IG1D7>KYP8~j$^~wYg48G{-mbGWP{By^_Pv?! zn|bfew?8V1j9|R>!%MaAc!Yinf@nY-j@@(cSwjTPA%Y24$0j$&nfx4&5r-&G_*=qF zJb)7MU37EcqB)@z%f_2mAe8TYv94aQO;fjsqfRgCMqQt;Q#B{c_qt!Hqv|}OmR2KX3hVHtQS(Sry!%PLR*I@1vSbZL0D7AwY4kJPsg5skxuR$}G zp*^2*Yy5knh*q#0H470gYzQ|XJ%r?l*x^X*C~SX@Nc;xB!gsg@@!*O>A0kD!v1ErQ z31CSB)(x($AoQO+`EOndcuC;N4{rNkX6heI1(>Oan0O(6D9Ho2!$-`2*NagLO`?xJ zh4~iD#BF{FXNNAePnKt?MVamzR#nw4bvk=*%@LMnkt;r+p0eUp%y+UZz)@2FP=8qS#)Fu`Q<% zWnZOMzR~g%VJ`wzvo!D@f$97N=6AH$MZb=u*Aky3yv)--k4)W_r@9w@8GUS9Dt`Oq zpFEe2-ACMTtUKF}p=4(L^oG{UxYy}WvEE1ubw65g=7ab$Ds z%M+ej^puI7G;tkAkg2UWoC=WKX7wAZmw(pFJ@>utDHnUv#RsU#t@xvWy8h;Rb)(ul zp7)LwHm`b0u_qM)Br6|}e=xpU{P2mpLb@lU`$tgnnY}&-8SeE*kvO*ROh8%hq-W0J zH9VsU>!aY^!ZT-t+tZWa-Z_P5^1_|RV}XAL2R0wrOIgv6mrBI0luAAdpMwRR4%_uL z+65P}Q84?`Q>IOtbvnf|5C*@yGY+QDV~lr3L@eANLRj00Ax>F+bqgQg;Zk^Pmq*-* J&||@$@fWhMT0Z~) literal 0 HcmV?d00001 diff --git a/addons/__pycache__/afk.cpython-312.pyc b/addons/__pycache__/afk.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2ca0ab1838dddbd619ce6f34364ca3bceca0590 GIT binary patch literal 8993 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/animations.cpython-312.pyc b/addons/__pycache__/animations.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1f8ff80bb7863883cd7be7df7eec5a42988deac GIT binary patch literal 73638 zcmeI)Piz!b9KiASc6YYRwp|pcLZD^&m#|8=1PGXDs;iigfFLNE5M_7hOxuC|)6C95 zT3WNViZnq>G}4-wfG9*$xp^QFVmNv5V6h}68xEv3Mow)h8q$+*wtr|z^xVYnFFU_| z^Zv}d_nA4q%rBLdVWHxkpZ7QKtCnKKJDCapbYWtTD)b6N91?~!d}(<|`h@8-{ND%q zI-Qz5Yivn{!}q)!?`_k(ru8vdENjsn$F#Ez z(~~RBE2wgpIwl^dv|C7TL9#U@M=uz+Pk43wj!F&8#QndSzE_$rHI&BZMYlgo~ zU2BCp`}fgjUJ8g-u|u5MqmGU0D8J%AA!EV4O^v1a<3-zB=e-J*+LotmQ#V?pPA+O# zX4G&EGwwwyR^cvJ9Y(KR9=+Z@|M%(W^$*>(s&V5;p)h*=(%q{+{HnTm|FO}lKaO;L zH2nG5->(*GYwO(yaUp6|)F02dZSSR%dUuJK*$-d;{Kms0h0epVk*-hNCsg&u z(VxB^>AI$JEV}d6#7@^zm8my%yUBD+BkJZ&J9^AYr&ak#Yjl^X8~Ns(Gj_i3bo{?l z+>2B=IvuHXZ|FwyfT=e)`Q*OF#=FObDVTh>cz#6Y8sk#J71JmKByKo zHId0!U2`sD*11RAtmD=lOgnbYGU{~0$Yt|&vqSUome!(7+Me7}b>!bu=}+;nAnvYM zH4u2}&axGKYx)j+wx{sg?a0y|tJ@k_zGX17btts8kht%QJRL0T8>Ztrd$lKfE2Poy>1lQ|MfmcuroDi7kQ48&v5=xlC*e-l(YY%FoEe_TY_YLtc5C z^zwEuxA_}e);CBscqaU+(4~%vmsQ#=r05mx;^^ES(>)E@KV91;3~^G8JLl{5pVBln zrd8|^XS6H+6Ef!8>xR{cvGd+GVODCX3R{dsm3sPpWK3X3{2A$S+rE ziZoo_v!Q##*^0q%^-!Stw?Oq|zCty2R;`x3vO3TgTrJg`QkF~_xrSuY4ym?cxjXgf zk_{Q7^q5Ll|4vM(Mp3%mWax!V&T!Lay}d%!dGp98R2uV3DaR{9GBB}B$i?G9;j29R n_AOaG?yHjV3BT~wjCrN;&0fR7TXN;NPs$pvVO6PQdo%wBIuT<& literal 0 HcmV?d00001 diff --git a/addons/__pycache__/anime.cpython-312.pyc b/addons/__pycache__/anime.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06a59245ba7bce9459336526e041750b18c1ecb6 GIT binary patch literal 2456 zcmZ`*&2JmW6`$D;a=Bb-sSo-~k+k}-Vp3mD+FG$@H)ArU0TT3K0z;<`S!Dg0elSumj{za0=Kh&@4c^~uMym{Eax3!4~#xMT*-pW%Rp?^@uA8ZTkyaC`I($RIKW1UIi>sV)XF2#J! zV8kGU)%gd3`*=@U5B?h6Zz*2qR+*TP(|{F!_;OR3wbE%VqdUsQPc$>7-AEbAxG4Tm z{FAbD*IY}iXttJc4O_Wz05e+Jcxy>i6lLCU6Dx|AG1G=}u&)~~m~tk>=hWxb=kydY zOmI9e9|-;Y%tSl}tHG@1g8fXQbyli^0`Pqb-_9=~-ggj&NDC-=Sb|EyaQ%Eh7W`=a z`BTWwUD*GExySy7=g}Gl8{D4WVVVpc=Jv48_*T}K0^=NWL%vL*ndb-m{g&sKyhSs=^783#}71o zRN(g`2^0c)xG5XdCBSVI{~qb>faMmBe8sN`z;{qy@4PjIklj`g^e%r5 z6#DFA_%40T-o`QID&Z4WT7Au?6`dbln#<7l?yeXLedvmHQ_&7RZr8GuY|79aV_@ky zbSL_)7-%Ng%DIR8uD*Gp#Kf zYR*pO*?9aT!cpIO=HoMjZLY=QaU#++^_G@Nnnbv)WwngqfQ<4H$cY4tB$P1|x2TYl zXU3F#rx=f4^;hC?Wm;LvGfN`jwHsE>B`Dtx0v9Qc$EOulC5)=h#~8xhG*bp?ziHVC zL)EQBE^TDoSSMi(%O>Ko;i`^no0(f=Lq&nq4J)6A=C~ zjdG zjg;XUu`uC{PvC%rxpQal4pf=~o4x>o9fGyiYSOVXgw2`>!ls>N64_5yD;%3vniB>B zo!uY1!;>pk+L+AU$YtEz6K$IO#q|ypd_d>LP3Wk~%YtXm< zg?=oe@8#}|)za#hrz)3fC&y~?cs(>;oM}X&^~jJH8LCHOUL>|PP>YNe7rqO3KWpzO z4_1%O{%zoC`(j;KtO|?Iq^^xCr7Lx*-;?@l(m-);n_>A`+>kmp7E6npJr%Pion6P< z0TdF~VK(Q4P&)@)Ti>j`H|?Ds-= z-7SUJSt{Q1B-q>N>Hov|-<=0@cfHeZ)_N{fg%hA%?HI25*5zqWmK z|Eh0(99QsMjQiv3fWGa*b7S1M-GdZQb=3>e2jY}9jAB*&yRACh65Cj zVM-?_=117ay?9;;JnrKu9->;0Ph*NlIEqK9WQ-?4mA*+;wfn%o9R)(d&`)Sts)@AT zth+y>9au;9Pk`(S7t)rVOBrw3=Ygd^5zZJ82ngdB5gv0p?Fh^NMDmLOV%n@$;HgwH=-v zvSzJRF@!dOv`ipc302yWX$*BYj0#@Gw zf=$fB%;SuR2H4hK16Q!k%h>prbcuZ;%dkKa;O`v-@ZDzdpu+f<%lcf(<$20u&*0uy zz~d`yfz30nU@g(FsfY*qcyL8-CjpQ{X5>ili8RmtJ|Tq&x2|Pu+a+-bkT)sQ9&59bIkReQEW%?^$>M$$QF4 zq+|{*ox5>v`PAq7MtZcXjP}xy7}@DbD7w>AVd&^z4+akW0Yolsrqb6hUc1=MoVcGF z+fc^tD`P!|^}oF;y8S3Kks(W@d`w!F5UmWAkHZ~O&Pw0DjA-pJDd(lN=UIr4QY5Tp zNr>}NK0Y!r%+?cRVlcL@${|jNob`Pq#KR2nWKIs^y3Sn_#|a|*JEECHXLbv=@fpN^ zOplaTZI?G^t=B|&=ffY*%VI*Wglwr2ksb~L$#2DgCOeg%h_*#lQrc!f4@XEmjpTm- D55Oox literal 0 HcmV?d00001 diff --git a/addons/__pycache__/animedb.cpython-312.pyc b/addons/__pycache__/animedb.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23c50a14760d0cc60282a98c97ff36e5fda9b7dd GIT binary patch literal 1680 zcmZux&rcgy5PolWy=(lN1Op~O7TQ#pNT!D-Myl&Ha+<0_f~F*Df+DRKzYSip-le;1 z2o9)L6ICEpN>QaaYE!l9DHX|o&;!Jgdg#TJgRNB$ReNb}rbH@5J#=<$S1ItM8PA*j zX5RPa&G;w3--BRX|M60Go<`_*d(&F5ch>If@KZtrO(B8_rQjzNMii1LLO*8KaRWqL zchP#oL{s!48|CtMVe6TcL_L$`MODs82K*2{C#o|de?!-DwpWo2GnUc#ydkSI{M!zW zObgSR>GAyb@ByFFau7fa{`|ZsE8?^wfxq}2pS~?GH!>w|N{b7cPLgR459_kV&q!wT z6j{BYd7j%8qu9d31#ctd+)!*d3Lb7wG)+lYGtEml{8`X(h2k=|p6y*foW6%#k% z9=EMCjqe9JU<6eNAC7G`*g^axilfhd09gT<1{nnLy@JfnR*qMZ-sfaJsoS{C}!@9WyUOe9|9#~MA! zn;LI86OgvNFZFhTN#v6JbDQ1ei&5Hg>(ZRED43eX8nPm(rsd8;B4J(@3!Uk4jsHM0 z@``Ej7qvW$kbP#uI1+}Mk2Clu^C0Sllf#-kyT0fC@<-Y zmJ7U@n--VJil!hFE7&?*$Qd)X!z~+vHthGbhj9P3k*t=JM)K2n)y$7vQA}Nv$%sgZrWzy7Ld52Pi!+dVFT}Nj82h09 zKzl`0ccb=>61T=xx})2n;i_l2n5qTZtAUeSfs@t1sja}NZ^iAvQ1RUw7bt#Q3wM{U zu3fG4zqK7sR)fikJ6WeZuF+aoPpPn0sCLD+x?+!(H<*nNH{Pox$G5vCs_hdiY%S37 z`K49)p0=vhe8GETt7DL<8XnpT57kcef0Ot!vG&HJE46T>-iCtxyT}#v{DoX?p1Pxa zs54TUTATXfdNnvuaSzlZ$a{LP&Z5w{yS3Oac7a_E;#4nF4$-!KoPvOIC$@FBjV$*#y4TVDeHR$I{3cE%*>b`K_A_kb zpV8R185-mNqrEu_MfG3 n8Wda$;~h7LnHL=hhjv&*`D?z&3!0*+9X5zZce$3O4*>pOl5&?Q literal 0 HcmV?d00001 diff --git a/addons/__pycache__/antiflood.cpython-312.pyc b/addons/__pycache__/antiflood.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdacc747fa6f06665d772e7b67d737ac53a1e379 GIT binary patch literal 7732 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 DFqbAp literal 0 HcmV?d00001 diff --git a/addons/__pycache__/asstcmd.cpython-312.pyc b/addons/__pycache__/asstcmd.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa34f2a4914ae2e75c232e9df1b03d2d3f9eb559 GIT binary patch literal 7246 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 BY9#;w literal 0 HcmV?d00001 diff --git a/addons/__pycache__/astronomy.cpython-312.pyc b/addons/__pycache__/astronomy.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d23a8618c4f1270ce34e9c51d618e1ec1be4f85a GIT binary patch literal 1818 zcmZux-ER{|5Z}GK_4iktK!F5$icMmtjolVfP)aKqJ4F=|DoRmBRMlL(m&D;dtotBw zu&bz`)}=@!3L=)ugViUhP>Fw`BvK#xf*Yztt2`k3(DD|VRs!0G?mBS-v?J}_Z)Rs^ zXXa-1C%@kVD1Gwd>9H;WfL|HYBz_BQ9H(F&U@!zQ#GC?EZit5f^H@*>6%8TPG30=N z12V$swqpTq+F|Equ(0J~$XRs7-S!}5Jr8eI#k8)fl7>w&bwSE2(y$_ny&liQ>2Jkz z7xQJQpyPArJR+qNvL&WW%g{AlEs7uJbCzw$qCO&Kq@p-n6i=lFQ=UicmN+E-TUR$B|d7RCum;@xVsO7SzEE%~m*_cA?t|+y279`7(4K247J#z`1 zbX}rr19JeJ1dvq$mZ7z+Q-aNGFVXs3q!qit>O%1j?M%tREob2}rfxrK_E4?tV@)R(4pdzzr$^t9=`9cm4}m(5bp1uq=)M1ajP2c8}vT z$Kcj?0ygjao}Ym6mQz#hW0qAg`;$r5nh8xZrNpRyp}{4myknNCBnpyYvgWm|k=~=M z@kb0@&B|I%$9Zj(@OgFAVE>fxrjaAC@TkE+4}szoVq+!dFVkL};uDDk;j&rkLKw*_ zay($Lq7ZJ_B(9OXhO?5Q5YGo1mL~@cLpO+E$&(gw8gfCAaxy_?LCIT$S7ePKCM*(O zw=LqpvLahDaSu%9zbLAnh!&wP$X=U&2giP8n@DACh3s=4xUVd2j19p zW-ZWB{b)JRx#H@aPOZ5-l{YKutt0ncho)2OTo6UqIl=wPYPfa2XSSz$W;q@=z&|I(v>!Hq-P$PCH&C&^?yvGcd)rsr_Ew|SLo+992kUL!m4Vez+l)Qyt6KF? zgc=8e*G9h@osnyi%II>SYsJ-d&(*c+^R(u_GU&lHRd@bwyfjjc_ zPag>F`vX9h#qKNVb)KSU>jB{Ie)7QA@pR4GMh{VRZP%V^%guBRe)Im^rz^q8y&TOH|c@Pm+gJADk??T6{3!rgZw6fYit>3(7H zRe|9MPc;|2z3D!F@hy%?4nv0f8mH8XN{+cRz5Ei|lZo+5`(Z|OEFBOS?u1MpLDa)i z3^Clxyq$`>h%=kTdM=wK{IGf0V2`K4-T*?!m0{MZjsN`}*q{&?2kG|AbxhT$6PCnZt#FR&_D*${};%TtxW&` literal 0 HcmV?d00001 diff --git a/addons/__pycache__/audiotools.cpython-312.pyc b/addons/__pycache__/audiotools.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..386153765a89f75176d667b40389dd3ad1bbe508 GIT binary patch literal 9701 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/autoban.cpython-312.pyc b/addons/__pycache__/autoban.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a8861756e38e8f33fafd0fa6937581fb3a78203 GIT binary patch literal 3395 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/autopic.cpython-312.pyc b/addons/__pycache__/autopic.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dbf53bfe2a947eb9eef1a079029e952ea3f2e129 GIT binary patch literal 8630 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/blacklist.cpython-312.pyc b/addons/__pycache__/blacklist.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32f2a5e0ceb93ba0ee016241f9a9569bd5eb24a5 GIT binary patch literal 5913 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/button.cpython-312.pyc b/addons/__pycache__/button.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3527bf170c186cd30c9df56f66ef98c8624b616a GIT binary patch literal 2591 zcmb_e>u(#!5#PNB-@Kzp%9N5wVl1-~X@znSr%Z#|fUTE}HbRpis6`lMDBejr`5wgH z(t4CM)VdGKbs?rjW4lFR6$ntLc7Xf|ft}g~3KUiufb>BDTBJqlZ*r8Pwm)_Es1s8| z{?-FH`4*`+6RF~$?x^3)MJ(@S`)qGhW;eq5KcK)ni3uFUYFdNi_ ztYFK%s;GssAv=a3`EK}~C{o}@;QCHV*^VVH8N5&9C!yt;m2qxPR*ROO(%f_jV?)1B zZ6}G^Un;6bUdqiVs!Z5WF<&^7n>Mg5$SG2iv4RC8=dql_YHk|qmOve9=IoBABxms_ zCP%;hhUKFQ6C*{RwY-`vDS1VoF-QazBSVpL1x+Fmyr!Yac#aymTDcIRyO_sVMtWhV zX!c1+$-#N@+x`nF_O}3}Wrn8-uD}XYVas6NHv3;vgJ?g|IIrg`N~b*MNrAsl^zSm4 z*q`t`sBmR&p8Ja74n%>ypUPjh?XL7mv^i1xN{URH%EGw9_qGw*lo+iUycpaaB9 zu&r^>Q_sO;(XlD>yRo4D>oU25X9fX4D|_cPA9D7!*ZFW8J4oWrj1n&gNPRmUS$oAX z2TQxrCD#r2b*3eMvhHt!|Ihhww-a~%83(o3b|oOtJ8_Sr*}D?$s(Ar9*!9CN>td2tL#F4Jg}>GIr@qVCwHZw%$8xH+G+9||A1Y9$-rciot&H`(}gW61&f_k zW-R`!BFTmV!pp$o3x<|Ee4i)b$avteqREKfBf@yJ{GwS@6}&v0N_|I_^QIi1RnE$B zI#}XZUc_-lj~5Jtb#Ce3x1qIJpf@Cb{_T;n;ET%MLc_gDy(qtW5oT)6!7Aun^ zXpdWrVOlOEYsOg_xv7A+Phj~@>XN)Th7d8N-x@?G2=Y)OP&1b#t1_08Zi|=C636H{ zDrFZ+7(Gi7vw$r|QZ0AuOr}Yl$6L?i#PA%c$Z%=8q~p@?TdgTPoR=g+H-}pr(#0i< zqY$OZM%uvUdt?Ov3p`u_e~S%laM6{q>Pt1Q=??t#-1&3ONLM40+K8m;k)cL#sLC|` z!L`hVOf%AXDf3RII!gIhF1)fCe)jV5t0%6UsD~5Pk$Zlj_R^)J?;KrEe-e4I8S8Gu z1~+1Z^;oLWk*XfwjP9$UUyiSiHG`qr#D(uQ#g4Vb)y0Mw-w@*sF|i>gu8DsYGtHj; zSEsH_y|?_~Kz-oVk2)?-)q6%7v5~u>k*E2rj%@~nwUetSYtuh}?H|zt>u>!2)bCE! zqv`6{7USZDrWjpYUR`d8eH&umwT`=DUtK(S?bwExu5w=nKxhB@;d*rN2d}M+RtN66 zh0So^y1O18thzUSk=oeh!|R>b+;!if26yN#cc|$T*M?SyewJ=Q@VBZ&jQObD*?v`xm#be@ew$l;%*&%mB>H-M&I}l_+!@)!M8a$@jQ2%r#82rgA@JS?H(7! z2}tRnO;a`<8kp#1??m9lKG&TnPjNR#Z0__xihFI`Pc4&S3n2Odw%oZKX^C78^%D-! zZziJS(-JVf)^moQE@4GATP+bOF74dW^o(w%v0)I6-3oS7*zG}^$?io&Ka9k`qN|E7 z+s$HM;rGEdQ2_J;A&))Z)C{Sl%16=H2}}Q4n8yj(Vj+b84gnbZyDwZjQujT-;{FVH s{|Wj&1qVL|M?MFcI>>wqdLOt*^=qd-fxQoyUf8|O0;bPK=w;&OzXOj;bN~PV literal 0 HcmV?d00001 diff --git a/addons/__pycache__/calculator.cpython-312.pyc b/addons/__pycache__/calculator.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73b71032b04d0c565e5beeb079e84dfd0d4be18a GIT binary patch literal 6973 zcmcgRZBSd+mG{1PpFW<1#D~Bbuz?sHq}T?GZEWnA2sw^7*w~)9Nki+=D0fql>;<7KHvt3tBQ|kL0)D6zRNWTO;E~Y5U{N&jNU}{g*AW;y zf%+{l(h6UxXb}kfjQ_yygicUGn@aqqk||%hLozgTQk98igUws{K-+RCn1zx&X9HNH zqplV&=;tk3jbQzIbSF!=zXEtR2zsG(zD$!!C@*NYLAwqcBt zP4ue@+sBEQ!Ri{0A^VO8bWiPAF${>Z+b0G_6f1>puP5Lg4S3|B^nkL_XV)vbo>5s2 z4lBeH3dxEAdIVnac&{ov9U77)|L}mq`-j~l9$6NpVTBzPdKA-WK$e1j!R;LqZrc>b z=~A%ka~4Sc`}Ca++^pbE1s_%Lu?_r`f)6S9u!4^$c)x<%6?{;^9SXjtFl}uLZri{I zKBszc?_U){*}IJuB6wua1GH?|bll_H(H1 zMHrM_&b1F_RgHGkl2EX@VKkUk9Ich+gSx^}2A5i(uknlZvUbo={z%DYt=~MWsm1r; z2!017`XMvNexKve3uv3Ut=iapE|+TfV7Z3n^Fdo4*D#PVEBV%WCvX@GgdVQJ9a`^v z4m?%oOByC{0ynR_L-zyHR*INPQk!WjgxVqbV*hc}iKcJBcLu&j_)I@x$FN=BCp`fK z6dm1fcROf={uNb8LlWKOOLj)lh5P|=81&WW7ex1KevjQE(G5`af*5dL6~|$4z)yP+ z_bWkJ;UsY+FfP%3Q`i6~y4gP*@DGdbS4Tx@T+-8eW=K>Fqajdo4`3XOhhw1k`aH7R zFDN=7EXpFxjYUN-i6J-wp%7i%hK3D$t1mbtwvN6sIxLU2ej{@@T0Mdg91gWoDKdxd zz{t45`Dt0|hJgp*3*7?n7xZuv{fX$`=zYC6s#_*IR`iB9uDyQkjfoo*E0tAqFU`L6 zZhyj%+SUH^j_6CN%I>taJ89@%u~p8UnLU%X*_Ukg`KF&fdHcz&!1vS?$(k>+cb_?lSztz$QjB`z(VO7b-+-kB!OByq0rrkR#V%MToBVp}4%H9abQ z20vV}xE`($Cw#Vz&>7(IhSTb*!ylAkmyLW-ejM<-CD>I(?pj(XegwO!$=%K!fZwxV zR}Hym)ls|(Q&_FS8VWDL`Q?IR!=kk5^wN{2p5A{1By)N}n*iUM2D92%STA6iDu$X0 zPG9cy!s*M70)o-JxoT{6oPa!V4f%{-KPzEB4*JO$Aq@AN`>JJE_r06}8 z?DqylRpF$=(5mP>!=W)zvNO^ND5?sc)gI|2ZO3luImnN~7wQ6_>cl4|^USfxv9zgf z$y676ao(};&6MNheKu*TOPS72p33fB^i=dnimyqNn%|R}jS#&XZaA^igg;=h(?~ub zI>4{fyWQJzz+vCC@CN9tF8pc0zWTyzmTNG#0YERCw1clMdTukcR=9ZR+*{HFBcKTu zt|sPc3oO&Hta>)I(_qP#u22l;ycemmpl6Y*Gv8CarpmrZORmuB1XhzuuGH!Vt28X1 z7mOg<2=#)@UbzE!UccS-i_tg&DGjQWrwVxgTS`f9_bo{>evUldmmi62eTFdYPsgDMSr*1{0}6FTIlPfwY{xPqUyeZTP11;6zq_|F#vB% z>Vr&bpx_(@R5*#+>+43R>S{G~HRRq4yw~IPiEi0XJ$ny0X7DfwU2z{(NMCSRv{xuR zeRH~pJhIoPa060sbcA~R-k<>e)i;8or%wa=5+E+;S(n1X`&eN|f+GqM1;3o}^r(}g z=rT_W>9krH9RbRs!opKpF^I!LXv{DBV9aZtfWln~1U<4+(&Gt<&tCJ2BeFj@Y}aKx zL{(ZsCzW2Nl-S@XOgKC`6r!^f2^)-D-qW6qRu zciOOb$*?zNXqj}bfM?km>740~bW=CdGU=a(mirUozW)E3mXbmM#Cm2n{! zPFC+*Ht)~T)v8mq`%>lm)8_q4=KTePg*SJ88N(_CPi#C{ZC^G!HWP;GcTT3t9ci;; z$?PbgyJg+BW%zGLcg0#h6OM$Fb%&R&M^>tK#`eSxMtxCs73L1TWuJ1bFP?sSCQEx^`>mxjbcbI{SwR1GFBx|K zsX)VuNd$X%@#a{}x@>M)*;#X|`eyZy_r$#k=RXbn^S;#1)^tT{(%iagFwdAGrs$qk1(eu7cWjmWLJ-b|bc8#OGH$b(F^$&r#t?l6_hTR*X z|A13?qo?&kBfi^?`%aL%2b~5e-0Q-9-Q?bJXA=}YtjFgW@?nFs844e9_&i5G(y4`C zJcZ92$S?M(g3nZBT!I7rszS?(cTiL*X}1 z;|sgUZ%!Ts{I^H&g?jSaP94R&F~Hw3D&$mXP@zeM77XNmS9%lMNEX-8R8IJ~|g> zz(HmxgivuVdIq85dIC=j7@d1?$~1bTCe=lPKyfB$3?+_+jdLa4rjkBi+8Q*TAYoE8 z#`pMmqCqg`InBotR40nA%$6kQ97TcGOmCRXn;!RM%m#UxF&a7JRby-JlPDoIq9Cbu zwV4)G1H6}FPf|c_revpp1};?7Yu8KEl1SeMppbwcqGIfIKiECb$OsrJ>07jsM$Ew0 z(wK#UhcYIZlOgscs9}u|-GySN=(|uKS^%J$qEAVsQ8(#a+lNkee{Akv#M3X%T#j6h zd15alni8)jyb1o}l8&Ugd-7QTtGs186g_;iBGw+OnC*&<#xKS%C2;)G&F>_hU1(fr zTDZ8-bh~%4a`Dwg`TfR4`De8$>$55TG#D`mqCNlm^Ka|sN@h!9-h_U+v@L0EUnU1> zsAO+s@7p!8GpVxXL}+Snitk91jwRCZ=uLy>VWAR#-4WkgC}|%p?V*#x+~Ni6lP-G&ZQ(bMT9TLn9FBv}1MULsb9TRHMIPI589yMg!tWX#^^1 zL+D9>Yb?h2^KyiD{2O1MtY}K{&6D~+BIBP?UmEo-p}tS_#z_ME!7-B<_M_|g$A;qz z&Z%8fRWrLHyJC&8inx$yPwa_5|FN<4_lDz>+#hs&q+@Dy_J!!H(HA1uV~68qaa-IO zx7|FR;1ZsMuuzr|ZkraqvDm(NXwkEH=wH5-GC5Pao=J8Ev2XCN^Hb-hPS2c+oQv&= zKeue&mo)8PMhDh)aN9;-T*h_lj1E_R#v*3d8pYPj5o4Y@9cx;~_3I3SYiU!%8pYOm z#PCy&sV8O}5l6H?#Wy6#GTy(=oWS+8*MT*Pt$!E(t>LFyvJ`6YA(g^91K6WahZtl$ Nq3Z2V>s<%P{{le4lllMv literal 0 HcmV?d00001 diff --git a/addons/__pycache__/channelhacks.cpython-312.pyc b/addons/__pycache__/channelhacks.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4a5995cb7a26a744e3b7094f7a5edd38d05eee3 GIT binary patch literal 13911 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 CD;8M* literal 0 HcmV?d00001 diff --git a/addons/__pycache__/cleanaction.cpython-312.pyc b/addons/__pycache__/cleanaction.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..735c8b9b89155a3a6fe932bea1a288c60d914a94 GIT binary patch literal 3245 zcmcIm+iw$R7XQAvdu%680wfS%a~B2@6QBxVt3`G;Rn@G}wiKzj-CD*oOB{R&GZTne zdlfEPh=df=R!yYcO3^-nV72=X^y0kqp)X0DD(NT>yV{kuysR7$5=8s3=gfF)6M|@0 zVx&29=A84L?{a?MIp-U%S0?a$@b%lH(*hy?#2@G3%gm$y05eMzqR<3M(lDijAu3gv zd(^fFGYYG42{y@vIf`~X*zsXLDTIZj7#5RKSW3FWE^C~q2#R=Ly2sdK71woguRKv$ z2EU>r-*-En70+{8Z;iIDR;$!sCt){uaE-N;9oBqQ)JS8yYD8t$ncZ0tB^jT;;Q{W= zPfh8ZYD7lW#JK508i^&;Xet^r;_1`_bO0tkG*ROEcp{pKq@qdH&zmyJbVG}$&YA3l z5;ENr2}4WAl}Ie9n1XsyO&NMscs6ZZc10D%^4|5XpE1Sps9~sD%5+DSWIUxu(y2ry zRz7fRj0hj zyv}ervMK-^ztfj1ea2xzA?53eEZefprd=~|J*`=vT8{~efVQjaCwDf8q z-4Afw0@6PLju`1p&vS6x0`P{{8C1PA3VWY>2^@I~iu_5f9)_2}cUZ%?YfV7P$kVo? zV25P_$D6*WYCBQVj0Cr2*9{vF&j0~Rk)7Kv{vSZd zQ7x=6IVMYgNq%#jkR0nGhEvQ41RK3?dd4bQt*XdYGDjs_uy$T^GD?oiGFkSIMB%a= zQ2sOSG6Xuu+4z14GG5fHn;AY|$hR z1Dc}Qa3x_mHyBp;pQ^Oxq%E;h6;dD^FgB{w)IdB~1tOr3N6AHO&A z`$cKbi-3+<(M|ThL7%QQwLK&hXYH6jR%|)=5np2AcLQef?R~O}7veqG!PTFI2I-$W zL#<4Kr=gv4L6DHIYX@;5Ktr!_g+radFEr860JpG>M}8*-n}ybGp~L(_fI&$=MgA~{ z`~U^|%vHkjZnX)21LhU93Avn#3v8`EPYmx$f4X@|l12)z0`KrH;MZB;cr zH*!~UbL^7X3fOTqtTr~!9=v_<!FKCeGzT|)_unY(x$jFPXU=v&LS&~MId=m@Wlm0rb6UJ-MKS47Q zi74qezW5cZqGI5*dxAl!U68@(^?+ zL91!KOCEumSf{fgy`D@f6AASf+91fVdDK4w0=uE~v5(N^f5?rCO;GfEro_hrp$Gp> zPJBmBtP6zk=HI`gEYl_gnRcu*vaRSW sA@^{XKpRSpgtkn%S4i^`X`b^e_6*GbcBN-vsb`?rGx!}juHni44;{^u0{{R3 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/clone.cpython-312.pyc b/addons/__pycache__/clone.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6cae2f917a7aabcec5a0df6460697dabe9c39769 GIT binary patch literal 8871 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 Wt8P+uyqUD{D+<@zj;n+*F!6uw^J3rt literal 0 HcmV?d00001 diff --git a/addons/__pycache__/compressor.cpython-312.pyc b/addons/__pycache__/compressor.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1fbc1ef70f8ccfe5aff88f2fd90a81365104b05 GIT binary patch literal 9574 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/converter.cpython-312.pyc b/addons/__pycache__/converter.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bec303245f57eb64db0df9c96bad23cf600f263a GIT binary patch literal 11104 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 c0;XVP4*z6s94!#hi2FqKF|l9D2xy&Q?fBO`HH zY!QTqvmc6AV>5Cxnv!I(LzSv z8ZJ*_AJG+@dqmgd!}loAzYa%s6-K|sEVA$L zJepxL%(!KbGrSV}{(3!k)Bd@YYS7#MJeI_iXTCT40LtKT$378kIbw!YE6Voq$}-w{ zW_CQe3^(rDv6PXtYEK+UC1iChmK>$E*sWJ+YwNJaN0ewRHhs|V?+gSCy(A7oO^Pr0{o?Sp zXIKzQ#@^82`OqL$3&Y!Z*e7TXqnyHth#DQ!_)(HdPiU5y64t9;s~VNn5)2#FuW_{8 zHC9d$%~UE*%`_5G&WSoWmT!heI^ad8ebZn8HKo!DOF=+0FY2I!3yceB#PU| z+s0shZRwG8QcbsoN}oVmM3PcTrL8n*X~@=zDUH_^qz1wdKvz~k{DdCQqVMdE`QEwS zg1sSUZ}^}gZ*QFKzHh5s=vy3mf2ink7hFekuA_O^v4Z2+4W?*w%(uVWUUYjGdv5mJ z=)P~SGCV!r#n8=Awx%QR=`2)qW-XmXp<=#yu6bcHFVxQlA6P32*6N(Kdg(~sS~vSr zQLxYZ=6nl1dEwA(uqfE(o93Fb&-j;5EkBoi{+0D3>z?&Uw(@*l=qqr2Ij(P`3ORj` zH!P?!KqcRgx0O?{iff(02K+e=)^IB*0B|LMgSFhsnX_JaS@qyxJ-6yLQCy3utfz9? zZZL|@68lrbi_HJjK#A#}P=giy2grdf5vf5AcYqkelpKyA)eUu`w?;%x%$S}+K4z7E z8hXn-xi6>T{SPz*RDX-3nc5K#7so}Q@fp)wrYYk&i6_w&_9B|ZIw@KHnv}Zqs}D$t z(3_%6NhR%WN+R@PAXe&Q_xrp1`+NI!uJYLl{X-y>>xrET%HhOG1!ZeOiJDY_(5a?W z^n`M=X6?Qbl_%6#DygxGN_=KQcZqnY@KQlHgB+xy8ia-?6go$pdqj~uOAVAxba51b zvI*i}<&+JE=UW~)Tm?sM&QZG*%{vYQML8?yV{@@3bKWW5V2jR*d3jFGdRv#%%cI#- zudPSdL)rd;ta~u;3>7S)oF%m3+QlpavR=TyJg~WcMwo9g!WYhcJg{8#(S@A*c;4Au zurz;bY5sMC1&801H(}M+I=kv92OXju1dwu29dM8b@E4x5ICvPXdT~(XRu6C#*DzpM zt;1A`y7jQNtA<@YE_Qj@H5=}7n%3+*#Z^4`ta*8`uGO%BeY|E4how|B94?(JBJ}4& zKZQ@w7C@w*&9W8u;_xN(!Q c;eNcuBBp6Whnt6XOitXQTQ(U$q!EVt9VuT+BLDyZ literal 0 HcmV?d00001 diff --git a/addons/__pycache__/extra.cpython-312.pyc b/addons/__pycache__/extra.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d38837ca9931e2e82705e13c5ecb45bae855bee2 GIT binary patch literal 4233 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/fakeaction.cpython-312.pyc b/addons/__pycache__/fakeaction.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d15ccba6dca95b6e27ea4a44820323a738ef84fc GIT binary patch literal 1969 zcmb7FO>7%Q6rS1j{&?*qZkkdhB|mB!?zNE5COl!B!-Yi}3CI$RYFw!f=K@Dh5OU7RB(S z_n8R}&!#BsGw;Fhtghq#!T2;^*Et^({t9vg67lgT=u-}OxFTEcGcBCQiF?s-$lu3f zy$*4)aHOM&5U$=i>2-znVt0r-+B*>94zG7Gv=w_p)Y0LZuENa?XSvQ<91&q(sCcO3 z86xj+h=>$M6#GM4M|(#?+*wQLPvq6;3gnTsMYz+~AZH(OcldV&0Wu5oKHnbOFN?$b zdub$M999G{Q%Tp$upg{b9y}=aTvnqaBO_1Lbip?DbmdaT@+#>!+b>I6 zBgD4cbmw(Sm8%rzoZ}GH2cJ6xFT?L>cL8n7C>F1$Yw1m8xSpiueO?j{(4=!s>d1T>COHwwv)rO?D5{H-hTa_hyiEl~rd)2qAH?KX2_uRto zzgEMos8S!O4Q%u!e~79N;)(jX+PT~FckzeUz9e56pBrDyHlCYk#!uAn&++ah+)`ro zvD(;eWqGoh7~M>aHxlEkFWXijQ>g?eE1iocjMr(rZTo5Jw&meQ0!Nv{)SQwlzJp0uB#Q#{mFA2_eku*!#h%l IoR@&)A8ov|kpKVy literal 0 HcmV?d00001 diff --git a/addons/__pycache__/fastly.cpython-312.pyc b/addons/__pycache__/fastly.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c5740bca029b9ffcdf54d3c567f97705ec297f73 GIT binary patch literal 4294 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/figlet.cpython-312.pyc b/addons/__pycache__/figlet.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30bd193f1c1f754025f3703cc5e56af42fcfc266 GIT binary patch literal 18611 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

-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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/filter.cpython-312.pyc b/addons/__pycache__/filter.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43a76b50e5634b833b8fe3b546d651526966b379 GIT binary patch literal 7700 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 WQ+l$UJhkRMxcYd$%_G6ZmiyoTNB@`r literal 0 HcmV?d00001 diff --git a/addons/__pycache__/findsong.cpython-312.pyc b/addons/__pycache__/findsong.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5fb5f18b3b56cba23fed5e025dedf2da9368b2cd GIT binary patch literal 3154 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/fontsnew.cpython-312.pyc b/addons/__pycache__/fontsnew.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d90bd4498d3a7bb6a64cc14ccc186ed9b697918 GIT binary patch literal 13561 zcmeHNdvH@#8oxJ5+q8MKAQ5Q`#M)OxtS=T^K*ueVho!gz;xI@}o6x4V4c;U?YP%EY zgO);5nv#l|Eeo!rf(ioC0>UV>x^!nCAwar!_K$7U+4ZjtGR`vmwcmLqmuwTZZfAGY zp7xyYJKuM{@80wHoyR@-lSY%qL0JFgud6p3IPNQyVL?uro4a|A>*Gw^IJ zJWv@>8BjS;IZy>q1<)j*NkEf-u7AU7fMs zWYa&h*=VUXR@9pHv(wT-&V%}wU$ZoAF`Fy&3+(2t_NQJ>(?hU3gnFAE3G{ZW{+naR zz8>6(|C{w2t@ZY(rQKMMOT{-H={i5s_0foHJ7Qd&|2WqJOpKRWOTGCnZo=Mu%@CcT zmVIGw?^$3wDRm(}`bHJjt#@%EFY)83fL6MTt5DCWkb4(O z5wktib2{Yi!08@fqRuKEg3YqooS==vUiT4*=OCVe2o-dH4Dmd~4`W)ZN-&#Wv25Iy zz}w}$zT=lp!r$pjgIC;_+haV~tU_gC2iM!Kw+=bKXutU8kQ2oi2O9151q#zdY>d)~Xx#Z=wY z-P^2^{Vhj{4(2Gve9V~Rj5)!WlZ^R_!%kV#H6hPGCJ3vI3b7TQ`cDY7!> zDbq@utG|^tSAQ#QE|@u4nHI*hGNz3&I~mi?m<~EDLp=mJFm;kv=pg_I_0aC^Api*V zoT2)&lzvJn?b;qPq(W|jP?(2_-c0}zauXzn+_YES1V|w_?Nm1zq9J!XwIf3kCU%-9 zNDsNmkPW%_Pz%OKLrAkvHA2%8G- z(iu!HcN4NhNJ3Kr)||xTikoQmevgE{Pl;}j2#=H8X*`<{5%uRJxn@GP6VmoQ_HkU8 z!X9$Dg=kuZsZ8W=C!(W-vO+TKNep65R)%R$%`H$d=rx);_>1^B7BFCcZtr6 zNq`g?BF={PVBxj1m|SlqgcP|(%!f#AuD4;`A3wolXcr-!m|XiECIRAQ$VGJBkrCyg zNb%MUvOk!6a<*@vzCq!zLdOn|wTM^6{|A$J5Qs_cEr3F>c26GKS5B9uJfB zG3Ir~>}SjyjCqqWZ!v~Vn4aGG^BIB5H} zG#Gd>Ws}ivHw*QZ^e6();5dYVW{5YhgY;RBhvQHqSA#S$p@torBytnajx|kuBX4^I zEKx(m1R)pXs5N2&I|enw0qiyK?veG$+me#FCRwAb1~ptvz|Y78U#JaZf=R~SB-R_x zZG)p+4cY_5gvQ9**QCd&Aj{saN!}=5#J%(+$2BP$74{5Pax-V+cdPA_Sw5<%(J@(+ zHY(WrO#@+5Qlq>E%>pr@QPG%m7|k0Hn&i9ZD^On`gP71LXWmAu?Obm6A&9?$nEHWy z3vW=AeT%xh;qkTAM!SBQ-dLw!<=C{zYBQVAS!pdCrC=lbwEnqTv(aYOFG1V>)#xC# z$|8uIK_hDD$SJQg+AFKYq$#wqKPU zROR?pIR_pMsPdeP{;W#xF77MsDIK0NH8{oKpJE71nHAK|YL^eEPj+qX*xIguBE#BA zuIi3z-_+88c12LR!lzs@tke!`(p_si)^@M%d?~2W`!)K2CdXMaoOSub39rap@1;3MX@^W&EwMmP^XKeRDq4YRAH21Am?`en9aVmk;b` z`FwGn;iA>**?_h*s4Vp|CTv1oL}TmK1S)nh}fnvJ(RA)64b$Rs{mQ?N&X>od@KI}lv205g6| z^ACk<;gQUs;Yq*Y$$_GPVYxs1*~D-y>?rL1MIbFRsL1pyGNWrV#cS4Wf>#auBAfuO zSD_Jp1pD=AW8JT>`uXkF55i8pNwQl{2v!&xtaBu z8^QI`xWH9+U*C&+U-Zp*KA>9_Okd?wu1dI#E|xB>Suxw_tYz(`(WP~LK=&)Mv=)!L zwBAFv(HW~@X;n+N(S>LmorAa0g?JmC3)|>NiVOMA?}Kf0A%7v8FV0t7n4XOITpp#c z*DmB6GAg3?H4{LG@j=3mWL5ql$MVsE{>13}XgoT`7wX#Rh#Mo?(}`t#z^78zfcfRn zkB7z|^Q!~8HNo^XKINK(m@koHe#S#b)&*xT^v_;6U=7SJ^Uqk>zA}pW@_=qJ!F)+# z%)h`eFO)#t8Z_)~bON;$vp?z6@93yqFgj|t2o}3pZ>iVQF*5pBwI6m4rY^?_-3)3L zAG;~Egir?Ec^n}(2+V)KxhAXiuzLATx$NGwe{!;nv@j=2O@psd+Kl)gzm`Z5JoCXL zzYNZr@1He)U}a!dsek4QpE^4NVc(p^0bL2f@RCt6Je925@aS9N476+$2x}w1NSMIz z&lkgSR$ewX#u2-z*yk9LO9p9t+!CkgL%Z-ibmAZWZ)@&2ey)z}vt!p>_5+{;HH6%2z~D6(mPd8^ z|MIqJsdT~B$84GPD}Czek_ERUpj$!~+@+%~xc`3NM882tetED}pnqS$qI9#~8ospfmr5@Ec(G9hbY}6#;EoP+8_vmfh|CXk53; z5%jLS^9D&xf9#q7yAvOzC9wW+|9oWh6K|aRUNSPq5w}Y0ag3L}$R<8wu}cis4bVxq z#($&yAAXR&^R74d?RCMtIsUvkN3DUp5`XrR#Fs~R{;ngkQI33&#wXh{!&EV)yxe51 zEHB5`=fZ5Lv4DQ^Av}$eVw5aJNhwO6L&<8Cyoi$ZkccYy(GB{IOnGIU3I7%bUy|di zH~c{#f8oO)3-Gx^KwB6A&4U7J-S@bgkaGBz{kC#Joz>*1H9sX(f(+W7v%LUmSkCkO z4XvJ6d{@F}X=To|@8)G`WX@C|=`yDZNQTU*j^-xIoZ4uPmb|lwTIN*VSis3N-RrON zIX7e)KJ%uWlRXed+zmZalwalZB8vQ|!l%o-%I70Z7BVS7nk=b_n)m_};BL$SUp`&I zRle{B$|Dm)R70PljhFy;BL|z1r%)4k3UhW>6IvJiVze$BuJXB&$3v~amrw!i`!C7Z BJxTxo literal 0 HcmV?d00001 diff --git a/addons/__pycache__/forcesubscribe.cpython-312.pyc b/addons/__pycache__/forcesubscribe.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b145cfdcea62ea8d8542e66fdc48ef2e6d0fd58a GIT binary patch literal 13046 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/fun.cpython-312.pyc b/addons/__pycache__/fun.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c3996b4b250c382169126d4de92e9fa263a9926 GIT binary patch literal 6497 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/giftools.cpython-312.pyc b/addons/__pycache__/giftools.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b3713788ec9727abb5f64a953b0002d223b7870 GIT binary patch literal 8163 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/globaltools.cpython-312.pyc b/addons/__pycache__/globaltools.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c04303a6aae32e7ff80b2b2b45c35a5f22384ace GIT binary patch literal 42204 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/greetings.cpython-312.pyc b/addons/__pycache__/greetings.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa2afe490fe039ef58836211498793b0584463df GIT binary patch literal 17977 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/imagetools.cpython-312.pyc b/addons/__pycache__/imagetools.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ac74f161b60424a7a25b46b0f57fe4c12a47bae GIT binary patch literal 16290 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/logo.cpython-312.pyc b/addons/__pycache__/logo.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86fffa95e36603780a1e4f63169af7ae162ce5f6 GIT binary patch literal 4246 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/memify.cpython-312.pyc b/addons/__pycache__/memify.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..658f3e062c461ed5f71d0392cb4216d414f1bbde GIT binary patch literal 13242 zcmeHNYit`=cAnu3-yBjB^|T|2vSnM8Y{?HfisRQhlI19h9Y2#;NkdVbkwk_M?VX|Z z2#Ly@-G=HKYZ(iywQUyBZi`l`wXK8phZe{WCk+y3^G5@EL1xxKjok%W{Zpb8jg6x1 zIYSO9OLDBZae+lO(0upIopbL!_uQ+w=fO`o&O*WU>c^-0D;g;3_xPY)OqN*u5fE1? zp6a4_n%4#CE?O;hT{^X7x)`-&yI3fhpgv^iGK7p>#*nGYL{mJ=>x1TB>S#(w2^QWk zW4uOZdge{vr>9X?X?^9himB+G#$GU`v<88oWAJ)0K=qu2P<#%sSxLPBjkT=YW zt|J$`{-C!fD7bc5EWaE5g{%7we>@cGbsdNf3<$&}2}9B$*M8T5U}P}&cz_54!C{va zafJll?>*FQalv&q;_?x}D+y2=5=56*bcvGR_qsr~tM7Xw&>b1}hx=T-zqeN)LRfP3 zM#7Tlii(1(u2CIU9niDOT^DuvykYgtE*xpsPIu!{3B_+m!U4Z;&Cn@{6anO%~V1 zXkv@e0UUqXC2oKo&C4p`k=JRhSIEE&Q!(8G+c96;jt*E?j-~wrtQd)nu>o!+KhJ7o zkdGc9y+jVk~d$W8!+=7&k}`t^YuQM&-+xUb1UXfg+8{mx1Cutx?~+1#fy= z_al0Rq{f&rP^R^oFCV0>S7BeoO>uL~9H_{1Yn0Y1uu-eYm)bj;ikTk0ZTKG^uv%tq zEy&Ratd>RNSfK+(s?_8RRB2ScjOBJh+!C_{YVvP1iZ}9B-ZsNs%YMq?V+^YvKK}@k zY}Wb=)M`||Tq21zW({o1ztJd7%j!DW;+&N4uTJC1m%K5?UCaKbXJnQdw6`%sOsBnD zp)otmY`eypF9S_^TBCq-r$*U;1Yi|6avoD(YLP zOaBP>2;BT;N_tw8xRxReO`WHPsX=OpIZqAJzhnk!cfkpQAKiP!-KVuf)*Bwq9JJjd zwcW@37w~{}iII>X_2XfRXA+)}gTyZhjg5`n_t-|MPyBb>{oOA_BCaE0e+Z6c-gPE( z9J?0YxiYFU76v1dZ5v4R^jCjOo&p<{_k1!mmqs!8f_|K|Sp*?Hz5bw}7=8U-$>Zl0ho%TmNbJK37(OU~7`lk47>E#xz>wTC zUQswYpt z@rU{preEk+m|!G`Qw1|k#B&YpxFy%UElvHf&zhn=(XbS4Iv12k#LqW*c|H;rn_!Cm z-eK4@>cBi{hYmKuExrz)p?{;k8l~uBp|wxS8cJGQ^DrJdzh_g&dHSGgzYY))~_30>M`|IBL7)wd>{Z7Hrztxp%0 zr3$yogqSgqpPs|2c>gb62=7s z<=U32-Yr+}PF6RkDw@aa3B$Mnq`b_HaX)mVOqH^!@|LN3S

t#>`!=9IKowtGi`( zXT_U%Eu)x(?lxC+xofOzf=zOjI6KQ_>dH+wF1@U(pJ^a4X!YZfV;)c^|68x~YBP*(1;d(8dA zh7?;e$CfPU^m^_#h-@A+kJnyutU_-2jj4R$I8E7i+yxcd_o{f5zI(@7clQo=2p&Pb zSh)dSnN&7Q7P;+TE$CqEui&k|^zN4y%2x3OMeDiGOtu9E%KsGq3pU;NiaU4GKcPD* z_UaKD$oI?XPKJHIVk6ScbfT1nf<`-M!JRWw6PyNbp+dfXrntF?1x+# z(zSGF5&PkmBgplUo$f4QKXM#l;o)N^-C53lTztd{4>z~bog3Mkbx#BR$tJq9lKo^e zHvi;ly0e=7WIs0eHFdbNhWhnk9nhaLDA}h570oKbpitvbu}H-d6+wEa->71xiq$IC zm^*hcpVq6rZKsjm!2qW(d+>uIC<=}9H{o9V8#qZaPJ@(l8CG)!Vw85w#dT87F<8y` z&vU{7t_zrOxce{FSYhJe)yC)x6e$5G!g@akKIL5vm0u4A78|3%z}CeLJQLHaE%mFm z%()9{OJm#wE%k9D&&Ews&h!uDjPU%}U;<^e5I0NsEmW`7jC5WfGyEmR8-B(}B^n=? zSIh|LM(aZ}r{Wggq)K9q+hWFXnmi@tOz=Rt);eFtjJ$cqqP1=Vqv21$V2yKNgs);~ z^VS#_v&`5uV>E6DV~ay;9gQw5M<5mfv?E(rpw-0-;tuFDXACcqfQdP<70->p%J2n9 z=jR!-@`YG`|7?48CBtc zrMf-kCluPF79l--p1*l}P`FyTs9*ug{%bFjB%4sIgoN2*=H4R2BTJPi~;8m^Z z;50M;-`LQrK_3us-8ejAM#Ee6jTH7Jq37guf$BIAH@qh3<&q}>z=HsP2+Zw)pkE^B z7%MCW2MJCxyg z2Ee;9M6+Bdf?|wn14Od}D28B`0VNWhAjT3uLL(qbEYkSElxcgUF(+NtkOZYa^o|}`c}EPbwSS*7lB7p`b2ig9O{yp zV9AQIOZKhywN!KIlFCVwTv9i)=elY3nB3HwY-p29+HS(O>R5|hkFBpYsj7D2K2_bf zxLz98aG{5$Y-Ql~v&Ofcz4&b6?D&(n*bQl`W3=<`BF50ZcieHjkj5;Fn8~uNr&e-l zAxz1v>X|(#02^OVt>pYV*jw4_LE2J1!u8aOrlxGUo?6K$Vm-BjF$*n{LPH7!QYDWe zwQ}j1)lw@2ordUEfQKbhAW<@LrJF!Bgd#Qsj4u%kEfI7#2$vLtM0h4iL4?;6S&Icha@aT3BOrVi{2&&t#AE^Tf2N4b-97f0`4#;=# z5#0;&3_>daxCVaTYIy_I&WF52NF;v>eDA?62Eo;OJV}A0NoRYCYhOZJIN#qYEzcl(biRy0^-!(*}bX#C*}Po*O(MwACwgM5(4=~)w%Qi;KahIWm$n^ zYsv~(x7?ogfj@|5MD%h83D{r zikwHlm=Nhgcm?5Agl>Rr9Dnlgh)Ip(!;hQ5vJLkUAG~xsNe~%x(RC8S$1s8#iN~Ni zi69Ihd>4TrhzJrw6yXBGAi@yBFo43M{rvU8@;EXh%)`ANEME_nuZZ|B4bwuvemz*e z=D_<>&HaA}mX|IKmhZ*Hni?!8Z@{MoepYDo;4d^io=jXq4H@|H>w`fD_-hRrm00BDK#W;&vYOZ;iEy}5J^BC4Y$|> z0Kem+>Ca28G`qNgq8-1b%)g}^zo#t!LN&-#!yhQe=LSm0jlXh>uK8T&rnyCi(rsEm c>Wi1@08JNs-UT&z24{}JxtL)fZ^1DC1EqQh;{X5v literal 0 HcmV?d00001 diff --git a/addons/__pycache__/misc.cpython-312.pyc b/addons/__pycache__/misc.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83b3058fc994d8b2c6409db418a77bb3474626aa GIT binary patch literal 8603 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 BsUrXY literal 0 HcmV?d00001 diff --git a/addons/__pycache__/morsecode.cpython-312.pyc b/addons/__pycache__/morsecode.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5dbda33e3e90089c705aad5c1a48d586921c6046 GIT binary patch literal 2090 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 Mz%Jb9L8IgI-^DL)ng9R* literal 0 HcmV?d00001 diff --git a/addons/__pycache__/ncode.cpython-312.pyc b/addons/__pycache__/ncode.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..59b6cbe7ffbead755e269e9faa3e0047e09325a5 GIT binary patch literal 2615 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 Qy*BPqtGAcqzRw~4KT`_)iU0rr literal 0 HcmV?d00001 diff --git a/addons/__pycache__/notes.cpython-312.pyc b/addons/__pycache__/notes.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fed3ab44cdeb282d43fc4556a0475a6a04e227bf GIT binary patch literal 8223 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/ocr.cpython-312.pyc b/addons/__pycache__/ocr.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..59cc6007e16a30f48c90a1f5b71397db9bc38361 GIT binary patch literal 2300 zcmZ`)Z){Ul6u7Uzm?HB`ePG84>cDQyhB4&&~+h{}}V~!CFV%kUVTi5#9*Sz;C zwzj5GV?c~ROk@TL_~(lO6F=^QCLj<^{L(s;))zhy^n-jGqH*%cbGw$94Q_Hy&pr2? z-#PcZdrp6Hy9t7I^oN(GH;V}U#x~8xH-!6pKsbjeI)W&soQhN25gsGTQ$ZEJ=0Fk^ z@jRlo3;YoqhZH-tUvXT^EOY={u53otWEz=DsLEZI8t8Cue#h|mi&9!Mr710&rq4>_ zsv;YT6jw|s0ZLsZ(6BqX+&w-n8H!k!+J4vbDj7*bBl>V0x1(f68? zi{_o|20Q)1-T(x%XJpe<^mMFI7nT>Y1HA)u{|<-HK7^sl1(akbOP28j=$qf;e`gdo z>--LUpEtqcW9}UPo+zS&4CzrG+~Yio*c6)3NtW4?Mfs*@kt=XUR{!n1 zLe+)j>g7m}%~GVcqOHK|BDELz^XLLsw3$yd{RQLfu7U$FMA~x2eHmU9TT3%6ItxzP%5WCZsE5f#@|c@?3j}c6E@9%mgK3wB;UWrgTCvvZ`rVWN|wQ!zSy4 z0KL8Q7e747nqL|}Fflp2pOA_0!9)8e4@z%Iy}eTO0geV*El0wL)aRDPE1GWcSvq3b zVZuZptR*NkVOrc|*m5@pL?k7fv1v<;>smHrwK2oGcO(V%ft)Qd1wOJR)(4=~O10zZ z`e<8JbJ;1YRW@?zSj13dJvOcA0T%>SO^Z(%aZ5M=gUaF|m?Z#i%HpVM@v^B~oC%4j z35$zElBRANF1RC`u8sAeJ2b7Olu-6qHf?4@hg4J75;P=Js-=w(t8XS}+2A)ZmDBy; z%N~~TD$Kh-&_W5_cD0@!dVi?avF6<2vxm!Fo98+Ps-A(eW1!}3KW9H{FR$^>c>`4v zD2?6%+ifSeoypC)e5KvLx;)J5<+Cq;dhDa4RgbUi@YRUBN;)f~vr2pw;=AOVBR!?j zTHDHM+xkk|`nfiL)#WekuC;hi?|pyo%$AFTpA1$zH~!qYu>n-1Z96Gx$ahEoICRUv5 zN+Y*CT{ZIDH|94}vj=CxS39oiS83U?ujXC(m&ki<{~(^&N+a_QgR7ls1Tp`k> zrz#`}=@R#8|4Dzj-0J8whY?uFYf|H5rg z|3b~#voPNRpbPT^iNpATaSF=(wl5sQU*K?;@Z}nizQtil_-+8CYyCL9R=BolGsxes z#o=|r_dSCkUw;~hHwf3CS>@2wQE@V6IX|L@3i+y26j m;??8ju|!!+mbiO1#JSJB@(cFe<5uBee4j^L_oAo=0pLF+Dn$SQ literal 0 HcmV?d00001 diff --git a/addons/__pycache__/other.cpython-312.pyc b/addons/__pycache__/other.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e80bb68eebf2a75f67915d32adef6f94adaa7a2d GIT binary patch literal 4964 zcmb_gZ)_CD6`$EZw|jfOKmK!I90$(W#y-Gy9D@l7I2`BLw6v%|s03+sIlOCp=Ki?5 zYp}@~XcDz{iew{2aHxrJ+YfaFZBSKJQ9l(M8Ki#kakP6`a@h&^LR# zXXkvlRO(3c?#;ZJH*aU={ob4Vv(qUcC_lJ=bfCwM(BDYIDvZfIxd_a4B%)JD#3B{N zG3pc*qfgN><`ffSPq7$LNMc1=WNx#!sQfI^_Aa_*DmY~`Vd@C}hNO94(Z&;D! zcsM4tMZ_-OK3N)yj<%_zLsHk9f)9!@C?+XN_>AOJ6TTBLye&8oR$EsT^`94wdFFI7 zET)_>6&xcPNtcp{Nr|}Bq!6L+^r){tA)gP+VkCaX7g2qYxNk^~oC~YcD$PpxoMdS= zjWE?7ClVFx@R6k>l4xj!Wrk%RnFZ~<(TeYMVq}%d{-^8g$s6=+YFmXb$O-rvojr7< z`#Z;UT1tqza7I!?iYmiL>5k#3Dkmahs4pg7sAwiTnG|FGW?ysbc7L+L|GJ;jxuLMC z!U5=f|8O*_42ubJc!k0N_YTx2U2ww=BMf&-Ey$B-(7Zu~@xTnSt6O>Ax?P1kgU{9= zBsYKtvO-Z&;dbYXNEK$#w;Aicz61CBEgGR~)OGqNEQ^k#|J@Q1Z-OPpu${~`{K{H0 z|2ydXW}CE<*s`Wz0iCyCjQYRqitTJS?27N%zecp(<}8~;oAE_V{97>Jv(|cf6ZBWE z?YGXR@J;5fjxq87em;C*^>xqZsk`i5Yfq9&u03gMpV?J+!(Lb$jd5ePBs;iatv01n z6q2@|Bhdl!>a}u^lzqs;?2@oT0m<9P=+at6 zHc7*}?1!{iyldcP*BElA_8=DZQ77T1kI@(D)O^C((Jl2VHpx^<$`4p!OE6 z9US9Juf1yjoYwvgK4)3I@|)zZtAxX>9f z7Ha>3pu|U5XVgecTE=gFK}3G6^Re)V0(hz#!(KFK$1;B70`vm1->zdxXZj!%=p3PBK}s6YX$Uhq4(U`p zBoj2zaZDk|MxvTgmK)jzASSg9pB|2@!)+(>Xx$bT#Y9|bOQ-{q+&VO>Q({cs3G)Ck zk@5+k??2GeW%PGW7;m5Koamg~H?i+$T^X(>6@JKV$$B?jKXLWM2QN?eXP#@h6PP-Y z@pfwN&IP_R>nK|ppQ=kcYA<)^D4K1}R&Tn=-{7@sf4bT~(~zld(<<7=xi4*qcNDL2 z^dYx7>vB)_PxMblC!*7V@o2`iZTd%Pmw$rJ+J(uQ_iD0LUahJrUDcGS@@u63@zagU zQ5+k<*^0{R%~zYXil%f$(+qc~GE=czE89JeKdXE`)t{+soL0xX$EmE_GnsrZnXRmv zIyTjvqEhWQyKZzX)NG%rTPWW-evlX@O-NG*Q?HLp8P`^g-j}~z`+vUL*_p4vLJm> zLj!-I+{(iW8OAqq3F4bZE>Qu#p3fx!qoA|63=+30DqJrol)I(6)p}LLuz*+G@8VR+_c7GC^zB znC55XdNPPJp;9MW z6U!ozJqs5H-aL4a-0h+QK1MEkQL*$ETZd7+6=oE&&6R0`Xo z;ivK#fJYSanWo3e8;djH_Pb>n{gBb(DSPtHs z2z*IX8-%YAj-vI~%b@b;fx`tc==t4(vYsiPTgi^eskxyB6FG}G~rYb6Nv}!IgoD0Si}tefSrL@04d;9U9-Uz;~GLz2JHIPljs;H71y5g1Jg$ zZ&=DPu(*-7G%r2oJHWMr%gXn`{I{!u8}T(9bTZdB0{2@SbTc0ZT)+|+F9#QI1%7rX z4puU=Ej7T;aX9E@=6D<7-I&mFgH{?8z+fXj0=Y033c-H}p^%P@>^Q&sB=pN9E*pt# z9ze--d*$<{n8 I2VkxL0Io|s4gdfE literal 0 HcmV?d00001 diff --git a/addons/__pycache__/pdftools.cpython-312.pyc b/addons/__pycache__/pdftools.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a3c72721c3b41f194024f17d723feb101b001ff GIT binary patch literal 20814 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/pokedex.cpython-312.pyc b/addons/__pycache__/pokedex.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..204dbd23524983802a5eeb544ade5988c79bc95e GIT binary patch literal 7113 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 TZ|KgaCMR{Gu9=Y2 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/polls.cpython-312.pyc b/addons/__pycache__/polls.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aaccf7daa55eac794c89504a70e0e363a1aa76a6 GIT binary patch literal 3637 zcmb7HU2GHC6~5z{u_t3Yb`m@Pgz-X_IND7L>;k(uS<;ZEm@W_?S~Y-d$1{m1cxJpa zsKTxCi5ECHyIO?vC*W!y~(m)&iC7I+xAEpIO7ZtgeJIIBU)U#@o<=`0< zbWTqQT%WAS(~^?bxD(iUO4JkFpg1YW+;P)W`VU;Q$p|4X-s5VN{EYNqQF!p2OQV8{fmLeDO(n#50*}TORTbho z%ihPU7o?2pBXTOOzc27&3|H5nOvz%|XGS%=r-dKsA3)IuWL?xnLA#GPLC|KfCw5*b2!5f+-azYGiS$Pkmn3unT-+&e=|c(&r=9TsZ7stJa( zwpZFwJZeT+l1Ew4vNXJQcpW?o=#YBr1^&*BJd~M-d4V0fVQ1ob1!fD2E5ktUALupK z4D~uo%P`N4;o8V!;@RxYz(r~GCj3^E&DL7UaUyGfW$a2#nGD0bU$S!5uUI*T_nhxQ zNF{l1)**W!TFpkEk{!^mHTyOgr}YL4YlgJu!Bgj(!T&}3uI?52pL=q2yo~0<`>Z@x z`|LT&R_QI4_4DvqeuvQl8@G+4xb56t*o&;bZNqE3rDezri&KxI6~A?EH`hJ0v438+ zc9!22+x*)U$~v zBn^9o6b%aVmBCoN2&s<9ld+`8R|x$yP%2KP`XIt-wHBm`kM&F-x=!%isSUz?Uje?; zVIJIWa53n(B1Lw?Oc=ppCmaQmd#rSkctR25g5j>9iA*X0UNbX*pJ$yBBNYzSa8bs@ zq!9EO_IOf+s0I}oRdjIMlt zgA^f%U6A7n53Wf;Rx#BWv>KDg1r^s<#rw!`sDhSKWM0KT)KpAvhMgCZQ0t(}AOwT1 zB!X%RnqjXnyFuYu88oi2V$kPfDm0{&0t6}iQ^g=8!=}gvd3^Y^h8Y+Cu(F;fJG&E# zBy^`o)3ToK9cZyBBZ}b(K-Y)w0mHa&ge^1f>Ufy@; z(m>hQv~={!(Pgse+qpbc@a=+6PH(<(U%|Pr+|+#4|B*kxegDl^&R=XgRH{3acO8Q9 z#qeEcTe-G=t{*11n7He1E7vv5;h8RuU5=D}jh6=Q!DRMbys#L%`;A)l-WtNS8Z3DR z^UPqm+Or_c3BL&Eri#8@#p;d{(=pq3@7(BWd@MgM72|U8obnGgmH*&}^Y55~=5XgI&c)Vsu-k!(*@(es)Yel|3_~1p}?-P&8Ove+0O|97=!lN}8qWw>_U&EgK z$vfe8;*UhwMg6Id2K6>Uggw-4TN~CnB3w(|4)nJ|=aU{H?595IeGl|cL2sl!?G1o_ zXFCyYrtWafSbz6GxRv^BPYCqSyNGar`n+dS{zxD1eaNvQB24w=X9cjzIgNZk+O z2@{eOKAjYL)n4f0AJy6(5Njks5D%)|1od?*B8G?}I`JRW{=klG?y{@pE7E4OJ+Qw{ N_#ZkfP3-}<{{zpPfG+?5 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/profanityfilter.cpython-312.pyc b/addons/__pycache__/profanityfilter.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6575d1223d14c7e7b0d7734ee3899cfacd1098e1 GIT binary patch literal 1270 zcma)5O=uid9Di@VGs~_*6Rowj4@o2|?F_C5EowChh*2mC^|A=l*?n)b)6U2GX0~x{ z0>Ku^f{+Tu0D5gq?Bc-ZDYE{LEs#FWLNU!RVQ8h49 z5HqMwjT`2=GVrF>6|_Dis+ygVvfcg#ruO~s*T_r~MSe_EGIh}pLcbO=a?-Z%Fa3D# zQn2V#+TuyWkAtjp&L)J+Hb|O8EQuLOne?jpl*}ibk{~8NsW<)X1UcJeF{vdPnGeE{ zP!_U`kqov-#M0ECW6ps9XVJd}-sefwry&iAKF-xi7^E5aZObsqiYN@+JgF#bpz#I^ z+jy{V&#}x)GakfqqRlMvJbIFt{B$Ik+x+48fD@mLgm8U=CcC2`oP zOSar}0GHw0dkt^W=VgZJ~2<_ZjdqlZiA54*79cHK?;_+9(>54dN)yfm|A z7q5I!g>~7r57)lvjZR+Y%dA(bY+98&R%Od7 z-P20TpRaVfoek}UE#RH#PF%Cs-t0X)e!a3h(X*XR&AF>NJ0==={o#&*bay`;hl_kQ zb$I$1zIg;sAJJ~Ucna{XQ9ONAyESG=d=$fYrfdn*^Jr4{JTcnp3?p{vv=gU|d5_lm zY3%1rph5mj;N~*qpU@tRh|AFTt+%6uwnKKBAA_mv=+uE>N5vTLmPWAl;5md({e>oW d4WtzBjJ^7+wt?T-RV?i8sYp59NBkvlc?4<8Hkkkb literal 0 HcmV?d00001 diff --git a/addons/__pycache__/qrcode.cpython-312.pyc b/addons/__pycache__/qrcode.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61accd5e2b83ae00ed3cbdc1da9ae732bc9cb241 GIT binary patch literal 7111 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 NYEy4Bx736{{tp#V%TNFS literal 0 HcmV?d00001 diff --git a/addons/__pycache__/quote.cpython-312.pyc b/addons/__pycache__/quote.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8eea0bc1c5c7c4805f8cf6e2e987b95395f17d78 GIT binary patch literal 23846 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/random.cpython-312.pyc b/addons/__pycache__/random.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75b2c919306cd8ca0b0e73a62e90656f95856b01 GIT binary patch literal 4580 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/searchmsgs.cpython-312.pyc b/addons/__pycache__/searchmsgs.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ca25019ad4b473ec809efd0187d958b5f523edd GIT binary patch literal 2195 zcmb7FO>7fK6rR~1|J!jA91?`eQXpgqdNj6qhwawC9A#GzA&Ks@H~ZDJaiWgK}4O;^-T z5u+4KC;x)2?a7yU=D5hb&xfT*KXZhaG_iCH6KI+@npHU`Fndk^mEZY%cS?HE7AOES-h z630tE!&_h^93PDFa>*swJsJC&VM42pKZq%kC~zVD()BX%{SGgQ1Id!xkS$eH_SVF- zNGi*8HTk?Oi#79LSW$Q>5vdSW;z+0ZBK(%05eU79Fp#RE=vs}E8bTa42)+okpNEI| zoR}m(rD>GLU;)b)R$6@7=Rlkk79i(!yGkT@v=Sw zj7AYhtHcmks6^Cm*sQJ`&6y1A({M|gNRw8iI1LSzG`Tc zZ5vWthL`O~qA}95;X`!whha1V>o5kb6YU7BU8T3Ma8)V+@wrv%2D(WlXs)`nuenL4 z%_@#=F>YI3RkOiIDPMq*a>jNb8uEM;eM1gow)SYs9y%dP145$D=L;?A8MdS+Zff(p ziJ@>z;Fz$~myGiXW$P~HxHQUy`@%wE1$Qp#MY0rui6u0&1S?`m%~UQujgAR%LD9@o zx!RL@jx!&XxR`6=H0* z)JCuOs0giNy?6zOShq&)%Y7QDj3}~2r=T)cSbslsQh)MHGNB~>mG0&bbDWrv z{bdfpQ1%UuYL@brm!u}RK`$!#5^(<~dOn68SJzB>COo^T=&rs@7fC=X zMH_f{UerAn>yX2lId^$)kwo?_c_n|gaCqvCsm3`=>*K1%f>Jm;b#T_{E1D5)DcX>| zYMjloxkFcc3sn6tRQ(Hi7+&KOPoM)&;-1}9{vZN)zaICrQTH2O)A2rg&tCL^Jh&4! z54}{tLOk^0fXVdGPwIG27o7jthV^-`JwTE(hyXl8U>%dBj!hUeXDm%R-i-ro)J&@h z@KLBXb1=w>kzi1>L)qy6kHJWsE2YUTv<#skX(vo8mN(-fmyGcTq!!rfbt`X&3FyH1 gsl$$`r<)Psob|B3V((L83vO5@5z$;i(k@W^7lL{gvH$=8 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/snips.cpython-312.pyc b/addons/__pycache__/snips.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a715e3e53b20f8608818c7667729af87850dbf21 GIT binary patch literal 7792 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 EUxz0{lmGw# literal 0 HcmV?d00001 diff --git a/addons/__pycache__/song.cpython-312.pyc b/addons/__pycache__/song.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d2f6ec1c1e5a9b80c003ea0200067b338755a81 GIT binary patch literal 4131 zcmbVP?Q;{y8Q;A(Nhis&Y|F2_C>Ssbj*KnY1_GhjGAUqFj7zZHWMo-)*fJ-b*gIk5 z$TKdP_B*%` zNpif2?i7QLy3Jnamfngjy;W((=SsZ;gT=4kUGVm*@pvR5Y2M>kA~7X0uE^dO#INUm z?HzkPHmjsbEUI~rXmW%^C%u7VgoLmUF@els%EJSG~7l1Ne}eOIG$Qje(#=x92x$>g{~6EQla zfs_`DKBTJ&1Mu@Rj^eu=+vk7Y2Thh_M5i;478jgO7V(hZfV_T71LOS^lUapl698T?S;_@WjM)Jw&iUo!%sO& zeVb*byh`OYU<+$7D`W)8-asQ;;JvCgZAxg$Q$m|1jI7F!cJgCw!EGNvC6cHVsJ zZusP)%n0oNG`h-;plJ-gUWVNM5j%~2&NGB=(u`+<9xwB>dUe%XIKBRv%9mwbk0mCG z=hp9kNMFuqIeu~`GL$}^4)tgwfeYvKp3af8y@btk`$J1S-((svR*NO8F=|-1E z_nbH|bG2U?QO*t|4_%!e7`*(->E6L}mk)*}B+@^uO_TeFy8$!-zzkd1WbteAGefYZYz*Dy%tat-! zp5WY>Jj3$ATCu~D7tR8-e}E=&8uSbdwstd z_|?G2!B6&NdoHZ@Tv!pC*Tms0H@w0P=S0U%-woee`?H*9mGk7AQRTsnuWYRw`5NTz z`sV|C)i((9!3UoD1<#7NW6cxDx&kY%z~|OLo`sIb5R@Om8#&JNSo)FPI}RP?mK_4c z)tEj#7)CDF)rStU%WXK+AuJ!@Deh!wZ#Sm+AV=|0I(|l^+vzp6YK`0ulr1+kdrV1{K{+>AF%H`S-Wqe%sjp;0N!sKGqNlLTKhw!8?tr*HnJcHRdw^Nw_E2<=NXX~zo=-q-`Kv=acZsc^jbxK*4n>f?FSBZ zxSv!FQx3kcyUNm0qEu@j=dPV^xZSXDY|XttYu^tfZf}4`b^ZL&+ehd6^NfWL~juxo?)DA>pWizj`>P4 zPaoeP-X`W*81pz^g(`y^Is5*Nyp_h?fPhX~SYRr7D{@ueymaHzTk)*5>2qt-hUpu_ z3wRplhi?zB>}X%}bYxu}E3S^utsPWK0{_zf3=4eC+2_EwYI>{C`?$A~`+x)VVLP^cuEgMM zsmj)SlwE3Kz;n z-cCI)?=r_UZ|}3QpCa7H3ZG)0Vu5=5)QTy#v4DNmh9w-9)Mz+N>gcysS-3BSi#HjS z5UM(aQjt;jbf3S_KqxH|dOGYyBsV4j~{cooENiu38C8p_xGqs~UL|6P5Q;8`3 zkEa1m6#k-_r_XS29i*p|vPS5i6B49Bwj7^mTrw|5=7IPStwT3556NTekphjpL|%qA zN_W~2JYZ`vepGA0+IPJrM40G&ekM*si- literal 0 HcmV?d00001 diff --git a/addons/__pycache__/spam.cpython-312.pyc b/addons/__pycache__/spam.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c26bf5712650354c66c6bf01614e41dc8e967231 GIT binary patch literal 5500 zcmeHLT})fo9Y5!O`2%Bv!Le!ixHJ^71tw{eG^t1`0$!4(OV_4JnyM8zz8B)mAN1Z! z2oz6ITdlA}!YET=>ZV0~O4L-Usy$5FUI;{e*ozZqwROd$uIt0HCuky#vOetpzxFlY z(5Ra(oUef_UVgfdn*X}EB<2^t|;991qic5BCisO zN=%HtN+nj}V$4SjB@B^SiN7IyNDJ1IG^xefxs;(pb(!hrY{jwl>>pM8_XFA{a>c zO!B-e?%c6s!zd&<79J~%!w^L+8kb>OBFT}22EXRah$4nJ-d7xrYG=iQV{k(#tq?|& zFKER%GF*CLiV7|-B;-!0B0N#T5lvRW`yQ_Mv3r;_eyY=e&KqGswhV_gut`LU31uV( z5AEAf@8_X8N+_hGR?<(9bH(&AY>N$~DtU~UX_=xE^c+ShD-t8IX7Z(&38s&{{x~5i z7Ghe;OyS=N){OTyY=<{lLf&I$*`M(|jOcO$N5ISWu$Q?V9`+d{&ydSaP%R&^qtwqG zyN8|XRMd%|*I89lbPnfLx8TBuBQgr=a55q30xX2A$$n0!vVt$BTZ)OQ3!s1*RB``` zP}a70olVB&u8}jawj*69Vw#eSN?l<|N+#4UT)p7%7%V_sj>}3dI5k35&p`7xvU-tx z>2Rg#tS}>_-$*NI`=u8yhVssu>G)K9uJ@`t>ukArDDSTOicnsh6!K2jbaW~@CuE&X zIcw8xYtu3diqGv8)9q93mjXGi_BL0$%o3Zpn&)cQ)E4OGtsbr?K<5S8(<;nc>QEMG zPdhi?ETG&@q18DY=%%Ewf~%1fe~0BSBn2!0JS;D;_*-yX1mSjmDTQ#Q|)^`Vimg$;C^K%{Cj(mA&&t^aBsQ(o_< zk4$qBW{5?(uugI2lkzp7xMuijWyO5&hwY6`{14c~ ze}Vc5)S>M}bDHigMDbDbhehJpf;t?FY6`mElb{)|HiDa{P$Vu5T(49dpwX?yA=IxWbv7m^ zbl&jPSve``)kCt@Ur?K1#6}aEUU@LA%ApGpd02}k6S^g=jwK?|q|S|oqngeu;lz-v z;FKvYXs+{070Q?mx&ya;zZuP9oKLc%)2NDD7vW7*VCez=&=3Gj>4g8yGzu)_x?%9m#M<@?{9yKx&^|&3m6( zT^2~~^K^CDL27q@y;R{tpx(3O@y%6d>UU*5yK}DH8Q1PR*4+ryd%pR?dl;e>u=xX+ zMZo6J(}>M|2e^5Q7v)A8BHVn_4v=rUXo%r%R&}7fzbPb;g?bv|xP=B5Ww8;SFC6fN z0@lTCc90iE8tUQ}n=#JfUK-lTE$$OQzC|dujL~uwd~XT9P#b#-`f3(#HSs97Flf_C zQEs!Lyc6wpOEF7d_A`orsbC!(iN(|rDY^A=@yY*>i_M_?Jvc7@hoS$^0L-64o%^rA z{__xdj{*CZV+x*aiVqt+p_Iq40lG>I+*XjbDSl|mpiv2;0-OD)eEj{|udm%eJ&^ZT^aaR*wI1vj zT6`g=b)nl1@}fXPHQXW~Cdhzd9&WKoKpF50+IFK2_(Bydq8=~YVtJIU3}|oJDasW# zls#xU?pnXFJ=Y!#_%|UNf}TNygC%6MA&r5@<>efn@MQ%r^(HM#(TxODVlmH5s+3~1 z5=EY%61PdmZlE|2Z<7vbS&7=McmC~^3aB8S=|`+o zK)*_)@Eq=*va(JOOXRNPdHGq6j1kz`#%B_A1VZ=b-E?}#!TC#*dz;7 ztHM#b=VsuZ3sf(-RJ|=da;5$&!r0m-d-Cp@S^tcGuJ=kX=MXavamigb+d0#DmCw3c zbB@;Aj@A_(ELR`cim(Mk@@$(uIdgI@c4POow#?2GnfjAi d2RK|7cj`b80w^!)e z=Ugq4y~^g*yrUJEUM(`cpm`zhyhg98*P1iFj;ymYXYKsV+WAj(41S}&4-@bf?eoxg zdW3@kGHO~jPEU#q=KgDXr`LDjX4(n>3+GM?7Ev~7iP(jZ1_HzcJ8djA)!KeVj? literal 0 HcmV?d00001 diff --git a/addons/__pycache__/specialtools.cpython-312.pyc b/addons/__pycache__/specialtools.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3350343f6bb876521ac7b05b2d16f084a9bece9f GIT binary patch literal 19156 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%0D=gKWGl+fMf0krOgU5@EN4sDQ}m4YKaGOheib gr9O$U+eL`*)Wyx0Yj2P{P&Nx9K0;!Yv%^UIZx@$Dd;kCd literal 0 HcmV?d00001 diff --git a/addons/__pycache__/speechtool.cpython-312.pyc b/addons/__pycache__/speechtool.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c2964d46c311716a12a610bc479cd6db88091b3 GIT binary patch literal 4921 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 V2cDpA9v~4ttUjux-q(;o{~zsbsrLW? literal 0 HcmV?d00001 diff --git a/addons/__pycache__/sticklet.cpython-312.pyc b/addons/__pycache__/sticklet.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51891c1d45f82c36009200171a7d4c501bfb105d GIT binary patch literal 4335 zcmcIoYfK#16~6P@*X)zsg@y1~#{|6CK>YyXK!|bh0~;I@JB>_Jt(ToK%z7VWW&lHG zC0bYQqF4eaQdp`;CjCWZN234Se^C-OQEW@QU8G%4h!mw&TmG$MOHHWM_S}JCQ*5b9 z)sDnH-#zEtbI-ZwKF)H-X0sspUi)-#Gz;jDxTAm67I>Hfuz)x;ggAmDqr?!QQF4gX zC^bZBlpdmiQc)(x3^4@OrK5(JamW}m4Vhx*A+yF~qLvst#A?_OwZ?2iHo!*C6t#aq z5{N{+gEQZ<+$1(<=h$DMn_G?yIj6{gb$kfAmapGU`(I4NVxc%E`FkcpLNqiS<^9bT z%hxl%@n3vHNJ_F0z8vLcf0xW(k-INi{C@w%u*ipG-Y>$iM9i!5C366=rkfAAqt9oUju8wC+lg01n7&X)2oogH$eUlxj_ArVNjBgnaxoMMZoUP zk0UwiCb`K?l0QI~`T@E$#DSyR@kQ7j4Cr#S9*K0ujN`XGuA^_3?O3U;SQ&*8D-|YU ze|(H+don+1h*v7alUA8ybWe89a}LFy`fnmi8We+6`Q)5FVYaOdoid2-OI#LXJG)aS8sdFP$Ix11l%vm`0=GGod8s!>Y7OB-yi7LizyC%+> zG|Rhm8E4y;SiZMcp4R0hs%&2cNmhPF=SLcJRH6#2m~Yv)W3|cwUB+$4*NcAoGD1lk z>>g8OuP!f9&Y>6->n-PYgm%Twx$u$zB{7|bYZ7qT7LV3>NoUfbI5_v^UW6p0;@m=T zrNy7(JP`X2^8MO*8vUPqG)4B8;?)u7Rvb7o&NU6^4tmZ~?-GgEL?IPQp)XOlyf^91 zQ3R3?>fv>mP!D^kW7$coJE>XqBRp{9ykm8CwUy|vFBXxVA zK}25A`6a4*v3*XrP7dg!$dQtsjv_DWs6;^%vbyu*e3277d9XLO_nP8@aVHHeb|8*6ecgAb7&G> zp)R0FLbDqHyZgRpw+ifb5%2H5L9+ zA5fD-pz4gugcGsgei6^V4v!%c&48xe7f%Qiyg$bKr35tR;YGi=4!asZwalcz$)hS^ zQR$aY9PJ5^>riVT5#OExdi|e3M0|g4Hk#c(LwDLE@={`44D(X!C3x_q)+SlL1mNu zO*^s8>O-Y*aU&YB4<-yJ#SqNC*+vpVT*OCOrQ-aghzkOh#&wQ}gHR3O(S#7@MO+@h zU~!z6r^a}d0Uw|$DvLodLR5(JL2P$;IB`X__sHPy@VLxtrO@V#c)3*jziX?ckWh_B zr(|C0dr7s2NBQvOAS@9d55;(u-fX4N1Yn8hFRKQQhkA|&m!bj`QL0tq<6KaW(HI^L z$w7fr4VMxkEQo5!s@ z94`4xTJmuW7K}76gR1%XOJ~jpkN5Q-+srQ^s5D*z5uZ)fFv<%fqu{1y2q%#b#iTM2 zK_$B5+h}YZg)Q4UK0F?m$6H^C%3?y`T0be^z7f)U{e^pa^dIN4 zpEfQZEM0WNd_@nSw1?O8UpEbbWz#=4o%1_Rfb^XpE^$pviZAn<+ z(zcwhbJmt(-kbn6rfZ{Eh8XX+MH0N)knY3j`g!fZ^TZNy`dRwDo?QSxqTKxi`ly^Z z-AR8`aS-sw7UFa_{V_{nY(EG(pAbZU6a5K!v<^DIf4Zr^nf%n+2>8=OO#^Q9S?y5- zozH8Dfy4CYbv`WvacwM73e!`(Ut<9ZTw?luq@ zH_{k4*9|zCdsYhYJqLlYQ^W4Mfp+TN0S&hi7`J2ndz}Qd0hekF2DwBy7!+|Gr;-Ut z#09$8h#T$lr_T2EYj1=0ENs33)iSAKY=bTXCz#AL1qZzfs-NV zhjv6*zCh+LknIcP_!4>lg7#+7-Y-%2m+0`HkmG>?k+zKYnN_0U0og$q9#V*G)R2h( GYw#~Z(c}OC literal 0 HcmV?d00001 diff --git a/addons/__pycache__/tag.cpython-312.pyc b/addons/__pycache__/tag.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bca6d4bcdbb12b087c31c5f2d19ccaea02cac4d1 GIT binary patch literal 2972 zcmcImU2GFa5Z=A>@7YdllOKLcV^TnI06Pf+niK(XLLyW(RQyPlrOI4#MSZDwDGz-~6e`>md7)BOcnV4@wLEq9V#hH*1*z&v zx1O1unf-QlX4XIXd>n%DPH^AQ&n|?1rA%qqip0DL#04avI1;eH$T-EsSxjjbXj|NF z(KetRai>Mwfp*2+7VQ9_kDD& zxOv>4^@Xc4d5jQue|#*|rKVE6BIu#cqr4>Z{jwO^#BujWE{6`Cl!gs{keB5{TnNSi zelT=EO@~@rT0(D$seVz@L+U^%Im8>0N(&(+DSFwc)8eVF0lLpHP>(61R@UE3*$VXv z_x-A|#CZ(33f)R9nwTs*21Zm2IUDLs8q!g*bc#v~RVf>&iYzIMdQHbv?MMh@*^o34 zN^8mJLhCdj3zlX3iXj21CnFo0DhY{XN&vP>veXkP2$`fR zCnAswO{!wTc}>U(lU{=f5jA=1dQIyR!%d;4NORa+8$J+bh%?O_hNvmTGpMPVw4R`` zOG4%?4hK+Y;G2KUBJ?K0P!=XSytrH@hB3&C>0Fi~blAR>Tc8Det+>Z9BQV1(d^Y&( zCZn+?a}g;}Xu}ThM|Xc>9Ckk;02VZ@qOM#KY}f6j0y_i6d=gIZIdg&i&~8V=PSe?q z^7!2}Lc=c8b=X^JOSxe;$g7?q=Zru}YPyYJi7xG>tuk4`al!{4Six!Hqe#18Is}(d zThcULrSo4zml#Xap?px`wXUSQ=ykJcD|)pFZp*6-_?DOS%D?&{kgqKBB}zZ=5-4I7 zC|)VqE~02N?L`!JfwNGApMzrcb5I0cjA97}&Up1H3_7Q0i{s&f1O{brk-^skI(LVPIT$op%+IIv~(M-kJm~ODF2#{QWid09T;WNHmHuX zpKU{DU0<`uaM<7XfEKq#CxRX%;RjlfU6xXk@qiXHVN``+jv2n%f|Ltj(w;gwSv zs5|uV%4uS^8WCZkIT04RQ#eR$hIrf{zG53nqLzd`hVM}Li=ISzTe=ho-ek8~9{&$(zW zdY5aM<{BpO4A%%UmwTkM;O0hR1&?>6`8pbELaa6`V(P_Kl-V!CQ51Pj1gBrbJ(^ZxrA2)aLo|Wp_NQ3tnG7 zkn0)kEL1Pc>$#H!e{hT$-!a)Zvue}S%E(k*blM+1&)oCXkKysncYF=tBflosI~prg z*Nm|_b0T)7=W@?CZQpf#+wl^{{(L7O>3&(`JhK3`_KwHedG~l^GB~qxz+RmD@hSTyb1> zOlmhye0AdAG(Xus7W<-SyyuxZAIIi4L4@Zb^a|JI*5#Q`!XNEDwRf%+d3WKz=UR}x z=CR%i_kFsvq4y1ZYYpz*YP;3AyAGHiJG?O8b~Vwt1^2ewZnrup-Hu`I3kQfZkr32m zB0&NM&D|kYi5POk$fiYIqt#`luSN?_TT3VU<}PGBeL=NGIyvcNrMx?xEvBUg|9}yx zS>z)FiXIsf<+P|RR1MA2t7sl(q*3&bUE5Qtkdeh5T05|`@bz6V&9NBcM^*LM_GcTy wJ7>|ZS+sQ)ZJ9;eX3?5i6n*4CjIZF`UhvoaVP_fUk*fjM%)3jJ_BuHE2eZHIZU6uP literal 0 HcmV?d00001 diff --git a/addons/__pycache__/taglogger.cpython-312.pyc b/addons/__pycache__/taglogger.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b66e1f0b284fb67b86640f1e19c7d01eefda7225 GIT binary patch literal 17934 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/totalmsgs.cpython-312.pyc b/addons/__pycache__/totalmsgs.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f30622c1d97db2b32d6807c4984b03f5b82e48b7 GIT binary patch literal 1759 zcmZ`(T}&KR6ux(U_J3Ixx)e~_p)A5e%LX+?6Rc_2K2d1Y@=&Y}+np&pWM+rlnUOBt zZHP6d7!xEWg@l?kKH1PlAL|=`NgsS+L(SsE2U2~oK7qsp@x^oZhnB9r$-VR4^Yfj1 z?>T3F^7}mq#^p!vB^y|TexsZ6fPG=?_QGclNoW{JSYlMHF~bZ-5-V{k`v4GwWKQDm zI~H-#L2`bE7K;!K^J!PaZT$#a&yzdzLZ7Z_@swl;XFrK6YW#{S3#U9!roI(Mt}9tn zH{+^ij2a^z0ml2XX_1s6q;-o31)Ts&A)#9-Q&3Vu!XiWlm`KJ=PbG=)p=HP<71!jC zqP;{OSJP(>^S(%_UlpiF1@%*Umk742M`cr#6k}YCr$x&9lwKGVxMMPKaCYI{_O6Zy zNS)(x(}V*gO3y-BkOSsTn7h3ULj4HC!)DMJ)x0pq%Fq9tT*Boi&f*LvYzAkUR5$o@ z&l!~=^^oELs|OFdjUy~3_I3X);#+z zpl`UB#lR?ydeE2iFfX?tv%2gRM&wkM`~Uc6sBD!v;620-*}Kirm*_z}N-&ooGgbkd%#ZMh;xw8wA+j(6R0H=VQgMiG{v;tSBb8Pw3H_U7imk; zwlM@K?~zIOh>(p7ZY7$+MqH#&mQ%3Zl`?|){ zHWtY-a0|jT{)FWZv^RyeeEyjW(--o-=A5tjZu5pOJaz6Dr*AWGWSZM_duAHHXxywj zny-uG>LMF;o%!m{eBg90aC(~C3e?`>wi%WWZ`Rb#wa>QaYua)(ZQtSV-S^xNgGhl|(fjl>m;|8{aD0p&j+lBn+@jt(MkNkx&L=M%>4b2YSd1Ia| z^nCqsKG3orX!+UI^6xea+WjqW$KED4uy5Re>wbC`#a_kB4DNe{TV{h4hdTR?qZNev znz$9rQOq9$`AQ3p)pIN1ZosP{9BbrO>l_p}VX#>}?v91n)%K=XHM_>+n9H%|;3)QB zkgs`puw1L=DGqTIH)2=^BM#dsijtlXMZ3zBRoP7HsV>V@RHK-3WP7b*_QZrH6;gE% z?ZUwkX@X_n)vM`}rOIbWD{Se{)98W)Zi?}a!-=`SYY;y9I|}SL5aVADz4jQl?J#~k Oh<91Uv=<=>gUf&37^vs~ literal 0 HcmV?d00001 diff --git a/addons/__pycache__/truthdare.cpython-312.pyc b/addons/__pycache__/truthdare.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f32ecccdff081983e6dd1c6bcdffb9fad6cac05 GIT binary patch literal 1897 zcmeHH&2Jk;6rb5I@2=xC4g{%b6E;nVnl!c%gaYBCid%^TRV8Q;C_=K=p7mGv!_3YW z;@XncB2){c zJ!cwPLRFtMf7G(K$_;`&Qp&2Dre)tVh_=L*+LG?xNM`#+NXJIs<_cYfCQsRwuFXI{ zmNs;clnb7D-SMhV*{!J*&ekrL2&uXYsZ_zUi-v7rojBM{<{c}A>9yz-Tp{7$1Uu%E zQzd1`ey1h{;wkDRQq>7Du$?~+1v?UmwBMn|4I}=0}}4YhFWno3L6|@euGw#Le!t@Tliv{P zLM0Yz`!kY4k0^4QiYtSCU5FZD9aiGusy`#SE`A4)@&h0G`1=bXSOKqtZ*I~axzB$N zXVh!837Y313uU{g>BkAbPIO{ehE0-5E$fRx=zGx;vCL#u$F6~UqDKmeH@0b_3)rzT zhMjj1_26@*S1^lWEj~Lt8L)?uXLeRqvptyIR(#%YurHWp`-Ts(&le5iNAiwM=wUvW zbA7o`woyhmO2rDF^Eo$9f#tHiP`c9AJD(~!mXY#u zo=v>eM<&5e8KrcD9NRsj6{A$Ly5dX4;7xdfZXTuGy-kPT!LufKJQ!aswu-wiyty~H z(2*CKi;tApTBJ4JOg~c8)sfc7UHtXwjxyR-MyW_0xclMS*j900z1Y0`P#IV~+d8|3 z_LMUli*04RqfEAy$!7YY8eN@kP47N8y@@x`*2HdnZcj~gghX3N97KWg*0Tc@h{;~} z9KFWvk@PTJhv`9KWASAQAILC0Bs@?ghKC>>Ya)Bc)c*xQqjjSFy8<}#*8=GOW{mm* z3p7^fA((yWm=!c;b$dkeAxd(#;ZKfZRi0t$si}6$@nrhKJyHh zxOkXqSf$Nl_HW@4wgi~{J${tdBP*{=-a^5Pwn3N5LGaF={I=yF&oth}b5zE@VfQK> z4tNOR;gAf4?(+bS`~oI_1E(HGE;WTi32?EsPxj&XAt%9Pmj~R72Miq!GsVaIaEvJu MOc9tQ@CEAd5Bc%2ZU6uP literal 0 HcmV?d00001 diff --git a/addons/__pycache__/twitter.cpython-312.pyc b/addons/__pycache__/twitter.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5e69b965a4097ee8d9492a3efa9d184598e3463 GIT binary patch literal 12167 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 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/typing.cpython-312.pyc b/addons/__pycache__/typing.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b55e1a88354b17a3c35c7bff7dd9975022bb96d GIT binary patch literal 3487 zcmeHK&2Jl35PxsIyI!wl$Ej@N1e0#QtZq~%P$XJaNh;JuA+C1<46yIX$1 zUB9K2%tBt~CbLF*`Z~)2y&);4!I>GEn~@DeOv@bjaz;kGX>h7?L*@)ED{DEKQ^2Z_ zS90lb_L&p;>N5<;V;hexvaMAwof#kF-{%S2ofl10)^j%Vk)^7JC21+gwnNUDZv!8^ z38#4nVK{dY&3E2DH_p4BQ;tLlZyc>v!bNQKfhTp0716P}4LQ99>wHbDy1t+&^d6F2 zCE|Fm;)z}*xQh}gQ6;MAns@&*UXeU09!938V?W=jgO1i7CHiE~A{NkxpCDACix*Zvo~Iz9u`e-Z0WnM4J29^LsBcnA0)@K?Y|;48o{1BV{D zZerejRd>o|@x?33g3M*xg==P@U^!EBN>}CvEkE4d?x**=Pd5YI40JQl%|JH;|MLvk zxM-vFx8FGQ_!3XszN6+XkrmBU#-`G`X60>{tm!r>L$heRMWc{QDVj|gsx0Su#-`*2 zIcM4)C6~9%gkkD7Yh)Bf$%#qLv`OuTD%!qw^O!IS*`%gI6kT3WG|Nbs^2gws%80s{ zf~L{-9vM3G1_NJor%QF{aC9OAz37CMv~s33@qudUnj%ezlBDH~iMH2xzF^~o-Un`B zU?Tv%;vcA4Mo$BwdSJL37_JBSYJguKtOd@N-+Jr~HbVWYv-f5zrzdNnsd~>;g_&yf zo-V)L=nb#--RoPsSnG||y|J>;2)I_$5xQ>ml=8x5xScQrG&8Et5`#uP^*MkDn&8Oa2 zbB{*UaI-;1n|loMj5Zq#2OM+8L*q-x%xC9>A^ZatPLV(MgS6R$g&?^Zh&u9FEQHC; zxFc_Qun-})*tjE~$3j27b-|h64q_onZ-*j|9LK@{y*=*C@32_l=p8TP$Y28)ZegT_ z{Vj~PaG-^pgFI!s6AAcBNF;PWY)*GNX4`AEZ#a?4O064xhz?*L=@EcKW-_ZumMTx{ z1E4y;1V$WS&xJAG4^o&s@FU#wJL=h|5#hUgZC&^Uzp_sR@Zf<95$9Tx{t|fn1*r*3 A{r~^~ literal 0 HcmV?d00001 diff --git a/addons/__pycache__/unsplash.cpython-312.pyc b/addons/__pycache__/unsplash.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e755d4338dbd6d73d7bd67a074e78ed4e6f819c GIT binary patch literal 2344 zcmah~U2M}<6u#HKjuR(s(?UzDw$xo)){r*+StrEGkg`IyX%!Mf2oY^W!8U2CI1aYc zs>PAYU|SK@XkXSy11bBF#st&Y8{1w66eevi=>jBpJRtV4@iKwXBhN0Ca&b; zbB@1z&hha*pMR;U;s9Rn{Iq-QI|RV*#IP4#Q6BEX$|4X!7>H1$5>TeX6a*qIq696Y zFp`-tBRj$lnGLhDGwg(b0+Lf?&O6S*atx6@4$f7=gF5%a16s98HQE zADoEB6VZbSiSOmOyEC8hN8*`uQcESG+8Do0lcK6H#ve{g>eP0AnBSIEc;yhEiVNCy zj>l`S4SiFN#w31^g%5D|NLn8>tL;$bK=(*xKE`CD+Eh}AD`u6bOePabRE!*oCnS@L zNqR)n)p#;yQi^7}(+OQw;$lRQ#pzl*RyW@r*z7YpeK-M|it4(gCWXp7lf1x6+fVsLX!mcNdCFZ;?S5vU0ktL^mHjV9r0fXC@b^1{b9_uK z(jPDk*n_`ch7yqhCxAMjyX?IN949reSt7FIh_DGiv#kvETs%YYxW;GJr&rmD#MQH6 z$6i};hSqCrv;ht3JbR8R+y6l#18JSl&FHi__ftgJ2450rPNfpC#cI zF!vX}eiktI2z17gVJ7kOxs#SnWt^6Uv2($Shnoan)05CwvrEO)2Bw=|k55RvjHyA9 zC4CG}Hm@rcp14N_Yy}RhB$0XHcRY^-JNztSeQqpvYQbNKwrv*_ZS(%W0Zj;7* zWisWoG!ACcx`b2WttOOAN==#6$fyaYO%#`78ZHA%GWdi^D{JM&zA@aXzVyL#Qcw5o zEfZj0R1}q@)@M^-AT?!jWlqJegxZ6HkSWk6F%SL;9?gI|o|>Ykb=lKe^mHtHI+ zXH(JBv+U_9cmgv!Z@Imt`o_h53;Xh|uN3Nsi#5Y}=WvO0&y18nUZ(iBD=tz=5kvKjsAkSr^xlp zjNJBa%%;zdT=(`Dx&E1vTkh&g#?#@mu0reJ#oGCOtC?@V8v0TD;Xu(f`t8mO!3*kK zZ$r(Jv-I(|Kiq$G|E%`@f$OOAelzfHdwib*?%u~GuK&@Un&Fk-T%)Dtp_N~8 z5)^z?LJcb>>U^wygFnD~K@i#sFHtbmgf7v+Mr>SehM^X8xn(`k`(daJT^{Jd`jrM4 zYDZT#)Dhj+66$a)F$BNV3PV1$w9!HIPB!F6OFfo+iR`-C2t)noYSRXy<7k8E>VT8z zTU$ay=vqC4^=mDV$Tmy1Te5>C9zThBZP4-z5#%l(XR?uqs0fjWS(los9Jj!sq!y6l znou5$@+g#t!WtKH>{asjvJT!?;2~Cl>c?WmxlLBYbVAy$4q}u1m9;)B?$Z#$2h|Kj me^&z-_yYuQfZziMpsMoq-PfV-0p*2V4{1PcwlsAB@A(JM%QDyi literal 0 HcmV?d00001 diff --git a/addons/__pycache__/usernamelogger.cpython-312.pyc b/addons/__pycache__/usernamelogger.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cea21571983b3af070cf4d570ed2521a3b5043da GIT binary patch literal 4624 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 M8bNc=s0#i5CuQBMQUCw| literal 0 HcmV?d00001 diff --git a/addons/__pycache__/waifu.cpython-312.pyc b/addons/__pycache__/waifu.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a96519762e0d5d5e972fe063ee499d52c6bad4a5 GIT binary patch literal 2843 zcmZ`*S!^4}8J^jL_o34^SzFpds%0uBsl$y^TUF}D6yUga6GuW}r3JI%j;N(cuClwd zM1?AdBxtSHfE*x*>`IA*q-YbUK@GI;ZsN#&=!*mbC9};BSB;W;If5wnseoVhB>X>lw~gs{tXzxclJ%4_oMlqiqqgaMsQ>w~Yj1Zb0@ zrW1iK2ufB^fmO)}nl2}<5LJt~wy2nkTU50WHgI=N0`ziq`R6NPAa|@ngUv-e9&G(A!g>} zC6ZCD5&>vR)&%f?py(4s6|zb;tcl}9NKA;Tn9#u?!nkU>$5aZ1Sc6fC!D_iN!yCKs z!{^V%UpO;79J_QegjK4ZMs*S%cSa|a42kB(a#=kW9ZBn|B1=(Gl9a3#HA51a%o|RL z#Hb46dDRPS?UcV2ND+PM_Rc>&_w?K0m8O-KOYYuvu6G+Y(2RR0p3feObcY~3_DN9( zEx+z2$X4_Q^lb@@K9BI%Tvb4N%@qh7W98Rs&4F(~F24r*?=TDO&v+iqg6mSdj-(pw zv=o)Gr%8-;+bmOHv`fJGgsfLPVBNik6{c2p@6{mX*?)GH$#xWQ%D;c-e{5qdZLD$c z%^2lT5=q?qc$SrTz0tZ&Z?;gX#X|M5uGPArBfz^ks z-TIjNMjcy7vK9D!@nCE5uoY}t@X5AI_I;MtxTvKCo8$<9h}02FPJIO3+Uhe4!Kz^4 z`lxqU81|nKUrPtGdet&#*YmsjfCb;O?x~Oaa$xs-9-Txt@bz;hb)Q7nH=$pHu0Rh# zZ|*?)QR}8or1s3(|Bsj4^+*?XJw~HsX>Mu@n!m$QpPz)PgVAO9E@tgNwdZT&6rMuU z>}52CKW3+J$aB%)6G|rDtI}`F;5A)~_l6u>0?f9)NeQ)f>lh^=O1ddIMF~x@$GF4r z)he(&L)0-vpLyn@vRjmeaU};eYFtqTC{sdGzDlyft2v_PBf<-5B5F|1)x01kML8Q$ z>8Cslh039l$#g!hD~3&z(E>Hw z*b)L5=j%C z7|z&qf=ueNk_|ZwUd+mwoWV>_8ytP*44YXqHN!bBXT@|vOs5TgM~s6y9W>DlOf;Iz z^nIjFrB%n^O-A)JV4C$>9*X-v(8D77%7Gf1Z+v^Hd*w%^V7TOul%0{{_cz@QWp~?# zyRGc*+;DfUyjXH~70-U|_E+2u^Mk(_tOVQ3!QPEvZz0|N0-C5!XMg7!D#6~&qhN}@m$4!=-QQ~(8}4x z=z5@g-Sbp2R%N{WKqb(&eE8Pka-eS`(6`?I+@D5Df%E0&^Vb}o`wv!jWUU8>OHCtX z&&axG1mskF2X4GNcctuW-|)3pJdN`g<}OrPgXPxljn?ijnh)OOmwmTr zSml6=E;xgazHqnv6Jb!<*D#-)ORgX4{bR>%@efCDA6h?fs^mLecAWmJb#b2@IS%+!CysSC($K#Tch{shYn4{8S zpwh&HR97;S@J*`pZB%Kc*!e!(xt*Vfcp@X2nfMV>eRP**=wrt~Mv-!9GN^tJru5%K zy9@+8hVcU%kGX9h!mhs|@0ZBG*$}+JEV$lsRT&TO+-7}^Own5v7~FTWzlva3>EEWq Z0|#Qf6;I$RmSLC&wjdtZwp+*){a;6*z^ecN literal 0 HcmV?d00001 diff --git a/addons/__pycache__/warn.cpython-312.pyc b/addons/__pycache__/warn.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6097e40ad819bea838c4bb8a252b3e358da8001 GIT binary patch literal 10942 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 ah{8o{7Ypx`Ef3g2qI<|O>{g1=Vf`PHED|{Y literal 0 HcmV?d00001 diff --git a/addons/__pycache__/weather.cpython-312.pyc b/addons/__pycache__/weather.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b806d13c0227c597f7cea7a482f74ee267acb1d6 GIT binary patch literal 11776 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 XEIaWb*>Fqu7%^bcM#@Ql2G#!ucuO;3 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/webupload.cpython-312.pyc b/addons/__pycache__/webupload.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2a9d30900556e1850cd9deace7c52aaaaa80b0c GIT binary patch literal 3990 zcmcgvU2GHC6~1>oGafr*$HByj!A=Z<1p~2@g(bkk?j`|JC`naVwlrGgop>hp7<(q2 z8582Qx3pWeNsAPCX+X=0P*qwGR87@Nn?CgqEn2FrY#eFa5f5mqs$KP=L0PFAo_g;% z6E9X!+CKD3KKDEKo}YWp{h8xGx?E0x+MD;ko_x&#z+W(9HQO>+Jc+Gi9jJ~@-&Bwh{moae+eH=Gti9Zu(`7k?6Z>us?xCJbjs(=x}uQ|$?fVo33J}>Kt9oCiDdeNR@q}e1 zh4!(&S$QuI$fCL9&q`>l#h-`D4$Wn8DYu1cz1C#m)ooep5P`T7Aq06s8Pe8SnyK{` zs`aUs8n#e=B`VdQhpXk2w^{z`vv&<i`qZTK&ionrXHC)%t@7UWO8dW;fJEEu=g~ z<3Wq7^;Vwi*HWzDf6( zlRFM-%LNzGiydY`0%_oJ?^ms^<&DtO&E1`sVUZ^tYqn(UI zB02j=`o*+#F7y;0Q1F#NA9O~+YB5bV=s2eh%NKIak#rSBqiCMwIgK+IP2nVUL{M_< z2&xgPI2twVxDFW>rCh^EdKpHeIlA*gXGGPor7A*Wres8vElC8CKCOzJdTty`RuPhH z?@P+EDuhm%6%7t(x#q!1LQ&u#@ z&8T6ICpj%9@(O;F4LUoD!V(OdC}{>Es|JZPWYA{jRf7tU zv?vL&Z)F8#T%qy$2sFuLQAuZtQOI8WoI&$KT0pfIWkyg{GDzf63p*5Cv>3#N3kJ0u zy}43@#G7Kkm|;gp1yy&dVUJa-L8TdKsJL3fRi)XUZjUDAj1bKZXC*BgJzXsZqa4r6 zk{Vqp2P3273Vtn3;=@+{fzHz3!50_7?9H>~ zO}l4L7DM~ynf-sZvyU2^rp6}6rrw!+=c+K@xTWIXc*A$iR}8&W_V3lbdyDMe%AWo6 zOzYL=8^LSA60_|V^>gMnQ)ap<4!7=Td+2DZ_%`akj*_pV?2GE2=mb@1@Jzk@!z+0TFcn3lJ^t$^MDMmp3iYpbz%L`{Cb( z*Ra~$GX2JtH;RGR%FR7`V^5Lk!HYaNc~EZ%JZuP5T7x&(YpmYdRch^e#CoRsC;N3a zP+|i!b`-Gdwrl3wv)ml@8|K%{Y_8bWyJ#c)PP7uQbHa{R(dfI(O{R2rTglyaHG89Q ztuUL_yHAw5PZZs4W%q#23>2AxirX_KPKrM|r!)Q%<41bFjnikZoW1^*sqF4yI-UbBVcc7Nh<1p06xWHkbQz zr==jyHq7#VD7%m8%&`)4Y~dRa zI3r67ELh*Ygd%I|Tzc$1f)LuQr3EMO^unbD66Fg|ItJlVh4Fu}umw1d!>8(p=+J++ zZO{W};J_a8W-o@ne-#dNlYam`6k_gCaNq!WkKTgu4mfa#ytlJwGh#k+!9hTN5VOppCr0t!F16Ps%u9b8EFuV$eTY0|4rXLNn-*SCUO_DW)2Hr1WWfd@eBz-Xx#$Ma`B%{S iH?X@5c0Zv3;VL$V=i!bg#4dOoF4_RGvkDdbA^tbHNNnB! literal 0 HcmV?d00001 diff --git a/addons/__pycache__/whichsong.cpython-312.pyc b/addons/__pycache__/whichsong.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a6ddc6d3bee8f4ff2be7a7fc2f8e4a78feb5a38 GIT binary patch literal 2270 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 M5i`=}j3My<8?0_rvH$=8 literal 0 HcmV?d00001 diff --git a/addons/__pycache__/words.cpython-312.pyc b/addons/__pycache__/words.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7485d4c2fdfc11951c970185ed66eb9473d848b GIT binary patch literal 6722 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 Mz#}U~`U$-2-}7LkW&i*H literal 0 HcmV?d00001 diff --git a/addons/__pycache__/ziptools.cpython-312.pyc b/addons/__pycache__/ziptools.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39e4378c14d24b6d8705eb08b0a4a9fd708a4fda GIT binary patch literal 9789 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 literal 0 HcmV?d00001 diff --git a/addons/activitygen.py b/addons/activitygen.py new file mode 100644 index 0000000..2f094bd --- /dev/null +++ b/addons/activitygen.py @@ -0,0 +1,31 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available - + +โ€ข `{i}bored` + Get some activity to do when you get bored +""" + +from . import async_searcher, ultroid_cmd + + +@ultroid_cmd(pattern="bored$") +async def bored_cmd(event): + msg = await event.eor("`Generating an Activity for You!`") + content = await async_searcher( + "https://bored-api.appbrewery.com/random", re_json=True + ) + m = f"**Activity:** `{content['activity']}`" + if content.get("link"): + m += f"\n**Read More:** {content['link']}" + if content.get("participants"): + m += f"\n**Participants Required:** `{content['participants']}`" + if content.get("price"): + m += f"\n**Price:** `{content['price']}`" + await msg.edit(m) \ No newline at end of file diff --git a/addons/addons.txt b/addons/addons.txt new file mode 100644 index 0000000..7f2f21f --- /dev/null +++ b/addons/addons.txt @@ -0,0 +1,18 @@ +covid +emoji +fonttools +gtts +gingerit +jikanpy +git+https://github.com/New-dev0/AsyncLyricsExtractor.git +phlogo +pokedex.py +pyfiglet +pygments +pyjokes +quotefancy +shazamio +speechrecognition +speedtest-cli +textblob +wikipedia diff --git a/addons/afk.py b/addons/afk.py new file mode 100644 index 0000000..74e06eb --- /dev/null +++ b/addons/afk.py @@ -0,0 +1,165 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_afk") + + +import asyncio + +from telethon import events + +from pyUltroid.dB.afk_db import add_afk, del_afk, is_afk +from pyUltroid.dB.base import KeyManager + +from . import ( + LOG_CHANNEL, + NOSPAM_CHAT, + Redis, + asst, + get_string, + mediainfo, + udB, + ultroid_bot, + ultroid_cmd, + upload_file +) + +old_afk_msg = [] + +is_approved = KeyManager("PMPERMIT", cast=list).contains + + +@ultroid_cmd(pattern="afk( (.*)|$)", owner_only=True) +async def set_afk(event): + if event.client._bot or is_afk(): + return + text, media, media_type = None, None, None + if event.pattern_match.group(1).strip(): + text = event.text.split(maxsplit=1)[1] + reply = await event.get_reply_message() + if reply: + if reply.text and not text: + text = reply.text + if reply.media: + media_type = mediainfo(reply.media) + if media_type.startswith(("pic", "gif")): + file = await event.client.download_media(reply.media) + media = upload_file(file) + else: + media = reply.file.id + await event.eor("`Done`", time=2) + add_afk(text, media_type, media) + ultroid_bot.add_handler(remove_afk, events.NewMessage(outgoing=True)) + ultroid_bot.add_handler( + on_afk, + events.NewMessage( + incoming=True, func=lambda e: bool(e.mentioned or e.is_private) + ), + ) + msg1, msg2 = None, None + if text and media: + if "sticker" in media_type: + msg1 = await ultroid_bot.send_file(event.chat_id, file=media) + msg2 = await ultroid_bot.send_message( + event.chat_id, get_string("afk_5").format(text) + ) + else: + msg1 = await ultroid_bot.send_message( + event.chat_id, get_string("afk_5").format(text), file=media + ) + elif media: + if "sticker" in media_type: + msg1 = await ultroid_bot.send_file(event.chat_id, file=media) + msg2 = await ultroid_bot.send_message(event.chat_id, get_string("afk_6")) + else: + msg1 = await ultroid_bot.send_message( + event.chat_id, get_string("afk_6"), file=media + ) + elif text: + msg1 = await event.respond(get_string("afk_5").format(text)) + else: + msg1 = await event.respond(get_string("afk_6")) + old_afk_msg.append(msg1) + if msg2: + old_afk_msg.append(msg2) + return await asst.send_message(LOG_CHANNEL, msg2.text) + await asst.send_message(LOG_CHANNEL, msg1.text) + + +async def remove_afk(event): + if event.is_private and udB.get_key("PMSETTING") and not is_approved(event.chat_id): + return + elif "afk" in event.text.lower(): + return + elif event.chat_id in NOSPAM_CHAT: + return + if is_afk(): + _, _, _, afk_time = is_afk() + del_afk() + off = await event.reply(get_string("afk_1").format(afk_time)) + await asst.send_message(LOG_CHANNEL, get_string("afk_2").format(afk_time)) + for x in old_afk_msg: + try: + await x.delete() + except BaseException: + pass + await asyncio.sleep(10) + await off.delete() + + +async def on_afk(event): + if event.is_private and Redis("PMSETTING") and not is_approved(event.chat_id): + return + elif "afk" in event.text.lower(): + return + elif not is_afk(): + return + if event.chat_id in NOSPAM_CHAT: + return + sender = await event.get_sender() + if sender.bot or sender.verified: + return + text, media_type, media, afk_time = is_afk() + msg1, msg2 = None, None + if text and media: + if "sticker" in media_type: + msg1 = await event.reply(file=media) + msg2 = await event.reply(get_string("afk_3").format(afk_time, text)) + else: + msg1 = await event.reply( + get_string("afk_3").format(afk_time, text), file=media + ) + elif media: + if "sticker" in media_type: + msg1 = await event.reply(file=media) + msg2 = await event.reply(get_string("afk_4").format(afk_time)) + else: + msg1 = await event.reply(get_string("afk_4").format(afk_time), file=media) + elif text: + msg1 = await event.reply(get_string("afk_3").format(afk_time, text)) + else: + msg1 = await event.reply(get_string("afk_4").format(afk_time)) + for x in old_afk_msg: + try: + await x.delete() + except BaseException: + pass + old_afk_msg.append(msg1) + if msg2: + old_afk_msg.append(msg2) + + +if udB.get_key("AFK_DB"): + ultroid_bot.add_handler(remove_afk, events.NewMessage(outgoing=True)) + ultroid_bot.add_handler( + on_afk, + events.NewMessage( + incoming=True, func=lambda e: bool(e.mentioned or e.is_private) + ), + ) diff --git a/addons/animations.py b/addons/animations.py new file mode 100644 index 0000000..4c7d722 --- /dev/null +++ b/addons/animations.py @@ -0,0 +1,46 @@ +# Ultroid Userbot +# 2020 Copyright (c) + +# Animation Plugin + +""" + Animation Plugin + +โœ˜ Commands Available + +โ€ข `{i}kill` +โ€ข `{i}fp` + +""" + +import asyncio + + +@ultroid_cmd(pattern="kill$") +async def _(event): + animation_interval = 0.7 + animation_ttl = range(0, 12) + a = await event.eor("`ready to die dude.....`") + animation_chars = [ + "๏ผฆ๏ฝ‰๏ฝ‰๏ฝ‰๏ฝ‰๏ฝ‰๏ฝ’๏ฝ…", + "(ใ€€๏ฝฅเธดฯ‰๏ฝฅเธด)๏ธปใƒ‡โ•ไธ€-->", + "---->____________โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ ", + "------>__________โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ ", + "-------->โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ _________", + "---------->โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ _______", + "------------>โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ _____", + "-------------->โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ ____", + "------------------>", + "------>;(^ใ€‚^)ใƒŽ", + "(๏ฟฃใƒผ๏ฟฃ) DEAD", + """`Targeted user killed by Headshot๐Ÿ˜ˆ.๐Ÿ˜ˆ.๐Ÿ˜ˆ.๐Ÿ˜ˆ.๐Ÿ˜ˆ.๐Ÿ˜ˆ.๐Ÿ˜ˆ......` + `#Sad_Reacts_Offline`\n""", + ] + for i in animation_ttl: + await asyncio.sleep(animation_interval) + await a.edit(animation_chars[i % 12]) + + +@ultroid_cmd(pattern="fp$") +async def a(e): + await e.eor("๐Ÿคฆโ€โ™‚") diff --git a/addons/anime.py b/addons/anime.py new file mode 100644 index 0000000..dd3b230 --- /dev/null +++ b/addons/anime.py @@ -0,0 +1,45 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2022 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available - + +โ€ข `{i}character ` + Fetch anime character details. +""" + +import jikanpy + +from . import * + + +@ultroid_cmd(pattern="character ?(.*)") +async def anime_char_search(event): + xx = await event.eor(get_string("com_1")) + char_name = event.pattern_match.group(1) + if not char_name: + await eod(xx, "`Enter the name of a character too please!`", time=5) + jikan = jikanpy.jikan.Jikan() + try: + s = jikan.search("character", char_name) + except jikanpy.exceptions.APIException: + return await eod(xx, "`Couldn't find character!`", time=5) + a = s["results"][0]["mal_id"] + char_json = jikan.character(a) + pic = char_json["image_url"] + msg = f"**[{char_json['name']}]({char_json['url']})**" + if char_json["name_kanji"] != "Japanese": + msg += f" [{char_json['name_kanji']}]\n" + else: + msg += "\n" + if char_json["nicknames"]: + nicknames_string = ", ".join(char_json["nicknames"]) + msg += f"\n**Nicknames** : `{nicknames_string}`\n" + about = char_json["about"].split("\n", 1)[0].strip().replace("\n", "") + msg += f"\n**About**: __{about}__" + await event.reply(msg, file=pic, force_document=False) + await xx.delete() diff --git a/addons/animechan.py b/addons/animechan.py new file mode 100644 index 0000000..c7796c0 --- /dev/null +++ b/addons/animechan.py @@ -0,0 +1,25 @@ +# Ultroid - UserBot +# +# This file is a part of < https://github.com/TeamUltroid/UltroidAddons/> + +""" +Fetch Random anime quotes + +Command : `{i}aniquote` +""" + +from . import ultroid_cmd, async_searcher + + +@ultroid_cmd(pattern="aniquote") +async def _(ult): + u = await ult.eor("...") + try: + resp = await async_searcher( + "https://animechan.vercel.app/api/random", re_json=True + ) + results = f"**{resp['quote']}**\n" + results += f" โ€” __{resp['character']} ({resp['anime']})__" + return await u.edit(results) + except Exception: + await u.edit("`Something went wrong LOL ...`") diff --git a/addons/animedb.py b/addons/animedb.py new file mode 100644 index 0000000..2e538bc --- /dev/null +++ b/addons/animedb.py @@ -0,0 +1,35 @@ +# Made by : @Arnab431 || github.com/ArnabXD +# Made For : https://github.com/TeamUltroid/UltroidAddons + +""" +Search animes and manga from anilist.co using @animedb_bot + +โœ˜ Commands Available + +โ€ข `{i}manga ` + To get manga info +""" + + +from . import * + + +@ultroid_cmd( + pattern="manga ?(.*)", +) +async def manga(ult): + msg = await ult.eor("`Searching ...`") + keyword = ult.pattern_match.group(1) + if keyword is None: + return await msg.edit("`Provide a Keyword to search`") + try: + animes = await ult.client.inline_query("animedb_bot", f" {keyword}") + await animes[0].click( + ult.chat_id, + reply_to=ult.reply_to_msg_id, + silent=True if ult.is_reply else False, + hide_via=True, + ) + return await msg.delete() + except Exception: + return await msg.edit("`No Results Found ...`") diff --git a/addons/antiflood.py b/addons/antiflood.py new file mode 100644 index 0000000..b62c253 --- /dev/null +++ b/addons/antiflood.py @@ -0,0 +1,144 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_antiflood") + + +import re + +from telethon.events import NewMessage as NewMsg + +from pyUltroid.dB import DEVLIST +from pyUltroid.fns.admins import admin_check + +from . import Button, Redis, asst, callback, eod, get_string, udB, ultroid_bot, ultroid_cmd + +# Functions moved from antiflood_db.py +def get_flood(): + return udB.get_key("ANTIFLOOD") or {} + + +def set_flood(chat_id, limit): + omk = get_flood() + omk.update({chat_id: limit}) + return udB.set_key("ANTIFLOOD", omk) + + +def get_flood_limit(chat_id): + omk = get_flood() + if chat_id in omk.keys(): + return omk[chat_id] + + +def rem_flood(chat_id): + omk = get_flood() + if chat_id in omk.keys(): + del omk[chat_id] + return udB.set_key("ANTIFLOOD", omk) + + +_check_flood = {} + +if Redis("ANTIFLOOD"): + + @ultroid_bot.on( + NewMsg( + chats=list(get_flood().keys()), + ), + ) + async def flood_checm(event): + count = 1 + chat = (await event.get_chat()).title + if event.chat_id in _check_flood.keys(): + if event.sender_id == list(_check_flood[event.chat_id].keys())[0]: + count = _check_flood[event.chat_id][event.sender_id] + _check_flood[event.chat_id] = {event.sender_id: count + 1} + else: + _check_flood[event.chat_id] = {event.sender_id: count} + else: + _check_flood[event.chat_id] = {event.sender_id: count} + if await admin_check(event, silent=True) or getattr(event.sender, "bot", None): + return + if event.sender_id in DEVLIST: + return + if _check_flood[event.chat_id][event.sender_id] >= int( + get_flood_limit(event.chat_id) + ): + try: + name = event.sender.first_name + await event.client.edit_permissions( + event.chat_id, event.sender_id, send_messages=False + ) + del _check_flood[event.chat_id] + await event.reply(f"#AntiFlood\n\n{get_string('antiflood_3')}") + await asst.send_message( + int(Redis("LOG_CHANNEL")), + f"#Antiflood\n\n`Muted `[{name}](tg://user?id={event.sender_id})` in {chat}`", + buttons=Button.inline( + "Unmute", data=f"anti_{event.sender_id}_{event.chat_id}" + ), + ) + except BaseException: + pass + + +@callback( + re.compile( + "anti_(.*)", + ), +) +async def unmuting(e): + ino = (e.data_match.group(1)).decode("UTF-8").split("_") + user = int(ino[0]) + chat = int(ino[1]) + user_name = (await ultroid_bot.get_entity(user)).first_name + chat_title = (await ultroid_bot.get_entity(chat)).title + await ultroid_bot.edit_permissions(chat, user, send_messages=True) + await e.edit( + f"#Antiflood\n\n`Unmuted `[{user_name}](tg://user?id={user})` in {chat_title}`" + ) + + +@ultroid_cmd( + pattern="setflood ?(\\d+)", + admins_only=True, +) +async def setflood(e): + input_ = e.pattern_match.group(1).strip() + if not input_: + return await e.eor("`What?`", time=5) + if not input_.isdigit(): + return await e.eor(get_string("com_3"), time=5) + if m := set_flood(e.chat_id, input_): + return await eod(e, get_string("antiflood_4").format(input_)) + + +@ultroid_cmd( + pattern="remflood$", + admins_only=True, +) +async def remove_flood(e): + hmm = rem_flood(e.chat_id) + try: + del _check_flood[e.chat_id] + except BaseException: + pass + if hmm: + return await e.eor(get_string("antiflood_1"), time=5) + await e.eor(get_string("antiflood_2"), time=5) + + +@ultroid_cmd( + pattern="getflood$", + admins_only=True, +) +async def getflood(e): + if ok := get_flood_limit(e.chat_id): + return await e.eor(get_string("antiflood_5").format(ok), time=5) + await e.eor(get_string("antiflood_2"), time=5) diff --git a/addons/asstcmd.py b/addons/asstcmd.py new file mode 100644 index 0000000..5957b09 --- /dev/null +++ b/addons/asstcmd.py @@ -0,0 +1,129 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_asstcmd") + +import os + +from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button +from telethon import events, utils + +from . import asst, get_string, mediainfo, udB, ultroid_cmd, upload_file + +# Functions moved from asstcmd_db.py +def get_stuff(): + return udB.get_key("ASST_CMDS") or {} + + +def add_cmd(cmd, msg, media, button): + ok = get_stuff() + ok.update({cmd: {"msg": msg, "media": media, "button": button}}) + return udB.set_key("ASST_CMDS", ok) + + +def rem_cmd(cmd): + ok = get_stuff() + if ok.get(cmd): + ok.pop(cmd) + return udB.set_key("ASST_CMDS", ok) + + +def cmd_reply(cmd): + ok = get_stuff() + if ok.get(cmd): + okk = ok[cmd] + return okk["msg"], okk["media"], okk["button"] if ok.get("button") else None + return + + +def list_cmds(): + ok = get_stuff() + return ok.keys() + + +@ultroid_cmd(pattern="addcmd( (.*)|$)") +async def ac(e): + wrd = (e.pattern_match.group(1).strip()).lower() + wt = await e.get_reply_message() + if not (wt and wrd): + return await e.eor(get_string("asstcmd_1"), time=5) + if "/" in wrd: + wrd = wrd.replace("/", "") + btn = format_btn(wt.buttons) if wt.buttons else None + if wt and wt.media: + wut = mediainfo(wt.media) + if wut.startswith(("pic", "gif")): + dl = await e.client.download_media(wt.media) + m = upload_file(dl) + os.remove(dl) + elif wut == "video": + if wt.media.document.size > 8 * 1000 * 1000: + return await e.eor(get_string("com_4"), time=5) + dl = await e.client.download_media(wt.media) + m = upload_file(dl) + os.remove(dl) + else: + m = utils.pack_bot_file_id(wt.media) + if wt.text: + txt = wt.text + if not btn: + txt, btn = get_msg_button(wt.text) + add_cmd(wrd, txt, m, btn) + else: + add_cmd(wrd, None, m, btn) + else: + txt = wt.text + if not btn: + txt, btn = get_msg_button(wt.text) + add_cmd(wrd, txt, None, btn) + asst.add_handler( + astcmds, + events.NewMessage( + func=lambda x: x.text.startswith("/") and x.text[1:] in list(list_cmds()) + ), + ) + await e.eor(get_string("asstcmd_4").format(wrd)) + + +@ultroid_cmd(pattern="remcmd( (.*)|$)") +async def rc(e): + wrd = (e.pattern_match.group(1).strip()).lower() + if not wrd: + return await e.eor(get_string("asstcmd_2"), time=5) + wrd = wrd.replace("/", "") + rem_cmd(wrd) + await e.eor(get_string("asstcmd_3").format(wrd)) + + +@ultroid_cmd(pattern="listcmd$") +async def lscmd(e): + if list_cmds(): + ok = get_string("asstcmd_6") + for x in list_cmds(): + ok += f"/{x}" + "\n" + return await e.eor(ok) + return await e.eor(get_string("asstcmd_5")) + + +async def astcmds(e): + xx = (e.text.replace("/", "")).lower().split()[0] + if cmd_reply(xx): + msg, media, bt = cmd_reply(xx) + if bt: + bt = create_tl_btn(bt) + await e.reply(msg, file=media, buttons=bt) + + +if udB.get_key("ASST_CMDS"): + asst.add_handler( + astcmds, + events.NewMessage( + func=lambda x: x.text.startswith("/") and x.text[1:] in list(list_cmds()) + ), + ) diff --git a/addons/astronomy.py b/addons/astronomy.py new file mode 100644 index 0000000..6c3fd70 --- /dev/null +++ b/addons/astronomy.py @@ -0,0 +1,39 @@ +# Ultroid Userbot +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available - + +โ€ข `{i}apod`` + Get Astronomy Picture of Day by NASA +""" + +from bs4 import BeautifulSoup as bs + +from . import ultroid_cmd, async_searcher + + +@ultroid_cmd(pattern="apod$") +async def aposj(e): + link = "https://apod.nasa.gov/apod/" + C = await async_searcher(link) + m = bs(C, "html.parser", from_encoding="utf-8") + try: + try: + img = m.find_all("img")[0]["src"] + img = link + img + except IndexError: + img = None + expla = m.find_all("p")[2].text.replace("\n", " ") + expla = expla.split(" ")[0] + if len(expla) > 900: + expla = expla[:900] + "..." + expla = "__" + expla + "__" + await e.reply(expla, file=img) + if e.out: + await e.delete() + except Exception as E: + return await eod(e, str(E)) diff --git a/addons/audiotools.py b/addons/audiotools.py new file mode 100644 index 0000000..40343bb --- /dev/null +++ b/addons/audiotools.py @@ -0,0 +1,163 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + + +import os +import time +from datetime import datetime as dt + +from pyUltroid.fns.tools import set_attributes + +from . import ( + LOGS, + ULTConfig, + bash, + downloader, + eod, + eor, + genss, + get_help, + get_string, + humanbytes, + mediainfo, + stdr, + time_formatter, + ultroid_cmd +) + +__doc__ = get_help("help_audiotools") + + +@ultroid_cmd(pattern="makevoice$") +async def vnc(e): + if not e.reply_to: + return await eod(e, get_string("audiotools_1")) + r = await e.get_reply_message() + if not mediainfo(r.media).startswith(("audio", "video")): + return await eod(e, get_string("spcltool_1")) + xxx = await e.eor(get_string("com_1")) + file, _ = await e.client.fast_downloader( + r.document, + ) + await xxx.edit(get_string("audiotools_2")) + await bash( + f"ffmpeg -i '{file.name}' -map 0:a -codec:a libopus -b:a 100k -vbr on out.opus" + ) + try: + await e.client.send_message( + e.chat_id, file="out.opus", force_document=False, reply_to=r + ) + except Exception as er: + LOGS.exception(er) + return await xxx.edit("`Failed to convert in Voice...`") + await xxx.delete() + os.remove(file.name) + os.remove("out.opus") + + +@ultroid_cmd(pattern="atrim( (.*)|$)") +async def trim_aud(e): + sec = e.pattern_match.group(1).strip() + if not sec or "-" not in sec: + return await eod(e, get_string("audiotools_3")) + a, b = sec.split("-") + if int(a) >= int(b): + return await eod(e, get_string("audiotools_4")) + vido = await e.get_reply_message() + if vido and vido.media and mediainfo(vido.media).startswith(("video", "audio")): + if hasattr(vido.media, "document"): + vfile = vido.media.document + name = vido.file.name + else: + vfile = vido.media + name = "" + if not name: + name = dt.now().isoformat("_", "seconds") + ".mp4" + xxx = await e.eor(get_string("audiotools_5")) + c_time = time.time() + file = await downloader( + f"resources/downloads/{name}", + vfile, + xxx, + c_time, + f"Downloading {name}...", + ) + + o_size = os.path.getsize(file.name) + d_time = time.time() + diff = time_formatter((d_time - c_time) * 1000) + file_name = (file.name).split("/")[-1] + out = file_name.replace(file_name.split(".")[-1], "_trimmed.aac") + if int(b) > int(await genss(file.name)): + os.remove(file.name) + return await eod(xxx, get_string("audiotools_6")) + ss, dd = stdr(int(a)), stdr(int(b)) + xxx = await xxx.edit( + f"Downloaded `{file.name}` of `{humanbytes(o_size)}` in `{diff}`.\n\nNow Trimming Audio from `{ss}` to `{dd}`..." + ) + cmd = f'ffmpeg -i "{file.name}" -preset ultrafast -ss {ss} -to {dd} -vn -acodec copy "{out}" -y' + await bash(cmd) + os.remove(file.name) + f_time = time.time() + n_file, _ = await e.client.fast_uploader( + out, show_progress=True, event=e, message="Uploading...", to_delete=True + ) + attributes = await set_attributes(out) + + caption = get_string("audiotools_7").format(ss, dd) + await e.client.send_file( + e.chat_id, + n_file, + thumb=ULTConfig.thumb, + caption=caption, + attributes=attributes, + force_document=False, + reply_to=e.reply_to_msg_id, + ) + await xxx.delete() + else: + await e.eor(get_string("audiotools_1"), time=5) + + +@ultroid_cmd(pattern="extractaudio$") +async def ex_aud(e): + reply = await e.get_reply_message() + if not (reply and reply.media and mediainfo(reply.media).startswith("video")): + return await e.eor(get_string("audiotools_8")) + name = reply.file.name or "video.mp4" + vfile = reply.media.document + msg = await e.eor(get_string("com_1")) + c_time = time.time() + file = await downloader( + f"resources/downloads/{name}", + vfile, + msg, + c_time, + f"Downloading {name}...", + ) + + out_file = f"{file.name}.aac" + cmd = f"ffmpeg -i {file.name} -vn -acodec copy {out_file}" + o, err = await bash(cmd) + os.remove(file.name) + attributes = await set_attributes(out_file) + + f_time = time.time() + try: + n_file, _ = await e.client.fast_uploader( + out_file, show_progress=True, event=e, message="Uploading...", to_delete=True + ) + + except FileNotFoundError: + return await eor(msg, get_string("audiotools_9")) + await e.reply( + get_string("audiotools_10"), + file=n_file, + thumb=ULTConfig.thumb, + attributes=attributes, + ) + await msg.delete() diff --git a/addons/autoban.py b/addons/autoban.py new file mode 100644 index 0000000..ab002ba --- /dev/null +++ b/addons/autoban.py @@ -0,0 +1,59 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_autoban") + +from telethon import events + +from pyUltroid.dB.base import KeyManager + +from . import LOGS, asst, ultroid_bot, ultroid_cmd + +Keym = KeyManager("DND_CHATS", cast=list) + + +def join_func(e): + return e.user_joined and Keym.contains(e.chat_id) + + +async def dnd_func(event): + for user in event.users: + try: + await (await event.client.kick_participant(event.chat_id, user)).delete() + except Exception as ex: + LOGS.error("Error in DND:") + LOGS.exception(ex) + await event.delete() + + +@ultroid_cmd( + pattern="autokick (on|off)$", + admins_only=True, + manager=True, + require="ban_users", + fullsudo=True, +) +async def _(event): + match = event.pattern_match.group(1) + if match == "on": + if Keym.contains(event.chat_id): + return await event.eor("`Chat already in do not disturb mode.`", time=3) + Keym.add(event.chat_id) + event.client.add_handler(dnd_func, events.ChatAction(func=join_func)) + await event.eor("`Do not disturb mode activated for this chat.`", time=3) + elif match == "off": + if not Keym.contains(event.chat_id): + return await event.eor("`Chat is not in do not disturb mode.`", time=3) + Keym.remove(event.chat_id) + await event.eor("`Do not disturb mode deactivated for this chat.`", time=3) + + +if Keym.get(): + ultroid_bot.add_handler(dnd_func, events.ChatAction(func=join_func)) + asst.add_handler(dnd_func, events.ChatAction(func=join_func)) diff --git a/addons/autocorrect.py b/addons/autocorrect.py new file mode 100644 index 0000000..edb4116 --- /dev/null +++ b/addons/autocorrect.py @@ -0,0 +1,59 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2022 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_autocorrect") + +import string + +from . import HNDLR, LOGS, get_string, udB, ultroid_bot, ultroid_cmd # ignore: pylint + +try: + from gingerit.gingerit import GingerIt +except ImportError: + LOGS.info("GingerIt not found") + GingerIt = None + +from google_trans_new import google_translator +from telethon import events + + +@ultroid_cmd(pattern="autocorrect", fullsudo=True) +async def acc(e): + if not udB.get_key("AUTOCORRECT"): + udB.set_key("AUTOCORRECT", "True") + ultroid_bot.add_handler( + gramme, events.NewMessage(outgoing=True, func=lambda x: x.text) + ) + return await e.eor(get_string("act_1"), time=5) + udB.del_key("AUTOCORRECT") + await e.eor(get_string("act_2"), time=5) + + +async def gramme(event): + if not udB.get_key("AUTOCORRECT"): + return + t = event.text + if t[0] == HNDLR or t[0].lower() not in string.ascii_lowercase or t.endswith(".."): + return + tt = google_translator().detect(t) + if tt[0] != "en": + return + xx = GingerIt() + x = xx.parse(t) + res = x["result"] + try: + await event.edit(res) + except BaseException: + pass + + +if GingerIt and udB.get_key("AUTOCORRECT"): + ultroid_bot.add_handler( + gramme, events.NewMessage(outgoing=True, func=lambda x: x.text) + ) diff --git a/addons/autopic.py b/addons/autopic.py new file mode 100644 index 0000000..30a048b --- /dev/null +++ b/addons/autopic.py @@ -0,0 +1,156 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + + +import asyncio +import os +import random +from random import shuffle +import aiohttp +import re +from telethon.tl.functions.photos import UploadProfilePhotoRequest +from PIL import Image + +from pyUltroid.fns.helper import download_file, fast_download + +from . import LOGS, get_help, get_string, udB, ultroid_bot, ultroid_cmd + +__doc__ = get_help("help_autopic") + + +async def get_google_images(query: str): + """Extract image URLs from Google Images search results with fallbacks""" + + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" + } + + search_url = f"https://www.google.com/search?q={query}&tbm=isch" + + # Domains to exclude + excluded_domains = [ + 'gstatic.com', + 'google.com', + 'googleusercontent.com', + 'ssl.google.com' + ] + + def is_valid_url(url): + return not any(domain in url.lower() for domain in excluded_domains) + + try: + async with aiohttp.ClientSession() as session: + async with session.get(search_url, headers=headers) as response: + html = await response.text() + + # Try to extract from search results div first + img_urls = [] + search_pattern = r'

' + search_match = re.search(search_pattern, html, re.DOTALL) + if search_match: + search_content = search_match.group(1) + url_pattern = r'https://[^\"]*?\.(?:jpg|jpeg|png|webp)' + url_matches = re.finditer(url_pattern, search_content, re.IGNORECASE) + for url_match in url_matches: + url = url_match.group(0) + if url not in img_urls and is_valid_url(url): + img_urls.append(url) + + # Fallback to tdeeNb div if no results + if not img_urls: + pattern = r'
]*>(.*?)
' + matches = re.finditer(pattern, html, re.DOTALL) + for match in matches: + div_content = match.group(1) + url_pattern = r'https://[^\"]*?\.(?:jpg|jpeg|png|webp)' + url_matches = re.finditer(url_pattern, div_content, re.IGNORECASE) + for url_match in url_matches: + url = url_match.group(0) + if url not in img_urls and is_valid_url(url): + img_urls.append(url) + + # Fallback to general image search if still no results + if not img_urls: + pattern = r"https://[^\"]*?\.(?:jpg|jpeg|png|webp)" + matches = re.finditer(pattern, html, re.IGNORECASE) + for match in matches: + url = match.group(0) + if url not in img_urls and is_valid_url(url): + img_urls.append(url) + + # Final fallback to data URLs if still no results + if not img_urls: + pattern = r'data:image/(?:jpeg|png|webp);base64,[^\"]*' + matches = re.finditer(pattern, html, re.IGNORECASE) + for match in matches: + url = match.group(0) + if url not in img_urls: + img_urls.append(url) + + return img_urls + + except Exception as e: + print(f"Error fetching Google images: {e}") + return [] + + +@ultroid_cmd(pattern="autopic( (.*)|$)") +async def autopic(e): + search = e.pattern_match.group(1).strip() + if udB.get_key("AUTOPIC") and not search: + udB.del_key("AUTOPIC") + return await e.eor(get_string("autopic_5")) + if not search: + return await e.eor(get_string("autopic_1"), time=5) + e = await e.eor(get_string("com_1")) + images = await get_google_images(search) + if not images: + return await e.eor(get_string("autopic_2").format(search), time=5) + await e.eor(get_string("autopic_3").format(search)) + udB.set_key("AUTOPIC", search) + SLEEP_TIME = udB.get_key("SLEEP_TIME") or 1221 + while True: + for lie in images: + if udB.get_key("AUTOPIC") != search: + return + download_path, stime = await fast_download(lie, "resources/downloads/autopic.jpg") + img = Image.open(download_path) + img.save("resources/downloads/autopic.jpg") + file = await e.client.upload_file("resources/downloads/autopic.jpg") + await e.client(UploadProfilePhotoRequest(file=file)) + os.remove("resources/downloads/autopic.jpg") + await asyncio.sleep(SLEEP_TIME) + + shuffle(images) + + +if search := udB.get_key("AUTOPIC"): + images = {} + sleep = udB.get_key("SLEEP_TIME") or 1221 + + async def autopic_func(): + search = udB.get_key("AUTOPIC") + if images.get(search) is None: + images[search] = await get_google_images(search) + if not images.get(search): + return + img = random.choice(images[search]) + filee, stime = await fast_download(img, "resources/downloads/autopic.jpg") + img = Image.open(filee) + img.save("resources/downloads/autopic.jpg") + file = await ultroid_bot.upload_file("resources/downloads/autopic.jpg") + await ultroid_bot(UploadProfilePhotoRequest(file=file)) + os.remove(filee) + + try: + from apscheduler.schedulers.asyncio import AsyncIOScheduler + + schedule = AsyncIOScheduler() + schedule.add_job(autopic_func, "interval", seconds=sleep) + schedule.start() + except ModuleNotFoundError as er: + LOGS.error(f"autopic: '{er.name}' not installed.") diff --git a/addons/autoprofile.py b/addons/autoprofile.py new file mode 100644 index 0000000..7ccc518 --- /dev/null +++ b/addons/autoprofile.py @@ -0,0 +1,82 @@ +# +# Ultroid - UserBot +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +# Ported Plugin + +""" +โœ˜ Commands Available - + +โ€ข `{i}autoname` + `Starts AUTONAME`. + +โ€ข `{i}stopname` + `Stops AUTONAME.` + +โ€ข `{i}autobio` + `Starts AUTOBIO.` + +โ€ข `{i}stopbio` + `Stops AUTOBIO.` +""" + +import random + +from telethon.tl.functions.account import UpdateProfileRequest + +from . import * + + +@ultroid_cmd(pattern="(auto|stop)name$") +async def autoname_(event): + match = event.pattern_match.group(1) + if match == "stop": + udB.del_key("AUTONAME") + await event.eor("`AUTONAME has been Stopped !`") + return + udB.set_key("AUTONAME", "True") + await eod(event, "`Started AUTONAME`") + while True: + getn = udB.get_key("AUTONAME") + if not getn: + return + DM = time.strftime("%d-%m-%y") + HM = time.strftime("%H:%M") + name = f"๐Ÿ•’{HM} โšก{OWNER_NAME}โšก {DM} ๐Ÿ—“๏ธ" + await event.client(UpdateProfileRequest(first_name=name)) + await asyncio.sleep(1111) + + +@ultroid_cmd(pattern="(auto|stop)bio$") +async def autoname_(event): + match = event.pattern_match.group(1) + if match == "stop": + udB.del_key("AUTOBIO") + await event.eor("`AUTOBIO has been Stopped !`") + return + udB.set_key("AUTOBIO", "True") + await eod(event, "`Started AUTOBIO`") + BIOS = [ + "Busy Today !", + "ULTROID USER", + "Enjoying Life!", + "Unique as Always!" "Sprinkling a bit of magic", + "Intelligent !", + ] + while True: + getn = udB.get_key("AUTOBIO") + if not getn: + return + BIOMSG = random.choice(BIOS) + DM = time.strftime("%d-%m-%y") + HM = time.strftime("%H:%M") + name = f"๐Ÿ“…{DM} | {BIOMSG} | โŒš๏ธ{HM}" + await event.client( + UpdateProfileRequest( + about=name, + ) + ) + await asyncio.sleep(1111) diff --git a/addons/beautify.py b/addons/beautify.py new file mode 100644 index 0000000..33609f5 --- /dev/null +++ b/addons/beautify.py @@ -0,0 +1,197 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_beautify") + + +import os +import random + +from telethon.utils import get_display_name +from urllib.parse import urlencode +from . import Carbon, ultroid_cmd, get_string, inline_mention, LOGS +from secrets import token_hex + +_colorspath = "resources/colorlist.txt" + +if os.path.exists(_colorspath): + with open(_colorspath, "r") as f: + all_col = f.read().split() +else: + all_col = [] + + +@ultroid_cmd( + pattern="(rc|c)arbon", +) +async def cr_bn(event): + xxxx = await event.eor(get_string("com_1")) + te = event.pattern_match.group(1) + col = random.choice(all_col) if te[0] == "r" else "White" + if event.reply_to_msg_id: + temp = await event.get_reply_message() + if temp.media: + b = await event.client.download_media(temp) + with open(b) as a: + code = a.read() + os.remove(b) + else: + code = temp.message + else: + try: + code = event.text.split(" ", maxsplit=1)[1] + except IndexError: + return await xxxx.eor(get_string("carbon_2")) + xx = await Carbon(code=code, file_name="ultroid_carbon", backgroundColor=col) + if isinstance(xx, dict): + await xxxx.edit(f"`{xx}`") + return + await xxxx.delete() + await event.reply( + f"Carbonised by {inline_mention(event.sender)}", + file=xx, + ) + + +@ultroid_cmd( + pattern="ccarbon( (.*)|$)", +) +async def crbn(event): + match = event.pattern_match.group(1).strip() + if not match: + return await event.eor(get_string("carbon_3")) + msg = await event.eor(get_string("com_1")) + if event.reply_to_msg_id: + temp = await event.get_reply_message() + if temp.media: + b = await event.client.download_media(temp) + with open(b) as a: + code = a.read() + os.remove(b) + else: + code = temp.message + else: + try: + match = match.split(" ", maxsplit=1) + code = match[1] + match = match[0] + except IndexError: + return await msg.eor(get_string("carbon_2")) + xx = await Carbon(code=code, backgroundColor=match) + await msg.delete() + await event.reply( + f"Carbonised by {inline_mention(event.sender)}", + file=xx, + ) + + +RaySoTheme = [ + "meadow", + "breeze", + "raindrop", + "candy", + "crimson", + "falcon", + "sunset", + "noir", + "midnight", + "bitmap", + "ice", + "sand", + "forest", + "mono", +] + + +@ultroid_cmd(pattern="rayso") +async def pass_on(ult): + try: + from playwright.async_api import async_playwright + except ImportError: + await ult.eor( + "`playwright` is not installed!\nPlease install it to use this command.." + ) + return + + proc = await ult.eor(get_string("com_1")) + spli = ult.text.split() + theme, dark, title, text = None, True, get_display_name(ult.chat), None + if len(spli) > 1: + if spli[1] in RaySoTheme: + theme = spli[1] + if len(spli) > 2: + text = " ".join(spli[2:]) + else: + text = " ".join(spli[1:]) + if ult.is_reply: + try: + msg = await ult.get_reply_message() + text = msg.message if not text else text + title = get_display_name(msg.sender) + if not theme and spli[1] in RaySoTheme: + theme = spli[1] + except Exception as sam: + LOGS.exception(sam) + if not text: + await proc.eor("No text to beautify!") + return + if not theme: + theme = random.choice(RaySoTheme) + cleaned_text = "\n".join([line.strip() for line in text.splitlines()]) + name = token_hex(8) + ".png" + data = {"darkMode": dark, "theme": theme, "title": title} + url = f"https://ray.so/#{urlencode(data)}" + async with async_playwright() as play: + try: + browser = await play.chromium.launch() + page = await browser.new_page() + await page.goto(url) + await page.wait_for_load_state("networkidle") + try: + await page.wait_for_selector( + "div[class*='Editor_editor__']", timeout=60000 + ) + editor = await page.query_selector("div[class*='Editor_editor__']") + await editor.focus() + await editor.click() + + for line in cleaned_text.split("\n"): + await page.keyboard.type(line) + await page.keyboard.press("Enter") + + await page.evaluate( + """() => { + const button = document.querySelector('button[aria-label="Export as PNG"]'); + button.click(); + }""" + ) + + async with page.expect_download() as download_info: + download = await download_info.value + await download.save_as(name) + except playwright._impl._errors.TimeoutError: + LOGS.error("Timeout error: Selector not found within 60 seconds.") + await proc.eor("Failed to find the editor within 60 seconds.") + return + except Exception as e: + LOGS.error(f"Error occurred during playwright operation: {e}") + await proc.eor("An error occurred during the operation.") + return + finally: + if os.path.exists(name): + try: + await ult.reply(file=name) + await proc.try_delete() + os.remove(name) + except Exception as e: + LOGS.error(f"Error occurred while replying with the file: {e}") + await proc.eor("Failed to send the file.") + else: + LOGS.error(f"Error: File {name} not found or inaccessible.") + await proc.eor("Failed to save the file.") diff --git a/addons/blacklist.py b/addons/blacklist.py new file mode 100644 index 0000000..9de1258 --- /dev/null +++ b/addons/blacklist.py @@ -0,0 +1,109 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_blacklist") + +from telethon.tl.types import Channel + +from . import events, get_string, udB, ultroid_bot, ultroid_cmd + +# Functions moved from blacklist_db.py +def get_stuff(): + return udB.get_key("BLACKLIST_DB") or {} + + +def add_blacklist(chat, word): + ok = get_stuff() + if ok.get(chat): + for z in word.split(): + if z not in ok[chat]: + ok[chat].append(z) + else: + ok.update({chat: [word]}) + return udB.set_key("BLACKLIST_DB", ok) + + +def rem_blacklist(chat, word): + ok = get_stuff() + if ok.get(chat) and word in ok[chat]: + ok[chat].remove(word) + return udB.set_key("BLACKLIST_DB", ok) + + +def list_blacklist(chat): + ok = get_stuff() + if ok.get(chat): + txt = "".join(f"๐Ÿ‘‰`{z}`\n" for z in ok[chat]) + if txt: + return txt + + +def get_blacklist(chat): + ok = get_stuff() + if ok.get(chat): + return ok[chat] + + +@ultroid_cmd(pattern="blacklist( (.*)|$)", admins_only=True) +async def af(e): + wrd = e.pattern_match.group(1).strip() + chat = e.chat_id + if not (wrd): + return await e.eor(get_string("blk_1")) + wrd = e.text.split(maxsplit=1)[1] + add_blacklist(chat, wrd) + await e.eor(get_string("blk_2").format(wrd)) + + +@ultroid_cmd(pattern="remblacklist( (.*)|$)", admins_only=True) +async def rf(e): + wrd = e.pattern_match.group(1).strip() + chat = e.chat_id + if not wrd: + return await e.eor(get_string("blk_3")) + wrd = e.text.split(maxsplit=1)[1] + if rem_blacklist(chat, wrd): + await e.eor(get_string("blk_4").format(wrd)) + else: + await e.eor(get_string("blk_5")) + + +@ultroid_cmd(pattern="listblacklist$", admins_only=True) +async def lsnote(e): + if x := list_blacklist(e.chat_id): + await e.eor(get_string("blk_6").format(x)) + else: + await e.eor(get_string("blk_7")) + + +async def blacklist(e): + if not get_blacklist(e.chat_id): + return + xx = get_blacklist(e.chat_id) + if getattr(e, "sender", None) and isinstance(e.sender, Channel): + return + if not ( + isinstance(e.text, str) + and ("chat.whatsapp.com" in e.text.lower()) + and e.sender + and hasattr(e.sender, "username") + and e.sender.username == "Channel_Bot" + ): + text = e.text.lower().split() + for x in xx: + if x.lower() in text: + try: + await e.delete() + except Exception: + pass + break + + +if get_stuff(): + ultroid_bot.add_handler(blacklist, events.NewMessage(incoming=True)) diff --git a/addons/brainfuck.py b/addons/brainfuck.py new file mode 100644 index 0000000..91c9079 --- /dev/null +++ b/addons/brainfuck.py @@ -0,0 +1,201 @@ +# Made by : @Hackintush || github.com/ToxygenX +# Made For : https://github.com/TeamUltroid/UltroidAddons + +""" +โœ˜ Commands Available + +โ€ข `{i}bf` + Text to Brainfuck String Generator with text or reply. + +โ€ข `{i}rbf` + Brainfuck Interpreter with string or reply. +""" + +from . import * + + +def evaluate(commands): + interpreter = BrainfuckInterpreter(commands) + while interpreter.available(): + interpreter.step() + + return interpreter.output.read() + + +__all__ = "BrainfuckInterpreter" + + +class IOStream: + def __init__(self, data=None): + self._buffer = data or "" + + def __len__(self): + return len(self._buffer) + + def read(self, length=None): + if not length: + data = self._buffer + self._buffer = "" + else: + data = self._buffer[:length] + self._buffer = self._buffer[length:] + + return data + + def write(self, data): + self._buffer += data + + +class IncrementalByteCellArray: + def __init__(self): + self.byte_cells = [0] + self.data_pointer = 0 + + def __getitem__(self, item): + cell_amount = len(self.byte_cells) + if item > cell_amount - 1: + self.extend(item - cell_amount + 1) + + return self.byte_cells[item] + + def __setitem__(self, key: int, value: int): + cell_amount = len(self.byte_cells) + if key > cell_amount - 1: + self.extend(key - cell_amount + 1) + + self.byte_cells[key] = value + + def __len__(self): + return len(self.byte_cells) + + def __repr__(self): + return self.byte_cells.__repr__() + + def extend(self, size: int): + self.byte_cells += [0] * size + + def increment(self): + new_val = (self.get() + 1) % 256 + self.set(new_val) + + def decrement(self): + new_val = self.get() - 1 + if new_val < 0: + new_val = 255 + + self.set(new_val) + + def set(self, value: int): + self.__setitem__(self.data_pointer, value) + + def get(self): + return self.__getitem__(self.data_pointer) + + +class BrainfuckInterpreter: + def __init__(self, commands: str): + self._commands = commands + + self.input = IOStream() + self.output = IOStream() + + self.instruction_pointer = 0 + self.cells = IncrementalByteCellArray() + + self._opening_bracket_indexes = [] + + def _look_forward(self): + remaining_commands = self._commands[self.instruction_pointer :] + loop_counter = 0 + index = self.instruction_pointer + + for command in remaining_commands: + if command == "[": + loop_counter += 1 + elif command == "]": + loop_counter -= 1 + + if loop_counter == 0: + return index + + index += 1 + + def _interpret(self): + instruction = self._commands[self.instruction_pointer] + + if instruction == ">": + self.cells.data_pointer += 1 + elif instruction == "<": + self.cells.data_pointer -= 1 + elif instruction == "+": + self.cells.increment() + elif instruction == "-": + self.cells.decrement() + elif instruction == ".": + self.output.write(chr(self.cells.get())) + elif instruction == ",": + self.cells.set(self.input.read(1)) + elif instruction == "[": + if self.cells.get() == 0: + loop_end = self._look_forward() + self.instruction_pointer = loop_end + else: + self._opening_bracket_indexes.append(self.instruction_pointer) + elif instruction == "]": + if self.cells.get() != 0: + opening_bracket_index = self._opening_bracket_indexes.pop(-1) + + self.instruction_pointer = opening_bracket_index - 1 + else: + self._opening_bracket_indexes.pop(-1) + + def step(self) -> None: + self._interpret() + self.instruction_pointer += 1 + + def available(self) -> bool: + return not self.instruction_pointer >= len(self._commands) + + def command(self): + return self._commands[self.instruction_pointer] + + +def bf(text): + items = [] + for c in text: + items.append( + "[-]>[-]<" + + ("+" * (ord(c) // 10)) + + "[>++++++++++<-]>" + + ("+" * (ord(c) % 10)) + + ".<" + ) + return "".join(items) + + +@ultroid_cmd( + pattern="bf", +) +async def _(event): + input_ = event.text[4:] + if not input_: + if event.reply_to_msg_id: + previous_message = await event.get_reply_message() + input_ = previous_message.message + else: + return await eod(event, "Give me some text lol", time=5) + await event.eor(bf(input_)) + + +@ultroid_cmd( + pattern="rbf", +) +async def _(event): + input_ = event.text[5:] + if not input_: + if event.reply_to_msg_id: + previous_message = await event.get_reply_message() + input_ = previous_message.message + else: + return await eod(event, "Give me some text lol", time=5) + await event.eor(f"{evaluate(input_)}") diff --git a/addons/broadcast.py b/addons/broadcast.py new file mode 100644 index 0000000..4eb1d36 --- /dev/null +++ b/addons/broadcast.py @@ -0,0 +1,216 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + + +from . import get_help + +__doc__ = get_help("help_broadcast") + +import asyncio +import io + +from telethon.utils import get_display_name + +from pyUltroid.dB.base import KeyManager + +from . import HNDLR, LOGS, eor, get_string, udB, ultroid_bot, ultroid_cmd + +KeyM = KeyManager("BROADCAST", cast=list) + + +@ultroid_cmd( + pattern="addch( (.*)|$)", + allow_sudo=False, +) +async def broadcast_adder(event): + msgg = event.pattern_match.group(1).strip() + x = await event.eor(get_string("bd_1")) + if msgg == "all": + await x.edit(get_string("bd_2")) + chats = [ + e.entity + for e in await event.client.get_dialogs() + if (e.is_group or e.is_channel) + ] + new = 0 + for i in chats: + try: + if ( + i.broadcast + and (i.creator or i.admin_rights) + and not KeyM.contains(i.id) + ): + new += 1 + cid = f"-100{i.id}" + KeyM.add(int(cid)) + except Exception as Ex: + LOGS.exception(Ex) + await x.edit(get_string("bd_3").format(KeyM.count(), new)) + return + if event.reply_to_msg_id: + previous_message = await event.get_reply_message() + raw_text = previous_message.text + lines = raw_text.split("\n") + length = len(lines) + for line_number in range(1, length - 2): + channel_id = lines[line_number][4:-1] + if not KeyM.contains(channel_id): + KeyM.add(channel_id) + await x.edit(get_string("bd_4")) + await asyncio.sleep(3) + await event.delete() + return + chat_id = event.chat_id + if chat_id == udB.get_key("LOG_CHANNEL"): + return + if KeyM.contains(chat_id): + await x.edit(get_string("bd_6")) + elif xx := KeyM.add(chat_id): + await x.edit(get_string("bd_5")) + else: + await x.edit(get_string("sf_8")) + await asyncio.sleep(3) + await x.delete() + + +@ultroid_cmd( + pattern="remch( (.*)|$)", + allow_sudo=False, +) +async def broadcast_remover(event): + chat_id = event.pattern_match.group(1).strip() or event.chat_id + x = await event.eor(get_string("com_1")) + if chat_id == "all": + await x.edit(get_string("bd_8")) + udB.del_key("BROADCAST") + await x.edit("Database cleared.") + return + if KeyM.contains(chat_id): + KeyM.remove(chat_id) + await x.edit(get_string("bd_7")) + else: + await x.edit(get_string("bd_9")) + await asyncio.sleep(3) + await x.delete() + + +@ultroid_cmd( + pattern="listchannels$", +) +async def list_all(event): + x = await event.eor(get_string("com_1")) + channels = KeyM.get() + num = KeyM.count() + if not channels: + return await eor(x, "No chats were added.", time=5) + msg = "Channels in database:\n" + for channel in channels: + name = "" + try: + name = get_display_name(await event.client.get_entity(channel)) + except ValueError: + name = "" + msg += f"=> **{name}** [`{channel}`]\n" + msg += f"\nTotal {num} channels." + if len(msg) > 4096: + MSG = msg.replace("*", "").replace("`", "") + with io.BytesIO(str.encode(MSG)) as out_file: + out_file.name = "channels.txt" + await event.reply( + "Channels in Database", + file=out_file, + force_document=True, + allow_cache=False, + ) + await x.delete() + else: + await x.edit(msg) + + +@ultroid_cmd( + pattern="forward$", + allow_sudo=False, +) +async def forw(event): + if not event.is_reply: + return await event.eor(get_string("ex_1")) + ultroid_bot = event.client + channels = KeyM.get() + x = await event.eor("Sending...") + if not channels: + return await x.edit(f"Please add channels by using `{HNDLR}add` in them.") + error_count = 0 + sent_count = 0 + previous_message = await event.get_reply_message() + error_count = 0 + for channel in channels: + try: + await ultroid_bot.forward_messages(channel, previous_message) + sent_count += 1 + await x.edit( + f"Sent : {sent_count}\nError : {error_count}\nTotal : {len(channels)}", + ) + except Exception: + try: + await ultroid_bot.send_message( + udB.get_key("LOG_CHANNEL"), + f"Error in sending at {channel}.", + ) + except Exception as Em: + LOGS.info(Em) + error_count += 1 + await x.edit( + f"Sent : {sent_count}\nError : {error_count}\nTotal : {len(channels)}", + ) + await x.edit(f"{sent_count} messages sent with {error_count} errors.") + if error_count > 0: + await ultroid_bot.send_message( + udB.get_key("LOG_CHANNEL"), f"{error_count} Errors" + ) + + +@ultroid_cmd( + pattern="broadcast( (.*)|$)", + allow_sudo=False, +) +async def sending(event): + x = await event.eor(get_string("com_1")) + if not event.is_reply: + return await x.edit(get_string("ex_1")) + channels = KeyM.get() + if not channels: + return await x.edit(f"Please add channels by using `{HNDLR}add` in them.") + await x.edit("Sending....") + if event.reply_to_msg_id: + previous_message = await event.get_reply_message() + if previous_message.poll: + return await x.edit(f"Reply `{HNDLR}forward` for polls.") + if previous_message: + error_count = 0 + sent_count = 0 + for channel in channels: + try: + await ultroid_bot.send_message(channel, previous_message) + sent_count += 1 + await x.edit( + f"Sent : {sent_count}\nError : {error_count}\nTotal : {len(channels)}", + ) + except Exception as error: + await ultroid_bot.send_message( + udB.get_key("LOG_CHANNEL"), + f"Error in sending at {channel}.\n\n{error}", + ) + error_count += 1 + await x.edit( + f"Sent : {sent_count}\nError : {error_count}\nTotal : {len(channels)}", + ) + await x.edit(f"{sent_count} messages sent with {error_count} errors.") + if error_count > 0: + await ultroid_bot.send_message( + udB.get_key("LOG_CHANNEL"), + f"{error_count} Errors", + ) diff --git a/addons/button.py b/addons/button.py new file mode 100644 index 0000000..ef1fbb2 --- /dev/null +++ b/addons/button.py @@ -0,0 +1,54 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_button") + +import os + +from . import upload_file as uf +from telethon.utils import pack_bot_file_id + +from pyUltroid.fns.tools import create_tl_btn, get_msg_button + +from . import HNDLR, get_string, mediainfo, ultroid_cmd +from ._inline import something + + +@ultroid_cmd(pattern="button") +async def butt(event): + media, wut, text = None, None, None + if event.reply_to: + wt = await event.get_reply_message() + if wt.text: + text = wt.text + if wt.media: + wut = mediainfo(wt.media) + if wut and wut.startswith(("pic", "gif")): + dl = await wt.download_media() + media = uf(dl) + elif wut == "video": + if wt.media.document.size > 8 * 1000 * 1000: + return await event.eor(get_string("com_4"), time=5) + dl = await wt.download_media() + media = uf(dl) + os.remove(dl) + else: + media = pack_bot_file_id(wt.media) + try: + text = event.text.split(maxsplit=1)[1] + except IndexError: + if not text: + return await event.eor( + f"**Please give some text in correct format.**\n\n`{HNDLR}help button`", + ) + text, buttons = get_msg_button(text) + if buttons: + buttons = create_tl_btn(buttons) + await something(event, text, media, buttons) + await event.delete() diff --git a/addons/calculator.py b/addons/calculator.py new file mode 100644 index 0000000..3514c29 --- /dev/null +++ b/addons/calculator.py @@ -0,0 +1,153 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + + +from . import get_help + +__doc__ = get_help("help_calculator") + +import re + +from . import Button, asst, callback, get_string, in_pattern, udB, ultroid_cmd + +CALC = {} + +m = [ + "AC", + "C", + "โŒซ", + "%", + "7", + "8", + "9", + "+", + "4", + "5", + "6", + "-", + "1", + "2", + "3", + "x", + "00", + "0", + ".", + "รท", +] +tultd = [Button.inline(f"{x}", data=f"calc{x}") for x in m] +lst = list(zip(tultd[::4], tultd[1::4], tultd[2::4], tultd[3::4])) +lst.append([Button.inline("=", data="calc=")]) + + +@ultroid_cmd(pattern="calc") +async def icalc(e): + udB.del_key("calc") + if e.client._bot: + return await e.reply(get_string("calc_1"), buttons=lst) + results = await e.client.inline_query(asst.me.username, "calc") + await results[0].click(e.chat_id, silent=True, hide_via=True) + await e.delete() + + +@in_pattern("calc", owner=True) +async def _(e): + calc = e.builder.article("Calc", text=get_string("calc_1"), buttons=lst) + await e.answer([calc]) + + +@callback(re.compile("calc(.*)"), owner=True) +async def _(e): + x = (e.data_match.group(1)).decode() + user = e.query.user_id + get = None + if x == "AC": + if CALC.get(user): + CALC.pop(user) + await e.edit( + get_string("calc_1"), + buttons=[Button.inline(get_string("calc_2"), data="recalc")], + ) + elif x == "C": + if CALC.get(user): + CALC.pop(user) + await e.answer("cleared") + elif x == "โŒซ": + if CALC.get(user): + get = CALC[user] + if get: + CALC.update({user: get[:-1]}) + await e.answer(str(get[:-1])) + elif x == "%": + if CALC.get(user): + get = CALC[user] + if get: + CALC.update({user: f"{get}/100"}) + await e.answer(str(f"{get}/100")) + elif x == "รท": + if CALC.get(user): + get = CALC[user] + if get: + CALC.update({user: f"{get}/"}) + await e.answer(str(f"{get}/")) + elif x == "x": + if CALC.get(user): + get = CALC[user] + if get: + CALC.update({user: f"{get}*"}) + await e.answer(str(f"{get}*")) + elif x == "=": + if CALC.get(user): + get = CALC[user] + if get: + if get.endswith(("*", ".", "/", "-", "+")): + get = get[:-1] + out = eval(get) + try: + num = float(out) + await e.answer(f"Answer : {num}", cache_time=0, alert=True) + except BaseException: + CALC.pop(user) + await e.answer(get_string("sf_8"), cache_time=0, alert=True) + await e.answer("None") + else: + if CALC.get(user): + get = CALC[user] + if get: + CALC.update({user: get + x}) + return await e.answer(str(get + x)) + CALC.update({user: x}) + await e.answer(str(x)) + + +@callback("recalc", owner=True) +async def _(e): + m = [ + "AC", + "C", + "โŒซ", + "%", + "7", + "8", + "9", + "+", + "4", + "5", + "6", + "-", + "1", + "2", + "3", + "x", + "00", + "0", + ".", + "รท", + ] + tultd = [Button.inline(f"{x}", data=f"calc{x}") for x in m] + lst = list(zip(tultd[::4], tultd[1::4], tultd[2::4], tultd[3::4])) + lst.append([Button.inline("=", data="calc=")]) + await e.edit(get_string("calc_1"), buttons=lst) diff --git a/addons/channelhacks.py b/addons/channelhacks.py new file mode 100644 index 0000000..561517a --- /dev/null +++ b/addons/channelhacks.py @@ -0,0 +1,224 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +from . import get_help + +__doc__ = get_help("help_channelhacks") + + +import asyncio +import io + +from telethon.errors.rpcerrorlist import FloodWaitError +from telethon.utils import get_display_name, get_peer_id + +from pyUltroid.dB.base import KeyManager + +from . import LOGS, asst, eor, events, get_string, udB, ultroid_bot, ultroid_cmd + +ERROR = {} +SourceM = KeyManager("CH_SOURCE", cast=list) +DestiM = KeyManager("CH_DESTINATIONS", cast=list) + + +async def autopost_func(e): + if not udB.get_key("AUTOPOST"): + return + x = SourceM.get() + th = await e.get_chat() + if get_peer_id(th) not in x: + return + y = DestiM.get() + for ys in y: + try: + await e.client.send_message(int(ys), e.message) + except Exception as ex: + try: + ERROR[str(ex)] + except KeyError: + ERROR.update({str(ex): ex}) + Error = f"**Error on AUTOPOST**\n\n`{ex}`" + await asst.send_message(udB.get_key("LOG_CHANNEL"), Error) + + +@ultroid_cmd(pattern="shift (.*)") +async def _(e): + x = e.pattern_match.group(1).strip() + z = await e.eor(get_string("com_1")) + a, b = x.split("|") + try: + c = await e.client.parse_id(a) + except Exception: + await z.edit(get_string("cha_1")) + return + try: + d = await e.client.parse_id(b) + except Exception as er: + LOGS.exception(er) + await z.edit(get_string("cha_1")) + return + async for msg in e.client.iter_messages(int(c), reverse=True): + try: + await asyncio.sleep(2) + await e.client.send_message(int(d), msg) + except FloodWaitError as er: + await asyncio.sleep(er.seconds + 5) + await e.client.send_message(int(d), msg) + except BaseException as er: + LOGS.exception(er) + await z.edit("Done") + + +@ultroid_cmd(pattern="asource (.*)") +async def source(e): + if x := e.pattern_match.group(1).strip(): + try: + y = await e.client.parse_id(x) + except Exception as er: + LOGS.exception(er) + return + else: + y = e.chat_id + if not SourceM.contains(y): + SourceM.add(y) + await e.eor(get_string("cha_2")) + ultroid_bot.add_handler(autopost_func, events.NewMessage()) + else: + await e.eor(get_string("cha_3")) + + +@ultroid_cmd(pattern="dsource( (.*)|$)") +async def dd(event): + chat_id = event.pattern_match.group(1).strip() + x = await event.eor(get_string("com_1")) + if chat_id == "all": + await x.edit(get_string("bd_8")) + udB.del_key("CH_SOURCE") + await x.edit(get_string("cha_4")) + return + if chat_id: + try: + y = await event.client.parse_id(chat_id) + except Exception as er: + LOGS.exception(er) + return + else: + y = event.chat_id + if SourceM.contains(y): + SourceM.remove(y) + await eor(x, get_string("cha_5"), time=5) + else: + await eor(x, "Source channel is already removed from database. ", time=3) + + +@ultroid_cmd(pattern="listsource") +async def list_all(event): + x = await event.eor(get_string("com_1")) + num = SourceM.count() + if not num: + return await eor(x, "No chats were added.", time=5) + msg = get_string("cha_8") + channels = SourceM.get() + for channel in channels: + name = "" + try: + name = get_display_name(await event.client.get_entity(int(channel))) + except BaseException: + name = "" + msg += f"\n=> **{name}** [`{channel}`]" + msg += f"\nTotal {num} channels." + if len(msg) > 4096: + MSG = msg.replace("*", "").replace("`", "") + with io.BytesIO(str.encode(MSG)) as out_file: + out_file.name = "channels.txt" + await event.reply( + "Channels in database", + file=out_file, + force_document=True, + allow_cache=False, + ) + await x.delete() + else: + await x.edit(msg) + + +@ultroid_cmd(pattern="adest (.*)") +async def destination(e): + if x := e.pattern_match.group(1).strip(): + try: + y = await e.client.parse_id(x) + except Exception as er: + LOGS.exception(er) + return + else: + y = e.chat_id + if not DestiM.contains(y): + DestiM.add(y) + await e.eor("Destination added succesfully") + else: + await e.eor("Destination channel already added") + + +@ultroid_cmd(pattern="ddest( (.*)|$)") +async def dd(event): + chat_id = event.pattern_match.group(1).strip() + x = await event.eor(get_string("com_1")) + if chat_id == "all": + await x.edit(get_string("bd_8")) + udB.del_key("CH_DESTINATION") + await x.edit("Destinations database cleared.") + return + if chat_id: + try: + y = await event.client.parse_id(chat_id) + except Exception as er: + LOGS.exception(er) + return + else: + y = event.chat_id + if DestiM.contains(y): + DestiM.remove(y) + await eor(x, "Destination removed from database") + else: + await eor(x, "Destination channel is already removed from database. ", time=5) + + +@ultroid_cmd(pattern="listdest") +async def list_all(event): + ultroid_bot = event.client + x = await event.eor(get_string("com_1")) + channels = DestiM.get() + num = len(channels) + if not num: + return await eor(x, "No chats were added.", time=5) + msg = get_string("cha_7") + for channel in channels: + name = "" + try: + name = get_display_name(await ultroid_bot.get_entity(int(channel))) + except BaseException: + name = "" + msg += f"\n=> **{name}** [`{channel}`]" + msg += f"\nTotal {num} channels." + if len(msg) > 4096: + MSG = msg.replace("*", "").replace("`", "") + with io.BytesIO(str.encode(MSG)) as out_file: + out_file.name = "channels.txt" + await ultroid_bot.send_file( + event.chat_id, + out_file, + force_document=True, + allow_cache=False, + caption="Destination channels in database", + reply_to=event, + ) + await x.delete() + else: + await x.edit(msg) + + +if udB.get_key("AUTOPOST"): + ultroid_bot.add_handler(autopost_func, events.NewMessage()) diff --git a/addons/chatbot.py b/addons/chatbot.py new file mode 100644 index 0000000..02b0ddb --- /dev/null +++ b/addons/chatbot.py @@ -0,0 +1,109 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_chatbot") + +import asyncio + +from pyUltroid.fns.tools import get_chatbot_reply + +from telethon.tl.types import Channel + +from . import LOGS, eod, get_string, inline_mention, udB, ultroid_cmd, ultroid_bot, events + + +@ultroid_cmd(pattern="repai") +async def im_lonely_chat_with_me(event): + if event.reply_to: + message = (await event.get_reply_message()).message + else: + try: + message = event.text.split(" ", 1)[1] + except IndexError: + return await eod(event, get_string("tban_1"), time=10) + reply_ = await get_chatbot_reply(message=message) + await event.eor(reply_) + + +@ultroid_cmd(pattern="addai") +async def add_chatBot(event): + await chat_bot_fn(event, type_="add") + + +@ultroid_cmd(pattern="remai") +async def rem_chatBot(event): + await chat_bot_fn(event, type_="remov") + + +@ultroid_cmd(pattern="listai") +async def lister(event): + key = udB.get_key("CHATBOT_USERS") or {} + users = key.get(event.chat_id, []) + if not users: + return await event.eor(get_string("chab_2"), time=5) + msg = "**Total List Of AI Enabled Users In This Chat :**\n\n" + for i in users: + try: + user = await event.client.get_entity(int(i)) + user = inline_mention(user) + except BaseException: + user = f"`{i}`" + msg += f"โ€ข {user}\n" + await event.eor(msg, link_preview=False) + + +async def chat_bot_fn(event, type_): + if event.reply_to: + user_ = (await event.get_reply_message()).sender + else: + temp = event.text.split(maxsplit=1) + try: + user_ = await event.client.get_entity(await event.client.parse_id(temp[1])) + except BaseException as er: + LOGS.exception(er) + user_ = event.chat if event.is_private else None + if not user_: + return await eod( + event, + get_string("chab_1"), + ) + key = udB.get_key("CHATBOT_USERS") or {} + chat = event.chat_id + user = user_.id + if type_ == "add": + if key.get(chat): + if user not in key[chat]: + key[chat].append(user) + else: + key.update({chat: [user]}) + elif type_ == "remov": + if key.get(chat): + if user in key[chat]: + key[chat].remove(user) + if chat in key and not key[chat]: + del key[chat] + udB.set_key("CHATBOT_USERS", key) + await event.eor(f"**ChatBot:**\n{type_}ed {inline_mention(user_)}") + + + +@ultroid_bot.on(events.NewMessage(incoming=True)) +async def chatBot_replies(e): + sender = await e.get_sender() +if isinstance(sender, Channel): + return + if sender.bot: + return + key = udB.get_key("CHATBOT_USERS") or {} + if e.text and key.get(e.chat_id) and sender.id in key[e.chat_id]: + msg = await get_chatbot_reply(e.message.message) + if msg: + sleep = udB.get_key("CHATBOT_SLEEP") or 1.5 + await asyncio.sleep(sleep) + await e.reply(msg) diff --git a/addons/cleanaction.py b/addons/cleanaction.py new file mode 100644 index 0000000..ffb7e78 --- /dev/null +++ b/addons/cleanaction.py @@ -0,0 +1,60 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_cleanaction") + + +from telethon.utils import get_display_name + +from . import get_string, udB, ultroid_cmd, events, ultroid_bot + + +@ultroid_cmd(pattern="addclean$", admins_only=True) +async def _(e): + key = udB.get_key("CLEANCHAT") or [] + if e.chat_id in key: + return await e.eor(get_string("clan_5")) + key.append(e.chat_id) + udB.set_key("CLEANCHAT", key) + await e.eor(get_string("clan_1"), time=5) + + +@ultroid_cmd(pattern="remclean$") +async def _(e): + key = udB.get_key("CLEANCHAT") or [] + if e.chat_id in key: + key.remove(e.chat_id) + udB.set_key("CLEANCHAT", key) + await e.eor(get_string("clan_2"), time=5) + + +@ultroid_cmd(pattern="listclean$") +async def _(e): + if k := udB.get_key("CLEANCHAT"): + o = "" + for x in k: + try: + title = get_display_name(await e.client.get_entity(x)) + except BaseException: + title = get_string("clan_3") + o += f"{x} {title}\n" + return await e.eor(o) + await e.eor(get_string("clan_4"), time=5) + +# Add chat action handler for clean action +async def clean_action(event): + key = udB.get_key("CLEANCHAT") or [] + if event.chat_id in key: + try: + await event.delete() + except BaseException: + pass + +# Register the handler +ultroid_bot.add_handler(clean_action, events.ChatAction()) diff --git a/addons/clone.py b/addons/clone.py new file mode 100644 index 0000000..dc66932 --- /dev/null +++ b/addons/clone.py @@ -0,0 +1,143 @@ +# Ported From DarkCobra , Originally By Uniborg +# Ultroid - UserBot +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available + +โ€ข `{i}clone ` + clone the identity of user. + +โ€ข `{i}revert` + Revert to your original identity +""" +import html +import io +import os + +from telethon.tl.functions.account import UpdateProfileRequest +from telethon.tl.functions.photos import DeletePhotosRequest, UploadProfilePhotoRequest +from telethon.tl.functions.users import GetFullUserRequest +from telethon.tl.types import MessageEntityMentionName + +from . import * + + +@ultroid_cmd(pattern="clone ?(.*)", fullsudo=True) +async def _(event): + eve = await event.eor("Processing...") + reply_message = await event.get_reply_message() + whoiam = await event.client(GetFullUserRequest(ultroid_bot.uid)) + if whoiam.full_user.about: + mybio = f"{str(ultroid_bot.me.id)}01" + # saving bio for revert + udB.set_key(f"{mybio}", whoiam.full_user.about) + udB.set_key(f"{ultroid_bot.uid}02", whoiam.users[0].first_name) + if whoiam.users[0].last_name: + udB.set_key(f"{ultroid_bot.uid}03", whoiam.users[0].last_name) + replied_user, error_i_a = await get_full_user(event) + if replied_user is None: + await eve.edit(str(error_i_a)) + return + user_id = replied_user.users[0].id + profile_pic = await event.client.download_profile_photo(user_id) + first_name = html.escape(replied_user.users[0].first_name) + if first_name is not None: + first_name = first_name.replace("\u2060", "") + last_name = replied_user.users[0].last_name + if last_name is not None: + last_name = html.escape(last_name) + last_name = last_name.replace("\u2060", "") + if last_name is None: + last_name = "โชโฌโฎโฎโฎ" + user_bio = replied_user.full_user.about + await event.client(UpdateProfileRequest(first_name=first_name)) + await event.client(UpdateProfileRequest(last_name=last_name)) + await event.client(UpdateProfileRequest(about=user_bio)) + if profile_pic: + pfile = await event.client.upload_file(profile_pic) + await event.client(UploadProfilePhotoRequest(file=pfile)) + os.remove(profile_pic) + await eve.delete() + await event.client.send_message( + event.chat_id, f"I am {first_name} from now...", reply_to=reply_message + ) + + +@ultroid_cmd(pattern="revert$") +async def _(event): + name = OWNER_NAME + mybio = f"{str(ultroid_bot.me.id)}01" + bio = chc if (chc := udB.get_key(mybio)) else "Error : Bio Lost" + fname = udB.get_key(f"{ultroid_bot.uid}02") + lname = udB.get_key(f"{ultroid_bot.uid}03") + if fname: + name = fname + ok = lname if lname else "" + n = 1 + client = event.client + await client( + DeletePhotosRequest(await event.client.get_profile_photos("me", limit=n)) + ) + await client(UpdateProfileRequest(about=bio)) + await client(UpdateProfileRequest(first_name=name)) + await client(UpdateProfileRequest(last_name=ok)) + await event.eor("Succesfully reverted to your account back !") + udB.del_key(f"{ultroid_bot.uid}01") + udB.del_key(f"{ultroid_bot.uid}02") + udB.del_key(f"{ultroid_bot.uid}03") + + +async def get_full_user(event): + if event.reply_to_msg_id: + previous_message = await event.get_reply_message() + if previous_message.forward: + replied_user = await event.client( + GetFullUserRequest( + previous_message.forward.sender_id + or previous_message.forward.channel_id + ) + ) + return replied_user, None + replied_user = await event.client( + GetFullUserRequest(previous_message.sender_id) + ) + return replied_user, None + else: + input_str = None + try: + input_str = event.pattern_match.group(1) + except IndexError as e: + return None, e + if event.message.entities is not None: + mention_entity = event.message.entities + probable_user_mention_entity = mention_entity[0] + if isinstance(probable_user_mention_entity, MessageEntityMentionName): + user_id = probable_user_mention_entity.user_id + replied_user = await event.client(GetFullUserRequest(user_id)) + return replied_user, None + try: + user_object = await event.client.get_entity(input_str) + user_id = user_object.id + replied_user = await event.client(GetFullUserRequest(user_id)) + return replied_user, None + except Exception as e: + return None, e + elif event.is_private: + try: + user_id = event.chat_id + replied_user = await event.client(GetFullUserRequest(user_id)) + return replied_user, None + except Exception as e: + return None, e + else: + try: + user_object = await event.client.get_entity(int(input_str)) + user_id = user_object.id + replied_user = await event.client(GetFullUserRequest(user_id)) + return replied_user, None + except Exception as e: + return None, e diff --git a/addons/compressor.py b/addons/compressor.py new file mode 100644 index 0000000..a221d8f --- /dev/null +++ b/addons/compressor.py @@ -0,0 +1,177 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_compressor") + + +import asyncio +import os +import re +import time +from datetime import datetime as dt + +from telethon.errors.rpcerrorlist import MessageNotModifiedError +from telethon.tl.types import DocumentAttributeVideo + +from pyUltroid.fns.tools import metadata + +from . import ( + ULTConfig, + bash, + downloader, + get_string, + humanbytes, + math, + mediainfo, + time_formatter, + ultroid_cmd, + uploader, +) + + +@ultroid_cmd(pattern="compress( (.*)|$)") +async def _(e): + cr = e.pattern_match.group(1).strip() + crf = 27 + to_stream = False + if cr: + k = e.text.split() + if len(k) == 2: + crf = int(k[1]) if k[1].isdigit() else 27 + elif len(k) > 2: + crf = int(k[1]) if k[1].isdigit() else 27 + to_stream = "stream" in k[2] + vido = await e.get_reply_message() + if vido and vido.media and "video" in mediainfo(vido.media): + if hasattr(vido.media, "document"): + vfile = vido.media.document + name = vido.file.name + else: + vfile = vido.media + name = "" + if not name: + name = "video_" + dt.now().isoformat("_", "seconds") + ".mp4" + xxx = await e.eor(get_string("audiotools_5")) + c_time = time.time() + file = await downloader( + f"resources/downloads/{name}", + vfile, + xxx, + c_time, + f"Downloading {name}...", + ) + + o_size = os.path.getsize(file.name) + d_time = time.time() + diff = time_formatter((d_time - c_time) * 1000) + file_name = (file.name).split("/")[-1] + out = file_name.replace(file_name.split(".")[-1], "compressed.mkv") + await xxx.edit( + f"`Downloaded {file.name} of {humanbytes(o_size)} in {diff}.\nNow Compressing...`" + ) + x, y = await bash( + f'mediainfo --fullscan """{file.name}""" | grep "Frame count"' + ) + if y and y.endswith("NOT_FOUND"): + return await xxx.edit(f"ERROR: `{y}`") + total_frames = x.split(":")[1].split("\n")[0] + progress = f"progress-{c_time}.txt" + with open(progress, "w"): + pass + proce = await asyncio.create_subprocess_shell( + f'ffmpeg -hide_banner -loglevel quiet -progress {progress} -i """{file.name}""" -preset ultrafast -vcodec libx265 -crf {crf} -c:a copy """{out}""" -y', + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + while proce.returncode != 0: + await asyncio.sleep(3) + with open(progress, "r+") as fil: + text = fil.read() + frames = re.findall("frame=(\\d+)", text) + size = re.findall("total_size=(\\d+)", text) + speed = 0 + if len(frames): + elapse = int(frames[-1]) + if len(size): + size = int(size[-1]) + per = elapse * 100 / int(total_frames) + time_diff = time.time() - int(d_time) + speed = round(elapse / time_diff, 2) + if int(speed) != 0: + some_eta = ((int(total_frames) - elapse) / speed) * 1000 + text = f"`Compressing {file_name} at {crf} CRF.\n`" + progress_str = "`[{0}{1}] {2}%\n\n`".format( + "".join("โ—" for _ in range(math.floor(per / 5))), + "".join("" for _ in range(20 - math.floor(per / 5))), + round(per, 2), + ) + + e_size = f"{humanbytes(size)} of ~{humanbytes((size / per) * 100)}" + eta = f"~{time_formatter(some_eta)}" + try: + await xxx.edit( + text + + progress_str + + "`" + + e_size + + "`" + + "\n\n`" + + eta + + "`" + ) + except MessageNotModifiedError: + pass + os.remove(file.name) + c_size = os.path.getsize(out) + f_time = time.time() + difff = time_formatter((f_time - d_time) * 1000) + await xxx.edit( + f"`Compressed {humanbytes(o_size)} to {humanbytes(c_size)} in {difff}\nTrying to Upload...`" + ) + differ = 100 - ((c_size / o_size) * 100) + caption = f"**Original Size: **`{humanbytes(o_size)}`\n" + caption += f"**Compressed Size: **`{humanbytes(c_size)}`\n" + caption += f"**Compression Ratio: **`{differ:.2f}%`\n" + caption += f"\n**Time Taken To Compress: **`{difff}`" + n_file, _ = await e.client.fast_uploader( + out, show_progress=True, event=e, message="Uploading...", to_delete=True + ) + if to_stream: + data = await metadata(out) + width = data["width"] + height = data["height"] + duration = data["duration"] + attributes = [ + DocumentAttributeVideo( + duration=duration, w=width, h=height, supports_streaming=True + ) + ] + await e.client.send_file( + e.chat_id, + n_file, + thumb=ULTConfig.thumb, + caption=caption, + attributes=attributes, + force_document=False, + reply_to=e.reply_to_msg_id, + ) + else: + await e.client.send_file( + e.chat_id, + n_file, + thumb=ULTConfig.thumb, + caption=caption, + force_document=True, + reply_to=e.reply_to_msg_id, + ) + await xxx.delete() + os.remove(out) + os.remove(progress) + else: + await e.eor(get_string("audiotools_8"), time=5) diff --git a/addons/converter.py b/addons/converter.py new file mode 100644 index 0000000..201ff76 --- /dev/null +++ b/addons/converter.py @@ -0,0 +1,196 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_converter") + +import os +import time + +from . import LOGS + +try: + import cv2 +except ImportError: + cv2 = None + +try: + from PIL import Image +except ImportError: + LOGS.info(f"{__file__}: PIL not Installed.") + Image = None + +from . import upload_file as uf + +from . import ( + ULTConfig, + bash, + con, + downloader, + get_paste, + get_string, + udB, + ultroid_cmd, + uploader, +) + +opn = [] + + +@ultroid_cmd( + pattern="thumbnail$", +) +async def _(e): + r = await e.get_reply_message() + if r.photo: + dl = await r.download_media() + elif r.document and r.document.thumbs: + dl = await r.download_media(thumb=-1) + else: + return await e.eor("`Reply to Photo or media with thumb...`") + nn = uf(dl) + os.remove(dl) + udB.set_key("CUSTOM_THUMBNAIL", str(nn)) + await bash(f"wget {nn} -O resources/extras/ultroid.jpg") + await e.eor(get_string("cvt_6").format(nn), link_preview=False) + + +@ultroid_cmd( + pattern="rename( (.*)|$)", +) +async def imak(event): + reply = await event.get_reply_message() + t = time.time() + if not reply: + return await event.eor(get_string("cvt_1")) + inp = event.pattern_match.group(1).strip() + if not inp: + return await event.eor(get_string("cvt_2")) + xx = await event.eor(get_string("com_1")) + if reply.media: + if hasattr(reply.media, "document"): + file = reply.media.document + image = await downloader( + reply.file.name or str(time.time()), + reply.media.document, + xx, + t, + get_string("com_5"), + ) + + file = image.name + else: + file = await event.client.download_media(reply.media) + if os.path.exists(inp): + os.remove(inp) + await bash(f'mv """{file}""" """{inp}"""') + if not os.path.exists(inp) or os.path.exists(inp) and not os.path.getsize(inp): + os.rename(file, inp) + k = time.time() + n_file, _ = await event.client.fast_uploader( + inp, show_progress=True, event=event, message="Uploading...", to_delete=True + ) + await event.reply( + f"`{n_file.name}`", + file=n_file, + force_document=True, + thumb=ULTConfig.thumb, + ) + os.remove(inp) + await xx.delete() + + +conv_keys = { + "img": "png", + "sticker": "webp", + "webp": "webp", + "image": "png", + "webm": "webm", + "gif": "gif", + "json": "json", + "tgs": "tgs", +} + + +@ultroid_cmd( + pattern="convert( (.*)|$)", +) +async def uconverter(event): + xx = await event.eor(get_string("com_1")) + a = await event.get_reply_message() + if a is None: + return await event.eor("`Reply to Photo or media with thumb...`") + input_ = event.pattern_match.group(1).strip() + b = await a.download_media("resources/downloads/") + if not b and (a.document and a.document.thumbs): + b = await a.download_media(thumb=-1) + if not b: + return await xx.edit(get_string("cvt_3")) + try: + convert = conv_keys[input_] + except KeyError: + return await xx.edit(get_string("sts_3").format("gif/img/sticker/webm")) + file = await con.convert(b, outname="ultroid", convert_to=convert) + print(file) + + if file: + await event.client.send_file( + event.chat_id, file, reply_to=event.reply_to_msg_id or event.id + ) + os.remove(file) + else: + await xx.edit("`Failed to convert`") + return + await xx.delete() + +@ultroid_cmd( + pattern="doc( (.*)|$)", +) +async def _(event): + input_str = event.pattern_match.group(1).strip() + if not (input_str and event.is_reply): + return await event.eor(get_string("cvt_1"), time=5) + xx = await event.eor(get_string("com_1")) + a = await event.get_reply_message() + if not a.message: + return await xx.edit(get_string("ex_1")) + with open(input_str, "w") as b: + b.write(str(a.message)) + await xx.edit(f"**Packing into** `{input_str}`") + await event.reply(file=input_str, thumb=ULTConfig.thumb) + await xx.delete() + os.remove(input_str) + + +@ultroid_cmd( + pattern="open( (.*)|$)", +) +async def _(event): + a = await event.get_reply_message() + b = event.pattern_match.group(1).strip() + if not ((a and a.media) or (b and os.path.exists(b))): + return await event.eor(get_string("cvt_7"), time=5) + xx = await event.eor(get_string("com_1")) + rem = None + if not b: + b = await a.download_media() + rem = True + try: + with open(b) as c: + d = c.read() + except UnicodeDecodeError: + return await xx.eor(get_string("cvt_8"), time=5) + try: + await xx.edit(f"```{d}```") + except BaseException: + what, data = await get_paste(d) + await xx.edit( + f"**MESSAGE EXCEEDS TELEGRAM LIMITS**\n\nSo Pasted It On [SPACEBIN]({data['link']})" + ) + if rem: + os.remove(b) diff --git a/addons/covid.py b/addons/covid.py new file mode 100644 index 0000000..a7bffe1 --- /dev/null +++ b/addons/covid.py @@ -0,0 +1,39 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available + +โ€ข `{i}covid country name` + Gets the Covid-19 Status of a given Country. +""" + +from covid import Covid + +from . import ultroid_cmd + + +@ultroid_cmd(pattern="covid") +async def coronish(event): + covid = Covid() + okie = event.text.split(maxsplit=1) + try: + country = okie[1] + except IndexError: + await event.eor("Give a country name to Search for it's Covid Cases!") + return + try: + cases = covid.get_status_by_country_name((country).lower()) + act = cases["active"] + conf = cases["confirmed"] + dec = cases["deaths"] + rec = cases["recovered"] + await event.eor( + f"**Country:** **{country.capitalize()}**\n**Active:** {act}\n**Confirmed:** {conf}\n**Recovered:** {rec}\n**Deceased:** {dec}", + ) + except ValueError: + await event.eor(f"It seems that Country {country} is invalid!") diff --git a/addons/echo.py b/addons/echo.py new file mode 100644 index 0000000..d76a425 --- /dev/null +++ b/addons/echo.py @@ -0,0 +1,145 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_echo") + +from telethon.utils import get_display_name + +from . import events, udB, ultroid_bot, ultroid_cmd, LOGS, types + +# Functions moved from echo_db.py +def get_stuff(): + return udB.get_key("ECHO") or {} + + +def add_echo(chat, user): + x = get_stuff() + if k := x.get(int(chat)): + if user not in k: + k.append(int(user)) + x.update({int(chat): k}) + else: + x.update({int(chat): [int(user)]}) + return udB.set_key("ECHO", x) + + +def rem_echo(chat, user): + x = get_stuff() + if k := x.get(int(chat)): + if user in k: + k.remove(int(user)) + x.update({int(chat): k}) + return udB.set_key("ECHO", x) + + +def check_echo(chat, user): + x = get_stuff() + if (k := x.get(int(chat))) and int(user) in k: + return True + + +def list_echo(chat): + x = get_stuff() + return x.get(int(chat)) + + +@ultroid_cmd(pattern="addecho( (.*)|$)") +async def echo(e): + r = await e.get_reply_message() + if r: + user = r.sender_id + else: + try: + user = e.text.split()[1] + if user.startswith("@"): + ok = await e.client.get_entity(user) + user = ok.id + else: + user = int(user) + except BaseException: + return await e.eor("Reply To A user.", time=5) + if check_echo(e.chat_id, user): + return await e.eor("Echo already activated for this user.", time=5) + add_echo(e.chat_id, user) + ok = await e.client.get_entity(user) + user = f"{ok.first_name} {ok.last_name}" if ok.last_name else ok.first_name + await e.eor(f"Activated Echo For {user}.") + + +@ultroid_cmd(pattern="remecho( (.*)|$)") +async def rm(e): + r = await e.get_reply_message() + if r: + user = r.sender_id + else: + try: + user = e.text.split()[1] + if user.startswith("@"): + ok = await e.client.get_entity(user) + user = ok.id + else: + user = int(user) + except BaseException: + return await e.eor("Reply To A User.", time=5) + if check_echo(e.chat_id, user): + rem_echo(e.chat_id, user) + ok = await e.client.get_entity(user) + user = f"{ok.first_name} {ok.last_name}" if ok.last_name else ok.first_name + return await e.eor(f"Deactivated Echo For {user}.") + await e.eor("Echo not activated for this user") + + +@ultroid_cmd(pattern="listecho$") +async def lstecho(e): + k = list_echo(e.chat_id) + if k: + user = "**Activated Echo For Users:**\n\n" + for x in k: + try: + ok = await e.client.get_entity(x) + kk = f"{ok.first_name} {ok.last_name}" if ok.last_name else ok.first_name + user += f"โ€ข{kk}\n" + except BaseException: + user += f"โ€ข[{x}](tg://user?id={x})\n" + await e.eor(user) + else: + await e.eor("`No echo activated here!`", time=5) + + +@ultroid_bot.on(events.NewMessage(incoming=True)) +async def samereply(e): + if check_echo(e.chat_id, e.sender_id): + if e.text: + text = e.text + if e.reply_to: + if e.reply_to.reply_to_top_id: + reply_msg = await e.get_reply_message() + if reply_msg.text: + text = reply_msg.text + try: + await e.client.send_message(e.chat_id, text, reply_to=e.id) + except Exception as er: + print(er) + if e.media: + await e.client.send_file(e.chat_id, e.media, reply_to=e.id) + + +# Add a separate handler for echo replies +async def echo_handler(e): + sender = await e.get_sender() + if not isinstance(sender, types.User) or sender.bot: + return + if check_echo(e.chat_id, e.sender_id): + try: + await e.respond(e.message) + except Exception as er: + LOGS.exception(er) + +# Register the handler +ultroid_bot.add_handler(echo_handler, events.NewMessage(incoming=True)) diff --git a/addons/encodedecode.py b/addons/encodedecode.py new file mode 100644 index 0000000..aa95fdf --- /dev/null +++ b/addons/encodedecode.py @@ -0,0 +1,53 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available - + +โ€ข {i}encode + encode the text + + โ€ข {i}decode + decode the text +""" + +import base64 + +from . import ultroid_cmd + + +@ultroid_cmd(pattern="encode ?(.*)") +async def encod(e): + match = e.pattern_match.group(1) + if not match and e.is_reply: + gt = await e.get_reply_message() + if gt.text: + match = gt.text + if not (match or e.is_reply): + return await e.eor("`Give me Something to Encode..`") + byt = match.encode("ascii") + et = base64.b64encode(byt) + atc = et.decode("ascii") + await e.eor(f"**=>> Encoded Text :** `{match}`\n\n**=>> OUTPUT :**\n`{atc}`") + + +@ultroid_cmd(pattern="decode ?(.*)") +async def encod(e): + match = e.pattern_match.group(1) + if not match and e.is_reply: + gt = await e.get_reply_message() + if gt.text: + match = gt.text + if not (match or e.is_reply): + return await e.eor("`Give me Something to Decode..`") + byt = match.encode("ascii") + try: + et = base64.b64decode(byt) + atc = et.decode("ascii") + await e.eor(f"**=>> Decoded Text :** `{match}`\n\n**=>> OUTPUT :**\n`{atc}`") + except Exception as p: + await e.eor("**ERROR :** " + str(p)) diff --git a/addons/extra.py b/addons/extra.py new file mode 100644 index 0000000..7fa9ac8 --- /dev/null +++ b/addons/extra.py @@ -0,0 +1,85 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("extra") + +import asyncio + +from . import get_string, ultroid_cmd + + +@ultroid_cmd( + pattern="del$", + manager=True, +) +async def delete_it(delme): + msg_src = await delme.get_reply_message() + if not msg_src: + return + await msg_src.try_delete() + await delme.try_delete() + + +@ultroid_cmd( + pattern="copy$", +) +async def copy(e): + reply = await e.get_reply_message() + if reply: + await reply.reply(reply) + return await e.try_delete() + await e.eor(get_string("ex_1"), time=5) + + +@ultroid_cmd( + pattern="edit", +) +async def editer(edit): + message = edit.text + chat = await edit.get_input_chat() + string = str(message[6:]) + reply = await edit.get_reply_message() + if reply and reply.text: + try: + await reply.edit(string) + await edit.delete() + except BaseException: + pass + else: + i = 1 + async for message in edit.client.iter_messages(chat, from_user="me", limit=2): + if i == 2: + await message.edit(string) + await edit.delete() + break + i += 1 + + +@ultroid_cmd( + pattern="reply$", +) +async def _(e): + if e.reply_to_msg_id: + chat = e.chat_id + try: + msg = (await e.client.get_messages(e.chat_id, limit=1, max_id=e.id))[0] + except IndexError: + return await e.eor( + "`You have previously sent no message to reply again...`", time=5 + ) + except BaseException as er: + return await e.eor(f"**ERROR:** `{er}`") + await asyncio.wait( + [ + e.client.delete_messages(chat, [e.id, msg.id]), + e.client.send_message(chat, msg, reply_to=e.reply_to_msg_id), + ] + ) + else: + await e.try_delete() diff --git a/addons/fakeaction.py b/addons/fakeaction.py new file mode 100644 index 0000000..7e88941 --- /dev/null +++ b/addons/fakeaction.py @@ -0,0 +1,36 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_fakeaction") + +import math +import time + +from pyUltroid.fns.admins import ban_time + +from . import asyncio, get_string, ultroid_cmd + + +@ultroid_cmd( + pattern="f(typing|audio|contact|document|game|location|sticker|photo|round|video)( (.*)|$)" +) +async def _(e): + act = e.pattern_match.group(1).strip() + t = e.pattern_match.group(2) + if act in ["audio", "round", "video"]: + act = f"record-{act}" + if t.isdigit(): + t = int(t) + elif t.endswith(("s", "h", "d", "m")): + t = math.ceil((ban_time(t)) - time.time()) + else: + t = 60 + await e.eor(get_string("fka_1").format(str(t)), time=5) + async with e.client.action(e.chat_id, act): + await asyncio.sleep(t) diff --git a/addons/fastly.py b/addons/fastly.py new file mode 100644 index 0000000..cb118de --- /dev/null +++ b/addons/fastly.py @@ -0,0 +1,84 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +Fasly Bot Cheat. + +โ€ข `{i}fastly` - On/Off command. + +โ€ข Also Required : `OCR_API`. Add it using the command `.setdb OCR_API api_key` +โ€ข To get the API visit 'https://ocr.space/ocrapi' +The bot will try to auto reply first to the messages by @FastlyWriteBot + +โ€ข Add User id of fastly clone to `FASTLY_CLONES` to allow this plugin work with them. +""" + +from telegraph import upload_file +from telethon import events +from . import udB, LOGS, ultroid_bot, ultroid_cmd, async_searcher +from os import remove + +base_url = "https://api.ocr.space/parse/imageurl?apikey={api}&url={tgraph}" + +BotList = [1806208310] + +if udB.get_key("FASTLY_CLONES"): + for i in udB.get_key("FASTLY_CLONES").split(): + try: + BotList.append(int(i)) + except TypeError: + LOGS.exception(f"Invalid Value in 'FASTLY_CLONES': {i}") + + +async def fastly_bot(event): + if not udB.get_key("FASTLY"): + return + api = udB.get_key("OCR_API") + if not (api and event.photo): + return + med = await event.download_media() + upload = upload_file(med) + link = "https://telegra.ph" + upload[0] + out = await async_searcher(base_url.format(api=api, tgraph=link), re_json=True) + try: + txt = out["ParsedResults"][0]["ParsedText"] + except (KeyError, IndexError): + return + txt = txt.split("By@")[0].replace("\n", "").replace("\r", "") + if txt: + try: + await event.reply(txt) + except Exception as er: + LOGS.exception(er) + try: + remove(med) + except Exception as e: + LOGS.exception(e) + + +@ultroid_cmd(pattern="fastly$") +async def fastOnOff(event): + xx = await event.eor("`...`") + get_ = udB.get_key("FASTLY") + if not get_: + if not udB.get_key("OCR_API"): + return await xx.edit("`OCR_API` is missing.\nAdd it before using this..") + udB.set_key("FASTLY", True) + ultroid_bot.add_handler( + fastly_bot, + events.NewMessage(incoming=True, from_users=BotList), + ) + return await xx.edit("`Auto Fastly Response Activated`") + udB.del_key("FASTLY") + await xx.edit("`Fastly Stopped!`") + + +if udB.get_key("FASTLY"): + ultroid_bot.add_handler( + fastly_bot, + events.NewMessage(incoming=True, from_users=BotList), + ) diff --git a/addons/figlet.py b/addons/figlet.py new file mode 100644 index 0000000..6291359 --- /dev/null +++ b/addons/figlet.py @@ -0,0 +1,506 @@ +""" +โœ˜ Commands Available + +โ€ข `{i}figlet ` + Make a text a figlet. +""" + +import pyfiglet + +from . import ultroid_cmd, split_list + +CMD_SET = { + "slant": "slant", + "3D": "3-d", + "5line": "5lineoblique", + "alpha": "alphabet", + "banner": "banner3-D", + "doh": "doh", + "iso": "isometric1", + "letters": "letters", + "allig": "alligator", + "dotm": "dotmatrix", + "bubble": "bubble", + "bulb": "bulbhead", + "digi": "digital", + "3x5": "3x5", + "1943": "1943____", + "4x4": "4x4_offr", + "5x7": "5x7", + "5x8": "5x8", + "64f1": "64f1____", + "6x10": "6x10", + "6x9": "6x9", + "zooloo": "a_zooloo", + "acro": "acrobatic", + "aveng": "advenger", + "allig2": "alligator2", + "aqua": "aquaplan", + "arrows": "arrows", + "asc": "asc_____", + "ascii12": "ascii12", + "ascii9": "ascii9", + "ascii": "ascii___", + "assalt": "assalt_m", + "asslt": "asslt__m", + "atc": "atc_____", + "atcg": "atc_gran", + "avatar": "avatar", + "bm200": "b_m__200", + "banner3": "banner3", + "banner4": "banner4", + "barb": "barbwire", + "basic": "basic", + "battles": "battle_s", + "battlesh": "battlesh", + "baz": "baz__bil", + "beer": "beer_pub", + "bell": "bell", + "big": "big", + "bigascii12": "bigascii12", + "bigascii9": "bigascii9", + "bigchief": "bigchief", + "bigmono12": "bigmono12", + "bigmono9": "bigmono9", + "binary": "binary", + "block": "block", + "brite": "brite", + "briteb": "briteb", + "britebi": "britebi", + "britei": "britei", + "broadway": "broadway", + "bubbles": "bubble__", + "buble": "bubble_b", + "bhead": "bulbhead", + "c1": "c1______", + "c2": "c2______", + "cascii": "c_ascii_", + "cconsen": "c_consen", + "calgphy2": "calgphy2", + "caligraphy": "caligraphy", + "catwalk": "catwalk", + "causin": "caus_in_", + "char1": "char1___", + "char2": "char2___", + "char3": "char3___", + "char4": "char4___", + "charact1": "charact1", + "charact2": "charact2", + "charact3": "charact3", + "charact4": "charact4", + "charact5": "charact5", + "charact6": "charact6", + "characte": "characte", + "charset": "charset_", + "chartr": "chartr", + "chartri": "chartri", + "chunky": "chunky", + "circle": "circle", + "clb6x10": "clb6x10", + "clb8x10": "clb8x10", + "clb8x8": "clb8x8", + "clr4x6": "clr4x6", + "clr5x10": "clr5x10", + "clr5x6": "clr5x6", + "clr5x8": "clr5x8", + "clr6x10": "clr6x10", + "clr6x6": "clr6x6", + "clr6x8": "clr6x8", + "clr7x10": "clr7x10", + "clr7x8": "clr7x8", + "clr8x10": "clr8x10", + "clr8x8": "clr8x8", + "coilcop": "coil_cop", + "coinstak": "coinstak", + "colossal": "colossal", + "comsen": "com_sen_", + "computer": "computer", + "contessa": "contessa", + "contrast": "contrast", + "convoy": "convoy__", + "cosmic": "cosmic", + "cosmike": "cosmike", + "cour": "cour", + "courb": "courb", + "courbi": "courbi", + "couri": "couri", + "crawford": "crawford", + "cricket": "cricket", + "cursive": "cursive", + "cyberlarge": "cyberlarge", + "cybermedium": "cybermedium", + "cybersmall": "cybersmall", + "ddragon": "d_dragon", + "dcsbfmo": "dcs_bfmo", + "decimal": "decimal", + "deepstr": "deep_str", + "defleppard": "defleppard", + "demo1": "demo_1__", + "demo2": "demo_2__", + "demom": "demo_m__", + "devilish": "devilish", + "diamond": "diamond", + "doom": "doom", + "double": "double", + "drpepper": "drpepper", + "druid": "druid___", + "efist": "e__fist_", + "ebbs1": "ebbs_1__", + "ebbs2": "ebbs_2__", + "eca": "eca_____", + "eftichess": "eftichess", + "eftifont": "eftifont", + "eftipiti": "eftipiti", + "eftirobot": "eftirobot", + "eftitalic": "eftitalic", + "eftiwall": "eftiwall", + "eftiwater": "eftiwater", + "emboss": "emboss", + "emboss2": "emboss2", + "epic": "epic", + "etcrvs": "etcrvs__", + "f15": "f15_____", + "facesof": "faces_of", + "fairmea": "fair_mea", + "fairligh": "fairligh", + "fantasy": "fantasy_", + "fbr12": "fbr12___", + "fbr1": "fbr1____", + "fbr2": "fbr2____", + "fbrstri": "fbr_stri", + "fbrtilt": "fbr_tilt", + "fender": "fender", + "finalass": "finalass", + "fireing": "fireing_", + "flynsh": "flyn_sh", + "fourtops": "fourtops", + "fp1": "fp1_____", + "fp2": "fp2_____", + "fraktur": "fraktur", + "funkydr": "funky_dr", + "future": "future", + "future1": "future_1", + "future2": "future_2", + "future3": "future_3", + "future4": "future_4", + "future5": "future_5", + "future6": "future_6", + "future7": "future_7", + "future8": "future_8", + "fuzzy": "fuzzy", + "gauntlet": "gauntlet", + "ghostbo": "ghost_bo", + "goofy": "goofy", + "gothic": "gothic", + "gothics": "gothic__", + "graceful": "graceful", + "gradient": "gradient", + "graffiti": "graffiti", + "grandpr": "grand_pr", + "greek": "greek", + "greenbe": "green_be", + "hades": "hades___", + "heavyme": "heavy_me", + "helv": "helv", + "helvb": "helvb", + "helvbi": "helvbi", + "helvi": "helvi", + "heroboti": "heroboti", + "hex": "hex", + "highnoo": "high_noo", + "hills": "hills___", + "holly": "hollywood", + "homepak": "home_pak", + "houseof": "house_of", + "hypabal": "hypa_bal", + "hyper": "hyper___", + "incraw": "inc_raw_", + "invita": "invita", + "iso2": "isometric2", + "iso3": "isometric3", + "iso4": "isometric4", + "italic": "italic", + "italics": "italics_", + "ivrit": "ivrit", + "jazmine": "jazmine", + "jerusalem": "jerusalem", + "joust": "joust___", + "ktk": "katakana", + "kban": "kban", + "kgamesi": "kgames_i", + "kikstar": "kik_star", + "krakout": "krak_out", + "larry3d": "larry3d", + "lazyjon": "lazy_jon", + "lcd": "lcd", + "lean": "lean", + "letter": "letter", + "letterr": "letter_", + "letterw3": "letterw3", + "lexible": "lexible_", + "linux": "linux", + "lockergnome": "lockergnome", + "lower": "lower", + "madnurs": "mad_nurs", + "madrid": "madrid", + "magicma": "magic_ma", + "marquee": "marquee", + "mastero": "master_o", + "maxfour": "maxfour", + "mayhemd": "mayhem_d", + "mcg": "mcg_____", + "migally": "mig_ally", + "mike": "mike", + "mini": "mini", + "mirror": "mirror", + "mnemonic": "mnemonic", + "modern": "modern__", + "mono12": "mono12", + "mono9": "mono9", + "morse": "morse", + "moscow": "moscow", + "mshebrew210": "mshebrew210", + "nancyjf": "nancyj-fancy", + "nancyju": "nancyj-underlined", + "nancyj": "nancyj", + "newasci": "new_asci", + "nfi1": "nfi1____", + "nipl": "nipples", + "notieca": "notie_ca", + "npn": "npn_____", + "ntgreek": "ntgreek", + "null": "null", + "nvscript": "nvscript", + "o8": "o8", + "octal": "octal", + "odellak": "odel_lak", + "ogre": "ogre", + "okbeer": "ok_beer_", + "os2": "os2", + "outrun": "outrun__", + "pshm": "p_s_h_m_", + "pskateb": "p_skateb", + "pacospe": "pacos_pe", + "pagga": "pagga", + "panther": "panther_", + "pawnins": "pawn_ins", + "pawp": "pawp", + "peaks": "peaks", + "pebbles": "pebbles", + "pepper": "pepper", + "phonix": "phonix__", + "platoon2": "platoon2", + "platoon": "platoon_", + "pod": "pod_____", + "poison": "poison", + "puffy": "puffy", + "pyramid": "pyramid", + "r2d2": "r2-d2___", + "rad": "rad_____", + "radphan": "rad_phan", + "radical": "radical_", + "rainbow": "rainbow_", + "rallys2": "rally_s2", + "rallysp": "rally_sp", + "rampage": "rampage_", + "rastan": "rastan__", + "rawrecu": "raw_recu", + "rci": "rci_____", + "rectangles": "rectangles", + "relief": "relief", + "relief2": "relief2", + "rev": "rev", + "ripper": "ripper!_", + "roadrai": "road_rai", + "rockbox": "rockbox_", + "rok": "rok_____", + "roman": "roman", + "romans": "roman___", + "rot13": "rot13", + "rounded": "rounded", + "rowancap": "rowancap", + "rozzo": "rozzo", + "runic": "runic", + "runyc": "runyc", + "sans": "sans", + "sansb": "sansb", + "sansbi": "sansbi", + "sansi": "sansi", + "sblood": "sblood", + "sbook": "sbook", + "sbookb": "sbookb", + "sbookbi": "sbookbi", + "sbooki": "sbooki", + "script": "script", + "scripts": "script__", + "serifcap": "serifcap", + "shadow": "shadow", + "shimrod": "shimrod", + "short": "short", + "skatero": "skate_ro", + "skateord": "skateord", + "skateroc": "skateroc", + "sketchs": "sketch_s", + "slide": "slide", + "slscript": "slscript", + "sm": "sm______", + "small": "small", + "smascii12": "smascii12", + "smascii9": "smascii9", + "smblock": "smblock", + "smbraille": "smbraille", + "smisome1": "smisome1", + "smkeyboard": "smkeyboard", + "smmono12": "smmono12", + "smmono9": "smmono9", + "smscript": "smscript", + "smshadow": "smshadow", + "smslant": "smslant", + "smtengwar": "smtengwar", + "spaceop": "space_op", + "spcdemo": "spc_demo", + "speed": "speed", + "stacey": "stacey", + "stampatello": "stampatello", + "standard": "standard", + "starwar": "star_war", + "starwars": "starwars", + "stealth": "stealth_", + "stellar": "stellar", + "stencil1": "stencil1", + "stencil2": "stencil2", + "stop": "stop", + "straight": "straight", + "street_s": "street_s", + "subteran": "subteran", + "superte": "super_te", + "tofap": "t__of_ap", + "tanja": "tanja", + "tav1": "tav1____", + "taxi": "taxi____", + "tec1": "tec1____", + "tec7000": "tec_7000", + "tecrvs": "tecrvs__", + "tengwar": "tengwar", + "term": "term", + "thick": "thick", + "thin": "thin", + "threepoint": "threepoint", + "tipan": "ti_pan__", + "ticks": "ticks", + "ticksslant": "ticksslant", + "tiles": "tiles", + "times": "times", + "timesofl": "timesofl", + "tinkertoy": "tinker-toy", + "tomahawk": "tomahawk", + "tombstone": "tombstone", + "top_duck": "top_duck", + "trashman": "trashman", + "trek": "trek", + "triadst": "triad_st", + "ts1": "ts1_____", + "tsalagi": "tsalagi", + "tsm": "tsm_____", + "tsnbase": "tsn_base", + "tty": "tty", + "ttyb": "ttyb", + "tubular": "tubular", + "twincob": "twin_cob", + "twopoint": "twopoint", + "typeset": "type_set", + "ucffan": "ucf_fan_", + "ugalympi": "ugalympi", + "unarmed": "unarmed_", + "univers": "univers", + "upper": "upper", + "usa": "usa_____", + "usapq": "usa_pq__", + "usaflag": "usaflag", + "utopia": "utopia", + "utopiab": "utopiab", + "utopiabi": "utopiabi", + "utopiai": "utopiai", + "vortron": "vortron_", + "warofw": "war_of_w", + "wavy": "wavy", + "weird": "weird", + "whimsy": "whimsy", + "wideterm": "wideterm", + "xbrite": "xbrite", + "xbriteb": "xbriteb", + "xbritebi": "xbritebi", + "xbritei": "xbritei", + "xchartr": "xchartr", + "xchartri": "xchartri", + "xcour": "xcour", + "xcourb": "xcourb", + "xcourbi": "xcourbi", + "xcouri": "xcouri", + "xhelv": "xhelv", + "xhelvb": "xhelvb", + "xhelvbi": "xhelvbi", + "xhelvi": "xhelvi", + "xsans": "xsans", + "xsansb": "xsansb", + "xsansbi": "xsansbi", + "xsansi": "xsansi", + "xsbook": "xsbook", + "xsbookb": "xsbookb", + "xsbookbi": "xsbookbi", + "xsbooki": "xsbooki", + "xtimes": "xtimes", + "xtty": "xtty", + "xttyb": "xttyb", + "yiear": "yie-ar__", + "yieark": "yie_ar_k", + "zpilot": "z-pilot_", + "zigzag": "zig_zag_", + "zone7": "zone7___", +} + +DataList = sorted(list(CMD_SET.keys())) +Split = split_list(DataList, 42) +offset = 0 + + +@ultroid_cmd(pattern="figlet( ?(.*)|$)") +async def figlet(event): + input_str = event.pattern_match.group(1).strip() + if not input_str: + return await event.eor("`Provide some text to make figlet...`") + if input_str == "list": + global offset + if offset == len(Split): + offset = 0 + All = Split[offset] + Text = "**List of Figlet Fonts :**\n\n" + while All: + c = 3 + Nline = "โ€ขโ€ข " + " ".join([f"`{a}`" for a in All[:3]]) + while (c < len(All) - 1) and len(Nline) < 32: + c += 1 + Nline += f" `{All[c]}`" + Text += Nline + "\n" + All = All[c:] + await event.eor(Text) + offset += 1 + return + if "|" in input_str: + text, cmd = input_str.split("|", maxsplit=1) + elif input_str is not None: + cmd = None + text = input_str + else: + await event.eor("Please add some text to figlet") + return + if cmd is not None: + try: + font = CMD_SET[cmd] + except KeyError: + await event.eor("Invalid selected font.") + return + result = pyfiglet.figlet_format(text, font=font) + else: + result = pyfiglet.figlet_format(text) + await event.eor(f"โ€Œโ€Œโ€Ž`{result}`") diff --git a/addons/filter.py b/addons/filter.py new file mode 100644 index 0000000..c25c41c --- /dev/null +++ b/addons/filter.py @@ -0,0 +1,140 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_filter") + +import os +import re + +from telethon.tl.types import User +from telethon.utils import get_display_name + +from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button + +from . import events, get_string, mediainfo, udB, ultroid_bot, ultroid_cmd, upload_file +from ._inline import something + +# Functions moved from filter_db.py +def get_stuff(): + return udB.get_key("FILTERS") or {} + + +def add_filter(chat, word, msg, media, button): + ok = get_stuff() + if ok.get(chat): + ok[chat].update({word: {"msg": msg, "media": media, "button": button}}) + else: + ok.update({chat: {word: {"msg": msg, "media": media, "button": button}}}) + udB.set_key("FILTERS", ok) + + +def rem_filter(chat, word): + ok = get_stuff() + if ok.get(chat) and ok[chat].get(word): + ok[chat].pop(word) + udB.set_key("FILTERS", ok) + + +def rem_all_filter(chat): + ok = get_stuff() + if ok.get(chat): + ok.pop(chat) + udB.set_key("FILTERS", ok) + + +def get_filter(chat): + ok = get_stuff() + if ok.get(chat): + return ok[chat] + + +def list_filter(chat): + ok = get_stuff() + if ok.get(chat): + return "".join(f"๐Ÿ‘‰ `{z}`\n" for z in ok[chat]) + + +@ultroid_cmd(pattern="addfilter( (.*)|$)") +async def af(e): + wrd = (e.pattern_match.group(1).strip()).lower() + wt = await e.get_reply_message() + chat = e.chat_id + if not (wt and wrd): + return await e.eor(get_string("flr_1")) + btn = format_btn(wt.buttons) if wt.buttons else None + if wt and wt.media: + wut = mediainfo(wt.media) + if wut.startswith(("pic", "gif")): + dl = await wt.download_media() + variable = upload_file(dl) + os.remove(dl) + elif wut == "video": + if wt.media.document.size > 8 * 1000 * 1000: + return await e.eor(get_string("com_4")) + dl = await wt.download_media() + variable = upload_file(dl) + os.remove(dl) + else: + variable = None + else: + variable = None + if not wt.text and not variable: + return await e.eor(get_string("flr_2")) + txt = wt.text or None + if txt: + if button := get_msg_button(txt): + txt = button[0] + button = button[1] + elif btn: + button = btn + else: + button = None + add_filter(chat, wrd, txt, variable, button) + await e.eor(get_string("flr_3").format(wrd)) + ultroid_bot.add_handler(filter_func, events.NewMessage()) + + +@ultroid_cmd(pattern="remfilter( (.*)|$)") +async def rf(e): + wrd = (e.pattern_match.group(1).strip()).lower() + chat = e.chat_id + if not wrd: + return await e.eor(get_string("flr_4")) + rem_filter(chat, wrd) + await e.eor(get_string("flr_5").format(wrd)) + + +@ultroid_cmd(pattern="listfilter$") +async def lsnote(e): + if x := list_filter(e.chat_id): + await e.eor(get_string("flr_6").format(x)) + else: + await e.eor(get_string("flr_7")) + + +async def filter_func(e): + if isinstance(e.sender, User) and e.sender.bot: + return + xx = (e.text).lower() + chat = e.chat_id + if x := get_filter(chat): + for c in x: + pat = r"( |^|[^\w])" + re.escape(c) + r"( |$|[^\w])" + if re.search(pat, xx): + if k := x.get(c): + msg = k["msg"] + media = k["media"] + if k.get("button"): + btn = create_tl_btn(k["button"]) + return await something(e, msg, media, btn) + await e.reply(msg, file=media) + + +if get_stuff(): + ultroid_bot.add_handler(filter_func, events.NewMessage()) diff --git a/addons/findsong.py b/addons/findsong.py new file mode 100644 index 0000000..355eb70 --- /dev/null +++ b/addons/findsong.py @@ -0,0 +1,41 @@ +# Ultroid Userbot +# Made by senku + +""" +โœ˜ Commands Available + +โ€ข `{i}findsong ` + Identify the song name +""" + +from telethon.errors.rpcerrorlist import YouBlockedUserError + +from . import * + + +@ultroid_cmd(pattern="findsong$") +async def _(event): + if not event.reply_to_msg_id: + return await event.eor("Reply to an audio message.") + reply_message = await event.get_reply_message() + chat = "@auddbot" + snku = await event.eor("Identifying the song") + async with event.client.conversation(chat) as conv: + try: + await conv.send_message("/start") + await conv.get_response() + await conv.send_message(reply_message) + check = await conv.get_response() + if not check.text.startswith("Audio received"): + return await snku.edit( + "An error while identifying the song. Try to use a 5-10s long audio message." + ) + await snku.edit("Wait just a sec...") + result = await conv.get_response() + await event.client.send_read_acknowledge(conv.chat_id) + except YouBlockedUserError: + await snku.edit("Please unblock (@auddbot) and try again") + return + namem = f"**Song Name : **{result.text.splitlines()[0]}\ + \n\n**Details : **__{result.text.splitlines()[2]}__" + await snku.edit(namem) diff --git a/addons/flaticon.py b/addons/flaticon.py new file mode 100644 index 0000000..0abff1a --- /dev/null +++ b/addons/flaticon.py @@ -0,0 +1,45 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + + +""" +โœ˜ Commands Available + +โ€ข `{i}icon ` + Icon search from flaticon.com and uploading as sticker. +""" + +import os +import random + +from bs4 import BeautifulSoup as bs + +from . import LOGS, ultroid_cmd, download_file, async_searcher, get_string + + +@ultroid_cmd(pattern="icon ?(.*)") +async def www(e): + a = e.pattern_match.group(1) + if not a: + return await e.eor("Give some Text to Get Icon from Flaticon.com") + tt = await e.eor(get_string("com_1")) + query = a.replace(" ", "%20") + try: + link = f"https://www.flaticon.com/search?word={query}" + ge = await async_searcher(link) + cl = bs(ge, "html.parser", from_encoding="utf-8") + results = cl.find_all( + "img", src="https://media.flaticon.com/dist/min/img/loader.gif" + ) + dome = results[random.randrange(0, len(results) - 1)]["data-src"] + await download_file(dome, "sticker.webp") + await e.reply(file="sticker.webp") + os.remove("sticker.webp") + await tt.delete() + except Exception as E: + LOGS.info(E) + await tt.edit("`No Results Found`") diff --git a/addons/fontgen.py b/addons/fontgen.py new file mode 100644 index 0000000..d686c75 --- /dev/null +++ b/addons/fontgen.py @@ -0,0 +1,60 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import get_help + +__doc__ = get_help("help_fontgen") + +import string + +from . import eod, ultroid_cmd + +_default = string.ascii_letters +Fonts = { + "small caps": "แด€ส™แด„แด…แด‡า“ษขสœษชแดŠแด‹สŸแดษดแดแด˜ฯ™ส€sแด›แดœแด แดกxสแดขABCDEFGHIJKLMNOPQRSTUVWXYZ", + "monospace": "๐šŠ๐š‹๐šŒ๐š๐šŽ๐š๐š๐š‘๐š’๐š“๐š”๐š•๐š–๐š—๐š˜๐š™๐šš๐š›๐šœ๐š๐šž๐šŸ๐š ๐šก๐šข๐šฃ๐™ฐ๐™ฑ๐™ฒ๐™ณ๐™ด๐™ต๐™ถ๐™ท๐™ธ๐™น๐™บ๐™ป๐™ผ๐™ฝ๐™พ๐™ฟ๐š€๐š๐š‚๐šƒ๐š„๐š…๐š†๐š‡๐šˆ๐š‰", + "double stroke": "๐•’๐•“๐•”๐••๐•–๐•—๐•˜๐•™๐•š๐•›๐•œ๐•๐•ž๐•Ÿ๐• ๐•ก๐•ข๐•ฃ๐•ค๐•ฅ๐•ฆ๐•ง๐•จ๐•ฉ๐•ช๐•ซ๐”ธ๐”นโ„‚๐”ป๐”ผ๐”ฝ๐”พโ„๐•€๐•๐•‚๐•ƒ๐•„โ„•๐•†โ„™โ„šโ„๐•Š๐•‹๐•Œ๐•๐•Ž๐•๐•โ„ค", + "script royal": "๐’ถ๐’ท๐’ธ๐’น๐‘’๐’ป๐‘”๐’ฝ๐’พ๐’ฟ๐“€๐“๐“‚๐“ƒ๐‘œ๐“…๐“†๐“‡๐“ˆ๐“‰๐“Š๐“‹๐“Œ๐“๐“Ž๐“๐’œโ„ฌ๐’ž๐’Ÿโ„ฐโ„ฑ๐’ขโ„‹โ„๐’ฅ๐’ฆโ„’โ„ณ๐’ฉ๐’ช๐’ซ๐’ฌโ„›๐’ฎ๐’ฏ๐’ฐ๐’ฑ๐’ฒ๐’ณ๐’ด๐’ต", +} + + +@ultroid_cmd( + pattern="font( (.*)|$)", +) +async def _(e): + input = e.pattern_match.group(1).strip() + reply = await e.get_reply_message() + if not input: + m = "**Available Fonts**\n\n" + for x in Fonts.keys(): + m += f"โ€ข `{x}`\n" + return await e.eor(m, time=5) + if not reply: + try: + _ = input.split(":", maxsplit=1) + font = _[0][:-1] + text = _[1] + except IndexError: + return await eod(e, help) + elif not input: + return await eod(e, "`Give font dude :/`") + else: + font = input + text = reply.message + if font not in Fonts.keys(): + return await e.eor(f"`{font} not in font list`.", time=5) + msg = gen_font(text, Fonts[font]) + await e.eor(msg) + + +def gen_font(text, new_font): + new_font = " ".join(new_font).split() + for q in text: + if q in _default: + new = new_font[_default.index(q)] + text = text.replace(q, new) + return text diff --git a/addons/fontsnew.py b/addons/fontsnew.py new file mode 100644 index 0000000..2cc2c54 --- /dev/null +++ b/addons/fontsnew.py @@ -0,0 +1,517 @@ +# +# Credits @chewmo +# +# Ported for Ultroid < https://github.com/TeamUltroid/Ultroid > +# + +""" +โœ˜ Commands Available - + +โ€ข `{i}weeb ` + turns text to ๅฑฑไน‡ไน‡ไนƒ font + +โ€ข `{i}tantext ` + turns text to แŽฟแŽฏแแŽฟแ‹๏พ’แŽฟ font + +โ€ข `{i}linetext ` + turns text to ๐•ƒ๐•€โ„•๐”ผ๐•‹๐”ผ๐•๐•‹ + +โ€ข `{i}boxtext ` + turns text to ๐Ÿ„ฑ๐Ÿ„พ๐Ÿ…‡๐Ÿ…ƒ๐Ÿ„ด๐Ÿ…‡๐Ÿ…ƒ + +โ€ข `{i}bubbletext ` + turns text to โ’ทโ“Šโ’ทโ’ทโ“โ’บโ“‰โ’บโ“โ“‰ + +โ€ข `{i}cursive ` + turns text to ๐“ฌ๐“พ๐“ป๐“ผ๐“ฒ๐“ฟ๐“ฎ font + +โ€ข `{i}greekify ` + turns text to ฯ‘ะณฮตฮตฮบฮนา“ฯˆ font + +โ€ข `{i}sorcify ` + turns text to ึ†ึ…ส€ฦˆษ›ส€ษ›ส€ font + +โ€ข `{i}fraktify ` + turns text to ๐–‹๐–—๐–†๐–๐–™๐–š๐–—๐–Š font + +โ€ข `{i}rusify ` + turns text to ัั†$ั—fั‡ font +""" + + +normiefont = [ + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", +] +weebyfont = [ + "ๅ‚", + "ไนƒ", + "ๅŒš", + "ๅˆ€", + "ไน‡", + "ไธ‹", + "ๅŽถ", + "ๅ„", + "ๅทฅ", + "ไธ", + "้•ฟ", + "ไนš", + "ไปŽ", + "๐ ˜จ", + "ๅฃ", + "ๅฐธ", + "ใ”ฟ", + "ๅฐบ", + "ไธ‚", + "ไธ…", + "ๅ‡ต", + "ใƒช", + "ๅฑฑ", + "ไน‚", + "ไธซ", + "ไน™", +] +tantextfont = [ + "แŽฏ", + "แฐ", + "แฃ", + "แŽด", + "แ‹", + "แŽด", + "แŽถ", + "แ‚", + "i", + "แ ", + "แฆ", + "l", + "m", + "แ", + "แซ", + "แŽต", + "แ„", + "แ–‡", + "แŽฆ", + "แŽฟ", + "แŒ", + "แ‰", + "แฏ", + "๏พ’", + "แŽฉ", + "แƒ", +] +linetextfont = [ + "๐”ธ", + "๐”น", + "โ„‚", + "๐”ป", + "๐”ผ", + "๐”ฝ", + "๐”พ", + "โ„", + "๐•€", + "๐•", + "๐•‚", + "๐•ƒ", + "๐•„", + "โ„•", + "๐•†", + "โ„™", + "โ„š", + "โ„", + "๐•Š", + "๐•‹", + "๐•Œ", + "๐•", + "๐•Ž", + "๐•", + "๐•", + "โ„ค", +] +boxtextfont = [ + "๐Ÿ„ฐ", + "๐Ÿ„ฑ", + "๐Ÿ„ฒ", + "๐Ÿ„ณ", + "๐Ÿ„ด", + "๐Ÿ„ต", + "๐Ÿ„ถ", + "๐Ÿ„ท", + "๐Ÿ„ธ", + "๐Ÿ„น", + "๐Ÿ„บ", + "๐Ÿ„ป", + "๐Ÿ„ผ", + "๐Ÿ„ฝ", + "๐Ÿ„พ", + "๐Ÿ„ฟ", + "๐Ÿ…€", + "๐Ÿ…", + "๐Ÿ…‚", + "๐Ÿ…ƒ", + "๐Ÿ…„", + "๐Ÿ……", + "๐Ÿ…†", + "๐Ÿ…‡", + "๐Ÿ…ˆ", + "๐Ÿ…‰", +] +bubbletextfont = [ + "โ’ถ", + "โ’ท", + "โ’ธ", + "โ’น", + "โ’บ", + "โ’ป", + "โ’ผ", + "โ’ฝ", + "โ’พ", + "โ’ฟ", + "โ“€", + "โ“", + "โ“‚", + "โ“ƒ", + "โ“„", + "โ“…", + "โ“†", + "โ“‡", + "โ“ˆ", + "โ“‰", + "โ“Š", + "โ“‹", + "โ“Œ", + "โ“", + "โ“Ž", + "โ“", +] +cursivefont = [ + "๐“ช", + "๐“ซ", + "๐“ฌ", + "๐“ญ", + "๐“ฎ", + "๐“ฏ", + "๐“ฐ", + "๐“ฑ", + "๐“ฒ", + "๐“ณ", + "๐“ด", + "๐“ต", + "๐“ถ", + "๐“ท", + "๐“ธ", + "๐“น", + "๐“บ", + "๐“ป", + "๐“ผ", + "๐“ฝ", + "๐“พ", + "๐“ฟ", + "๐”€", + "๐”", + "๐”‚", + "๐”ƒ", +] +greekfont = [ + "ฮป", + "ฯ", + "ฯ‚", + "d", + "ฮต", + "า“", + "ฯ‘", + "ะฝ", + "ฮน", + "ฯณ", + "ฮบ", + "l", + "ฯป", + "ฯ€", + "ฯƒ", + "ฯ", + "ฯ†", + "ะณ", + "s", + "ฯ„", + "ฯ…", + "v", + "ัˆ", + "ฯฐ", + "ฯˆ", + "z", +] +sorcererfont = [ + "วŸ", + "ษฎ", + "ฦˆ", + "ษ–", + "ษ›", + "ส„", + "ษข", + "ษฆ", + "ษจ", + "ส", + "ำ„", + "สŸ", + "ส", + "ีผ", + "ึ…", + "ึ„", + "ีฆ", + "ส€", + "ึ†", + "ศถ", + "สŠ", + "ส‹", + "ีก", + "ำผ", + "ส", + "ส", +] +frakturfont = [ + "๐–†", + "๐–‡", + "๐–ˆ", + "๐–‰", + "๐–Š", + "๐–‹", + "๐–Œ", + "๐–", + "๐–Ž", + "๐–", + "๐–", + "๐–‘", + "๐–’", + "๐–“", + "๐–”", + "๐–•", + "๐––", + "๐–—", + "๐–˜", + "๐–™", + "๐–š", + "๐–›", + "๐–œ", + "๐–", + "๐–ž", + "๐–Ÿ", +] +rusifont = [ + "ะฐ", + "ะฑ", + "c", + "ะด", + "ั‘", + "f", + "g", + "ะฝ", + "ั—", + "j", + "ะบ", + "ะณ", + "ัซ", + "ะฟ", + "ัณ", + "p", + "ั„", + "ั", + "$", + "ั‚", + "ั†", + "ัต", + "ั‰", + "ะถ", + "ั‡", + "ะท", +] + + +@ultroid_cmd(pattern="weeb ?(.*)") +async def weebify(ult): + args = ult.pattern_match.group(1) + if not args and ult.is_reply: + get = await ult.get_reply_message() + args = get.text + if not args: + await ult.edit("What I am Supposed to Weebify? Please Give Text Sir") + return + string = "".join(args).lower() + for normiecharacter in string: + if normiecharacter in normiefont: + weebycharacter = weebyfont[normiefont.index(normiecharacter)] + string = string.replace(normiecharacter, weebycharacter) + await ult.eor(string) + + +@ultroid_cmd(pattern="tantext ?(.*)") +async def tantxt(ult): + args = ult.pattern_match.group(1) + if not args and ult.is_reply: + get = await ult.get_reply_message() + args = get.text + if not args: + await ult.edit("What I am Supposed to tanify? Please Give Text Sir") + return + string = "".join(args).lower() + for normiecharacter in string: + if normiecharacter in normiefont: + tanycharacter = tantextfont[normiefont.index(normiecharacter)] + string = string.replace(normiecharacter, tanycharacter) + await ult.eor(string) + + +@ultroid_cmd(pattern="linetext ?(.*)") +async def linetxt(ult): + args = ult.pattern_match.group(1) + if not args and ult.is_reply: + get = await ult.get_reply_message() + args = get.text + if not args: + await ult.edit("What I am Supposed to linefy? Please Give Text Sir") + return + string = "".join(args).lower() + for normiecharacter in string: + if normiecharacter in normiefont: + linecharacter = linetextfont[normiefont.index(normiecharacter)] + string = string.replace(normiecharacter, linecharacter) + await ult.edit(string) + + +@ultroid_cmd(pattern="boxtext ?(.*)") +async def boxtxt(ult): + args = ult.pattern_match.group(1) + if not args and ult.is_reply: + get = await ult.get_reply_message() + args = get.text + if not args: + return await ult.edit("What I am Supposed to boxify? Please Give Text Sir") + string = "".join(args).lower() + for normiecharacter in string: + if normiecharacter in normiefont: + boxcharacter = boxtextfont[normiefont.index(normiecharacter)] + string = string.replace(normiecharacter, boxcharacter) + await ult.eor(string) + + +@ultroid_cmd(pattern="bubbletext ?(.*)") +async def bubbletxt(ult): + args = ult.pattern_match.group(1) + if not args and ult.is_reply: + get = await ult.get_reply_message() + args = get.text + if not args: + return await ult.edit("What I am Supposed to bubblify? Please Give Text Sir") + string = "".join(args).lower() + for normiecharacter in string: + if normiecharacter in normiefont: + bubblecharacter = bubbletextfont[normiefont.index(normiecharacter)] + string = string.replace(normiecharacter, bubblecharacter) + await ult.eor(string) + + +@ultroid_cmd(pattern="cursive ?(.*)") +async def cursive(ult): + args = ult.pattern_match.group(1) + if not args and ult.is_reply: + get = await ult.get_reply_message() + args = get.text + if not args: + return await ult.edit( + "What I am Supposed to write in cursive? Please Give Text Sir" + ) + string = "".join(args).lower() + for normiecharacter in string: + if normiecharacter in normiefont: + cursivecharacter = cursivefont[normiefont.index(normiecharacter)] + string = string.replace(normiecharacter, cursivecharacter) + await ult.eor(string) + + +@ultroid_cmd(pattern="greekify ?(.*)") +async def greektext(ult): + args = ult.pattern_match.group(1) + if not args and ult.is_reply: + get = await ult.get_reply_message() + args = get.text + if not args: + return await ult.edit("What I am Supposed to greekify? Please Give Text Sir") + string = "".join(args).lower() + for normiecharacter in string: + if normiecharacter in normiefont: + greekcharacter = greekfont[normiefont.index(normiecharacter)] + string = string.replace(normiecharacter, greekcharacter) + await ult.eor(string) + + +@ultroid_cmd(pattern="sorcify ?(.*)") +async def sorcerertext(ult): + + args = ult.pattern_match.group(1) + if not args and ult.is_reply: + get = await ult.get_reply_message() + args = get.text + if not args: + await ult.edit("What I am Supposed to sorcify? Please Give Text Sir") + return + string = "".join(args).lower() + for normiecharacter in string: + if normiecharacter in normiefont: + sorcerercharacter = sorcererfont[normiefont.index(normiecharacter)] + string = string.replace(normiecharacter, sorcerercharacter) + await ult.eor(string) + + +@ultroid_cmd(pattern="fraktify ?(.*)") +async def frakturtext(ult): + args = ult.pattern_match.group(1) + if not args and ult.is_reply: + get = await ult.get_reply_message() + args = get.text + if not args: + await ult.edit("What I am Supposed to fraktify? Please Give Text Sir") + return + string = "".join(args).lower() + for normiecharacter in string: + if normiecharacter in normiefont: + frakturcharacter = frakturfont[normiefont.index(normiecharacter)] + string = string.replace(normiecharacter, frakturcharacter) + await ult.eor(string) + + +@ultroid_cmd(pattern="rusify ?(.*)") +async def rusitext(ult): + args = ult.pattern_match.group(1) + if not args and ult.is_reply: + get = await ult.get_reply_message() + args = get.text + if not args: + return await ult.edit("What I am Supposed to rusify? Please Give Text Sir") + string = "".join(args).lower() + for normiecharacter in string: + if normiecharacter in normiefont: + rusicharacter = rusifont[normiefont.index(normiecharacter)] + string = string.replace(normiecharacter, rusicharacter) + await ult.eor(string) diff --git a/addons/forcesubscribe.py b/addons/forcesubscribe.py new file mode 100644 index 0000000..3245053 --- /dev/null +++ b/addons/forcesubscribe.py @@ -0,0 +1,229 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available - + +โ€ข `{i}fsub ` + Enable ForceSub in Used Chat ! + +โ€ข `{i}checkfsub` + Check/Get Active ForceSub Setting of Used Chat. + +โ€ข `{i}remfsub` + Remove ForceSub from Used Chat ! + + Note - You Need to be Admin in Both Channel/Chats + in order to Use ForceSubscribe. +""" + +import re + +from telethon.errors.rpcerrorlist import ChatAdminRequiredError, UserNotParticipantError +from telethon.tl.custom import Button +from telethon.tl.functions.channels import GetParticipantRequest +from telethon.tl.functions.messages import ExportChatInviteRequest +from telethon.tl.types import ( + Channel, + ChannelParticipantBanned, + ChannelParticipantLeft, + User, +) + +from . import ( + LOGS, + asst, + callback, + events, + get_string, + in_pattern, + inline_mention, + udB, + ultroid_bot, + ultroid_cmd, +) + +# Functions moved from forcesub_db.py +def get_chats(): + return udB.get_key("FORCESUB") or {} + + +def add_forcesub(chat_id, chattojoin): + omk = get_chats() + omk.update({chat_id: chattojoin}) + return udB.set_key("FORCESUB", omk) + + +def get_forcesetting(chat_id): + omk = get_chats() + if chat_id in omk.keys(): + return omk[chat_id] + + +def rem_forcesub(chat_id): + omk = get_chats() + if chat_id in omk.keys(): + try: + del omk[chat_id] + return udB.set_key("FORCESUB", omk) + except KeyError: + return False + + +CACHE = {} + + +@ultroid_cmd(pattern="fsub( (.*)|$)", admins_only=True, groups_only=True) +async def addfor(e): + match = e.pattern_match.group(1).strip() + if not match: + return await e.eor(get_string("fsub_1"), time=5) + try: + match = await e.client.parse_id(match) + except BaseException: + return await e.eor(get_string("fsub_2"), time=5) + add_forcesub(e.chat_id, match) + await e.eor("Added ForceSub in This Chat !") + ultroid_bot.add_handler(force_sub, events.NewMessage(incoming=True)) + + +@ultroid_cmd(pattern="remfsub$") +async def remor(e): + res = rem_forcesub(e.chat_id) + if not res: + return await e.eor(get_string("fsub_3"), time=5) + await e.eor("Removed ForceSub...") + + +@ultroid_cmd(pattern="checkfsub$") +async def getfsr(e): + res = get_forcesetting(e.chat_id) + if not res: + return await e.eor("ForceSub is Not Active In This Chat !", time=5) + cha = await e.client.get_entity(int(res)) + await e.eor(f"**ForceSub Status** : `Active`\n- **{cha.title}** `({res})`") + + +@in_pattern("fsub( (.*)|$)", owner=True) +async def fcall(e): + match = e.pattern_match.group(1).strip() + spli = match.split("_") + user = await ultroid_bot.get_entity(int(spli[0])) + cl = await ultroid_bot.get_entity(int(spli[1])) + text = f"Hi {inline_mention(user)}, You Need to Join" + text += f" {cl.title} in order to Chat in this Group." + el = ( + f"https://t.me/{cl.username}" + if cl.username + else (await ultroid_bot(ExportChatInviteRequest(cl))).link + ) + + res = [ + await e.builder.article( + title="forcesub", + text=text, + buttons=[ + [Button.url(text=get_string("fsub_4"), url=el)], + [Button.inline(get_string("fsub_5"), data=f"unm_{match}")], + ], + ) + ] + await e.answer(res) + + +@callback(re.compile("unm_(.*)")) +async def diesoon(e): + match = (e.data_match.group(1)).decode("UTF-8") + spli = match.split("_") + if e.sender_id != int(spli[0]): + return await e.answer(get_string("fsub_7"), alert=True) + try: + values = await ultroid_bot(GetParticipantRequest(int(spli[1]), int(spli[0]))) + if isinstance(values.participant, ChannelParticipantLeft) or ( + isinstance(values.participant, ChannelParticipantBanned) and values.left + ): + raise UserNotParticipantError("") + except UserNotParticipantError: + return await e.answer( + "Please Join That Channel !\nThen Click This Button !", alert=True + ) + await ultroid_bot.edit_permissions( + e.chat_id, int(spli[0]), send_messages=True, until_date=None + ) + await e.edit(get_string("fsub_8")) + + +async def force_sub(ult): + if not udB.get_key("FORCESUB"): + return + user = await ult.get_sender() + joinchat = get_forcesetting(ult.chat_id) + if (not joinchat) or (isinstance(user, User) and user.bot): + return + if CACHE.get(ult.chat_id): + if CACHE[ult.chat_id].get(user.id): + CACHE[ult.chat_id].update({user.id: CACHE[ult.chat_id][user.id] + 1}) + else: + CACHE[ult.chat_id].update({user.id: 1}) + else: + CACHE.update({ult.chat_id: {user.id: 1}}) + count = CACHE[ult.chat_id][user.id] + if count == 11: + CACHE[ult.chat_id][user.id] = 1 + return + if count in range(2, 11): + return + try: + await ultroid_bot.get_permissions(int(joinchat), user.id) + return + except UserNotParticipantError: + pass + if isinstance(user, Channel): + try: + await ultroid_bot.edit_permissions( + ult.chat_id, user.id, view_messages=False + ) + return + except BaseException as er: + LOGS.exception(er) + try: + await ultroid_bot.edit_permissions(ult.chat_id, user.id, send_messages=False) + except ChatAdminRequiredError: + return + except Exception as e: + await ult.delete() + LOGS.info(e) + res = await ultroid_bot.inline_query(asst.me.username, f"fsub {user.id}_{joinchat}") + await res[0].click(ult.chat_id, reply_to=ult.id) + + +# Add a handler for chat actions (user join events) +async def force_sub_action(ult): + if not udB.get_key("FORCESUB"): + return + if not (ult.user_joined or ult.user_added): + return + if not get_forcesetting(ult.chat_id): + return + user = await ult.get_user() + if user.bot: + return + joinchat = get_forcesetting(ult.chat_id) + try: + await ultroid_bot(GetParticipantRequest(int(joinchat), user.id)) + except UserNotParticipantError: + await ultroid_bot.edit_permissions( + ult.chat_id, user.id, send_messages=False + ) + res = await ultroid_bot.inline_query( + asst.me.username, f"fsub {user.id}_{joinchat}" + ) + await res[0].click(ult.chat_id, reply_to=ult.action_message.id) + + +if udB.get_key("FORCESUB"): + ultroid_bot.add_handler(force_sub, events.NewMessage(incoming=True)) + ultroid_bot.add_handler(force_sub_action, events.ChatAction()) diff --git a/addons/fun.py b/addons/fun.py new file mode 100644 index 0000000..0e69df7 --- /dev/null +++ b/addons/fun.py @@ -0,0 +1,123 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available + +โ€ข `{i}joke` + To get joke. + +โ€ข `{i}url ` + To get a shorten link of long link. + +โ€ข `{i}phlogo ` + Make a phub based logo. + +โ€ข `{i}decide` + Decide something. + +โ€ข `{i}xo` + Opens tic tac game only where using inline mode is allowed. + +โ€ข `{i}wordi` + Opens word game only where using inline mode is allowed. + +โ€ข `{i}gps ` + Shows the desired place in the map. +""" + +import random, os + +import requests +from bs4 import BeautifulSoup as bs +from pyjokes import get_joke +from telethon.errors import ChatSendMediaForbiddenError +from phlogo import generate + +from . import ultroid_cmd, get_string, HNDLR, async_searcher + + +@ultroid_cmd(pattern="joke$") +async def _(ult): + await ult.eor(get_joke()) + + +@ultroid_cmd(pattern="url ?(.*)") +async def _(event): + input_str = event.pattern_match.group(1) + if not input_str: + await event.eor("`Give some url`") + return + sample_url = "https://da.gd/s?url={}".format(input_str) + response_api = requests.get(sample_url).text + if response_api: + await event.eor( + "**Shortened url**==> {}\n**Given url**==> {}.".format( + response_api, input_str + ), + ) + else: + await event.eor("`Something went wrong. Please try again Later.`") + + +@ultroid_cmd(pattern="decide$") +async def _(event): + hm = await event.eor("`Deciding`") + r = await async_searcher("https://yesno.wtf/api", re_json=True) + try: + await event.reply(r["answer"], file=r["image"]) + await hm.delete() + except ChatSendMediaForbiddenError: + await event.eor(r["answer"]) + + +@ultroid_cmd(pattern="xo$") +async def xo(ult): + xox = await ult.client.inline_query("xobot", "play") + await xox[random.randrange(0, len(xox) - 1)].click( + ult.chat_id, reply_to=ult.reply_to_msg_id, silent=True, hide_via=True + ) + await ult.delete() + + +@ultroid_cmd(pattern="phlogo( (.*)|$)") +async def make_logog(ult): + msg = await ult.eor(get_string("com_1")) + match = ult.pattern_match.group(1).strip() + reply = await ult.get_reply_message() + if not match and (reply and reply.text): + match = reply.text + else: + return await msg.edit(f"`Provide a name to make logo...`") + first, last = "", "" + if len(match.split()) >= 2: + first, last = match.split()[:2] + else: + last = match + logo = generate(first, last) + name = f"{ult.id}.png" + logo.save(name) + await ult.client.send_message( + ult.chat_id, file=name, reply_to=ult.reply_to_msg_id or ult.id + ) + os.remove(name) + await msg.delete() + + +Bot = {"gps":"openmap_bot", "wordi":"wordibot"} + +@ultroid_cmd(pattern="(gps|wordi) (.*)") +async def _map(ult): + cmd = ult.pattern_match.group(1) + get = ult.pattern_match.group(2) + if not get: + return await ult.eor(f"Use this command as `{HNDLR}{cmd} `") + quer = await ult.client.inline_query(Bot[cmd], get) + await quer[0].click( + ult.chat_id, reply_to=ult.reply_to_msg_id, silent=True, hide_via=True + ) + await ult.delete() diff --git a/addons/gdrive.py b/addons/gdrive.py new file mode 100644 index 0000000..bafffbd --- /dev/null +++ b/addons/gdrive.py @@ -0,0 +1,232 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available + +โ€ข `{i}gdul ` + Reply to file to upload on Google Drive. + Add file name to upload on Google Drive. + +โ€ข `{i}gdown | ` + Download from Gdrive link or file id. + +โ€ข `{i}gdsearch ` + Search file name on Google Drive and get link. + +โ€ข `{i}gdlist` + List all GDrive files. + +โ€ข `{i}gdfolder` + Link to your Google Drive Folder. + If added then all files will be uploaded in this folder. +""" + +import os +import time + +from telethon.tl.types import Message + +from pyUltroid.fns.gDrive import GDriveManager +from pyUltroid.fns.helper import time_formatter + +from . import ULTConfig, asst, eod, eor, get_string, ultroid_cmd + + +@ultroid_cmd( + pattern="gdown( (.*)|$)", + fullsudo=True, +) +async def gdown(event): + GDrive = GDriveManager() + match = event.pattern_match.group(1).strip() + if not match: + return await eod(event, "`Give file id or Gdrive link to download from!`") + filename = match.split(" | ")[1].strip() if " | " in match else None + eve = await event.eor(get_string("com_1")) + _start = time.time() + status, response = await GDrive._download_file(eve, match, filename) + if not status: + return await eve.edit(response) + await eve.edit( + f"`Downloaded ``{response}`` in {time_formatter((time.time() - _start)*1000)}`" + ) + + +@ultroid_cmd( + pattern="gdlist$", + fullsudo=True, +) +async def files(event): + GDrive = GDriveManager() + if not os.path.exists(GDrive.token_file): + return await event.eor(get_string("gdrive_6").format(asst.me.username)) + eve = await event.eor(get_string("com_1")) + msg = "" + if files := GDrive._list_files: + msg += f"{len(files.keys())} files found in gdrive.\n\n" + for _ in files: + msg += f"> [{files[_]}]({_})\n" + else: + msg += "Nothing in Gdrive" + if len(msg) < 4096: + await eve.edit(msg, link_preview=False) + else: + with open("drive-files.txt", "w") as f: + f.write( + msg.replace("[", "File Name: ") + .replace("](", "\nยป Link: ") + .replace(")\n", "\n\n") + ) + try: + await eve.delete() + except BaseException: + pass + await event.client.send_file( + event.chat_id, + "drive-files.txt", + thumb=ULTConfig.thumb, + reply_to=event, + ) + os.remove("drive-files.txt") + + +@ultroid_cmd( + pattern="gdul( (.*)|$)", + fullsudo=True, +) +async def _(event): + GDrive = GDriveManager() + if not os.path.exists(GDrive.token_file): + return await eod(event, get_string("gdrive_6").format(asst.me.username)) + input_file = event.pattern_match.group(1).strip() or await event.get_reply_message() + if not input_file: + return await eod(event, "`Reply to file or give its location.`") + mone = await event.eor(get_string("com_1")) + if isinstance(input_file, Message): + location = "resources/downloads" + if input_file.photo: + filename = await input_file.download_media(location) + else: + filename = input_file.file.name + if not filename: + filename = str(round(time.time())) + filename = f"{location}/{filename}" + try: + filename, downloaded_in = await event.client.fast_downloader( + file=input_file.media.document, + filename=filename, + show_progress=True, + event=mone, + message=get_string("com_5"), + ) + filename = filename.name + except Exception as e: + return await eor(mone, str(e), time=10) + await mone.edit( + f"`Downloaded to ``{filename}`.`", + ) + else: + filename = input_file.strip() + if not os.path.exists(filename): + return await eod( + mone, + "File Not found in local server. Give me a file path :((", + time=5, + ) + folder_id = None + if os.path.isdir(filename): + files = os.listdir(filename) + if not files: + return await eod( + mone, "`Requested directory is empty. Can't create empty directory.`" + ) + folder_id = GDrive.create_directory(filename) + c = 0 + for files in sorted(files): + file = f"{filename}/{files}" + if not os.path.isdir(file): + try: + await GDrive._upload_file(mone, path=file, folder_id=folder_id) + c += 1 + except Exception as e: + return await mone.edit( + f"Exception occurred while uploading to gDrive {e}" + ) + return await mone.edit( + f"`Uploaded `[{filename}](https://drive.google.com/folderview?id={folder_id})` with {c} files.`" + ) + try: + g_drive_link = await GDrive._upload_file( + mone, + filename, + ) + await mone.edit( + get_string("gdrive_7").format(filename.split("/")[-1], g_drive_link) + ) + except Exception as e: + await mone.edit(f"Exception occurred while uploading to gDrive {e}") + + +@ultroid_cmd( + pattern="gdsearch( (.*)|$)", + fullsudo=True, +) +async def _(event): + GDrive = GDriveManager() + if not os.path.exists(GDrive.token_file): + return await event.eor(get_string("gdrive_6").format(asst.me.username)) + input_str = event.pattern_match.group(1).strip() + if not input_str: + return await event.eor("`Give filename to search on GDrive...`") + eve = await event.eor(f"`Searching for {input_str} in G-Drive...`") + files = GDrive.search(input_str) + msg = "" + if files: + msg += ( + f"{len(files.keys())} files with {input_str} in title found in GDrive.\n\n" + ) + for _ in files: + msg += f"> [{files[_]}]({_})\n" + else: + msg += f"`No files with title {input_str}`" + if len(msg) < 4096: + await eve.eor(msg, link_preview=False) + else: + with open("drive-files.txt", "w") as f: + f.write( + msg.replace("[", "File Name: ") + .replace("](", "\nยป Link: ") + .replace(")\n", "\n\n") + ) + try: + await eve.delete() + except BaseException: + pass + await event.client.send_file( + event.chat_id, + f"{input_str}.txt", + thumb=ULTConfig.thumb, + reply_to=event, + ) + os.remove(f"{input_str}.txt") + + +@ultroid_cmd( + pattern="gdfolder$", + fullsudo=True, +) +async def _(event): + GDrive = GDriveManager() + if not os.path.exists(GDrive.token_file): + return await event.eor(get_string("gdrive_6").format(asst.me.username)) + if GDrive.folder_id: + await event.eor( + "`Your G-Drive Folder link : `\n" + + GDrive._create_folder_link(GDrive.folder_id) + ) + else: + await eod(event, "Set FOLDERID from your Assistant bot's Settings ") diff --git a/addons/giftools.py b/addons/giftools.py new file mode 100644 index 0000000..5c8d0d2 --- /dev/null +++ b/addons/giftools.py @@ -0,0 +1,128 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available + +โ€ข`{i}invertgif` + Make Gif Inverted(negative). + +โ€ข`{i}bwgif` + Make Gif black and white + +โ€ข`{i}rvgif` + Reverse a gif + +โ€ข`{i}vtog` + Reply To Video , It will Create Gif + Video to Gif + +โ€ข`{i}gif ` + Send video regarding to query. +""" +import os +import random +import time +from datetime import datetime as dt + +from . import HNDLR, LOGS, bash, downloader, get_string, mediainfo, ultroid_cmd + + +@ultroid_cmd(pattern="(bw|invert)gif$") +async def igif(e): + match = e.pattern_match.group(1).strip() + a = await e.get_reply_message() + if not (a and a.media): + return await e.eor("`Reply To gif only`", time=5) + wut = mediainfo(a.media) + if "gif" not in wut: + return await e.eor("`Reply To Gif Only`", time=5) + xx = await e.eor(get_string("com_1")) + z = await a.download_media() + if match == "bw": + cmd = f'ffmpeg -i "{z}" -vf format=gray ult.gif -y' + else: + cmd = f'ffmpeg -i "{z}" -vf lutyuv="y=negval:u=negval:v=negval" ult.gif -y' + try: + await bash(cmd) + await e.client.send_file(e.chat_id, "ult.gif", supports_streaming=True) + os.remove(z) + os.remove("ult.gif") + await xx.delete() + except Exception as er: + LOGS.info(er) + + +@ultroid_cmd(pattern="rvgif$") +async def reverse_gif(event): + a = await event.get_reply_message() + if not (a and a.media) and "video" not in mediainfo(a.media): + return await event.eor("`Reply To Video only`", time=5) + msg = await event.eor(get_string("com_1")) + file = await a.download_media() + await bash(f'ffmpeg -i "{file}" -vf reverse -af areverse reversed.mp4 -y') + await event.respond("- **Reversed Video/GIF**", file="reversed.mp4") + await msg.delete() + os.remove(file) + os.remove("reversed.mp4") + + +@ultroid_cmd(pattern="gif( (.*)|$)") +async def gifs(ult): + get = ult.pattern_match.group(1).strip() + xx = random.randint(0, 5) + n = 0 + if ";" in get: + try: + n = int(get.split(";")[-1]) + except IndexError: + pass + if not get: + return await ult.eor(f"`{HNDLR}gif `") + m = await ult.eor(get_string("com_2")) + gifs = await ult.client.inline_query("gif", get) + if not n: + await gifs[xx].click( + ult.chat_id, reply_to=ult.reply_to_msg_id, silent=True, hide_via=True + ) + else: + for x in range(n): + await gifs[x].click( + ult.chat_id, reply_to=ult.reply_to_msg_id, silent=True, hide_via=True + ) + await m.delete() + + +@ultroid_cmd(pattern="vtog$") +async def vtogif(e): + a = await e.get_reply_message() + if not (a and a.media): + return await e.eor("`Reply To video only`", time=5) + wut = mediainfo(a.media) + if "video" not in wut: + return await e.eor("`Reply To Video Only`", time=5) + xx = await e.eor(get_string("com_1")) + dur = a.media.document.attributes[0].duration + tt = time.time() + if int(dur) < 120: + z = await a.download_media() + await bash( + f'ffmpeg -i {z} -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 ult.gif -y' + ) + else: + filename = a.file.name + if not filename: + filename = "video_" + dt.now().isoformat("_", "seconds") + ".mp4" + vid = await downloader(filename, a.media.document, xx, tt, get_string("com_5")) + z = vid.name + await bash( + f'ffmpeg -ss 3 -t 100 -i {z} -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 ult.gif' + ) + + await e.client.send_file(e.chat_id, "ult.gif", support_stream=True) + os.remove(z) + os.remove("ult.gif") + await xx.delete() diff --git a/addons/glitch.py b/addons/glitch.py new file mode 100644 index 0000000..d147ae4 --- /dev/null +++ b/addons/glitch.py @@ -0,0 +1,42 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available - + +โ€ข`{i}glitch ` + gives a glitchy gif. +""" +import os + +from .. import bash, get_string, mediainfo, ultroid_cmd + + +@ultroid_cmd(pattern="glitch$") +async def _(e): + try: + import glitch_me # ignore :pylint + except ModuleNotFoundError: + await bash( + "pip install -e git+https://github.com/1Danish-00/glitch_me.git#egg=glitch_me" + ) + reply = await e.get_reply_message() + if not reply or not reply.media: + return await e.eor(get_string("cvt_3")) + xx = await e.eor(get_string("glitch_1")) + wut = mediainfo(reply.media) + if wut.startswith(("pic", "sticker")): + ok = await reply.download_media() + elif reply.document and reply.document.thumbs: + ok = await reply.download_media(thumb=-1) + else: + return await xx.eor(get_string("com_4")) + cmd = f"glitch_me gif --line_count 200 -f 10 -d 50 '{ok}' ult.gif" + await bash(cmd) + await e.reply(file="ult.gif", force_document=False) + await xx.delete() + os.remove(ok) + os.remove("ult.gif") diff --git a/addons/globaltools.py b/addons/globaltools.py new file mode 100644 index 0000000..ff2231b --- /dev/null +++ b/addons/globaltools.py @@ -0,0 +1,789 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available - + +โ€ข `{i}gban ` +โ€ข `{i}ungban` + Ban/Unban Globally. + +โ€ข `{i}gstat ` + Check if user is GBanned. + +โ€ข `{i}listgban` : List all GBanned users. + +โ€ข `{i}gmute` | `{i}ungmute` + Mute/UnMute Globally. + +โ€ข `{i}gkick ` `Globally Kick User` +โ€ข `{i}gcast ` `Globally Send msg in all grps` + +โ€ข `{i}gadmincast ` `Globally broadcast in your admin chats` +โ€ข `{i}gucast ` `Globally send msg in all pm users` + +โ€ข `{i}gblacklist ` + globally promote user where you are admin + - Set whether To promote only in groups/channels/all. + Eg- `gpromote group boss` ~ promotes user in all grps. + `gpromote @username all sar` ~ promote the user in all group & channel +โ€ข `{i}gdemote` - `demote user globally` +""" +import asyncio +import os + +from telethon.errors.rpcerrorlist import ChatAdminRequiredError, FloodWaitError +from telethon.tl.functions.channels import EditAdminRequest +from telethon.tl.functions.contacts import BlockRequest, UnblockRequest +from telethon.tl.types import ChatAdminRights, User + +from pyUltroid.dB import DEVLIST +from pyUltroid.dB.base import KeyManager +from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button + +from . import ( + HNDLR, + LOGS, + NOSPAM_CHAT, + OWNER_NAME, + eod, + eor, + get_string, + inline_mention, + udB, + ultroid_bot, + ultroid_cmd, +) +from ._inline import something + +def list_gbanned(): + return udB.get_key("GBAN") or {} + + +def gban(user, reason): + ok = list_gbanned() + ok.update({int(user): reason or "No Reason. "}) + return udB.set_key("GBAN", ok) + + +def ungban(user): + ok = list_gbanned() + if ok.get(int(user)): + del ok[int(user)] + return udB.set_key("GBAN", ok) + + +def is_gbanned(user): + ok = list_gbanned() + if ok.get(int(user)): + return ok[int(user)] + + +def gmute(user): + ok = list_gmuted() + ok.append(int(user)) + return udB.set_key("GMUTE", ok) + + +def ungmute(user): + ok = list_gmuted() + if user in ok: + ok.remove(int(user)) + return udB.set_key("GMUTE", ok) + + +def is_gmuted(user): + return int(user) in list_gmuted() + + +def list_gmuted(): + return udB.get_key("GMUTE") or [] + + +_gpromote_rights = ChatAdminRights( + add_admins=False, + invite_users=True, + change_info=False, + ban_users=True, + delete_messages=True, + pin_messages=True, +) + +_gdemote_rights = ChatAdminRights( + add_admins=False, + invite_users=False, + change_info=False, + ban_users=False, + delete_messages=False, + pin_messages=False, +) + +keym = KeyManager("GBLACKLISTS", cast=list) + + +@ultroid_cmd(pattern="gpromote( (.*)|$)", fullsudo=True) +async def _(e): + x = e.pattern_match.group(1).strip() + ultroid_bot = e.client + if not x: + return await e.eor(get_string("schdl_2"), time=5) + user = await e.get_reply_message() + if user: + ev = await e.eor("`Promoting Replied User Globally`") + ok = e.text.split() + key = "all" + if len(ok) > 1 and (("group" in ok[1]) or ("channel" in ok[1])): + key = ok[1] + rank = ok[2] if len(ok) > 2 else "AdMin" + c = 0 + user.id = user.peer_id.user_id if e.is_private else user.from_id.user_id + async for x in e.client.iter_dialogs(): + if ( + "group" in key.lower() + and x.is_group + or "group" not in key.lower() + and "channel" in key.lower() + and x.is_channel + ): + try: + await e.client( + EditAdminRequest( + x.id, + user.id, + _gpromote_rights, + rank, + ), + ) + c += 1 + except BaseException: + pass + elif ( + ("group" not in key.lower() or x.is_group) + and ( + "group" in key.lower() + or "channel" not in key.lower() + or x.is_channel + ) + and ( + "group" in key.lower() + or "channel" in key.lower() + or x.is_group + or x.is_channel + ) + ): + try: + await e.client( + EditAdminRequest( + x.id, + user.id, + _gpromote_rights, + rank, + ), + ) + c += 1 + except Exception as er: + LOGS.info(er) + await eor(ev, f"Promoted The Replied Users in Total : {c} {key} chats") + else: + k = e.text.split() + if not k[1]: + return await eor( + e, "`Give someone's username/id or replied to user.", time=5 + ) + user = k[1] + if user.isdigit(): + user = int(user) + try: + name = await e.client.get_entity(user) + except BaseException: + return await e.eor(f"`No User Found Regarding {user}`", time=5) + ev = await e.eor(f"`Promoting {name.first_name} globally.`") + key = "all" + if len(k) > 2 and (("group" in k[2]) or ("channel" in k[2])): + key = k[2] + rank = k[3] if len(k) > 3 else "AdMin" + c = 0 + async for x in e.client.iter_dialogs(): + if ( + "group" in key.lower() + and x.is_group + or "group" not in key.lower() + and "channel" in key.lower() + and x.is_channel + or "group" not in key.lower() + and "channel" not in key.lower() + and (x.is_group or x.is_channel) + ): + try: + await ultroid_bot( + EditAdminRequest( + x.id, + user, + _gpromote_rights, + rank, + ), + ) + c += 1 + except BaseException: + pass + await eor(ev, f"Promoted {name.first_name} in Total : {c} {key} chats.") + + +@ultroid_cmd(pattern="gdemote( (.*)|$)", fullsudo=True) +async def _(e): + x = e.pattern_match.group(1).strip() + ultroid_bot = e.client + if not x: + return await e.eor(get_string("schdl_2"), time=5) + user = await e.get_reply_message() + if user: + user.id = user.peer_id.user_id if e.is_private else user.from_id.user_id + ev = await e.eor("`Demoting Replied User Globally`") + ok = e.text.split() + key = "all" + if len(ok) > 1 and (("group" in ok[1]) or ("channel" in ok[1])): + key = ok[1] + rank = "Not AdMin" + c = 0 + async for x in e.client.iter_dialogs(): + if ( + "group" in key.lower() + and x.is_group + or "group" not in key.lower() + and "channel" in key.lower() + and x.is_channel + or "group" not in key.lower() + and "channel" not in key.lower() + and (x.is_group or x.is_channel) + ): + try: + await ultroid_bot( + EditAdminRequest( + x.id, + user.id, + _gdemote_rights, + rank, + ), + ) + c += 1 + except BaseException: + pass + await eor(ev, f"Demoted The Replied Users in Total : {c} {key} chats") + else: + k = e.text.split() + if not k[1]: + return await eor( + e, "`Give someone's username/id or replied to user.", time=5 + ) + user = k[1] + if user.isdigit(): + user = int(user) + try: + name = await ultroid_bot.get_entity(user) + except BaseException: + return await e.eor(f"`No User Found Regarding {user}`", time=5) + ev = await e.eor(f"`Demoting {name.first_name} globally.`") + key = "all" + if len(k) > 2 and (("group" in k[2]) or ("channel" in k[2])): + key = k[2] + rank = "Not AdMin" + c = 0 + async for x in ultroid_bot.iter_dialogs(): + if ( + "group" in key.lower() + and x.is_group + or "group" not in key.lower() + and "channel" in key.lower() + and x.is_channel + or "group" not in key.lower() + and "channel" not in key.lower() + and (x.is_group or x.is_channel) + ): + try: + await ultroid_bot( + EditAdminRequest( + x.id, + user, + _gdemote_rights, + rank, + ), + ) + c += 1 + except BaseException: + pass + await eor(ev, f"Demoted {name.first_name} in Total : {c} {key} chats.") + + +@ultroid_cmd(pattern="ungban( (.*)|$)", fullsudo=True) +async def _(e): + xx = await e.eor("`UnGbanning...`") + match = e.pattern_match.group(1).strip() + peer = None + if e.reply_to_msg_id: + userid = (await e.get_reply_message()).sender_id + elif match: + try: + userid = int(match) + except ValueError: + userid = match + try: + userid = (await e.client.get_entity(userid)).id + except Exception as er: + return await xx.edit(f"Failed to get User...\nError: {er}") + elif e.is_private: + userid = e.chat_id + else: + return await xx.eor("`Reply to some msg or add their id.`", time=5) + if not is_gbanned(userid): + return await xx.edit("`User/Channel is not Gbanned...`") + try: + if not peer: + peer = await e.client.get_entity(userid) + name = inline_mention(peer) + except BaseException: + userid = int(userid) + name = str(userid) + chats = 0 + if e.client._dialogs: + dialog = e.client._dialogs + else: + dialog = await e.client.get_dialogs() + e.client._dialogs.extend(dialog) + for ggban in dialog: + if ggban.is_group or ggban.is_channel: + try: + await e.client.edit_permissions(ggban.id, userid, view_messages=True) + chats += 1 + except FloodWaitError as fw: + LOGS.info( + f"[FLOOD_WAIT_ERROR] : on Ungban\nSleeping for {fw.seconds+10}" + ) + await asyncio.sleep(fw.seconds + 10) + try: + await e.client.edit_permissions( + ggban.id, userid, view_messages=True + ) + chats += 1 + except BaseException as er: + LOGS.exception(er) + except (ChatAdminRequiredError, ValueError): + pass + except BaseException as er: + LOGS.exception(er) + ungban(userid) + if isinstance(peer, User): + await e.client(UnblockRequest(userid)) + await xx.edit( + f"`Ungbaned` {name} in {chats} `chats.\nRemoved from gbanwatch.`", + ) + + +@ultroid_cmd(pattern="gban( (.*)|$)", fullsudo=True) +async def _(e): + xx = await e.eor("`Gbanning...`") + reason = "" + if e.reply_to_msg_id: + userid = (await e.get_reply_message()).sender_id + try: + reason = e.text.split(" ", maxsplit=1)[1] + except IndexError: + pass + elif e.pattern_match.group(1).strip(): + usr = e.text.split(maxsplit=2)[1] + try: + userid = await e.client.parse_id(usr) + except ValueError: + userid = usr + try: + reason = e.text.split(maxsplit=2)[2] + except IndexError: + pass + elif e.is_private: + userid = e.chat_id + try: + reason = e.text.split(" ", maxsplit=1)[1] + except IndexError: + pass + else: + return await xx.eor("`Reply to some msg or add their id.`", time=5) + user = None + try: + user = await e.client.get_entity(userid) + name = inline_mention(user) + except BaseException: + userid = int(userid) + name = str(userid) + chats = 0 + if userid == ultroid_bot.uid: + return await xx.eor("`I can't gban myself.`", time=3) + elif userid in DEVLIST: + return await xx.eor("`I can't gban my Developers.`", time=3) + elif is_gbanned(userid): + return await eod( + xx, + "`User is already gbanned and added to gbanwatch.`", + time=4, + ) + if e.client._dialogs: + dialog = e.client._dialogs + else: + dialog = await e.client.get_dialogs() + e.client._dialogs.extend(dialog) + for ggban in dialog: + if ggban.is_group or ggban.is_channel: + try: + await e.client.edit_permissions(ggban.id, userid, view_messages=False) + chats += 1 + except FloodWaitError as fw: + LOGS.info( + f"[FLOOD_WAIT_ERROR] : on GBAN Command\nSleeping for {fw.seconds+10}" + ) + await asyncio.sleep(fw.seconds + 10) + try: + await e.client.edit_permissions( + ggban.id, userid, view_messages=False + ) + chats += 1 + except BaseException as er: + LOGS.exception(er) + except (ChatAdminRequiredError, ValueError): + pass + except BaseException as er: + LOGS.exception(er) + gban(userid, reason) + if isinstance(user, User): + await e.client(BlockRequest(userid)) + gb_msg = f"**#Gbanned** {name} `in {chats} chats and added to gbanwatch!`" + if reason: + gb_msg += f"\n**Reason** : {reason}" + await xx.edit(gb_msg) + + +@ultroid_cmd(pattern="g(admin|)cast( (.*)|$)", fullsudo=True) +async def gcast(event): + text, btn, reply = "", None, None + if xx := event.pattern_match.group(2): + msg, btn = get_msg_button(event.text.split(maxsplit=1)[1]) + elif event.is_reply: + reply = await event.get_reply_message() + msg = reply.text + if reply.buttons: + btn = format_btn(reply.buttons) + else: + msg, btn = get_msg_button(msg) + else: + return await eor( + event, "`Give some text to Globally Broadcast or reply a message..`" + ) + + kk = await event.eor("`Globally Broadcasting Msg...`") + er = 0 + done = 0 + err = "" + if event.client._dialogs: + dialog = event.client._dialogs + else: + dialog = await event.client.get_dialogs() + event.client._dialogs.extend(dialog) + for x in dialog: + if x.is_group: + chat = x.entity.id + if ( + not keym.contains(chat) + and int(f"-100{str(chat)}") not in NOSPAM_CHAT + and ( + ( + event.text[2:7] != "admin" + or (x.entity.admin_rights or x.entity.creator) + ) + ) + ): + try: + if btn: + bt = create_tl_btn(btn) + await something( + event, + msg, + reply.media if reply else None, + bt, + chat=chat, + reply=False, + ) + else: + await event.client.send_message( + chat, msg, file=reply.media if reply else None + ) + done += 1 + except FloodWaitError as fw: + await asyncio.sleep(fw.seconds + 10) + try: + if btn: + bt = create_tl_btn(btn) + await something( + event, + msg, + reply.media if reply else None, + bt, + chat=chat, + reply=False, + ) + else: + await event.client.send_message( + chat, msg, file=reply.media if reply else None + ) + done += 1 + except Exception as rr: + err += f"โ€ข {rr}\n" + er += 1 + except BaseException as h: + err += f"โ€ข {str(h)}" + "\n" + er += 1 + text += f"Done in {done} chats, error in {er} chat(s)" + if err != "": + open("gcast-error.log", "w+").write(err) + text += f"\nYou can do `{HNDLR}ul gcast-error.log` to know error report." + await kk.edit(text) + + +@ultroid_cmd(pattern="gucast( (.*)|$)", fullsudo=True) +async def gucast(event): + msg, btn, reply = "", None, None + if xx := event.pattern_match.group(1).strip(): + msg, btn = get_msg_button(event.text.split(maxsplit=1)[1]) + elif event.is_reply: + reply = await event.get_reply_message() + msg = reply.text + if reply.buttons: + btn = format_btn(reply.buttons) + else: + msg, btn = get_msg_button(msg) + else: + return await eor( + event, "`Give some text to Globally Broadcast or reply a message..`" + ) + kk = await event.eor("`Globally Broadcasting Msg...`") + er = 0 + done = 0 + if event.client._dialogs: + dialog = event.client._dialogs + else: + dialog = await event.client.get_dialogs() + event.client._dialogs.extend(dialog) + for x in dialog: + if x.is_user and not x.entity.bot: + chat = x.id + if not keym.contains(chat): + try: + if btn: + bt = create_tl_btn(btn) + await something( + event, + msg, + reply.media if reply else None, + bt, + chat=chat, + reply=False, + ) + else: + await event.client.send_message( + chat, msg, file=reply.media if reply else None + ) + done += 1 + except BaseException: + er += 1 + await kk.edit(f"Done in {done} chats, error in {er} chat(s)") + + +@ultroid_cmd(pattern="gkick( (.*)|$)", fullsudo=True) +async def gkick(e): + xx = await e.eor("`Gkicking...`") + if e.reply_to_msg_id: + userid = (await e.get_reply_message()).sender_id + elif e.pattern_match.group(1).strip(): + userid = await e.client.parse_id(e.pattern_match.group(1).strip()) + elif e.is_private: + userid = e.chat_id + else: + return await xx.edit("`Reply to some msg or add their id.`", time=5) + name = (await e.client.get_entity(userid)).first_name + chats = 0 + if userid == ultroid_bot.uid: + return await xx.eor("`I can't gkick myself.`", time=3) + if userid in DEVLIST: + return await xx.eor("`I can't gkick my Developers.`", time=3) + if e.client._dialogs: + dialog = e.client._dialogs + else: + dialog = await e.client.get_dialogs() + e.client._dialogs.extend(dialog) + for gkick in dialog: + if gkick.is_group or gkick.is_channel: + try: + await e.client.kick_participant(gkick.id, userid) + chats += 1 + except BaseException: + pass + await xx.edit(f"`Gkicked` [{name}](tg://user?id={userid}) `in {chats} chats.`") + + +@ultroid_cmd(pattern="gmute( (.*)|$)", fullsudo=True) +async def _(e): + xx = await e.eor("`Gmuting...`") + if e.reply_to_msg_id: + userid = (await e.get_reply_message()).sender_id + elif e.pattern_match.group(1).strip(): + userid = await e.client.parse_id(e.pattern_match.group(1).strip()) + elif e.is_private: + userid = e.chat_id + else: + return await xx.eor("`Reply to some msg or add their id.`", tome=5, time=5) + name = await e.client.get_entity(userid) + chats = 0 + if userid == ultroid_bot.uid: + return await xx.eor("`I can't gmute myself.`", time=3) + if userid in DEVLIST: + return await xx.eor("`I can't gmute my Developers.`", time=3) + if is_gmuted(userid): + return await xx.eor("`User is already gmuted.`", time=4) + if e.client._dialogs: + dialog = e.client._dialogs + else: + dialog = await e.client.get_dialogs() + e.client._dialogs.extend(dialog) + for onmute in dialog: + if onmute.is_group: + try: + await e.client.edit_permissions(onmute.id, userid, send_messages=False) + chats += 1 + except BaseException: + pass + gmute(userid) + await xx.edit(f"`Gmuted` {inline_mention(name)} `in {chats} chats.`") + + +@ultroid_cmd(pattern="ungmute( (.*)|$)", fullsudo=True) +async def _(e): + xx = await e.eor("`UnGmuting...`") + if e.reply_to_msg_id: + userid = (await e.get_reply_message()).sender_id + elif e.pattern_match.group(1).strip(): + userid = await e.client.parse_id(e.pattern_match.group(1).strip()) + elif e.is_private: + userid = e.chat_id + else: + return await xx.eor("`Reply to some msg or add their id.`", time=5) + name = (await e.client.get_entity(userid)).first_name + chats = 0 + if not is_gmuted(userid): + return await xx.eor("`User is not gmuted.`", time=3) + if e.client._dialogs: + dialog = e.client._dialogs + else: + dialog = await e.client.get_dialogs() + e.client._dialogs.extend(dialog) + for hurr in dialog: + if hurr.is_group: + try: + await e.client.edit_permissions(hurr.id, userid, send_messages=True) + chats += 1 + except BaseException: + pass + ungmute(userid) + await xx.edit(f"`Ungmuted` {inline_mention(name)} `in {chats} chats.`") + + +@ultroid_cmd( + pattern="listgban$", +) +async def list_gengbanned(event): + users = list_gbanned() + x = await event.eor(get_string("com_1")) + msg = "" + if not users: + return await x.edit("`You haven't GBanned anyone!`") + for i in users: + try: + name = await event.client.get_entity(int(i)) + except BaseException: + name = i + msg += f"User: {inline_mention(name, html=True)}\n" + reason = users[i] + msg += f"Reason: {reason}\n\n" if reason is not None else "\n" + gbanned_users = f"List of users GBanned by {OWNER_NAME}:\n\n{msg}" + if len(gbanned_users) > 4096: + with open("gbanned.txt", "w") as f: + f.write( + gbanned_users.replace("", "") + .replace("", "") + .replace("
", "") + ) + await x.reply( + file="gbanned.txt", + message=f"List of users GBanned by {inline_mention(ultroid_bot.me)}", + ) + os.remove("gbanned.txt") + await x.delete() + else: + await x.edit(gbanned_users, parse_mode="html") + + +@ultroid_cmd( + pattern="gstat( (.*)|$)", +) +async def gstat_(e): + xx = await e.eor(get_string("com_1")) + if e.is_private: + userid = (await e.get_chat()).id + elif e.reply_to_msg_id: + userid = (await e.get_reply_message()).sender_id + elif e.pattern_match.group(1).strip(): + try: + userid = await e.client.parse_id(e.pattern_match.group(1).strip()) + except Exception as err: + return await xx.eor(f"{err}", time=10) + else: + return await xx.eor("`Reply to some msg or add their id.`", time=5) + name = (await e.client.get_entity(userid)).first_name + msg = f"**{name} is " + is_banned = is_gbanned(userid) + reason = list_gbanned().get(userid) + if is_banned: + msg += "Globally Banned" + msg += f" with reason** `{reason}`" if reason else ".**" + else: + msg += "not Globally Banned.**" + await xx.edit(msg) + + +@ultroid_cmd(pattern="gblacklist$") +async def blacklist_(event): + await gblacker(event, "add") + + +@ultroid_cmd(pattern="ungblacklist$") +async def ungblacker(event): + await gblacker(event, "remove") + + +async def gblacker(event, type_): + try: + chat_id = int(event.text.split(maxsplit=1)[1]) + try: + chat_id = (await event.client.get_entity(chat_id)).id + except Exception as e: + return await event.eor(f"**ERROR**\n`{str(e)}`") + except IndexError: + chat_id = event.chat_id + if type_ == "add": + keym.add(chat_id) + elif type_ == "remove": + keym.remove(chat_id) + await event.eor(f"Global Broadcasts: \n{type_}ed {chat_id}") diff --git a/addons/greetings.py b/addons/greetings.py new file mode 100644 index 0000000..b519f29 --- /dev/null +++ b/addons/greetings.py @@ -0,0 +1,354 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available - + +---- Welcomes ---- +โ€ข `{i}setwelcome ` + Set welcome message in the current chat. + +โ€ข `{i}clearwelcome` + Delete the welcome in the current chat. + +โ€ข `{i}getwelcome` + Get the welcome message in the current chat. + +---- GoodByes ---- +โ€ข `{i}setgoodbye ` + Set goodbye message in the current chat. + +โ€ข `{i}cleargoodbye` + Delete the goodbye in the current chat. + +โ€ข `{i}getgoodbye` + Get the goodbye message in the current chat. + +โ€ข `{i}thankmembers on/off` + Send a thank you sticker on hitting a members count of 100*x in your groups. +""" +import os +import asyncio + +from . import upload_file as uf +from telethon.utils import pack_bot_file_id, get_display_name + +from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button +from pyUltroid.dB import stickers +from pyUltroid.fns.helper import inline_mention + +from . import HNDLR, eor, get_string, mediainfo, udB, ultroid_cmd, events, ultroid_bot, something + +# Functions moved from greetings_db.py +def get_stuff(key=None): + return udB.get_key(key) or {} + + +def add_welcome(chat, msg, media, button): + ok = get_stuff("WELCOME") + ok.update({chat: {"welcome": msg, "media": media, "button": button}}) + return udB.set_key("WELCOME", ok) + + +def get_welcome(chat): + ok = get_stuff("WELCOME") + return ok.get(chat) + + +def delete_welcome(chat): + ok = get_stuff("WELCOME") + if ok.get(chat): + ok.pop(chat) + return udB.set_key("WELCOME", ok) + + +def add_goodbye(chat, msg, media, button): + ok = get_stuff("GOODBYE") + ok.update({chat: {"goodbye": msg, "media": media, "button": button}}) + return udB.set_key("GOODBYE", ok) + + +def get_goodbye(chat): + ok = get_stuff("GOODBYE") + return ok.get(chat) + + +def delete_goodbye(chat): + ok = get_stuff("GOODBYE") + if ok.get(chat): + ok.pop(chat) + return udB.set_key("GOODBYE", ok) + + +def add_thanks(chat): + x = get_stuff("THANK_MEMBERS") + x.update({chat: True}) + return udB.set_key("THANK_MEMBERS", x) + + +def remove_thanks(chat): + x = get_stuff("THANK_MEMBERS") + if x.get(chat): + x.pop(chat) + return udB.set_key("THANK_MEMBERS", x) + + +def must_thank(chat): + x = get_stuff("THANK_MEMBERS") + return x.get(chat) + + +Note = "\n\nNote: `{mention}`, `{group}`, `{count}`, `{name}`, `{fullname}`, `{username}`, `{userid}` can be used as formatting parameters.\n\n" + + +@ultroid_cmd(pattern="setwelcome", groups_only=True) +async def setwel(event): + x = await event.eor(get_string("com_1")) + r = await event.get_reply_message() + btn = format_btn(r.buttons) if (r and r.buttons) else None + try: + text = event.text.split(maxsplit=1)[1] + except IndexError: + text = r.text if r else None + if r and r.media: + wut = mediainfo(r.media) + if wut.startswith(("pic", "gif")): + dl = await r.download_media() + m = uf(dl) + os.remove(dl) + elif wut == "video": + if r.media.document.size > 8 * 1000 * 1000: + return await eor(x, get_string("com_4"), time=5) + dl = await r.download_media() + m = uf(dl) + os.remove(dl) + elif wut == "web": + m = None + else: + m = pack_bot_file_id(r.media) + if r.text: + txt = r.text + if not btn: + txt, btn = get_msg_button(r.text) + add_welcome(event.chat_id, txt, m, btn) + else: + add_welcome(event.chat_id, None, m, btn) + await eor(x, get_string("grt_1")) + elif text: + if not btn: + txt, btn = get_msg_button(text) + add_welcome(event.chat_id, txt, None, btn) + await eor(x, get_string("grt_1")) + else: + await eor(x, get_string("grt_3"), time=5) + + +@ultroid_cmd(pattern="clearwelcome$", groups_only=True) +async def clearwel(event): + if not get_welcome(event.chat_id): + return await event.eor(get_string("grt_4"), time=5) + delete_welcome(event.chat_id) + await event.eor(get_string("grt_5"), time=5) + + +@ultroid_cmd(pattern="getwelcome$", groups_only=True) +async def listwel(event): + wel = get_welcome(event.chat_id) + if not wel: + return await event.eor(get_string("grt_4"), time=5) + msgg, med = wel["welcome"], wel["media"] + if wel.get("button"): + btn = create_tl_btn(wel["button"]) + return await something(event, msgg, med, btn) + await event.reply(f"**Welcome Note in this chat**\n\n`{msgg}`", file=med) + await event.delete() + + +@ultroid_cmd(pattern="setgoodbye", groups_only=True) +async def setgb(event): + x = await event.eor(get_string("com_1")) + r = await event.get_reply_message() + btn = format_btn(r.buttons) if (r and r.buttons) else None + try: + text = event.text.split(maxsplit=1)[1] + except IndexError: + text = r.text if r else None + if r and r.media: + wut = mediainfo(r.media) + if wut.startswith(("pic", "gif")): + dl = await r.download_media() + m = uf(dl) + os.remove(dl) + elif wut == "video": + if r.media.document.size > 8 * 1000 * 1000: + return await eor(x, get_string("com_4"), time=5) + dl = await r.download_media() + m = uf(dl) + os.remove(dl) + elif wut == "web": + m = None + else: + m = pack_bot_file_id(r.media) + if r.text: + txt = r.text + if not btn: + txt, btn = get_msg_button(r.text) + add_goodbye(event.chat_id, txt, m, btn) + else: + add_goodbye(event.chat_id, None, m, btn) + await eor(x, "`Goodbye note saved`") + elif text: + if not btn: + txt, btn = get_msg_button(text) + add_goodbye(event.chat_id, txt, None, btn) + await eor(x, "`Goodbye note saved`") + else: + await eor(x, get_string("grt_7"), time=5) + + +@ultroid_cmd(pattern="cleargoodbye$", groups_only=True) +async def clearwgb(event): + if not get_goodbye(event.chat_id): + return await event.eor(get_string("grt_6"), time=5) + delete_goodbye(event.chat_id) + await event.eor("`Goodbye Note Deleted`", time=5) + + +@ultroid_cmd(pattern="getgoodbye$", groups_only=True) +async def listgd(event): + wel = get_goodbye(event.chat_id) + if not wel: + return await event.eor(get_string("grt_6"), time=5) + msgg = wel["goodbye"] + med = wel["media"] + if wel.get("button"): + btn = create_tl_btn(wel["button"]) + return await something(event, msgg, med, btn) + await event.reply(f"**Goodbye Note in this chat**\n\n`{msgg}`", file=med) + await event.delete() + + +@ultroid_cmd(pattern="thankmembers (on|off)", groups_only=True) +async def thank_set(event): + type_ = event.pattern_match.group(1).strip() + if not type_ or type_ == "": + await eor( + event, + f"**Current Chat Settings:**\n**Thanking Members:** `{must_thank(event.chat_id)}`\n\nUse `{HNDLR}thankmembers on` or `{HNDLR}thankmembers off` to toggle current settings!", + ) + return + chat = event.chat_id + if type_.lower() == "on": + add_thanks(chat) + elif type_.lower() == "off": + remove_thanks(chat) + await eor( + event, + f"**Done! Thank you members has been turned** `{type_.lower()}` **for this chat**!", + ) + +# Add handlers for welcome and goodbye messages +async def welcome_handler(ult): + if not (ult.user_joined or ult.user_added): + return + if get_welcome(ult.chat_id): + user = await ult.get_user() + chat = await ult.get_chat() + title = chat.title or "this chat" + count = ( + chat.participants_count + or (await ult.client.get_participants(chat, limit=0)).total + ) + mention = inline_mention(user) + name = user.first_name + fullname = get_display_name(user) + uu = user.username + username = f"@{uu}" if uu else mention + userid = user.id + wel = get_welcome(ult.chat_id) + msgg = wel["welcome"] + med = wel["media"] or None + msg = None + if msgg: + msg = msgg.format( + mention=mention, + group=title, + count=count, + name=name, + fullname=fullname, + username=username, + userid=userid, + ) + if wel.get("button"): + btn = create_tl_btn(wel["button"]) + await something(ult, msg, med, btn) + elif msg: + send = await ult.reply( + msg, + file=med, + ) + await asyncio.sleep(150) + await send.delete() + else: + await ult.reply(file=med) + +async def goodbye_handler(ult): + if not (ult.user_left or ult.user_kicked): + return + if get_goodbye(ult.chat_id): + user = await ult.get_user() + chat = await ult.get_chat() + title = chat.title or "this chat" + count = ( + chat.participants_count + or (await ult.client.get_participants(chat, limit=0)).total + ) + mention = inline_mention(user) + name = user.first_name + fullname = get_display_name(user) + uu = user.username + username = f"@{uu}" if uu else mention + userid = user.id + wel = get_goodbye(ult.chat_id) + msgg = wel["goodbye"] + med = wel["media"] + msg = None + if msgg: + msg = msgg.format( + mention=mention, + group=title, + count=count, + name=name, + fullname=fullname, + username=username, + userid=userid, + ) + if wel.get("button"): + btn = create_tl_btn(wel["button"]) + await something(ult, msg, med, btn) + elif msg: + send = await ult.reply( + msg, + file=med, + ) + await asyncio.sleep(150) + await send.delete() + else: + await ult.reply(file=med) + +# Thank members handler +async def thank_members_handler(ult): + if must_thank(ult.chat_id): + chat_count = (await ult.client.get_participants(ult.chat_id, limit=0)).total + if chat_count % 100 == 0: + stik_id = chat_count / 100 - 1 + sticker = stickers[stik_id] + await ult.respond(file=sticker) + +# Register handlers +ultroid_bot.add_handler(welcome_handler, events.ChatAction()) +ultroid_bot.add_handler(goodbye_handler, events.ChatAction()) +ultroid_bot.add_handler(thank_members_handler, events.ChatAction()) diff --git a/addons/hack.py b/addons/hack.py new file mode 100644 index 0000000..1b0a553 --- /dev/null +++ b/addons/hack.py @@ -0,0 +1,134 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available + +โ€ข `{i}hack` + Do a Prank With Replied user. + +""" + +import asyncio +import random + +from . import * + + +@ultroid_cmd(pattern="hack") +async def _(event): + animation_interval = 0.7 + animation_ttl = range(0, 11) + xx = await event.eor("Installing..") + animation_chars = [ + "`Installing Files To Hacked Private Server...`", + "`Target Selected.`", + "`Installing... 0%\nโ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’ `", + "`Installing... 4%\nโ–ˆโ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’ `", + "`Installing... 8%\nโ–ˆโ–ˆโ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’ `", + "`lnstallig... 20%\nโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’ `", + "`Installing... 36%\nโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’ `", + "`Installing... 52%\nโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’โ–’ `", + "`Installing... 84%\nโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–’โ–’โ–’โ–’ `", + "`Installing... 100%\nโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆInstalledโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ `", + "`Target files Uploading...\n\nDirecting To Remote server to hack..`", + ] + for i in animation_ttl: + await asyncio.sleep(animation_interval) + await xx.edit(animation_chars[i % 11]) + await asyncio.sleep(2) + animation_interval = 0.6 + animation_ttl = range(0, 14) + await xx.edit("`Connecting nd getting combined token from my.telegram.org`") + await asyncio.sleep(1) + animation_chars = [ + "`root@anon:~#` ", + "`root@anon:~# ls`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~#`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...\nroot@anon:~# `", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...\nroot@anon:~# touch setup.py`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...\nroot@anon:~# touch setup.py\n\nsetup.py deployed ...`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...\nroot@anon:~# touch setup.py\n\nsetup.py deployed ...\nAuto CMD deployed ...`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...\nroot@anon:~# touch setup.py\n\nsetup.py deployed ...\nAuto CMD deployed ...\n\nroot@anon:~# trap whoami`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...\nroot@anon:~# touch setup.py\n\nsetup.py deployed ...\nAuto CMD deployed ...\n\nroot@anon:~# trap whoami\n\nwhoami=user`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...\nroot@anon:~# touch setup.py\n\nsetup.py deployed ...\nAuto CMD deployed ...\n\nroot@anon:~# trap whoami\n\nwhoami=user\nboost_trap on force ...`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...\nroot@anon:~# touch setup.py\n\nsetup.py deployed ...\nAuto CMD deployed ...\n\nroot@anon:~# trap whoami\n\nwhoami=user\nboost_trap on force ...\nvictim detected in ghost ...`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...\nroot@anon:~# touch setup.py\n\nsetup.py deployed ...\nAuto CMD deployed ...\n\nroot@anon:~# trap whoami\n\nwhoami=user\nboost_trap on force ...\nvictim detected in ghost ...\n\nAll Done!`", + "`root@anon:~# ls\n\n usr ghost codes \n\nroot@aono:~# # So Let's Hack it ...\nroot@anon:~# touch setup.py\n\nsetup.py deployed ...\nAuto CMD deployed ...\n\nroot@anon:~# trap whoami\n\nwhoami=user\nboost_trap on force ...\nvictim detected in ghost ...\n\nAll Done!\nInstalling Token!\nToken=`DJ65gulO90P90nlkm65dRfc8I`", + ] + for i in animation_ttl: + await asyncio.sleep(animation_interval) + await xx.edit(animation_chars[i % 14]) + await asyncio.sleep(2) + await xx.edit("`starting telegram hack`") + await asyncio.sleep(1) + # credit to kraken,sawan + await xx.edit( + "`hacking... 0%completed.\nTERMINAL:\nDownloading Bruteforce-Telegram-0.1.tar.gz (1.3) kB`" + ) + await asyncio.sleep(2) + await xx.edit( + " `hacking... 4% completed\n TERMINAL:\nDownloading Bruteforce-Telegram-0.1.tar.gz (9.3 kB)\nCollecting Data Package`" + ) + await asyncio.sleep(1) + await xx.edit( + "`hacking.....6% completed\n TERMINAL:\nDownloading Bruteforce-Telegram-0.1.tar.gz (9.3 kB)\nCollecting Data Packageseeing target account chat\n lding chat tg-bot bruteforce finished`" + ) + await asyncio.sleep(1) + await xx.edit( + "`hacking.....8%completed\n TERMINAL:\nDownloading Bruteforce-Telegram-0.1.tar.gz (9.3 kB)\nCollecting Data Packageseeing target account chat\n lding chat tg-bot bruteforce finished\n creating pdf of chat`" + ) + await asyncio.sleep(1) + await xx.edit( + "`hacking....15%completed\n Terminal:chat history from telegram exporting to private database.\n terminal 874379gvrfghhuu5tlotruhi5rbh installing`" + ) + await asyncio.sleep(1) + await xx.edit( + "`hacking....24%completed\n TERMINAL:\nDownloading Bruteforce-Telegram-0.1.tar.gz (9.3 kB)\nCollecting Data Packageseeing target account chat\n lding chat tg-bot bruteforce finished\nerminal:chat history from telegram exporting to private database.\n terminal 874379gvrfghhuu5tlotruhi5rbh installed\n creting data into pdf`" + ) + await asyncio.sleep(1) + await xx.edit( + "`hacking....32%completed\n looking for use history \n downloading-telegram -id prtggtgf . gfr (12.99 mb)\n collecting data starting imprute attack to user account\n chat history from telegram exporting to private database.\n terminal 874379gvrfghhuu5tlotruhi5rbh installed\n creted data into pdf\nDownload sucessful Bruteforce-Telegram-0.1.tar.gz (1.3)`" + ) + await asyncio.sleep(1) + await xx.edit( + "`hacking....38%completed\n\nDownloading Bruteforce-Telegram-0.1.tar.gz (9.3 kB)\nCollecting Data Package\n Downloading Telegram-Data-Sniffer-7.1.1-py2.py3-none-any.whl (82 kB): finished with status 'done'\nCreated wheel for telegram: filename=Telegram-Data-Sniffer-0.0.1-py3-none-any.whl size=1306 sha256=cb224caad7fe01a6649188c62303cd4697c1869fa12d280570bb6ac6a88e6b7e`" + ) + await asyncio.sleep(1) + await xx.edit( + "`hacking....52%completed\nexterting data from telegram private server\ndone with status 36748hdeg \n checking for more data in device`" + ) + await asyncio.sleep(2) + await xx.edit( + "`hacking....60%completed\nmore data found im target device\npreparing to download data\n process started with status 7y75hsgdt365ege56es \n status changed to up`" + ) + await asyncio.sleep(1) + await xx.edit( + "`hacking....73% completed\n downloading data from device\n process completed with status 884hfhjh\nDownloading-0.1.tar.gz (9.3 kB)\nCollecting Data Packageseeing target\n lding chat tg-bot bruteforce finished\n creating pdf of chat`" + ) + await asyncio.sleep(1) + await xx.edit( + "`hacking...88%completed\nall data from telegram private server downloaded\nterminal download sucessfull--with status jh3233fdg66y yr4vv.irh\n data collected from tg-bot\nTERMINAL:\n Bruteforce-Telegram-0.1.tar.gz (1.3)downloaded`" + ) + await asyncio.sleep(0.5) + await xx.edit( + "`100%\nโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆHACKEDโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ `\n\n\n TERMINAL:\nDownloading Bruteforce-Telegram-0.1.tar.gz (9.3 kB)\nCollecting Data Package\n Downloading Telegram-Data-Sniffer-7.1.1-py2.py3-none-any.whl (82 kB)\nBuilding wheel for Tg-Bruteforcing (setup.py): finished with status 'done'\nCreated wheel for telegram: filename=Telegram-Data-Sniffer-0.0.1-py3-none-any.whl size=1306 sha256=cb224caad7fe01a6649188c62303cd4697c1869fa12d280570bb6ac6a88e6b7e\n Stored in directory: `" + ) + await asyncio.sleep(2) + await xx.edit("`account hacked\n collecting all data\n converting data into pdf`") + await asyncio.sleep(1) + sub = "https://drive.google.com/file/d/" + LINKS = [ + "1JNA0HY1v8ClBDU9PhmyQ-z8KuLgvteT5/view?usp=sharing", + "1HXclQumyRIRy9STTiHcTAHpSMM2mj5ZF/view?usp=sharing", + ] + ME = sub + LINKS[random.randrange(0, len(LINKS))] + MSG = "`pdf created click link below to download data\n\n" + MSG += " Don't worry only i can open this ๐Ÿ˜Ž๐Ÿ˜Ž.. If u don't" + MSG += f" Believe me, try to download` ๐Ÿ™‚\n\n{ME}" + await xx.edit(MSG) diff --git a/addons/howto.py b/addons/howto.py new file mode 100644 index 0000000..8018438 --- /dev/null +++ b/addons/howto.py @@ -0,0 +1,38 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available - + +โ€ข `{i}htg ` + How To Google. + Some peoples don't know how to google so help them ๐Ÿ™ƒ๐Ÿ™‚. + +โ€ข `{i}htd ` + How to duck duck go... +""" + + +from . import ultroid_cmd, async_searcher + + +API = {"g": "lmgtfy.com/?q={}%26iie=1", "d": "lmddgtfy.net/?q={}"} + + +@ultroid_cmd(pattern="ht(g|d)( ?(.*)|$)") +async def _(e): + key = e.pattern_match.group(1) + text = e.pattern_match.group(2) + if not text: + return await e.eor("`Give some text`", time=5) + url = "https://da.gd/s?url=https://" + API[key].format(text.replace(" ", "+")) + response = await async_searcher(url) + if response: + return await e.eor( + "[{}]({})\n`Thank me Later ๐Ÿ™ƒ` ".format(text, response.rstrip()), time=8 + ) + await e.eor("`something is wrong. please try again later.`") diff --git a/addons/imagetools.py b/addons/imagetools.py new file mode 100644 index 0000000..22fd011 --- /dev/null +++ b/addons/imagetools.py @@ -0,0 +1,292 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available - + +โ€ข `{i}border ` + To create border around that media.. + Ex - `{i}border 12,22,23` + - `{i}border 12,22,23 ; width (in number)` + +โ€ข `{i}grey ` + To make it black nd white. + +โ€ข `{i}color ` + To make it Colorfull. + +โ€ข `{i}toon ` + To make it toon. + +โ€ข `{i}danger ` + To make it look Danger. + +โ€ข `{i}negative ` + To make negative image. + +โ€ข `{i}blur ` + To make it blurry. + +โ€ข `{i}quad ` + create a Vortex. + +โ€ข `{i}mirror ` + To create mirror pic. + +โ€ข `{i}flip ` + To make it flip. + +โ€ข `{i}sketch ` + To draw its sketch. + +โ€ข `{i}blue ` + just cool. + +โ€ข `{i}csample ` + example : `{i}csample red` + `{i}csample #ffffff` + +โ€ข `{i}pixelator ` + Create a Pixelated Image.. +""" +import os + +from . import LOGS, con + +try: + import cv2 +except ImportError: + LOGS.error(f"{__file__}: OpenCv not Installed.") + +import numpy as np + +try: + from PIL import Image +except ImportError: + Image = None + LOGS.info(f"{__file__}: PIL not Installed.") + +from . import upload_file as upf +from telethon.errors.rpcerrorlist import ( + ChatSendMediaForbiddenError, + MessageDeleteForbiddenError, +) + +from . import ( + Redis, + async_searcher, + download_file, + get_string, + requests, + udB, + ultroid_cmd, +) + + +@ultroid_cmd(pattern="color$") +async def _(event): + reply = await event.get_reply_message() + if not (reply and reply.media): + return await event.eor("`Reply To a Black and White Image`") + xx = await event.eor("`Coloring image ๐ŸŽจ๐Ÿ–Œ๏ธ...`") + image = await reply.download_media() + img = cv2.VideoCapture(image) + ret, frame = img.read() + cv2.imwrite("ult.jpg", frame) + if udB.get_key("DEEP_API"): + key = Redis("DEEP_API") + else: + key = "quickstart-QUdJIGlzIGNvbWluZy4uLi4K" + r = requests.post( + "https://api.deepai.org/api/colorizer", + files={"image": open("ult.jpg", "rb")}, + headers={"api-key": key}, + ) + os.remove("ult.jpg") + os.remove(image) + if "status" in r.json(): + return await event.edit( + r.json()["status"] + "\nGet api nd set `{i}setdb DEEP_API key`" + ) + r_json = r.json()["output_url"] + await event.client.send_file(event.chat_id, r_json, reply_to=reply) + await xx.delete() + + +@ultroid_cmd(pattern="(grey|blur|negative|danger|mirror|quad|sketch|flip|toon)$") +async def ult_tools(event): + match = event.pattern_match.group(1) + ureply = await event.get_reply_message() + if not (ureply and (ureply.media)): + await event.eor(get_string("cvt_3")) + return + ultt = await ureply.download_media() + xx = await event.eor(get_string("com_1")) + if ultt.endswith(".tgs"): + xx = await xx.edit(get_string("sts_9")) + file = await con.convert(ultt, convert_to="png", outname="ult") + ult = cv2.imread(file) + if match == "grey": + ultroid = cv2.cvtColor(ult, cv2.COLOR_BGR2GRAY) + elif match == "blur": + ultroid = cv2.GaussianBlur(ult, (35, 35), 0) + elif match == "negative": + ultroid = cv2.bitwise_not(ult) + elif match == "danger": + dan = cv2.cvtColor(ult, cv2.COLOR_BGR2RGB) + ultroid = cv2.cvtColor(dan, cv2.COLOR_HSV2BGR) + elif match == "mirror": + ish = cv2.flip(ult, 1) + ultroid = cv2.hconcat([ult, ish]) + elif match == "flip": + trn = cv2.flip(ult, 1) + ish = cv2.rotate(trn, cv2.ROTATE_180) + ultroid = cv2.vconcat([ult, ish]) + elif match == "quad": + ult = cv2.imread(file) + roid = cv2.flip(ult, 1) + mici = cv2.hconcat([ult, roid]) + fr = cv2.flip(mici, 1) + trn = cv2.rotate(fr, cv2.ROTATE_180) + ultroid = cv2.vconcat([mici, trn]) + elif match == "sketch": + gray_image = cv2.cvtColor(ult, cv2.COLOR_BGR2GRAY) + inverted_gray_image = 255 - gray_image + blurred_img = cv2.GaussianBlur(inverted_gray_image, (21, 21), 0) + inverted_blurred_img = 255 - blurred_img + ultroid = cv2.divide(gray_image, inverted_blurred_img, scale=256.0) + elif match == "toon": + height, width, _ = ult.shape + samples = np.zeros([height * width, 3], dtype=np.float32) + count = 0 + for x in range(height): + for y in range(width): + samples[count] = ult[x][y] + count += 1 + _, labels, centers = cv2.kmeans( + samples, + 12, + None, + (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10000, 0.0001), + 5, + cv2.KMEANS_PP_CENTERS, + ) + centers = np.uint8(centers) + ish = centers[labels.flatten()] + ultroid = ish.reshape(ult.shape) + cv2.imwrite("ult.jpg", ultroid) + await ureply.reply( + file="ult.jpg", + force_document=False, + ) + await xx.delete() + os.remove("ult.jpg") + os.remove(file) + + +@ultroid_cmd(pattern="csample (.*)") +async def sampl(ult): + if color := ult.pattern_match.group(1).strip(): + img = Image.new("RGB", (200, 100), f"{color}") + img.save("csample.png") + try: + try: + await ult.delete() + await ult.respond(f"Colour Sample for `{color}` !", file="csample.png") + except MessageDeleteForbiddenError: + await ult.reply(f"Colour Sample for `{color}` !", file="csample.png") + except ChatSendMediaForbiddenError: + await ult.eor("Umm! Sending Media is disabled here!") + + else: + await ult.eor("Wrong Color Name/Hex Code specified!") + + +@ultroid_cmd( + pattern="blue$", +) +async def ultd(event): + ureply = await event.get_reply_message() + xx = await event.eor("`...`") + if not (ureply and (ureply.media)): + await xx.edit(get_string("cvt_3")) + return + ultt = await ureply.download_media() + if ultt.endswith(".tgs"): + await xx.edit(get_string("sts_9")) + file = await con.convert(ultt, convert_to="png", outname="ult") + lnk = upf(file) + r = await async_searcher( + f"https://nekobot.xyz/api/imagegen?type=blurpify&image={lnk}", re_json=True + ) + ms = r.get("message") + if not r["success"]: + return await xx.edit(ms) + await download_file(ms, "ult.png") + img = Image.open("ult.png").convert("RGB") + img.save("ult.webp", "webp") + await event.client.send_file( + event.chat_id, + "ult.webp", + force_document=False, + reply_to=event.reply_to_msg_id, + ) + await xx.delete() + os.remove("ult.png") + os.remove("ult.webp") + os.remove(ultt) + + +@ultroid_cmd(pattern="border( (.*)|$)") +async def ok(event): + hm = await event.get_reply_message() + if not (hm and (hm.photo or hm.sticker)): + return await event.eor("`Reply to Sticker or Photo..`") + col = event.pattern_match.group(1).strip() + wh = 20 + if not col: + col = [255, 255, 255] + else: + try: + if ";" in col: + col_ = col.split(";", maxsplit=1) + wh = int(col_[1]) + col = col_[0] + col = [int(col) for col in col.split(",")[:2]] + except ValueError: + return await event.eor("`Not a Valid Input...`") + okla = await hm.download_media() + img1 = cv2.imread(okla) + constant = cv2.copyMakeBorder(img1, wh, wh, wh, wh, cv2.BORDER_CONSTANT, value=col) + cv2.imwrite("output.png", constant) + await event.client.send_file(event.chat.id, "output.png") + os.remove("output.png") + os.remove(okla) + await event.delete() + + +@ultroid_cmd(pattern="pixelator( (.*)|$)") +async def pixelator(event): + reply_message = await event.get_reply_message() + if not (reply_message and (reply_message.photo or reply_message.sticker)): + return await event.eor("`Reply to a photo`") + hw = 50 + try: + hw = int(event.pattern_match.group(1).strip()) + except (ValueError, TypeError): + pass + msg = await event.eor(get_string("com_1")) + image = await reply_message.download_media() + input_ = cv2.imread(image) + height, width = input_.shape[:2] + w, h = (hw, hw) + temp = cv2.resize(input_, (w, h), interpolation=cv2.INTER_LINEAR) + output = cv2.resize(temp, (width, height), interpolation=cv2.INTER_NEAREST) + cv2.imwrite("output.jpg", output) + await msg.respond("โ€ข Pixelated by Ultroid", file="output.jpg") + await msg.delete() + os.remove("output.jpg") + os.remove(image) diff --git a/addons/imdb.py b/addons/imdb.py new file mode 100644 index 0000000..fee6a6b --- /dev/null +++ b/addons/imdb.py @@ -0,0 +1,27 @@ +# Ultroid Userbot +# + +""" +Search movie details from IMDB + +โœ˜ Commands Available +โ€ข `{i}imdb ` +""" + +from . import * + + +@ultroid_cmd(pattern="imdb ?(.*)") +async def imdb(e): + m = await e.eor("`...`") + movie_name = e.pattern_match.group(1) + if not movie_name: + return await eor(m, "`Provide a movie name too`") + try: + mk = await e.client.inline_query("imdbot", movie_name) + await mk[0].click(e.chat_id) + await m.delete() + except IndexError: + return await eor(m, "No Results Found...") + except Exception as er: + return await eor(m, str(er)) \ No newline at end of file diff --git a/addons/inline/__init__.py b/addons/inline/__init__.py new file mode 100644 index 0000000..7aab8e9 --- /dev/null +++ b/addons/inline/__init__.py @@ -0,0 +1 @@ +from .. import * diff --git a/addons/inline/__pycache__/__init__.cpython-312.pyc b/addons/inline/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bac11afc8262a9ddfbdfd435efe53606c156d3db GIT binary patch literal 165 zcmX@j%ge<81Tn`0GX#P3V-N=hn4pZ$d_cx@h7^Vr#vF#VOpFYbOq$FuL9&{Rw-~kj zfF#38hR-0?zx4Do@^e%5OOs0TN=o%Zb4rTxGgI^vQ&RHtiuE(|ax(K$_2c6+^D;}~ oSWd+qq-c`v$L5cTQZ)8Y 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 OQrZ0%=&sma^Iv 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 Ro=MJEcl{L|(O&~;{{@fiXM_L% literal 0 HcmV?d00001 diff --git a/addons/inline/__pycache__/pypi.cpython-312.pyc b/addons/inline/__pycache__/pypi.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5175ecf2ffbf7252e8ba7cb013376143fe630374 GIT binary patch literal 13003 zcmds7Yj70TmG188dG$OsdOv^x3Be3P0wG?q01JtS493_%63ep1Xu6R`%tP+(F=*VA z9Xs|SDoFw5B*=wX6#rSpkX@yUtteHg3OKd{?4KErsx;}~3ikR(@^5%}*HP_{J?G9t zBY6NPaqU*^mFD*8+xOh}J?A^;-ha1PI0{1F@17lMTTM~_fiJnB%@X(DVJPZ6#Zx@( zr+&`R6wmM)Kix}{C)3N2r>0j!o@_4*Pu8yuXnVCJuhy>%=zH~q*7*$qW3Q3WdOsWB zdQF5j_{{-Jua%~ZSh~?~3)p(?Pq!x7lO##2_k^HrJ{<;GGB?bKM zNAfQ%%D=3De+}=1UN$|ll;uTBSy52R+DG!&7v*m#;BOw))Kfx910}+oL0OvNhRj$M z#ypoRhsML7mh*Po1D$EB}o1p# zAg%Kbg?wJ5^xjZl#OFuSvQzMcW#6%||4=AA0tu#oM?B7lP6U0&MkBQ&zL5=1Ur>@g ze!p|=%g%z2SmMsGEQf+FM%C``e16w+s!{fb28IQ%EWy``?vOVe5Q1{2EQ`K@uqSai$RHe7X>Nom!)RTo8167suT-94gBuMAUaRU`ESG7 zWe&;tpisj(0g_Ln@|!3(t;70)k6ALe(NN&jP*GZ;WJ4~OLU#bE(1$1&bKuXI?9!_G zA&)fV_YJ5zX~@&Mag(YOg5D4>sKz1TB<~v(Bw00Ko_;yh9~S*EQyO@{XGjzHejhJk z2b|71cgs*HAhd)B!a+IQa>Or-As^r3;rUQdYVigAzM#;8que|)syYURpdi8`>kkKg zFNXyvMy!QmR>4o&1W}B-ZLd6UJ!c)4E=AssTu_qsrdj)@gnd)ezGd1my*zI3i1nnF zIN#WJ)|g;xQl_#vTXr8fsRhH1Lr#Xh2?!W=%s|30rY;H!l^a?ZBKm-f5i22wsu>hy z7cEu;E#b5|#TrbuLvnve^bPug9zPC^xD1llVy+U1pa-UkGdoW27~h&St&FoP#X3k` z&^Vkw(zySIVjs6Acu*NIo4}F@!?>arg)5rN+0^J`Ru~V8<{Kfmtn_2iVKTua=S9r%_6wV6hnwM6@sUHTN~ED2cVl{GLH6 zqIs!Li7+p^bnvbGy1a5A9O5639>@pLr1IK*~PYnFR})^ZEr(u%CQ&L6g_R zPx=>#V$|o3vh$7S8po?9S|?up^@`s#{i zmeEnzRZ+$WvoH*w7KdU&g4giu6>T1zuqYOy8o4ybt1!dmIePx7XmX;3*I%*cxW5O$ z@KsouKVi;m{!y!?qO8K6rC(dkmniHjpr*xoh2={~4O&IZI|!u%s+3TApvnkk0IHl& zMj2%m35qUPXO!bB6deG!N<|NGm12OnS}{UgbI}+zDW+j$UK9%W%`!@75(-i+@{)Y2 zS+OYkE4BH3W|dJIk}&Md5(N*w4qChfE6t5X)F#_<8HQKnsQD+qlwYQB7pRNO6=#m; zF&xYJ6^l6rnW!D+x`^h4)V!vguXWfoPv4GgbmPtfBSGo3=ePP!@uyR zf;EH^Vo~7Dyajfwb-rg;Y?rfRxu}=Wr=MtWA8)3#AYGn^anFJ5%?P>Eo2eiC34Y)E zxdvc&(}BpkAz2=g+FM!%MbF4kb4VO)IR=orW!<_q@1~8Owl?9IXT5ODyJh40ts9z$ zM+PHHavTIlAp;UEuSQ#jrBG0%og!i}&>)6@=cF{^_sObuWGEzu4u^58NuORl_372v zt=Okm-?;UT^V6&2x6VLx^F0ygBf|LtfPGtrM})z!2NK-w`5exLylywgAus%6Id9&4 z52LHAKD~NjQBLQ_Z$Y+OF~}9Wc@=ps+nsV?T0j~ZPL6ks4s(L95hJ!dtT1&DBLJJE5_s+TCvF3vd;)^{~<8myo$4Q>k^JI^g)W)GTd2HOKJ}82A|$b3F@ z?H*gVb;Fi*9^SKc{l*P#1Fgq4ZQ8OK*RD!)E`x}WLTtro14eBaZNvz>DI)L}H$wzD zw<6t+5e|!pmW#LzBg~{)`D|GaHiY3G%|pU7{EgRh=g&oe)G^m_9#`gh!Np0K-(~ z#DIvZN3}>Ne6n|_KVv|tR*y6q^!7^`qZCR2t2E$|iSeYe$9zFv)xdHRQIv`GSb!cA z!S+^l*&>VwpFh~szrW|uVO19%K}+9NqH2X#aG&UKDFg;p!%jeq{YReLuj;dVLN$P0 zI|7?Wc<9uqnwNc0y?jy@pTz1rv3d^nQa=<87P+_!Q*nNYfrQ5Of{-z*N;A#uCyR0j zjBCFjiZ24wUSv#xfcq2mWsJIG*%8~FvNgx{rkM(@E#;^@?>^_Ab*xA@R!nS|Dv3K* z0FIpMOgJ`;=^r#x6%7-6|M{7pJ~Oo^+0b!~pDEurYugvwo6_47`q~NI9hHo`ain#u0TO;e7k zuBnaF?DV&%d*ZviasGJR>yP^bacgi)bEl;2eAT(C@rJjSj_Gcfl$|~NRy7diuBnP^ zx*J_Hz?o!R$HSvaxQ}XoFiOo+XtM`prA>C4X=IPT<$7?oUv)u6BI1=A} zXvTc_w%L(M-G1#K;@|F#f9r+#uD%)bi)pQ$6kKka?UbqUzxD4 zOjSEmD;iTZ?YC>{QdLi-s;W~}4XLV{`$lbT#RD_7WZ9zBB^7Bi)v$V^agv$bJn4!% z+fvnask-{~N~)ysK2=)cNNdV1*87@D8~0ySrIAZx^q`e8I%W-32}9K#dugi9iT|}r zQ_C9hziwHou?>j3CB_P1H(9I?G#21oM`=yz(xT0-*#iw8|JKB_ljf;`WX;x8?WU;{ zQ@;2PDPAq7^`tEYqzDQTF}xU(!u5QeUPI($L5`=@_i=*R^}M(__xv+o{QAKwa0(VibLdnlD?SNo|Y*u69Cc6iu=EcrCBXwGb?` z;(7E1d9=J?IByk@j+5vioJO!15UxSUVgIP^A$d98l*=2{&m&evpXW5l=yW1s*pZ{= zpNL}>Lk`78jdI>bRgC#EjEZsbDDfO>Uf!y(fbk6%HBnCCc$=clyhWh5B*jiF8~C10 z(etL`pwh+7^VaAv>hVQ^FX0^uO>DZ-T>l1Xut%xkyuCTk0+x>HN?9)7;u%Ie=P|XF zgB84}w#RT3YajEsw~yEXd%y5FrW>Ji(s?EIZSee)L14n*mmY<)M%mMi6j>fV?bL`RUE8syXwqUkCtL z6uTjdYV!I$lH@z)1H?;^SVVK6r88pcbN9KGqe@?&(l0KDjNuB15Ys|?089dqC(s@t zZMdQ6C+q`3ozTQvmq1vyn6FQDs8+zl_{A&e01 ziU=-Lb~xkd2&Q{;9 zs=1_lTQ~mQNin`*Z?dW<&X(V@YX<;*vCHpR>L+$jY?*A0 zo0_3ztRZe~o$8oszQ)AOT?w`;o3>_h-{iJwNP8l|J`wA_qj#JYKGxTMoEZFRi4$YPNo&ijp(SBx$wMw=+kH*CCd8Zf&zPUi zLaxPyWdWC=cwyshEJ%I3-;S`b@i$x!ned$^d7$qE`ZqnGlYVbFqF(1LldGE|ujibm01DS4C@ zd%~QV(*Fq@QMhui4qY9fgUDJv4~C)efR-4Bheq? zaiCnf0`);`V&c4TQhP$x7|fNfl9znYWOB4fBDjJ>D){4hPFic z#@K=1>&sI%FId0^^I7)1@thGP<&ri3snuAlcgm{L8mhE*yzNr^+wBv4vKEy~ZS!nx zTcWmY>QJ(F>-6$OZAZLj+w^nS*y&fUJ^QhJ&pi#W-q&bLz!=gRxiJ<6p(SpADq(nP zjQyL0^qq_u7q2~>v>ur?97!0Cq?eP z(%aj*OS$)3cL4p{^>lX?``gxPpg%Ct-8Jk7W*yR{B(9->j?@$f7bt!gNMH026Y2XW zApZBHZ^p7IYRlv;qbN$wl`<|#68OB-iozwNC|lqwhr0p_1M-HwoV|@uOmd8(w9pYr zp)HgY2z|b2gox~^Q{d)(;})Pm;-I^L&oei#wsQx;g5!>u5+g8YW&ONa*)^$L&T}+0_joh{OuE-ku@YgL<*DB5Q;WuDS{5w zWpyZW>R>(S;7^MKP(y*{GqY4wAJr9XNrRMo|o zZcS8fg{wXf43wkt?91=ej~`FgxZ_P7$&ziLoN9D;%ob2i#t z0eUwkdgwj)Fz;nz-Jct*XDp{JXZd*j*6I4`@@daC^NnY(TjM*Pi7!7mV|eyVAuTRUNv+iT}5e| z<|MSJUtii~q$g}$4EwJ;EkM5CL3iod_qUmVj*!c3g@TO8ymr)D?W^HR$wPD(m6sf_ z=An+oq1f$+%h^mtF?8O42iH_Vdi23=iPBMKvCru-`U`Ni*iuw~73!|MECXqmzgM83 zMgy4y2wM9!b((ImP7_~&F2Z#%+yHP+)di2D=0M)%FG$aSEf&V6Icx}MG_Jj^B>&&+&OO6zC2-Hp0wA`+Fc2|YqCCR zZ=QS^3~hVsYdx{9v9jBbS4g)js^O%_l+;Q|64b6&Rku*$ayU)K`>vb z;>N3@xsrE27gHwyy0*YiPk@)caFKeT+<6h35%7-yS9>u#F-zD2L5~(m#umYuLE)S| zohz8dey`u>JudL#DacZVD-nrr*bz0}m@qAmb>FsDj%!W_$DdDFSH7# z6OuAcK*T31J0u7EBJNC82a1vp1w=&nq5)GlxJr<{4XtVhq&5++`>D);Bm&Z*M3kJW zsV6WJ66NfvuQV#jLO?ahf?ohfZ7_4vTa|llmi^6eV4J@PEuu3}#DfL3q%aTOe~?5g zrfbQ)Xb}aSxDO*crn2DGmEi(6oY|854f_6mI5+R_C)ZlZkukZln(=X>FI44xLC_7d z3=HJVRW*2_B{=8A+ei#gf`T(j8YK^z{hz^2bfjw_nlp3+LVVaSY!@%UE369;Q4ps! zG)+ISQndXKl$HD&|3Dc(p_Y6?Rg?dQPpJAd%hJuCuxr2ID7x;C)W%P!ZJ$tWpHQu7 zma*yY=uM}huSH{_G{scVX)SAFV|p+nZ6z_&J)MRwzh|cD#(Rbmx-z|*ve;tAyE=+7 zkL^y%D>Za3Vq zFUW^lc&crN-g1{IrN2dE#;s{W-fdctaeb0&oo<++cid$RG>7?~q|->=t0t zc}tSpdaZ1R-hG!bXEN`B%s}2vhj vDb^C(d8+5Np15_*4BPZac5R$po7TdYIdby;Z@O+b^?`fIE|Uh_jS&A2>Q{4s literal 0 HcmV?d00001 diff --git a/addons/inline/__pycache__/winget.cpython-312.pyc b/addons/inline/__pycache__/winget.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8d19d07610afcd109aabcec1b5821f492fe8a60 GIT binary patch literal 2875 zcmZuzTWl2989rxrW-qfh-+;t1$$%a3Zj3h~v@QUp~TS8)a39b@URH>3%yHX$NL)9b#m8vhhHLbU!MorU~=54`=irkm}XD>KH z9BIyc=l1>oIsf^;nLh`EGJ^8vA5W#<^dR(a-e?uE3D#EtTt^zxuz?c%Ef_c}BwQG2 zE=@GVtdx+l?u0w*NqDl}gtv};2_KA0#Fy!65pKReK$`o8E8zz&j}gcQ6G4mwL_C^T z^R39sLSv@p|1nx_E=q)8+?#oJlcR;SfELv8GH$dnn!%CK7rb#Yf}OS#W-iah$i%3X z%4dnmzTopBZbzOZENL^Uo0CpRwP(y!(k3cRr3rOp-Av|G#t1c?zzNgPP4b$NpVUq2 zhQ*Gk+BVB80Oij=TvU!&*{o`6wlZ=_)eUvRAj%&3^SNIrl<*EuObZbE20b^d8}kyk99y(!z)7TJZG^F6|sh&hW=SW za~Fk-{|PG~a;>Np_)HfIwq_MwUytc~aDOg?&G&`tuAfK}niVI}tW*>=KesT7F8m%= zyNhluP`BtQdbD62d5fM*xW&2o)!OOwq?@Hv6PZXN!CD4RLuwhGe#F&S;?`oIzt}MPE^7+_ieibhpsvTkFxb z!?{1Z+>GzabIVd=^zjI^e8=d@A4F7?sGun()^^MWz%$tI$=YI$B~2d?*B{KgC+32yT_urP(DUFXmg z9zrF2<@uC=>yem3L+Hvyct(HYn!=I3la#vwN#f0_({|3#nd8w-$lv5kj$|{HvWVdL z>?xh4(#c%b2|t1$0aVQv#?p-C?BQ5U&FO=UoExNhGj?fjET^U}s*}Y2HZkoyB}Xii zsla`Z(LC7&tC_AE-&29O(Zke>Hch$4~po5hS`~pv34<*Tr4Jqw?tx4#(zpFB0 zGeXhEEU8hHm2t=0Y}u3xZ9y293%+Rdv^r_SxFd3~fqM&rEEfU|tx`rNVP}+Q zJ~-^N!K-AB5E_vjiRsKBj$hmK#c}1S;fRb(!(mU<<;pI!7Z0`M?e&J76*^B^N)szb ztvra{aKC;Fj6__Nrz7ov%8^qlsB)6&SrQ4+Ufv}&0x6#`H8LHi)S`}CHSH-vDZk|W zM019kA`QKEfdD&V#?nDF)m)C48uv;!G?01^k5bAYlz#@DU^Do7UGpPBMMX4$K{?hT2Nq3+4k9kmPxx8g4K3FBIp+YPhp>v<}+3 zu6wU}7rR&6`sSr-`<9YcI=eV@bKg?1()-Qw&Y|+qt9K9IWq&$;ces2eUDhv_jY}1M zsysbY(F^7D3UFQ$H;{#p7~*R8jH*YmgCM}IrAv}0*x>7`$L{<8b% z>a)ixZO1C!WAozQ{cTk_R2p5}vgj!dR%B(quj=(*l^5h{$F}QxuI*Xt*j?$^UESKf zBraX3^uPSkmb<6#ombb+Tb1)xIrmNtp%LMP0IxH`IpItA`@spJ=0ctQ>qzJf{TB(r z&{rl!$}nfZZL`Rtl_wj!Q=_~jlH z*!lp8aNwcNtHy#+4TL_7-aNP39s6h-(1)J^`mhZ2KKXvVawA{3=7R+rJTfo-??DLl zAHy{-*ne1)ku-)k?6)DzKiVFD8Q+vfhtV&e2lTOw<1z7L|HxC&_@p-w-y8ZQHqrx) z+kPA$l5Yq4Io^lk`^DSekT@QW#0Ok=dU1T0`%a(4aYTUrJ1=042Skqdx_P}HLtO|q z(|)Y}KT-%cg@qA=OoAvz+8lurr=7Q1+A;^3G00|e#HRdf;|Nm|4ytEjJpn0~ed^^E zmwLyWx8cu2!RZDV4XGm91xF{iZwad=4^<{0gnZazqb6wc$OGwY0oJ z4$PfvV=h7_YY>EPsmj{S&>hhTf=&LfG?}$N$sWcW39U8WOhRnk4$gInP%z z!n^*3{qx5cNAKYs_l0gehSyz4*jcN?+AzXhbAdI~SwWqpWO>(6x$9ehMf>S7u=IZ~ CzWnz9 literal 0 HcmV?d00001 diff --git a/addons/inline/__pycache__/xdasearch.cpython-312.pyc b/addons/inline/__pycache__/xdasearch.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..47df49affebd44beb2009743f45e6da408888e2e GIT binary patch literal 3294 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 r{- +# PLease read the GNU Affero General Public License in +# . + + +from telethon.tl.custom import Button +from . import in_pattern, InlinePlugin, async_searcher, asst +from telethon.tl.types import InputWebDocument + +__doc__ = f""" +โœ˜ Commands Available - +โ€ข `@{asst.username} gh .` + Searches for the Github username and returns the latest feeds. + End your query with a dot (.) to search. +""" + +@in_pattern("gh", owner=True) +async def gh_feeds(ult): + try: + username = ult.text.split(maxsplit=1)[1] + except IndexError: + await ult.answer( + [], + switch_pm="Enter Github Username to see feeds...", + switch_pm_param="start", + ) + return + if not username.endswith("."): + return await ult.answer( + [], switch_pm="End your query with . to search...", switch_pm_param="start" + ) + username = username[:-1] + data = await async_searcher( + f"https://api.github.com/users/{username}/events", re_json=True + ) + if not isinstance(data, list): + msg = "".join(f"{ak}: `{data[ak]}" + "`\n" for ak in list(data.keys())) + return await ult.answer( + [ + await ult.builder.article( + title=data["message"], text=msg, link_preview=False + ) + ], + cache_time=300, + switch_pm="Error!!!", + switch_pm_param="start", + ) + res = [] + res_ids = [] + for cont in data[:50]: + text = f"@{username}" + title = f"@{username}" + extra = None + if cont["type"] == "PushEvent": + text += " pushed in" + title += " pushed in" + dt = cont["payload"]["commits"][-1] + url = "https://github.com/" + dt["url"].split("/repos/")[-1] + extra = f"\n-> message: {dt['message']}" + elif cont["type"] == "IssueCommentEvent": + title += " commented at" + text += " commented at" + url = cont["payload"]["comment"]["html_url"] + elif cont["type"] == "CreateEvent": + title += " created" + text += " created" + url = "https://github.com/" + cont["repo"]["name"] + elif cont["type"] == "PullRequestEvent": + if ( + cont["payload"]["pull_request"].get("user", {}).get("login") + != username.lower() + ): + continue + url = cont["payload"]["pull_request"]["html_url"] + text += " created a pull request in" + title += " created a pull request in" + elif cont["type"] == "ForkEvent": + text += " forked" + title += " forked" + url = cont["payload"]["forkee"]["html_url"] + else: + continue + repo = cont["repo"]["name"] + repo_url = f"https://github.com/{repo}" + title += f" {repo}" + text += f" {repo}" + if extra: + text += extra + thumb = InputWebDocument(cont["actor"]["avatar_url"], 0, "image/jpeg", []) + article = await ult.builder.article( + title=title, + text=text, + url=repo_url, + parse_mode="html", + link_preview=False, + thumb=thumb, + buttons=[ + Button.url("View", url), + Button.switch_inline("Search again", query=ult.text, same_peer=True), + ], + ) + if article.id not in res_ids: + res_ids.append(article.id) + res.append(article) + msg = f"Showing {len(res)} feeds!" if res else "Nothing Found" + await ult.answer(res, cache_time=5000, switch_pm=msg, switch_pm_param="start") + +InlinePlugin.update({"Gษชแด›Hแดœส™ า“แด‡แด‡แด…s": "gh"}) diff --git a/addons/inline/imdb.py b/addons/inline/imdb.py new file mode 100644 index 0000000..e5d28c8 --- /dev/null +++ b/addons/inline/imdb.py @@ -0,0 +1,295 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2024 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +import hashlib +import json +import re + +import requests +from bs4 import BeautifulSoup +from telethon import Button + +try: + from PIL import Image +except ImportError: + Image = None + +from telethon.tl.types import InputWebDocument as wb + +from . import LOGS, callback, in_pattern, udB, async_searcher, asst + +__doc__ = f""" +โœ˜ Commands Available - +โ€ข `@{asst.username} imdb ` + Searches for the movie on IMDb and returns the results. +โ€ข `@{asst.username} imdb y=` + Searches for the movie on IMDb by year and returns the results. +""" + +# Define your OMDB API key +OMDB_API_KEY = udB.get_key("OMDb_API") #OpenMovies Database get free key from http://www.omdbapi.com/ with 1000 dailiy uses +imdbp = "https://graph.org/file/3b45a9ed4868167954300.jpg" + +LIST = {} +hash_to_url = {} + + +def generate_unique_id(url): + hashed_id = hashlib.sha256(url.encode()).hexdigest()[:8] + hash_to_url[hashed_id] = url + return hashed_id + + +def get_original_url(hashed_id): + return hash_to_url.get(hashed_id) + + +async def get_movie_data(search_term, full_plot=False): + if "y=" in search_term: + parts = search_term.split("y=") + if parts: + LOGS.info(f"YEAR_prts: {parts}") + movie_name = parts[0].strip() + if movie_name: + year = parts[1].strip() if len(parts) > 1 else None + if year: + SBY = True + else: + SBY = False + else: + SBY = False + movie_name = search_term + else: + SBY = False + movie_name = search_term + else: + SBY = False + movie_name = search_term + + url = f"http://www.omdbapi.com/?apikey={OMDB_API_KEY}&t={movie_name}" + + if SBY is True: + url += f"&y={year}" + if full_plot is True: + url += "&plot=full" + + data = await async_searcher(url, re_json=True) + if data.get("Response") == "True": + return data + else: + LOGS.info("Error: Unable to fetch movie data") + return None + + +def get_trailer(imdbID): + url = f"https://www.imdb.com/title/{imdbID}/" + headers = {"User-Agent": "Mozilla/5.0"} + + response = requests.get(url, headers=headers) + if response.status_code == 200: + soup = BeautifulSoup(response.content, "html.parser") + script = soup.find("script", type="application/ld+json") + data = json.loads(script.string) + trailer_url = data.get("trailer", {}).get("embedUrl") + if trailer_url: + LOGS.info(f"Trailer URL: {trailer_url}") + return f"{trailer_url}" + else: + LOGS.info("Could not find trailer link") + return None + + else: + LOGS.info("Error: Unable to fetch IMDb page") + return None + + +@in_pattern("imdb", owner=False) +async def inline_imdb_command(event): + try: + movie_name = event.text.split(" ", maxsplit=1)[1] + LOGS.info(f"QUERY\n{movie_name}") + except IndexError: + indexarticle = event.builder.article( + title="Sแด‡แด€ส€แด„สœ Sแดแดแด‡แด›สœษชษดษข", + thumb=wb(imdbp, 0, "image/jpeg", []), + text="**Iแดแด…ส™ Sแด‡แด€ส€แด„สœ**\n\nสแดแดœ แด…ษชแด…ษด'แด› sแด‡แด€ส€แด„สœ แด€ษดสแด›สœษชษดษข", + buttons=[ + Button.switch_inline( + "Sแด‡แด€ส€แด„สœ Aษขแด€ษชษด", + query="imdb ", + same_peer=True, + ), + Button.switch_inline( + "Sแด‡แด€ส€แด„สœ Bส Yแด‡แด€ส€", + query="imdb IF y= 2024 ", + same_peer=True, + ), + ], + ) + await event.answer([indexarticle]) + return + + try: + movie_data = await get_movie_data(movie_name) + if movie_data: + title = movie_data.get("Title", "") + year = movie_data.get("Year", "") + rated = movie_data.get("Rated", "") + released = movie_data.get("Released", "") + runtime = movie_data.get("Runtime", "") + ratings = movie_data.get("Ratings", "") + ratings_str = ", ".join( + [f"{rating['Source']}: `{rating['Value']}`" for rating in ratings] + ) + genre = movie_data.get("Genre", "") + director = movie_data.get("Director", "") + actors = movie_data.get("Actors", "") + plot = movie_data.get("Plot", "") + language = movie_data.get("Language", "") + country = movie_data.get("Country", "") + awards = movie_data.get("Awards", "") + poster_url = movie_data.get("Poster", "") + imdbRating = movie_data.get("imdbRating", "") + imdbVotes = movie_data.get("imdbVotes", "") + BoxOffice = movie_data.get("BoxOffice", "") + imdbID = movie_data.get("imdbID", "") + movie_details = ( + f"**Tษชแด›สŸแด‡:** {title}\n" + f"**Yแด‡แด€ส€:** `{year}`\n" + f"**Rแด€แด›แด‡แด…:** `{rated}`\n" + f"**Rแด‡สŸแด‡แด€sแด‡แด…:** {released}\n" + f"**Rแดœษดแด›ษชแดแด‡:** `{runtime}`\n" + f"**Gแด‡ษดส€แด‡:** {genre}\n" + f"**Dษชส€แด‡แด„แด›แดส€:** {director}\n" + f"**Aแด„แด›แดส€s:** {actors}\n" + f"**PสŸแดแด›:** {plot}\n" + f"**Lแด€ษดษขแดœแด€ษขแด‡:** `{language}`\n" + f"**Cแดแดœษดแด›ส€ส:** {country}\n" + f"**Aแดกแด€ส€แด…s:** {awards}\n" + f"**Rแด€แด›ษชษดษขs:** {ratings_str}\n" + f"**IMDส™ Rแด€แด›ษชษดษข:** `{imdbRating}`\n" + f"**IMDส™ Lษชษดแด‹:** https://www.imdb.com/title/{imdbID}\n" + f"**ษชแดแด…ส™Vแดแด›แด‡s:** `{imdbVotes}`\n" + f"**BแดxOา“า“ษชแด„แด‡:** `{BoxOffice}`" + ) + except Exception as er: + LOGS.info(f"Exception: {er}") + + try: + plot_id = generate_unique_id(movie_details) + except UnboundLocalError: + if " y= " in movie_name: + noresult = movie_name.replace(" y= ", " ") + elif "y= " in movie_name: + noresult = movie_name.replace("y= ", "") + elif "y=" in movie_name: + noresult = movie_name.replace("y=", "") + else: + noresult = movie_name + + return await event.answer( + [ + await event.builder.article( + title="Nแด ส€แด‡sแดœสŸแด›s า“แดแดœษดแด…", + text=f"**IMDส™**\nTส€ส แด€ษดแดแด›สœแด‡ส€ sแด‡แด€ส€แด„สœ", + thumb=wb(imdbp, 0, "image/jpeg", []), + buttons=[ + Button.switch_inline( + "Sแด‡แด€ส€แด„สœ Aษขแด€ษชษด", + query="imdb ", + same_peer=True, + ), + Button.switch_inline( + "Sแด‡แด€ส€แด„สœ Bส Yแด‡แด€ส€", + query=f"imdb {movie_name} y= ", + same_peer=True, + ), + ], + ) + ], + switch_pm=f"{noresult}", + switch_pm_param="start", + ) + except Exception as er: + LOGS.info(f"Exception: {er}") + return + + txt = f"**Tษชแด›สŸแด‡:** {title}\n**Rแด‡สŸแด‡แด€sแด‡แด…:** {released}\n**Cแดแดœษดแด›ส€ส:** {country}" + button = [ + [Button.inline("FแดœสŸสŸ Dแด‡แด›แด€ษชสŸs", data=f"plot_button:{plot_id}")], + [Button.switch_inline("Sแด‡แด€ส€แด„สœ Aษขแด€ษชษด", query="imdb ", same_peer=True)], + ] + + article = await event.builder.article( + type="photo", + text=txt, + title=f"{title}", + include_media=True, + description=f"{released}\nษชแดแด…ส™: {imdbRating}\nLแด€ษดษขแดœแด€ษขแด‡: {language}", + link_preview=False, + thumb=wb(poster_url, 0, "image/jpeg", []), + content=wb(poster_url, 0, "image/jpeg", []), + buttons=button, + ) + LIST.update( + { + plot_id: { + "text": txt, + "buttons": button, + "imdbID": imdbID, + "movie_name": movie_name, + "plot": plot, + } + } + ) + await event.answer([article]) + + +@callback(re.compile("plot_button:(.*)"), owner=False) +async def plot_button_clicked(event): + plot_id = event.data.decode().split(":", 1)[1] + details = get_original_url(plot_id) + plot = LIST[plot_id]["plot"] + imdbID = LIST[plot_id]["imdbID"] + trailer_url = get_trailer(imdbID) + btns = [ + [Button.inline("Back", data=f"imdb_back_button:{plot_id}")], + ] + if trailer_url: + btns.insert(0, [Button.url("Trailer", url=trailer_url)]) + if plot.endswith("..."): + btns.insert( + 0, [Button.inline("Extended Plot", data=f"extended_plot:{plot_id}")] + ) + await event.edit(details, buttons=btns) + + +@callback(re.compile("imdb_back_button:(.*)"), owner=False) +async def back_button_clicked(event): + plot_id = event.data.decode().split(":", 1)[1] + if not LIST.get(plot_id): + return await event.answer("Query Expired! Search again ๐Ÿ”") + text = LIST[plot_id]["text"] + buttons = LIST[plot_id]["buttons"] + await event.edit(text, buttons=buttons) + + +@callback(re.compile("extended_plot:(.*)"), owner=False) +async def extended_plot_button_clicked(event): + plot_id = event.data.decode().split(":", 1)[1] + if not LIST.get(plot_id): + return await event.answer("Query Expired! Search again ๐Ÿ”") + movie_name = LIST[plot_id]["movie_name"] + + ext_plot = await get_movie_data(movie_name, full_plot=True) + fullplot = ext_plot.get("Plot", "") + + if fullplot: + extended_plot = f"**Exแด›แด‡ษดแด…แด‡แด… PสŸแดแด›:** {fullplot}" + btns = [ + [Button.inline("Back", data=f"imdb_back_button:{plot_id}")], + ] + await event.edit(extended_plot, buttons=btns) diff --git a/addons/inline/koo.py b/addons/inline/koo.py new file mode 100644 index 0000000..d8371a3 --- /dev/null +++ b/addons/inline/koo.py @@ -0,0 +1,112 @@ + +# Ultroid - UserBot +# Copyright (C) 2021-2022 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from telethon.tl.types import InputWebDocument as wb +from telethon.tl.custom import Button +from . import in_pattern, InlinePlugin, async_searcher, asst + +__doc__ = f""" +โœ˜ Commands Available - +โ€ข `@{asst.username} koo ` + Searches for the query on Koo and returns the results. +""" + +_koo_ = {} + + +@in_pattern("koo", owner=True) +async def koo_search(ult): + """Search Users on koo with API""" + try: + match = ult.text.split(maxsplit=1)[1].lower() + match_ = match + except IndexError: + await ult.answer( + [], switch_pm="Enter Query to Search..", switch_pm_param="start" + ) + return + if _koo_.get(match): + return await ult.answer( + _koo_[match], switch_pm="โ€ข Koo Search โ€ข", switch_pm_param="start" + ) + res = [] + se_ = None + key_count = None + if " | " in match: + match = match.split(" | ", maxsplit=1) + try: + key_count = int(match[1]) + except ValueError: + pass + match = match[0] + match = match.replace(" ", "+") + req = await async_searcher( + f"https://www.kooapp.com/apiV1/search?query={match}&searchType=EXPLORE", + re_json=True, + ) + if key_count: + try: + se_ = [req["feed"][key_count - 1]] + except KeyError: + pass + if not se_: + se_ = req["feed"] + for count, feed in enumerate(se_[:10]): + if feed["uiItemType"] == "search_profile": + count += 1 + item = feed["items"][0] + profileImage = ( + item["profileImageBaseUrl"] + if item.get("profileImageBaseUrl") + else "https://telegra.ph/file/dc28e69bd7ea2c0f25329.jpg" + ) + extra = await async_searcher( + "https://www.kooapp.com/apiV1/users/handle/" + item["userHandle"], + re_json=True, + ) + img = wb(profileImage, 0, "image/jpeg", []) + text = f"โ€ฃ **Name :** `{item['name']}`" + if extra.get("title"): + text += f"\nโ€ฃ **Title :** `{extra['title']}`" + text += f"\nโ€ฃ **Username :** `@{item['userHandle']}`" + if extra.get("description"): + text += f"\nโ€ฃ **Description :** `{extra['description']}`" + text += f"\nโ€ฃ **Followers :** `{extra['followerCount']}` โ€ฃ **Following :** {extra['followingCount']}" + if extra.get("socialProfile") and extra["socialProfile"].get("website"): + text += f"\nโ€ฃ **Website :** {extra['socialProfile']['website']}" + res.append( + await ult.builder.article( + title=item["name"], + description=item.get("title") or f"@{item['userHandle']}", + type="photo", + content=img, + thumb=img, + include_media=True, + text=text, + buttons=[ + Button.url( + "View", + "https://kooapp.com/profile/" + item["userHandle"], + ), + Button.switch_inline( + "โ€ข Share โ€ข", + query=ult.text if key_count else f"{ult.text} | {count}", + ), + ], + ) + ) + + if not res: + switch = "No Results Found :(" + else: + _koo_.update({match_: res}) + switch = f"Showing {len(res)} Results!" + await ult.answer(res, switch_pm=switch, switch_pm_param="start") + + +InlinePlugin.update({"Kแดแด Sแด‡แด€ส€แด„สœ": "koo @__kumar__amit"}) diff --git a/addons/inline/npmsearch.py b/addons/inline/npmsearch.py new file mode 100644 index 0000000..3996c99 --- /dev/null +++ b/addons/inline/npmsearch.py @@ -0,0 +1,49 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2022 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from telethon.tl.types import InputWebDocument as wb +from telethon.tl.custom import Button +from . import in_pattern, InlinePlugin, async_searcher, asst + +__doc__ = f""" +โœ˜ Commands Available - +โ€ข `@{asst.username} npm ` + Searches for the package on NPM and returns the results. +""" + + +@in_pattern("npm") +async def search_npm(event): + try: + query = event.text.split(maxsplit=1)[1] + except IndexError: + await event.answer([], switch_pm="Enter query to search", switch_pm_param="start" + ) + return + data = await async_searcher(f"https://registry.npmjs.com/-/v1/search?text={query.replace(' ','+')}&size=7", re_json=True) + res = [] + for obj in data["objects"]: + package = obj["package"] + url = package["links"]["npm"] + title = package["name"] + keys = package.get("keywords", []) + text = f"**[{title}]({package['links'].get('homepage', '')})\n{package['description']}**\n" + text += f"**Version:** `{package['version']}`\n" + text += f"**Keywords:** `{','.join(keys)}`" + res.append(await event.builder.article( + title=title, + text=text, + url=url, + link_preview=False, + buttons=[ + Button.url("View", url), + Button.switch_inline("Search again", query=event.text, same_peer=True), + ], + )) + await event.answer(res, switch_pm="NPM Search", switch_pm_param="start") + +InlinePlugin.update({"Npm Search": "npm"}) diff --git a/addons/inline/omgubuntu.py b/addons/inline/omgubuntu.py new file mode 100644 index 0000000..5441575 --- /dev/null +++ b/addons/inline/omgubuntu.py @@ -0,0 +1,72 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2022 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + + +from telethon.tl.custom import Button +from telethon.tl.types import InputWebDocument as wb +from .. import async_searcher, in_pattern, InlinePlugin, asst +from bs4 import BeautifulSoup as bs + +__doc__ = f""" +โœ˜ Commands Available - +โ€ข `@{asst.username} omgu ` + Searches for the query on OMG Ubuntu and returns the results. +""" + +_OMG = {} + +@in_pattern("omgu", owner=True) +async def omgubuntu(ult): + try: + match = ult.text.split(maxsplit=1)[1].lower() + except IndexError: + await ult.answer( + [], switch_pm="Enter Query to search...", switch_pm_param="start" + ) + return + if _OMG.get(match): + return await ult.answer( + _OMG[match], switch_pm="OMG Ubuntu Search :]", switch_pm_param="start" + ) + get_web = "https://www.omgubuntu.co.uk/?s=" + match.replace(" ", "+") + get_ = await async_searcher(get_web, re_content=True) + BSC = bs(get_, "html.parser", from_encoding="utf-8") + res = [] + for cont in BSC.find_all("div", "sbs-layout__item"): + img = cont.find("div", "sbs-layout__image") + url = img.find("a")["href"] + src = img.find("img")["src"] + con = cont.find("div", "sbs-layout__content") + tit = con.find("a", "layout__title-link") + title = tit.text.strip() + desc = con.find("p", "layout__description").text.strip() + text = f"[{title.strip()}]({url})\n\n{desc}" + img = wb(src, 0, "image/jpeg", []) + res.append( + await ult.builder.article( + title=title, + type="photo", + description=desc, + url=url, + text=text, + buttons=Button.switch_inline( + "Search Again", query=ult.text, same_peer=True + ), + include_media=True, + content=img, + thumb=img, + ) + ) + await ult.answer( + res, + switch_pm=f"Showing {len(res)} results!" if res else "No Results Found :[", + switch_pm_param="start", + ) + _OMG[match] = res + + +InlinePlugin.update({"OแดษขUส™แดœษดแด›แดœ": "omgu cutefish"}) diff --git a/addons/inline/pypi.py b/addons/inline/pypi.py new file mode 100644 index 0000000..4b64fb1 --- /dev/null +++ b/addons/inline/pypi.py @@ -0,0 +1,287 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2024 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +from . import * +import hashlib +import inspect +import os +import re +from datetime import datetime +from html import unescape +from random import choice +from re import compile as re_compile +from bs4 import BeautifulSoup as bs + +try: + from markdownify import markdownify as md +except ImportError: + os.system("pip3 install -q markdownify") + from markdownify import markdownify as md + +from telethon import Button +from telethon.tl.alltlobjects import LAYER, tlobjects +from telethon.tl.types import DocumentAttributeAudio as Audio +from telethon.tl.types import InputWebDocument as wb +from telethon.tl.types import MessageEntityTextUrl + +__doc__ = f""" +โœ˜ Commands Available - +โ€ข `@{asst.username} pypi ` + Searches for the package on PyPI and returns the results. +""" + +hash_to_url = {} + + +def generate_unique_id(url): + hashed_id = hashlib.sha256(url.encode()).hexdigest()[:8] + hash_to_url[hashed_id] = url + return hashed_id + + +def get_original_url(hashed_id): + return hash_to_url.get(hashed_id) + + +def clean_desc(description): + # Remove lines starting with ".." + description = re.sub(r"^\.\.", "", description, flags=re.MULTILINE) + # Remove lines starting with "|" + description = re.sub(r"^\|", "", description, flags=re.MULTILINE) + # Remove lines starting with ":" + description = re.sub(r"^:", "", description, flags=re.MULTILINE) + # Remove lines starting with " :" + description = re.sub(r"^ {2}:", "", description, flags=re.MULTILINE) + # Remove lines starting with "/3/" + description = re.sub(r"/\d+/", "", description) + # Remove lines starting with "code-block:: python" + description = re.sub( + r"^\s*code-block::.*$", "", description, flags=re.IGNORECASE | re.MULTILINE + ) + # Remove any remaining leading or trailing whitespace + description = description.strip() + return description + + +PYPI_LIST = {} + + +@in_pattern("pypi") +async def inline_pypi_handler(event): + pypimg = "https://graph.org/file/004c65a44efa1efc85193.jpg" + BASE_URL = "https://pypi.org/pypi/{}/json" + try: + package = event.text.split(" ", maxsplit=1)[1] + except IndexError: + await event.answer( + [ + event.builder.article( + type="photo", + include_media=True, + title="sแด‡แด€ส€แด„สœ แด˜สแด˜ษช", + thumb=wb(pypimg, 0, "image/jpeg", []), + content=wb(pypimg, 0, "image/jpeg", []), + text=f"**แด˜สแด˜ษช sแด‡แด€ส€แด„สœ**\n\nสแดแดœ แด…ษชแด…ษด'แด› sแด‡แด€ส€แด„สœ า“แดส€ แด€ษดสแด›สœษชษดษข.", + buttons=[ + Button.switch_inline( + "sแด‡แด€ส€แด„สœ แด€ษขแด€ษชษด", + query="pypi ", + same_peer=True, + ), + ], + ) + ] + ) + return + + response = await async_searcher(BASE_URL.format(package), re_json=True) + if response is not None and "info" in response: + info = response["info"] + name = info["name"] + url = info["package_url"] + version = info["version"] + summary = info["summary"] + qid = generate_unique_id(name) + txt = f"**แด˜แด€แด„แด‹แด€ษขแด‡:** [{name}]({url}) (`{version}`)\n\n**แด…แด‡แด›แด€ษชสŸs:** `{summary}`" + + offset = txt.find(name) + length = len(name) + url_entity = MessageEntityTextUrl(offset=offset, length=length, url=url) + + # Extract document links from description + document_links = re.findall(r"(https?://\S+)", info["description"]) + + buttons = [ + Button.inline("sสœแดแดก แด…แด‡แด›แด€ษชสŸs", data=f"pypi_details:{qid}"), + Button.inline("แด…แดแด„แดœแดแด‡ษดแด› สŸษชษดแด‹s", data=f"pypi_documents:{qid}"), + ] + + await event.answer( + [ + event.builder.article( + type="photo", + include_media=True, + title="แด˜แด€แด„แด‹แด€ษขแด‡ ษชษดา“แด", + thumb=wb( + "https://graph.org/file/f09380ada91534b2f6687.jpg", + 0, + "image/jpeg", + [], + ), + content=wb( + "https://graph.org/file/f09380ada91534b2f6687.jpg", + 0, + "image/jpeg", + [], + ), + description=f"{name}\n{version}", + text=txt, + buttons=buttons, + ) + ] + ) + + PYPI_LIST.update( + { + qid: { + "info": info, + "name": name, + "url": url, + "version": version, + "summary": summary, + "text": txt, + "document_links": document_links, + "buttons": buttons, + } + } + ) + else: + await event.answer( + [ + event.builder.article( + title="แด˜แด€แด„แด‹แด€ษขแด‡ ษดแดแด› า“แดแดœษดแด…", + thumb=wb(pypimg, 0, "image/jpeg", []), + text=f"**แด˜แด€แด„แด‹แด€ษขแด‡:** `{package}`\n\n**แด…แด‡แด›แด€ษชสŸs:** `ษดแดแด› า“แดแดœษดแด…`", + ) + ] + ) + return + + +@callback(re.compile("pypi_details:(.*)"), owner=False) +async def show_details(event): + qid = event.data.decode().split(":", 1)[1] + if not PYPI_LIST.get(qid): + return await event.answer("Qแดœแด‡ส€ส แด‡xแด˜ษชส€แด‡แด…! Sแด‡แด€ส€แด„สœ แด€ษขแด€ษชษด ๐Ÿ”") + info = PYPI_LIST[qid] + details = info["info"] + + author = details.get("author", "Uษดแด‹ษดแดแดกษด") + author_email = details.get("author_email", "Uษดแด‹ษดแดแดกษด") + classifiers = "\n".join(details.get("classifiers", [])) + description = details.get("description", "N/A") + + formatted_description = md(description) + clean_description = re.sub(r"\*\*|`|\\|_", "", formatted_description) + clean_description = clean_desc(clean_description) + PYPI_LIST[qid]["description"] = clean_description + + text = f"**แด€แดœแด›สœแดส€:** {author}\n" + text += f"**แด€แดœแด›สœแดส€ แด‡แดแด€ษชสŸ:** {author_email}\n" + text += f"**แด„สŸแด€ssษชา“ษชแด‡ส€s:**\n{classifiers}\n" + + if description == "N/A": + buttons = [ + Button.inline("ส™แด€แด„แด‹", data=f"pypi_back_button:{qid}"), + ] + await event.edit(text, buttons=buttons) + else: + buttons = [ + Button.inline("แดแดส€แด‡", data=f"pypi_description_more:{qid}"), + Button.inline("ส™แด€แด„แด‹", data=f"pypi_back_button:{qid}"), + ] + await event.edit(text, buttons=buttons) + + +@callback(re.compile("pypi_documents:(.*)"), owner=True) +async def show_documents(event): + qid = event.data.decode().split(":", 1)[1] + if not PYPI_LIST.get(qid): + return await event.answer("Qแดœแด‡ส€ส แด‡xแด˜ษชส€แด‡แด…! Sแด‡แด€ส€แด„สœ แด€ษขแด€ษชษด ๐Ÿ”") + document_links = PYPI_LIST[qid]["document_links"] + if document_links: + text = "**แด…แดแด„ สŸษชษดแด‹s**\nโ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ€ข\n" + text += "\n".join( + [ + f"โ•ฐโžข [{link.split('//')[1].split('/')[0]}]({link})" + for link in document_links + ] + ) + text += "\nโ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ€ข" + buttons = [ + Button.inline("ส™แด€แด„แด‹", data=f"pypi_back_button:{qid}"), + ] + await event.edit(text, buttons=buttons) + else: + await event.answer("ษดแด แด…แดแด„แดœแดแด‡ษดแด› สŸษชษดแด‹s า“แดแดœษดแด….") + + +@callback(re.compile("pypi_description_more:(.*)"), owner=True) +async def show_full_description(event): + qid = event.data.decode().split(":", 1)[1] + description = PYPI_LIST[qid].get("description") + if description: + already_defined_text_length = len("แด…แด‡sแด„ส€ษชแด˜แด›ษชแดษด:\nPage X/Y\n") + current_page = 1 + await show_description_with_pagination( + event, qid, description, already_defined_text_length, current_page + ) + + +async def show_description_with_pagination( + event, qid, description, already_defined_text_length, current_page +): + available_length = 1024 - already_defined_text_length + + description_chunks = [ + description[i : i + available_length] + for i in range(0, len(description), available_length) + ] + total_chunks = len(description_chunks) + + text = f"**แด…แด‡sแด„ส€ษชแด˜แด›ษชแดษด:**\n**Pแด€ษขแด‡** `{current_page}`/`{total_chunks}`\n{description_chunks[current_page - 1]}" + buttons = [ + Button.inline("<<", data=f"pypi_description_page:{qid}:{current_page-1}"), + Button.inline("ส™แด€แด„แด‹", data=f"pypi_back_button:{qid}"), + Button.inline(">>", data=f"pypi_description_page:{qid}:{current_page+1}"), + ] + await event.edit(text, buttons=buttons) + + +@callback(re.compile("pypi_description_page:(.*):(\\d+)"), owner=True) +async def handle_description_page(event): + qid, page = event.data.decode().split(":")[1:] + description = PYPI_LIST[qid].get("description") + if description: + already_defined_text_length = len("แด…แด‡sแด„ส€ษชแด˜แด›ษชแดษด:\nPage X/Y\n") + page_number = int(page) + await show_description_with_pagination( + event, + qid, + description, + already_defined_text_length, + current_page=page_number, + ) + + +@callback(re.compile("pypi_back_button:(.*)"), owner=True) +async def back_button_clicked(event): + qid = event.data.decode().split(":", 1)[1] + if not PYPI_LIST.get(qid): + return await event.answer("Qแดœแด‡ส€ส แด‡xแด˜ษชส€แด‡แด…! Sแด‡แด€ส€แด„สœ แด€ษขแด€ษชษด ๐Ÿ”") + text = PYPI_LIST[qid]["text"] + buttons = PYPI_LIST[qid]["buttons"] + await event.edit(text, buttons=buttons) diff --git a/addons/inline/winget.py b/addons/inline/winget.py new file mode 100644 index 0000000..14571a4 --- /dev/null +++ b/addons/inline/winget.py @@ -0,0 +1,49 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# + +import re +from telethon.tl.types import InputWebDocument as wb +from . import get_string, async_searcher, in_pattern, InlinePlugin, async_searcher, asst + +__doc__ = f""" +โœ˜ Commands Available - +โ€ข `@{asst.username} winget ` + Searches for the query on Winget and returns the results. +""" +from telethon.tl.custom import Button + +@in_pattern("winget", owner=True) +async def search_winget(event): + QUERY = event.text.split(maxsplit=1) + try: + query = QUERY[1] + except IndexError: + await event.answer( + [], switch_pm=get_string("instu_3"), switch_pm_param="start" + ) + return + le = "https://api.winget.run/v2/packages?ensureContains=true&partialMatch=true&take=20&query=" + query.replace(" ", "+") + ct = await async_searcher(le, re_json=True) + out = [] + for on in ct["Packages"]: + data = on["Latest"] + name = data["Name"] + homep = data.get("Homepage") + text = f"> **{name}**\n - {data['Description']}\n\n`winget install {on['Id']}`\n\n**Version:** `{on['Versions'][0]}`\n" + text += "**Tags:**" + " ".join([f"#{_}" for _ in data["Tags"]]) + if homep: + text += f"\n\n{homep}" + out.append( + await event.builder.article( + title=name, description=data["Description"], url=homep, text=text, buttons=Button.switch_inline("Search Again", "winget", same_peer=True) + ) + ) + uppar = "|> Winget Results" if out else "No Results Found :(" + await event.answer(out, switch_pm=uppar, switch_pm_param="start", cache_time=3000) + + +InlinePlugin.update({"Search Winget": "winget telegram"}) diff --git a/addons/inline/xdasearch.py b/addons/inline/xdasearch.py new file mode 100644 index 0000000..42a3bdc --- /dev/null +++ b/addons/inline/xdasearch.py @@ -0,0 +1,66 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# + +import re +from bs4 import BeautifulSoup as bs +from telethon.tl.types import InputWebDocument as wb +from . import get_string, async_searcher, in_pattern, InlinePlugin, asst + +__doc__ = f""" +โœ˜ Commands Available - + +โ€ข `@{asst.username} xda ` + Searches for the query on XDA Developers and returns the results. +""" + +# Inspired by @FindXDaBot + +@in_pattern("xda", owner=True) +async def xda_dev(event): + QUERY = event.text.split(maxsplit=1) + try: + query = QUERY[1] + except IndexError: + await event.answer( + [], switch_pm=get_string("instu_3"), switch_pm_param="start" + ) + return + le = "https://www.xda-developers.com/search/?q=" + query.replace(" ", "+") + ct = await async_searcher(le, re_content=True) + ml = bs(ct, "html.parser", from_encoding="utf-8") + cards = ml.find_all("div", class_="display-card") + out = [] + for card in cards: + # Title and URL + title_tag = card.find("h5", class_="display-card-title") + a_tag = title_tag.find("a") if title_tag else None + title = a_tag.get("title") or a_tag.text.strip() if a_tag else "No Title" + href = a_tag.get("href") if a_tag else "" + if href and href.startswith("/"): + href = "https://www.xda-developers.com" + href + + # Description + desc_tag = card.find("p", class_="display-card-excerpt") + desc = desc_tag.text.strip() if desc_tag else "" + + # Thumbnail + img_tag = card.find("img") + thumb = img_tag.get("data-img-url") or img_tag.get("src") if img_tag else None + if thumb: + thumb = wb(thumb, 0, "image/jpeg", []) + + text = f"[{title}]({href})" + out.append( + await event.builder.article( + title=title, description=desc, url=href, thumb=thumb, text=text + ) + ) + uppar = "|| XDA Search Results ||" if out else "No Results Found :(" + await event.answer(out, switch_pm=uppar, switch_pm_param="start") + + +InlinePlugin.update({"Search on XDA": "xda telegram"}) \ No newline at end of file diff --git a/addons/inlinefun.py b/addons/inlinefun.py new file mode 100644 index 0000000..abd0f1a --- /dev/null +++ b/addons/inlinefun.py @@ -0,0 +1,136 @@ +# +# Ultroid - UserBot +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +# .tweet made for ultroid + +# .uta ported from Dark-Cobra + +""" +โœ˜ Commands Available - + +โ€ข `{i}uta ` + Inline song search and downloader. + +โ€ข `{i}gglax ` + Create google search sticker with text. + +โ€ข `{i}stic ` + Get random stickers from emoji. + +โ€ข `{i}frog ` + make text stickers. + +โ€ข `{i}tweet ` + make twitter posts. + +โ€ข `{i}quot ` + write quote on animated sticker. +""" + +from random import choice + +from addons.waifu import deEmojify + +from . import ultroid_cmd, get_string + + +@ultroid_cmd(pattern="tweet ?(.*)") +async def tweet(e): + wai = await e.eor() + text = e.pattern_match.group(1) + if not text: + return await wai.edit("`Give me Some Text !`") + try: + results = await e.client.inline_query("twitterstatusbot", text) + await e.reply("New Tweet", file=results[0].document) + await wai.delete() + except Exception as m: + await e.eor(str(m)) + + +@ultroid_cmd(pattern="stic ?(.*)") +async def tweet(e): + if len(e.text) > 5 and e.text[5] != " ": + return + wai = await e.eor(get_string("com_1")) + text = e.pattern_match.group(1) + if not text: + return await wai.edit("`Give me Some Emoji !`") + results = await e.client.inline_query("sticker", text) + num = choice(results) + await e.reply("@sticker", file=num.document) + await wai.delete() + + +@ultroid_cmd(pattern="gglax ?(.*)") +async def gglax_sticker(e): + wai = await e.eor(get_string("com_1")) + text = e.pattern_match.group(1) + if not text: + return await wai.edit("`Give me Some Text !`") + try: + results = await e.client.inline_query("googlaxbot", text) + await e.reply("Googlax", file=results[0].document) + await wai.delete() + except Exception as m: + await e.eor(str(m)) + + +@ultroid_cmd(pattern="frog ?(.*)") +async def honkasays(e): + wai = await e.eor(get_string("com_1")) + text = e.pattern_match.group(1) + if not text: + return await wai.edit("`Give Me Some Text !`") + text = deEmojify(text) + if not text.endswith("."): + text += "." + if len(text) <= 9: + q = 2 + elif len(text) >= 14: + q = 0 + else: + q = 1 + try: + res = await e.client.inline_query("honka_says_bot", text) + await e.reply("Honka", file=res[q].document) + await wai.delete() + except Exception as er: + await wai.edit(str(er)) + + +@ultroid_cmd(pattern="uta ?(.*)") +async def nope(doit): + ok = doit.pattern_match.group(1) + replied = await doit.get_reply_message() + a = await doit.eor(get_string("com_1")) + if ok: + pass + elif replied and replied.message: + ok = replied.message + else: + return await doit.eor( + "`Sir please give some query to search and download it for you..!`", + ) + sticcers = await doit.client.inline_query("Lybot", f"{(deEmojify(ok))}") + await doit.reply(file=sticcers[0].document) + await a.delete() + + +@ultroid_cmd(pattern="quot ?(.*)") +async def quote_(event): + IFUZI = event.pattern_match.group(1) + if "quotly" in event.text: + return + if not IFUZI: + return await event.eor("`Give some text to make Quote..`") + EI_IR = await event.eor(get_string("com_1")) + try: + RE_ZK = await event.client.inline_query("@QuotAfBot", IFUZI) + await event.reply(file=choice(RE_ZK).document) + except Exception as U_TG: + return await EI_IR.edit(str(U_TG)) + await EI_IR.delete() diff --git a/addons/limited.py b/addons/limited.py new file mode 100644 index 0000000..3a5edff --- /dev/null +++ b/addons/limited.py @@ -0,0 +1,32 @@ +# inspired from bin.py which was made by @danish_00 +# written by @senku_ishigamiii/@Uzumaki_Naruto_XD + +""" +โœ˜ Commands Available - + +โ€ข `{i}limited` + Check you are limited or not ! +""" + +from telethon import events +from telethon.errors.rpcerrorlist import YouBlockedUserError + +from . import ultroid_cmd + + +@ultroid_cmd(pattern="limited$") +async def demn(ult): + chat = "@SpamBot" + msg = await ult.eor("Checking If You Are Limited...") + async with ult.client.conversation(chat) as conv: + try: + response = conv.wait_event( + events.NewMessage(incoming=True, from_users=178220800) + ) + await conv.send_message("/start") + response = await response + await ult.client.send_read_acknowledge(chat) + except YouBlockedUserError: + await msg.edit("Boss! Please Unblock @SpamBot ") + return + await msg.edit(f"~ {response.message.message}") diff --git a/addons/locks.py b/addons/locks.py new file mode 100644 index 0000000..edbdc6b --- /dev/null +++ b/addons/locks.py @@ -0,0 +1,39 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available - + +โ€ข `{i}lock ` + Lock the Used Setting in Used Group. + +โ€ข `{i}unlock ` + UNLOCK the Used Setting in Used Group. +""" +from telethon.tl.functions.messages import EditChatDefaultBannedRightsRequest + +from pyUltroid.fns.admins import lock_unlock + +from . import ultroid_cmd + + +@ultroid_cmd( + pattern="(un|)lock( (.*)|$)", admins_only=True, manager=True, require="change_info" +) +async def un_lock(e): + mat = e.pattern_match.group(2).strip() + if not mat: + return await e.eor("`Give some Proper Input..`", time=5) + lock = e.pattern_match.group(1) == "" + ml = lock_unlock(mat, lock) + if not ml: + return await e.eor("`Incorrect Input`", time=5) + msg = "Locked" if lock else "Unlocked" + try: + await e.client(EditChatDefaultBannedRightsRequest(e.chat_id, ml)) + except Exception as er: + return await e.eor(str(er)) + await e.eor(f"**{msg}** - `{mat}` ! ") diff --git a/addons/logo.py b/addons/logo.py new file mode 100644 index 0000000..551104f --- /dev/null +++ b/addons/logo.py @@ -0,0 +1,101 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available - + +โ€ข `{i}logo ` + Generate a logo of the given Text + Or Reply To image , to write ur text on it. + Or Reply To Font File, To write with that font. + +""" +import glob +import os +import random + +from telethon.tl.types import InputMessagesFilterPhotos + +try: + from PIL import Image +except ImportError: + Image = None +from pyUltroid.fns.misc import unsplashsearch +from pyUltroid.fns.tools import LogoHelper + +from . import OWNER_ID, OWNER_NAME, download_file, get_string, mediainfo, ultroid_cmd + + +@ultroid_cmd(pattern="logo( (.*)|$)") +async def logo_gen(event): + xx = await event.eor(get_string("com_1")) + name = event.pattern_match.group(1).strip() + if not name: + return await xx.eor("`Give a name too!`", time=5) + bg_, font_ = None, None + if event.reply_to_msg_id: + temp = await event.get_reply_message() + if temp.media: + if hasattr(temp.media, "document") and ( + ("font" in temp.file.mime_type) + or (".ttf" in temp.file.name) + or (".otf" in temp.file.name) + ): + font_ = await temp.download_media("resources/fonts/") + elif "pic" in mediainfo(temp.media): + bg_ = await temp.download_media() + if not bg_: + SRCH = [ + "background", + "neon", + "anime", + "art", + "bridges", + "streets", + "computer", + "cyberpunk", + "nature", + "abstract", + "exoplanet", + "magic", + "3d render", + ] + res = await unsplashsearch(random.choice(SRCH), limit=1) + bg_, _ = await download_file(res[0], "resources/downloads/logo.png") + newimg = "resources/downloads/unsplash-temp.jpg" + img_ = Image.open(bg_) + img_.save(newimg) + os.remove(bg_) + bg_ = newimg + + if not font_: + fpath_ = glob.glob("resources/fonts/*") + font_ = random.choice(fpath_) + if len(name) <= 8: + strke = 10 + elif len(name) >= 9: + strke = 5 + else: + strke = 20 + name = LogoHelper.make_logo( + bg_, + name, + font_, + fill="white", + stroke_width=strke, + stroke_fill="black", + ) + await xx.edit("`Done!`") + await event.client.send_file( + event.chat_id, + file=name, + caption=f"Logo by [{OWNER_NAME}](tg://user?id={OWNER_ID})", + force_document=True, + ) + os.remove(name) + await xx.delete() + if os.path.exists(bg_): + os.remove(bg_) diff --git a/addons/memify.py b/addons/memify.py new file mode 100644 index 0000000..82beda2 --- /dev/null +++ b/addons/memify.py @@ -0,0 +1,339 @@ +# Ported Nd Modified For Ultroid +# Ported From DarkCobra (Modified by @ProgrammingError) +# +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available - + +โ€ข `{i}mmf ; ` + To create memes as sticker, + for trying different fonts use (.mmf _1)(u can use 1 to 10). + +โ€ข `{i}mms ; ` + To create memes as pic, + for trying different fonts use (.mms _1)(u can use 1 to 10). + +""" + +import asyncio +import os +import textwrap + +import cv2 +from PIL import Image, ImageDraw, ImageFont + +from . import * + + +@ultroid_cmd(pattern="mmf ?(.*)") +async def ultd(event): + ureply = await event.get_reply_message() + msg = event.pattern_match.group(1) + if not (ureply and (ureply.media)): + xx = await event.eor("`Reply to any media`") + return + if not msg: + xx = await event.eor("`Give me something text to write...`") + return + ultt = await ureply.download_media() + if ultt.endswith((".tgs")): + xx = await event.eor("`Ooo Animated Sticker ๐Ÿ‘€...`") + cmd = ["lottie_convert.py", ultt, "ult.png"] + file = "ult.png" + process = await asyncio.create_subprocess_exec( + *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await process.communicate() + stderr.decode().strip() + stdout.decode().strip() + elif ultt.endswith((".webp", ".png")): + xx = await event.eor("`Processing`") + im = Image.open(ultt) + im.save("ult.png", format="PNG", optimize=True) + file = "ult.png" + else: + xx = await event.eor("`Processing`") + img = cv2.VideoCapture(ultt) + heh, lol = img.read() + cv2.imwrite("ult.png", lol) + file = "ult.png" + stick = await draw_meme_text(file, msg) + await event.client.send_file( + event.chat_id, stick, force_document=False, reply_to=event.reply_to_msg_id + ) + await xx.delete() + try: + os.remove(ultt) + os.remove(file) + os.remove(stick) + except BaseException: + pass + + +async def draw_meme_text(image_path, msg): + img = Image.open(image_path) + os.remove(image_path) + i_width, i_height = img.size + if "_" in msg: + text, font = msg.split("_") + else: + text = msg + font = "default" + if ";" in text: + upper_text, lower_text = text.split(";") + else: + upper_text = text + lower_text = "" + draw = ImageDraw.Draw(img) + m_font = ImageFont.truetype( + f"resources/fonts/{font}.ttf", int((70 / 640) * i_width) + ) + current_h, pad = 10, 5 + if upper_text: + for u_text in textwrap.wrap(upper_text, width=15): + bbox = draw.textbbox((0, 0), u_text, font=m_font) + u_width, u_height = bbox[2] - bbox[0], bbox[3] - bbox[1] + draw.text( + xy=(((i_width - u_width) / 2) - 1, int((current_h / 640) * i_width)), + text=u_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=(((i_width - u_width) / 2) + 1, int((current_h / 640) * i_width)), + text=u_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=((i_width - u_width) / 2, int(((current_h / 640) * i_width)) - 1), + text=u_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=(((i_width - u_width) / 2), int(((current_h / 640) * i_width)) + 1), + text=u_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=((i_width - u_width) / 2, int((current_h / 640) * i_width)), + text=u_text, + font=m_font, + fill=(255, 255, 255), + ) + current_h += u_height + pad + if lower_text: + for l_text in textwrap.wrap(lower_text, width=15): + bbox = draw.textbbox((0, 0), l_text, font=m_font) + u_width, u_height = bbox[2] - bbox[0], bbox[3] - bbox[1] + draw.text( + xy=( + ((i_width - u_width) / 2) - 1, + i_height - u_height - int((80 / 640) * i_width), + ), + text=l_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=( + ((i_width - u_width) / 2) + 1, + i_height - u_height - int((80 / 640) * i_width), + ), + text=l_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=( + (i_width - u_width) / 2, + (i_height - u_height - int((80 / 640) * i_width)) - 1, + ), + text=l_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=( + (i_width - u_width) / 2, + (i_height - u_height - int((80 / 640) * i_width)) + 1, + ), + text=l_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=( + (i_width - u_width) / 2, + i_height - u_height - int((80 / 640) * i_width), + ), + text=l_text, + font=m_font, + fill=(255, 255, 255), + ) + current_h += u_height + pad + imag = "ultt.webp" + img.save(imag, "WebP") + return imag + + +@ultroid_cmd(pattern="mms ?(.*)") +async def mms(event): + ureply = await event.get_reply_message() + msg = event.pattern_match.group(1) + if not (ureply and (ureply.media)): + xx = await event.eor("`Reply to any media`") + return + if not msg: + xx = await event.eor("`Give me something text to write ๐Ÿ˜‘`") + return + ultt = await ureply.download_media() + if ultt.endswith((".tgs")): + xx = await event.eor("`Ooo Animated Sticker ๐Ÿ‘€...`") + cmd = ["lottie_convert.py", ultt, "ult.png"] + file = "ult.png" + process = await asyncio.create_subprocess_exec( + *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await process.communicate() + stderr.decode().strip() + stdout.decode().strip() + elif ultt.endswith((".webp", ".png")): + xx = await event.eor("`Processing`") + im = Image.open(ultt) + im.save("ult.png", format="PNG", optimize=True) + file = "ult.png" + else: + xx = await event.eor("`Processing`") + img = cv2.VideoCapture(ultt) + heh, lol = img.read() + cv2.imwrite("ult.png", lol) + file = "ult.png" + pic = await draw_meme(file, msg) + await event.client.send_file( + event.chat_id, pic, force_document=False, reply_to=event.reply_to_msg_id + ) + await xx.delete() + try: + os.remove(ultt) + os.remove(file) + except BaseException: + pass + os.remove(pic) + + +async def draw_meme(image_path, msg): + img = Image.open(image_path) + os.remove(image_path) + i_width, i_height = img.size + if "_" in msg: + text, font = msg.split("_") + else: + text = msg + font = "default" + if ";" in text: + upper_text, lower_text = text.split(";") + else: + upper_text = text + lower_text = "" + draw = ImageDraw.Draw(img) + m_font = ImageFont.truetype( + f"resources/fonts/{font}.ttf", int((70 / 640) * i_width) + ) + current_h, pad = 10, 5 + if upper_text: + for u_text in textwrap.wrap(upper_text, width=15): + bbox = draw.textbbox((0, 0), u_text, font=m_font) + u_width, u_height = bbox[2] - bbox[0], bbox[3] - bbox[1] + draw.text( + xy=(((i_width - u_width) / 2) - 1, int((current_h / 640) * i_width)), + text=u_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=(((i_width - u_width) / 2) + 1, int((current_h / 640) * i_width)), + text=u_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=((i_width - u_width) / 2, int(((current_h / 640) * i_width)) - 1), + text=u_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=(((i_width - u_width) / 2), int(((current_h / 640) * i_width)) + 1), + text=u_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=((i_width - u_width) / 2, int((current_h / 640) * i_width)), + text=u_text, + font=m_font, + fill=(255, 255, 255), + ) + current_h += u_height + pad + if lower_text: + for l_text in textwrap.wrap(lower_text, width=15): + bbox = draw.textbbox((0, 0), l_text, font=m_font) + u_width, u_height = bbox[2] - bbox[0], bbox[3] - bbox[1] + draw.text( + xy=( + ((i_width - u_width) / 2) - 1, + i_height - u_height - int((20 / 640) * i_width), + ), + text=l_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=( + ((i_width - u_width) / 2) + 1, + i_height - u_height - int((20 / 640) * i_width), + ), + text=l_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=( + (i_width - u_width) / 2, + (i_height - u_height - int((20 / 640) * i_width)) - 1, + ), + text=l_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=( + (i_width - u_width) / 2, + (i_height - u_height - int((20 / 640) * i_width)) + 1, + ), + text=l_text, + font=m_font, + fill=(0, 0, 0), + ) + draw.text( + xy=( + (i_width - u_width) / 2, + i_height - u_height - int((20 / 640) * i_width), + ), + text=l_text, + font=m_font, + fill=(255, 255, 255), + ) + current_h += u_height + pad + pics = "ultt.png" + img.save(pics, "png") + return pics \ No newline at end of file diff --git a/addons/misc.py b/addons/misc.py new file mode 100644 index 0000000..e82b670 --- /dev/null +++ b/addons/misc.py @@ -0,0 +1,140 @@ +# Ultroid - UserBot +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available - + +โ€ข `{i}eod` + `Get Event of the Today` + +โ€ข `{i}pntrst ` + Download and send pinterest pins + +โ€ข `{i}gadget ` + Gadget Search from Telegram. + +โ€ข `{i}randomuser` + Generate details about a random user. + +โ€ข `{i}ascii ` + Convert replied image into html. +""" + +import os +from datetime import datetime as dt + +from bs4 import BeautifulSoup as bs + +try: + from htmlwebshot import WebShot +except ImportError: + WebShot = None +try: + from img2html.converter import Img2HTMLConverter +except ImportError: + Img2HTMLConverter = None + +from . import async_searcher, get_random_user_data, get_string, re, ultroid_cmd + + +@ultroid_cmd(pattern="eod$") +async def diela(e): + m = await e.eor(get_string("com_1")) + li = "https://daysoftheyear.com" + te = "๐ŸŽŠ **Events of the Day**\n\n" + da = dt.now() + month = da.strftime("%b") + li += f"/days/{month}/" + da.strftime("%F").split("-")[2] + ct = await async_searcher(li, re_content=True) + bt = bs(ct, "html.parser", from_encoding="utf-8") + ml = bt.find_all("a", "js-link-target", href=re.compile("daysoftheyear.com/days")) + for eve in ml[:5]: + te += f'โ€ข [{eve.text}]({eve["href"]})\n' + await m.edit(te, link_preview=False) + + +@ultroid_cmd( + pattern="pntrst( (.*)|$)", +) +async def pinterest(e): + m = e.pattern_match.group(1).strip() + if not m: + return await e.eor("`Give pinterest link.`", time=3) + soup = await async_searcher( + "https://www.expertstool.com/download-pinterest-video/", + data={"url": m}, + post=True, + ) + try: + _soup = bs(soup, "html.parser").find("table").tbody.find_all("tr") + except BaseException: + return await e.eor("`Wrong link or private pin.`", time=5) + file = _soup[1] if len(_soup) > 1 else _soup[0] + file = file.td.a["href"] + await e.client.send_file(e.chat_id, file, caption=f"Pin:- {m}") + + +@ultroid_cmd(pattern="gadget( (.*)|$)") +async def mobs(e): + mat = e.pattern_match.group(1).strip() + if not mat: + await e.eor("Please Give a Mobile Name to look for.") + query = mat.replace(" ", "%20") + jwala = f"https://gadgets.ndtv.com/search?searchtext={query}" + c = await async_searcher(jwala) + b = bs(c, "html.parser", from_encoding="utf-8") + co = b.find_all("div", "rvw-imgbox") + if not co: + return await e.eor("No Results Found!") + bt = await e.eor(get_string("com_1")) + out = "**๐Ÿ“ฑ Mobile / Gadgets Search**\n\n" + li = co[0].find("a") + imu, title = None, li.find("img")["title"] + cont = await async_searcher(li["href"]) + nu = bs(cont, "html.parser", from_encoding="utf-8") + req = nu.find_all("div", "_pdsd") + imu = nu.find_all( + "img", src=re.compile("https://i.gadgets360cdn.com/products/large/") + ) + if imu: + imu = imu[0]["src"].split("?")[0] + "?downsize=*:420&output-quality=80" + out += f"โ˜‘๏ธ **[{title}]({li['href']})**\n\n" + for fp in req: + ty = fp.findNext() + out += f"- **{ty.text}** - `{ty.findNext().text}`\n" + out += "_" + if imu == []: + imu = None + await e.reply(out, file=imu, link_preview=False) + await bt.delete() + + +@ultroid_cmd(pattern="randomuser") +async def _gen_data(event): + x = await event.eor(get_string("com_1")) + msg, pic = await get_random_user_data() + await event.reply(file=pic, message=msg) + await x.delete() + + +@ultroid_cmd( + pattern="ascii( (.*)|$)", +) +async def _(e): + if not Img2HTMLConverter: + return await e.eor("'img2html-converter' not installed!") + if not e.reply_to_msg_id: + return await e.eor(get_string("ascii_1")) + m = await e.eor(get_string("ascii_2")) + img = await (await e.get_reply_message()).download_media() + char = e.pattern_match.group(1).strip() or "โ– " + converter = Img2HTMLConverter(char=char) + html = converter.convert(img) + shot = WebShot(quality=85) + pic = await shot.create_pic_async(html=html) + await m.delete() + await e.reply(file=pic) + os.remove(pic) + os.remove(img) diff --git a/addons/morsecode.py b/addons/morsecode.py new file mode 100644 index 0000000..84139a9 --- /dev/null +++ b/addons/morsecode.py @@ -0,0 +1,38 @@ +# Ultroid - UserBot +# +# This file is a part of < https://github.com/TeamUltroid/UltroidAddons/ > +# PLease read the GNU Affero General Public License in +# . + +""" +โœ˜ Commands Available - + +โ€ข `{i}mencode ` + Encode the given text to Morse Code. + +โ€ข `{i}mdecode ` + Decode the given text from Morse Code. +""" + +from . import async_searcher, ultroid_cmd, get_string + +@ultroid_cmd(pattern="mencode ?(.*)") +async def mencode(event): + msg = await event.eor(get_string("com_1")) + text = event.pattern_match.group(1) + if not text: + return msg.edit("Please give a text!") + base_url = "https://apis.xditya.me/morse/encode?text=" + text + encoded = await async_searcher(base_url, re_content=False) + await msg.edit("**Encoded.**\n\n**Morse Code:** `{}`".format(encoded)) + + +@ultroid_cmd(pattern="mdecode ?(.*)") +async def mencode(event): + msg = await event.eor(get_string("com_1")) + text = event.pattern_match.group(1) + if not text: + return await msg.edit("Please give a text!") + base_url = "https://apis.xditya.me/morse/decode?text=" + text + encoded = await async_searcher(base_url, re_content=False) + await msg.edit("**Decoded.**\n\n**Message:** `{}`".format(encoded)) \ No newline at end of file diff --git a/addons/mute.py b/addons/mute.py new file mode 100644 index 0000000..f183a5b --- /dev/null +++ b/addons/mute.py @@ -0,0 +1,235 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +โœ˜ Commands Available - + +โ€ข `{i}mute ` + Mute user in current chat. + +โ€ข `{i}unmute ` + Unmute user in current chat. + +โ€ข `{i}dmute ` + Mute user in current chat by deleting msgs. + +โ€ข `{i}undmute ` + Unmute dmuted user in current chat. + +โ€ข `{i}tmute