cct-cli 0.7.9.0__py3-none-any.whl
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.
- calc_terminal/__init__.py +14 -0
- calc_terminal/__main__.py +14 -0
- calc_terminal/activity.py +1334 -0
- calc_terminal/agent.py +3387 -0
- calc_terminal/agent_runtime.py +519 -0
- calc_terminal/ai_context.py +447 -0
- calc_terminal/ai_modes.py +752 -0
- calc_terminal/ai_personalization.py +286 -0
- calc_terminal/ai_preview_feedback.py +213 -0
- calc_terminal/aicore.py +2572 -0
- calc_terminal/anim.py +367 -0
- calc_terminal/app.py +3685 -0
- calc_terminal/art.py +639 -0
- calc_terminal/atomsim.py +368 -0
- calc_terminal/attachments.py +743 -0
- calc_terminal/benchmark_system.py +414 -0
- calc_terminal/browser/__init__.py +36 -0
- calc_terminal/browser/browser_state.py +346 -0
- calc_terminal/browser/devserver.py +176 -0
- calc_terminal/browser/engine.py +494 -0
- calc_terminal/browser/navigation.py +84 -0
- calc_terminal/browser/preview.py +429 -0
- calc_terminal/browser/preview_entry.py +95 -0
- calc_terminal/browser/project_detector.py +144 -0
- calc_terminal/browser/server.py +449 -0
- calc_terminal/browser/state.py +75 -0
- calc_terminal/browser/watcher.py +99 -0
- calc_terminal/browser_gui/__init__.py +1 -0
- calc_terminal/browser_gui/__main__.py +3 -0
- calc_terminal/browser_gui/launcher.py +173 -0
- calc_terminal/browser_gui/playwright_browser.py +117 -0
- calc_terminal/browser_gui/qt_browser.py +1501 -0
- calc_terminal/browser_gui/webview_browser.py +57 -0
- calc_terminal/capabilities/__init__.py +35 -0
- calc_terminal/capabilities/adapters/__init__.py +33 -0
- calc_terminal/capabilities/adapters/bioinformatics.py +204 -0
- calc_terminal/capabilities/adapters/browser_adapter.py +205 -0
- calc_terminal/capabilities/adapters/filesystem.py +206 -0
- calc_terminal/capabilities/adapters/git_adapter.py +202 -0
- calc_terminal/capabilities/adapters/jupyter_adapter.py +138 -0
- calc_terminal/capabilities/adapters/ml_frameworks.py +158 -0
- calc_terminal/capabilities/adapters/platforms.py +200 -0
- calc_terminal/capabilities/adapters/python_exec.py +93 -0
- calc_terminal/capabilities/adapters/quantum_adapter.py +150 -0
- calc_terminal/capabilities/adapters/scientific_comp.py +123 -0
- calc_terminal/capabilities/adapters/structural_bio.py +161 -0
- calc_terminal/capabilities/adapters/terminal.py +99 -0
- calc_terminal/capabilities/bus.py +178 -0
- calc_terminal/capabilities/discovery.py +207 -0
- calc_terminal/capabilities/schema.py +221 -0
- calc_terminal/cat.ico +0 -0
- calc_terminal/cat_browser.py +2018 -0
- calc_terminal/chat_store.py +703 -0
- calc_terminal/cli.py +1178 -0
- calc_terminal/code_editor.py +640 -0
- calc_terminal/collaboration.py +723 -0
- calc_terminal/commands_data.py +139 -0
- calc_terminal/compatibility_engine.py +352 -0
- calc_terminal/compute/__init__.py +31 -0
- calc_terminal/compute/fabric.py +350 -0
- calc_terminal/config.py +227 -0
- calc_terminal/core/__init__.py +41 -0
- calc_terminal/core/checkpoint.py +156 -0
- calc_terminal/core/input/__init__.py +45 -0
- calc_terminal/core/mode_registry.py +300 -0
- calc_terminal/core/project_graph.py +172 -0
- calc_terminal/core/recovery.py +129 -0
- calc_terminal/core/security_layer.py +112 -0
- calc_terminal/core/task_graph.py +202 -0
- calc_terminal/core/unified_runtime.py +184 -0
- calc_terminal/core/verification.py +257 -0
- calc_terminal/customization.py +1566 -0
- calc_terminal/derivations.py +153 -0
- calc_terminal/device_control.py +263 -0
- calc_terminal/diagnostics/__init__.py +27 -0
- calc_terminal/diagnostics/doctor_engine.py +382 -0
- calc_terminal/diagnostics/self_test.py +247 -0
- calc_terminal/doctor.py +519 -0
- calc_terminal/easter_eggs.py +274 -0
- calc_terminal/editor/__init__.py +1 -0
- calc_terminal/editor/actions.py +263 -0
- calc_terminal/editor/commands.py +160 -0
- calc_terminal/editor/shortcuts.py +226 -0
- calc_terminal/engine.py +259 -0
- calc_terminal/errors.py +120 -0
- calc_terminal/event_stream.py +146 -0
- calc_terminal/eventbus.py +133 -0
- calc_terminal/extensions.py +733 -0
- calc_terminal/fallback_cli.py +1321 -0
- calc_terminal/first_run.py +265 -0
- calc_terminal/fomoji_auth.py +1043 -0
- calc_terminal/formulas.py +82 -0
- calc_terminal/fs_cache.py +121 -0
- calc_terminal/fs_watcher.py +277 -0
- calc_terminal/game.py +193 -0
- calc_terminal/gen1.py +5 -0
- calc_terminal/generators.py +245 -0
- calc_terminal/gestures/__init__.py +42 -0
- calc_terminal/gestures/bindings.py +175 -0
- calc_terminal/gestures/manager.py +477 -0
- calc_terminal/goodbye.py +363 -0
- calc_terminal/gpu3d.py +290 -0
- calc_terminal/graphs.py +358 -0
- calc_terminal/hardware_analyzer.py +440 -0
- calc_terminal/host/__init__.py +30 -0
- calc_terminal/host/browser_manager.py +187 -0
- calc_terminal/host/desktop.py +1386 -0
- calc_terminal/host/launcher.py +395 -0
- calc_terminal/host/terminal.py +279 -0
- calc_terminal/identity.py +216 -0
- calc_terminal/input/__init__.py +54 -0
- calc_terminal/input/capabilities.py +258 -0
- calc_terminal/input/focus.py +87 -0
- calc_terminal/input/gestures.py +64 -0
- calc_terminal/input/pointer.py +114 -0
- calc_terminal/input/touch.py +345 -0
- calc_terminal/keys.py +84 -0
- calc_terminal/live_automation.py +165 -0
- calc_terminal/mathtext.py +433 -0
- calc_terminal/mcp.py +386 -0
- calc_terminal/memory.py +337 -0
- calc_terminal/memory_v2.py +479 -0
- calc_terminal/metrics.py +333 -0
- calc_terminal/mode_detection.py +146 -0
- calc_terminal/model.py +2431 -0
- calc_terminal/model_router.py +665 -0
- calc_terminal/models/__init__.py +0 -0
- calc_terminal/models/active_state.py +187 -0
- calc_terminal/models/dynamic_registry.py +584 -0
- calc_terminal/models/manager.py +781 -0
- calc_terminal/models/model_metadata.json +3526 -0
- calc_terminal/models/profiles.py +194 -0
- calc_terminal/models/registry.py +265 -0
- calc_terminal/models/schema.py +197 -0
- calc_terminal/models/validator.py +287 -0
- calc_terminal/models/verification_engine.py +368 -0
- calc_terminal/native_picker.py +215 -0
- calc_terminal/ollama_catalog.py +279 -0
- calc_terminal/ollama_download.py +233 -0
- calc_terminal/orchestrator.py +304 -0
- calc_terminal/package_research.py +322 -0
- calc_terminal/packages.py +1024 -0
- calc_terminal/pc_specs.py +116 -0
- calc_terminal/permissions.py +334 -0
- calc_terminal/pet.py +106 -0
- calc_terminal/pipeline.py +505 -0
- calc_terminal/platform/__init__.py +491 -0
- calc_terminal/platform/desktop.py +491 -0
- calc_terminal/platform/web.py +781 -0
- calc_terminal/preview/__init__.py +1 -0
- calc_terminal/preview/dev_server.py +303 -0
- calc_terminal/preview/diagnostics.py +131 -0
- calc_terminal/preview/live_reload.py +66 -0
- calc_terminal/preview/manager.py +129 -0
- calc_terminal/project_stats.py +209 -0
- calc_terminal/projects.py +328 -0
- calc_terminal/providers/__init__.py +0 -0
- calc_terminal/providers/adapters/__init__.py +80 -0
- calc_terminal/providers/adapters/anthropic_adapter.py +127 -0
- calc_terminal/providers/adapters/base.py +106 -0
- calc_terminal/providers/adapters/chinese_adapters.py +420 -0
- calc_terminal/providers/adapters/gemini_adapter.py +101 -0
- calc_terminal/providers/adapters/ollama_adapter.py +83 -0
- calc_terminal/providers/adapters/openai_adapter.py +159 -0
- calc_terminal/providers/adapters/other_adapters.py +246 -0
- calc_terminal/providers/anthropic_provider.py +172 -0
- calc_terminal/providers/auto_update.py +416 -0
- calc_terminal/providers/base_provider.py +105 -0
- calc_terminal/providers/discovery_manager.py +207 -0
- calc_terminal/providers/gemini_provider.py +178 -0
- calc_terminal/providers/lifecycle.py +767 -0
- calc_terminal/providers/ollama_adapter.py +707 -0
- calc_terminal/providers/openai_provider.py +254 -0
- calc_terminal/providers/provider_manager.py +1827 -0
- calc_terminal/providers/providers.json +4075 -0
- calc_terminal/reactionsim.py +279 -0
- calc_terminal/registry.py +337 -0
- calc_terminal/report.py +162 -0
- calc_terminal/research/__init__.py +45 -0
- calc_terminal/research/artifact_intel.py +126 -0
- calc_terminal/research/data_lineage.py +123 -0
- calc_terminal/research/experiment_ledger.py +303 -0
- calc_terminal/research/reproducibility.py +131 -0
- calc_terminal/resilience/__init__.py +47 -0
- calc_terminal/resilience/agent_state.py +121 -0
- calc_terminal/resilience/capability_matcher.py +174 -0
- calc_terminal/resilience/circuit_breaker.py +158 -0
- calc_terminal/resilience/failover_engine.py +230 -0
- calc_terminal/resilience/health_monitor.py +192 -0
- calc_terminal/resilience/ollama_adapter.py +125 -0
- calc_terminal/resilience/orchestrator.py +312 -0
- calc_terminal/resilience/types.py +134 -0
- calc_terminal/sandbox.py +98 -0
- calc_terminal/scires.py +558 -0
- calc_terminal/security_scanner.py +126 -0
- calc_terminal/session.py +294 -0
- calc_terminal/sim3d.py +206 -0
- calc_terminal/solver.py +276 -0
- calc_terminal/sound.py +127 -0
- calc_terminal/task_reports.py +287 -0
- calc_terminal/terminal_host.py +201 -0
- calc_terminal/terminal_identity.py +411 -0
- calc_terminal/test_ai_mode_reliability.py +344 -0
- calc_terminal/test_browser.py +368 -0
- calc_terminal/test_code_editor_upgrade.py +485 -0
- calc_terminal/test_customization.py +1148 -0
- calc_terminal/test_customization_ui.py +612 -0
- calc_terminal/test_dynamic_registry.py +304 -0
- calc_terminal/test_extensions.py +436 -0
- calc_terminal/test_overhaul.py +557 -0
- calc_terminal/test_project_detect.py +255 -0
- calc_terminal/test_root_cause_fix.py +527 -0
- calc_terminal/test_stability.py +532 -0
- calc_terminal/test_terminal_identity.py +132 -0
- calc_terminal/test_v079_speed.py +460 -0
- calc_terminal/theme.py +1107 -0
- calc_terminal/timeline.py +139 -0
- calc_terminal/todos.py +246 -0
- calc_terminal/tool_call_normalizer.py +419 -0
- calc_terminal/tui.py +104 -0
- calc_terminal/ui/__init__.py +8 -0
- calc_terminal/ui/activity_panel.py +231 -0
- calc_terminal/ui/activity_stream_panel.py +238 -0
- calc_terminal/ui/animations.py +122 -0
- calc_terminal/ui/app.py +7271 -0
- calc_terminal/ui/attach_panel.py +597 -0
- calc_terminal/ui/attachments.py +424 -0
- calc_terminal/ui/backup_panel.py +810 -0
- calc_terminal/ui/browser_shell.py +887 -0
- calc_terminal/ui/cat_agent.py +357 -0
- calc_terminal/ui/chats_panel.py +899 -0
- calc_terminal/ui/command_palette.py +125 -0
- calc_terminal/ui/command_palette_modal.py +166 -0
- calc_terminal/ui/composer.py +1141 -0
- calc_terminal/ui/context_menu.py +197 -0
- calc_terminal/ui/conversation.py +1435 -0
- calc_terminal/ui/customization_panel.py +1229 -0
- calc_terminal/ui/dashboard.py +404 -0
- calc_terminal/ui/design_system.py +557 -0
- calc_terminal/ui/diff_panel.py +213 -0
- calc_terminal/ui/editor.py +2102 -0
- calc_terminal/ui/empty_state.py +302 -0
- calc_terminal/ui/events.py +487 -0
- calc_terminal/ui/extensions_panel.py +815 -0
- calc_terminal/ui/footer.py +166 -0
- calc_terminal/ui/gestures_panel.py +383 -0
- calc_terminal/ui/goodbye_screen.py +100 -0
- calc_terminal/ui/header.py +1034 -0
- calc_terminal/ui/help_panel.py +254 -0
- calc_terminal/ui/live_activities.py +914 -0
- calc_terminal/ui/mcp_panel.py +570 -0
- calc_terminal/ui/memory_center.py +524 -0
- calc_terminal/ui/mode_colors_panel.py +525 -0
- calc_terminal/ui/nav_screens.py +747 -0
- calc_terminal/ui/ollama_panel.py +536 -0
- calc_terminal/ui/palette.py +221 -0
- calc_terminal/ui/permission_panel.py +269 -0
- calc_terminal/ui/personalization_panel.py +517 -0
- calc_terminal/ui/personalize_center.py +1568 -0
- calc_terminal/ui/preview_panel.py +441 -0
- calc_terminal/ui/resizers.py +402 -0
- calc_terminal/ui/sidebar.py +1285 -0
- calc_terminal/ui/statusbar.py +168 -0
- calc_terminal/ui/theme_css.py +1396 -0
- calc_terminal/ui/thinking.py +226 -0
- calc_terminal/ui/timeline_panel.py +102 -0
- calc_terminal/ui/todo_panel.py +193 -0
- calc_terminal/ui/viewport.py +136 -0
- calc_terminal/ui/vision_panel.py +489 -0
- calc_terminal/ui/welcome_modal.py +343 -0
- calc_terminal/ui/widgets.py +160 -0
- calc_terminal/ui/workspace.py +831 -0
- calc_terminal/viewers/__init__.py +1 -0
- calc_terminal/viewers/document_viewer.py +252 -0
- calc_terminal/viewers/image_viewer.py +241 -0
- calc_terminal/viewers/pdf_viewer.py +203 -0
- calc_terminal/viewers/presentation_viewer.py +164 -0
- calc_terminal/viewers/registry.py +120 -0
- calc_terminal/viewers/spreadsheet_viewer.py +204 -0
- calc_terminal/vision/__init__.py +89 -0
- calc_terminal/vision/analysis.py +194 -0
- calc_terminal/vision/annotations.py +297 -0
- calc_terminal/vision/capture.py +171 -0
- calc_terminal/vision/context.py +231 -0
- calc_terminal/vision/correlation.py +169 -0
- calc_terminal/vision/cursor.py +258 -0
- calc_terminal/vision/events.py +66 -0
- calc_terminal/vision/frame_pipeline.py +259 -0
- calc_terminal/vision/priority.py +218 -0
- calc_terminal/vision/provider.py +180 -0
- calc_terminal/vision/safety.py +149 -0
- calc_terminal/vision/session.py +281 -0
- calc_terminal/vision/verify.py +162 -0
- calc_terminal/vision.py +514 -0
- calc_terminal/vscode_integration.py +113 -0
- calc_terminal/web/__init__.py +8 -0
- calc_terminal/web/cat_runtime.py +710 -0
- calc_terminal/web/server.py +2891 -0
- calc_terminal/web/static/css/app.css +3152 -0
- calc_terminal/web/static/icons/badge-72.png +0 -0
- calc_terminal/web/static/icons/cat.ico +0 -0
- calc_terminal/web/static/icons/icon-128.png +0 -0
- calc_terminal/web/static/icons/icon-144.png +0 -0
- calc_terminal/web/static/icons/icon-152.png +0 -0
- calc_terminal/web/static/icons/icon-192.png +0 -0
- calc_terminal/web/static/icons/icon-384.png +0 -0
- calc_terminal/web/static/icons/icon-512.png +0 -0
- calc_terminal/web/static/icons/icon-72.png +0 -0
- calc_terminal/web/static/icons/icon-96.png +0 -0
- calc_terminal/web/static/icons/icon.svg +34 -0
- calc_terminal/web/static/icons/new-project.png +0 -0
- calc_terminal/web/static/icons/open-project.png +0 -0
- calc_terminal/web/static/index.html +734 -0
- calc_terminal/web/static/js/app.js +2403 -0
- calc_terminal/web/static/manifest.json +88 -0
- calc_terminal/web/static/sw.js +230 -0
- calc_terminal/workflow_engine.py +769 -0
- calc_terminal/workspace.py +593 -0
- calc_terminal/workspace_index.py +385 -0
- cct_cli-0.7.9.0.dist-info/METADATA +210 -0
- cct_cli-0.7.9.0.dist-info/RECORD +325 -0
- cct_cli-0.7.9.0.dist-info/WHEEL +5 -0
- cct_cli-0.7.9.0.dist-info/entry_points.txt +4 -0
- cct_cli-0.7.9.0.dist-info/licenses/LICENSE +21 -0
- cct_cli-0.7.9.0.dist-info/top_level.txt +1 -0
calc_terminal/art.py
ADDED
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Showcase ASCII block-art library for Chemistry Calc Terminal.
|
|
3
|
+
|
|
4
|
+
A curated gallery of big block-art pieces built from `█ ▓ ▒ ▀ ▄ ╗ ╔ ║ ╣ ╠` and
|
|
5
|
+
friends — chemistry-themed (flask, atom, molecule, benzene ring, DNA), mascots
|
|
6
|
+
(cat, robot, owl, penguin), decorative dividers, abstract 3D shapes, and
|
|
7
|
+
wordmark banners. Every piece renders through `theme.gradient` + `theme.vpad`,
|
|
8
|
+
so it reuses the existing 24-bit color stack — no new rendering code.
|
|
9
|
+
|
|
10
|
+
Used by:
|
|
11
|
+
* the rotating boot banner (a different piece bounces in each launch)
|
|
12
|
+
* the `/art` browse command (walk the whole gallery)
|
|
13
|
+
* easter eggs (themed reveals with a confetti burst)
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
if __name__ == '__main__':
|
|
17
|
+
print("This is a library file and is not meant to be run directly.")
|
|
18
|
+
print("Please run 'python main.py' or 'python model.py' from the project root directory.")
|
|
19
|
+
import sys
|
|
20
|
+
sys.exit(1)
|
|
21
|
+
|
|
22
|
+
import random
|
|
23
|
+
|
|
24
|
+
from . import theme
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# ============================================================ the gallery ==
|
|
28
|
+
# Each value is a list of plain (uncolored) art lines. They're colored at
|
|
29
|
+
# render time by `render()`. Keep widths moderate (<= ~46 cols) so a centered
|
|
30
|
+
# piece fits comfortably inside the app's panel width on an 80-col terminal.
|
|
31
|
+
GALLERY = {
|
|
32
|
+
# ------------------------------------------------ chemistry ----------
|
|
33
|
+
"flask": [
|
|
34
|
+
" _",
|
|
35
|
+
" / \\",
|
|
36
|
+
" | |",
|
|
37
|
+
" | |",
|
|
38
|
+
" / \\",
|
|
39
|
+
" / \\",
|
|
40
|
+
" / ▓▓▓▓▓ \\",
|
|
41
|
+
" / ▓▓▓▓▓▓▓ \\",
|
|
42
|
+
"/▓▓▓▓▓▓▓▓▓▓▓▓▓\\",
|
|
43
|
+
"===============\\",
|
|
44
|
+
" \\___________/",
|
|
45
|
+
],
|
|
46
|
+
"atom": [
|
|
47
|
+
" ___",
|
|
48
|
+
" ,' `.",
|
|
49
|
+
" / (o) \\ .----.",
|
|
50
|
+
" | .---. | / o \\",
|
|
51
|
+
" \\ \\|/ /----( o )",
|
|
52
|
+
" `-.|-.' \\ o /",
|
|
53
|
+
" .----'|`----. `----'",
|
|
54
|
+
" / o | o \\ |",
|
|
55
|
+
" ( o | o ) (o)",
|
|
56
|
+
" \\ o | o / |",
|
|
57
|
+
" '----'|`----'",
|
|
58
|
+
" |",
|
|
59
|
+
],
|
|
60
|
+
"molecule": [
|
|
61
|
+
" ___",
|
|
62
|
+
" / \\",
|
|
63
|
+
" | H |",
|
|
64
|
+
" \\___/",
|
|
65
|
+
" |",
|
|
66
|
+
" _____|_____",
|
|
67
|
+
" / \\",
|
|
68
|
+
" | O |",
|
|
69
|
+
" \\___________/",
|
|
70
|
+
" | |",
|
|
71
|
+
" __|__ __|__",
|
|
72
|
+
" / \\ / \\",
|
|
73
|
+
"| H | H |",
|
|
74
|
+
" \\_____/ \\_____/",
|
|
75
|
+
],
|
|
76
|
+
"benzene": [
|
|
77
|
+
" _____",
|
|
78
|
+
" ,' `.",
|
|
79
|
+
" / . \\",
|
|
80
|
+
" | . . |",
|
|
81
|
+
" \\ . /",
|
|
82
|
+
" `._____,'",
|
|
83
|
+
" / \\",
|
|
84
|
+
" / C₆H₆ \\",
|
|
85
|
+
" /_________\\",
|
|
86
|
+
],
|
|
87
|
+
"testtube": [
|
|
88
|
+
" ╔═══╗",
|
|
89
|
+
" ║ ║",
|
|
90
|
+
" ║ ║",
|
|
91
|
+
" ║ ║",
|
|
92
|
+
" ║▓▓▓║",
|
|
93
|
+
" ║▓▓▓║",
|
|
94
|
+
" ║▓▓▓║",
|
|
95
|
+
" ║▓▓▓║",
|
|
96
|
+
" ╚═╦═╝",
|
|
97
|
+
" ║",
|
|
98
|
+
" ▼",
|
|
99
|
+
],
|
|
100
|
+
"crystal": [
|
|
101
|
+
" /\\",
|
|
102
|
+
" / \\",
|
|
103
|
+
" /____\\",
|
|
104
|
+
" /\\ /\\",
|
|
105
|
+
" / \\ / \\",
|
|
106
|
+
" /____\\/____\\",
|
|
107
|
+
" \\ /\\ /",
|
|
108
|
+
" \\ / \\ /",
|
|
109
|
+
" \\/____\\/",
|
|
110
|
+
" ||",
|
|
111
|
+
" ||",
|
|
112
|
+
],
|
|
113
|
+
"dna": [
|
|
114
|
+
" \\ /",
|
|
115
|
+
" \\ /",
|
|
116
|
+
" | |",
|
|
117
|
+
" / \\",
|
|
118
|
+
" / \\",
|
|
119
|
+
" | |",
|
|
120
|
+
" \\ /",
|
|
121
|
+
" | |",
|
|
122
|
+
" / \\",
|
|
123
|
+
" / \\",
|
|
124
|
+
" | |",
|
|
125
|
+
" \\ /",
|
|
126
|
+
" | |",
|
|
127
|
+
],
|
|
128
|
+
"beaker": [
|
|
129
|
+
" _______",
|
|
130
|
+
" | |",
|
|
131
|
+
" | |",
|
|
132
|
+
" | |",
|
|
133
|
+
" |\\ /|",
|
|
134
|
+
" | \\ / |",
|
|
135
|
+
" | \\ / |",
|
|
136
|
+
" | V |",
|
|
137
|
+
" |_______|",
|
|
138
|
+
],
|
|
139
|
+
|
|
140
|
+
# -------------------------------------------------- mascots ----------
|
|
141
|
+
"cat_chemist": [
|
|
142
|
+
" /\\_/\\",
|
|
143
|
+
" ( o.o ) __",
|
|
144
|
+
" > ^ < / \\",
|
|
145
|
+
" / \\ |██|",
|
|
146
|
+
" / \\ \\__/",
|
|
147
|
+
" | C C C |",
|
|
148
|
+
" | H |",
|
|
149
|
+
" \\___O____/",
|
|
150
|
+
],
|
|
151
|
+
"robot_chemist": [
|
|
152
|
+
" .-------.",
|
|
153
|
+
" | o o |",
|
|
154
|
+
" | [___] |",
|
|
155
|
+
" `-._____.-'",
|
|
156
|
+
" /| |\\",
|
|
157
|
+
" / | ▓▓▓ | \\",
|
|
158
|
+
" | | ▓▓▓ | |",
|
|
159
|
+
" | |_____| |",
|
|
160
|
+
" | _| |_ |",
|
|
161
|
+
" '__|_____|__'",
|
|
162
|
+
],
|
|
163
|
+
"owl": [
|
|
164
|
+
" ___",
|
|
165
|
+
" /o o\\",
|
|
166
|
+
" ( v )",
|
|
167
|
+
" /| |\\",
|
|
168
|
+
" / |___| \\",
|
|
169
|
+
" / | | \\",
|
|
170
|
+
"| |___| |",
|
|
171
|
+
"|___| |___|",
|
|
172
|
+
" | |",
|
|
173
|
+
" ▢ ▢",
|
|
174
|
+
],
|
|
175
|
+
"penguin": [
|
|
176
|
+
" ___",
|
|
177
|
+
" / \\",
|
|
178
|
+
" | > < |",
|
|
179
|
+
" | \\_/ |",
|
|
180
|
+
" /_____\\",
|
|
181
|
+
" /\\ /\\",
|
|
182
|
+
" / \\ / \\",
|
|
183
|
+
" /----\\ /----\\",
|
|
184
|
+
"/ V \\",
|
|
185
|
+
"| |",
|
|
186
|
+
"\\_____________/",
|
|
187
|
+
],
|
|
188
|
+
|
|
189
|
+
# ----------------------------------------------- wordmarks ----------
|
|
190
|
+
"CAT": [
|
|
191
|
+
" ██████╗ ██████╗██╗ ",
|
|
192
|
+
"██╔════╝ ██╔════╝██║ ",
|
|
193
|
+
"██║ ██╗ ██║ ██║ ",
|
|
194
|
+
"██║ ╚██╗██║ ██║ ",
|
|
195
|
+
"╚██████╔╝╚██████╗███████╗",
|
|
196
|
+
" ╚═════╝ ╚═════╝╚══════╝",
|
|
197
|
+
],
|
|
198
|
+
"CHEM": [
|
|
199
|
+
"██╗ ██╗███████╗███╗ ███╗",
|
|
200
|
+
"██║ ██║██╔════╝████╗ ████║",
|
|
201
|
+
"███████║█████╗ ██╔████╔██║",
|
|
202
|
+
"██╔══██║██╔══╝ ██║╚██╔╝██║",
|
|
203
|
+
"██║ ██║███████╗██║ ╚═╝ ██║",
|
|
204
|
+
"╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝",
|
|
205
|
+
],
|
|
206
|
+
|
|
207
|
+
# ----------------------------------------------- decorative ----------
|
|
208
|
+
"divider_ornate": [
|
|
209
|
+
"✦━━━━━━━━━━━ ◆ ━━━━━━━━━━━✦",
|
|
210
|
+
" ╭─────────╮ ",
|
|
211
|
+
" │ ⚗ CAT ⚗ │ ",
|
|
212
|
+
" ╰─────────╯ ",
|
|
213
|
+
"✦━━━━━━━━━━━ ◆ ━━━━━━━━━━━✦",
|
|
214
|
+
],
|
|
215
|
+
"stars_burst": [
|
|
216
|
+
" ✦ * ✧",
|
|
217
|
+
" * ✦ *",
|
|
218
|
+
" ╭───────╮",
|
|
219
|
+
" ✧ │ ✦ ✦ │ ✧",
|
|
220
|
+
" ╰───────╯",
|
|
221
|
+
" * ✦ *",
|
|
222
|
+
" ✧ * ✦",
|
|
223
|
+
],
|
|
224
|
+
"wave": [
|
|
225
|
+
"▁▂▃▄▅▆▇█▇▆▅▄▃▂▁▂▃▄▅▆▇█▇▆▅▄▃▂▁",
|
|
226
|
+
"▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔",
|
|
227
|
+
" ~ chemistry is just applied waves ~",
|
|
228
|
+
],
|
|
229
|
+
|
|
230
|
+
# -------------------------------------------------- abstract ----------
|
|
231
|
+
"cube_3d": [
|
|
232
|
+
" +---------+",
|
|
233
|
+
" /| /|",
|
|
234
|
+
"/ | / |",
|
|
235
|
+
"+--+------+ |",
|
|
236
|
+
"| | | +",
|
|
237
|
+
"| +------+--+",
|
|
238
|
+
"| / | /",
|
|
239
|
+
"|/ |/",
|
|
240
|
+
"+---------+",
|
|
241
|
+
],
|
|
242
|
+
"pyramid": [
|
|
243
|
+
" /\\",
|
|
244
|
+
" / \\",
|
|
245
|
+
" / \\",
|
|
246
|
+
" / \\",
|
|
247
|
+
" / \\",
|
|
248
|
+
" / \\",
|
|
249
|
+
" / \\",
|
|
250
|
+
" /______________\\",
|
|
251
|
+
],
|
|
252
|
+
"spiral": [
|
|
253
|
+
" ╭─────╮",
|
|
254
|
+
" ╭╯ ╰╮",
|
|
255
|
+
" ╭╯ ╭─╮ ╰╮",
|
|
256
|
+
" │ ╭╯ ╰╮ │",
|
|
257
|
+
" │ ╰─╮ │ │",
|
|
258
|
+
" ╰╮ ╰─╯ ╭╯",
|
|
259
|
+
" ╰╮ ╭╯",
|
|
260
|
+
" ╰─────╯",
|
|
261
|
+
],
|
|
262
|
+
"dragon": [
|
|
263
|
+
" /\\___/\\",
|
|
264
|
+
" ( o o )",
|
|
265
|
+
" ( =^= )",
|
|
266
|
+
" ) (",
|
|
267
|
+
" ____/ \\____",
|
|
268
|
+
" / \\",
|
|
269
|
+
" ====/ ◣ ◢ \\====",
|
|
270
|
+
" \\__________________/",
|
|
271
|
+
" | | | |",
|
|
272
|
+
" ▤ ▤ ▤ ▤",
|
|
273
|
+
],
|
|
274
|
+
"rocket": [
|
|
275
|
+
" /\\",
|
|
276
|
+
" / \\",
|
|
277
|
+
" | |",
|
|
278
|
+
" | |",
|
|
279
|
+
" |____|",
|
|
280
|
+
" /| CAT|\\",
|
|
281
|
+
" / |____| \\",
|
|
282
|
+
" / | | \\",
|
|
283
|
+
" | |====| |",
|
|
284
|
+
" \\ | | /",
|
|
285
|
+
" \\_/____\\_/",
|
|
286
|
+
" | || |",
|
|
287
|
+
" * ** *",
|
|
288
|
+
],
|
|
289
|
+
"heart_molecule": [
|
|
290
|
+
" ◢◣ ◢◣",
|
|
291
|
+
" ◢██◣ ◢██◣",
|
|
292
|
+
" █████████",
|
|
293
|
+
" ███████",
|
|
294
|
+
" █████",
|
|
295
|
+
" ███",
|
|
296
|
+
" █",
|
|
297
|
+
],
|
|
298
|
+
"wizard": [
|
|
299
|
+
" .-.",
|
|
300
|
+
" / \\",
|
|
301
|
+
" |○ ○ ○|",
|
|
302
|
+
" | ▽ |",
|
|
303
|
+
" \\___/",
|
|
304
|
+
" _|_|_",
|
|
305
|
+
" / \\",
|
|
306
|
+
" / ✦ ✦ \\",
|
|
307
|
+
" | ▓▓▓▓▓ |",
|
|
308
|
+
" \\_______/",
|
|
309
|
+
" | |",
|
|
310
|
+
" _| |_",
|
|
311
|
+
],
|
|
312
|
+
|
|
313
|
+
# ------------------------------------------------ chemistry (v0.5.6) --
|
|
314
|
+
"bunsen_burner": [
|
|
315
|
+
" ) (",
|
|
316
|
+
" ( )",
|
|
317
|
+
" ) \\ / (",
|
|
318
|
+
" ( )( )",
|
|
319
|
+
" \\_( )_/",
|
|
320
|
+
" | |",
|
|
321
|
+
" ___| |___",
|
|
322
|
+
" / \\",
|
|
323
|
+
" | ▓▓▓▓▓▓▓ |",
|
|
324
|
+
" |_____________|",
|
|
325
|
+
" | |",
|
|
326
|
+
" ___| |___",
|
|
327
|
+
" |___________|",
|
|
328
|
+
],
|
|
329
|
+
"erlenmeyer": [
|
|
330
|
+
" ___",
|
|
331
|
+
" | |",
|
|
332
|
+
" | |",
|
|
333
|
+
" \\ /",
|
|
334
|
+
" | |",
|
|
335
|
+
" / \\",
|
|
336
|
+
" / ▓▓ \\",
|
|
337
|
+
" / ▓▓▓▓▓▓ \\",
|
|
338
|
+
" /▓▓▓▓▓▓▓▓▓▓\\",
|
|
339
|
+
" /____________\\",
|
|
340
|
+
],
|
|
341
|
+
"periodic_tile": [
|
|
342
|
+
" ┌─────────┐",
|
|
343
|
+
" │ 29 │",
|
|
344
|
+
" │ │",
|
|
345
|
+
" │ Cu │",
|
|
346
|
+
" │ │",
|
|
347
|
+
" │ Copper │",
|
|
348
|
+
" │ 63.546 │",
|
|
349
|
+
" └─────────┘",
|
|
350
|
+
],
|
|
351
|
+
"scale_balance": [
|
|
352
|
+
" ___",
|
|
353
|
+
" / \\",
|
|
354
|
+
" ____|_____|____",
|
|
355
|
+
" | | | |",
|
|
356
|
+
" (‾‾‾‾)| |(‾‾‾‾)",
|
|
357
|
+
" \\__/ | | \\__/",
|
|
358
|
+
" | |",
|
|
359
|
+
" __|_____|__",
|
|
360
|
+
" |____________|",
|
|
361
|
+
],
|
|
362
|
+
"hourglass": [
|
|
363
|
+
" ┌───────┐",
|
|
364
|
+
" \\ /",
|
|
365
|
+
" \\ . /",
|
|
366
|
+
" \\ : /",
|
|
367
|
+
" \\:/",
|
|
368
|
+
" /:\\",
|
|
369
|
+
" / : \\",
|
|
370
|
+
" / . \\",
|
|
371
|
+
" / \\",
|
|
372
|
+
" └───────┘",
|
|
373
|
+
],
|
|
374
|
+
"lightning_flask": [
|
|
375
|
+
" _",
|
|
376
|
+
" / \\",
|
|
377
|
+
" | |",
|
|
378
|
+
" | | \\",
|
|
379
|
+
" / \\ \\",
|
|
380
|
+
" / ⚡ \\ \\",
|
|
381
|
+
" / ⚡▓▓⚡ \\ /",
|
|
382
|
+
"/▓▓▓▓⚡▓▓▓▓▓▓\\ /",
|
|
383
|
+
"==============\\",
|
|
384
|
+
" \\___________/",
|
|
385
|
+
],
|
|
386
|
+
|
|
387
|
+
# -------------------------------------------------- mascots (v0.5.6) --
|
|
388
|
+
"phoenix": [
|
|
389
|
+
" \\ ^ /",
|
|
390
|
+
" ) \\ ' / (",
|
|
391
|
+
" `. (o) .'",
|
|
392
|
+
" -==( ('|') )==-",
|
|
393
|
+
" .' /'\\ `.",
|
|
394
|
+
" ( / \\ )",
|
|
395
|
+
" / \\",
|
|
396
|
+
" ' '",
|
|
397
|
+
],
|
|
398
|
+
"fox_scholar": [
|
|
399
|
+
" /\\ /\\",
|
|
400
|
+
" ( ^.^ )___",
|
|
401
|
+
" > ▽ < / \\",
|
|
402
|
+
" / |███|",
|
|
403
|
+
" / CAT |___|",
|
|
404
|
+
" | ________ |",
|
|
405
|
+
" \\________/‾\\/",
|
|
406
|
+
],
|
|
407
|
+
"dragonfly": [
|
|
408
|
+
" ══════╤══════",
|
|
409
|
+
" │",
|
|
410
|
+
" ,-(°)-.",
|
|
411
|
+
" ╱══╡ ╞══╲",
|
|
412
|
+
" ╱ └──┬──┘ ╲",
|
|
413
|
+
" │",
|
|
414
|
+
" │",
|
|
415
|
+
" ╱ ╲",
|
|
416
|
+
],
|
|
417
|
+
|
|
418
|
+
# ----------------------------------------------- decorative (v0.5.6) --
|
|
419
|
+
"circuit_frame": [
|
|
420
|
+
"┌──╴ ╶──┬──╴ ╶──┐",
|
|
421
|
+
"│ ● │ ● │",
|
|
422
|
+
"├──┐ ┌──┴──┐ ┌──┤",
|
|
423
|
+
"│ └──┤ CAT ├──┘ │",
|
|
424
|
+
"├──┐ └─────┘ ┌──┤",
|
|
425
|
+
"│ ● │ ● │",
|
|
426
|
+
"└──╴ ╶──┴──╴ ╶──┘",
|
|
427
|
+
],
|
|
428
|
+
"molecule_ring": [
|
|
429
|
+
" ●───●",
|
|
430
|
+
" ╱ ╲",
|
|
431
|
+
" ● ●",
|
|
432
|
+
" │ │",
|
|
433
|
+
" ● ●",
|
|
434
|
+
" ╲ ╱",
|
|
435
|
+
" ●───●",
|
|
436
|
+
],
|
|
437
|
+
"orbit_rings": [
|
|
438
|
+
" . · ˚ ✦ ˚ · .",
|
|
439
|
+
" ⟨ ╭──────────╮ ⟩",
|
|
440
|
+
" ⟨ │ ╭────╮ │ ⟩",
|
|
441
|
+
" ⟨ │ │ ●● │ │ ⟩",
|
|
442
|
+
" ⟨ │ ╰────╯ │ ⟩",
|
|
443
|
+
" ⟨ ╰──────────╯ ⟩",
|
|
444
|
+
" · ˚ ✦ ˚ ·",
|
|
445
|
+
],
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
# -------------------------------------------------------------- captions --
|
|
450
|
+
# Short one-line descriptions, shown in the /art browser under each piece.
|
|
451
|
+
CAPTIONS = {
|
|
452
|
+
"flask": "The classic — where every reaction begins.",
|
|
453
|
+
"atom": "Nucleus in the center, electrons everywhere else.",
|
|
454
|
+
"molecule": "H₂O: two hydrogens, one oxygen, infinite importance.",
|
|
455
|
+
"benzene": "C₆H₆ — the aromatic ring that confused chemists for decades.",
|
|
456
|
+
"testtube": "Drop it in. Watch what happens.",
|
|
457
|
+
"crystal": "A lattice, frozen in time.",
|
|
458
|
+
"dna": "The double helix — chemistry that learned to remember.",
|
|
459
|
+
"beaker": "Bigger than a test tube, same science.",
|
|
460
|
+
"cat_chemist": "Schrodinger's lab assistant (may or may not be helpful).",
|
|
461
|
+
"robot_chemist": "Never sleeps, never spills, never stops calculating.",
|
|
462
|
+
"owl": "Wise enough to know the answer is always 'it depends'.",
|
|
463
|
+
"penguin": "Linux's mascot, now doing chemistry.",
|
|
464
|
+
"CAT": "The wordmark, in big blocks.",
|
|
465
|
+
"CHEM": "CHEMISTRY, abbreviated loudly.",
|
|
466
|
+
"divider_ornate": "A flourish for when you need a clean break.",
|
|
467
|
+
"stars_burst": "Pure decoration. Sparkle responsibly.",
|
|
468
|
+
"wave": "Everything is waves, if you zoom out enough.",
|
|
469
|
+
"cube_3d": "A three-dimensional hint, in two dimensions.",
|
|
470
|
+
"pyramid": "Ancient architecture, or a single molecular orbital?",
|
|
471
|
+
"spiral": "Entropy, visualized.",
|
|
472
|
+
"dragon": "Reactive. Approach with care.",
|
|
473
|
+
"rocket": "CAT, ready for liftoff.",
|
|
474
|
+
"heart_molecule":"Bonding is just chemistry with feelings.",
|
|
475
|
+
"wizard": "Casts spells. Also casts equations.",
|
|
476
|
+
"bunsen_burner": "The original heat source. Still undefeated.",
|
|
477
|
+
"erlenmeyer": "The conical one — least likely to spill on a swirl.",
|
|
478
|
+
"periodic_tile": "Element 29. Also this edition's namesake.",
|
|
479
|
+
"scale_balance": "Whatever goes in must come out — mass is stubborn like that.",
|
|
480
|
+
"hourglass": "Half-life, visualized one grain at a time.",
|
|
481
|
+
"lightning_flask": "Exothermic and proud of it.",
|
|
482
|
+
"phoenix": "Combustion with better PR.",
|
|
483
|
+
"fox_scholar": "Quick, clever, mildly caffeinated.",
|
|
484
|
+
"dragonfly": "Symmetry with wings.",
|
|
485
|
+
"circuit_frame": "For when the terminal wants to feel like a lab bench.",
|
|
486
|
+
"molecule_ring": "Minimalist bonding, maximum vibes.",
|
|
487
|
+
"orbit_rings": "Electrons, doing their best impression of planets.",
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
# ============================================================ boot banners ==
|
|
492
|
+
# A handful of full banners shown one-per-launch (rotating). Each is a tuple
|
|
493
|
+
# (art_lines, subtitle). `random_boot()` picks one at random — different piece
|
|
494
|
+
# every launch. They're larger/wordier than gallery pieces so boot feels grand.
|
|
495
|
+
# v0.7.9.5: Updated branding from "CHEMISTRY CALC TERMINAL" to "CAT"
|
|
496
|
+
BOOT_BANNERS = [
|
|
497
|
+
(GALLERY["flask"], "CAT"),
|
|
498
|
+
(GALLERY["atom"], "CAT"),
|
|
499
|
+
(GALLERY["molecule"], "CAT"),
|
|
500
|
+
(GALLERY["CAT"], "CAT"),
|
|
501
|
+
(GALLERY["benzene"], "CAT"),
|
|
502
|
+
(GALLERY["dna"], "CAT"),
|
|
503
|
+
(GALLERY["crystal"], "CAT"),
|
|
504
|
+
(GALLERY["rocket"], "CAT"),
|
|
505
|
+
]
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
# ============================================================ render API ==
|
|
509
|
+
def gallery_names():
|
|
510
|
+
"""Ordered list of gallery piece names — the menu for the /art browser.
|
|
511
|
+
Order is fixed (dict insertion order) so the menu is stable across runs."""
|
|
512
|
+
return list(GALLERY.keys())
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
def info(name):
|
|
516
|
+
"""The short caption for a piece (or a fallback if unknown)."""
|
|
517
|
+
return CAPTIONS.get(name, "an ASCII art piece")
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
def _piece_width(piece):
|
|
521
|
+
return max((theme.vlen(line) for line in piece), default=0)
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
def render(piece, color_a=theme.CYAN, color_b=theme.PURPLE, bold=True,
|
|
525
|
+
align="center", width=None):
|
|
526
|
+
"""Render a list of art lines as a gradient-colored, aligned block.
|
|
527
|
+
|
|
528
|
+
Reuses `theme.gradient` (per-char 24-bit interpolation) and `theme.vpad`
|
|
529
|
+
so there's no new color code here. `align` is "center" (default) or
|
|
530
|
+
"left". `width`, if given, is the column budget to align within; when
|
|
531
|
+
omitted it sizes to the widest line + a 2-col margin.
|
|
532
|
+
|
|
533
|
+
Returns the joined string (newline-separated) — the caller prints it.
|
|
534
|
+
Lines that are pure whitespace are preserved as blank rows so vertical
|
|
535
|
+
spacing in the art is kept intact.
|
|
536
|
+
"""
|
|
537
|
+
out = []
|
|
538
|
+
target = width if width is not None else _piece_width(piece) + 2
|
|
539
|
+
for line in piece:
|
|
540
|
+
if line.strip() == "":
|
|
541
|
+
out.append("")
|
|
542
|
+
continue
|
|
543
|
+
colored = theme.gradient(line, color_a, color_b, bold=bold)
|
|
544
|
+
if align == "left":
|
|
545
|
+
out.append(theme.vpad(colored, target, "left"))
|
|
546
|
+
else:
|
|
547
|
+
out.append(theme.vpad(colored, target, "center"))
|
|
548
|
+
return "\n".join(out)
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
def render_by_name(name, color_a=theme.CYAN, color_b=theme.PURPLE, bold=True,
|
|
552
|
+
align="center", width=None):
|
|
553
|
+
"""Convenience: render a gallery piece by its name."""
|
|
554
|
+
piece = GALLERY.get(name)
|
|
555
|
+
if piece is None:
|
|
556
|
+
return ""
|
|
557
|
+
return render(piece, color_a, color_b, bold, align, width)
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
def random_boot(rng=None):
|
|
561
|
+
"""Pick one boot banner at random. Different each launch. Returns the
|
|
562
|
+
(art_lines, subtitle) tuple; the caller animates + prints it.
|
|
563
|
+
|
|
564
|
+
`rng` is accepted for deterministic tests (pass a `random.Random`); the
|
|
565
|
+
default uses the global module RNG so boot genuinely varies per run."""
|
|
566
|
+
pick = rng.choice(BOOT_BANNERS) if rng else random.choice(BOOT_BANNERS)
|
|
567
|
+
return pick
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
# ---------------------------------------------------------- /art browser --
|
|
571
|
+
# Moved here from the old chatui.py during the chat-UI rewrite — this is
|
|
572
|
+
# an ASCII art gallery viewer, not part of the chat interface, so it
|
|
573
|
+
# belongs with the gallery data it browses rather than in fallback_cli.py.
|
|
574
|
+
# (Not currently wired to a slash command; kept intact rather than
|
|
575
|
+
# deleted so the feature isn't lost.)
|
|
576
|
+
def art_browser():
|
|
577
|
+
"""An interactive gallery viewer for this module's ASCII art library.
|
|
578
|
+
Lists every piece in `GALLERY`; picking a number reveals that piece
|
|
579
|
+
with a bouncy gradient animation + its caption. `r` re-rolls to a
|
|
580
|
+
random piece, `q` returns to the caller.
|
|
581
|
+
|
|
582
|
+
Cross-platform: uses blocking `input()` for the menu (works
|
|
583
|
+
everywhere, including Windows where raw single-key reads are flaky).
|
|
584
|
+
"""
|
|
585
|
+
from . import engine
|
|
586
|
+
names = gallery_names()
|
|
587
|
+
while True:
|
|
588
|
+
theme.clear_screen()
|
|
589
|
+
print()
|
|
590
|
+
print(theme.center(theme.gradient(" ASCII ART GALLERY ", theme.CYAN, theme.PURPLE, bold=True), engine.WIDTH))
|
|
591
|
+
print(theme.center(theme.faint("browse the showcase — pick a number, or q to exit"), engine.WIDTH))
|
|
592
|
+
print()
|
|
593
|
+
per_col = (len(names) + 1) // 2
|
|
594
|
+
for i in range(per_col):
|
|
595
|
+
left = f" {theme.fg(str(i + 1) + '.', theme.OC_PRIMARY, bold=True)} {names[i]}" if i < len(names) else ""
|
|
596
|
+
j = i + per_col
|
|
597
|
+
right = f" {theme.fg(str(j + 1) + '.', theme.OC_PRIMARY, bold=True)} {names[j]}" if j < len(names) else ""
|
|
598
|
+
gap = " " * max(2, 40 - theme.vlen(left))
|
|
599
|
+
print(theme.text(left) + (gap + theme.text(right) if right else ""))
|
|
600
|
+
print()
|
|
601
|
+
print(theme.faint(" r = random piece q = back to home"))
|
|
602
|
+
try:
|
|
603
|
+
choice = input(theme.badge(" PICK ", theme.BG_INFO) + " ").strip().lower()
|
|
604
|
+
except (EOFError, KeyboardInterrupt):
|
|
605
|
+
print()
|
|
606
|
+
return
|
|
607
|
+
|
|
608
|
+
if choice in ("q", "quit", "exit", "/back", ""):
|
|
609
|
+
return
|
|
610
|
+
if choice in ("r", "random"):
|
|
611
|
+
_show_art_piece(random.choice(names))
|
|
612
|
+
continue
|
|
613
|
+
if choice.isdigit() and 1 <= int(choice) <= len(names):
|
|
614
|
+
_show_art_piece(names[int(choice) - 1])
|
|
615
|
+
continue
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
def _show_art_piece(name):
|
|
619
|
+
"""Reveal one gallery piece with a bouncy animation + caption, then
|
|
620
|
+
wait for Enter before returning to the menu."""
|
|
621
|
+
from . import engine
|
|
622
|
+
from . import anim as _anim
|
|
623
|
+
theme.clear_screen()
|
|
624
|
+
print()
|
|
625
|
+
c1 = random.choice([theme.CYAN, theme.PURPLE, theme.GREEN, theme.OC_PRIMARY, theme.OC_ACCENT])
|
|
626
|
+
c2 = random.choice([theme.PURPLE, theme.CYAN, theme.OC_SECONDARY, theme.ORANGE])
|
|
627
|
+
_anim.confetti_burst(width=engine.WIDTH, count=14)
|
|
628
|
+
print()
|
|
629
|
+
print(theme.center(theme.gradient(name.upper(), c1, c2, bold=True), engine.WIDTH))
|
|
630
|
+
print()
|
|
631
|
+
rendered = render_by_name(name, color_a=c1, color_b=c2)
|
|
632
|
+
_anim.bouncy_reveal(rendered.split("\n"), delay=0.05)
|
|
633
|
+
print()
|
|
634
|
+
print(theme.center(theme.dim(info(name)), engine.WIDTH))
|
|
635
|
+
print()
|
|
636
|
+
try:
|
|
637
|
+
input(theme.faint(" press Enter to return to the gallery\u2026"))
|
|
638
|
+
except (EOFError, KeyboardInterrupt):
|
|
639
|
+
print()
|