[
  {
    "path": "Dockerfile",
    "content": "FROM python:3.11-alpine\n\nCOPY . .\nRUN python setup.py install\n\nENTRYPOINT [ \"python3\",\"/cli/chiasmodon_cli.py\" ]"
  },
  {
    "path": "LICENSE.txt",
    "content": "MIT License\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE."
  },
  {
    "path": "README.md",
    "content": "\r\n# Chiasmodon\r\n\r\n[![asciicast](https://asciinema.org/a/QrEtBLFMQrjU1sjRjcgTdo41m.svg)](https://asciinema.org/a/QrEtBLFMQrjU1sjRjcgTdo41m)\r\n<p align=\"center\">\r\n<img src=\"https://badge.fury.io/py/chiasmodon.svg\" />\r\n</p>\r\nChiasmodon is an OSINT tool that allows users to gather information from various sources and conduct targeted searches based on domains, Google Play applications, email addresses, IP addresses, organizations, URLs, and more. It provides comprehensive scanning capabilities, customizable output formats, and additional options for enhanced data analysis and customization.\r\n\r\n\r\n## ✨Features\r\n\r\n- [x] **🌐Domain**: Conduct targeted searches by specifying a domain name to gather relevant information related to the domain.\r\n- [x] **🎮Google Play Application**: Search for information related to a specific application on the Google Play Store by providing the application ID.\r\n- [x] **✉️Email, 👤Username, 🔒Password**: Conduct searches based on email, username, or password to identify potential security risks or compromised credentials.\r\n- [x] **🔍 IP Address**: Perform searches using an IP address to gather information such as geolocation, associated domain names, and historical data.\r\n- [x] **🌍 CIDR**: Search for information related to a specified CIDR (Classless Inter-Domain Routing) block, including IP range details and associated networks.\r\n- [x] **🔢 ASN**: Retrieve information about an Autonomous System Number (ASN), including its owner, associated IP ranges, and network details.\r\n- [x] **🔌 Port**: Search for information about a specific port number, including its common usage, associated services, and potential vulnerabilities.\r\n- [x] **🌐 ISP**: Conduct searches based on an Internet Service Provider (ISP) name to gather information about the ISP, its services, and associated IP ranges.\r\n- [x] **🏢 Organization (ORG)**: Search for information related to a specific organization or company, including its contact details, associated domains, and network infrastructure.\r\n- [x] **🔗 URL Path**: Perform searches based on a specific URL path to gather information about the path, its content, and potential security risks.\r\n- [x] **📞 Phone**: Conduct searches using a phone number to gather information such as the associated owner, location, and any available public records.\r\n- [x] **🔍Scan**: Perform a comprehensive scan on a given company domain name in one click, including finding\r\n  - Related companies.\r\n  - App applications.\r\n  - Ips (`Port, Org, Isp, Asn`).\r\n  - Subdomains.\r\n  - Client credentials (`Email, Username, Password`).\r\n  - Employee credentials (`Email, Username, Password`)\r\n  - URLs (`Domain/IP, Port, Endpoint`)\r\n\r\n- [X] **🌍Country**: Sort and filter search results by country to gain insights into the geographic distribution of the identified information.\r\n- [x] **📋Output Customization**: Choose the desired output format (text, JSON, or CSV) and specify the filename to save the search results.\r\n- [x] **⚙️Additional Options**: The tool offers various additional options, such as viewing different result types (credentials, URLs, subdomains, emails, passwords, usernames, or applications), setting API tokens, specifying timeouts, limiting results, and more.\r\n\r\n## 🚀Comming soon\r\n\r\n- **🏢Company Name**: We understand the importance of comprehensive company research. In our upcoming release, you'll be able to search by company name and access a wide range of documents associated with that company. This feature will provide you with a convenient and efficient way to gather crucial information, such as legal documents, financial reports, and other relevant records.\r\n\r\n- **👤Face (Photo)**: Visual data is a powerful tool, and we are excited to introduce our advanced facial recognition feature. With \"Search by Face (Photo),\" you can upload an image containing a face and leverage cutting-edge technology to identify and match individuals across various data sources. This will allow you to gather valuable information, such as social media profiles, online presence, and potential connections, all through the power of facial recognition.\r\n\r\n## Why Chiasmodon name ?\r\nChiasmodon niger is a species of deep sea fish in the family Chiasmodontidae. It is known for its ability to **swallow fish larger than itself**. and so do we. 😉\r\n![Chiasmodon background](https://journal.voca.network/wp-content/uploads/2017/10/DTR083_1200.png)\r\n\r\n## 🔑 Subscription\r\nJoin us today and unlock the potential of our cutting-edge OSINT tool. Contact https://t.me/Chiasmod0n on Telegram to subscribe and start harnessing the power of Chiasmodon for your domain investigations.\r\n\r\n## ⬇️Install\r\n```bash\r\n$ pip install chiasmodon\r\n```\r\nOnly for linux 👇 \r\n```bash\r\n$ activate-global-python-argcomplete\r\n```\r\n## 💻Usage\r\nChiasmodon provides a flexible and user-friendly command-line interface and python library. Here are some examples to demonstrate its usage:\r\n\r\n\r\n```\r\nusage: chiasmodon_cli.py [-h]\r\n                         [-m {cred.username,cred.password,cred.email,cred.phone,cred.email.domain,cred.country,domain,domain.all,ip,ip.asn,ip.isp,ip.org,ip.port,ip.country,app.id,app.name,app.domain,url.path,url.port}]\r\n                         [-vt {full,cred,url,email,phone,password,username,app,domain,ip,related,subdomain}] [-s] [-sr SCAN_RELATED]\r\n                         [-ss SCAN_SUBDOMAINS] [-sa SCAN_APPS] [-si SCAN_IPS] [-sc SCAN_CLIENTS] [-se SCAN_EMPLOYEES] [-o OUTPUT]\r\n                         [-ot {text,json,csv}] [-t TIMEOUT] [-l LIMIT] [-nc] [-lv] [-lm] [--init INIT] [-v]\r\n                         query\r\n\r\nChiasmodon CLI\r\n\r\npositional arguments:\r\n  query                 query argument\r\n\r\noptions:\r\n  -h, --help            show this help message and exit\r\n  -m {cred.username,cred.password,cred.email,cred.phone,cred.email.domain,cred.country,domain,domain.all,ip,ip.asn,ip.isp,ip.org,ip.port,ip.country,app.id,app.name,app.domain,url.path,url.port}, --method {cred.username,cred.password,cred.email,cred.phone,cred.email.domain,cred.country,domain,domain.all,ip,ip.asn,ip.isp,ip.org,ip.port,ip.country,app.id,app.name,app.domain,url.path,url.port}\r\n                        method to search by it,default is \"domain\".\r\n  -vt {full,cred,url,email,phone,password,username,app,domain,ip,related,subdomain}, --view-type {full,cred,url,email,phone,password,username,app,domain,ip,related,subdomain}\r\n                        type view the result default is \"full\".\r\n  -s, --scan            scan the company domain (Related company, Clients, Employees, Company ASNs, Company Apps).\r\n  -sr SCAN_RELATED, --scan-related SCAN_RELATED\r\n                        Run related scan, default is yes, Ex: -sr no\r\n  -ss SCAN_SUBDOMAINS, --scan-subdomains SCAN_SUBDOMAINS\r\n                        Run subdomains scan, default is yes, Ex: -ss no\r\n  -sa SCAN_APPS, --scan-apps SCAN_APPS\r\n                        Run App scan, default is yes, Ex: -sa no\r\n  -si SCAN_IPS, --scan-ips SCAN_IPS\r\n                        Run IPs scan, default is yes, Ex: -si no\r\n  -sc SCAN_CLIENTS, --scan-clients SCAN_CLIENTS\r\n                        Run clients scan, default is yes, Ex: -sc no\r\n  -se SCAN_EMPLOYEES, --scan-employees SCAN_EMPLOYEES\r\n                        Run employees scan, default is yes, Ex: -se no\r\n  -o OUTPUT, --output OUTPUT\r\n                        filename to save the result\r\n  -ot {text,json,csv}, --output-type {text,json,csv}\r\n                        output format default is \"text\".\r\n  -t TIMEOUT, --timeout TIMEOUT\r\n                        request timeout default is 360 sec.\r\n  -l LIMIT, --limit LIMIT\r\n                        limit results default is 10000.\r\n  -nc, --no-color       show result without color.\r\n  -lv, --list-view-type\r\n                        list view type.\r\n  -lm, --list-methods   list methods.\r\n  --init INIT           set the api token.\r\n  -v, --version         version.\r\n```\r\n\r\nExamples:\r\n```\r\n# Scan company by domain\r\nchiasmodon_cli.py example.com --scan\r\n\r\n# Search for target domain, you will see the result for only this \"example.com\" \r\nchiasmodon_cli.py example.com \r\n    \r\n# Search in target and target subdomains\r\nchiasmodon_cli.py example.com --method domain.all\r\n\r\n# Search for target subdomains\r\nchiasmodon_cli.py example.com --view-type subdomain\r\n        \r\n# Search for all creds in United States \r\nchiasmodon_cli.py US --method cred.country\r\n\r\n# Search for related companies by domain\r\nchiasmodon_cli.py example.com --view-type related\r\n\r\n# search for target app id \r\nchiasmodon_cli.py com.discord --method app.id \r\n    \r\n# search for target app domain \r\nchiasmodon_cli.py discord.com --method app.domain\r\n    \r\n# search for target app name \r\nchiasmodon_cli.py Discord --method app.name\r\n    \r\n# Search for ip asn\r\nchiasmodon_cli.py AS123 --method ip.asn\r\n\r\n# Search for cred username\r\nchiasmodon_cli.py someone --method cred.username\r\n\r\n# Search for cred password\r\nchiasmodon_cli.py example@123 --method cred.password\r\n\r\n# Search for url endpoint\r\nchiasmodon_cli.py /wp-login.php --method url.path\r\n\r\n# Search for ip\r\nchiasmodon_cli.py 1.1.1.1 --method ip\r\n\r\n# Search for cidr\r\nchiasmodon_cli.py xx.xx.xx.0/24 --method ip\r\n\r\n# Search for target creds by domain emsils\r\nchiasmodon_cli.py example.com --method cred.email.domain\r\n\r\n# Search for target email\r\nchiasmodon_cli.py someone@example.com --method cred.email  \r\n\r\n# search for multiple targets: \r\nchiasmodon_cli.py targets.txt --method domain  --output example-creds.txt \r\n```\r\n\r\nPlease note that these examples represent only a fraction of the available options and use cases. Refer to the documentation for more detailed instructions and explore the full range of features provided by Chiasmodon.\r\n\r\n\r\n## 💬 Contributions and Feedback\r\n\r\nContributions and feedback are welcome! If you encounter any issues or have suggestions for improvements, please submit them to the Chiasmodon GitHub repository. Your input will help us enhance the tool and make it more effective for the OSINT community.\r\n\r\n## 📜License\r\n\r\nChiasmodon is released under the [MIT License](https://opensource.org/licenses/MIT). See the [LICENSE](https://github.com/chiasmodon/LICENSE.txt) file for more details.\r\n\r\n## ⚠️Disclaimer\r\n\r\nChiasmodon is intended for legal and authorized use only. Users are responsible for ensuring compliance with applicable laws and regulations when using the tool. The developers of Chiasmodon disclaim any responsibility for the misuse or illegal use of the tool.\r\n\r\n## 📢Acknowledgments\r\n\r\nChiasmodon is the result of collaborative efforts from a dedicated team of contributors who believe in the power of OSINT. We would like to express our gratitude to the open-source community for their valuable contributions and support.\r\n\r\n## 🔗Chiasmodon Links\r\n\r\n- [🐍 Python Library](https://pypi.org/project/chiasmodon)\r\n- [📱 Mobile (APK)](https://github.com/chiasmod0n/chiasmodon-mobile)\r\n- [🌐 Website](http://chiasmodon.online)\r\n- [💬 Telegram](https://t.me/chiasmod0n)\r\n- [🐦 X/Twitter](https://x.com/chiasmod0n)\r\n\r\n\r\n## ⭐️Star History\r\n\r\n<a href=\"https://star-history.com/#chiasmod0n/chiasmodon&Date\">\r\n <picture>\r\n   <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/svg?repos=chiasmod0n/chiasmodon&type=Date&theme=dark\" />\r\n   <source media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/svg?repos=chiasmod0n/chiasmodon&type=Date\" />\r\n   <img alt=\"Star History Chart\" src=\"https://api.star-history.com/svg?repos=chiasmod0n/chiasmodon&type=Date\" />\r\n </picture>\r\n</a>\r\n"
  },
  {
    "path": "cli/chiasmodon_cli.py",
    "content": "#!/usr/bin/python3\n# PYTHON_ARGCOMPLETE_OK\n\nimport os\nimport sys\nimport argcomplete\nimport json\nimport argparse\nimport tldextract\nfrom yaspin import yaspin\nfrom pathlib import Path \nfrom pychiasmodon import Chiasmodon,Result,VERSION,VIEW_TYPE_LIST,T,_METHODS\n\nROOT_DIR = os.path.dirname(os.path.abspath(__file__))\n\nclass ULIT:\n    @staticmethod\n    def rFile(file:Path) -> str:\n        if not file.is_file():\n            print(f'{T.RED}Not found {file} file.{T.RESET}')\n            return\n\n        with open(file, 'r') as f:\n            return f.read()    \n\n    @staticmethod\n    def wFile(file:Path, data:str) -> str:\n        with open(file, 'w') as f:\n            f.write(data)\n\n    @staticmethod\n    def rFileToJson(file:Path) -> dict:\n        return json.loads(ULIT.rFile(file=file))\n\n    @staticmethod\n    def wJsonToFile(file:Path, data:dict) -> dict:\n        ULIT.wFile(\n            file=file,\n            data=json.dumps(data)\n        )\n\n    @staticmethod\n    def get_root_domain(d:str) -> str:\n        domain = d.split()[0]\n        x = tldextract.extract(domain)\n        if not x.suffix:\n            return None\n\n        return '{}.{}'.format(x.domain, x.suffix)\n\nclass Scan(Chiasmodon):\n    def __init__(self, options:argparse.Namespace) -> None:        \n        self.options :argparse.Namespace=options\n        self.result :list = []\n        conf_file :Path = Path(ROOT_DIR, 'conf.json')\n        token:str = ''\n        \n        if not conf_file.is_file():ULIT.wJsonToFile(conf_file, {})\n\n        if self.options.init:\n            token = self.options.init\n            ULIT.wJsonToFile(conf_file, {'token':self.options.init})\n\n        elif not conf_file.is_file():\n            ULIT.wJsonToFile(conf_file, {})\n            token = ''\n\n        else:\n            token = ULIT.rFileToJson(conf_file).get('token') or ''\n\n        super().__init__(\n            token=token,\n            conf_file=conf_file,\n            color=True if not self.options.no_color else False,\n            debug=True, \n            check_token=self.options.init,\n        )\n\n        if self.options.init:\n            sys.exit()\n        \n        self.scan_mode = True\n\n    def scan_callback(self,beta,ys):\n        self.print(beta.print(), ys)\n\n    def proc(self):\n        if not self.options.query:\n            self.print(f\"{T.RED}You can't run scan without company domain\\nPlease use (-d or --domain) to scan the domain{T.RESET}\")\n            sys.exit(0)\n        \n        domain = ULIT.get_root_domain(self.options.query)\n        if not domain:\n            self.print(f\"{T.RED}Wrong domain{T.RESET}\",)\n            sys.exit(0)\n\n        self.output_folder = Path(domain)\n        self.output_folder.mkdir(exist_ok=True, parents=True)\n\n        self.__scan(\n            domain=domain,\n        )\n\n\n    def __scan(self, domain):\n        status = False\n\n        print_output = f'{T.MAGENTA}>{T.RESET}{T.YELLOW} Saved output{T.RESET}: \\n'\n        output = {\n            'related':[],\n            'apps':[], \n            'client-creds':[],\n            'client-usernames':[],\n            'client-passwords':[],\n            'client-emails':[],\n            'employe-creds':[],\n            'employe-usernames':[],\n            'employe-passwords':[],\n            'employe-emails':[],\n            'subdomains':[],\n            'urls':[],\n            'endpoints':[],\n            'ports':[],\n\n        }\n        \n        if self.options.scan_related.lower() == 'yes':\n            related = self.search(\n                method='domain',\n                query=domain,\n                view_type='related',\n                sort=True ,\n                timeout=self.options.timeout,\n                limit=1000000,\n                callback_view_result=self.scan_callback,\n                yaspin=yaspin,\n                search_text=f'Find {T.GREEN+domain+T.RESET} related companies...',\n                err_text=f'Not found related !'\n            )\n\n\n            if related:\n                status = True\n                output['related'] = [i.save_format() for i in related]\n                ULIT.wFile((self.output_folder / 'related.txt'), '\\n'.join(output['related'])) \n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'related.txt')}{T.RESET}\\n\"\n            else:\n                self.print(f'{T.RED}💥  Not found related !{T.RESET}')\n            self.print(f'{T.MAGENTA}{\"-\"*30}{T.RESET}')\n        if self.options.scan_subdomains.lower() == 'yes':\n            subdomains = self.search(\n                method='domain',\n                query=domain,\n                view_type='subdomain',\n                sort=True ,\n                timeout=self.options.timeout,\n                limit=1000000,\n                callback_view_result=self.scan_callback,\n                yaspin=yaspin,\n                search_text=f'Find {T.GREEN+domain+T.RESET} subdomains...',\n                err_text=f'Not found subdomains !'\n            )\n\n\n            if subdomains:\n                status = True\n                output['subdomains'] = [i.save_format() for i in subdomains]\n                ULIT.wFile((self.output_folder / 'subdomains.txt'), '\\n'.join(output['subdomains'])) \n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'subdomains.txt')}{T.RESET}\\n\"\n            self.print(f'{T.MAGENTA}{\"-\"*30}{T.RESET}')\n            \n        if self.options.scan_apps.lower() == 'yes':\n            apps = self.search(\n                method='app.domain',\n                query=domain,\n                view_type='app',\n                sort=True ,\n                timeout=self.options.timeout,\n                limit=1000000,\n                callback_view_result=self.scan_callback,\n                yaspin=yaspin,\n                search_text=f'Find {T.GREEN+domain+T.RESET} Apps...',\n                err_text=f'Not found apps !'\n            )\n\n\n            if apps:\n                status = True\n                output['apps'] = [i.save_format() for i in apps]\n                ULIT.wFile((self.output_folder / 'apps.txt'), '\\n'.join(output['apps'])) \n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'apps.txt')}{T.RESET}\\n\"\n            self.print(f'{T.MAGENTA}{\"-\"*30}{T.RESET}')\n        if self.options.scan_ips.lower() == 'yes':\n            ips = self.search(\n                method='domain.all',\n                query=domain,\n                view_type='ip',\n                sort=True ,\n                timeout=self.options.timeout,\n                limit=1000000,\n                callback_view_result=self.scan_callback,\n                yaspin=yaspin,\n                search_text=f'Find {T.GREEN+domain+T.RESET} IPs...',\n                err_text=f'Not found ips !'\n            )\n\n\n            if ips:\n                status = True\n                output['ips'] = [i.save_format() for i in ips]\n                ULIT.wFile((self.output_folder / 'ips.txt'), '\\n'.join(output['ips'])) \n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'ips.txt')}{T.RESET}\\n\"\n                \n            self.print(f'{T.MAGENTA}{\"-\"*30}{T.RESET}')\n        if self.options.scan_clients.lower() == 'yes':\n            client_creds:list[Result] = self.search(\n                query=domain,\n                method='domain.all',\n                view_type='full',\n                sort=True ,\n                timeout=self.options.timeout,\n                limit=1000000,\n                callback_view_result=self.scan_callback,\n                yaspin=yaspin,\n                search_text=f'Find {T.GREEN+domain+T.RESET} client creds...',\n                err_text=f'Not found clients !'\n                \n            )\n        \n            if client_creds:\n                status = True\n                output['client-creds'] =[i.save_format() for i in client_creds]\n                ULIT.wFile((self.output_folder / 'client-creds.txt'), '\\n'.join([':'.join(i) for i in output['client-creds']]))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'client-creds.txt')}{T.RESET}\\n\"\n                \n                for i in client_creds:\n                    output['client-usernames'].append(i.credUsername) if i.credUsername and not i.credEmail  and '/' not in i.credUsername and  i.credUsername not in output['client-usernames']  else None\n                    output['client-passwords'].append(i.credPassword) if i.credPassword and i.credPassword not in output['client-passwords'] else None\n                    output['client-emails'].append(i.credEmail) if i.credEmail  and i.credEmail not in output['client-emails'] else None\n                    output['subdomains'].append(i.domain) if i.domain and i.domain not in output['subdomains'] and i.domain != domain else None\n                    output['urls'].append(i.url) if i.url and i.url not in output['urls'] else None\n                    output['endpoints'].append(i.urlPath) if i.urlPath and i.urlPath not in output['endpoints'] else None\n                    output['ports'].append(i.urlPort) if i.urlPort and i.urlPort not in output['ports'] else None\n                    \n                ULIT.wFile((self.output_folder / 'client-usernames.txt'), '\\n'.join(output['client-usernames']))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'client-usernames.txt')}{T.RESET}\\n\"\n                ULIT.wFile((self.output_folder / 'client-emails.txt'), '\\n'.join(output['client-emails']))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'client-emails.txt')}{T.RESET}\\n\"\n                ULIT.wFile((self.output_folder / 'client-passwords.txt'), '\\n'.join(output['client-passwords']))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'client-passwords.txt')}{T.RESET}\\n\"\n                ULIT.wFile((self.output_folder / 'endpoints.txt'), '\\n'.join(output['endpoints']))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'endpoints.txt')}{T.RESET}\\n\"\n                ULIT.wFile((self.output_folder / 'ports.txt'), '\\n'.join([f\"{i}\" for i in output['ports']]))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'ports.txt')}{T.RESET}\\n\"\n                ULIT.wFile((self.output_folder / 'subdomains.txt'), '\\n'.join(output['subdomains']))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'subdomains.txt')}{T.RESET}\\n\"\n                ULIT.wFile((self.output_folder / 'urls.txt'), '\\n'.join([f\"{i}\" for i in output['urls']]))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'urls.txt')}{T.RESET}\\n\"\n\n\n            self.print(f'{T.MAGENTA}{\"-\"*30}{T.RESET}')\n        if self.options.scan_employees.lower() == 'yes':\n            employe_creds = self.search(\n                query=domain,\n                method='cred.email.domain',\n                view_type='full',\n                sort=True,\n                timeout=self.options.timeout,\n                callback_view_result=self.scan_callback,\n                limit=1000000,\n                yaspin=yaspin,\n                search_text=f'Find {T.GREEN+domain+T.RESET} employees creds...',\n                err_text=f'Not found Employees!'\n            )\n\n            if employe_creds:\n                status = True\n                output['employe-creds'] =[i.save_format() for i in employe_creds]\n                ULIT.wFile((self.output_folder / 'employe-creds.txt'), '\\n'.join([':'.join(i) for i in output['employe-creds']]))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'employe-creds.txt')}{T.RESET}\\n\"\n                for i in employe_creds:\n                    output['employe-usernames'].append(i.credUsername) if i.credUsername and not i.credEmail and '/' not in i.credUsername and i.credUsername not in output['employe-usernames']  else None\n                    output['employe-passwords'].append(i.credPassword) if i.credPassword and i.credPassword not in output['employe-passwords'] else None\n                    output['employe-emails'].append(i.credEmail) if i.credEmail  and i.credEmail not in output['employe-emails'] else None\n                    \n                ULIT.wFile((self.output_folder / 'employe-usernames.txt'), '\\n'.join(output['employe-usernames']))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'employe-usernames.txt')}{T.RESET}\\n\"\n                ULIT.wFile((self.output_folder / 'employe-emails.txt'), '\\n'.join(output['employe-emails']))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'employe-emails.txt')}{T.RESET}\\n\"\n                ULIT.wFile((self.output_folder / 'employe-passwords.txt'), '\\n'.join(output['employe-passwords']))\n                print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'employe-passwords.txt')}{T.RESET}\\n\"\n        \n\n        if status:\n            ULIT.wJsonToFile((self.output_folder / 'scan.json'), output)\n            print_output += f\"\\t{T.MAGENTA}-{T.RESET} {T.BLUE}{(self.output_folder / 'scan.json')}{T.RESET}\"\n            self.print(print_output)\n        \nclass CLI(Chiasmodon):\n    def __init__(self, options:argparse.Namespace) -> None:\n\n        self.options :argparse.Namespace=options\n        self.result :list = []\n\n        conf_file :Path = Path(ROOT_DIR, 'conf.json')\n        token:str = '' \n        \n        if not conf_file.is_file():ULIT.wJsonToFile(conf_file, {})\n\n        if self.options.init:\n            token = self.options.init\n            ULIT.wJsonToFile(conf_file, {'token':self.options.init})\n\n        elif not conf_file.is_file():\n            ULIT.wJsonToFile(conf_file, {})\n            token = ''\n\n        else:\n            token = ULIT.rFileToJson(conf_file).get('token') or ''\n\n        super().__init__(\n            token=token,\n            conf_file=conf_file,\n            color=True if not self.options.no_color else False,\n            #debug=self.options.debug, \n            debug=True, \n            check_token=self.options.init,\n        )\n\n        if self.options.init:\n            sys.exit()\n\n    def review_results(self,\n                       beta:Result, \n                       ys=True,\n                    ) -> None:\n\n        if beta.save_format() not in self.result:\n            self.print(beta.print(), ys=ys)\n            self.result.append(beta.save_format())\n        \n    def save_result(self, view_type) -> None:\n\n        if self.options.output:\n\n            if self.options.output_type == \"text\":\n                if self.result and view_type != 'cred':\n                    self.result.remove(None) if None in self.result else None\n                \n                ULIT.wFile(\n                    self.options.output,\n                    '\\n'.join([':'.join(i) if type(i) == list else i for i in self.result]) \n                )\n\n            if self.options.output_type == \"csv\":\n                if self.result and view_type != 'cred':\n                    self.result.remove(None) if None in self.result else None\n                \n                ULIT.wFile(\n                    self.options.output,\n                    '\\n'.join([','.join(['url/app_id','user/email', 'password', 'country', 'date'])]+[','.join(i) if type(i) == list else i for i in self.result])  if view_type == 'cred' else  '\\n'.join([view_type]+[','.join(i) if type(i) == list else i for i in self.result]) \n                )\n\n            if self.options.output_type == \"json\":\n                ULIT.wJsonToFile(\n                    self.options.output,\n                    self.result\n                )\n\n\n    def proc(self):\n\n        query = ULIT.rFile(f).splitlines() if (f:=Path(self.options.query)).is_file() else [self.options.query.strip()] \n\n\n        for i in query:\n            self.search(\n                query=i,\n                method=self.options.method,\n                view_type=self.options.view_type,\n                limit=self.options.limit,\n                timeout=self.options.timeout,\n                sort=True,\n                yaspin=yaspin,\n                callback_view_result=self.review_results,\n            )\n\n        if self.options.output and self.result:\n            self.save_result(self.options.view_type)\n            self.print(f'{T.MAGENTA}>{T.RESET}{T.YELLOW} Saved output to {T.RESET}: {T.GREEN}{self.options.output}{T.RESET}')\n\n      \nif __name__ == \"__main__\":\n\n    if len(sys.argv) == 1 or '--help' in sys.argv or '-h' in sys.argv:\n        print(f\"\"\"\n   🙂           🙂                 \n  /|\\\\           /|\\\\               \n  /\\\\            /\\\\                                                                                   \n \\\\___/        \\\\___/                 🔑\n{T.BLUE}~^~^~^~^~^~^~^~^~^~^~^~^~{T.BLUE}~^~^~^~{T.GREEN}    {T.RESET}/|\\\\{T.GREEN}\n|\\\\   {T.YELLOW}\\\\\\\\\\\\\\\\{T.GREEN}__     {T.MAGENTA}Chiasmodon{T.RESET} {T.RED}{VERSION}{T.GREEN}    {T.RESET}/\\\\{T.GREEN}\n| \\\\_/    {T.RED}o{T.GREEN} \\\\    {T.CYAN}o{T.GREEN}                  {T.RESET}\\\\___/{T.GREEN}\n> _   {T.YELLOW}(({T.GREEN} <_  {T.CYAN}oo{T.GREEN}        \n| / \\\\__+___/        \n|/     |/           \n\n{T.MAGENTA}>{T.RESET} {T.YELLOW}Admin{T.RESET}: {T.GREEN}https://t.me/Chiasmod0n\n{T.RESET}\"\"\")\n    parser = argparse.ArgumentParser(description='Chiasmodon CLI',  formatter_class=argparse.RawTextHelpFormatter,)\n\n    if '-lm' not in sys.argv and '--list-methods' not in sys.argv and '-lv' not in sys.argv and '--list-view-type' not in sys.argv and '-v' not in sys.argv and '--version' not in sys.argv and '--init' not in sys.argv:\n        parser.add_argument('query', type=str,      help='query argument')\n\n    parser.add_argument('-m','--method',        help='method to search by it,default is \"domain\".', choices=_METHODS, type=str, default='domain')\n    parser.add_argument('-vt','--view-type',    help='type view the result default is \"full\".', choices=VIEW_TYPE_LIST, type=str, default='full')\n    parser.add_argument('-s','--scan',          help='scan the company domain (Related company, Clients, Employees, Company ASNs, Company Apps).',action='store_true')\n    parser.add_argument('-sr','--scan-related', help='Run related scan, default is yes, Ex: -sr no',type=str, default='yes')\n    parser.add_argument('-ss','--scan-subdomains', help='Run subdomains scan, default is yes, Ex: -ss no',type=str, default='yes')\n    parser.add_argument('-sa','--scan-apps',    help='Run App scan, default is yes, Ex: -sa no',type=str, default='yes')\n    parser.add_argument('-si','--scan-ips',     help='Run IPs scan, default is yes, Ex: -si no',type=str, default='yes')\n    parser.add_argument('-sc','--scan-clients', help='Run clients scan, default is yes, Ex: -sc no',type=str, default='yes')\n    parser.add_argument('-se','--scan-employees',help='Run employees scan, default is yes, Ex: -se no',type=str, default='yes')\n    parser.add_argument('-o','--output',        help='filename to save the result', type=str,)\n    parser.add_argument('-ot','--output-type',  help='output format default is \"text\".', choices=['text', 'json', 'csv'], type=str, default='text')\n    parser.add_argument('-t','--timeout',       help='request timeout default is 360 sec.',type=int, default=360)\n    parser.add_argument('-l','--limit',         help='limit results default is 10000.',type=int, default=10000)\n    parser.add_argument('-nc','--no-color',     help='show result without color.',action='store_true')\n    parser.add_argument('-lv','--list-view-type',help='list view type.',action='store_true')\n    parser.add_argument('-lm','--list-methods',   help='list methods.',  action='store_true')\n    parser.add_argument('--init',               help='set the api token.',type=str)\n\n    parser.add_argument('-v','--version',         help='version.',action='store_true') \n\n    parser.epilog  = f'''\nExamples:\n\n    # Scan company by domain\n    {Path(sys.argv[0]).name} example.com --scan\n\n    # Search for target domain, you will see the result for only this \"example.com\" \n    {Path(sys.argv[0]).name} example.com \n    \n    # Search in target and target subdomains\n    {Path(sys.argv[0]).name} example.com --method domain.all\n\n    # Search for target subdomains\n    {Path(sys.argv[0]).name} example.com --view-type subdomain\n        \n    # Search for all creds in United States \n    {Path(sys.argv[0]).name} US --method cred.country\n\n    # Search for related companies by domain\n    {Path(sys.argv[0]).name} example.com --view-type related\n\n    # search for target app id \n    {Path(sys.argv[0]).name} com.discord --method app.id \n    \n    # search for target app domain \n    {Path(sys.argv[0]).name} discord.com --method app.domain\n    \n    # search for target app name \n    {Path(sys.argv[0]).name} Discord --method app.name\n    \n    # Search for ip asn\n    {Path(sys.argv[0]).name} AS123 --method ip.asn\n\n    # Search for cred username\n    {Path(sys.argv[0]).name} someone --method cred.username\n\n    # Search for cred password\n    {Path(sys.argv[0]).name} example@123 --method cred.password\n\n    # Search for url endpoint\n    {Path(sys.argv[0]).name} /wp-login.php --method url.path\n\n    # Search for ip\n    {Path(sys.argv[0]).name} 1.1.1.1 --method ip\n\n    # Search for cidr\n    {Path(sys.argv[0]).name} xx.xx.xx.0/24 --method ip\n\n    # Search for target creds by domain emsils\n    {Path(sys.argv[0]).name} example.com --method cred.email.domain\n\n    # Search for target email\n    {Path(sys.argv[0]).name} someone@example.com --method cred.email  \n\n    # search for multiple targets: \n    {Path(sys.argv[0]).name} targets.txt --method domain  --output example-creds.txt \n    '''\n\n    argcomplete.autocomplete(parser)\n    args = parser.parse_args()\n    if args.list_view_type:\n        for i in VIEW_TYPE_LIST:\n            print(i)\n        sys.exit(0)\n\n    if args.list_methods:\n        for i in _METHODS:\n            print(i)\n        sys.exit(0)\n\n    if args.version:\n        print(VERSION)\n        sys.exit(0)\n\n    if args.scan:\n        root=Scan(options=args)\n        root.proc()\n\n    else:\n        root=CLI(options=args)\n        root.proc()\n"
  },
  {
    "path": "pychiasmodon.py",
    "content": "import re\r\nimport os \r\nimport sys\r\nimport time\r\nimport requests\r\nfrom yaspin import Spinner \r\n\r\nVERSION = \"3.0.2\"\r\n_API_URL = 'http://chiasmodon.online/v2/api/beta'\r\n_API_HEADERS = {'user-agent':'cli/python'}\r\n_VIEW_TYPE = {\r\n    'full':[\r\n        'cred.username',\r\n        'cred.phone',\r\n        'cred.password',\r\n        'cred.email',\r\n        'cred.email.domain',\r\n        'cred.country',\r\n        'domain',\r\n        'domain.all',\r\n        \r\n        'ip',\r\n        'ip.asn',\r\n        'ip.isp',\r\n        'ip.org',\r\n        'ip.port',\r\n        'ip.country',\r\n        'app.id',\r\n        'app.name',\r\n        'app.domain',\r\n        'url.path',\r\n        'url.port',\r\n    ],\r\n    'cred':[\r\n        'cred.phone',\r\n        'cred.username',\r\n        'cred.password',\r\n        'cred.email',\r\n        'cred.email.domain',\r\n        'cred.country',\r\n        'domain',\r\n        'domain.all',\r\n        \r\n        'ip',\r\n        'ip.asn',\r\n        'ip.isp',\r\n        'ip.org',\r\n        'ip.port',\r\n        'ip.country',\r\n        'app.id',\r\n        'app.name',\r\n        'app.domain',\r\n        'url.path',\r\n        'url.port',\r\n    ],\r\n    'url':[\r\n        'cred.username',\r\n        'cred.password',\r\n        'cred.phone',\r\n        'cred.email',\r\n        'cred.email.domain',\r\n        'cred.country',\r\n        'domain',\r\n        'domain.all',\r\n        'ip',\r\n        'ip.asn',\r\n        'ip.isp',\r\n        'ip.org',\r\n        'ip.port',\r\n        'ip.country',\r\n        'url.path',\r\n        'url.port',\r\n    ],\r\n    'email':[\r\n        'cred.username',\r\n        'cred.phone',\r\n        'cred.password',\r\n        'cred.country',\r\n        'cred.email.domain',\r\n        'domain',\r\n        'domain.all',\r\n        'ip',\r\n        'ip.asn',\r\n        'ip.isp',\r\n        'ip.org',\r\n        'ip.port',\r\n        'ip.country',\r\n        'app.id',\r\n        'app.name',\r\n        'app.domain',\r\n        'url.path',\r\n        'url.port',\r\n    ],\r\n    'phone':[\r\n        'cred.username',\r\n        'cred.email',\r\n        'cred.email.domain',\r\n        'domain',\r\n        'domain.all',\r\n        'ip',\r\n        'ip.asn',\r\n        'ip.isp',\r\n        'ip.org',\r\n        'ip.port',\r\n        'ip.country',\r\n        'app.id',\r\n        'app.name',\r\n        'app.domain',\r\n        'url.path',\r\n        'url.port',\r\n        'cred.country',\r\n    ],    \r\n    'password':[\r\n        'cred.username',\r\n        'cred.phone',\r\n\r\n        'cred.email',\r\n        'cred.email.domain',\r\n        'domain',\r\n        'domain.all',\r\n        'ip',\r\n        'ip.asn',\r\n        'ip.isp',\r\n        'ip.org',\r\n        'ip.port',\r\n        'ip.country',\r\n        'app.id',\r\n        'app.name',\r\n        'app.domain',\r\n        'url.path',\r\n        'url.port',\r\n        'cred.country',\r\n    ],\r\n    'username': [\r\n        'cred.phone',\r\n        'cred.password',\r\n        'domain',\r\n        'domain.all',\r\n        'ip',\r\n        'ip.asn',\r\n        'ip.isp',\r\n        'ip.org',\r\n        'ip.port',\r\n        'ip.country',\r\n        'app.id',\r\n        'app.name',\r\n        'app.domain',\r\n        'url.path',\r\n        'url.port',\r\n        'cred.country',\r\n    ],\r\n    'app':[\r\n        'cred.phone',\r\n        'cred.username',\r\n        'cred.password',\r\n        'cred.email',\r\n        'cred.email.domain',\r\n        'cred.country', \r\n        'app.domain'\r\n    ],\r\n    'domain':[\r\n        'cred.username',\r\n        'cred.phone',\r\n        'cred.password',\r\n        'cred.email',\r\n        'cred.email.domain',\r\n        'cred.country',\r\n        'domain',\r\n        'domain.all',\r\n        \r\n        'ip',\r\n        'ip.asn',\r\n        'ip.isp',\r\n        'ip.org',\r\n        'ip.port',\r\n        'ip.country',\r\n        'app.id',\r\n        'app.name',\r\n        'app.domain',\r\n        'url.path',\r\n        'url.port',\r\n    ],\r\n    'ip':[\r\n        'cred.username',\r\n        'cred.phone',\r\n        'cred.password',\r\n        'cred.email',\r\n        'cred.email.domain',\r\n        'domain',\r\n        'domain.all',\r\n        'ip.asn',\r\n        'ip.isp',\r\n        'ip.org',\r\n        'ip.port',\r\n        'ip.country',\r\n        'app.id',\r\n        'app.name',\r\n        'app.domain',\r\n        'url.path',\r\n        'url.port',\r\n        'cred.country',\r\n    ],\r\n    'related':[\r\n        'domain',\r\n    ],\r\n    'subdomain':[\r\n        'domain'\r\n    ]\r\n}\r\n\r\n_METHODS = [\r\n    # cred\r\n    'cred.username',         # Query like -> somone\r\n    'cred.password',         # Query like -> lol@123\r\n    'cred.email',            # Query like -> somone@example.com\r\n    'cred.phone',            # Query line -> xxxxxxxx # without : + or - or  space or ) or (\r\n    'cred.email.domain',     # Query like -> example.com\r\n    'cred.country',          # Query like -> US \r\n\r\n    # domain\r\n    'domain',           # Query like -> example.com\r\n    'domain.all',       # Query like -> example.com\r\n\r\n    # ip\r\n    'ip',               # Query like -> 1.1.1.1\r\n    'ip.asn',           # Query like -> as123\r\n    'ip.isp',           # Query like -> \"isp company\"\r\n    'ip.org',           # Query like -> \"org name\"\r\n    'ip.port',          # Query like -> 22\r\n    'ip.country',       # Query like -> US\r\n    \r\n    # app\r\n    'app.id',           # Query like -> com.example\r\n    'app.name',         # Query like -> Example\r\n    'app.domain',       # Query like -> example.com\r\n    \r\n    # url\r\n    'url.path',         # Query like -> \"isp company\"\r\n    'url.port',         # Query like -> 8080\r\n]\r\n\r\nVIEW_TYPE_LIST = list(_VIEW_TYPE.keys())\r\n\r\nclass T:\r\n    RED      = '\\033[91m'\r\n    GREEN    = '\\033[92m'\r\n    YELLOW   = '\\033[93m'\r\n    BLUE     = '\\033[94m'\r\n    MAGENTA  = '\\033[95m'\r\n    CYAN     = '\\033[96m'\r\n    RESET    = '\\033[0m'\r\n\r\n\r\nclass Chiasmodon:\r\n    def __init__(self, token=None, color=True, debug=True,conf_file=None,check_token=True) -> None:\r\n        self.token                 = token\r\n        self.conf_file             = conf_file\r\n        self.debug                 = debug\r\n        self.err :bool             = False \r\n        self.msg :str              = '' \r\n        self.__result:list[Result] = []\r\n        self.scan_mode             = False\r\n\r\n        if not color:\r\n            T.RED      = ''\r\n            T.GREEN    = ''\r\n            T.YELLOW   = ''\r\n            T.BLUE     = ''\r\n            T.MAGENTA  = ''\r\n            T.CYAN     = ''\r\n            T.RESET    = ''\r\n        \r\n        if self.token and check_token:\r\n            if self.__check_token():\r\n                self.print(f'{T.GREEN}Set token successfully{T.RESET}')\r\n\r\n            else:\r\n                try:os.remove(conf_file)\r\n                except:pass\r\n\r\n                self.print(f'{T.RED}{self.msg}{T.RESET}')\r\n                return\r\n\r\n    def proc_all_domains(self,\r\n                query,\r\n                view_type,\r\n                sort,\r\n                timeout,\r\n                limit,\r\n                callback_view_result,\r\n                yaspin,\r\n                search_text,\r\n                err_text) -> list:\r\n        \r\n\r\n        domains :list = self.__proc_query(\r\n                query=query,\r\n                method='domain',\r\n                view_type='subdomain',\r\n                sort=sort,\r\n                timeout=timeout,\r\n                limit=limit,\r\n                callback_view_result=None,\r\n                yaspin=None,\r\n                search_text=search_text,\r\n                err_text=err_text,\r\n        )\r\n        self.__result :list = []\r\n        result :list = []\r\n        \r\n        domains = [i.domain for i in domains]\r\n        if query not in domains:domains.append(query)\r\n\r\n        for domain in domains:\r\n            result.extend(self.__proc_query(\r\n                query=domain,\r\n                method='domain',\r\n                view_type=view_type,\r\n                sort=sort,\r\n                timeout=timeout,\r\n                limit=limit,\r\n                callback_view_result=callback_view_result,\r\n                yaspin=yaspin,\r\n                search_text=search_text.replace(query, domain),\r\n                err_text=err_text,\r\n            ))\r\n            self.__result :list = []\r\n        \r\n        return result\r\n\r\n    \r\n    def filter(self,query:str,method:str):\r\n\r\n        if 'domain' in method:\r\n            if not re.match(r\"^(?!.*\\d+\\.\\d+\\.\\d+\\.\\d+$)[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$\", query):\r\n                self.print(f'{T.RED}Your format query is wrong!\\nThis is not domain.{T.RESET}')\r\n                return False\r\n\r\n        elif method == 'ip':\r\n            if not re.match(r\"\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b\", query):\r\n                self.print(f'{T.RED}Your format query is wrong!\\nAccept only ipv4.{T.RESET}')\r\n                return False\r\n        \r\n        elif method == 'ip.asn':\r\n            if not query.lower().startswith('as'):\r\n                self.print(f'{T.RED}Your format query is wrong!\\nThe ASN starts with AS\\nLike this: AS1234.{T.RESET}')\r\n                return False\r\n        \r\n        elif method in ['ip.port', 'url.port']:\r\n            if not re.match(r\":(\\d+)\", query):\r\n                self.print(f'{T.RED}Your format query is wrong!\\nThis is not port.{T.RESET}')\r\n                return False\r\n        \r\n        elif method == 'cred.email':\r\n            if not re.match(r'^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$', query):\r\n                self.print(f'{T.RED}Your format query is wrong!\\nThis is not email.{T.RESET}')\r\n                return False\r\n        \r\n        elif method == 'cred.country' or method == 'ip.country':\r\n            if not len(query) == 2:\r\n                self.print(f'{T.RED}Your format query is wrong!\\nAccept only country code.{T.RESET}')\r\n                return False\r\n        \r\n        elif method == 'url.path':\r\n            if not query[0] == '/':\r\n                self.print(f'{T.RED}Your format query is wrong!\\nThe url path moset be like: /somthing{T.RESET}')\r\n                return False\r\n        \r\n        return query\r\n\r\n    def print(self,text, ys=None, ys_err=False) -> None:\r\n        if text == None:return \r\n        if self.debug:\r\n            if ys:\r\n                if not ys_err:\r\n                    ys.write(text)\r\n                else:\r\n                    ys.text = text\r\n            else:\r\n                print(text)\r\n\r\n    def __check_token(self):\r\n        if self.__request({\r\n            'token'     : self.token,\r\n            'version'   : VERSION,\r\n            'method'    : 'token'\r\n        }).get('is_active'):\r\n            return True \r\n\r\n        return False \r\n\r\n    def __request(self, data:dict,timeout=60):\r\n\r\n        try:\r\n            resp = requests.post(_API_URL, data=data, headers=_API_HEADERS, timeout=timeout)\r\n            resp.close()\r\n            resp = resp.json()\r\n\r\n            try:\r\n                if resp.get('err'):\r\n                    self.err = True \r\n                    self.msg = resp['msg']\r\n            except:pass\r\n\r\n            return resp\r\n\r\n        except requests.exceptions.ReadTimeout:\r\n            self.print(f\"{T.RED}\\nError: timeout !\\nPlease try agine later.{T.RESET}\")\r\n            sys.exit()\r\n\r\n        except requests.exceptions.InvalidJSONError:\r\n            self.print(f\"{T.RED}\\nError: Server send wrong data.\\nPlease try agine later.{T.RESET}\")\r\n            sys.exit()\r\n\r\n        except Exception as e:\r\n            self.print(f\"{T.RED}\\nRequest error: {e}\\nPlease try agine later.{T.RESET}\")\r\n            sys.exit()\r\n\r\n\r\n    def __proc_query(self, \r\n                    method:str, \r\n                    query:str, \r\n                    view_type:str, \r\n                    timeout:int,\r\n                    sort:bool, \r\n                    limit:int,\r\n                    yaspin:bool,\r\n                    callback_view_result,\r\n                    search_text='',\r\n                    err_text=''\r\n                    ) -> dict:\r\n        Result.VIEW_TYPE = view_type\r\n\r\n        result : list[Result] = []\r\n\r\n        data = {\r\n\r\n            'token'         :       self.token,\r\n            'type-view'     :       view_type,\r\n            'method'        :       method,\r\n            'version'       :       VERSION,\r\n            'query'         :       query,\r\n            'get-info'      :       'yes'\r\n        }\r\n\r\n        if yaspin:\r\n            with yaspin(Spinner([\"🐟\",\"🐠\",\"🐡\",\"🐬\",\"🐋\",\"🐳\",\"🦈\",\"🐙\",\"🐚\",\"🪼\",\"🪸\"], 200),text=f\"Processing {query} ...\" if not search_text else search_text) as sp:\r\n                process_info = self.__request(\r\n                    data=data,\r\n                    timeout=timeout,\r\n                )\r\n\r\n            if process_info and process_info.get('count') == 0:\r\n                if not err_text:\r\n                    self.print(f\"{T.RED}Not found result{T.RESET}\", sp,ys_err=True)\r\n                else:\r\n                    self.print(f\"{T.RED}{err_text}{T.RESET}\", sp,ys_err=True)\r\n                        \r\n\r\n                sp.fail(\"💥 \")\r\n                sp.stop()\r\n                return result \r\n\r\n            else:\r\n                sp.ok(\"⚓ \")\r\n\r\n        else:\r\n            process_info = self.__request(\r\n                data=data,\r\n                timeout=timeout,\r\n            )\r\n            if process_info and process_info.get('count') == 0:\r\n                self.print(f\"{T.RED}Not found result{T.RESET}\")\r\n                return result\r\n            \r\n        \r\n        del data['get-info'] \r\n\r\n        if self.err:\r\n            self.err= False\r\n            self.print(f'{T.RED}Error: {self.msg}{T.RESET}',ys_err=True) \r\n            return\r\n            \r\n        if yaspin: \r\n            self.print(f\"{T.YELLOW}Pages count{T.YELLOW}: {T.GREEN}{process_info['pages'] if process_info['count'] != -1 else 'unknown'}{T.RESET}\")\r\n\r\n        data['sid'] = process_info['sid']\r\n\r\n        if yaspin:\r\n            YS = yaspin(f'Get pages 0/{process_info[\"pages\"]}').green.bold.shark #.on_black\r\n            YS.start()\r\n\r\n        else:\r\n            YS = None\r\n        \r\n        for p in range(1, process_info['pages']+0x1):\r\n            if yaspin:YS.text = f'Get pages {p}/{process_info[\"pages\"]}'\r\n            \r\n            data['page'] = p\r\n\r\n            beta_result = self.__request(\r\n                data=data,\r\n                timeout=timeout,\r\n            )\r\n\r\n            if self.err:\r\n                self.err=False\r\n                if yaspin:self.print(f\"{T.RED}{self.msg}{T.RESET}\", YS, ys_err=True);YS.fail(\"💥 \");YS.stop()\r\n                return result\r\n\r\n            for r in beta_result['data']:\r\n                \r\n                column :Result = Result(**r)\r\n\r\n                if sort and column in self.__result:\r\n                    continue\r\n                \r\n                if callback_view_result != None:\r\n                    callback_view_result(beta=column, ys=YS)\r\n\r\n                result.append(column)\r\n                self.__result.append(column)\r\n\r\n                if len(result) == limit:\r\n                    if yaspin:YS.text='';YS.stop()\r\n                    return result\r\n                \r\n            if beta_result['done']:\r\n                if yaspin:YS.text='';YS.stop()\r\n                return result\r\n\r\n            time.sleep(0x1)\r\n\r\n        if not result:\r\n            if yaspin:self.print(f\"{T.RED}Not found result{T.RESET}\", YS,ys_err=True);YS.fail(\"💥 \");YS.stop()\r\n            else:self.print(f\"{T.RED}Not found result{T.RESET}\")\r\n        else:\r\n            if yaspin:YS.text='';YS.stop()\r\n        return result\r\n    \r\n    def search(self,\r\n               query,\r\n               method='domain',\r\n               view_type='full',\r\n               limit=10000,\r\n               timeout=60,\r\n               sort=True,\r\n               yaspin=False,\r\n               search_text='',\r\n               err_text='',\r\n               callback_view_result=None) -> dict:\r\n        \r\n        \r\n        if method not in _METHODS:\r\n            raise Exception(f\"{T.RED}not found this method: {method}.{T.RESET}\")\r\n        \r\n        if method not in _VIEW_TYPE[view_type]:\r\n            raise Exception(f\"{T.RED}{view_type} doesn't support ({method}).{T.RESET}\")\r\n        \r\n        \r\n        self.err = False\r\n        self.msg = ''\r\n        result = None\r\n\r\n        query = self.filter(query, method)\r\n        if query == False:\r\n            return\r\n\r\n        if method == \"domain.all\":\r\n            result = self.proc_all_domains(\r\n                query=query,\r\n                view_type=view_type,\r\n                sort=sort,\r\n                timeout=timeout,\r\n                limit=limit,\r\n                callback_view_result=callback_view_result,\r\n                yaspin=yaspin,\r\n                search_text=search_text,\r\n                err_text=err_text,\r\n            )\r\n\r\n        else:\r\n\r\n            result = self.__proc_query(\r\n                query=query,\r\n                method=method,\r\n                view_type=view_type,\r\n                sort=sort,\r\n                timeout=timeout,\r\n                limit=limit,\r\n                callback_view_result=callback_view_result,\r\n                yaspin=yaspin,\r\n                search_text=search_text,\r\n                err_text=err_text,\r\n            )\r\n\r\n        self.__result:list = []\r\n\r\n        return result\r\n\r\nclass Result(dict):\r\n    VIEW_TYPE = None\r\n    HID_PASS  = True if os.environ.get('HID_PASS') else False \r\n    def __init__(self,type,**kwargs) -> None:\r\n        \r\n        self.kwargs         = kwargs\r\n        Type           = type \r\n\r\n        self.url            = None\r\n        self.urlPort        = None\r\n        self.urlPath        = None\r\n        self.credEmail      = None\r\n        self.credUsername   = None\r\n        self.credPassword   = None\r\n        self.credCountry    = None\r\n        self.credDate       = None \r\n        self.credPhone      = None \r\n        self.domain         = None \r\n        self.ip             = None \r\n        self.ipAsn          = None\r\n        self.ipIsp          = None\r\n        self.ipOrg          = None\r\n        self.ipPorts        = None\r\n        self.ipCountry      = None\r\n        self.appID          = None\r\n        self.appName        = None \r\n        self.appIcon        = None \r\n        self.appDomain      = None \r\n\r\n        if Type == \"login\":\r\n            if kwargs.get('url'):\r\n                self.urlPath = kwargs['url']['path']\r\n                self.urlPort = kwargs['url']['port']\r\n                self.url    = self.__convert_url(kwargs['url'])\r\n                \r\n                if kwargs['url']['ip']:\r\n                    self.__convert_and_set_ip(kwargs['url']['ip'])\r\n\r\n                elif kwargs['url']['domain']:\r\n                    self.domain = self.__convert_domain(kwargs['url']['domain'])    \r\n                \r\n\r\n            if kwargs.get('app'):\r\n                self.appID   = kwargs['app']['id']\r\n                self.appName = kwargs['app']['name']\r\n                self.appIcon = kwargs['app']['icon']\r\n                if kwargs['app']['domain']:\r\n                    self.appDomain = self.__convert_domain(kwargs['app']['domain'])\r\n\r\n            if kwargs.get('cred'):\r\n                if kwargs['cred']['email']:\r\n                    self.credEmail = self.__convert_email(kwargs['cred']['email'])\r\n\r\n                self.credUsername = kwargs['cred']['username']\r\n                self.credPassword = kwargs['cred']['password'] if not self.HID_PASS else '*'*len(kwargs['cred']['password']) \r\n                if kwargs['cred']['phone']:\r\n                    self.credPhone = self.__convert_phone(kwargs['cred']['phone'])\r\n\r\n\r\n            if kwargs.get('country'):\r\n                self.credCountry = kwargs['country']['f']\r\n            \r\n            self.credDate = kwargs['date']\r\n\r\n        elif Type == 'url':\r\n            self.urlPath = kwargs['path']\r\n            self.urlPort = kwargs['port']\r\n            self.url = self.__convert_url(kwargs)\r\n\r\n            if kwargs['ip']:\r\n                self.url    = self.__convert_url(kwargs)\r\n                self.__convert_and_set_ip(kwargs['ip'])\r\n\r\n            elif kwargs['domain']:\r\n                self.domain = self.__convert_domain(kwargs['domain'])    \r\n\r\n        elif Type == \"email\":\r\n            self.credEmail = self.__convert_email(kwargs)\r\n        \r\n        elif Type == \"domain\":\r\n            self.domain = self.__convert_domain(kwargs)\r\n\r\n        elif Type == 'app':\r\n            self.appID = kwargs['id']\r\n            self.appName = kwargs['name']\r\n            self.appIcon = kwargs['icon']\r\n\r\n            if kwargs['domain']:\r\n                self.domain = self.__convert_domain(kwargs['domain'])    \r\n\r\n\r\n        elif Type == 'ip':\r\n            self.__convert_and_set_ip(kwargs)\r\n    \r\n    def __convert_phone(self,phone):\r\n        return f\"+{phone['country']['p']} {phone['number']}\"\r\n\r\n    def __convert_email(self,email):\r\n        return f\"{email['name']}@{self.__convert_domain(email['domain'])}\"\r\n\r\n    def __convert_and_set_ip(self,ip):\r\n        self.ip         = ip['ip']\r\n        self.ipAsn      = ip['asn']\r\n        self.ipOrg      = ip['org']\r\n        self.ipIsp      = ip['isp']\r\n        self.ipPorts    = ip['ports']\r\n        self.ipCountry  = ip['country']['f'] if ip['country'] else None\r\n\r\n    def __convert_url(self,url:dict):\r\n        if url['domain']:\r\n            return f\"{url['proto']}://{self.__convert_domain(url['domain'])}:{url['port']}{url['path']}\" \r\n        elif url['ip']:\r\n            return f\"{url['proto']}://{url['ip']['ip']}:{url['port']}{url['path']}\" \r\n\r\n        \r\n        return None \r\n\r\n    def __convert_domain(self,domain:dict):\r\n        return f\"{(domain['sub']+'.') if domain['sub'] else ''}{domain['name']}{('.'+domain['suffix']) if domain['suffix']  else ''}\"\r\n\r\n\r\n    def __str__(self) -> str:\r\n        return self.save_format()\r\n\r\n    def __radd__(self, other):\r\n        if isinstance(other, str):\r\n            return   other + self.save_format() \r\n        else:\r\n            return NotImplemented\r\n\r\n    def __add__(self, other):\r\n        if isinstance(other, str):\r\n            return self.save_format() + other\r\n        else:\r\n            return NotImplemented\r\n          \r\n    def __getattr__(self, key):\r\n        if key in self:\r\n            return self[key]\r\n        else:\r\n            raise AttributeError(f\"'Result' object has no attribute '{key}'\")\r\n\r\n    def __setattr__(self, key, value):\r\n        self[key] = value\r\n        \r\n    \r\n    def print(self,):\r\n        c=\"\"\r\n\r\n        if self.VIEW_TYPE == \"email\" and self.credEmail:\r\n            c+=f\"{T.MAGENTA}[ {T.YELLOW}Email{T.MAGENTA} ]{T.MAGENTA}> {T.CYAN}{self.credEmail}{T.RESET}\"\r\n\r\n        if self.VIEW_TYPE == \"password\" and self.credPassword:\r\n            c+=f\"{T.MAGENTA}[ {T.YELLOW}Email{T.MAGENTA} ]{T.MAGENTA}> {T.CYAN}{self.credPassword}{T.RESET}\"\r\n\r\n        if self.VIEW_TYPE == \"username\" and self.credUsername:\r\n            c+=f\"{T.MAGENTA}[ {T.YELLOW}Email{T.MAGENTA} ]{T.MAGENTA}> {T.CYAN}{self.credUsername}{T.RESET}\"\r\n        \r\n        if self.VIEW_TYPE == \"app\" and self.appID:\r\n            if self.appID:c+=f\"{T.MAGENTA}[ {T.YELLOW}APP{T.MAGENTA} ]{T.RED}{T.MAGENTA}>  {T.CYAN}{self.appID}{T.RESET}\\n\"\r\n            if self.appName:c+=f\"{T.MAGENTA}[ {T.YELLOW}APP{T.MAGENTA} ]{T.RED}{T.MAGENTA}> {T.RED} Name{T.RESET}{' ':10}: {T.CYAN}{self.appName}{T.RESET}\\n\"\r\n            if self.appIcon:c+=f\"{T.MAGENTA}[ {T.YELLOW}APP{T.MAGENTA} ]{T.RED}{T.MAGENTA}> {T.RED} Icon{T.RESET}{' ':10}: {T.CYAN}{self.appIcon}{T.RESET}\\n\"\r\n            if self.appDomain:c+=f\"{T.MAGENTA}[ {T.YELLOW}APP{T.MAGENTA} ]{T.MAGENTA}> {T.RED} Domain{T.RESET}{' ':8}: {T.CYAN}{self.appDomain}{T.RESET}\\n\"\r\n            \r\n        if self.VIEW_TYPE == \"url\" and self.url:\r\n            if self.url:c+=f\"{T.MAGENTA}[ {T.YELLOW}URL{T.MAGENTA}  ]{T.MAGENTA}>  {T.CYAN}{self.url}{T.RESET}\\n\"\r\n            if self.urlPath:c+=f\"{T.MAGENTA}[ {T.YELLOW}URL{T.MAGENTA}  ]{T.MAGENTA}> {T.RED} Path{T.RESET}{' ':10}: {T.CYAN}{self.urlPath}{T.RESET}\\n\"\r\n            if self.urlPort:c+=f\"{T.MAGENTA}[ {T.YELLOW}URL{T.MAGENTA}  ]{T.MAGENTA}> {T.RED} Port{T.RESET}{' ':10}: {T.CYAN}{self.urlPort}{T.RESET}\\n\"\r\n\r\n        if self.VIEW_TYPE == \"ip\" and self.ip:\r\n            if self.ip:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA} ]{T.MAGENTA}>  {T.BLUE}{self.ip}{T.RESET}\\n\"\r\n            if self.ipPorts:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA} ]{T.RED}{T.MAGENTA}> {T.RED} Ports{T.RESET}{' ':9}: {T.CYAN}{self.ipPorts}{T.RESET}\\n\"\r\n            if self.ipAsn:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA} ]{T.RED}{T.MAGENTA}> {T.RED} Asn{T.RESET}{' ':11}: {T.CYAN}{self.ipAsn}{T.RESET}\\n\"\r\n            if self.ipIsp:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA} ]{T.RED}{T.MAGENTA}> {T.RED} Isp{T.RESET}{' ':11}: {T.CYAN}{self.ipIsp}{T.RESET}\\n\"\r\n            if self.ipOrg:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA} ]{T.RED}{T.MAGENTA}> {T.RED} Org{T.RESET}{' ':11}: {T.CYAN}{self.ipOrg}{T.RESET}\\n\"\r\n            if self.ipCountry:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA} ]{T.MAGENTA}>{T.RED}  Country{T.RESET}{' ':7}: {T.CYAN}{self.ipCountry}{T.RESET}\\n\"\r\n\r\n        if self.VIEW_TYPE in [\"domain\", 'subdomain', 'related'] and self.domain:\r\n            c+=f\"{T.MAGENTA}[ {T.YELLOW}Domain{T.MAGENTA} ]{T.MAGENTA}> {T.CYAN}{self.domain}{T.RESET}\"\r\n\r\n        if self.VIEW_TYPE == \"phone\" and self.credPhone:\r\n            return f\"{T.MAGENTA}> {T.CYAN}{self.credPhone}{T.RESET}\"\r\n\r\n        if self.VIEW_TYPE == \"cred\":\r\n            if self.url:c+=f\"{T.MAGENTA}[ {T.YELLOW}URL{T.MAGENTA}  ]{T.MAGENTA}>  {T.BLUE}{self.url}{T.RESET}\\n\"\r\n            if self.appID:c+=f\"{T.MAGENTA}[ {T.YELLOW}APP{T.MAGENTA}  ]{T.RED}{T.MAGENTA}>  {T.CYAN}{self.appID}{T.RESET}\\n\"\r\n            if self.credEmail:c+=f\"{T.MAGENTA}[ {T.YELLOW}CRED{T.MAGENTA} ]{T.MAGENTA}> {T.RED} Email{T.RESET}{' ':9}: {T.GREEN}{self.credEmail}{T.RESET}\\n\"\r\n            if self.credUsername and not self.credEmail:c+=f\"{T.MAGENTA}[ {T.YELLOW}CRED{T.MAGENTA} ]{T.MAGENTA}> {T.RED} Username{T.RESET}{' ':6}: {T.GREEN}{self.credUsername}{T.RESET}\\n\"\r\n            if self.credPassword:c+=f\"{T.MAGENTA}[ {T.YELLOW}CRED{T.MAGENTA} ]{T.MAGENTA}> {T.RED} Password{T.RESET}{' ':6}: {T.GREEN}{self.credPassword}{T.RESET}\\n\"\r\n            if self.credPhone:c+=f\"{T.MAGENTA}[ {T.YELLOW}CRED{T.MAGENTA} ]{T.MAGENTA}> {T.RED} Phone{T.RESET}{' ':9}: {T.GREEN}{self.credPhone}{T.RESET}\\n\"\r\n            if self.credCountry:c+=f\"{T.MAGENTA}[ {T.YELLOW}CRED{T.MAGENTA} ]{T.MAGENTA}>{T.RED}  Country{T.RESET}{' ':7}: {T.CYAN}{self.credCountry}{T.RESET}\\n\"\r\n\r\n        if self.VIEW_TYPE == \"full\":\r\n            if self.url:c+=f\"{T.MAGENTA}[ {T.YELLOW}URL{T.MAGENTA}  ]{T.MAGENTA}>  {T.BLUE}{self.url}{T.RESET}\\n\"\r\n            if self.urlPath and self.urlPath != '/':c+=f\"{T.MAGENTA}[ {T.YELLOW}URL{T.MAGENTA}  ]{T.MAGENTA}> {T.RED} Path{T.RESET}{' ':10}: {T.CYAN}{self.urlPath}{T.RESET}\\n\"\r\n            if self.urlPort and self.urlPort not in [80, 443]:c+=f\"{T.MAGENTA}[ {T.YELLOW}URL{T.MAGENTA}  ]{T.MAGENTA}> {T.RED} Port{T.RESET}{' ':10}: {T.CYAN}{self.urlPort}{T.RESET}\\n\"\r\n            if self.ip:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA}   ]{T.MAGENTA}>  {T.BLUE}{self.ip}{T.RESET}\\n\"\r\n            if self.ipPorts:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA}   ]{T.RED}{T.MAGENTA}> {T.RED} Ports{T.RESET}{' ':9}: {T.CYAN}{self.ipPorts}{T.RESET}\\n\"\r\n            if self.ipAsn:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA}   ]{T.RED}{T.MAGENTA}> {T.RED} Asn{T.RESET}{' ':11}: {T.CYAN}{self.ipAsn}{T.RESET}\\n\"\r\n            if self.ipIsp:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA}   ]{T.RED}{T.MAGENTA}> {T.RED} Isp{T.RESET}{' ':11}: {T.CYAN}{self.ipIsp}{T.RESET}\\n\"\r\n            if self.ipOrg:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA}   ]{T.RED}{T.MAGENTA}> {T.RED} Org{T.RESET}{' ':11}: {T.CYAN}{self.ipOrg}{T.RESET}\\n\"\r\n            if self.ipCountry:c+=f\"{T.MAGENTA}[ {T.YELLOW}IP{T.MAGENTA}   ]{T.MAGENTA}>{T.RED}  Country{T.RESET}{' ':7}: {T.CYAN}{self.ipCountry}{T.RESET}\\n\"\r\n            \r\n            if self.appID:c+=f\"{T.MAGENTA}[ {T.YELLOW}APP{T.MAGENTA}  ]{T.RED}{T.MAGENTA}>  {T.CYAN}{self.appID}{T.RESET}\\n\"\r\n            if self.appName:c+=f\"{T.MAGENTA}[ {T.YELLOW}APP{T.MAGENTA}  ]{T.RED}{T.MAGENTA}> {T.RED} Name{T.RESET}{' ':10}: {T.CYAN}{self.appName}{T.RESET}\\n\"\r\n            if self.appIcon:c+=f\"{T.MAGENTA}[ {T.YELLOW}APP{T.MAGENTA}  ]{T.RED}{T.MAGENTA}> {T.RED} Icon{T.RESET}{' ':10}: {T.CYAN}{self.appIcon}{T.RESET}\\n\"\r\n            if self.appDomain:c+=f\"{T.MAGENTA}[ {T.YELLOW}APP{T.MAGENTA}  ]{T.MAGENTA}> {T.RED} Domain{T.RESET}{' ':8}: {T.CYAN}{self.appDomain}{T.RESET}\\n\"\r\n            \r\n            if self.credEmail:c+=f\"{T.MAGENTA}[ {T.YELLOW}CRED{T.MAGENTA} ]{T.MAGENTA}> {T.RED} Email{T.RESET}{' ':9}: {T.GREEN}{self.credEmail}{T.RESET}\\n\"\r\n            if self.credUsername and not self.credEmail:c+=f\"{T.MAGENTA}[ {T.YELLOW}CRED{T.MAGENTA} ]{T.MAGENTA}> {T.RED} Username{T.RESET}{' ':6}: {T.GREEN}{self.credUsername}{T.RESET}\\n\"\r\n            if self.credPassword:c+=f\"{T.MAGENTA}[ {T.YELLOW}CRED{T.MAGENTA} ]{T.MAGENTA}> {T.RED} Password{T.RESET}{' ':6}: {T.GREEN}{self.credPassword}{T.RESET}\\n\"\r\n            if self.credPhone:c+=f\"{T.MAGENTA}[ {T.YELLOW}CRED{T.MAGENTA} ]{T.MAGENTA}> {T.RED} Phone{T.RESET}{' ':9}: {T.GREEN}{self.credPhone}{T.RESET}\\n\"\r\n            if self.credCountry:c+=f\"{T.MAGENTA}[ {T.YELLOW}CRED{T.MAGENTA} ]{T.MAGENTA}>{T.RED}  Country{T.RESET}{' ':7}: {T.CYAN}{self.credCountry}{T.RESET}\\n\"\r\n\r\n        return c            \r\n\r\n    def save_format(self):\r\n        result = []\r\n        if self.VIEW_TYPE in ['cred', 'full']:\r\n            # 1 \r\n            if self.url:\r\n                result.append(self.url)\r\n            elif self.appID:\r\n                result.append(self.appID)\r\n            else:\r\n                result.append('')\r\n\r\n            # 2\r\n            if self.credUsername:\r\n                result.append(self.credUsername)\r\n            elif self.credEmail:\r\n                result.append(self.credEmail)\r\n            else:\r\n                result.append('')\r\n            \r\n            # 3 \r\n            if self.credPassword:\r\n                result.append(self.credPassword)\r\n            else:\r\n                result.append('')\r\n            \r\n            # 4 \r\n            if self.credCountry:\r\n                result.append(self.credCountry)\r\n            else:\r\n                result.append('')\r\n            \r\n            # 5\r\n            #if self.credDate:\r\n            #    result.append(self.credDate)\r\n            #else:\r\n            #    result.append('')\r\n\r\n            return result\r\n\r\n        elif self.VIEW_TYPE in ['subdomain', 'related', 'domain']:\r\n            return self.domain\r\n        \r\n        elif self.VIEW_TYPE == 'email':\r\n            return self.credEmail\r\n\r\n        elif self.VIEW_TYPE == 'phone':\r\n            return self.credPhone\r\n\r\n        elif self.VIEW_TYPE == 'username':\r\n            return self.credUsername\r\n        \r\n        elif self.VIEW_TYPE == 'password':\r\n            return self.credPassword\r\n        \r\n        \r\n        elif self.VIEW_TYPE == 'ip':\r\n            return self.ip\r\n        \r\n        elif self.VIEW_TYPE == 'app':\r\n            return self.appID\r\n\r\n        elif self.VIEW_TYPE == 'url':\r\n            return self.url\r\n        else:\r\n            return 'null'\r\n"
  },
  {
    "path": "requirements.txt",
    "content": "tldextract==5.1.2\r\nyaspin==3.0.1\r\nargcomplete==3.3.0\r\nrequests==2.31.0"
  },
  {
    "path": "setup.py",
    "content": "#!/usr/bin/python3\r\nfrom distutils.core import setup\r\nfrom os import path\r\nhere = path.abspath(path.dirname(__file__))\r\nwith open(path.join(here, 'README.md'), encoding='utf-8') as f:\r\n    long_description = f.read()\r\n\r\nsetup(name='chiasmodon',\r\n      version='3.0.2',\r\n      description='Chiasmodon is an OSINT tool that allows users to gather information from various sources and conduct targeted searches based on domains, Google Play applications, email addresses, IP addresses, organizations, URLs, and more. It provides comprehensive scanning capabilities, customizable output formats, and additional options for enhanced data analysis and customization.',\r\n      long_description=long_description,\r\n      long_description_content_type='text/markdown',\r\n      author='chiasmod0n',\r\n      keywords='intelligence osint credentials emails asn cidr bugbounty subdomains information-gathering intelligence-analysis reconnaissance attack-surface subdomain-enumeration reconnaissance-framework bugbounty-tool email-enumeration chiasmodon',\r\n      url='https://github.com/chiasmod0n/chiasmodon',\r\n      packages=['.'],\r\n      scripts=['cli/chiasmodon_cli.py'],\r\n      install_requires=['requests', 'yaspin', 'tldextract','argcomplete']\r\n    ) \r\n"
  }
]