evolver-tools 33.0.0__tar.gz → 35.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {evolver_tools-33.0.0/src/evolver_tools.egg-info → evolver_tools-35.0.0}/PKG-INFO +24 -9
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/README.md +22 -7
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/pyproject.toml +2 -2
- evolver_tools-35.0.0/src/evolver_tools/__init__.py +4 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/cli.py +4 -4
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/agent_b_tool.py +1 -1
- evolver_tools-35.0.0/src/evolver_tools/vendor/ansi_to_txt.py +89 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/b64/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/cal_tool/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/cal_tool/cli.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/chart_cli/__init__.py +1 -1
- evolver_tools-35.0.0/src/evolver_tools/vendor/chrono.py +275 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/colors/__init__.py +1 -1
- evolver_tools-35.0.0/src/evolver_tools/vendor/csv_schema.py +174 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_stats/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_stats/cli.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/diff_csv.py +1 -1
- evolver_tools-35.0.0/src/evolver_tools/vendor/diff_lines.py +166 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/diff_tool/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/dirsize/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/dt_convert.py +1 -1
- evolver_tools-35.0.0/src/evolver_tools/vendor/emoji_cli.py +465 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/env_manager.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/envcheck/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ff/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/find_dups/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/find_dups/cli.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/fmt/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/hashsum/__init__.py +1 -1
- evolver_tools-35.0.0/src/evolver_tools/vendor/html_strip.py +143 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/http_live/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ipcalc/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ipinfo/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/jq_lite/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json2csv/__init__.py +1 -1
- evolver_tools-35.0.0/src/evolver_tools/vendor/json_patch.py +319 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/jsonql/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/license_cli/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/license_cli/cli.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/log_analyzer.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/markdown_check/__init__.py +1 -1
- evolver_tools-35.0.0/src/evolver_tools/vendor/markdown_format.py +246 -0
- evolver_tools-35.0.0/src/evolver_tools/vendor/merge_json.py +87 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/nb/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/passgen/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/portcheck/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/portcheck/__main__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/project_doctor/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ren/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/siege_lite/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/smellfinder/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/sqlite_cli/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/sysmon/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/timer/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/treedir/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/treedir/__main__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/urlparse_tool/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/urlparse_tool/cli.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/uuid_tool/__init__.py +1 -1
- evolver_tools-35.0.0/src/evolver_tools/vendor/validate.py +197 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/web_summary/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/wordcount/__init__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/wordcount/__main__.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/xml2json.py +1 -1
- {evolver_tools-33.0.0 → evolver_tools-35.0.0/src/evolver_tools.egg-info}/PKG-INFO +24 -9
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools.egg-info/SOURCES.txt +10 -0
- evolver_tools-33.0.0/src/evolver_tools/__init__.py +0 -4
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/LICENSE +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/setup.cfg +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/autoreg.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ansi_strip.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/api_tester.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ascii_banner.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ascii_gen.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/audit_log.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/b64/b64.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/backup.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/banner/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/banner/banner.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/base32.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/base58.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/bookmark.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/calendar_cli.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/case_convert.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/cert_check.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/cert_info.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/changelog_gen/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/changelog_gen/changelog_gen.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/changelog_gen.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/chart_cli/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/checksum_dir.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/clipboard/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/clipboard/clipboard.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/code_auditor.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/code_review.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/code_stats.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/colorize.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/colors/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/config_validator.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/config_vault.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/cowsay.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/crc_check.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/cron/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/cron/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/cron_check.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/cron_pretty.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/crontab_helper.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/crypto_box.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/crypto_price.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv2json.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_dedup.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_filter.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_head.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_merge.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_pretty.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_slice.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_sort.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_stats/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_stats/analyzer.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_to_table.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_validate.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/csv_view.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/date_diff.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/db_mate.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/db_schema.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/dedup_files.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/dep_graph.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/dev_dashboard.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/dice_roll.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/diff_files.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/diff_tool/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/diff_yaml.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/disk_cleanup.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/disk_usage/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/disk_usage/disk_usage.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/dns_lookup.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/docker_helper.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/env_diff.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/env_sorter.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/env_template.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/epoch.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/excel2csv.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/factor.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ff/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/figlet_cli.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/figlet_tool.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/file_encrypt.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/file_find.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/file_joiner.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/file_patch.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/file_splitter.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/file_type.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/file_watch.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/find_empty.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/firewall_rule.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/fmt/fmt.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/fold.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/geo_ip.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/git_branch_cleaner.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/git_log_pretty.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/git_stats.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/gzip_cli.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/hash_check.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/hash_file.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/hashsum/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/hex_tool.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/hexdec.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/hexdump.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/html2markdown.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/html2md.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/http_headers.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/http_live/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/http_server.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/http_status.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/humanize.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/image_meta.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ini2json.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ini_parser/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ini_parser/ini_parser.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ip_info.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ip_location.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ipcalc/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ipinfo/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/join.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/joke.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/jq_lite/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json2csv/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json2ini.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_diff.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_flatten.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_keys.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_merge.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_path.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_pretty/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_pretty/json_pretty.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_schema_validate.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_sort.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_to_table.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/json_to_yaml.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/jsonql/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/jwt_decode.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/key_value_store.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/license.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/license_cli/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/link_check.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/log_hawk.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/log_tail.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/mac_address.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/macrogen.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/markdown_lint.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/markdown_preview.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/markdown_to_html.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/markdown_toc.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/math_eval.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/media_studio.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/morse.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/nb/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/net_analyzer.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/net_speed.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/network_scan.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/nl.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/note_taker.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/otp_gen.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/password_strength.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/pdf_info.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/pdf_text.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/pipe_viewer.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/pomodoro.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/port_scan.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/pr_tool/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/pr_tool/pr_tool.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/process_kill.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/progress_bar.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/project_doctor/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/qc_calc.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/qc_report.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/qc_sample.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/qr_cli.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/qrcode.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/quote.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/quote_tool/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/quote_tool/quote.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/rainbow.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/random.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/random_cli.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/random_string.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/reminder.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ren/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/replace_text.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/restore.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/rot13.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/route_trace.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/scan_open_ports.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/scan_ports.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/screen_recorder.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/screenshot_cli.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/search_files.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/search_history.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/secret_scanner.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/seq.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/service_check.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/shuffle.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/siege_lite/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/slugify.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/smellfinder/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/sort/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/sort/sort.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/spinner.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/split.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/split_tool/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/split_tool/split.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/sql2csv.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/sqlite_cli/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ssh_key_gen.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/ssl_check.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/stopwatch.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/subnet.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/sysmon/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/sysmon_pro.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/system_info.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/temp_cleaner.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/template.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/text_dedent.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/text_stats.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/text_wrap.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/time_duration.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/timeout.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/timer_pro/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/timer_pro/timer_pro.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/timer_pro.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/todo_cli.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/toml2json.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/tr.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/tree.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/tsv2csv.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/uniq_tool/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/uniq_tool/uniq.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/unit_convert.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/uri_encode.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/url_parser.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/uuid_gen.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/uuid_tool/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/watch.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/weather_cli.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/web_download.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/web_summary/__main__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/whois_lookup.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/world_clock.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/xml_format.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/yaml2json/__init__.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/yaml2json/yaml2json.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/yaml2toml.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/yaml_validate.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools/vendor/yes.py +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools.egg-info/dependency_links.txt +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools.egg-info/entry_points.txt +0 -0
- {evolver_tools-33.0.0 → evolver_tools-35.0.0}/src/evolver_tools.egg-info/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: evolver-tools
|
|
3
|
-
Version:
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 35.0.0
|
|
4
|
+
Summary: 244 CLI tools + 9 flagship projects — one pip install
|
|
5
5
|
Author: EVOLVER
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://evolver-dev.github.io/evolver-tools
|
|
@@ -22,17 +22,17 @@ Dynamic: license-file
|
|
|
22
22
|
|
|
23
23
|
# EVOLVER Tools
|
|
24
24
|
|
|
25
|
-
**
|
|
25
|
+
**249 CLI tools + 9 flagship projects — one `pip install`.**
|
|
26
26
|
|
|
27
|
-
Zero-dependency (
|
|
27
|
+
Zero-dependency (245/249), cross-platform, production-ready. Version **35.0.0**.
|
|
28
28
|
Systems ops, data processing, text manipulation, security, dev tooling, and creative utilities.
|
|
29
|
-
All in a single install — not
|
|
29
|
+
All in a single install — not 239 separate packages.
|
|
30
30
|
|
|
31
31
|
## Quick Start
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
pip install evolver-tools
|
|
35
|
-
evtool list # Show all
|
|
35
|
+
evtool list # Show all 249 tools
|
|
36
36
|
evtool sysmon # Launch system monitor
|
|
37
37
|
evtool ff < data.txt # Fuzzy search through data
|
|
38
38
|
evtool csv-stats data.csv # Analyze CSV columns
|
|
@@ -281,8 +281,7 @@ Nine flagship projects ship as integrated CLI+TUI suites within evolver-tools:
|
|
|
281
281
|
## Requirements
|
|
282
282
|
|
|
283
283
|
- Python 3.8+
|
|
284
|
-
- No external dependencies for
|
|
285
|
-
- A few tools (sysmon, sysmon-pro, etc.) optionally use psutil
|
|
284
|
+
- No external dependencies for 239 of 239 tools (stdlib only)
|
|
286
285
|
- Network-dependent tools (ipinfo, weather, etc.) use public APIs
|
|
287
286
|
|
|
288
287
|
## Pricing
|
|
@@ -291,7 +290,7 @@ evolver-tools is **MIT open source** and free forever for all tools.
|
|
|
291
290
|
|
|
292
291
|
| Tier | Price | What you get |
|
|
293
292
|
|------|-------|-------------|
|
|
294
|
-
| **Free (MIT)** | ¥0 | All
|
|
293
|
+
| **Free (MIT)** | ¥0 | All 239 tools, full source, forever |
|
|
295
294
|
| **Full Suite** | ¥79 one-time | All tools + priority support + early access + name in credits |
|
|
296
295
|
| **Sponsor** | ¥5/month | GitHub Sponsors badge + Discord + vote on priorities |
|
|
297
296
|
| **Enterprise Basic** | ¥500/year | Custom tool development |
|
|
@@ -300,6 +299,22 @@ evolver-tools is **MIT open source** and free forever for all tools.
|
|
|
300
299
|
|
|
301
300
|
👉 [View full pricing page](https://evolver-dev.github.io/evolver-tools/pricing/) — feature comparison, testimonials, and FAQ.
|
|
302
301
|
|
|
302
|
+
## Changelog
|
|
303
|
+
|
|
304
|
+
### v35.0.0 — 2026-06-01 (+5 tools, 249 total)
|
|
305
|
+
- **merge-json** — Deep merge multiple JSON files (arrays concatenate, dicts recurse)
|
|
306
|
+
- **validate** — Generic file validator (JSON/YAML/CSV/TOML/XML auto-detect)
|
|
307
|
+
- **diff-lines** — Line-by-line diff between two files (color, side-by-side)
|
|
308
|
+
- **csv-schema** — Infer CSV schema (column types, nulls, stats, samples)
|
|
309
|
+
- **chrono** — Advanced date/time calculator (durations, workdays, ranges, age)
|
|
310
|
+
|
|
311
|
+
### v34.0.0 — 2026-06-01 (+5 tools, 244 total)
|
|
312
|
+
- **emoji-cli** — Search and display emoji (230+ emoji, categories, --random)
|
|
313
|
+
- **html-strip** — Strip HTML tags, extract plain text (stdin/file, --preserve-links)
|
|
314
|
+
- **json-patch** — Apply JSON Patch (RFC 6902) operations to JSON files
|
|
315
|
+
- **markdown-format** — Format/beautify Markdown tables and lists
|
|
316
|
+
- **ansi-to-txt** — Strip ANSI escape codes, convert to plain text
|
|
317
|
+
|
|
303
318
|
Support the project via one-time purchase (¥79) or monthly sponsorship on [GitHub Sponsors](https://github.com/sponsors/evolver-dev).
|
|
304
319
|
|
|
305
320
|
## Links
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# EVOLVER Tools
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**249 CLI tools + 9 flagship projects — one `pip install`.**
|
|
4
4
|
|
|
5
|
-
Zero-dependency (
|
|
5
|
+
Zero-dependency (245/249), cross-platform, production-ready. Version **35.0.0**.
|
|
6
6
|
Systems ops, data processing, text manipulation, security, dev tooling, and creative utilities.
|
|
7
|
-
All in a single install — not
|
|
7
|
+
All in a single install — not 239 separate packages.
|
|
8
8
|
|
|
9
9
|
## Quick Start
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
pip install evolver-tools
|
|
13
|
-
evtool list # Show all
|
|
13
|
+
evtool list # Show all 249 tools
|
|
14
14
|
evtool sysmon # Launch system monitor
|
|
15
15
|
evtool ff < data.txt # Fuzzy search through data
|
|
16
16
|
evtool csv-stats data.csv # Analyze CSV columns
|
|
@@ -259,8 +259,7 @@ Nine flagship projects ship as integrated CLI+TUI suites within evolver-tools:
|
|
|
259
259
|
## Requirements
|
|
260
260
|
|
|
261
261
|
- Python 3.8+
|
|
262
|
-
- No external dependencies for
|
|
263
|
-
- A few tools (sysmon, sysmon-pro, etc.) optionally use psutil
|
|
262
|
+
- No external dependencies for 239 of 239 tools (stdlib only)
|
|
264
263
|
- Network-dependent tools (ipinfo, weather, etc.) use public APIs
|
|
265
264
|
|
|
266
265
|
## Pricing
|
|
@@ -269,7 +268,7 @@ evolver-tools is **MIT open source** and free forever for all tools.
|
|
|
269
268
|
|
|
270
269
|
| Tier | Price | What you get |
|
|
271
270
|
|------|-------|-------------|
|
|
272
|
-
| **Free (MIT)** | ¥0 | All
|
|
271
|
+
| **Free (MIT)** | ¥0 | All 239 tools, full source, forever |
|
|
273
272
|
| **Full Suite** | ¥79 one-time | All tools + priority support + early access + name in credits |
|
|
274
273
|
| **Sponsor** | ¥5/month | GitHub Sponsors badge + Discord + vote on priorities |
|
|
275
274
|
| **Enterprise Basic** | ¥500/year | Custom tool development |
|
|
@@ -278,6 +277,22 @@ evolver-tools is **MIT open source** and free forever for all tools.
|
|
|
278
277
|
|
|
279
278
|
👉 [View full pricing page](https://evolver-dev.github.io/evolver-tools/pricing/) — feature comparison, testimonials, and FAQ.
|
|
280
279
|
|
|
280
|
+
## Changelog
|
|
281
|
+
|
|
282
|
+
### v35.0.0 — 2026-06-01 (+5 tools, 249 total)
|
|
283
|
+
- **merge-json** — Deep merge multiple JSON files (arrays concatenate, dicts recurse)
|
|
284
|
+
- **validate** — Generic file validator (JSON/YAML/CSV/TOML/XML auto-detect)
|
|
285
|
+
- **diff-lines** — Line-by-line diff between two files (color, side-by-side)
|
|
286
|
+
- **csv-schema** — Infer CSV schema (column types, nulls, stats, samples)
|
|
287
|
+
- **chrono** — Advanced date/time calculator (durations, workdays, ranges, age)
|
|
288
|
+
|
|
289
|
+
### v34.0.0 — 2026-06-01 (+5 tools, 244 total)
|
|
290
|
+
- **emoji-cli** — Search and display emoji (230+ emoji, categories, --random)
|
|
291
|
+
- **html-strip** — Strip HTML tags, extract plain text (stdin/file, --preserve-links)
|
|
292
|
+
- **json-patch** — Apply JSON Patch (RFC 6902) operations to JSON files
|
|
293
|
+
- **markdown-format** — Format/beautify Markdown tables and lists
|
|
294
|
+
- **ansi-to-txt** — Strip ANSI escape codes, convert to plain text
|
|
295
|
+
|
|
281
296
|
Support the project via one-time purchase (¥79) or monthly sponsorship on [GitHub Sponsors](https://github.com/sponsors/evolver-dev).
|
|
282
297
|
|
|
283
298
|
## Links
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "evolver-tools"
|
|
7
|
-
version = "
|
|
8
|
-
description = "
|
|
7
|
+
version = "35.0.0"
|
|
8
|
+
description = "244 CLI tools + 9 flagship projects — one pip install"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
11
11
|
requires-python = ">=3.8"
|
|
@@ -14,21 +14,21 @@ from evolver_tools.autoreg import auto_discover
|
|
|
14
14
|
def list_tools():
|
|
15
15
|
"""Display all available tools."""
|
|
16
16
|
tools = auto_discover()
|
|
17
|
-
print(f'\x1b[1;36m===== EVOLVER Tools
|
|
17
|
+
print(f'\x1b[1;36m===== EVOLVER Tools v35.0.0 =====\x1b[0m')
|
|
18
18
|
print()
|
|
19
19
|
for name, info in sorted(tools.items()):
|
|
20
20
|
print(f' \033[1;33m{name:<18}\033[0m {info["desc"]}')
|
|
21
21
|
print()
|
|
22
22
|
print(f' Total: {len(tools)} tools')
|
|
23
23
|
print()
|
|
24
|
-
print('Usage:
|
|
25
|
-
print('
|
|
24
|
+
print('Usage: evtool <toolname> [args...]')
|
|
25
|
+
print(' evtool list')
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def run_tool(tool_name, args):
|
|
29
29
|
tools = auto_discover()
|
|
30
30
|
if tool_name not in tools:
|
|
31
|
-
print(f'Unknown tool: {tool_name}')
|
|
31
|
+
print(f'Unknown tool: {tool_name}. Use \"evtool list\" to see all tools.')
|
|
32
32
|
sys.exit(1)
|
|
33
33
|
info = tools[tool_name]
|
|
34
34
|
mod_path = info["module"]
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""ansi-to-txt — Convert ANSI-colored terminal output to plain text."""
|
|
3
|
+
TOOL_META = {"name": "ansi-to-txt", "desc": "Strip ANSI escape codes, convert to plain text", "func": "main"}
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
import re
|
|
7
|
+
import argparse
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Regex to match ANSI escape sequences
|
|
11
|
+
ANSI_ESCAPE = re.compile(r'\x1b\[[0-9;]*[a-zA-Z]|\x1b\][0-9;]*(?:\x07|\x1b\\)|\x1b[PX^_].*?(?:\x07|\x1b\\)')
|
|
12
|
+
|
|
13
|
+
# C1 control characters (rare but possible)
|
|
14
|
+
C1_CONTROLS = re.compile(r'[\x80-\x9a\x9c\x9b\x9d-\x9f]')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def strip_ansi(text):
|
|
18
|
+
"""Remove all ANSI escape sequences from text."""
|
|
19
|
+
text = ANSI_ESCAPE.sub('', text)
|
|
20
|
+
text = C1_CONTROLS.sub('', text)
|
|
21
|
+
return text
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def simplify_ansi(text):
|
|
25
|
+
"""Replace known ANSI formatting with simple markers."""
|
|
26
|
+
# Bold → *text*
|
|
27
|
+
text = re.sub(r'\x1b\[1m(.*?)\x1b\[0m', r'*\1*', text)
|
|
28
|
+
text = re.sub(r'\x1b\[1m(.*?)\x1b\[(?:2[2-9]|3[0-7])?m', r'*\1*', text)
|
|
29
|
+
# Underline → _text_
|
|
30
|
+
text = re.sub(r'\x1b\[4m(.*?)\x1b\[0m', r'_\1_', text)
|
|
31
|
+
# Remove all remaining sequences
|
|
32
|
+
text = ANSI_ESCAPE.sub('', text)
|
|
33
|
+
text = C1_CONTROLS.sub('', text)
|
|
34
|
+
return text
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def main():
|
|
38
|
+
parser = argparse.ArgumentParser(
|
|
39
|
+
description="Strip ANSI escape codes and convert to plain text.",
|
|
40
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
41
|
+
epilog="""
|
|
42
|
+
Examples:
|
|
43
|
+
command-with-colors | ansi-to-txt
|
|
44
|
+
ansi-to-txt --file output.log > clean.txt
|
|
45
|
+
ls --color=always | ansi-to-txt
|
|
46
|
+
make 2>&1 | ansi-to-txt --simplify
|
|
47
|
+
cat ansi_output.txt | ansi-to-txt -o clean.txt
|
|
48
|
+
""",
|
|
49
|
+
)
|
|
50
|
+
parser.add_argument("--file", "-f", help="File with ANSI codes to process")
|
|
51
|
+
parser.add_argument("--output", "-o", help="Output file (default: stdout)")
|
|
52
|
+
parser.add_argument("--simplify", "-s", action="store_true",
|
|
53
|
+
help="Replace bold/underline with *text*/_text_ markers instead of stripping")
|
|
54
|
+
args = parser.parse_args()
|
|
55
|
+
|
|
56
|
+
if args.file:
|
|
57
|
+
try:
|
|
58
|
+
with open(args.file, "rb") as f:
|
|
59
|
+
raw = f.read()
|
|
60
|
+
except FileNotFoundError:
|
|
61
|
+
print(f"Error: file not found: {args.file}", file=sys.stderr)
|
|
62
|
+
sys.exit(1)
|
|
63
|
+
except Exception as e:
|
|
64
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
65
|
+
sys.exit(1)
|
|
66
|
+
else:
|
|
67
|
+
raw = sys.stdin.buffer.read()
|
|
68
|
+
|
|
69
|
+
# Decode with replacement for bad bytes
|
|
70
|
+
text = raw.decode("utf-8", errors="replace")
|
|
71
|
+
|
|
72
|
+
if args.simplify:
|
|
73
|
+
result = simplify_ansi(text)
|
|
74
|
+
else:
|
|
75
|
+
result = strip_ansi(text)
|
|
76
|
+
|
|
77
|
+
if args.output:
|
|
78
|
+
try:
|
|
79
|
+
with open(args.output, "w", encoding="utf-8") as f:
|
|
80
|
+
f.write(result)
|
|
81
|
+
except Exception as e:
|
|
82
|
+
print(f"Error writing: {e}", file=sys.stderr)
|
|
83
|
+
sys.exit(1)
|
|
84
|
+
else:
|
|
85
|
+
sys.stdout.write(result)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
main()
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""chrono — Advanced date/time calculator.
|
|
3
|
+
|
|
4
|
+
Calculate durations, add/subtract time, find business days,
|
|
5
|
+
convert timezones, and generate date ranges.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
chrono now # Current timestamp
|
|
9
|
+
chrono days 2024-01-01 2024-12-31 # Days between dates
|
|
10
|
+
chrono add 2024-01-01 90 days # Add/subtract time
|
|
11
|
+
chrono workdays 2024-01-01 2024-12-31 # Business days between dates
|
|
12
|
+
chrono range 2024-01-01 2024-01-31 3d # Generate date range with step
|
|
13
|
+
chrono age 1990-06-15 # Age from birthdate
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import sys
|
|
17
|
+
import os
|
|
18
|
+
import re
|
|
19
|
+
from datetime import datetime, date, timedelta
|
|
20
|
+
|
|
21
|
+
TOOL_META = {
|
|
22
|
+
"name": "chrono",
|
|
23
|
+
"func": "main",
|
|
24
|
+
"desc": "Advanced date/time calculator (durations, business days, ranges, age)",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
|
28
|
+
MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
|
29
|
+
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
|
30
|
+
|
|
31
|
+
UNITS = {
|
|
32
|
+
"d": "days", "day": "days", "days": "days",
|
|
33
|
+
"w": "weeks", "week": "weeks", "weeks": "weeks",
|
|
34
|
+
"m": "months", "month": "months", "months": "months",
|
|
35
|
+
"y": "years", "year": "years", "years": "years",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def parse_date(s):
|
|
40
|
+
"""Parse a date string into a date object."""
|
|
41
|
+
s = s.strip().strip('"').strip("'")
|
|
42
|
+
|
|
43
|
+
if s.lower() in ("now", "today"):
|
|
44
|
+
return date.today()
|
|
45
|
+
|
|
46
|
+
formats = [
|
|
47
|
+
"%Y-%m-%d", "%Y/%m/%d", "%d-%m-%Y", "%d/%m/%Y",
|
|
48
|
+
"%m-%d-%Y", "%m/%d/%Y", "%Y%m%d",
|
|
49
|
+
]
|
|
50
|
+
for fmt in formats:
|
|
51
|
+
try:
|
|
52
|
+
return datetime.strptime(s, fmt).date()
|
|
53
|
+
except ValueError:
|
|
54
|
+
continue
|
|
55
|
+
print(f"Error: cannot parse date '{s}'", file=sys.stderr)
|
|
56
|
+
print("Supported formats: YYYY-MM-DD, YYYY/MM/DD, DD-MM-YYYY", file=sys.stderr)
|
|
57
|
+
sys.exit(1)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def parse_delta(s):
|
|
61
|
+
"""Parse a time delta string like '90 days', '2w', '3m', '1y'."""
|
|
62
|
+
s = s.strip()
|
|
63
|
+
m = re.match(r"^(-?\d+)\s*(day|days|d|week|weeks|w|month|months|m|year|years|y)$", s, re.I)
|
|
64
|
+
if not m:
|
|
65
|
+
print(f"Error: cannot parse duration '{s}'", file=sys.stderr)
|
|
66
|
+
print("Examples: 90 days, 2w, 3m, 1y, -7d", file=sys.stderr)
|
|
67
|
+
sys.exit(1)
|
|
68
|
+
|
|
69
|
+
num = int(m.group(1))
|
|
70
|
+
unit = m.group(2).lower()
|
|
71
|
+
|
|
72
|
+
if unit in ("d", "day", "days"):
|
|
73
|
+
return timedelta(days=num)
|
|
74
|
+
elif unit in ("w", "week", "weeks"):
|
|
75
|
+
return timedelta(weeks=num)
|
|
76
|
+
else:
|
|
77
|
+
# For months/years, return a proxy that we handle specially
|
|
78
|
+
return ("month_year", num, unit in ("y", "year", "years"))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def format_date(d):
|
|
82
|
+
"""Format a date nicely."""
|
|
83
|
+
return f"{WEEKDAYS[d.weekday()]}, {d.strftime('%Y-%m-%d')}"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def cmd_now(*_):
|
|
87
|
+
now = datetime.now()
|
|
88
|
+
d = now.date()
|
|
89
|
+
t = now.time()
|
|
90
|
+
print(f"Today: {format_date(d)}")
|
|
91
|
+
print(f"Time: {t.strftime('%H:%M:%S')}")
|
|
92
|
+
print(f"ISO: {now.isoformat()}")
|
|
93
|
+
print(f"Epoch: {int(now.timestamp())}")
|
|
94
|
+
print(f"DOY: {d.timetuple().tm_yday}/366")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def cmd_days(args):
|
|
98
|
+
if len(args) < 2:
|
|
99
|
+
print("Usage: chrono days <date1> <date2>", file=sys.stderr)
|
|
100
|
+
sys.exit(1)
|
|
101
|
+
d1 = parse_date(args[0])
|
|
102
|
+
d2 = parse_date(args[1])
|
|
103
|
+
delta = (d2 - d1).days
|
|
104
|
+
print(f"{format_date(d1)} → {format_date(d2)}")
|
|
105
|
+
print(f"Difference: {abs(delta)} day{'s' if abs(delta) != 1 else ''}")
|
|
106
|
+
if delta < 0:
|
|
107
|
+
print("Direction: backward")
|
|
108
|
+
elif delta > 0:
|
|
109
|
+
print("Direction: forward")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def cmd_add(args):
|
|
113
|
+
if len(args) < 1:
|
|
114
|
+
print("Usage: chrono add <date> <delta> [--format ISO|full]", file=sys.stderr)
|
|
115
|
+
sys.exit(1)
|
|
116
|
+
d = parse_date(args[0])
|
|
117
|
+
|
|
118
|
+
if len(args) >= 2:
|
|
119
|
+
delta = parse_delta(args[1])
|
|
120
|
+
if isinstance(delta, tuple):
|
|
121
|
+
_, num, is_year = delta
|
|
122
|
+
if is_year:
|
|
123
|
+
new_year = d.year + num
|
|
124
|
+
try:
|
|
125
|
+
d = d.replace(year=new_year)
|
|
126
|
+
except ValueError:
|
|
127
|
+
# Handle Feb 29 edge case
|
|
128
|
+
import calendar
|
|
129
|
+
last_day = calendar.monthrange(new_year, d.month)[1]
|
|
130
|
+
d = d.replace(year=new_year, day=min(d.day, last_day))
|
|
131
|
+
else:
|
|
132
|
+
new_month = d.month + num
|
|
133
|
+
year_shift = (new_month - 1) // 12
|
|
134
|
+
new_month = ((new_month - 1) % 12) + 1
|
|
135
|
+
new_year = d.year + year_shift
|
|
136
|
+
import calendar
|
|
137
|
+
last_day = calendar.monthrange(new_year, new_month)[1]
|
|
138
|
+
d = d.replace(year=new_year, month=new_month, day=min(d.day, last_day))
|
|
139
|
+
else:
|
|
140
|
+
d = d + delta
|
|
141
|
+
|
|
142
|
+
show_fmt = "--format" in args
|
|
143
|
+
if show_fmt:
|
|
144
|
+
idx = args.index("--format")
|
|
145
|
+
fmt_type = args[idx + 1] if idx + 1 < len(args) else "full"
|
|
146
|
+
|
|
147
|
+
print(format_date(d))
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def cmd_workdays(args):
|
|
151
|
+
if len(args) < 2:
|
|
152
|
+
print("Usage: chrono workdays <date1> <date2>", file=sys.stderr)
|
|
153
|
+
sys.exit(1)
|
|
154
|
+
d1 = parse_date(args[0])
|
|
155
|
+
d2 = parse_date(args[1])
|
|
156
|
+
|
|
157
|
+
if d1 > d2:
|
|
158
|
+
d1, d2 = d2, d1
|
|
159
|
+
|
|
160
|
+
count = 0
|
|
161
|
+
current = d1
|
|
162
|
+
while current <= d2:
|
|
163
|
+
if current.weekday() < 5: # Mon-Fri
|
|
164
|
+
count += 1
|
|
165
|
+
current += timedelta(days=1)
|
|
166
|
+
|
|
167
|
+
print(f"{format_date(d1)} → {format_date(d2)}")
|
|
168
|
+
print(f"Calendar days: {(d2 - d1).days}")
|
|
169
|
+
print(f"Workdays: {count}")
|
|
170
|
+
print(f"Weekends: {(d2 - d1).days - count}")
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def cmd_range(args):
|
|
174
|
+
if len(args) < 2:
|
|
175
|
+
print("Usage: chrono range <start> <end> [step]", file=sys.stderr)
|
|
176
|
+
print(" step examples: 1d (default), 2d, 1w, 1m")
|
|
177
|
+
sys.exit(1)
|
|
178
|
+
|
|
179
|
+
start = parse_date(args[0])
|
|
180
|
+
end = parse_date(args[1])
|
|
181
|
+
|
|
182
|
+
step_delta = timedelta(days=1)
|
|
183
|
+
if len(args) >= 3:
|
|
184
|
+
delta = parse_delta(args[2])
|
|
185
|
+
if isinstance(delta, tuple):
|
|
186
|
+
print("Error: step must be days or weeks only", file=sys.stderr)
|
|
187
|
+
sys.exit(1)
|
|
188
|
+
step_delta = delta
|
|
189
|
+
if step_delta.days <= 0:
|
|
190
|
+
print("Error: step must be positive", file=sys.stderr)
|
|
191
|
+
sys.exit(1)
|
|
192
|
+
|
|
193
|
+
current = start
|
|
194
|
+
count = 0
|
|
195
|
+
while current <= end:
|
|
196
|
+
print(format_date(current))
|
|
197
|
+
current += step_delta
|
|
198
|
+
count += 1
|
|
199
|
+
|
|
200
|
+
print(f"\n{count} dates in range")
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def cmd_age(args):
|
|
204
|
+
if not args:
|
|
205
|
+
print("Usage: chrono age <birthdate> [reference_date]", file=sys.stderr)
|
|
206
|
+
sys.exit(1)
|
|
207
|
+
|
|
208
|
+
birth = parse_date(args[0])
|
|
209
|
+
ref = parse_date(args[1]) if len(args) >= 2 else date.today()
|
|
210
|
+
|
|
211
|
+
if birth > ref:
|
|
212
|
+
print(f"Error: birthdate {birth} is after reference date {ref}", file=sys.stderr)
|
|
213
|
+
sys.exit(1)
|
|
214
|
+
|
|
215
|
+
years = ref.year - birth.year
|
|
216
|
+
months = ref.month - birth.month
|
|
217
|
+
days = ref.day - birth.day
|
|
218
|
+
|
|
219
|
+
if days < 0:
|
|
220
|
+
months -= 1
|
|
221
|
+
import calendar
|
|
222
|
+
days += calendar.monthrange(ref.year, ref.month - 1 if ref.month > 1 else 12)[0]
|
|
223
|
+
if months < 0:
|
|
224
|
+
years -= 1
|
|
225
|
+
months += 12
|
|
226
|
+
|
|
227
|
+
total_days = (ref - birth).days
|
|
228
|
+
|
|
229
|
+
print(f"Birth: {format_date(birth)}")
|
|
230
|
+
print(f"Reference: {format_date(ref)}")
|
|
231
|
+
print(f"Age: {years} years, {months} months, {days} days")
|
|
232
|
+
print(f"Total days: {total_days}")
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
COMMANDS = {
|
|
236
|
+
"now": cmd_now,
|
|
237
|
+
"days": cmd_days,
|
|
238
|
+
"add": cmd_add,
|
|
239
|
+
"workdays": cmd_workdays,
|
|
240
|
+
"range": cmd_range,
|
|
241
|
+
"age": cmd_age,
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def main():
|
|
246
|
+
args = sys.argv[1:]
|
|
247
|
+
|
|
248
|
+
if not args or args[0] in ("-h", "--help"):
|
|
249
|
+
print("Usage: chrono <command> [args...]")
|
|
250
|
+
print()
|
|
251
|
+
print("Commands:")
|
|
252
|
+
print(" now Current date/time info")
|
|
253
|
+
print(" days <d1> <d2> Days between two dates")
|
|
254
|
+
print(" add <date> <delta> Add/subtract time (90d, 2w, 3m, 1y, -7d)")
|
|
255
|
+
print(" workdays <d1> <d2> Business days between dates")
|
|
256
|
+
print(" range <start> <end> [step] Generate date range")
|
|
257
|
+
print(" age <birthdate> [ref] Calculate age")
|
|
258
|
+
print()
|
|
259
|
+
print("Date formats: YYYY-MM-DD (YYYY/MM/DD, DD-MM-YYYY)")
|
|
260
|
+
print(" 'now' or 'today' for current date")
|
|
261
|
+
return
|
|
262
|
+
|
|
263
|
+
cmd = args[0]
|
|
264
|
+
cmd_args = args[1:]
|
|
265
|
+
|
|
266
|
+
if cmd not in COMMANDS:
|
|
267
|
+
print(f"Error: unknown command '{cmd}'", file=sys.stderr)
|
|
268
|
+
print(f"Available: {', '.join(COMMANDS.keys())}", file=sys.stderr)
|
|
269
|
+
sys.exit(1)
|
|
270
|
+
|
|
271
|
+
COMMANDS[cmd](cmd_args)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
if __name__ == "__main__":
|
|
275
|
+
main()
|