Compare commits

..

4 Commits

Author SHA1 Message Date
AI Christianson c4fea3327b Automatic commit before Assistant edits 2024-12-26 17:08:15 +00:00
AI Christianson abf3fb034e Assistant checkpoint: Configure Python package auto-installation
Assistant generated file changes:
- .replit: Configure auto package installation
- replit.nix: Add Python and development dependencies

---

User prompt:

our project has pyproject and requirements-dev. can we set up the replit such that deps are auto installed?
2024-12-26 17:07:14 +00:00
AI Christianson 8aa6695e7d Automatic commit before Assistant edits 2024-12-26 16:59:35 +00:00
AI Christianson b5fa809799 Automatic commit before Assistant edits 2024-12-26 16:49:41 +00:00
359 changed files with 3870 additions and 84129 deletions

View File

@ -1,12 +0,0 @@
#!/bin/bash
echo "Running tests before push..."
make test
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo "Tests failed. Push aborted."
exit 1
fi
exit 0

View File

@ -1,6 +0,0 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"

View File

@ -23,7 +23,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
python-version: '3.x'
# Step 3: Install Normal and Dev Dependencies
- name: Install Dependencies

View File

@ -1,34 +0,0 @@
name: Tests
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
# Cancel any in-progress job or run
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
matrix:
python-version: ["3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Setup and Run Tests
run: |
make setup-dev
make test

12
.gitignore vendored
View File

@ -7,15 +7,3 @@ __pycache__/
/dist
/.ra-aid
.coverage
/.venv
/venv
/.idea
/htmlcov
.envrc
appmap.log
*.swp
/vsc/node_modules
/vsc/dist
node_modules/
/frontend/common/dist
/frontend/web/dist/

View File

@ -1 +0,0 @@
3.12.7

View File

@ -5,360 +5,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.17.1] 2025-03-13
### Fixed
- Fixed bug with `process_thinking_content` function by moving it from `agent_utils` to `ra_aid.text.processing` module
- Fixed config parameter handling in research request functions
- Updated development setup instructions in README to use `pip install -e ".[dev]"` instead of `pip install -r requirements-dev.txt`
## [0.17.0] 2025-03-12
### Added
- Added support for think tags in models with the new extract_think_tag function
- Enhanced CiaynAgent and expert tool to extract and display thinking content from <think>...</think> tags
- Added model parameters for think tag support
- Added comprehensive testing for think tag functionality
- Added `--show-thoughts` flag to show thoughts of thinking models
- Added `--show-cost` flag to display cost information during agent operations
- Enhanced cost tracking with AnthropicCallbackHandler for monitoring token usage and costs
- Added Session and Trajectory models to track application state and agent actions
- Added comprehensive environment inventory system for collecting and providing system information to agents
- Added repository implementations for Session and Trajectory models
- Added support for reasoning assistance in research phase
- Added new config parameters for managing cost display and reasoning assistance
### Changed
- Updated langchain/langgraph deps
- Improved trajectory tracking for better debugging and analysis
- Enhanced prompts throughout the system for better performance
- Improved token management with better handling of thinking tokens in Claude models
- Updated project information inclusion in prompts
- Reorganized agent code with better extraction of core functionality
- Refactored anthropic token limiting for better control over token usage
### Fixed
- Fixed binary file detection
- Fixed environment inventory sorting
- Fixed token limiter functionality
- Various test improvements and fixes
## [0.16.1] 2025-03-07
### Changed
- Replaced thread-local storage with contextvars in agent_context.py for better context isolation
- Improved React agent execution with LangGraph's interrupt mechanism
- Enhanced _run_agent_stream function to properly handle agent state and continuation
### Fixed
- Fixed tests to work with the new implementation
## [0.16.0] 2025-03-07
### Added
- Database-backed memory system with SQLite (.ra-aid/pk.db)
- Repository pattern for memory access (KeyFactRepository, KeySnippetRepository, ResearchNoteRepository)
- Memory garbage collection with configurable thresholds
- "--wipe-project-memory" flag to reset memory
- Memory statistics in status panel
- Propagation depth control for agent_should_exit
- Fixed string parameter for ripgrep tool
- Support for Claude 3.7 Sonnet thinking tokens in expert tool
### Changed
- Enhanced file logging with support for .ra-aid/logs/
- Improved CiaynAgent with better tool validation and execution
- Memory-related prompt improvements
### Fixed
- Various bug fixes in tool execution
- Test improvements for memory system
## [0.15.2] - 2025-02-27
### Added
- Added agent_should_exit context functionality with propagation to parent contexts
- Improved agent crash detection with non-propagating crash state
- Enhanced ripgrep tool with better context support
- Improved agent context inheritance
- Added comprehensive test coverage for exit and crash handling
## [0.15.1] - 2025-02-27
### Fixed
- Improved chat prompt to prevent endless loop behavior with sonnet 3.7.
## [0.15.0] - 2025-02-27
### Added
- Added database infrastructure with models, connections, and migrations
- Added agent context system for improved context management
- Added aider-free mode with command line option to disable aider-related functionality
- Added database-related dependencies
### Changed
- Improved file editing tools with enhanced functionality
- Enhanced agent implementation tools with modified return values and logic
- Improved agent tool prompts for better clarity and effectiveness
- Fixed langgraph prebuilt dependency
### Fixed
- Fixed project state detection logic with added tests
## [0.14.9] - 2025-02-25
### Added
- Added binary file detection and filtering to prevent binary files from being added to related files
- Added python-magic dependency for improved binary file detection
- Added support for "thinking" budget parameter for Claude 3.7 Sonnet
### Changed
- Updated dependencies:
- langchain-anthropic from 0.3.7 to 0.3.8
- langchain-google-genai from 2.0.10 to 2.0.11
- Improved shell command tool description to recommend keeping commands under 300 words
- Enhanced binary file filtering to include detailed reporting of skipped files
- Updated test assertions to be more flexible with parameter checking
## [0.14.8] - 2025-02-25
### Changed
- Improved programmer.py tool prompts for better clarity on related files visibility
- Enhanced programmer tool to remind users to call emit_related_files on any new files created
- Updated README.md to use media queries for showing different logos based on color scheme preference
## [0.14.7] - 2025-02-25
### Added
- Windows compatibility improvements
- Add error handling for Windows-specific modules
- Add Windows-specific tests for compatibility
### Changed
- Improve cross-platform support in interactive.py
- WebUI improvements
- Improve message display
- Add syntax highlighting
- Add animations
- Expert tool prompt improvements
### Fixed
- WebUI improvements
- Fix WebSocket communication
- Interactive command handling improvements
- Fix interactive history capture
- Fix command capture bugs
- Multiple fixes for interactive command execution on both Linux and Windows
- Enhance error handling for interactive processes
## [0.14.6] - 2025-02-25
### Added
- Added `--no-git` flag to aider commands to prevent git operations
### Changed
- Updated aider-chat dependency from 0.75 to 0.75.1
- Improved prompts for better tool effectiveness
- Enhanced emit_key_snippet documentation to focus on upcoming work relevance
## [0.14.5] - 2025-02-24
### Changed
- Optimized prompts
## [0.14.4] - 2025-02-24
### Changed
- Updated aider-chat dependency from 0.74.2 to 0.75
- Improved tool calling performance by minimizing tool return values
- Replaced emit_key_snippets with emit_key_snippet for simpler code snippet management
- Simplified return values for multiple tools to improve tool calling accuracy
- Updated tool prompts to remove unnecessary context cleanup references
- Reorganized order of tools in read-only tools list
### Fixed
- Fixed tests to align with updated tool return values
- Updated test assertions to match new simplified tool outputs
## [0.14.3] - 2025-02-24
### Added
- Added support for Claude 3.7 Sonnet model
- Added version display in startup configuration panel
### Changed
- Updated language library dependencies (langgraph, langchain-core, langchain, langchain-openai, langchain-google-genai)
- Changed default Anthropic model from Claude 3.5 Sonnet to Claude 3.7 Sonnet
### Fixed
- Fixed f-string syntax error in write_file.py
- Fixed bug where model selection on Anthropic was always using default instead of respecting user selection
- Fixed Anthropic key error message to reference the correct variable
- Added test for user-specified Anthropic model selection
## [0.14.2] - 2025-02-19
### Added
- Added automatic fallback mechanism to alternative LLM models on consecutive failures
- Added FallbackHandler class to manage tool failures and fallback logic
- Added console notification for tool fallback activation
- Added detailed fallback configuration options in command line arguments
- Added validation for required environment variables for LLM providers
### Changed
- Enhanced CiaynAgent to handle chat history and improve context management
- Improved error handling and logging in fallback mechanism
- Streamlined fallback model selection and invocation process
- Refactored agent stream handling for better clarity
- Reduced maximum tool failures from 3 to 2
### Fixed
- Fixed tool execution error handling and retry logic
- Enhanced error resilience and user experience with fallback handler
- Improved error message formatting and logging
- Updated error handling to include base message for better debugging
## [0.14.1] - 2025-02-13
### Added
- Added expected_runtime_seconds parameter for shell commands with graceful process shutdown
- Added config printing at startup (#88)
### Changed
- Enforce byte limit in interactive commands
- Normalize/dedupe related file paths
- Relax aider version requirement for SWE-bench compatibility
- Upgrade langchain/langgraph dependencies
### Fixed
- Fixed aider flags (#89)
- Fixed write_file_tool references
## [0.14.0] - 2025-02-12
### Added
- Status panel showing tool/LLM status and outputs
- Automatic detection of OpenAI expert models
- Timeouts on LLM clients
### Changed
- Improved interactive TTY process capture and history handling
- Upgraded langgraph dependencies
- Improved prompts and work logging
- Refined token/bytes ratio handling
- Support default temperature on per-model basis
- Reduced tool count for more reliable tool calling
- Updated logo and branding assets
- Set environment variables to disable common interactive modes
### Fixed
- Various test fixes
- Bug fixes for completion message handling and file content operations
- Interactive command input improvements
- Use reasoning_effort=high for OpenAI expert models
- Do not default to o1 model (#82)
- Make current working directory and date available to more agents
## [0.13.2] - 2025-02-02
- Fix temperature parameter error for expert tool.
## [0.13.1] - 2025-01-31
### Added
- WebUI (#61)
- Support o3-mini
### Changed
- Convert list input to string to handle create-react-agent tool calls correctly (#66)
- Add commands for code checking and fixing using ruff (#63)
### Fixed
- Fix token estimation
- Fix tests
- Prevent duplicate files (#64)
- Ensure default temperature is set correctly for different providers
- Do not incorrectly give temp parameter to expert model
- Correcting URLs that were referencing ai-christianson/ra-aid - should be ai-christianson/RA.Aid (#69)
### Improved
- Integrate litellm to retrieve model token limits for better flexibility (#51)
- Handle user defined test cmd (#59)
- Run tests during Github CICD (#58)
- Refactor models_tokens to be models_params so we can track multiple parameters on a per-model basis.
## [0.13.0] - 2025-01-22
### Added
- Added Deepseek Provider Support and Custom Deepseek Reasoner Chat Model (#50)
- Added Aider config File Argument Support (#43)
- Added configurable --recursion-limit argument (#46)
- Set Default Max Token Limit with Provider/Model Dictionary (#45)
### Changed
- Updated aider-chat version from 0.69.1 to 0.72.1 (#47)
### Fixed
- Fixed Issue 42 related to Levenshtein (#44)
### Improved
- Various prompt improvements
- Better handling of 429 errors on openrouter
- Improved project info handling and token usage optimization
- Extracted tool reflection functionality
- Improved work log handling
- Added tests for CiaynAgent._does_not_conform_to_pattern
## [0.12.1] - 2025-01-08
- Fix bug where directories are added as related files.
## [0.12.0] - 2025-01-04
### Added
- Google Gemini AI provider support
- Dependency check functionality in ra_aid/dependencies.py
- Test coverage reporting to pytest commands
### Changed
- Updated minimum Python requirement to 3.9
- Updated OpenAI model defaults
- Modified test files to support new Gemini provider
- Updated SWE-bench dataset generation script with UV package management
### Fixed
- Date-based assertions in directory listing tests
## [0.11.3] - 2024-12-30
- MacOS fixes.
## [0.11.2] - 2024-12-30
- Fix SyntaxError: f-string expression part cannot include a backslash.
## [0.11.1] - 2024-12-29
- Improve prompts.
- Fix issue #24.
## [0.11.0] - 2024-12-28
- Add CiaynAgent to support models that do not have, or are not good at, agentic function calling.
- Improve env var validation.
- Add --temperature CLI parameter.
## [0.10.3] - 2024-12-27
- Fix logging on interrupt.
- Fix web research prompt.
- Simplify planning stage by executing tasks directly.
- Make research notes available to more agents/tools.
## [0.10.2] - 2024-12-26
## [Unreleased]
- Add logging.
- Fix bug where anthropic is used in chat mode even if another provider is specified.
## [0.10.0] - 2024-12-24

View File

@ -1,4 +1,4 @@
include LICENSE
include README.md
include CHANGELOG.md
recursive-include ra_aid/server/static *
include LICENSE
include requirements*.txt
recursive-include agent_langchain *.py

View File

@ -1,22 +0,0 @@
.PHONY: test setup-dev setup-hooks
test:
# for future consideration append --cov-fail-under=80 to fail test coverage if below 80%
python -m pytest --cov=ra_aid --cov-report=term-missing --cov-report=html
setup-dev:
pip install -e ".[dev]"
setup-hooks: setup-dev
pre-commit install
check:
ruff check
fix:
ruff check . --select I --fix # First sort imports
ruff format .
ruff check --fix
fix-basic:
ruff check --fix

221
README.md
View File

@ -1,41 +1,33 @@
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/logo-white-transparent.gif">
<source media="(prefers-color-scheme: light)" srcset="assets/logo-black-transparent.png">
<img src="assets/logo-black-transparent.png" alt="RA.Aid - Develop software autonomously." style="margin-bottom: 20px;">
</picture>
```ascii
██▀███ ▄▄▄ ▄▄▄ ██▓▓█████▄
▓██ ▒ ██▒▒████▄ ▒████▄ ▓██▒▒██▀ ██▌
▓██ ░▄█ ▒▒██ ▀█▄ ▒██ ▀█▄ ▒██▒░██ █▌
▒██▀▀█▄ ░██▄▄▄▄██ ░██▄▄▄▄██ ░██░░▓█▄ ▌
░██▓ ▒██▒ ▓█ ▓██▒ ██▓ ▓█ ▓██▒░██░░▒████▓
░ ▒▓ ░▒▓░ ▒▒ ▓▒█░ ▒▓▒ ▒▒ ▓▒█░░▓ ▒▒▓ ▒
░▒ ░ ▒░ ▒ ▒▒ ░ ░▒ ▒ ▒▒ ░ ▒ ░ ░ ▒ ▒
░░ ░ ░ ▒ ░ ░ ▒ ▒ ░ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░
░ ░
```
[![Python Versions](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
[![Status](https://img.shields.io/badge/status-Beta-yellow)]()
**Develop software autonomously.**
# RA.Aid
RA.Aid (pronounced "raid") helps you develop software autonomously. It is a standalone coding agent built on LangGraph's agent-based task execution framework. The tool provides an intelligent assistant that can help with research, planning, and implementation of multi-step development tasks. RA.Aid can optionally integrate with `aider` (https://aider.chat/) via the `--use-aider` flag to leverage its specialized code editing capabilities.
**AI software development agent powered by `aider` and advanced reasoning models like `o1`.**
The result is **near-fully-autonomous software development**.
RA.Aid (ReAct Aid) was made by putting `aider` (https://aider.chat/) in a LangChain ReAct agent loop. This unique combination allows developers to leverage aider's code editing capabilities while benefiting from LangChain's agent-based task execution framework. The tool provides an intelligent assistant that can help with research, planning, and implementation of multi-step development tasks.
**Enjoying RA.Aid?** Show your support by giving us a star ⭐ on [GitHub](https://github.com/ai-christianson/RA.Aid)!
RA.Aid is a practical tool for everyday software development and is used for developing real-world applications.
Here's a demo of RA.Aid adding a feature to itself:
<img src="assets/demo-ra-aid-task-1.gif" alt="RA.Aid Demo" autoplay loop style="width: 100%; max-width: 800px;">
## Documentation
Complete documentation is available at https://docs.ra-aid.ai
Key sections:
- [Installation Guide](https://docs.ra-aid.ai/quickstart/installation)
- [Recommended Configuration](https://docs.ra-aid.ai/quickstart/recommended)
- [Open Models Setup](https://docs.ra-aid.ai/quickstart/open-models)
- [Usage Examples](https://docs.ra-aid.ai/category/usage)
- [Logging System](https://docs.ra-aid.ai/configuration/logging)
- [Memory Management](https://docs.ra-aid.ai/configuration/memory-management)
- [Contributing Guide](https://docs.ra-aid.ai/contributing)
- [Getting Help](https://docs.ra-aid.ai/getting-help)
## Table of Contents
- [Features](#features)
- [Installation](#installation)
- [Usage](#usage)
@ -103,31 +95,6 @@ What sets RA.Aid apart is its ability to handle complex programming tasks that e
## Installation
### Windows Installation
1. Install Python 3.8 or higher from [python.org](https://www.python.org/downloads/)
2. Install required system dependencies:
```powershell
# Install Chocolatey if not already installed (run in admin PowerShell)
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
# Install ripgrep using Chocolatey
choco install ripgrep
```
3. Install RA.Aid:
```powershell
pip install ra-aid
```
4. Install Windows-specific dependencies:
```powershell
pip install pywin32
```
5. Set up your API keys in a `.env` file:
```env
ANTHROPIC_API_KEY=your_anthropic_key
OPENAI_API_KEY=your_openai_key
```
### Unix/Linux Installation
RA.Aid can be installed directly using pip:
```bash
@ -136,7 +103,14 @@ pip install ra-aid
### Prerequisites
Before using RA.Aid, you'll need API keys for the required AI services:
Before using RA.Aid, you'll need:
1. Python package `aider` installed and available in your PATH:
```bash
pip install aider-chat
```
2. API keys for the required AI services:
```bash
# Set up API keys based on your preferred provider:
@ -144,7 +118,7 @@ Before using RA.Aid, you'll need API keys for the required AI services:
# For Anthropic Claude models (recommended)
export ANTHROPIC_API_KEY=your_api_key_here
# For OpenAI models (optional)
# For OpenAI models
export OPENAI_API_KEY=your_api_key_here
# For OpenRouter provider (optional)
@ -153,14 +127,11 @@ export OPENROUTER_API_KEY=your_api_key_here
# For OpenAI-compatible providers (optional)
export OPENAI_API_BASE=your_api_base_url
# For Gemini provider (optional)
export GEMINI_API_KEY=your_api_key_here
# For web research capabilities
export TAVILY_API_KEY=your_api_key_here
```
Note: When using the `--use-aider` flag, the programmer tool (aider) will automatically select its model based on your available API keys:
Note: The programmer tool (aider) will automatically select its model based on your available API keys:
- If ANTHROPIC_API_KEY is set, it will use Claude models
- If only OPENAI_API_KEY is set, it will use OpenAI models
- You can set multiple API keys to enable different features
@ -169,9 +140,6 @@ You can get your API keys from:
- Anthropic API key: https://console.anthropic.com/
- OpenAI API key: https://platform.openai.com/api-keys
- OpenRouter API key: https://openrouter.ai/keys
- Gemini API key: https://aistudio.google.com/app/apikey
Complete installation documentation is available in our [Installation Guide](https://docs.ra-aid.ai/quickstart/installation).
## Usage
@ -184,51 +152,22 @@ ra-aid -m "Your task or query here"
# Research-only mode (no implementation)
ra-aid -m "Explain the authentication flow" --research-only
# File logging with console warnings (default mode)
ra-aid -m "Add new feature" --log-mode file
# Console-only logging with detailed output
ra-aid -m "Add new feature" --log-mode console --log-level debug
# Enable verbose logging for detailed execution information
ra-aid -m "Add new feature" --verbose
```
More information is available in our [Usage Examples](https://docs.ra-aid.ai/category/usage), [Logging System](https://docs.ra-aid.ai/configuration/logging), and [Memory Management](https://docs.ra-aid.ai/configuration/memory-management) documentation.
### Command Line Options
- `-m, --message`: The task or query to be executed (required except in chat mode)
- `-m, --message`: The task or query to be executed (required)
- `--research-only`: Only perform research without implementation
- `--provider`: The LLM provider to use (choices: anthropic, openai, openrouter, openai-compatible, gemini)
- `--model`: The model name to use (required for non-Anthropic providers)
- `--use-aider`: Enable aider integration for code editing. When enabled, RA.Aid uses aider's specialized code editing capabilities instead of its own native file modification tools. This option is useful when you need aider's specific editing features or prefer its approach to code modifications. This feature is optional and disabled by default.
- `--research-provider`: Provider to use specifically for research tasks (falls back to --provider if not specified)
- `--research-model`: Model to use specifically for research tasks (falls back to --model if not specified)
- `--planner-provider`: Provider to use specifically for planning tasks (falls back to --provider if not specified)
- `--planner-model`: Model to use specifically for planning tasks (falls back to --model if not specified)
- `--cowboy-mode`: Skip interactive approval for shell commands
- `--expert-provider`: The LLM provider to use for expert knowledge queries (choices: anthropic, openai, openrouter, openai-compatible, gemini)
- `--expert-model`: The model name to use for expert knowledge queries (required for non-OpenAI providers)
- `--hil, -H`: Enable human-in-the-loop mode for interactive assistance during task execution
- `--chat`: Enable chat mode with direct human interaction (implies --hil)
- `--log-mode`: Logging mode (choices: file, console)
- `file` (default): Logs to both file and console (only warnings and errors to console)
- `console`: Logs to console only at the specified log level with no file logging
- `--log-level`: Set specific logging level (debug, info, warning, error, critical)
- With `--log-mode=file`: Controls the file logging level (console still shows only warnings+)
- With `--log-mode=console`: Controls the console logging level directly
- Default: warning
- `--experimental-fallback-handler`: Enable experimental fallback handler to attempt to fix too calls when the same tool fails 3 times consecutively. (OPENAI_API_KEY recommended as openai has the top 5 tool calling models.) See `ra_aid/tool_leaderboard.py` for more info.
- `--pretty-logger`: Enables colored panel-style formatted logging output for better readability.
- `--temperature`: LLM temperature (0.0-2.0) to control randomness in responses
- `--disable-limit-tokens`: Disable token limiting for Anthropic Claude react agents
- `--recursion-limit`: Maximum recursion depth for agent operations (default: 100)
- `--test-cmd`: Custom command to run tests. If set user will be asked if they want to run the test command
- `--auto-test`: Automatically run tests after each code change
- `--max-test-cmd-retries`: Maximum number of test command retry attempts (default: 3)
- `--test-cmd-timeout`: Timeout in seconds for test command execution (default: 300)
- `--version`: Show program version number and exit
- `--server`: Launch the server with web interface (alpha feature)
- `--server-host`: Host to listen on for server (default: 0.0.0.0) (alpha feature)
- `--server-port`: Port to listen on for server (default: 1818) (alpha feature)
- `--hil, -H`: Enable human-in-the-loop mode, allowing the agent to interactively ask you questions during task execution
- `--provider`: Specify the model provider (See Model Configuration section)
- `--model`: Specify the model name (See Model Configuration section)
- `--expert-provider`: Specify the provider for the expert tool (defaults to OpenAI)
- `--expert-model`: Specify the model name for the expert tool (defaults to o1-preview for OpenAI)
- `--chat`: Enable chat mode for interactive assistance
- `--verbose`: Enable detailed logging output for debugging and monitoring
### Example Tasks
@ -305,38 +244,6 @@ Make sure to set your TAVILY_API_KEY environment variable to enable this feature
Enable with `--chat` to transform ra-aid into an interactive assistant that guides you through research and implementation tasks. Have a natural conversation about what you want to build, explore options together, and dispatch work - all while maintaining context of your discussion. Perfect for when you want to think through problems collaboratively rather than just executing commands.
### Server with Web Interface
RA.Aid includes a modern server with web interface that provides:
- Beautiful dark-themed chat interface
- Real-time streaming of command output
- Request history with quick resubmission
- Responsive design that works on all devices
To launch the server with web interface:
```bash
# Start with default settings (0.0.0.0:1818)
ra-aid --server
# Specify custom host and port
ra-aid --server --server-host 127.0.0.1 --server-port 3000
```
Command line options for server with web interface:
- `--server`: Launch the server with web interface
- `--server-host`: Host to listen on (default: 0.0.0.0)
- `--server-port`: Port to listen on (default: 1818)
After starting the server, open your web browser to the displayed URL (e.g., http://localhost:1818). The interface provides:
- Left sidebar showing request history
- Main chat area with real-time output
- Input box for typing requests
- Automatic reconnection handling
- Error reporting and status messages
All ra-aid commands sent through the web interface automatically use cowboy mode for seamless execution.
### Command Interruption and Feedback
<img src="assets/demo-chat-mode-interrupted-1.gif" alt="Command Interrupt Demo" autoplay loop style="display: block; margin: 0 auto; width: 100%; max-width: 800px;">
@ -365,11 +272,11 @@ ra-aid -m "Update all deprecated API calls" --cowboy-mode
### Model Configuration
RA.Aid supports multiple AI providers and models. The default model is Anthropic's Claude 3 Sonnet (`claude-3-7-sonnet-20250219`).
RA.Aid supports multiple AI providers and models. The default model is Anthropic's Claude 3 Sonnet (`claude-3-5-sonnet-20241022`).
When using the `--use-aider` flag, the programmer tool (aider) automatically selects its model based on your available API keys. It will use Claude models if ANTHROPIC_API_KEY is set, or fall back to OpenAI models if only OPENAI_API_KEY is available.
The programmer tool (aider) automatically selects its model based on your available API keys. It will use Claude models if ANTHROPIC_API_KEY is set, or fall back to OpenAI models if only OPENAI_API_KEY is available.
Note: The expert tool can be configured to use different providers (OpenAI, Anthropic, OpenRouter, Gemini) using the --expert-provider flag along with the corresponding EXPERT_*API_KEY environment variables. Each provider requires its own API key set through the appropriate environment variable.
Note: The expert tool can be configured to use different providers (OpenAI, Anthropic, OpenRouter) using the --expert-provider flag along with the corresponding EXPERT_*API_KEY environment variables. Each provider requires its own API key set through the appropriate environment variable.
#### Environment Variables
@ -378,17 +285,13 @@ RA.Aid supports multiple providers through environment variables:
- `ANTHROPIC_API_KEY`: Required for the default Anthropic provider
- `OPENAI_API_KEY`: Required for OpenAI provider
- `OPENROUTER_API_KEY`: Required for OpenRouter provider
- `DEEPSEEK_API_KEY`: Required for DeepSeek provider
- `OPENAI_API_BASE`: Required for OpenAI-compatible providers along with `OPENAI_API_KEY`
- `GEMINI_API_KEY`: Required for Gemini provider
Expert Tool Environment Variables:
- `EXPERT_OPENAI_API_KEY`: API key for expert tool using OpenAI provider
- `EXPERT_ANTHROPIC_API_KEY`: API key for expert tool using Anthropic provider
- `EXPERT_OPENROUTER_API_KEY`: API key for expert tool using OpenRouter provider
- `EXPERT_OPENAI_API_BASE`: Base URL for expert tool using OpenAI-compatible provider
- `EXPERT_GEMINI_API_KEY`: API key for expert tool using Gemini provider
- `EXPERT_DEEPSEEK_API_KEY`: API key for expert tool using DeepSeek provider
You can set these permanently in your shell's configuration file (e.g., `~/.bashrc` or `~/.zshrc`):
@ -404,16 +307,13 @@ export OPENROUTER_API_KEY=your_api_key_here
# For OpenAI-compatible providers
export OPENAI_API_BASE=your_api_base_url
# For Gemini provider
export GEMINI_API_KEY=your_api_key_here
```
### Custom Model Examples
1. **Using Anthropic (Default)**
```bash
# Uses default model (claude-3-7-sonnet-20250219)
# Uses default model (claude-3-5-sonnet-20241022)
ra-aid -m "Your task"
# Or explicitly specify:
@ -430,18 +330,9 @@ export GEMINI_API_KEY=your_api_key_here
ra-aid -m "Your task" --provider openrouter --model mistralai/mistral-large-2411
```
4. **Using DeepSeek**
```bash
# Direct DeepSeek provider (requires DEEPSEEK_API_KEY)
ra-aid -m "Your task" --provider deepseek --model deepseek-reasoner
# DeepSeek via OpenRouter
ra-aid -m "Your task" --provider openrouter --model deepseek/deepseek-r1
```
4. **Configuring Expert Provider**
The expert tool is used by the agent for complex logic and debugging tasks. It can be configured to use different providers (OpenAI, Anthropic, OpenRouter, Gemini, openai-compatible) using the --expert-provider flag along with the corresponding EXPERT_*API_KEY environment variables.
The expert tool is used by the agent for complex logic and debugging tasks. It can be configured to use different providers (OpenAI, Anthropic, OpenRouter) using the --expert-provider flag along with the corresponding EXPERT_*API_KEY environment variables.
```bash
# Use Anthropic for expert tool
@ -452,17 +343,9 @@ export GEMINI_API_KEY=your_api_key_here
export OPENROUTER_API_KEY=your_openrouter_api_key
ra-aid -m "Your task" --expert-provider openrouter --expert-model mistralai/mistral-large-2411
# Use DeepSeek for expert tool
export DEEPSEEK_API_KEY=your_deepseek_api_key
ra-aid -m "Your task" --expert-provider deepseek --expert-model deepseek-reasoner
# Use default OpenAI for expert tool
export EXPERT_OPENAI_API_KEY=your_openai_api_key
ra-aid -m "Your task" --expert-provider openai --expert-model o1
# Use Gemini for expert tool
export EXPERT_GEMINI_API_KEY=your_gemini_api_key
ra-aid -m "Your task" --expert-provider gemini --expert-model gemini-2.0-flash-thinking-exp-1219
ra-aid -m "Your task" --expert-provider openai --expert-model o1-preview
```
Aider specific Environment Variables you can add:
@ -479,9 +362,7 @@ Note: For `AIDER_FLAGS`, you can specify flags with or without the leading `--`.
**Important Notes:**
- Performance varies between models. The default Claude 3 Sonnet model currently provides the best and most reliable results.
- Model configuration is done via command line arguments: `--provider` and `--model`
- The `--model` argument is required for all providers except Anthropic (which defaults to `claude-3-7-sonnet-20250219`)
More information is available in our [Open Models Setup](https://docs.ra-aid.ai/quickstart/open-models) guide.
- The `--model` argument is required for all providers except Anthropic (which defaults to `claude-3-5-sonnet-20241022`)
## Architecture
@ -529,8 +410,8 @@ RA.Aid implements a three-stage architecture for handling development and resear
1. Clone the repository:
```bash
git clone https://github.com/ai-christianson/RA.Aid.git
cd RA.Aid
git clone https://github.com/ai-christianson/ra-aid.git
cd ra-aid
```
2. Create and activate a virtual environment:
@ -541,7 +422,7 @@ source venv/bin/activate # On Windows use `venv\Scripts\activate`
3. Install development dependencies:
```bash
pip install -e ".[dev]"
pip install -r requirements-dev.txt
```
4. Run tests:
@ -579,8 +460,6 @@ git push origin feature/your-feature-name
- Keep commits focused and message clear
- Ensure all tests pass before submitting PR
More information is available in our [Contributing Guide](https://docs.ra-aid.ai/contributing).
## License
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
@ -589,6 +468,6 @@ Copyright (c) 2024 AI Christianson
## Contact
- **Issues**: Please report bugs and feature requests on our [Issue Tracker](https://github.com/ai-christianson/RA.Aid/issues)
- **Repository**: [https://github.com/ai-christianson/RA.Aid](https://github.com/ai-christianson/RA.Aid)
- **Documentation**: [https://github.com/ai-christianson/RA.Aid#readme](https://github.com/ai-christianson/RA.Aid#readme)
- **Issues**: Please report bugs and feature requests on our [Issue Tracker](https://github.com/ai-christianson/ra-aid/issues)
- **Repository**: [https://github.com/ai-christianson/ra-aid](https://github.com/ai-christianson/ra-aid)
- **Documentation**: [https://github.com/ai-christianson/ra-aid#readme](https://github.com/ai-christianson/ra-aid#readme)

View File

@ -1,20 +0,0 @@
# A couple thoughts:
1. I like that you're using websockets. I think a bi-directional message passing is what we will ultimately need, and this sets up the groundwork for that.
2. Since rn we're just sending raw ra-aid text output to the front-end, an easy win to make it render nicer would be to put it in a non-wrapping or similar.
3. I like the minimal html/js as an initial setup.
Thoughts for down the line if we merge this (the following would be in future PRs):
1. We'll ultimately want to stream structured objects from the agent
* Rn, the code has a ton of cases like console.print(Panel(panel_content, title="Expert Context", border_style="blue")). We will want to abstract these calls and have something like a send_agent_output function. Depending on config (e.g. CLI use vs web ui use), that would send an object onto the web socket stream, or send output to the console.
2. We need a way to send user inputs back to the agent, e.g. anything currently using stdin (we don't use stdin directly rn, but we do have things that use tty or prompt the user for input which ultimately do use stdin)
3. Tricky run_shell_command is really powerful, and it essentially passes fully interactive TTY through to the user. If we want to keep the same UX, we could do this potentially by using tty.js on the front-end and streaming the tty over websocket. Alternatively, we could simply disable TTY tools like run_shell_command or restrict them to a non-tty mode (e.g. simple command running, stdout/stderr capture only)
4. Ideally we should keep the websocket and any API endpoints friendly to machine endpoints. JSON objects over websocket + any JSON REST endpoints we might need would satisfy this.
5. The UX itself should be carefully considered. IMO one of the big benefits of a web UI is to be able to have the agent doing work which I can direct from a mobile device, so I think an efficient mobile-first UI would be ideal. For this, my initial thought was something like react + shadcn.
6. Initially I had considered https://socket.io/. In this PR, we're just going straight to websockets, which is cool and has one less dependency. Not sure if socket.io would be worth it, but wanted to mention it. The overall architecture wouldn't change.
7. Semi-related: we should have a way to send logs to a directory or to a logging backend.
@leonj1 I think starting with a small PR like this and then incrementally adding to the web UI is a good approach.
@sosacrazy126 would be interested in your thoughts since I know you were working on webui as well, want to respect the work you've done.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

View File

@ -1,16 +0,0 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "frontend/common/tailwind.config.js",
"css": "frontend/common/src/styles/global.css",
"baseColor": "zinc",
"cssVariables": true
},
"aliases": {
"components": "@ra-aid/common/components",
"utils": "@ra-aid/common/utils"
}
}

20
docs/.gitignore vendored
View File

@ -1,20 +0,0 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@ -1,41 +0,0 @@
# Website
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
### Installation
```
$ yarn
```
### Local Development
```
$ yarn start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
### Build
```
$ yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
### Deployment
Using SSH:
```
$ USE_SSH=true yarn deploy
```
Not using SSH:
```
$ GIT_USER=<Your GitHub username> yarn deploy
```
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

View File

@ -1,8 +0,0 @@
{
"label": "Configuration",
"position": 3,
"link": {
"type": "generated-index",
"description": "Configure RA.Aid for optimal performance and behavior."
}
}

View File

@ -1,167 +0,0 @@
# Logging System
RA.Aid includes a powerful and flexible logging system that helps you troubleshoot issues and monitor the tool's operation. This document explains how to configure and use the logging features effectively.
## Overview
The logging system in RA.Aid provides:
- Configurable logging modes for different use cases
- Multiple log levels for controlling verbosity
- File logging with rotation and backup capabilities
- Pretty console logging with formatted display
- Comprehensive log messages capturing agent activity
## Command Line Options
RA.Aid provides the following command line options to control logging behavior:
### Log Mode
The `--log-mode` option determines where logs are directed:
```bash
ra-aid -m "Add new feature" --log-mode file
```
Available modes:
- `file` (default): Logs are written to both file and console
- Console shows only warnings and errors
- File contains all logs at the specified log level
- `console`: Logs are only shown in the console at the specified log level
- No log files are created
### Log Level
The `--log-level` option controls the verbosity of logging:
```bash
ra-aid -m "Add new feature" --log-level debug
```
Available levels (case-insensitive):
- `debug`: Most verbose, includes detailed debugging information
- `info`: General information about operations
- `warning` (default): Potential issues that might need attention
- `error`: Error conditions that prevent normal operation
- `critical`: Critical errors that may cause the application to terminate
The log level affects different outputs depending on the log mode:
- With `--log-mode=file`: Controls the file logging level, while console still shows only warnings and errors
- With `--log-mode=console`: Controls the console logging level directly
### Pretty Logger
The `--pretty-logger` option enables formatted panel-style logging output:
```bash
ra-aid -m "Add new feature" --pretty-logger
```
When enabled, log messages appear in colored panels with titles indicating the log level:
- 🔥 CRITICAL: Bold red panels for critical errors
- ❌ ERROR: Red panels for errors
- ⚠️ WARNING: Yellow panels for warnings
- INFO: Green panels for informational messages
- 🐞 DEBUG: Blue panels for debug messages
## Log Files
When `--log-mode=file` is used, RA.Aid creates and maintains log files with the following characteristics:
### Location
Log files are stored in the `.ra-aid/logs/` directory in your current working directory:
```
.ra-aid/logs/ra_aid_YYYYMMDD_HHMMSS.log
```
RA.Aid automatically creates this directory if it doesn't exist.
### Naming Convention
Log files follow a timestamp-based naming pattern:
```
ra_aid_YYYYMMDD_HHMMSS.log
```
Where:
- `YYYYMMDD`: Year, month, and day when the log file was created
- `HHMMSS`: Hour, minute, and second when the log file was created
Example: `ra_aid_20250301_143027.log`
### Log Rotation
RA.Aid uses automatic log rotation to manage log file size and prevent excessive disk usage:
- Maximum file size: 5 MB
- Maximum backup files: 100
When a log file reaches 5 MB, it is renamed with a numeric suffix (e.g., `.1`, `.2`), and a new log file is created. Up to 100 backup files are maintained.
## Examples
### Basic Usage (Default)
Use the default file logging mode with warnings and errors:
```bash
ra-aid -m "Add new feature"
```
### Detailed File Logging
Log everything including debug messages to file (console still shows only warnings+):
```bash
ra-aid -m "Add new feature" --log-level debug
```
### Console-Only Debugging
Get detailed debug logs in the console without creating log files:
```bash
ra-aid -m "Add new feature" --log-mode console --log-level debug
```
### Informational Console Logging
Get informational console output without debug details:
```bash
ra-aid -m "Add new feature" --log-mode console --log-level info
```
### Pretty Logging Output
Use formatted panel-style logging for better readability:
```bash
ra-aid -m "Add new feature" --pretty-logger
```
## Debugging Tips
- For troubleshooting issues, start with `--log-mode console --log-level debug`
- Examine log files in `.ra-aid/logs/` for historical issues
- Use `--pretty-logger` when working with complex tasks for better log clarity
- For production use, the default settings (`--log-mode file --log-level warning`) provide a good balance of information without excessive output
## Log Message Format
Standard log messages follow this format:
```
YYYY-MM-DD HH:MM:SS,MS - logger_name - LEVEL - Message text
```
Example:
```
2025-03-01 14:30:27,123 - ra_aid.agent_utils - WARNING - Command execution timeout after 60 seconds
```

View File

@ -1,124 +0,0 @@
# Memory Management
## Introduction
RA.Aid's memory system enables the agent to persist knowledge across sessions, creating a more efficient and coherent experience. The memory stores key facts, code snippets, and research notes about your project, allowing RA.Aid to build on previous work and avoid redundant operations.
This persistent memory gives RA.Aid the ability to:
- Remember important project facts and architectural decisions
- Store relevant code snippets with their file locations
- Preserve research findings and technical notes
- Build contextual understanding of your project over time
## Database Architecture
RA.Aid's memory is stored in a SQLite database file located in a hidden `.ra-aid` directory within your current working directory. The specific file path is:
```
.ra-aid/pk.db
```
This database implements several key tables:
- `KeyFact`: Stores important facts about your project
- `KeySnippet`: Preserves code snippets with their file paths and line numbers
- `ResearchNote`: Contains detailed research findings
- `HumanInput`: Tracks user inputs to provide context for memory items
All memory items have timestamps (created_at, updated_at) that help with relevance tracking and garbage collection.
The memory system uses thread-local state via Python's contextvars to ensure thread safety when multiple components access the database simultaneously.
## Memory Repositories and Garbage Collection
RA.Aid implements the repository pattern for database access, with specialized repositories for each memory type:
- `KeyFactRepository`
- `KeySnippetRepository`
- `ResearchNoteRepository`
Each repository provides methods to add, query, and delete items while abstracting the underlying database implementation.
To prevent uncontrolled growth of the memory database, RA.Aid implements automatic garbage collection that triggers when specific thresholds are exceeded:
- Facts: > 50 items
- Snippets: > 35 items
- Notes: > 30 items
When garbage collection activates, specialized agents analyze all stored items, considering factors like:
- Relevance to the current task
- Age of the memory items
- Relationship to other items
- Overall importance
Memory items associated with the current human input are protected from garbage collection to preserve context for the active task.
## CLI Commands and Configuration
RA.Aid provides a CLI flag to completely reset the memory database:
```bash
ra-aid --wipe-project-memory [other arguments]
```
This flag deletes the entire `.ra-aid/pk.db` database file, giving you a fresh start with no stored memory.
The memory statistics are displayed in the status panel when you start RA.Aid, showing:
- The number of facts, snippets, and notes currently stored
- A reminder about the `--wipe-project-memory` flag when memory items exist
### When to Wipe Memory
You might want to wipe project memory in these situations:
1. **Major Codebase Changes**: When your project has undergone significant refactoring or structural changes, making the stored memory items obsolete.
2. **Fresh Start**: When beginning a new phase of development and you want to clear out irrelevant historical context.
3. **Incorrect Information**: If the agent has stored incorrect or outdated information that's affecting its performance.
4. **Troubleshooting**: When unexpected behavior might be related to the stored memory items.
## Troubleshooting
Common memory-related issues and their solutions:
### Issue: Agent recalling outdated information
**Solution**: Use `--wipe-project-memory` to reset the memory database, especially after major code changes.
### Issue: Database lockup or corruption
**Solution**:
1. Ensure RA.Aid has properly shut down before starting a new session
2. If issues persist, use `--wipe-project-memory` to recreate the database
3. Check the logs in `.ra-aid/logs/` for specific errors
### Issue: Memory items seem irrelevant
**Solution**:
- Let the automatic garbage collection work by continuing to use RA.Aid
- For immediate reset, use `--wipe-project-memory`
### Issue: Missing .ra-aid directory
**Solution**: The directory is automatically created when you run RA.Aid. If it's missing, simply run RA.Aid again.
## Examples / Use Cases
### Example 1: Wiping memory after major refactoring
```bash
# After refactoring your project structure
ra-aid --wipe-project-memory -m "Update the authentication system"
```
### Example 2: Starting a new development phase
```bash
# Before starting work on a new major feature
ra-aid --wipe-project-memory -m "Implement payment processing system"
```
### Example 3: Checking memory status without wiping
```bash
# Check the memory statistics in the status panel
ra-aid -m "Show me the project structure"
# Look for the 💾 Memory: X facts, Y snippets, Z notes line
```
### Example 4: Using memory during ongoing development
When working on a complex feature over multiple sessions, memory allows RA.Aid to:
1. Remember architectural decisions from previous sessions
2. Recall the context of partially implemented features
3. Build on previous research without repeating the same queries
4. Maintain awareness of project constraints and requirements

View File

@ -1,96 +0,0 @@
# Reasoning Assistance
## Overview
Reasoning Assistance is a feature in RA.Aid that helps weaker models make better decisions about tool usage and task planning. It leverages a stronger model (typically your expert model) to provide strategic guidance to the main agent model at the beginning of each agent stage.
This feature is particularly useful when working with less capable models that may struggle with complex reasoning, tool selection, or planning. By providing expert guidance upfront, these models can perform more effectively and produce better results.
## How It Works
When reasoning assistance is enabled, RA.Aid performs the following steps at the beginning of each agent stage (research, planning, implementation):
1. Makes a one-off call to the expert model with a specialized prompt that includes:
- A description of the current task and stage
- The complete list of available tools
- Instructions to provide strategic guidance on approaching the task
2. Incorporates the expert model's response into the main agent's prompt.
3. The main agent then proceeds with execution, guided by the expert's recommendations on which tools to use and how to approach the task
## Configuration
### Command Line Flags
You can enable or disable reasoning assistance using these command-line flags:
```bash
# Enable reasoning assistance
ra-aid -m "Your task description" --reasoning-assistance
# Disable reasoning assistance (overrides model defaults)
ra-aid -m "Your task description" --no-reasoning-assistance
```
## Examples
### Using Reasoning Assistance with Weaker Models
```bash
# Use qwen-qwq-32b as the expert model to provide guidance
ra-aid --model qwen-32b-coder-instruct --expert-model qwen-qwq-32b --reasoning-assistance -m "Create a simple web server in Python"
```
### Disabling Reasoning Assistance for Strong Models
Reasoning assistance has different defaults depending on which model is used. If you would like to explicitly disable reasoning assistance, use the `--no-reasoning-assistance` flag.
```bash
# Use Claude 3 Opus without reasoning assistance
ra-aid -m "Create a simple web server in Python" --model claude-3-opus-20240229 --no-reasoning-assistance
```
## Benefits and Use Cases
Reasoning assistance provides several advantages:
1. **Better Tool Selection**: Helps models choose the right tools for specific tasks
2. **Improved Planning**: Provides strategic guidance on how to approach complex problems
3. **Reduced Errors**: Decreases the likelihood of tool misuse or inefficient approaches
4. **Model Flexibility**: Allows using weaker models more effectively by augmenting their reasoning capabilities
5. **Consistency**: Ensures more consistent behavior across different models
Common use cases include:
- Working with open-source models that have less robust tool use capabilities
- Tackling complex tasks that require careful planning and tool sequencing
- Ensuring consistent behavior when switching between different models
## Best Practices
For optimal results with reasoning assistance:
1. **Use Strong Expert Models**: The quality of reasoning assistance depends on the expert model's capabilities. Use the strongest model available for the expert role.
2. **Enable for Weaker Models**: Enable reasoning assistance by default for models known to struggle with tool selection or complex reasoning.
3. **Disable for Strong Models**: Models like Claude 3 Opus or GPT-4 typically don't need reasoning assistance and might perform better without it.
4. **Custom Tasks**: For highly specialized or unusual tasks, manually enabling reasoning assistance can be beneficial even for stronger models.
5. **Review Generated Guidance**: If debugging issues, examine the expert guidance provided to understand how it's influencing the agent's behavior.
## Troubleshooting
Common issues and solutions:
| Issue | Possible Solution |
|-------|-------------------|
| Reasoning assistance seems to make no difference | Verify both `--reasoning-assistance` flag is set and check the logs to confirm the expert model is being called |
| Expert model provides irrelevant or incorrect agent guidance | Try using a stronger expert model with `--expert-model` flag |
| Agent ignores expert guidance | Some models may not correctly follow the guidance format; try a different agent model |
| Slow performance | Reasoning assistance requires an additional model call at the start of each stage; disable it for simpler tasks if speed is critical |
| Conflicting approach with custom instructions | If you're providing specific instructions that conflict with reasoning assistance, use `--no-reasoning-assistance` |
If problems persist, check if the expert model and agent model are compatible, and consider adjusting the temperature setting to control randomness in both models.

View File

@ -1,140 +0,0 @@
# Thinking Models
RA.Aid supports models that can reveal their internal reasoning process, providing greater transparency into how they arrive at their responses. This feature, called "thinking models," helps users better understand the model's decision-making and logic.
## Overview
Thinking models allow you to see the model's internal reasoning process separately from its final response. This offers several benefits:
- **Transparency**: Understand how the model interprets your instructions and reasons through problems
- **Debugging**: Identify where a model's reasoning might go astray
- **Learning**: Gain insights into the model's approach to problem-solving
- **Trust**: Build greater confidence in the model's outputs by seeing its thought process
RA.Aid extracts and displays thinking content in special "💭 Thoughts" panels, keeping the main response clean while still providing access to the reasoning behind it.
## How Thinking Models Work in RA.Aid
RA.Aid supports two different methods for implementing thinking models:
### 1. Explicit Think Tags
Some models, like `qwen-qwq-32b`, use explicit XML-style thinking tags to delineate their reasoning process:
```
<think>
First, I need to understand what this code does.
The function seems to be parsing a configuration file...
</think>
The function parse_config() has an issue with its error handling...
```
RA.Aid extracts the content between these `<think>...</think>` tags and displays it separately from the main response.
### 2. Native Thinking Mode
More advanced models, like Claude 3.7 Sonnet, have native thinking capabilities built in at the API level. When RA.Aid uses these models, it sends special configuration parameters in the API request:
```python
{"thinking": {"type": "enabled", "budget_tokens": 12000}}
```
These models return structured responses with separate thinking and response content, which RA.Aid processes and displays accordingly.
## Configuration and Setup
### Enabling Thinking Models
To enable the display of thinking content, use the `--show-thoughts` CLI flag when running RA.Aid:
```bash
ra-aid -m "Add error handling to the database module" --show-thoughts
```
When this flag is enabled, RA.Aid will display thinking content in separate panels whenever it's available from the model.
### Supported Models
Currently, the following models support thinking mode in RA.Aid:
| Model | Provider | Type |
|-------|----------|------|
| qwen-qwq-32b | openai-compatible | Explicit think tags |
| claude-3-7-sonnet-20250219 | anthropic | Native thinking mode |
Each model's support is configured in the `models_params.py` file using the appropriate parameter.
## Examples and Usage
### Using a Model with Explicit Think Tags
When using the `qwen-qwq-32b` model with the `--show-thoughts` flag:
```bash
ra-aid -m "Refactor the error handling logic" --provider openai-compatible --model qwen-qwq-32b --show-thoughts
```
The model might include explicit think tags in its response:
```
<think>
Let me analyze the existing error handling logic:
1. Current approach uses try/except blocks scattered throughout
2. Error messages are inconsistent
3. There's no central logging mechanism
I should suggest a unified error handling approach with proper logging.
</think>
I recommend refactoring the error handling logic by implementing a centralized error handler...
```
RA.Aid will extract this thinking content and display it in a separate panel titled "💭 Thoughts", while showing only the actual response in the main output.
### Using a Model with Native Thinking
When using Claude 3.7 Sonnet with the `--show-thoughts` flag:
```bash
ra-aid -m "Debug the database connection issue" --provider anthropic --model claude-3-7-sonnet-20250219 --show-thoughts
```
RA.Aid configures the model to use its native thinking mode, and then processes the structured response to show thinking content separately.
### Without the --show-thoughts Flag
If you run RA.Aid without the `--show-thoughts` flag, the thinking content is still extracted from the model responses, but it won't be displayed in the console. This gives you a cleaner output focused only on the model's final responses.
## Troubleshooting and Best Practices
### Common Issues
#### Thinking content not appearing
If you're not seeing thinking content despite using the `--show-thoughts` flag:
- Ensure you're using a model that supports thinking (qwen-qwq-32b or claude-3-7-sonnet-20250219)
- Verify that the model is properly configured in your environment
- Check that the model is actually including thinking content in its responses (not all prompts will generate thinking)
#### Excessive or irrelevant thinking
If the thinking content is too verbose or irrelevant:
- Try to formulate more specific and concise prompts
- Consider using a different model if the thinking style doesn't meet your needs
### Best Practices
For the most effective use of thinking models:
1. **Use selectively**: Enable `--show-thoughts` when you need to understand the model's reasoning process, but consider disabling it for routine tasks to keep output concise.
2. **Choose the right model**: Different models have different thinking styles. Claude models tend to provide more structured and methodical reasoning, while other models might have different approaches.
3. **Ask questions that benefit from reasoning**: Complex problem-solving, debugging, and analysis tasks benefit most from seeing the model's thought process.
4. **Compare thinking with output**: Use the thinking content to evaluate the quality of the model's reasoning and identify potential flaws in its approach.
5. **Provide clear instructions**: When the model's thinking seems off-track, provide clearer instructions in your next prompt to guide its reasoning process.

View File

@ -1,79 +0,0 @@
# Contributing to RA.Aid
Welcome to the RA.Aid community! We're thrilled you're interested in contributing. This project thrives thanks to contributors like you, and we're excited to have you join us on this journey.
## Ways to Contribute
There are many valuable ways to contribute to RA.Aid:
### 1. Join Our Community
- Join our Discord community to connect with other users and contributors
- Help answer questions from other users
- Share your experiences and use cases
- Provide feedback and suggestions
### 2. Report Issues
- Found a bug? Open an issue on our [GitHub repository](https://github.com/ai-christianson/RA.Aid/issues)
- Before creating a new issue, please check if it already exists
- Include as much detail as possible:
- Steps to reproduce
- Expected vs actual behavior
- Your environment (OS, Python version, etc.)
- Any relevant error messages
### 3. Contribute to Documentation
- Our documentation lives in the `docs/` folder
- Found a typo? Have an idea for better explanations? Open a PR!
- You can use RA.Aid itself to help draft documentation changes
- Even small improvements are welcome
### 4. Code Contributions
- Look for issues labeled "help wanted" or "good first issue" on our GitHub
- Feel free to pick up any open issue - don't be shy!
- **You can even use RA.Aid to help understand the codebase and make changes**
- Before starting work on larger changes, please open an issue to discuss
## Making Your First Contribution
1. Fork the repository
2. Create a branch for your changes
3. Make your changes
4. Write/update tests if needed
5. Submit a Pull Request
6. Wait for review and address any feedback
Don't hesitate to ask questions if you're unsure about anything. Remember: every expert was once a beginner!
## Development Setup
1. Clone the repository:
```bash
git clone https://github.com/ai-christianson/RA.Aid.git
cd RA.Aid
```
2. Create and activate a virtual environment:
```bash
python -m venv venv
source venv/bin/activate
```
3. Install in dev mode:
```bash
pip install -e .
```
4. Run RA.Aid:
```bash
ra-aid -m "Your task or query here"
```
## This is Your Project Too
RA.Aid is a community project that grows stronger with each contribution. Whether it's fixing a typo in documentation, reporting a bug, or adding a new feature - every contribution matters and is valued.
Don't feel like you need to make massive changes to contribute. Small, focused contributions are often the best way to start. Use what you know, and learn as you go!

View File

@ -1,29 +0,0 @@
# Getting Help
## Troubleshooting Common Issues
Before seeking external help, check the following:
### Check the Logs
RA.Aid maintains detailed logs that can help diagnose many common issues. By default, logs are stored in the `.ra-aid/logs/` directory in your working directory.
1. Check the most recent log file in `.ra-aid/logs/` directory
2. Look for ERROR or WARNING level messages that might indicate what went wrong
3. For more detailed logging options, see the [Logging documentation](/configuration/logging)
### Common Problems
- **Error connecting to API**: Verify your API key is set correctly
- **Command not found**: Ensure RA.Aid is installed properly and in your PATH
- **Script execution failures**: Check that required dependencies are installed
## Bug Reports and Feature Requests
If you encounter any issues or have ideas for improvements, please file them on our [GitHub Issues page](https://github.com/ai-christianson/RA.Aid/issues).
## Community Support
Join our Discord community to chat with other users and get help:
- [Join the Discord Server](https://discord.gg/f6wYbzHYxV)

View File

@ -1,58 +0,0 @@
---
sidebar_position: 1
slug: /
---
# Welcome to RA.Aid
RA.Aid (pronounced "raid") is your AI-powered development companion that helps you build software autonomously. As a standalone coding agent built on LangChain's agent-based task execution framework, RA.Aid can handle research, planning, and implementation of your development tasks. Whether you're working on new features, refactoring code, or researching solutions, RA.Aid makes development faster and more efficient.
## Why RA.Aid?
- 🤖 **Autonomous Development**: Let RA.Aid handle complex programming tasks while you focus on the big picture
- 🔍 **Smart Research**: Automatically researches solutions and best practices
- 📋 **Intelligent Planning**: Breaks down complex tasks into manageable steps
- 💬 **Interactive Mode**: Get help when you need it through natural conversation
## Quick Start
Ready to get started? Jump right to:
- [Installation Guide](/quickstart/installation)
- [Basic Usage Examples](/usage/modern-web-app)
### Basic Example
Here's how simple it is to use RA.Aid:
```bash
# Install RA.Aid
pip install ra-aid
# Set up API keys
export ANTHROPIC_API_KEY=your_key_here
export OPENAI_API_KEY=your_key_here
export TAVILY_API_KEY=your_key_here
# Start using it
ra-aid -m "Add input validation to the login form"
```
## Key Features
- **Three-Stage Workflow**: Research → Planning → Implementation
- **Web Research**: Automatically searches for best practices and solutions
- **Interactive Mode**: Get help when you need it through natural conversation
- **Multiple AI Providers**: Support for various AI models to suit your needs
- **Git Integration**: Works seamlessly with your version control
- **Standalone Code Agent**: Built-in code modification capabilities by default
- **Optional Aider Integration**: Use the `--use-aider` flag to leverage aider's specialized code editing abilities
## Next Steps
- Check out the [Installation Guide](/quickstart/installation) to set up RA.Aid
- See [Usage Examples](/usage/modern-web-app) to get started quickly
- Read our [Contributing Guide](/contributing) to get involved
- Join our [Discord Community](https://discord.gg/f6wYbzHYxV) for help and discussions
Ready to revolutionize your development workflow? Let's get started! 🚀

View File

@ -1,8 +0,0 @@
{
"label": "Quick Start",
"position": 2,
"link": {
"type": "generated-index",
"description": "5 minutes to learn the most important Docusaurus concepts."
}
}

View File

@ -1,70 +0,0 @@
---
sidebar_position: 1
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Installation
Getting started is easy! You can install RA.Aid using any of these three methods - pick the one that works best for you:
<Tabs groupId="install-method">
<TabItem value="uv" label="UV" default>
Create a new Python 3.12 virtual environment and install RA.Aid:
First install [uv](https://docs.astral.sh/uv/getting-started/installation/), then:
```bash
uv venv -p 3.12
```
<Tabs groupId="operating-system">
<TabItem value="unix" label="Unix/macOS">
```bash
source .venv/bin/activate
```
</TabItem>
<TabItem value="windows" label="Windows">
```bash
.venv\Scripts\activate
```
</TabItem>
</Tabs>
```bash
uv pip install ra-aid
```
</TabItem>
<TabItem value="pip" label="pip">
Install RA.Aid using pip:
```bash
pip install ra-aid
```
:::note
If you're using Python 3.13 or newer, we recommend using the UV installation method instead due to compatibility issues with newer Python versions.
:::
</TabItem>
<TabItem value="macos" label="macOS">
Install RA.Aid using Homebrew:
```bash
brew tap ai-christianson/homebrew-ra-aid
brew install ra-aid
```
</TabItem>
</Tabs>
Once installed, see the [Recommended Configuration](recommended) to set up RA.Aid with the recommended settings.

View File

@ -1,215 +0,0 @@
---
sidebar_position: 3
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Open Models Configuration
RA.Aid supports a variety of open source and compatible model providers. This guide covers configuration options and best practices for using different models with RA.Aid.
## Overview
<Tabs groupId="provider-overview">
<TabItem value="providers" label="Supported Providers" default>
RA.Aid supports these model providers:
| Provider | Description | Key Features |
|----------|-------------|--------------|
| DeepSeek | Chinese hedge fund who creates sophisticated LLMs | Strong, open models like R1 |
| OpenRouter | Multi-model gateway service | Access to 100+ models, unified API interface, pay-per-token |
| OpenAI-compatible | Self-hosted model endpoints | Compatible with Llama, Mistral and other open models |
| Anthropic | Claude model series | 200k token context, strong tool use, JSON/XML parsing |
| Gemini | Google's multimodal models | Code generation in 20+ languages, parallel request support |
</TabItem>
<TabItem value="setup" label="Quick Setup">
### Basic Configuration
1. Set your provider's API key:
```bash
# Choose the appropriate provider
export DEEPSEEK_API_KEY=your_key
export OPENROUTER_API_KEY=your_key
export OPENAI_API_KEY=your_key
export ANTHROPIC_API_KEY=your_key
export GEMINI_API_KEY=your_key
```
2. Run RA.Aid with your chosen provider:
```bash
ra-aid -m "Your task" --provider <provider> --model <model>
```
</TabItem>
</Tabs>
## Provider Configuration
<Tabs groupId="model-provider">
<TabItem value="deepseek" label="DeepSeek" default>
### DeepSeek Models
DeepSeek offers powerful reasoning models optimized for complex tasks.
```bash
# Environment setup
export DEEPSEEK_API_KEY=your_api_key_here
# Basic usage
ra-aid -m "Your task" --provider deepseek --model deepseek-reasoner
# With temperature control
ra-aid -m "Your task" --provider deepseek --model deepseek-reasoner --temperature 0.7
```
**Available Models:**
- `deepseek-reasoner`: Optimized for reasoning tasks
- Access via OpenRouter: `deepseek/deepseek-r1`
</TabItem>
<TabItem value="openrouter" label="OpenRouter">
### OpenRouter Integration
OpenRouter provides access to multiple open source models through a single API.
```bash
# Environment setup
export OPENROUTER_API_KEY=your_api_key_here
# Example commands
ra-aid -m "Your task" --provider openrouter --model mistralai/mistral-large-2411
ra-aid -m "Your task" --provider openrouter --model deepseek/deepseek-r1
```
**Popular Models:**
- `mistralai/mistral-large-2411`
- `anthropic/claude-3`
- `deepseek/deepseek-r1`
</TabItem>
<TabItem value="openai-compatible" label="OpenAI-compatible">
### OpenAI-compatible Endpoints
Use OpenAI-compatible API endpoints with custom hosting solutions.
```bash
# Environment setup
export OPENAI_API_KEY=your_api_key_here
export OPENAI_API_BASE=https://your-api-endpoint
# Usage
ra-aid -m "Your task" --provider openai-compatible --model your-model-name
```
**Configuration Options:**
- Set custom base URL with `OPENAI_API_BASE`
- Supports temperature control
- Compatible with most OpenAI-style APIs
</TabItem>
<TabItem value="gemini" label="Google Gemini">
### Google Gemini Models
Google's Gemini models offer powerful multimodal capabilities with extensive code generation support.
```bash
# Environment setup
export GEMINI_API_KEY=your_api_key_here
# Basic usage
ra-aid -m "Your task" --provider gemini --model gemini-1.5-pro-latest
# With temperature control
ra-aid -m "Your task" --provider gemini --model gemini-1.5-flash-latest --temperature 0.5
```
**Available Models:**
- `gemini-pro`: Original Gemini Pro model
- `gemini-1.5-flash-latest`: Latest Gemini 1.5 Flash model (fast responses)
- `gemini-1.5-pro-latest`: Latest Gemini 1.5 Pro model (strong reasoning)
- `gemini-1.5-flash`: Gemini 1.5 Flash release
- `gemini-1.5-pro`: Gemini 1.5 Pro release
- `gemini-1.0-pro`: Original Gemini 1.0 Pro model
**Configuration Notes:**
- All Gemini models support a 128,000 token context window
- Temperature control is supported for creative vs. deterministic responses
- Obtain your API key from [AI Studio](https://aistudio.google.com/app/apikey)
</TabItem>
</Tabs>
## Advanced Configuration
<Tabs groupId="advanced-config">
<TabItem value="expert" label="Expert Model">
### Expert Tool Configuration
Configure the expert model for specialized tasks; this usually benefits from a more powerful, slower, reasoning model:
```bash
# DeepSeek expert
export EXPERT_DEEPSEEK_API_KEY=your_key
ra-aid -m "Your task" --expert-provider deepseek --expert-model deepseek-reasoner
# OpenRouter expert
export EXPERT_OPENROUTER_API_KEY=your_key
ra-aid -m "Your task" --expert-provider openrouter --expert-model mistralai/mistral-large-2411
# Gemini expert
export EXPERT_GEMINI_API_KEY=your_key
ra-aid -m "Your task" --expert-provider gemini --expert-model gemini-2.0-flash-thinking-exp-1219
```
</TabItem>
<TabItem value="temperature" label="Temperature Control">
### Temperature Settings
Control model creativity vs determinism:
```bash
# More deterministic (good for coding)
ra-aid -m "Your task" --temperature 0.2
# More creative (good for brainstorming)
ra-aid -m "Your task" --temperature 0.8
```
**Note:** Not all models support temperature control. Check provider documentation.
</TabItem>
</Tabs>
## Best Practices
- Set environment variables in your shell configuration file
- Use lower temperatures (0.1-0.3) for coding tasks
- Test different models to find the best fit for your use case
- Consider using expert mode for complex programming tasks
## Environment Variables
Complete list of supported environment variables:
| Variable | Provider | Purpose |
|----------|----------|----------|
| `OPENROUTER_API_KEY` | OpenRouter | Main API access |
| `DEEPSEEK_API_KEY` | DeepSeek | Main API access |
| `OPENAI_API_KEY` | OpenAI-compatible | API access |
| `OPENAI_API_BASE` | OpenAI-compatible | Custom endpoint |
| `ANTHROPIC_API_KEY` | Anthropic | API access |
| `GEMINI_API_KEY` | Gemini | API access |
| `EXPERT_OPENROUTER_API_KEY` | OpenRouter | Expert tool |
| `EXPERT_DEEPSEEK_API_KEY` | DeepSeek | Expert tool |
| `EXPERT_GEMINI_API_KEY` | Gemini | Expert tool |
## Troubleshooting
- Verify API keys are set correctly
- Check endpoint URLs for OpenAI-compatible setups
- Monitor API rate limits and quotas

View File

@ -1,76 +0,0 @@
---
sidebar_position: 2
---
# Recommended Config
This configuration combines the strengths of multiple AI models to provide the best experience:
- Anthropic Sonnet excels at driving the agent's core reasoning and planning
- OpenAI's models provide robust debugging and logical analysis capabilities
- Tavily web search integration allows the agent to find relevant information online
:::info
RA.Aid must be installed before using these configurations. If you haven't installed it yet, please see the [Installation Guide](installation).
:::
## Getting API Keys
To use RA.Aid with the recommended configuration, you'll need to obtain API keys from the following services:
1. **OpenAI API Key**: Create an account at [OpenAI's platform](https://platform.openai.com) and generate an API key from your dashboard.
2. **Anthropic API Key**: Sign up at [Anthropic's Console](https://console.anthropic.com), then generate an API key from the API Keys section.
3. **Tavily API Key** (optional): Create an account at [Tavily](https://app.tavily.com/sign-in) and get your API key from the dashboard.
Please keep your API keys secure and never share them publicly. Each service has its own pricing and usage terms.
## Configuration
Configure your API keys:
```bash
# For OpenAI (required)
export OPENAI_API_KEY=your_api_key_here
# For Anthropic (required)
export ANTHROPIC_API_KEY=your_api_key_here
# For web search capability (optional)
export TAVILY_API_KEY=your_api_key_here
```
## Basic Usage
Start RA.Aid in interactive chat mode:
```bash
ra-aid --chat
```
Or run with a single command:
```bash
ra-aid -m "Help me understand this code"
```
If you prefer to use aider's specialized code editing capabilities instead of RA.Aid's built-in file modification tools:
```bash
ra-aid -m "Implement this feature" --use-aider
```
You can control logging verbosity and location using the `--log-mode` and `--log-level` options:
```bash
# Log to file (with only warnings to console)
ra-aid -m "Your task" --log-mode file --log-level debug
# Log everything to console
ra-aid -m "Your task" --log-mode console --log-level info
```
For more detailed logging configuration, see the [Logging documentation](../configuration/logging.md).
For information on RA.Aid's memory management and how to reset memory when needed, see the [Memory Management documentation](../configuration/memory-management.md).

View File

@ -1,8 +0,0 @@
{
"label": "Usage",
"position": 4,
"link": {
"type": "generated-index",
"description": "Learn how to use RA.Aid effectively in different scenarios."
}
}

View File

@ -1,19 +0,0 @@
# Create a Game using RA.Aid
RA.Aid can work on almost any kind of software, including writing games in languages like C++.
## Creating the Initial Game
To get started with creating a game, you can use RA.Aid with a simple command like:
```
ra-aid -m "Create a basic breakout clone in C++ using opengl."
```
## Adding Features
Once your base game is working, you can add features like this:
```
ra-aid -m "Add score tracking/display to the main screen."
```

View File

@ -1,45 +0,0 @@
# Create a Modern Web App
When using AI tools like RA.Aid to create a modern web application, it's most effective to break down the work from a high level into discrete tasks. This guide will walk you through a practical example of building a Next.js application with common modern features.
## Setting Up a Fresh Next.js Application
To get started with a new Next.js project, you can use RA.Aid with a simple command like:
```
ra-aid -m "Initialize a new nextjs app."
```
RA.Aid will execute the necessary commands and set up a clean Next.js project for you with the latest best practices. It'll even search the web to read documentation about the latest version of Next.
## Adding shadcn/ui Components
Once your base Next.js application is ready, you can add the shadcn/ui component library. Tell RA.Aid:
```
ra-aid -m "Install shadcn into this project and put a few examples of shadcn components on the main page."
```
This will configure your project with shadcn/ui's CLI, set up the necessary styling, and add your first components.
## Integrating Prisma with SQLite
For database integration, you can add Prisma ORM with SQLite. Simply instruct RA.Aid:
```
ra-aid -m "Integrate prisma/sqlite into this project."
```
RA.Aid will handle the Prisma setup, create your database schema, and set up your first model.
## Adding Features Incrementally
With the foundation in place, you can start adding features one by one. Here's an example:
```
ra-aid -m "Add a simple user registration form. Include fields for email and password."
```
Keep your feature requests focused and specific. This allows RA.Aid to implement them effectively while maintaining code quality.
Remember to build your application incrementally, testing each feature as it's added. This approach helps manage complexity and ensures a stable development process.

View File

@ -1,17 +0,0 @@
# Work with an Existing Mono Repo using RA.Aid
RA.Aid is good at handling complex monorepo projects. For example, if you you have an app set up like this:
```
app/
web/
backend/
```
You can run RA.Aid at the top level and give it commands like this:
```
ra-aid -m "Update the user form to support birthdates. Be sure to also update the DB model and migration scripts."
```
RA.Aid will proceed to work on multiple high-level components of your application.

View File

@ -1,74 +0,0 @@
import {themes as prismThemes} from 'prism-react-renderer';
import type {Config} from '@docusaurus/types';
import type * as Preset from '@docusaurus/preset-classic';
const config: Config = {
title: 'RA-Aid Documentation',
favicon: 'img/favicon.ico',
url: 'https://docs.ra-aid.ai',
baseUrl: '/',
onDuplicateRoutes: 'ignore',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
plugins: [],
presets: [
[
'classic',
{
docs: {
sidebarPath: './sidebars.ts',
routeBasePath: '/',
},
theme: {
customCss: './src/css/custom.css',
},
} satisfies Preset.Options,
],
],
themeConfig: {
navbar: {
logo: {
alt: 'Site Logo',
src: 'img/logo-black-transparent.png',
srcDark: 'img/logo-white-transparent.gif',
href: 'https://ra-aid.ai'
},
items: [
{
type: 'doc',
position: 'left',
docId: 'intro',
label: 'Docs',
},
{
href: 'https://github.com/ai-christianson/RA.Aid',
label: 'GitHub',
position: 'right',
},
],
},
footer: {
style: 'dark',
copyright: `Copyright © ${new Date().getFullYear()} AI Christianson. Built with RA.Aid and Docusaurus.`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
},
colorMode: {
defaultMode: 'dark',
respectPrefersColorScheme: false,
},
} satisfies Preset.ThemeConfig,
};
export default config;

17934
docs/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +0,0 @@
{
"name": "docs",
"version": "0.0.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "node scripts/version.js && docusaurus start",
"generate-version": "node scripts/version.js",
"build": "npm run generate-version && docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc",
"version-json": "node scripts/version.js"
},
"dependencies": {
"@docusaurus/core": "3.7.0",
"@docusaurus/preset-classic": "3.7.0",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.7.0",
"@docusaurus/tsconfig": "3.7.0",
"@docusaurus/types": "3.7.0",
"typescript": "~5.6.2"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 3 chrome version",
"last 3 firefox version",
"last 5 safari version"
]
},
"engines": {
"node": ">=18.0"
}
}

View File

@ -1,31 +0,0 @@
# Docusaurus Scripts
This directory contains utility scripts for the Docusaurus documentation site.
## version.js
This script reads the version from `../../ra_aid/__version__.py` and creates a `version.json` file in the Docusaurus `static/` directory, which will be included in the built site.
### Usage
The script is automatically run as part of the build and start processes via npm scripts defined in `package.json`, but can also be run manually:
```bash
# From docs directory
npm run version-json
# Or directly
node scripts/version.js
```
### Output
The script creates a `static/version.json` file with the following format:
```json
{
"version": "x.y.z"
}
```
This file will be available at `/version.json` in the built site, allowing client-side version checks.

View File

@ -1,62 +0,0 @@
#!/usr/bin/env node
/**
* Script to read version from ra_aid/__version__.py and create version.json
* in the Docusaurus static directory.
*/
const fs = require('fs');
const path = require('path');
// Paths
const versionFilePath = path.resolve(__dirname, '../../ra_aid/__version__.py');
const outputPath = path.resolve(__dirname, '../static/version.json');
/**
* Extract version string from the __version__.py file
* @param {string} content - The file content
* @returns {string|null} - Extracted version or null if not found
*/
function extractVersion(content) {
const regex = /__version__\s*=\s*["']([^"']+)["']/;
const match = content.match(regex);
return match ? match[1] : null;
}
// Main function to create version.json
function createVersionJson() {
try {
// Read version file
console.log(`Reading version from ${versionFilePath}...`);
const versionFileContent = fs.readFileSync(versionFilePath, 'utf8');
// Extract version
const version = extractVersion(versionFileContent);
if (!version) {
console.error('Failed to extract version from file');
process.exit(1);
}
console.log(`Extracted version: ${version}`);
// Create version JSON
const versionJson = JSON.stringify({ version }, null, 2);
// Ensure static directory exists
const staticDir = path.dirname(outputPath);
if (!fs.existsSync(staticDir)) {
console.log(`Creating directory: ${staticDir}`);
fs.mkdirSync(staticDir, { recursive: true });
}
// Write JSON file
fs.writeFileSync(outputPath, versionJson);
console.log(`Version JSON written to ${outputPath}`);
} catch (error) {
console.error(`Error creating version.json: ${error.message}`);
process.exit(1);
}
}
// Execute the main function
createVersionJson();

View File

@ -1,33 +0,0 @@
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
/**
* Creating a sidebar enables you to:
- create an ordered group of docs
- render a sidebar for each doc of that group
- provide next/previous navigation
The sidebars can be generated from the filesystem, or explicitly defined here.
Create as many sidebars as you want.
*/
const sidebars: SidebarsConfig = {
// By default, Docusaurus generates a sidebar from the docs folder structure
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
// But you can create a sidebar manually
/*
tutorialSidebar: [
'intro',
'hello',
{
type: 'category',
label: 'Tutorial',
items: ['quickstarts/create-a-document'],
},
],
*/
};
export default sidebars;

View File

@ -1,71 +0,0 @@
import type {ReactNode} from 'react';
import clsx from 'clsx';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
type FeatureItem = {
title: string;
Svg: React.ComponentType<React.ComponentProps<'svg'>>;
description: ReactNode;
};
const FeatureList: FeatureItem[] = [
{
title: 'Easy to Use',
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
description: (
<>
Docusaurus was designed from the ground up to be easily installed and
used to get your website up and running quickly.
</>
),
},
{
title: 'Focus on What Matters',
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
description: (
<>
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
ahead and move your docs into the <code>docs</code> directory.
</>
),
},
{
title: 'Powered by React',
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
description: (
<>
Extend or customize your website layout by reusing React. Docusaurus can
be extended while reusing the same header and footer.
</>
),
},
];
function Feature({title, Svg, description}: FeatureItem) {
return (
<div className={clsx('col col--4')}>
<div className="text--center">
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<Heading as="h3">{title}</Heading>
<p>{description}</p>
</div>
</div>
);
}
export default function HomepageFeatures(): ReactNode {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
);
}

View File

@ -1,11 +0,0 @@
.features {
display: flex;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.featureSvg {
height: 200px;
width: 200px;
}

View File

@ -1,30 +0,0 @@
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
:root {
--ifm-color-primary: #2e8555;
--ifm-color-primary-dark: #29784c;
--ifm-color-primary-darker: #277148;
--ifm-color-primary-darkest: #205d3b;
--ifm-color-primary-light: #33925d;
--ifm-color-primary-lighter: #359962;
--ifm-color-primary-lightest: #3cad6e;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
--ifm-color-primary: #25c2a0;
--ifm-color-primary-dark: #21af90;
--ifm-color-primary-darker: #1fa588;
--ifm-color-primary-darkest: #1a8870;
--ifm-color-primary-light: #29d5b0;
--ifm-color-primary-lighter: #32d8b4;
--ifm-color-primary-lightest: #4fddbf;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
}

View File

@ -1 +0,0 @@
version.json

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -1,171 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1088" height="687.962" viewBox="0 0 1088 687.962">
<title>Easy to Use</title>
<g id="Group_12" data-name="Group 12" transform="translate(-57 -56)">
<g id="Group_11" data-name="Group 11" transform="translate(57 56)">
<path id="Path_83" data-name="Path 83" d="M1017.81,560.461c-5.27,45.15-16.22,81.4-31.25,110.31-20,38.52-54.21,54.04-84.77,70.28a193.275,193.275,0,0,1-27.46,11.94c-55.61,19.3-117.85,14.18-166.74,3.99a657.282,657.282,0,0,0-104.09-13.16q-14.97-.675-29.97-.67c-15.42.02-293.07,5.29-360.67-131.57-16.69-33.76-28.13-75-32.24-125.27-11.63-142.12,52.29-235.46,134.74-296.47,155.97-115.41,369.76-110.57,523.43,7.88C941.15,276.621,1036.99,396.031,1017.81,560.461Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_84" data-name="Path 84" d="M986.56,670.771c-20,38.52-47.21,64.04-77.77,80.28a193.272,193.272,0,0,1-27.46,11.94c-55.61,19.3-117.85,14.18-166.74,3.99a657.3,657.3,0,0,0-104.09-13.16q-14.97-.675-29.97-.67-23.13.03-46.25,1.72c-100.17,7.36-253.82-6.43-321.42-143.29L382,283.981,444.95,445.6l20.09,51.59,55.37-75.98L549,381.981l130.2,149.27,36.8-81.27L970.78,657.9l14.21,11.59Z" transform="translate(-56 -106.019)" fill="#f2f2f2"/>
<path id="Path_85" data-name="Path 85" d="M302,282.962l26-57,36,83-31-60Z" opacity="0.1"/>
<path id="Path_86" data-name="Path 86" d="M610.5,753.821q-14.97-.675-29.97-.67L465.04,497.191Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<path id="Path_87" data-name="Path 87" d="M464.411,315.191,493,292.962l130,150-132-128Z" opacity="0.1"/>
<path id="Path_88" data-name="Path 88" d="M908.79,751.051a193.265,193.265,0,0,1-27.46,11.94L679.2,531.251Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<circle id="Ellipse_11" data-name="Ellipse 11" cx="3" cy="3" r="3" transform="translate(479 98.962)" fill="#f2f2f2"/>
<circle id="Ellipse_12" data-name="Ellipse 12" cx="3" cy="3" r="3" transform="translate(396 201.962)" fill="#f2f2f2"/>
<circle id="Ellipse_13" data-name="Ellipse 13" cx="2" cy="2" r="2" transform="translate(600 220.962)" fill="#f2f2f2"/>
<circle id="Ellipse_14" data-name="Ellipse 14" cx="2" cy="2" r="2" transform="translate(180 265.962)" fill="#f2f2f2"/>
<circle id="Ellipse_15" data-name="Ellipse 15" cx="2" cy="2" r="2" transform="translate(612 96.962)" fill="#f2f2f2"/>
<circle id="Ellipse_16" data-name="Ellipse 16" cx="2" cy="2" r="2" transform="translate(736 192.962)" fill="#f2f2f2"/>
<circle id="Ellipse_17" data-name="Ellipse 17" cx="2" cy="2" r="2" transform="translate(858 344.962)" fill="#f2f2f2"/>
<path id="Path_89" data-name="Path 89" d="M306,121.222h-2.76v-2.76h-1.48v2.76H299V122.7h2.76v2.759h1.48V122.7H306Z" fill="#f2f2f2"/>
<path id="Path_90" data-name="Path 90" d="M848,424.222h-2.76v-2.76h-1.48v2.76H841V425.7h2.76v2.759h1.48V425.7H848Z" fill="#f2f2f2"/>
<path id="Path_91" data-name="Path 91" d="M1144,719.981c0,16.569-243.557,74-544,74s-544-57.431-544-74,243.557,14,544,14S1144,703.413,1144,719.981Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_92" data-name="Path 92" d="M1144,719.981c0,16.569-243.557,74-544,74s-544-57.431-544-74,243.557,14,544,14S1144,703.413,1144,719.981Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<ellipse id="Ellipse_18" data-name="Ellipse 18" cx="544" cy="30" rx="544" ry="30" transform="translate(0 583.962)" fill="#3f3d56"/>
<path id="Path_93" data-name="Path 93" d="M624,677.981c0,33.137-14.775,24-33,24s-33,9.137-33-24,33-96,33-96S624,644.844,624,677.981Z" transform="translate(-56 -106.019)" fill="#ff6584"/>
<path id="Path_94" data-name="Path 94" d="M606,690.66c0,15.062-6.716,10.909-15,10.909s-15,4.153-15-10.909,15-43.636,15-43.636S606,675.6,606,690.66Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<rect id="Rectangle_97" data-name="Rectangle 97" width="92" height="18" rx="9" transform="translate(489 604.962)" fill="#2f2e41"/>
<rect id="Rectangle_98" data-name="Rectangle 98" width="92" height="18" rx="9" transform="translate(489 586.962)" fill="#2f2e41"/>
<path id="Path_95" data-name="Path 95" d="M193,596.547c0,55.343,34.719,100.126,77.626,100.126" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_96" data-name="Path 96" d="M270.626,696.673c0-55.965,38.745-101.251,86.626-101.251" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_97" data-name="Path 97" d="M221.125,601.564c0,52.57,22.14,95.109,49.5,95.109" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_98" data-name="Path 98" d="M270.626,696.673c0-71.511,44.783-129.377,100.126-129.377" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_99" data-name="Path 99" d="M254.3,697.379s11.009-.339,14.326-2.7,16.934-5.183,17.757-1.395,16.544,18.844,4.115,18.945-28.879-1.936-32.19-3.953S254.3,697.379,254.3,697.379Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_100" data-name="Path 100" d="M290.716,710.909c-12.429.1-28.879-1.936-32.19-3.953-2.522-1.536-3.527-7.048-3.863-9.591l-.368.014s.7,8.879,4.009,10.9,19.761,4.053,32.19,3.953c3.588-.029,4.827-1.305,4.759-3.2C294.755,710.174,293.386,710.887,290.716,710.909Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_101" data-name="Path 101" d="M777.429,633.081c0,38.029,23.857,68.8,53.341,68.8" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_102" data-name="Path 102" d="M830.769,701.882c0-38.456,26.623-69.575,59.525-69.575" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_103" data-name="Path 103" d="M796.755,636.528c0,36.124,15.213,65.354,34.014,65.354" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_104" data-name="Path 104" d="M830.769,701.882c0-49.139,30.773-88.9,68.8-88.9" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_105" data-name="Path 105" d="M819.548,702.367s7.565-.233,9.844-1.856,11.636-3.562,12.2-.958,11.368,12.949,2.828,13.018-19.844-1.33-22.119-2.716S819.548,702.367,819.548,702.367Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_106" data-name="Path 106" d="M844.574,711.664c-8.54.069-19.844-1.33-22.119-2.716-1.733-1.056-2.423-4.843-2.654-6.59l-.253.01s.479,6.1,2.755,7.487,13.579,2.785,22.119,2.716c2.465-.02,3.317-.9,3.27-2.2C847.349,711.159,846.409,711.649,844.574,711.664Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_107" data-name="Path 107" d="M949.813,724.718s11.36-1.729,14.5-4.591,16.89-7.488,18.217-3.667,19.494,17.447,6.633,19.107-30.153,1.609-33.835-.065S949.813,724.718,949.813,724.718Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_108" data-name="Path 108" d="M989.228,734.173c-12.86,1.659-30.153,1.609-33.835-.065-2.8-1.275-4.535-6.858-5.2-9.45l-.379.061s1.833,9.109,5.516,10.783,20.975,1.725,33.835.065c3.712-.479,4.836-1.956,4.529-3.906C993.319,732.907,991.991,733.817,989.228,734.173Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_109" data-name="Path 109" d="M670.26,723.9s9.587-1.459,12.237-3.875,14.255-6.32,15.374-3.095,16.452,14.725,5.6,16.125-25.448,1.358-28.555-.055S670.26,723.9,670.26,723.9Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_110" data-name="Path 110" d="M703.524,731.875c-10.853,1.4-25.448,1.358-28.555-.055-2.367-1.076-3.827-5.788-4.39-7.976l-.32.051s1.547,7.687,4.655,9.1,17.7,1.456,28.555.055c3.133-.4,4.081-1.651,3.822-3.3C706.977,730.807,705.856,731.575,703.524,731.875Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_111" data-name="Path 111" d="M178.389,719.109s7.463-1.136,9.527-3.016,11.1-4.92,11.969-2.409,12.808,11.463,4.358,12.553-19.811,1.057-22.23-.043S178.389,719.109,178.389,719.109Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_112" data-name="Path 112" d="M204.285,725.321c-8.449,1.09-19.811,1.057-22.23-.043-1.842-.838-2.979-4.506-3.417-6.209l-.249.04s1.2,5.984,3.624,7.085,13.781,1.133,22.23.043c2.439-.315,3.177-1.285,2.976-2.566C206.973,724.489,206.1,725.087,204.285,725.321Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_113" data-name="Path 113" d="M439.7,707.337c0,30.22-42.124,20.873-93.7,20.873s-93.074,9.347-93.074-20.873,42.118-36.793,93.694-36.793S439.7,677.117,439.7,707.337Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<path id="Path_114" data-name="Path 114" d="M439.7,699.9c0,30.22-42.124,20.873-93.7,20.873s-93.074,9.347-93.074-20.873S295.04,663.1,346.616,663.1,439.7,669.676,439.7,699.9Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
</g>
<g id="docusaurus_keytar" transform="translate(312.271 493.733)">
<path id="Path_40" data-name="Path 40" d="M99,52h91.791V89.153H99Z" transform="translate(5.904 -14.001)" fill="#fff" fill-rule="evenodd"/>
<path id="Path_41" data-name="Path 41" d="M24.855,163.927A21.828,21.828,0,0,1,5.947,153a21.829,21.829,0,0,0,18.908,32.782H46.71V163.927Z" transform="translate(-3 -4.634)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_42" data-name="Path 42" d="M121.861,61.1l76.514-4.782V45.39A21.854,21.854,0,0,0,176.52,23.535H78.173L75.441,18.8a3.154,3.154,0,0,0-5.464,0l-2.732,4.732L64.513,18.8a3.154,3.154,0,0,0-5.464,0l-2.732,4.732L53.586,18.8a3.154,3.154,0,0,0-5.464,0L45.39,23.535c-.024,0-.046,0-.071,0l-4.526-4.525a3.153,3.153,0,0,0-5.276,1.414l-1.5,5.577-5.674-1.521a3.154,3.154,0,0,0-3.863,3.864L26,34.023l-5.575,1.494a3.155,3.155,0,0,0-1.416,5.278l4.526,4.526c0,.023,0,.046,0,.07L18.8,48.122a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,59.05a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,69.977a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,80.9a3.154,3.154,0,0,0,0,5.464L23.535,89.1,18.8,91.832a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,102.76a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,113.687a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,124.615a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,135.542a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,146.469a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,157.4a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,168.324a3.154,3.154,0,0,0,0,5.464l4.732,2.732A21.854,21.854,0,0,0,45.39,198.375H176.52a21.854,21.854,0,0,0,21.855-21.855V89.1l-76.514-4.782a11.632,11.632,0,0,1,0-23.219" transform="translate(-1.681 -17.226)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_43" data-name="Path 43" d="M143,186.71h32.782V143H143Z" transform="translate(9.984 -5.561)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_44" data-name="Path 44" d="M196.71,159.855a5.438,5.438,0,0,0-.7.07c-.042-.164-.081-.329-.127-.493a5.457,5.457,0,1,0-5.4-9.372q-.181-.185-.366-.367a5.454,5.454,0,1,0-9.384-5.4c-.162-.046-.325-.084-.486-.126a5.467,5.467,0,1,0-10.788,0c-.162.042-.325.08-.486.126a5.457,5.457,0,1,0-9.384,5.4,21.843,21.843,0,1,0,36.421,21.02,5.452,5.452,0,1,0,.7-10.858" transform="translate(10.912 -6.025)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_45" data-name="Path 45" d="M153,124.855h32.782V103H153Z" transform="translate(10.912 -9.271)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_46" data-name="Path 46" d="M194.855,116.765a2.732,2.732,0,1,0,0-5.464,2.811,2.811,0,0,0-.349.035c-.022-.082-.04-.164-.063-.246a2.733,2.733,0,0,0-1.052-5.253,2.7,2.7,0,0,0-1.648.566q-.09-.093-.184-.184a2.7,2.7,0,0,0,.553-1.633,2.732,2.732,0,0,0-5.245-1.07,10.928,10.928,0,1,0,0,21.031,2.732,2.732,0,0,0,5.245-1.07,2.7,2.7,0,0,0-.553-1.633q.093-.09.184-.184a2.7,2.7,0,0,0,1.648.566,2.732,2.732,0,0,0,1.052-5.253c.023-.081.042-.164.063-.246a2.814,2.814,0,0,0,.349.035" transform="translate(12.767 -9.377)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_47" data-name="Path 47" d="M65.087,56.891a2.732,2.732,0,0,1-2.732-2.732,8.2,8.2,0,0,0-16.391,0,2.732,2.732,0,0,1-5.464,0,13.659,13.659,0,0,1,27.319,0,2.732,2.732,0,0,1-2.732,2.732" transform="translate(0.478 -15.068)" fill-rule="evenodd"/>
<path id="Path_48" data-name="Path 48" d="M103,191.347h65.565a21.854,21.854,0,0,0,21.855-21.855V93H124.855A21.854,21.854,0,0,0,103,114.855Z" transform="translate(6.275 -10.199)" fill="#ffff50" fill-rule="evenodd"/>
<path id="Path_49" data-name="Path 49" d="M173.216,129.787H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0,21.855H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186m0,21.855H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0-54.434H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0,21.652H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186m0,21.855H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186M189.585,61.611c-.013,0-.024-.007-.037-.005-3.377.115-4.974,3.492-6.384,6.472-1.471,3.114-2.608,5.139-4.473,5.078-2.064-.074-3.244-2.406-4.494-4.874-1.436-2.835-3.075-6.049-6.516-5.929-3.329.114-4.932,3.053-6.346,5.646-1.5,2.762-2.529,4.442-4.5,4.364-2.106-.076-3.225-1.972-4.52-4.167-1.444-2.443-3.112-5.191-6.487-5.1-3.272.113-4.879,2.606-6.3,4.808-1.5,2.328-2.552,3.746-4.551,3.662-2.156-.076-3.27-1.65-4.558-3.472-1.447-2.047-3.077-4.363-6.442-4.251-3.2.109-4.807,2.153-6.224,3.954-1.346,1.709-2.4,3.062-4.621,2.977a1.093,1.093,0,0,0-.079,2.186c3.3.11,4.967-1.967,6.417-3.81,1.286-1.635,2.4-3.045,4.582-3.12,2.1-.09,3.091,1.218,4.584,3.327,1.417,2,3.026,4.277,6.263,4.394,3.391.114,5.022-2.42,6.467-4.663,1.292-2,2.406-3.734,4.535-3.807,1.959-.073,3.026,1.475,4.529,4.022,1.417,2.4,3.023,5.121,6.324,5.241,3.415.118,5.064-2.863,6.5-5.5,1.245-2.282,2.419-4.437,4.5-4.509,1.959-.046,2.981,1.743,4.492,4.732,1.412,2.79,3.013,5.95,6.365,6.071l.185,0c3.348,0,4.937-3.36,6.343-6.331,1.245-2.634,2.423-5.114,4.444-5.216Z" transform="translate(7.109 -13.11)" fill-rule="evenodd"/>
<path id="Path_50" data-name="Path 50" d="M83,186.71h43.71V143H83Z" transform="translate(4.42 -5.561)" fill="#3ecc5f" fill-rule="evenodd"/>
<g id="Group_8" data-name="Group 8" transform="matrix(0.966, -0.259, 0.259, 0.966, 109.327, 91.085)">
<rect id="Rectangle_3" data-name="Rectangle 3" width="92.361" height="36.462" rx="2" transform="translate(0 0)" fill="#d8d8d8"/>
<g id="Group_2" data-name="Group 2" transform="translate(1.531 23.03)">
<rect id="Rectangle_4" data-name="Rectangle 4" width="5.336" height="5.336" rx="1" transform="translate(16.797 0)" fill="#4a4a4a"/>
<rect id="Rectangle_5" data-name="Rectangle 5" width="5.336" height="5.336" rx="1" transform="translate(23.12 0)" fill="#4a4a4a"/>
<rect id="Rectangle_6" data-name="Rectangle 6" width="5.336" height="5.336" rx="1" transform="translate(29.444 0)" fill="#4a4a4a"/>
<rect id="Rectangle_7" data-name="Rectangle 7" width="5.336" height="5.336" rx="1" transform="translate(35.768 0)" fill="#4a4a4a"/>
<rect id="Rectangle_8" data-name="Rectangle 8" width="5.336" height="5.336" rx="1" transform="translate(42.091 0)" fill="#4a4a4a"/>
<rect id="Rectangle_9" data-name="Rectangle 9" width="5.336" height="5.336" rx="1" transform="translate(48.415 0)" fill="#4a4a4a"/>
<rect id="Rectangle_10" data-name="Rectangle 10" width="5.336" height="5.336" rx="1" transform="translate(54.739 0)" fill="#4a4a4a"/>
<rect id="Rectangle_11" data-name="Rectangle 11" width="5.336" height="5.336" rx="1" transform="translate(61.063 0)" fill="#4a4a4a"/>
<rect id="Rectangle_12" data-name="Rectangle 12" width="5.336" height="5.336" rx="1" transform="translate(67.386 0)" fill="#4a4a4a"/>
<path id="Path_51" data-name="Path 51" d="M1.093,0H14.518a1.093,1.093,0,0,1,1.093,1.093V4.243a1.093,1.093,0,0,1-1.093,1.093H1.093A1.093,1.093,0,0,1,0,4.243V1.093A1.093,1.093,0,0,1,1.093,0ZM75,0H88.426a1.093,1.093,0,0,1,1.093,1.093V4.243a1.093,1.093,0,0,1-1.093,1.093H75a1.093,1.093,0,0,1-1.093-1.093V1.093A1.093,1.093,0,0,1,75,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_3" data-name="Group 3" transform="translate(1.531 10.261)">
<path id="Path_52" data-name="Path 52" d="M1.093,0H6.218A1.093,1.093,0,0,1,7.31,1.093V4.242A1.093,1.093,0,0,1,6.218,5.335H1.093A1.093,1.093,0,0,1,0,4.242V1.093A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_13" data-name="Rectangle 13" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
<rect id="Rectangle_14" data-name="Rectangle 14" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
<rect id="Rectangle_15" data-name="Rectangle 15" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
<rect id="Rectangle_16" data-name="Rectangle 16" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
<rect id="Rectangle_17" data-name="Rectangle 17" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
<rect id="Rectangle_18" data-name="Rectangle 18" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
<rect id="Rectangle_19" data-name="Rectangle 19" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
<rect id="Rectangle_20" data-name="Rectangle 20" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
<rect id="Rectangle_21" data-name="Rectangle 21" width="5.336" height="5.336" rx="1" transform="translate(58.888 0)" fill="#4a4a4a"/>
<rect id="Rectangle_22" data-name="Rectangle 22" width="5.336" height="5.336" rx="1" transform="translate(65.212 0)" fill="#4a4a4a"/>
<rect id="Rectangle_23" data-name="Rectangle 23" width="5.336" height="5.336" rx="1" transform="translate(71.536 0)" fill="#4a4a4a"/>
<rect id="Rectangle_24" data-name="Rectangle 24" width="5.336" height="5.336" rx="1" transform="translate(77.859 0)" fill="#4a4a4a"/>
<rect id="Rectangle_25" data-name="Rectangle 25" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
</g>
<g id="Group_4" data-name="Group 4" transform="translate(91.05 9.546) rotate(180)">
<path id="Path_53" data-name="Path 53" d="M1.093,0H6.219A1.093,1.093,0,0,1,7.312,1.093v3.15A1.093,1.093,0,0,1,6.219,5.336H1.093A1.093,1.093,0,0,1,0,4.243V1.093A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_26" data-name="Rectangle 26" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
<rect id="Rectangle_27" data-name="Rectangle 27" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
<rect id="Rectangle_28" data-name="Rectangle 28" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
<rect id="Rectangle_29" data-name="Rectangle 29" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
<rect id="Rectangle_30" data-name="Rectangle 30" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
<rect id="Rectangle_31" data-name="Rectangle 31" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
<rect id="Rectangle_32" data-name="Rectangle 32" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
<rect id="Rectangle_33" data-name="Rectangle 33" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
<rect id="Rectangle_34" data-name="Rectangle 34" width="5.336" height="5.336" rx="1" transform="translate(58.889 0)" fill="#4a4a4a"/>
<rect id="Rectangle_35" data-name="Rectangle 35" width="5.336" height="5.336" rx="1" transform="translate(65.213 0)" fill="#4a4a4a"/>
<rect id="Rectangle_36" data-name="Rectangle 36" width="5.336" height="5.336" rx="1" transform="translate(71.537 0)" fill="#4a4a4a"/>
<rect id="Rectangle_37" data-name="Rectangle 37" width="5.336" height="5.336" rx="1" transform="translate(77.86 0)" fill="#4a4a4a"/>
<rect id="Rectangle_38" data-name="Rectangle 38" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
<rect id="Rectangle_39" data-name="Rectangle 39" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
<rect id="Rectangle_40" data-name="Rectangle 40" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
<rect id="Rectangle_41" data-name="Rectangle 41" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
<rect id="Rectangle_42" data-name="Rectangle 42" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
<rect id="Rectangle_43" data-name="Rectangle 43" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
<rect id="Rectangle_44" data-name="Rectangle 44" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
<rect id="Rectangle_45" data-name="Rectangle 45" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
<rect id="Rectangle_46" data-name="Rectangle 46" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
<rect id="Rectangle_47" data-name="Rectangle 47" width="5.336" height="5.336" rx="1" transform="translate(58.889 0)" fill="#4a4a4a"/>
<rect id="Rectangle_48" data-name="Rectangle 48" width="5.336" height="5.336" rx="1" transform="translate(65.213 0)" fill="#4a4a4a"/>
<rect id="Rectangle_49" data-name="Rectangle 49" width="5.336" height="5.336" rx="1" transform="translate(71.537 0)" fill="#4a4a4a"/>
<rect id="Rectangle_50" data-name="Rectangle 50" width="5.336" height="5.336" rx="1" transform="translate(77.86 0)" fill="#4a4a4a"/>
<rect id="Rectangle_51" data-name="Rectangle 51" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
</g>
<g id="Group_6" data-name="Group 6" transform="translate(1.531 16.584)">
<path id="Path_54" data-name="Path 54" d="M1.093,0h7.3A1.093,1.093,0,0,1,9.485,1.093v3.15A1.093,1.093,0,0,1,8.392,5.336h-7.3A1.093,1.093,0,0,1,0,4.243V1.094A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<g id="Group_5" data-name="Group 5" transform="translate(10.671 0)">
<rect id="Rectangle_52" data-name="Rectangle 52" width="5.336" height="5.336" rx="1" fill="#4a4a4a"/>
<rect id="Rectangle_53" data-name="Rectangle 53" width="5.336" height="5.336" rx="1" transform="translate(6.324 0)" fill="#4a4a4a"/>
<rect id="Rectangle_54" data-name="Rectangle 54" width="5.336" height="5.336" rx="1" transform="translate(12.647 0)" fill="#4a4a4a"/>
<rect id="Rectangle_55" data-name="Rectangle 55" width="5.336" height="5.336" rx="1" transform="translate(18.971 0)" fill="#4a4a4a"/>
<rect id="Rectangle_56" data-name="Rectangle 56" width="5.336" height="5.336" rx="1" transform="translate(25.295 0)" fill="#4a4a4a"/>
<rect id="Rectangle_57" data-name="Rectangle 57" width="5.336" height="5.336" rx="1" transform="translate(31.619 0)" fill="#4a4a4a"/>
<rect id="Rectangle_58" data-name="Rectangle 58" width="5.336" height="5.336" rx="1" transform="translate(37.942 0)" fill="#4a4a4a"/>
<rect id="Rectangle_59" data-name="Rectangle 59" width="5.336" height="5.336" rx="1" transform="translate(44.265 0)" fill="#4a4a4a"/>
<rect id="Rectangle_60" data-name="Rectangle 60" width="5.336" height="5.336" rx="1" transform="translate(50.589 0)" fill="#4a4a4a"/>
<rect id="Rectangle_61" data-name="Rectangle 61" width="5.336" height="5.336" rx="1" transform="translate(56.912 0)" fill="#4a4a4a"/>
<rect id="Rectangle_62" data-name="Rectangle 62" width="5.336" height="5.336" rx="1" transform="translate(63.236 0)" fill="#4a4a4a"/>
</g>
<path id="Path_55" data-name="Path 55" d="M1.094,0H8A1.093,1.093,0,0,1,9.091,1.093v3.15A1.093,1.093,0,0,1,8,5.336H1.093A1.093,1.093,0,0,1,0,4.243V1.094A1.093,1.093,0,0,1,1.093,0Z" transform="translate(80.428 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_7" data-name="Group 7" transform="translate(1.531 29.627)">
<rect id="Rectangle_63" data-name="Rectangle 63" width="5.336" height="5.336" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
<rect id="Rectangle_64" data-name="Rectangle 64" width="5.336" height="5.336" rx="1" transform="translate(6.324 0)" fill="#4a4a4a"/>
<rect id="Rectangle_65" data-name="Rectangle 65" width="5.336" height="5.336" rx="1" transform="translate(12.647 0)" fill="#4a4a4a"/>
<rect id="Rectangle_66" data-name="Rectangle 66" width="5.336" height="5.336" rx="1" transform="translate(18.971 0)" fill="#4a4a4a"/>
<path id="Path_56" data-name="Path 56" d="M1.093,0H31.515a1.093,1.093,0,0,1,1.093,1.093V4.244a1.093,1.093,0,0,1-1.093,1.093H1.093A1.093,1.093,0,0,1,0,4.244V1.093A1.093,1.093,0,0,1,1.093,0ZM34.687,0h3.942a1.093,1.093,0,0,1,1.093,1.093V4.244a1.093,1.093,0,0,1-1.093,1.093H34.687a1.093,1.093,0,0,1-1.093-1.093V1.093A1.093,1.093,0,0,1,34.687,0Z" transform="translate(25.294 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_67" data-name="Rectangle 67" width="5.336" height="5.336" rx="1" transform="translate(66.003 0)" fill="#4a4a4a"/>
<rect id="Rectangle_68" data-name="Rectangle 68" width="5.336" height="5.336" rx="1" transform="translate(72.327 0)" fill="#4a4a4a"/>
<rect id="Rectangle_69" data-name="Rectangle 69" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
<path id="Path_57" data-name="Path 57" d="M5.336,0V1.18A1.093,1.093,0,0,1,4.243,2.273H1.093A1.093,1.093,0,0,1,0,1.18V0Z" transform="translate(83.59 2.273) rotate(180)" fill="#4a4a4a"/>
<path id="Path_58" data-name="Path 58" d="M5.336,0V1.18A1.093,1.093,0,0,1,4.243,2.273H1.093A1.093,1.093,0,0,1,0,1.18V0Z" transform="translate(78.255 3.063)" fill="#4a4a4a"/>
</g>
<rect id="Rectangle_70" data-name="Rectangle 70" width="88.927" height="2.371" rx="1.085" transform="translate(1.925 1.17)" fill="#4a4a4a"/>
<rect id="Rectangle_71" data-name="Rectangle 71" width="4.986" height="1.581" rx="0.723" transform="translate(4.1 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_72" data-name="Rectangle 72" width="4.986" height="1.581" rx="0.723" transform="translate(10.923 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_73" data-name="Rectangle 73" width="4.986" height="1.581" rx="0.723" transform="translate(16.173 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_74" data-name="Rectangle 74" width="4.986" height="1.581" rx="0.723" transform="translate(21.421 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_75" data-name="Rectangle 75" width="4.986" height="1.581" rx="0.723" transform="translate(26.671 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_76" data-name="Rectangle 76" width="4.986" height="1.581" rx="0.723" transform="translate(33.232 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_77" data-name="Rectangle 77" width="4.986" height="1.581" rx="0.723" transform="translate(38.48 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_78" data-name="Rectangle 78" width="4.986" height="1.581" rx="0.723" transform="translate(43.73 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_79" data-name="Rectangle 79" width="4.986" height="1.581" rx="0.723" transform="translate(48.978 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_80" data-name="Rectangle 80" width="4.986" height="1.581" rx="0.723" transform="translate(55.54 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_81" data-name="Rectangle 81" width="4.986" height="1.581" rx="0.723" transform="translate(60.788 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_82" data-name="Rectangle 82" width="4.986" height="1.581" rx="0.723" transform="translate(66.038 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_83" data-name="Rectangle 83" width="4.986" height="1.581" rx="0.723" transform="translate(72.599 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_84" data-name="Rectangle 84" width="4.986" height="1.581" rx="0.723" transform="translate(77.847 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_85" data-name="Rectangle 85" width="4.986" height="1.581" rx="0.723" transform="translate(83.097 1.566)" fill="#d8d8d8" opacity="0.136"/>
</g>
<path id="Path_59" data-name="Path 59" d="M146.71,159.855a5.439,5.439,0,0,0-.7.07c-.042-.164-.081-.329-.127-.493a5.457,5.457,0,1,0-5.4-9.372q-.181-.185-.366-.367a5.454,5.454,0,1,0-9.384-5.4c-.162-.046-.325-.084-.486-.126a5.467,5.467,0,1,0-10.788,0c-.162.042-.325.08-.486.126a5.457,5.457,0,1,0-9.384,5.4,21.843,21.843,0,1,0,36.421,21.02,5.452,5.452,0,1,0,.7-10.858" transform="translate(6.275 -6.025)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_60" data-name="Path 60" d="M83,124.855h43.71V103H83Z" transform="translate(4.42 -9.271)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_61" data-name="Path 61" d="M134.855,116.765a2.732,2.732,0,1,0,0-5.464,2.811,2.811,0,0,0-.349.035c-.022-.082-.04-.164-.063-.246a2.733,2.733,0,0,0-1.052-5.253,2.7,2.7,0,0,0-1.648.566q-.09-.093-.184-.184a2.7,2.7,0,0,0,.553-1.633,2.732,2.732,0,0,0-5.245-1.07,10.928,10.928,0,1,0,0,21.031,2.732,2.732,0,0,0,5.245-1.07,2.7,2.7,0,0,0-.553-1.633q.093-.09.184-.184a2.7,2.7,0,0,0,1.648.566,2.732,2.732,0,0,0,1.052-5.253c.023-.081.042-.164.063-.246a2.811,2.811,0,0,0,.349.035" transform="translate(7.202 -9.377)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_62" data-name="Path 62" d="M143.232,42.33a2.967,2.967,0,0,1-.535-.055,2.754,2.754,0,0,1-.514-.153,2.838,2.838,0,0,1-.471-.251,4.139,4.139,0,0,1-.415-.339,3.2,3.2,0,0,1-.338-.415A2.7,2.7,0,0,1,140.5,39.6a2.968,2.968,0,0,1,.055-.535,3.152,3.152,0,0,1,.152-.514,2.874,2.874,0,0,1,.252-.47,2.633,2.633,0,0,1,.753-.754,2.837,2.837,0,0,1,.471-.251,2.753,2.753,0,0,1,.514-.153,2.527,2.527,0,0,1,1.071,0,2.654,2.654,0,0,1,.983.4,4.139,4.139,0,0,1,.415.339,4.019,4.019,0,0,1,.339.415,2.786,2.786,0,0,1,.251.47,2.864,2.864,0,0,1,.208,1.049,2.77,2.77,0,0,1-.8,1.934,4.139,4.139,0,0,1-.415.339,2.722,2.722,0,0,1-1.519.459m21.855-1.366a2.789,2.789,0,0,1-1.935-.8,4.162,4.162,0,0,1-.338-.415,2.7,2.7,0,0,1-.459-1.519,2.789,2.789,0,0,1,.8-1.934,4.139,4.139,0,0,1,.415-.339,2.838,2.838,0,0,1,.471-.251,2.752,2.752,0,0,1,.514-.153,2.527,2.527,0,0,1,1.071,0,2.654,2.654,0,0,1,.983.4,4.139,4.139,0,0,1,.415.339,2.79,2.79,0,0,1,.8,1.934,3.069,3.069,0,0,1-.055.535,2.779,2.779,0,0,1-.153.514,3.885,3.885,0,0,1-.251.47,4.02,4.02,0,0,1-.339.415,4.138,4.138,0,0,1-.415.339,2.722,2.722,0,0,1-1.519.459" transform="translate(9.753 -15.532)" fill-rule="evenodd"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1,170 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1041.277" height="554.141" viewBox="0 0 1041.277 554.141">
<title>Powered by React</title>
<g id="Group_24" data-name="Group 24" transform="translate(-440 -263)">
<g id="Group_23" data-name="Group 23" transform="translate(439.989 262.965)">
<path id="Path_299" data-name="Path 299" d="M1040.82,611.12q-1.74,3.75-3.47,7.4-2.7,5.67-5.33,11.12c-.78,1.61-1.56,3.19-2.32,4.77-8.6,17.57-16.63,33.11-23.45,45.89A73.21,73.21,0,0,1,942.44,719l-151.65,1.65h-1.6l-13,.14-11.12.12-34.1.37h-1.38l-17.36.19h-.53l-107,1.16-95.51,1-11.11.12-69,.75H429l-44.75.48h-.48l-141.5,1.53-42.33.46a87.991,87.991,0,0,1-10.79-.54h0c-1.22-.14-2.44-.3-3.65-.49a87.38,87.38,0,0,1-51.29-27.54C116,678.37,102.75,655,93.85,629.64q-1.93-5.49-3.6-11.12C59.44,514.37,97,380,164.6,290.08q4.25-5.64,8.64-11l.07-.08c20.79-25.52,44.1-46.84,68.93-62,44-26.91,92.75-34.49,140.7-11.9,40.57,19.12,78.45,28.11,115.17,30.55,3.71.24,7.42.42,11.11.53,84.23,2.65,163.17-27.7,255.87-47.29,3.69-.78,7.39-1.55,11.12-2.28,66.13-13.16,139.49-20.1,226.73-5.51a189.089,189.089,0,0,1,26.76,6.4q5.77,1.86,11.12,4c41.64,16.94,64.35,48.24,74,87.46q1.37,5.46,2.37,11.11C1134.3,384.41,1084.19,518.23,1040.82,611.12Z" transform="translate(-79.34 -172.91)" fill="#f2f2f2"/>
<path id="Path_300" data-name="Path 300" d="M576.36,618.52a95.21,95.21,0,0,1-1.87,11.12h93.7V618.52Zm-78.25,62.81,11.11-.09V653.77c-3.81-.17-7.52-.34-11.11-.52ZM265.19,618.52v11.12h198.5V618.52ZM1114.87,279h-74V191.51q-5.35-2.17-11.12-4V279H776.21V186.58c-3.73.73-7.43,1.5-11.12,2.28V279H509.22V236.15c-3.69-.11-7.4-.29-11.11-.53V279H242.24V217c-24.83,15.16-48.14,36.48-68.93,62h-.07v.08q-4.4,5.4-8.64,11h8.64V618.52h-83q1.66,5.63,3.6,11.12h79.39v93.62a87,87,0,0,0,12.2,2.79c1.21.19,2.43.35,3.65.49h0a87.991,87.991,0,0,0,10.79.54l42.33-.46v-97H498.11v94.21l11.11-.12V629.64H765.09V721l11.12-.12V629.64H1029.7v4.77c.76-1.58,1.54-3.16,2.32-4.77q2.63-5.45,5.33-11.12,1.73-3.64,3.47-7.4v-321h76.42Q1116.23,284.43,1114.87,279ZM242.24,618.52V290.08H498.11V618.52Zm267,0V290.08H765.09V618.52Zm520.48,0H776.21V290.08H1029.7Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_301" data-name="Path 301" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l46.65-28,93.6-.78,2-.01.66-.01,2-.03,44.94-.37,2.01-.01.64-.01,2-.01L315,509.3l.38-.01,35.55-.3h.29l277.4-2.34,6.79-.05h.68l5.18-.05,37.65-.31,2-.03,1.85-.02h.96l11.71-.09,2.32-.03,3.11-.02,9.75-.09,15.47-.13,2-.02,3.48-.02h.65l74.71-.64Z" fill="#65617d"/>
<path id="Path_302" data-name="Path 302" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l46.65-28,93.6-.78,2-.01.66-.01,2-.03,44.94-.37,2.01-.01.64-.01,2-.01L315,509.3l.38-.01,35.55-.3h.29l277.4-2.34,6.79-.05h.68l5.18-.05,37.65-.31,2-.03,1.85-.02h.96l11.71-.09,2.32-.03,3.11-.02,9.75-.09,15.47-.13,2-.02,3.48-.02h.65l74.71-.64Z" opacity="0.2"/>
<path id="Path_303" data-name="Path 303" d="M375.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
<path id="Path_304" data-name="Path 304" d="M375.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_305" data-name="Path 305" d="M377.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
<rect id="Rectangle_137" data-name="Rectangle 137" width="47.17" height="31.5" transform="translate(680.92 483.65)" fill="#3f3d56"/>
<rect id="Rectangle_138" data-name="Rectangle 138" width="47.17" height="31.5" transform="translate(680.92 483.65)" opacity="0.1"/>
<rect id="Rectangle_139" data-name="Rectangle 139" width="47.17" height="31.5" transform="translate(678.92 483.65)" fill="#3f3d56"/>
<path id="Path_306" data-name="Path 306" d="M298.09,483.65v4.97l-47.17,1.26v-6.23Z" opacity="0.1"/>
<path id="Path_307" data-name="Path 307" d="M460.69,485.27v168.2a4,4,0,0,1-3.85,3.95l-191.65,5.1h-.05a4,4,0,0,1-3.95-3.95V485.27a4,4,0,0,1,3.95-3.95h191.6a4,4,0,0,1,3.95,3.95Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
<path id="Path_308" data-name="Path 308" d="M265.19,481.32v181.2h-.05a4,4,0,0,1-3.95-3.95V485.27a4,4,0,0,1,3.95-3.95Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_309" data-name="Path 309" d="M194.59,319.15h177.5V467.4l-177.5,4Z" fill="#39374d"/>
<path id="Path_310" data-name="Path 310" d="M726.09,483.65v6.41l-47.17-1.26v-5.15Z" opacity="0.1"/>
<path id="Path_311" data-name="Path 311" d="M867.69,485.27v173.3a4,4,0,0,1-4,3.95h0L672,657.42a4,4,0,0,1-3.85-3.95V485.27a4,4,0,0,1,3.95-3.95H863.7a4,4,0,0,1,3.99,3.95Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
<path id="Path_312" data-name="Path 312" d="M867.69,485.27v173.3a4,4,0,0,1-4,3.95h0V481.32h0a4,4,0,0,1,4,3.95Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_313" data-name="Path 313" d="M775.59,319.15H598.09V467.4l177.5,4Z" fill="#39374d"/>
<path id="Path_314" data-name="Path 314" d="M663.19,485.27v168.2a4,4,0,0,1-3.85,3.95l-191.65,5.1h0a4,4,0,0,1-4-3.95V485.27a4,4,0,0,1,3.95-3.95h191.6A4,4,0,0,1,663.19,485.27Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
<path id="Path_315" data-name="Path 315" d="M397.09,319.15h177.5V467.4l-177.5,4Z" fill="#4267b2"/>
<path id="Path_316" data-name="Path 316" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l202.51-1.33h.48l40.99-.28h.19l283.08-1.87h.29l.17-.01h.47l4.79-.03h1.46l74.49-.5,4.4-.02.98-.01Z" opacity="0.1"/>
<circle id="Ellipse_111" data-name="Ellipse 111" cx="51.33" cy="51.33" r="51.33" transform="translate(435.93 246.82)" fill="#fbbebe"/>
<path id="Path_317" data-name="Path 317" d="M617.94,550.07s-99.5,12-90,0c3.44-4.34,4.39-17.2,4.2-31.85-.06-4.45-.22-9.06-.45-13.65-1.1-22-3.75-43.5-3.75-43.5s87-41,77-8.5c-4,13.13-2.69,31.57.35,48.88.89,5.05,1.92,10,3,14.7a344.66,344.66,0,0,0,9.65,33.92Z" transform="translate(-79.34 -172.91)" fill="#fbbebe"/>
<path id="Path_318" data-name="Path 318" d="M585.47,546c11.51-2.13,23.7-6,34.53-1.54,2.85,1.17,5.47,2.88,8.39,3.86s6.12,1.22,9.16,1.91c10.68,2.42,19.34,10.55,24.9,20s8.44,20.14,11.26,30.72l6.9,25.83c6,22.45,12,45.09,13.39,68.3a2437.506,2437.506,0,0,1-250.84,1.43c5.44-10.34,11-21.31,10.54-33s-7.19-23.22-4.76-34.74c1.55-7.34,6.57-13.39,9.64-20.22,8.75-19.52,1.94-45.79,17.32-60.65,6.92-6.68,17-9.21,26.63-8.89,12.28.41,24.85,4.24,37,6.11C555.09,547.48,569.79,548.88,585.47,546Z" transform="translate(-79.34 -172.91)" fill="#ff6584"/>
<path id="Path_319" data-name="Path 319" d="M716.37,657.17l-.1,1.43v.1l-.17,2.3-1.33,18.51-1.61,22.3-.46,6.28-1,13.44v.17l-107,1-175.59,1.9v.84h-.14v-1.12l.45-14.36.86-28.06.74-23.79.07-2.37a10.53,10.53,0,0,1,11.42-10.17c4.72.4,10.85.89,18.18,1.41l3,.22c42.33,2.94,120.56,6.74,199.5,2,1.66-.09,3.33-.19,5-.31,12.24-.77,24.47-1.76,36.58-3a10.53,10.53,0,0,1,11.6,11.23Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_320" data-name="Path 320" d="M429.08,725.44v-.84l175.62-1.91,107-1h.3v-.17l1-13.44.43-6,1.64-22.61,1.29-17.9v-.44a10.617,10.617,0,0,0-.11-2.47.3.3,0,0,0,0-.1,10.391,10.391,0,0,0-2-4.64,10.54,10.54,0,0,0-9.42-4c-12.11,1.24-24.34,2.23-36.58,3-1.67.12-3.34.22-5,.31-78.94,4.69-157.17.89-199.5-2l-3-.22c-7.33-.52-13.46-1-18.18-1.41a10.54,10.54,0,0,0-11.24,8.53,11,11,0,0,0-.18,1.64l-.68,22.16L429.54,710l-.44,14.36v1.12Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
<path id="Path_321" data-name="Path 321" d="M716.67,664.18l-1.23,15.33-1.83,22.85-.46,5.72-1,12.81-.06.64v.17h0l-.15,1.48.11-1.48h-.29l-107,1-175.65,1.9v-.28l.49-14.36,1-28.06.64-18.65A6.36,6.36,0,0,1,434.3,658a6.25,6.25,0,0,1,3.78-.9c2.1.17,4.68.37,7.69.59,4.89.36,10.92.78,17.94,1.22,13,.82,29.31,1.7,48,2.42,52,2,122.2,2.67,188.88-3.17,3-.26,6.1-.55,9.13-.84a6.26,6.26,0,0,1,3.48.66,5.159,5.159,0,0,1,.86.54,6.14,6.14,0,0,1,2,2.46,3.564,3.564,0,0,1,.25.61A6.279,6.279,0,0,1,716.67,664.18Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_322" data-name="Path 322" d="M377.44,677.87v3.19a6.13,6.13,0,0,1-3.5,5.54l-40.1.77a6.12,6.12,0,0,1-3.57-5.57v-3Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_323" data-name="Path 323" d="M298.59,515.57l-52.25,1V507.9l52.25-1Z" fill="#3f3d56"/>
<path id="Path_324" data-name="Path 324" d="M298.59,515.57l-52.25,1V507.9l52.25-1Z" opacity="0.1"/>
<path id="Path_325" data-name="Path 325" d="M300.59,515.57l-52.25,1V507.9l52.25-1Z" fill="#3f3d56"/>
<path id="Path_326" data-name="Path 326" d="M758.56,679.87v3.19a6.13,6.13,0,0,0,3.5,5.54l40.1.77a6.12,6.12,0,0,0,3.57-5.57v-3Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_327" data-name="Path 327" d="M678.72,517.57l52.25,1V509.9l-52.25-1Z" opacity="0.1"/>
<path id="Path_328" data-name="Path 328" d="M676.72,517.57l52.25,1V509.9l-52.25-1Z" fill="#3f3d56"/>
<path id="Path_329" data-name="Path 329" d="M534.13,486.79c.08,7-3.16,13.6-5.91,20.07a163.491,163.491,0,0,0-12.66,74.71c.73,11,2.58,22,.73,32.9s-8.43,21.77-19,24.9c17.53,10.45,41.26,9.35,57.76-2.66,8.79-6.4,15.34-15.33,21.75-24.11a97.86,97.86,0,0,1-13.31,44.75A103.43,103.43,0,0,0,637,616.53c4.31-5.81,8.06-12.19,9.72-19.23,3.09-13-1.22-26.51-4.51-39.5a266.055,266.055,0,0,1-6.17-33c-.43-3.56-.78-7.22.1-10.7,1-4.07,3.67-7.51,5.64-11.22,5.6-10.54,5.73-23.3,2.86-34.88s-8.49-22.26-14.06-32.81c-4.46-8.46-9.3-17.31-17.46-22.28-5.1-3.1-11-4.39-16.88-5.64l-25.37-5.43c-5.55-1.19-11.26-2.38-16.87-1.51-9.47,1.48-16.14,8.32-22,15.34-4.59,5.46-15.81,15.71-16.6,22.86-.72,6.59,5.1,17.63,6.09,24.58,1.3,9,2.22,6,7.3,11.52C532,478.05,534.07,482,534.13,486.79Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
</g>
<g id="docusaurus_keytar" transform="translate(670.271 615.768)">
<path id="Path_40" data-name="Path 40" d="M99,52h43.635V69.662H99Z" transform="translate(-49.132 -33.936)" fill="#fff" fill-rule="evenodd"/>
<path id="Path_41" data-name="Path 41" d="M13.389,158.195A10.377,10.377,0,0,1,4.4,153a10.377,10.377,0,0,0,8.988,15.584H23.779V158.195Z" transform="translate(-3 -82.47)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_42" data-name="Path 42" d="M66.967,38.083l36.373-2.273V30.615A10.389,10.389,0,0,0,92.95,20.226H46.2l-1.3-2.249a1.5,1.5,0,0,0-2.6,0L41,20.226l-1.3-2.249a1.5,1.5,0,0,0-2.6,0l-1.3,2.249-1.3-2.249a1.5,1.5,0,0,0-2.6,0l-1.3,2.249-.034,0-2.152-2.151a1.5,1.5,0,0,0-2.508.672L25.21,21.4l-2.7-.723a1.5,1.5,0,0,0-1.836,1.837l.722,2.7-2.65.71a1.5,1.5,0,0,0-.673,2.509l2.152,2.152c0,.011,0,.022,0,.033l-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6L20.226,41l-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3A10.389,10.389,0,0,0,30.615,103.34H92.95A10.389,10.389,0,0,0,103.34,92.95V51.393L66.967,49.12a5.53,5.53,0,0,1,0-11.038" transform="translate(-9.836 -17.226)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_43" data-name="Path 43" d="M143,163.779h15.584V143H143Z" transform="translate(-70.275 -77.665)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_44" data-name="Path 44" d="M173.779,148.389a2.582,2.582,0,0,0-.332.033c-.02-.078-.038-.156-.06-.234a2.594,2.594,0,1,0-2.567-4.455q-.086-.088-.174-.175a2.593,2.593,0,1,0-4.461-2.569c-.077-.022-.154-.04-.231-.06a2.6,2.6,0,1,0-5.128,0c-.077.02-.154.038-.231.06a2.594,2.594,0,1,0-4.461,2.569,10.384,10.384,0,1,0,17.314,9.992,2.592,2.592,0,1,0,.332-5.161" transform="translate(-75.08 -75.262)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_45" data-name="Path 45" d="M153,113.389h15.584V103H153Z" transform="translate(-75.08 -58.444)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_46" data-name="Path 46" d="M183.389,108.944a1.3,1.3,0,1,0,0-2.6,1.336,1.336,0,0,0-.166.017c-.01-.039-.019-.078-.03-.117a1.3,1.3,0,0,0-.5-2.5,1.285,1.285,0,0,0-.783.269q-.043-.044-.087-.087a1.285,1.285,0,0,0,.263-.776,1.3,1.3,0,0,0-2.493-.509,5.195,5.195,0,1,0,0,10,1.3,1.3,0,0,0,2.493-.509,1.285,1.285,0,0,0-.263-.776q.044-.043.087-.087a1.285,1.285,0,0,0,.783.269,1.3,1.3,0,0,0,.5-2.5c.011-.038.02-.078.03-.117a1.337,1.337,0,0,0,.166.017" transform="translate(-84.691 -57.894)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_47" data-name="Path 47" d="M52.188,48.292a1.3,1.3,0,0,1-1.3-1.3,3.9,3.9,0,0,0-7.792,0,1.3,1.3,0,1,1-2.6,0,6.493,6.493,0,0,1,12.987,0,1.3,1.3,0,0,1-1.3,1.3" transform="translate(-21.02 -28.41)" fill-rule="evenodd"/>
<path id="Path_48" data-name="Path 48" d="M103,139.752h31.168a10.389,10.389,0,0,0,10.389-10.389V93H113.389A10.389,10.389,0,0,0,103,103.389Z" transform="translate(-51.054 -53.638)" fill="#ffff50" fill-rule="evenodd"/>
<path id="Path_49" data-name="Path 49" d="M141.1,94.017H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0-25.877H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.293H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m7.782-47.993c-.006,0-.011,0-.018,0-1.605.055-2.365,1.66-3.035,3.077-.7,1.48-1.24,2.443-2.126,2.414-.981-.035-1.542-1.144-2.137-2.317-.683-1.347-1.462-2.876-3.1-2.819-1.582.054-2.344,1.451-3.017,2.684-.715,1.313-1.2,2.112-2.141,2.075-1-.036-1.533-.938-2.149-1.981-.686-1.162-1.479-2.467-3.084-2.423-1.555.053-2.319,1.239-2.994,2.286-.713,1.106-1.213,1.781-2.164,1.741-1.025-.036-1.554-.784-2.167-1.65-.688-.973-1.463-2.074-3.062-2.021a3.815,3.815,0,0,0-2.959,1.879c-.64.812-1.14,1.456-2.2,1.415a.52.52,0,0,0-.037,1.039,3.588,3.588,0,0,0,3.05-1.811c.611-.777,1.139-1.448,2.178-1.483,1-.043,1.47.579,2.179,1.582.674.953,1.438,2.033,2.977,2.089,1.612.054,2.387-1.151,3.074-2.217.614-.953,1.144-1.775,2.156-1.81.931-.035,1.438.7,2.153,1.912.674,1.141,1.437,2.434,3.006,2.491,1.623.056,2.407-1.361,3.09-2.616.592-1.085,1.15-2.109,2.14-2.143.931-.022,1.417.829,2.135,2.249.671,1.326,1.432,2.828,3.026,2.886l.088,0c1.592,0,2.347-1.6,3.015-3.01.592-1.252,1.152-2.431,2.113-2.479Z" transform="translate(-55.378 -38.552)" fill-rule="evenodd"/>
<path id="Path_50" data-name="Path 50" d="M83,163.779h20.779V143H83Z" transform="translate(-41.443 -77.665)" fill="#3ecc5f" fill-rule="evenodd"/>
<g id="Group_8" data-name="Group 8" transform="matrix(0.966, -0.259, 0.259, 0.966, 51.971, 43.3)">
<rect id="Rectangle_3" data-name="Rectangle 3" width="43.906" height="17.333" rx="2" transform="translate(0 0)" fill="#d8d8d8"/>
<g id="Group_2" data-name="Group 2" transform="translate(0.728 10.948)">
<rect id="Rectangle_4" data-name="Rectangle 4" width="2.537" height="2.537" rx="1" transform="translate(7.985 0)" fill="#4a4a4a"/>
<rect id="Rectangle_5" data-name="Rectangle 5" width="2.537" height="2.537" rx="1" transform="translate(10.991 0)" fill="#4a4a4a"/>
<rect id="Rectangle_6" data-name="Rectangle 6" width="2.537" height="2.537" rx="1" transform="translate(13.997 0)" fill="#4a4a4a"/>
<rect id="Rectangle_7" data-name="Rectangle 7" width="2.537" height="2.537" rx="1" transform="translate(17.003 0)" fill="#4a4a4a"/>
<rect id="Rectangle_8" data-name="Rectangle 8" width="2.537" height="2.537" rx="1" transform="translate(20.009 0)" fill="#4a4a4a"/>
<rect id="Rectangle_9" data-name="Rectangle 9" width="2.537" height="2.537" rx="1" transform="translate(23.015 0)" fill="#4a4a4a"/>
<rect id="Rectangle_10" data-name="Rectangle 10" width="2.537" height="2.537" rx="1" transform="translate(26.021 0)" fill="#4a4a4a"/>
<rect id="Rectangle_11" data-name="Rectangle 11" width="2.537" height="2.537" rx="1" transform="translate(29.028 0)" fill="#4a4a4a"/>
<rect id="Rectangle_12" data-name="Rectangle 12" width="2.537" height="2.537" rx="1" transform="translate(32.034 0)" fill="#4a4a4a"/>
<path id="Path_51" data-name="Path 51" d="M.519,0H6.9A.519.519,0,0,1,7.421.52v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0ZM35.653,0h6.383a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H35.652a.519.519,0,0,1-.519-.519V.519A.519.519,0,0,1,35.652,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_3" data-name="Group 3" transform="translate(0.728 4.878)">
<path id="Path_52" data-name="Path 52" d="M.519,0H2.956a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_13" data-name="Rectangle 13" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
<rect id="Rectangle_14" data-name="Rectangle 14" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
<rect id="Rectangle_15" data-name="Rectangle 15" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
<rect id="Rectangle_16" data-name="Rectangle 16" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
<rect id="Rectangle_17" data-name="Rectangle 17" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
<rect id="Rectangle_18" data-name="Rectangle 18" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
<rect id="Rectangle_19" data-name="Rectangle 19" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
<rect id="Rectangle_20" data-name="Rectangle 20" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
<rect id="Rectangle_21" data-name="Rectangle 21" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
<rect id="Rectangle_22" data-name="Rectangle 22" width="2.537" height="2.537" rx="1" transform="translate(31 0)" fill="#4a4a4a"/>
<rect id="Rectangle_23" data-name="Rectangle 23" width="2.537" height="2.537" rx="1" transform="translate(34.006 0)" fill="#4a4a4a"/>
<rect id="Rectangle_24" data-name="Rectangle 24" width="2.537" height="2.537" rx="1" transform="translate(37.012 0)" fill="#4a4a4a"/>
<rect id="Rectangle_25" data-name="Rectangle 25" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
</g>
<g id="Group_4" data-name="Group 4" transform="translate(43.283 4.538) rotate(180)">
<path id="Path_53" data-name="Path 53" d="M.519,0H2.956a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_26" data-name="Rectangle 26" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
<rect id="Rectangle_27" data-name="Rectangle 27" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
<rect id="Rectangle_28" data-name="Rectangle 28" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
<rect id="Rectangle_29" data-name="Rectangle 29" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
<rect id="Rectangle_30" data-name="Rectangle 30" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
<rect id="Rectangle_31" data-name="Rectangle 31" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
<rect id="Rectangle_32" data-name="Rectangle 32" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
<rect id="Rectangle_33" data-name="Rectangle 33" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
<rect id="Rectangle_34" data-name="Rectangle 34" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
<rect id="Rectangle_35" data-name="Rectangle 35" width="2.537" height="2.537" rx="1" transform="translate(31.001 0)" fill="#4a4a4a"/>
<rect id="Rectangle_36" data-name="Rectangle 36" width="2.537" height="2.537" rx="1" transform="translate(34.007 0)" fill="#4a4a4a"/>
<rect id="Rectangle_37" data-name="Rectangle 37" width="2.537" height="2.537" rx="1" transform="translate(37.013 0)" fill="#4a4a4a"/>
<rect id="Rectangle_38" data-name="Rectangle 38" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
<rect id="Rectangle_39" data-name="Rectangle 39" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
<rect id="Rectangle_40" data-name="Rectangle 40" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
<rect id="Rectangle_41" data-name="Rectangle 41" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
<rect id="Rectangle_42" data-name="Rectangle 42" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
<rect id="Rectangle_43" data-name="Rectangle 43" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
<rect id="Rectangle_44" data-name="Rectangle 44" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
<rect id="Rectangle_45" data-name="Rectangle 45" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
<rect id="Rectangle_46" data-name="Rectangle 46" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
<rect id="Rectangle_47" data-name="Rectangle 47" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
<rect id="Rectangle_48" data-name="Rectangle 48" width="2.537" height="2.537" rx="1" transform="translate(31.001 0)" fill="#4a4a4a"/>
<rect id="Rectangle_49" data-name="Rectangle 49" width="2.537" height="2.537" rx="1" transform="translate(34.007 0)" fill="#4a4a4a"/>
<rect id="Rectangle_50" data-name="Rectangle 50" width="2.537" height="2.537" rx="1" transform="translate(37.013 0)" fill="#4a4a4a"/>
<rect id="Rectangle_51" data-name="Rectangle 51" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
</g>
<g id="Group_6" data-name="Group 6" transform="translate(0.728 7.883)">
<path id="Path_54" data-name="Path 54" d="M.519,0h3.47a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.52A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<g id="Group_5" data-name="Group 5" transform="translate(5.073 0)">
<rect id="Rectangle_52" data-name="Rectangle 52" width="2.537" height="2.537" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
<rect id="Rectangle_53" data-name="Rectangle 53" width="2.537" height="2.537" rx="1" transform="translate(3.006 0)" fill="#4a4a4a"/>
<rect id="Rectangle_54" data-name="Rectangle 54" width="2.537" height="2.537" rx="1" transform="translate(6.012 0)" fill="#4a4a4a"/>
<rect id="Rectangle_55" data-name="Rectangle 55" width="2.537" height="2.537" rx="1" transform="translate(9.018 0)" fill="#4a4a4a"/>
<rect id="Rectangle_56" data-name="Rectangle 56" width="2.537" height="2.537" rx="1" transform="translate(12.025 0)" fill="#4a4a4a"/>
<rect id="Rectangle_57" data-name="Rectangle 57" width="2.537" height="2.537" rx="1" transform="translate(15.031 0)" fill="#4a4a4a"/>
<rect id="Rectangle_58" data-name="Rectangle 58" width="2.537" height="2.537" rx="1" transform="translate(18.037 0)" fill="#4a4a4a"/>
<rect id="Rectangle_59" data-name="Rectangle 59" width="2.537" height="2.537" rx="1" transform="translate(21.042 0)" fill="#4a4a4a"/>
<rect id="Rectangle_60" data-name="Rectangle 60" width="2.537" height="2.537" rx="1" transform="translate(24.049 0)" fill="#4a4a4a"/>
<rect id="Rectangle_61" data-name="Rectangle 61" width="2.537" height="2.537" rx="1" transform="translate(27.055 0)" fill="#4a4a4a"/>
<rect id="Rectangle_62" data-name="Rectangle 62" width="2.537" height="2.537" rx="1" transform="translate(30.061 0)" fill="#4a4a4a"/>
</g>
<path id="Path_55" data-name="Path 55" d="M.52,0H3.8a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.52A.519.519,0,0,1,.519,0Z" transform="translate(38.234 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_7" data-name="Group 7" transform="translate(0.728 14.084)">
<rect id="Rectangle_63" data-name="Rectangle 63" width="2.537" height="2.537" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
<rect id="Rectangle_64" data-name="Rectangle 64" width="2.537" height="2.537" rx="1" transform="translate(3.006 0)" fill="#4a4a4a"/>
<rect id="Rectangle_65" data-name="Rectangle 65" width="2.537" height="2.537" rx="1" transform="translate(6.012 0)" fill="#4a4a4a"/>
<rect id="Rectangle_66" data-name="Rectangle 66" width="2.537" height="2.537" rx="1" transform="translate(9.018 0)" fill="#4a4a4a"/>
<path id="Path_56" data-name="Path 56" d="M.519,0H14.981A.519.519,0,0,1,15.5.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.018V.519A.519.519,0,0,1,.519,0Zm15.97,0h1.874a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H16.489a.519.519,0,0,1-.519-.519V.519A.519.519,0,0,1,16.489,0Z" transform="translate(12.024 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_67" data-name="Rectangle 67" width="2.537" height="2.537" rx="1" transform="translate(31.376 0)" fill="#4a4a4a"/>
<rect id="Rectangle_68" data-name="Rectangle 68" width="2.537" height="2.537" rx="1" transform="translate(34.382 0)" fill="#4a4a4a"/>
<rect id="Rectangle_69" data-name="Rectangle 69" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
<path id="Path_57" data-name="Path 57" d="M2.537,0V.561a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,.561V0Z" transform="translate(39.736 1.08) rotate(180)" fill="#4a4a4a"/>
<path id="Path_58" data-name="Path 58" d="M2.537,0V.561a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,.561V0Z" transform="translate(37.2 1.456)" fill="#4a4a4a"/>
</g>
<rect id="Rectangle_70" data-name="Rectangle 70" width="42.273" height="1.127" rx="0.564" transform="translate(0.915 0.556)" fill="#4a4a4a"/>
<rect id="Rectangle_71" data-name="Rectangle 71" width="2.37" height="0.752" rx="0.376" transform="translate(1.949 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_72" data-name="Rectangle 72" width="2.37" height="0.752" rx="0.376" transform="translate(5.193 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_73" data-name="Rectangle 73" width="2.37" height="0.752" rx="0.376" transform="translate(7.688 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_74" data-name="Rectangle 74" width="2.37" height="0.752" rx="0.376" transform="translate(10.183 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_75" data-name="Rectangle 75" width="2.37" height="0.752" rx="0.376" transform="translate(12.679 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_76" data-name="Rectangle 76" width="2.37" height="0.752" rx="0.376" transform="translate(15.797 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_77" data-name="Rectangle 77" width="2.37" height="0.752" rx="0.376" transform="translate(18.292 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_78" data-name="Rectangle 78" width="2.37" height="0.752" rx="0.376" transform="translate(20.788 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_79" data-name="Rectangle 79" width="2.37" height="0.752" rx="0.376" transform="translate(23.283 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_80" data-name="Rectangle 80" width="2.37" height="0.752" rx="0.376" transform="translate(26.402 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_81" data-name="Rectangle 81" width="2.37" height="0.752" rx="0.376" transform="translate(28.897 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_82" data-name="Rectangle 82" width="2.37" height="0.752" rx="0.376" transform="translate(31.393 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_83" data-name="Rectangle 83" width="2.37" height="0.752" rx="0.376" transform="translate(34.512 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_84" data-name="Rectangle 84" width="2.37" height="0.752" rx="0.376" transform="translate(37.007 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_85" data-name="Rectangle 85" width="2.37" height="0.752" rx="0.376" transform="translate(39.502 0.744)" fill="#d8d8d8" opacity="0.136"/>
</g>
<path id="Path_59" data-name="Path 59" d="M123.779,148.389a2.583,2.583,0,0,0-.332.033c-.02-.078-.038-.156-.06-.234a2.594,2.594,0,1,0-2.567-4.455q-.086-.088-.174-.175a2.593,2.593,0,1,0-4.461-2.569c-.077-.022-.154-.04-.231-.06a2.6,2.6,0,1,0-5.128,0c-.077.02-.154.038-.231.06a2.594,2.594,0,1,0-4.461,2.569,10.384,10.384,0,1,0,17.314,9.992,2.592,2.592,0,1,0,.332-5.161" transform="translate(-51.054 -75.262)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_60" data-name="Path 60" d="M83,113.389h20.779V103H83Z" transform="translate(-41.443 -58.444)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_61" data-name="Path 61" d="M123.389,108.944a1.3,1.3,0,1,0,0-2.6,1.338,1.338,0,0,0-.166.017c-.01-.039-.019-.078-.03-.117a1.3,1.3,0,0,0-.5-2.5,1.285,1.285,0,0,0-.783.269q-.043-.044-.087-.087a1.285,1.285,0,0,0,.263-.776,1.3,1.3,0,0,0-2.493-.509,5.195,5.195,0,1,0,0,10,1.3,1.3,0,0,0,2.493-.509,1.285,1.285,0,0,0-.263-.776q.044-.043.087-.087a1.285,1.285,0,0,0,.783.269,1.3,1.3,0,0,0,.5-2.5c.011-.038.02-.078.03-.117a1.335,1.335,0,0,0,.166.017" transform="translate(-55.859 -57.894)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_62" data-name="Path 62" d="M141.8,38.745a1.41,1.41,0,0,1-.255-.026,1.309,1.309,0,0,1-.244-.073,1.349,1.349,0,0,1-.224-.119,1.967,1.967,0,0,1-.2-.161,1.52,1.52,0,0,1-.161-.2,1.282,1.282,0,0,1-.218-.722,1.41,1.41,0,0,1,.026-.255,1.5,1.5,0,0,1,.072-.244,1.364,1.364,0,0,1,.12-.223,1.252,1.252,0,0,1,.358-.358,1.349,1.349,0,0,1,.224-.119,1.309,1.309,0,0,1,.244-.073,1.2,1.2,0,0,1,.509,0,1.262,1.262,0,0,1,.468.192,1.968,1.968,0,0,1,.2.161,1.908,1.908,0,0,1,.161.2,1.322,1.322,0,0,1,.12.223,1.361,1.361,0,0,1,.1.5,1.317,1.317,0,0,1-.379.919,1.968,1.968,0,0,1-.2.161,1.346,1.346,0,0,1-.223.119,1.332,1.332,0,0,1-.5.1m10.389-.649a1.326,1.326,0,0,1-.92-.379,1.979,1.979,0,0,1-.161-.2,1.282,1.282,0,0,1-.218-.722,1.326,1.326,0,0,1,.379-.919,1.967,1.967,0,0,1,.2-.161,1.351,1.351,0,0,1,.224-.119,1.308,1.308,0,0,1,.244-.073,1.2,1.2,0,0,1,.509,0,1.262,1.262,0,0,1,.468.192,1.967,1.967,0,0,1,.2.161,1.326,1.326,0,0,1,.379.919,1.461,1.461,0,0,1-.026.255,1.323,1.323,0,0,1-.073.244,1.847,1.847,0,0,1-.119.223,1.911,1.911,0,0,1-.161.2,1.967,1.967,0,0,1-.2.161,1.294,1.294,0,0,1-.722.218" transform="translate(-69.074 -26.006)" fill-rule="evenodd"/>
</g>
<g id="React-icon" transform="translate(906.3 541.56)">
<path id="Path_330" data-name="Path 330" d="M263.668,117.179c0-5.827-7.3-11.35-18.487-14.775,2.582-11.4,1.434-20.477-3.622-23.382a7.861,7.861,0,0,0-4.016-1v4a4.152,4.152,0,0,1,2.044.466c2.439,1.4,3.5,6.724,2.672,13.574-.2,1.685-.52,3.461-.914,5.272a86.9,86.9,0,0,0-11.386-1.954,87.469,87.469,0,0,0-7.459-8.965c5.845-5.433,11.332-8.41,15.062-8.41V78h0c-4.931,0-11.386,3.514-17.913,9.611-6.527-6.061-12.982-9.539-17.913-9.539v4c3.712,0,9.216,2.959,15.062,8.356a84.687,84.687,0,0,0-7.405,8.947,83.732,83.732,0,0,0-11.4,1.972c-.412-1.793-.717-3.532-.932-5.2-.843-6.85.2-12.175,2.618-13.592a3.991,3.991,0,0,1,2.062-.466v-4h0a8,8,0,0,0-4.052,1c-5.039,2.9-6.168,11.96-3.568,23.328-11.153,3.443-18.415,8.947-18.415,14.757,0,5.828,7.3,11.35,18.487,14.775-2.582,11.4-1.434,20.477,3.622,23.382a7.882,7.882,0,0,0,4.034,1c4.931,0,11.386-3.514,17.913-9.611,6.527,6.061,12.982,9.539,17.913,9.539a8,8,0,0,0,4.052-1c5.039-2.9,6.168-11.96,3.568-23.328C256.406,128.511,263.668,122.988,263.668,117.179Zm-23.346-11.96c-.663,2.313-1.488,4.7-2.421,7.083-.735-1.434-1.506-2.869-2.349-4.3-.825-1.434-1.7-2.833-2.582-4.2C235.517,104.179,237.974,104.645,240.323,105.219Zm-8.212,19.1c-1.4,2.421-2.833,4.716-4.321,6.85-2.672.233-5.379.359-8.1.359-2.708,0-5.415-.126-8.069-.341q-2.232-3.2-4.339-6.814-2.044-3.523-3.73-7.136c1.112-2.4,2.367-4.805,3.712-7.154,1.4-2.421,2.833-4.716,4.321-6.85,2.672-.233,5.379-.359,8.1-.359,2.708,0,5.415.126,8.069.341q2.232,3.2,4.339,6.814,2.044,3.523,3.73,7.136C234.692,119.564,233.455,121.966,232.11,124.315Zm5.792-2.331c.968,2.4,1.793,4.805,2.474,7.136-2.349.574-4.823,1.058-7.387,1.434.879-1.381,1.757-2.8,2.582-4.25C236.4,124.871,237.167,123.419,237.9,121.984ZM219.72,141.116a73.921,73.921,0,0,1-4.985-5.738c1.614.072,3.263.126,4.931.126,1.685,0,3.353-.036,4.985-.126A69.993,69.993,0,0,1,219.72,141.116ZM206.38,130.555c-2.546-.377-5-.843-7.352-1.417.663-2.313,1.488-4.7,2.421-7.083.735,1.434,1.506,2.869,2.349,4.3S205.5,129.192,206.38,130.555ZM219.63,93.241a73.924,73.924,0,0,1,4.985,5.738c-1.614-.072-3.263-.126-4.931-.126-1.686,0-3.353.036-4.985.126A69.993,69.993,0,0,1,219.63,93.241ZM206.362,103.8c-.879,1.381-1.757,2.8-2.582,4.25-.825,1.434-1.6,2.869-2.331,4.3-.968-2.4-1.793-4.805-2.474-7.136C201.323,104.663,203.8,104.179,206.362,103.8Zm-16.227,22.449c-6.348-2.708-10.454-6.258-10.454-9.073s4.106-6.383,10.454-9.073c1.542-.663,3.228-1.255,4.967-1.811a86.122,86.122,0,0,0,4.034,10.92,84.9,84.9,0,0,0-3.981,10.866C193.38,127.525,191.694,126.915,190.134,126.252Zm9.647,25.623c-2.439-1.4-3.5-6.724-2.672-13.574.2-1.686.52-3.461.914-5.272a86.9,86.9,0,0,0,11.386,1.954,87.465,87.465,0,0,0,7.459,8.965c-5.845,5.433-11.332,8.41-15.062,8.41A4.279,4.279,0,0,1,199.781,151.875Zm42.532-13.663c.843,6.85-.2,12.175-2.618,13.592a3.99,3.99,0,0,1-2.062.466c-3.712,0-9.216-2.959-15.062-8.356a84.689,84.689,0,0,0,7.405-8.947,83.731,83.731,0,0,0,11.4-1.972A50.194,50.194,0,0,1,242.313,138.212Zm6.9-11.96c-1.542.663-3.228,1.255-4.967,1.811a86.12,86.12,0,0,0-4.034-10.92,84.9,84.9,0,0,0,3.981-10.866c1.775.556,3.461,1.165,5.039,1.829,6.348,2.708,10.454,6.258,10.454,9.073C259.67,119.994,255.564,123.562,249.216,126.252Z" fill="#61dafb"/>
<path id="Path_331" data-name="Path 331" d="M320.8,78.4Z" transform="translate(-119.082 -0.328)" fill="#61dafb"/>
<circle id="Ellipse_112" data-name="Ellipse 112" cx="8.194" cy="8.194" r="8.194" transform="translate(211.472 108.984)" fill="#61dafb"/>
<path id="Path_332" data-name="Path 332" d="M520.5,78.1Z" transform="translate(-282.975 -0.082)" fill="#61dafb"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 35 KiB

View File

@ -1,40 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1129" height="663" viewBox="0 0 1129 663">
<title>Focus on What Matters</title>
<circle cx="321" cy="321" r="321" fill="#f2f2f2" />
<ellipse cx="559" cy="635.49998" rx="514" ry="27.50002" fill="#3f3d56" />
<ellipse cx="558" cy="627" rx="460" ry="22" opacity="0.2" />
<rect x="131" y="152.5" width="840" height="50" fill="#3f3d56" />
<path d="M166.5,727.3299A21.67009,21.67009,0,0,0,188.1701,749H984.8299A21.67009,21.67009,0,0,0,1006.5,727.3299V296h-840Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
<path d="M984.8299,236H188.1701A21.67009,21.67009,0,0,0,166.5,257.6701V296h840V257.6701A21.67009,21.67009,0,0,0,984.8299,236Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
<path d="M984.8299,236H188.1701A21.67009,21.67009,0,0,0,166.5,257.6701V296h840V257.6701A21.67009,21.67009,0,0,0,984.8299,236Z" transform="translate(-35.5 -118.5)" opacity="0.2" />
<circle cx="181" cy="147.5" r="13" fill="#3f3d56" />
<circle cx="217" cy="147.5" r="13" fill="#3f3d56" />
<circle cx="253" cy="147.5" r="13" fill="#3f3d56" />
<rect x="168" y="213.5" width="337" height="386" rx="5.33505" fill="#606060" />
<rect x="603" y="272.5" width="284" height="22" rx="5.47638" fill="#2e8555" />
<rect x="537" y="352.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="537" y="396.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="537" y="440.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="537" y="484.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="865" y="552.5" width="88" height="26" rx="7.02756" fill="#3ecc5f" />
<path d="M1088.60287,624.61594a30.11371,30.11371,0,0,0,3.98291-15.266c0-13.79652-8.54358-24.98081-19.08256-24.98081s-19.08256,11.18429-19.08256,24.98081a30.11411,30.11411,0,0,0,3.98291,15.266,31.248,31.248,0,0,0,0,30.53213,31.248,31.248,0,0,0,0,30.53208,31.248,31.248,0,0,0,0,30.53208,30.11408,30.11408,0,0,0-3.98291,15.266c0,13.79652,8.54353,24.98081,19.08256,24.98081s19.08256-11.18429,19.08256-24.98081a30.11368,30.11368,0,0,0-3.98291-15.266,31.248,31.248,0,0,0,0-30.53208,31.248,31.248,0,0,0,0-30.53208,31.248,31.248,0,0,0,0-30.53213Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
<ellipse cx="1038.00321" cy="460.31783" rx="19.08256" ry="24.9808" fill="#3f3d56" />
<ellipse cx="1038.00321" cy="429.78574" rx="19.08256" ry="24.9808" fill="#3f3d56" />
<path d="M1144.93871,339.34489a91.61081,91.61081,0,0,0,7.10658-10.46092l-50.141-8.23491,54.22885.4033a91.566,91.566,0,0,0,1.74556-72.42605l-72.75449,37.74139,67.09658-49.32086a91.41255,91.41255,0,1,0-150.971,102.29805,91.45842,91.45842,0,0,0-10.42451,16.66946l65.0866,33.81447-69.40046-23.292a91.46011,91.46011,0,0,0,14.73837,85.83669,91.40575,91.40575,0,1,0,143.68892,0,91.41808,91.41808,0,0,0,0-113.02862Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M981.6885,395.8592a91.01343,91.01343,0,0,0,19.56129,56.51431,91.40575,91.40575,0,1,0,143.68892,0C1157.18982,436.82067,981.6885,385.60008,981.6885,395.8592Z" transform="translate(-35.5 -118.5)" opacity="0.1" />
<path d="M365.62,461.43628H477.094v45.12043H365.62Z" transform="translate(-35.5 -118.5)" fill="#fff" fill-rule="evenodd" />
<path d="M264.76252,608.74122a26.50931,26.50931,0,0,1-22.96231-13.27072,26.50976,26.50976,0,0,0,22.96231,39.81215H291.304V608.74122Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M384.17242,468.57061l92.92155-5.80726V449.49263a26.54091,26.54091,0,0,0-26.54143-26.54143H331.1161l-3.31768-5.74622a3.83043,3.83043,0,0,0-6.63536,0l-3.31768,5.74622-3.31767-5.74622a3.83043,3.83043,0,0,0-6.63536,0l-3.31768,5.74622L301.257,417.205a3.83043,3.83043,0,0,0-6.63536,0L291.304,422.9512c-.02919,0-.05573.004-.08625.004l-5.49674-5.49541a3.8293,3.8293,0,0,0-6.4071,1.71723l-1.81676,6.77338L270.607,424.1031a3.82993,3.82993,0,0,0-4.6912,4.69253l1.84463,6.89148-6.77072,1.81411a3.8315,3.8315,0,0,0-1.71988,6.40975l5.49673,5.49673c0,.02787-.004.05574-.004.08493l-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74621,3.31768L259.0163,466.081a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31767a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31767a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768L259.0163,558.976a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768A26.54091,26.54091,0,0,0,291.304,635.28265H450.55254A26.5409,26.5409,0,0,0,477.094,608.74122V502.5755l-92.92155-5.80727a14.12639,14.12639,0,0,1,0-28.19762" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M424.01111,635.28265h39.81214V582.19979H424.01111Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M490.36468,602.10586a6.60242,6.60242,0,0,0-.848.08493c-.05042-.19906-.09821-.39945-.15393-.59852A6.62668,6.62668,0,1,0,482.80568,590.21q-.2203-.22491-.44457-.44589a6.62391,6.62391,0,1,0-11.39689-6.56369c-.1964-.05575-.39414-.10218-.59056-.15262a6.63957,6.63957,0,1,0-13.10086,0c-.1964.05042-.39414.09687-.59056.15262a6.62767,6.62767,0,1,0-11.39688,6.56369,26.52754,26.52754,0,1,0,44.23127,25.52756,6.6211,6.6211,0,1,0,.848-13.18579" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M437.28182,555.65836H477.094V529.11693H437.28182Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M490.36468,545.70532a3.31768,3.31768,0,0,0,0-6.63536,3.41133,3.41133,0,0,0-.42333.04247c-.02655-.09953-.04911-.19907-.077-.29859a3.319,3.319,0,0,0-1.278-6.37923,3.28174,3.28174,0,0,0-2.00122.68742q-.10947-.11346-.22294-.22295a3.282,3.282,0,0,0,.67149-1.98265,3.31768,3.31768,0,0,0-6.37-1.2992,13.27078,13.27078,0,1,0,0,25.54082,3.31768,3.31768,0,0,0,6.37-1.2992,3.282,3.282,0,0,0-.67149-1.98265q.11347-.10947.22294-.22294a3.28174,3.28174,0,0,0,2.00122.68742,3.31768,3.31768,0,0,0,1.278-6.37923c.02786-.0982.05042-.19907.077-.29859a3.41325,3.41325,0,0,0,.42333.04246" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M317.84538,466.081a3.31768,3.31768,0,0,1-3.31767-3.31768,9.953,9.953,0,1,0-19.90608,0,3.31768,3.31768,0,1,1-6.63535,0,16.58839,16.58839,0,1,1,33.17678,0,3.31768,3.31768,0,0,1-3.31768,3.31768" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
<path d="M370.92825,635.28265h79.62429A26.5409,26.5409,0,0,0,477.094,608.74122v-92.895H397.46968a26.54091,26.54091,0,0,0-26.54143,26.54143Z" transform="translate(-35.5 -118.5)" fill="#ffff50" fill-rule="evenodd" />
<path d="M457.21444,556.98543H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,1,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,1,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0-66.10674H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.29459H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414M477.094,474.19076c-.01592,0-.0292-.008-.04512-.00663-4.10064.13934-6.04083,4.24132-7.75274,7.86024-1.78623,3.78215-3.16771,6.24122-5.43171,6.16691-2.50685-.09024-3.94007-2.92222-5.45825-5.91874-1.74377-3.44243-3.73438-7.34667-7.91333-7.20069-4.04227.138-5.98907,3.70784-7.70631,6.857-1.82738,3.35484-3.07084,5.39455-5.46887,5.30033-2.55727-.09289-3.91619-2.39536-5.48877-5.06013-1.75306-2.96733-3.77951-6.30359-7.8775-6.18946-3.97326.13669-5.92537,3.16507-7.64791,5.83912-1.82207,2.82666-3.09872,4.5492-5.52725,4.447-2.61832-.09289-3.9706-2.00388-5.53522-4.21611-1.757-2.4856-3.737-5.299-7.82308-5.16231-3.88567.13271-5.83779,2.61434-7.559,4.80135-1.635,2.07555-2.9116,3.71846-5.61218,3.615a1.32793,1.32793,0,1,0-.09555,2.65414c4.00377.134,6.03154-2.38873,7.79257-4.6275,1.562-1.9853,2.91027-3.69855,5.56441-3.78879,2.55594-.10882,3.75429,1.47968,5.56707,4.04093,1.7212,2.43385,3.67465,5.19416,7.60545,5.33616,4.11789.138,6.09921-2.93946,7.8536-5.66261,1.56861-2.43385,2.92221-4.53461,5.50734-4.62352,2.37944-.08892,3.67466,1.79154,5.50072,4.885,1.72121,2.91557,3.67069,6.21865,7.67977,6.36463,4.14709.14332,6.14965-3.47693,7.89475-6.68181,1.51155-2.77092,2.93814-5.38791,5.46621-5.4755,2.37944-.05573,3.62025,2.11668,5.45558,5.74622,1.71459,3.388,3.65875,7.22591,7.73019,7.37321l.22429.004c4.06614,0,5.99571-4.08074,7.70364-7.68905,1.51154-3.19825,2.94211-6.21069,5.3972-6.33411Z" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
<path d="M344.38682,635.28265h53.08286V582.19979H344.38682Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M424.01111,602.10586a6.60242,6.60242,0,0,0-.848.08493c-.05042-.19906-.09821-.39945-.15394-.59852A6.62667,6.62667,0,1,0,416.45211,590.21q-.2203-.22491-.44458-.44589a6.62391,6.62391,0,1,0-11.39689-6.56369c-.1964-.05575-.39413-.10218-.59054-.15262a6.63957,6.63957,0,1,0-13.10084,0c-.19641.05042-.39414.09687-.59055.15262a6.62767,6.62767,0,1,0-11.39689,6.56369,26.52755,26.52755,0,1,0,44.2313,25.52756,6.6211,6.6211,0,1,0,.848-13.18579" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M344.38682,555.65836h53.08286V529.11693H344.38682Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M410.74039,545.70532a3.31768,3.31768,0,1,0,0-6.63536,3.41133,3.41133,0,0,0-.42333.04247c-.02655-.09953-.04911-.19907-.077-.29859a3.319,3.319,0,0,0-1.278-6.37923,3.28174,3.28174,0,0,0-2.00122.68742q-.10947-.11346-.22294-.22295a3.282,3.282,0,0,0,.67149-1.98265,3.31768,3.31768,0,0,0-6.37-1.2992,13.27078,13.27078,0,1,0,0,25.54082,3.31768,3.31768,0,0,0,6.37-1.2992,3.282,3.282,0,0,0-.67149-1.98265q.11347-.10947.22294-.22294a3.28174,3.28174,0,0,0,2.00122.68742,3.31768,3.31768,0,0,0,1.278-6.37923c.02786-.0982.05042-.19907.077-.29859a3.41325,3.41325,0,0,0,.42333.04246" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M424.01111,447.8338a3.60349,3.60349,0,0,1-.65028-.06636,3.34415,3.34415,0,0,1-.62372-.18579,3.44679,3.44679,0,0,1-.572-.30522,5.02708,5.02708,0,0,1-.50429-.4114,3.88726,3.88726,0,0,1-.41007-.50428,3.27532,3.27532,0,0,1-.55737-1.84463,3.60248,3.60248,0,0,1,.06636-.65027,3.82638,3.82638,0,0,1,.18447-.62373,3.48858,3.48858,0,0,1,.30656-.57064,3.197,3.197,0,0,1,.91436-.91568,3.44685,3.44685,0,0,1,.572-.30523,3.344,3.344,0,0,1,.62372-.18578,3.06907,3.06907,0,0,1,1.30053,0,3.22332,3.22332,0,0,1,1.19436.491,5.02835,5.02835,0,0,1,.50429.41139,4.8801,4.8801,0,0,1,.41139.50429,3.38246,3.38246,0,0,1,.30522.57064,3.47806,3.47806,0,0,1,.25215,1.274A3.36394,3.36394,0,0,1,426.36,446.865a5.02708,5.02708,0,0,1-.50429.4114,3.3057,3.3057,0,0,1-1.84463.55737m26.54143-1.65884a3.38754,3.38754,0,0,1-2.35024-.96877,5.04185,5.04185,0,0,1-.41007-.50428,3.27532,3.27532,0,0,1-.55737-1.84463,3.38659,3.38659,0,0,1,.96744-2.34892,5.02559,5.02559,0,0,1,.50429-.41139,3.44685,3.44685,0,0,1,.572-.30523,3.3432,3.3432,0,0,1,.62373-.18579,3.06952,3.06952,0,0,1,1.30052,0,3.22356,3.22356,0,0,1,1.19436.491,5.02559,5.02559,0,0,1,.50429.41139,3.38792,3.38792,0,0,1,.96876,2.34892,3.72635,3.72635,0,0,1-.06636.65026,3.37387,3.37387,0,0,1-.18579.62373,4.71469,4.71469,0,0,1-.30522.57064,4.8801,4.8801,0,0,1-.41139.50429,5.02559,5.02559,0,0,1-.50429.41139,3.30547,3.30547,0,0,1-1.84463.55737" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,8 +0,0 @@
{
// This file is not used in compilation. It is here just for a nice editor experience.
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
"baseUrl": "."
},
"exclude": [".docusaurus", "build"]
}

View File

@ -1,11 +0,0 @@
import * as React from "react";
import { type VariantProps } from "class-variance-authority";
declare const buttonVariants: (props?: ({
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
size?: "default" | "sm" | "lg" | "icon" | null | undefined;
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
export { Button, buttonVariants };

View File

@ -1,44 +0,0 @@
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva } from "class-variance-authority";
import { cn } from "../../utils";
const buttonVariants = cva("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50", {
variants: {
variant: {
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
});
const Button = React.forwardRef((_a, ref) => {
var { className, variant, size, asChild = false } = _a, props = __rest(_a, ["className", "variant", "size", "asChild"]);
const Comp = asChild ? Slot : "button";
return (React.createElement(Comp, Object.assign({ className: cn(buttonVariants({ variant, size, className })), ref: ref }, props)));
});
Button.displayName = "Button";
export { Button, buttonVariants };

View File

@ -1,8 +0,0 @@
import * as React from "react";
declare const Card: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
declare const CardHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
declare const CardTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLParagraphElement>>;
declare const CardDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
declare const CardContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
declare const CardFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };

View File

@ -1,44 +0,0 @@
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import * as React from "react";
import { cn } from "../../utils";
const Card = React.forwardRef((_a, ref) => {
var { className } = _a, props = __rest(_a, ["className"]);
return (React.createElement("div", Object.assign({ ref: ref, className: cn("rounded-xl border bg-card text-card-foreground shadow", className) }, props)));
});
Card.displayName = "Card";
const CardHeader = React.forwardRef((_a, ref) => {
var { className } = _a, props = __rest(_a, ["className"]);
return (React.createElement("div", Object.assign({ ref: ref, className: cn("flex flex-col space-y-1.5 p-6", className) }, props)));
});
CardHeader.displayName = "CardHeader";
const CardTitle = React.forwardRef((_a, ref) => {
var { className } = _a, props = __rest(_a, ["className"]);
return (React.createElement("h3", Object.assign({ ref: ref, className: cn("font-semibold leading-none tracking-tight", className) }, props)));
});
CardTitle.displayName = "CardTitle";
const CardDescription = React.forwardRef((_a, ref) => {
var { className } = _a, props = __rest(_a, ["className"]);
return (React.createElement("p", Object.assign({ ref: ref, className: cn("text-sm text-muted-foreground", className) }, props)));
});
CardDescription.displayName = "CardDescription";
const CardContent = React.forwardRef((_a, ref) => {
var { className } = _a, props = __rest(_a, ["className"]);
return (React.createElement("div", Object.assign({ ref: ref, className: cn("p-6 pt-0", className) }, props)));
});
CardContent.displayName = "CardContent";
const CardFooter = React.forwardRef((_a, ref) => {
var { className } = _a, props = __rest(_a, ["className"]);
return (React.createElement("div", Object.assign({ ref: ref, className: cn("flex items-center p-6 pt-0", className) }, props)));
});
CardFooter.displayName = "CardFooter";
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };

View File

@ -1,9 +0,0 @@
export * from './button';
export * from './card';
export * from './collapsible';
export * from './floating-action-button';
export * from './input';
export * from './layout';
export * from './sheet';
export * from './switch';
export * from './scroll-area';

View File

@ -1,9 +0,0 @@
export * from './button';
export * from './card';
export * from './collapsible';
export * from './floating-action-button';
export * from './input';
export * from './layout';
export * from './sheet';
export * from './switch';
export * from './scroll-area';

View File

@ -1,5 +0,0 @@
import * as React from "react";
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
}
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
export { Input };

View File

@ -1,19 +0,0 @@
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import * as React from "react";
import { cn } from "../../utils";
const Input = React.forwardRef((_a, ref) => {
var { className, type } = _a, props = __rest(_a, ["className", "type"]);
return (React.createElement("input", Object.assign({ type: type, className: cn("flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50", className), ref: ref }, props)));
});
Input.displayName = "Input";
export { Input };

View File

@ -1,4 +0,0 @@
import * as React from "react";
import * as SwitchPrimitives from "@radix-ui/react-switch";
declare const Switch: React.ForwardRefExoticComponent<Omit<SwitchPrimitives.SwitchProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
export { Switch };

View File

@ -1,21 +0,0 @@
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import * as React from "react";
import * as SwitchPrimitives from "@radix-ui/react-switch";
import { cn } from "../../utils";
const Switch = React.forwardRef((_a, ref) => {
var { className } = _a, props = __rest(_a, ["className"]);
return (React.createElement(SwitchPrimitives.Root, Object.assign({ className: cn("peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input", className) }, props, { ref: ref }),
React.createElement(SwitchPrimitives.Thumb, { className: cn("pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0") })));
});
Switch.displayName = SwitchPrimitives.Root.displayName;
export { Switch };

View File

@ -1,11 +0,0 @@
import './styles/global.css';
export * from './utils/types';
export * from './utils';
export * from './components/ui';
export * from './components/TimelineStep';
export * from './components/TimelineFeed';
export * from './components/SessionDrawer';
export * from './components/SessionSidebar';
export * from './components/DefaultAgentScreen';
export declare const hello: () => void;
export { getSampleAgentSteps, getSampleAgentSessions } from './utils/sample-data';

View File

@ -1,22 +0,0 @@
// Entry point for @ra-aid/common package
import './styles/global.css';
// Export types first to avoid circular references
export * from './utils/types';
// Export utility functions
export * from './utils';
// Export UI components
export * from './components/ui';
// Export timeline components
export * from './components/TimelineStep';
export * from './components/TimelineFeed';
// Export session navigation components
export * from './components/SessionDrawer';
export * from './components/SessionSidebar';
// Export main screens
export * from './components/DefaultAgentScreen';
// Export the hello function (temporary example)
export const hello = () => {
console.log("Hello from @ra-aid/common");
};
// Directly export sample data functions
export { getSampleAgentSteps, getSampleAgentSessions } from './utils/sample-data';

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
import { type ClassValue } from "clsx";
/**
* Merges class names with Tailwind CSS classes
* Combines clsx for conditional logic and tailwind-merge for handling conflicting tailwind classes
*/
export declare function cn(...inputs: ClassValue[]): string;
export * from './utils';

View File

@ -1,11 +0,0 @@
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";
/**
* Merges class names with Tailwind CSS classes
* Combines clsx for conditional logic and tailwind-merge for handling conflicting tailwind classes
*/
export function cn(...inputs) {
return twMerge(clsx(inputs));
}
// Re-export everything from utils directory
export * from './utils';

File diff suppressed because it is too large Load Diff

View File

@ -1,43 +0,0 @@
{
"name": "@ra-aid/common",
"version": "1.0.0",
"private": true,
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"build": "tsc && postcss src/styles/global.css -o dist/styles/global.css",
"dev": "tsc --watch",
"watch:css": "postcss src/styles/global.css -o dist/styles/global.css --watch",
"watch": "concurrently \"npm run dev\" \"npm run watch:css\"",
"prepare": "npm run build"
},
"dependencies": {
"@radix-ui/react-collapsible": "^1.1.3",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-scroll-area": "^1.2.3",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.1.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"lucide-react": "^0.363.0",
"tailwind-merge": "^2.2.0",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@types/react": "^18.2.64",
"@types/react-dom": "^18.2.21",
"autoprefixer": "^10.4.17",
"concurrently": "^8.2.2",
"postcss": "^8.4.35",
"postcss-cli": "^10.1.0",
"tailwindcss": "^3.4.1",
"typescript": "^5.0.0"
},
"peerDependencies": {
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
}
}

View File

@ -1,6 +0,0 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -1,258 +0,0 @@
import React, { useState, useEffect } from 'react';
import { createPortal } from 'react-dom';
import { PanelLeft } from 'lucide-react';
import {
Button,
Layout
} from './ui';
import { SessionDrawer } from './SessionDrawer';
import { SessionList } from './SessionList';
import { TimelineFeed } from './TimelineFeed';
import { getSampleAgentSessions, getSampleAgentSteps } from '../utils/sample-data';
import logoBlack from '../assets/logo-black-transparent.png';
import logoWhite from '../assets/logo-white-transparent.gif';
/**
* DefaultAgentScreen component
*
* Main application screen for displaying agent sessions and their steps.
* Handles state management, responsive design, and UI interactions.
*/
export const DefaultAgentScreen: React.FC = () => {
// State for drawer open/close
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
// State for selected session
const [selectedSessionId, setSelectedSessionId] = useState<string | null>(null);
// State for theme (dark is default)
const [isDarkTheme, setIsDarkTheme] = useState(true);
// Get sample data
const sessions = getSampleAgentSessions();
const allSteps = getSampleAgentSteps();
// Set up theme on component mount
useEffect(() => {
const isDark = setupTheme();
setIsDarkTheme(isDark);
}, []);
// Set initial selected session if none selected
useEffect(() => {
if (!selectedSessionId && sessions.length > 0) {
setSelectedSessionId(sessions[0].id);
}
}, [sessions, selectedSessionId]);
// Close drawer when window resizes to desktop width
useEffect(() => {
const handleResize = () => {
// Check if we're at desktop size (corresponds to md: breakpoint in Tailwind)
if (window.innerWidth >= 768 && isDrawerOpen) {
setIsDrawerOpen(false);
}
};
// Add event listener
window.addEventListener('resize', handleResize);
// Clean up event listener on component unmount
return () => window.removeEventListener('resize', handleResize);
}, [isDrawerOpen]);
// Filter steps for selected session
const selectedSessionSteps = selectedSessionId
? allSteps.filter(step => sessions.find(s => s.id === selectedSessionId)?.steps.some(s => s.id === step.id))
: [];
// Handle session selection
const handleSessionSelect = (sessionId: string) => {
setSelectedSessionId(sessionId);
setIsDrawerOpen(false); // Close drawer on selection (mobile)
};
// Toggle theme function
const toggleTheme = () => {
const newIsDark = !isDarkTheme;
setIsDarkTheme(newIsDark);
// Update document element class
if (newIsDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
// Save to localStorage
localStorage.setItem('theme', newIsDark ? 'dark' : 'light');
};
// Render header content
const headerContent = (
<div className="w-full flex items-center justify-between h-full px-4">
<div className="flex-initial">
{/* Use the appropriate logo based on theme */}
<img
src={isDarkTheme ? logoWhite : logoBlack}
alt="RA.Aid Logo"
className="h-8"
/>
</div>
<div className="flex-initial ml-auto">
{/* Theme toggle button */}
<Button
variant="ghost"
size="icon"
onClick={toggleTheme}
aria-label={isDarkTheme ? "Switch to light mode" : "Switch to dark mode"}
>
{isDarkTheme ? (
// Sun icon for light mode toggle
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx="12" cy="12" r="5" />
<line x1="12" y1="1" x2="12" y2="3" />
<line x1="12" y1="21" x2="12" y2="23" />
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
<line x1="1" y1="12" x2="3" y2="12" />
<line x1="21" y1="12" x2="23" y2="12" />
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
</svg>
) : (
// Moon icon for dark mode toggle
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
</svg>
)}
</Button>
</div>
</div>
);
// Sidebar content with sessions list
const sidebarContent = (
<div className="h-full flex flex-col px-4 py-3">
<SessionList
sessions={sessions}
onSelectSession={handleSessionSelect}
currentSessionId={selectedSessionId || undefined}
className="flex-1 pr-1 -mr-1"
/>
</div>
);
// Render drawer
const drawerContent = (
<SessionDrawer
sessions={sessions}
currentSessionId={selectedSessionId || undefined}
onSelectSession={handleSessionSelect}
isOpen={isDrawerOpen}
onClose={() => setIsDrawerOpen(false)}
/>
);
// Render main content
const mainContent = (
selectedSessionId ? (
<>
<h2 className="text-xl font-semibold mb-4">
Session: {sessions.find(s => s.id === selectedSessionId)?.name || 'Unknown'}
</h2>
<TimelineFeed
steps={selectedSessionSteps}
/>
</>
) : (
<div className="flex items-center justify-center h-full">
<p className="text-muted-foreground">Select a session to view details</p>
</div>
)
);
// Floating action button component that uses Portal to render at document body level
const FloatingActionButton = ({ onClick }: { onClick: () => void }) => {
// Only render the portal on the client side, not during SSR
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
return () => setMounted(false);
}, []);
const button = (
<Button
variant="default"
size="icon"
onClick={onClick}
aria-label="Toggle sessions panel"
className="h-14 w-14 rounded-full shadow-xl bg-zinc-800 hover:bg-zinc-700 text-zinc-100 flex items-center justify-center border-2 border-zinc-700 dark:border-zinc-600"
>
<PanelLeft className="h-6 w-6" />
</Button>
);
const container = (
<div className="fixed bottom-6 right-6 z-[9999] md:hidden" style={{ pointerEvents: 'auto' }}>
{button}
</div>
);
// Return null during SSR, or the portal on the client
return mounted ? createPortal(container, document.body) : null;
};
return (
<>
<Layout
header={headerContent}
sidebar={sidebarContent}
drawer={drawerContent}
>
{mainContent}
</Layout>
<FloatingActionButton onClick={() => setIsDrawerOpen(true)} />
</>
);
};
// Helper function for theme setup
const setupTheme = () => {
// Check if theme preference is stored in localStorage
const storedTheme = localStorage.getItem('theme');
// Default to dark mode unless explicitly set to light
const isDark = storedTheme ? storedTheme === 'dark' : true;
// Apply theme to document
if (isDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
return isDark;
};

View File

@ -1,47 +0,0 @@
import React from 'react';
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
SheetClose
} from './ui/sheet';
import { AgentSession } from '../utils/types';
import { getSampleAgentSessions } from '../utils/sample-data';
import { SessionList } from './SessionList';
interface SessionDrawerProps {
onSelectSession?: (sessionId: string) => void;
currentSessionId?: string;
sessions?: AgentSession[];
isOpen?: boolean;
onClose?: () => void;
}
export const SessionDrawer: React.FC<SessionDrawerProps> = ({
onSelectSession,
currentSessionId,
sessions = getSampleAgentSessions(),
isOpen = false,
onClose
}) => {
return (
<Sheet open={isOpen} onOpenChange={onClose}>
<SheetContent
side="left"
className="w-full sm:max-w-md border-r border-border p-4"
>
<SheetHeader className="px-2">
<SheetTitle>Sessions</SheetTitle>
</SheetHeader>
<SessionList
sessions={sessions}
currentSessionId={currentSessionId}
onSelectSession={onSelectSession}
className="h-[calc(100vh-9rem)] mt-4"
wrapperComponent={SheetClose}
/>
</SheetContent>
</Sheet>
);
};

View File

@ -1,93 +0,0 @@
import React from 'react';
import { ScrollArea } from './ui/scroll-area';
import { AgentSession } from '../utils/types';
import { getSampleAgentSessions } from '../utils/sample-data';
interface SessionListProps {
onSelectSession?: (sessionId: string) => void;
currentSessionId?: string;
sessions?: AgentSession[];
className?: string;
wrapperComponent?: React.ElementType;
closeAction?: React.ReactNode;
}
export const SessionList: React.FC<SessionListProps> = ({
onSelectSession,
currentSessionId,
sessions = getSampleAgentSessions(),
className = '',
wrapperComponent: WrapperComponent = 'button',
closeAction
}) => {
// Get status color
const getStatusColor = (status: string) => {
switch (status) {
case 'active':
return 'bg-blue-500';
case 'completed':
return 'bg-green-500';
case 'error':
return 'bg-red-500';
default:
return 'bg-gray-500';
}
};
// Format timestamp
const formatDate = (date: Date) => {
return date.toLocaleDateString([], {
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
};
return (
<ScrollArea className={className}>
<div className="space-y-1.5 pt-1.5 pb-2">
{sessions.map((session) => {
const buttonContent = (
<>
<div className={`w-2.5 h-2.5 rounded-full ${getStatusColor(session.status)} mt-1.5 mr-3 flex-shrink-0`} />
<div className="flex-1 min-w-0 pr-1">
<div className="font-medium text-sm+ break-words">{session.name}</div>
<div className="text-xs text-muted-foreground mt-1 break-words">
{session.steps.length} steps {formatDate(session.updated)}
</div>
<div className="text-xs text-muted-foreground mt-0.5 break-words">
<span className="capitalize">{session.status}</span>
</div>
</div>
</>
);
return React.createElement(
WrapperComponent,
{
key: session.id,
onClick: () => onSelectSession?.(session.id),
className: `w-full flex items-start px-3 py-2.5 text-left rounded-md transition-colors hover:bg-accent/50 ${
currentSessionId === session.id ? 'bg-accent' : ''
}`
},
closeAction ? (
<>
{buttonContent}
<div className="ml-2 flex-shrink-0 self-center">
{React.cloneElement(closeAction as React.ReactElement, {
onClick: (e: React.MouseEvent) => {
e.stopPropagation();
onSelectSession?.(session.id);
}
})}
</div>
</>
) : buttonContent
);
})}
</div>
</ScrollArea>
);
};

View File

@ -1,32 +0,0 @@
import React from 'react';
import { AgentSession } from '../utils/types';
import { getSampleAgentSessions } from '../utils/sample-data';
import { SessionList } from './SessionList';
interface SessionSidebarProps {
onSelectSession?: (sessionId: string) => void;
currentSessionId?: string;
sessions?: AgentSession[];
className?: string;
}
export const SessionSidebar: React.FC<SessionSidebarProps> = ({
onSelectSession,
currentSessionId,
sessions = getSampleAgentSessions(),
className = ''
}) => {
return (
<div className={`flex flex-col h-full ${className}`}>
<div className="p-4 border-b border-border">
<h3 className="font-medium text-lg">Sessions</h3>
</div>
<SessionList
sessions={sessions}
currentSessionId={currentSessionId}
onSelectSession={onSelectSession}
className="flex-1"
/>
</div>
);
};

View File

@ -1,45 +0,0 @@
import React, { useMemo } from 'react';
import { TimelineStep } from './TimelineStep';
import { AgentStep } from '../utils/types';
interface TimelineFeedProps {
steps: AgentStep[];
maxHeight?: string;
}
export const TimelineFeed: React.FC<TimelineFeedProps> = ({
steps,
maxHeight
}) => {
// Always use 'desc' (newest first) sort order
const sortOrder = 'desc';
// Sort steps with newest first (desc order)
const sortedSteps = useMemo(() => {
return [...steps].sort((a, b) => {
return b.timestamp.getTime() - a.timestamp.getTime();
});
}, [steps]);
return (
<div className="w-full rounded-md bg-background">
<div
className="px-3 py-3 space-y-4 overflow-auto"
style={{ maxHeight: maxHeight || undefined }}
>
{sortedSteps.length > 0 ? (
sortedSteps.map((step) => (
<TimelineStep key={step.id} step={step} />
))
) : (
<div className="text-center text-muted-foreground py-12 border border-dashed border-border rounded-md">
<svg xmlns="http://www.w3.org/2000/svg" className="h-8 w-8 mx-auto mb-2 text-muted-foreground/50" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<p>No steps to display</p>
</div>
)}
</div>
</div>
);
}

View File

@ -1,99 +0,0 @@
import React from 'react';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collapsible';
import { AgentStep } from '../utils/types';
interface TimelineStepProps {
step: AgentStep;
}
export const TimelineStep: React.FC<TimelineStepProps> = ({ step }) => {
// Get status color
const getStatusColor = (status: string) => {
switch (status) {
case 'completed':
return 'bg-green-500';
case 'in-progress':
return 'bg-blue-500';
case 'error':
return 'bg-red-500';
case 'pending':
return 'bg-yellow-500';
default:
return 'bg-gray-500';
}
};
// Get icon based on step type
const getTypeIcon = (type: string) => {
switch (type) {
case 'tool-execution':
return '🛠️';
case 'thinking':
return '💭';
case 'planning':
return '📝';
case 'implementation':
return '💻';
case 'user-input':
return '👤';
default:
return '▶️';
}
};
// Format timestamp
const formatTime = (timestamp: Date) => {
return timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
};
return (
<Collapsible className="w-full mb-5 border border-border rounded-md overflow-hidden shadow-sm hover:shadow-md transition-all duration-200">
<CollapsibleTrigger className="w-full flex items-center justify-between p-4 text-left hover:bg-accent/30 cursor-pointer group">
<div className="flex items-center space-x-3 min-w-0 flex-1 pr-3">
<div className={`flex-shrink-0 w-3 h-3 rounded-full ${getStatusColor(step.status)} ring-1 ring-ring/20`} />
<div className="flex-shrink-0 text-lg group-hover:scale-110 transition-transform">{getTypeIcon(step.type)}</div>
<div className="min-w-0 flex-1">
<div className="font-medium text-foreground break-words">{step.title}</div>
<div className="text-sm text-muted-foreground line-clamp-2">
{step.type === 'tool-execution' ? 'Run tool' : step.content.substring(0, 60)}
{step.content.length > 60 ? '...' : ''}
</div>
</div>
</div>
<div className="text-xs text-muted-foreground flex flex-col items-end flex-shrink-0 min-w-[70px] text-right">
<span className="font-medium">{formatTime(step.timestamp)}</span>
{step.duration && (
<span className="mt-1 px-2 py-0.5 bg-secondary/50 rounded-full">
{(step.duration / 1000).toFixed(1)}s
</span>
)}
</div>
</CollapsibleTrigger>
<CollapsibleContent>
<div className="p-5 bg-card/50 border-t border-border">
<div className="text-sm break-words text-foreground leading-relaxed">
{step.content}
</div>
{step.duration && (
<div className="mt-4 pt-3 border-t border-border/50">
<div className="text-xs text-muted-foreground flex items-center">
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-3.5 w-3.5 mr-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<circle cx="12" cy="12" r="10" />
<polyline points="12 6 12 12 16 14" />
</svg>
Duration: {(step.duration / 1000).toFixed(1)} seconds
</div>
</div>
)}
</div>
</CollapsibleContent>
</Collapsible>
);
};

View File

@ -1,57 +0,0 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "../../utils";
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline:
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = "Button";
export { Button, buttonVariants };

View File

@ -1,76 +0,0 @@
import * as React from "react";
import { cn } from "../../utils";
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-xl border bg-card text-card-foreground shadow",
className
)}
{...props}
/>
));
Card.displayName = "Card";
const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
));
CardHeader.displayName = "CardHeader";
const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn("font-semibold leading-none tracking-tight", className)}
{...props}
/>
));
CardTitle.displayName = "CardTitle";
const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
));
CardDescription.displayName = "CardDescription";
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
));
CardContent.displayName = "CardContent";
const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
));
CardFooter.displayName = "CardFooter";
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };

View File

@ -1,27 +0,0 @@
import * as React from "react"
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
import { cn } from "../../utils"
const Collapsible = CollapsiblePrimitive.Root
const CollapsibleTrigger = CollapsiblePrimitive.Trigger
const CollapsibleContent = React.forwardRef<
React.ElementRef<typeof CollapsiblePrimitive.Content>,
React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Content>
>(({ className, children, ...props }, ref) => (
<CollapsiblePrimitive.Content
ref={ref}
className={cn(
"overflow-hidden data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
className
)}
{...props}
>
{children}
</CollapsiblePrimitive.Content>
))
CollapsibleContent.displayName = "CollapsibleContent"
export { Collapsible, CollapsibleTrigger, CollapsibleContent }

View File

@ -1,36 +0,0 @@
import React, { ReactNode } from 'react';
import { Button } from './button';
export interface FloatingActionButtonProps {
icon: ReactNode;
onClick: () => void;
ariaLabel?: string;
className?: string;
variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
}
/**
* FloatingActionButton component
*
* A button typically used for primary actions on mobile layouts
* Designed to be used with the Layout component's floatingAction prop
*/
export const FloatingActionButton: React.FC<FloatingActionButtonProps> = ({
icon,
onClick,
ariaLabel = 'Action button',
className = '',
variant = 'default'
}) => {
return (
<Button
variant={variant}
size="icon"
onClick={onClick}
aria-label={ariaLabel}
className={`h-14 w-14 rounded-full shadow-xl bg-blue-600 hover:bg-blue-700 text-white flex items-center justify-center border-2 border-white dark:border-gray-800 ${className}`}
>
{icon}
</Button>
);
};

View File

@ -1,9 +0,0 @@
export * from './button';
export * from './card';
export * from './collapsible';
export * from './floating-action-button';
export * from './input';
export * from './layout';
export * from './sheet';
export * from './switch';
export * from './scroll-area';

View File

@ -1,25 +0,0 @@
import * as React from "react";
import { cn } from "../../utils";
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
"flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}
/>
);
}
);
Input.displayName = "Input";
export { Input };

View File

@ -1,56 +0,0 @@
import React from 'react';
/**
* Layout component using Tailwind Grid utilities
* This component creates a responsive layout with:
* - Sticky header at the top (z-index 30)
* - Sidebar on desktop (hidden on mobile)
* - Main content area with proper positioning
* - Optional floating action button for mobile navigation
*/
export interface LayoutProps {
header: React.ReactNode;
sidebar?: React.ReactNode;
drawer?: React.ReactNode;
children: React.ReactNode;
floatingAction?: React.ReactNode;
}
export const Layout: React.FC<LayoutProps> = ({
header,
sidebar,
drawer,
children,
floatingAction
}) => {
return (
<div className="grid min-h-screen grid-cols-1 grid-rows-[64px_1fr] md:grid-cols-[280px_1fr] lg:grid-cols-[320px_1fr] xl:grid-cols-[350px_1fr] bg-background text-foreground relative">
{/* Header - always visible, spans full width */}
<header className="sticky top-0 z-30 h-16 flex items-center bg-background border-b border-border col-span-full">
{header}
</header>
{/* Sidebar - hidden on mobile, visible on tablet/desktop */}
{sidebar && (
<aside className="hidden md:block fixed top-16 bottom-0 w-[280px] lg:w-[320px] xl:w-[350px] overflow-y-auto z-20 bg-background border-r border-border">
{sidebar}
</aside>
)}
{/* Main content area */}
<main className="overflow-y-auto p-4 row-start-2 col-start-1 md:col-start-2 md:h-[calc(100vh-64px)]">
{children}
</main>
{/* Mobile drawer - rendered outside grid */}
{drawer}
{/* Floating action button for mobile */}
{floatingAction && (
<div className="fixed bottom-6 right-6 z-50 md:hidden">
{floatingAction}
</div>
)}
</div>
);
};

View File

@ -1,47 +0,0 @@
import * as React from "react"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
import { cn } from "../../utils"
const ScrollArea = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
>(({ className, children, ...props }, ref) => (
<ScrollAreaPrimitive.Root
ref={ref}
className={cn("relative overflow-hidden", className)}
{...props}
>
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
{children}
</ScrollAreaPrimitive.Viewport>
<ScrollBar />
<ScrollBar orientation="horizontal" />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
))
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
const ScrollBar = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
>(({ className, orientation = "vertical", ...props }, ref) => (
<ScrollAreaPrimitive.ScrollAreaScrollbar
ref={ref}
orientation={orientation}
className={cn(
"flex touch-none select-none transition-colors",
orientation === "vertical" &&
"h-full w-2.5 border-l border-l-transparent p-[1px]",
orientation === "horizontal" &&
"h-2.5 border-t border-t-transparent p-[1px]",
className
)}
{...props}
>
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
</ScrollAreaPrimitive.ScrollAreaScrollbar>
))
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
export { ScrollArea, ScrollBar }

View File

@ -1,134 +0,0 @@
import * as React from "react"
import * as SheetPrimitive from "@radix-ui/react-dialog"
import { cva, type VariantProps } from "class-variance-authority"
import { X } from "lucide-react"
import { cn } from "../../utils"
const Sheet = SheetPrimitive.Root
const SheetTrigger = SheetPrimitive.Trigger
const SheetClose = SheetPrimitive.Close
const SheetPortal = SheetPrimitive.Portal
const SheetOverlay = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Overlay
className={cn(
"fixed inset-0 z-70 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
ref={ref}
/>
))
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
const sheetVariants = cva(
"fixed z-70 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
{
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-full border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
},
},
defaultVariants: {
side: "right",
},
}
)
interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {}
const SheetContent = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Content>,
SheetContentProps
>(({ side = "right", className, children, ...props }, ref) => (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content
ref={ref}
className={cn(sheetVariants({ side }), className)}
{...props}
>
{children}
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
))
SheetContent.displayName = SheetPrimitive.Content.displayName
const SheetHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-2 text-center sm:text-left",
className
)}
{...props}
/>
)
SheetHeader.displayName = "SheetHeader"
const SheetFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
SheetFooter.displayName = "SheetFooter"
const SheetTitle = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold text-foreground", className)}
{...props}
/>
))
SheetTitle.displayName = SheetPrimitive.Title.displayName
const SheetDescription = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
SheetDescription.displayName = SheetPrimitive.Description.displayName
export {
Sheet,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
}

View File

@ -1,27 +0,0 @@
import * as React from "react";
import * as SwitchPrimitives from "@radix-ui/react-switch";
import { cn } from "../../utils";
const Switch = React.forwardRef<
React.ElementRef<typeof SwitchPrimitives.Root>,
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
>(({ className, ...props }, ref) => (
<SwitchPrimitives.Root
className={cn(
"peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
className
)}
{...props}
ref={ref}
>
<SwitchPrimitives.Thumb
className={cn(
"pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
)}
/>
</SwitchPrimitives.Root>
));
Switch.displayName = SwitchPrimitives.Root.displayName;
export { Switch };

View File

@ -1,33 +0,0 @@
// Entry point for @ra-aid/common package
import './styles/global.css';
// Export types first to avoid circular references
export * from './utils/types';
// Export utility functions
export * from './utils';
// Export UI components
export * from './components/ui';
// Export timeline components
export * from './components/TimelineStep';
export * from './components/TimelineFeed';
// Export session navigation components
export * from './components/SessionDrawer';
export * from './components/SessionSidebar';
// Export main screens
export * from './components/DefaultAgentScreen';
// Export the hello function (temporary example)
export const hello = (): void => {
console.log("Hello from @ra-aid/common");
};
// Directly export sample data functions
export {
getSampleAgentSteps,
getSampleAgentSessions
} from './utils/sample-data';

View File

@ -1,80 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 47.4% 11.2%;
--card: 0 0% 100%;
--card-foreground: 222.2 47.4% 11.2%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 100% 50%;
--destructive-foreground: 210 40% 98%;
--ring: 215 20.2% 65.1%;
--radius: 0.5rem;
}
.dark {
--background: 240 10% 3.9%; /* zinc-950 */
--foreground: 240 5% 96%; /* zinc-50 */
--card: 240 10% 3.9%; /* zinc-950 */
--card-foreground: 240 5% 96%; /* zinc-50 */
--popover: 240 10% 3.9%; /* zinc-950 */
--popover-foreground: 240 5% 96%; /* zinc-50 */
--primary: 240 5% 96%; /* zinc-50 */
--primary-foreground: 240 6% 10%; /* zinc-900 */
--secondary: 240 4% 16%; /* zinc-800 */
--secondary-foreground: 240 5% 96%; /* zinc-50 */
--muted: 240 4% 16%; /* zinc-800 */
--muted-foreground: 240 5% 65%; /* zinc-400 */
--accent: 240 4% 16%; /* zinc-800 */
--accent-foreground: 240 5% 96%; /* zinc-50 */
--destructive: 0 63% 31%; /* red-900 */
--destructive-foreground: 240 5% 96%; /* zinc-50 */
--border: 240 4% 16%; /* zinc-800 */
--input: 240 4% 16%; /* zinc-800 */
--ring: 240 5% 84%; /* zinc-300 */
--radius: 0.5rem;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
font-feature-settings: "rlig" 1, "calt" 1;
}
}

View File

@ -1,24 +0,0 @@
declare module '*.png' {
const content: string;
export default content;
}
declare module '*.gif' {
const content: string;
export default content;
}
declare module '*.jpg' {
const content: string;
export default content;
}
declare module '*.jpeg' {
const content: string;
export default content;
}
declare module '*.svg' {
const content: string;
export default content;
}

View File

@ -1,13 +0,0 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
/**
* Merges class names with Tailwind CSS classes
* Combines clsx for conditional logic and tailwind-merge for handling conflicting tailwind classes
*/
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
// Re-export everything from utils directory
export * from './utils';

View File

@ -1,13 +0,0 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
/**
* Merges class names with Tailwind CSS classes
* Combines clsx for conditional logic and tailwind-merge for handling conflicting tailwind classes
*/
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
// Note: Sample data functions and types are now exported directly from the root index.ts
// to avoid circular references

View File

@ -1,164 +0,0 @@
/**
* Sample data utility for agent UI components demonstration
*/
import { AgentStep, AgentSession } from './types';
/**
* Returns an array of sample agent steps
*/
export function getSampleAgentSteps(): AgentStep[] {
return [
{
id: "step-1",
timestamp: new Date(Date.now() - 30 * 60000), // 30 minutes ago
status: 'completed',
type: 'planning',
title: 'Initial Planning',
content: 'I need to analyze the codebase structure to understand the existing components and their relationships.',
duration: 5200
},
{
id: "step-2",
timestamp: new Date(Date.now() - 25 * 60000), // 25 minutes ago
status: 'completed',
type: 'tool-execution',
title: 'List Directory Structure',
content: 'Executing: list_directory_tree(path="src/", max_depth=2)\n\n📁 /project/src/\n├── 📁 components/\n│ ├── 📁 ui/\n│ └── App.tsx\n├── 📁 utils/\n└── index.tsx',
duration: 1800
},
{
id: "step-3",
timestamp: new Date(Date.now() - 20 * 60000), // 20 minutes ago
status: 'completed',
type: 'thinking',
title: 'Component Analysis',
content: 'Based on the directory structure, I see that the UI components are organized in a dedicated folder. I should examine the existing component patterns before implementing new ones.',
duration: 3500
},
{
id: "step-4",
timestamp: new Date(Date.now() - 15 * 60000), // 15 minutes ago
status: 'completed',
type: 'tool-execution',
title: 'Read Component Code',
content: 'Executing: read_file_tool(filepath="src/components/ui/Button.tsx")\n\n```tsx\nimport { cn } from "../../utils";\n\nexport interface ButtonProps {\n // Component props...\n}\n\nexport function Button({ children, ...props }: ButtonProps) {\n // Component implementation...\n}\n```',
duration: 2100
},
{
id: "step-5",
timestamp: new Date(Date.now() - 10 * 60000), // 10 minutes ago
status: 'completed',
type: 'implementation',
title: 'Creating NavBar Component',
content: 'I\'m creating a NavBar component following the design system patterns:\n\n```tsx\nimport { cn } from "../../utils";\n\nexport interface NavBarProps {\n // New component props...\n}\n\nexport function NavBar({ ...props }: NavBarProps) {\n // New component implementation...\n}\n```',
duration: 6800
},
{
id: "step-6",
timestamp: new Date(Date.now() - 5 * 60000), // 5 minutes ago
status: 'in-progress',
type: 'implementation',
title: 'Styling Timeline Component',
content: 'Currently working on styling the Timeline component to match the design system:\n\n```tsx\n// Work in progress...\nexport function Timeline({ steps, ...props }: TimelineProps) {\n // Current implementation...\n}\n```',
},
{
id: "step-7",
timestamp: new Date(Date.now() - 2 * 60000), // 2 minutes ago
status: 'error',
type: 'tool-execution',
title: 'Running Tests',
content: 'Error executing: run_shell_command(command="npm test")\n\nTest failed: TypeError: Cannot read property \'steps\' of undefined',
duration: 3200
},
{
id: "step-8",
timestamp: new Date(), // Now
status: 'pending',
type: 'planning',
title: 'Next Steps',
content: 'Need to plan the implementation of the SessionDrawer component...',
}
];
}
/**
* Returns an array of sample agent sessions
*/
export function getSampleAgentSessions(): AgentSession[] {
const steps = getSampleAgentSteps();
return [
{
id: "session-1",
name: "UI Component Implementation",
created: new Date(Date.now() - 35 * 60000), // 35 minutes ago
updated: new Date(), // Now
status: 'active',
steps: steps
},
{
id: "session-2",
name: "API Integration",
created: new Date(Date.now() - 2 * 3600000), // 2 hours ago
updated: new Date(Date.now() - 30 * 60000), // 30 minutes ago
status: 'completed',
steps: [
{
id: "other-step-1",
timestamp: new Date(Date.now() - 2 * 3600000), // 2 hours ago
status: 'completed',
type: 'planning',
title: 'API Integration Planning',
content: 'Planning the integration with the backend API...',
duration: 4500
},
{
id: "other-step-2",
timestamp: new Date(Date.now() - 1.5 * 3600000), // 1.5 hours ago
status: 'completed',
type: 'implementation',
title: 'Implementing API Client',
content: 'Creating API client with fetch utilities...',
duration: 7200
},
{
id: "other-step-3",
timestamp: new Date(Date.now() - 1 * 3600000), // 1 hour ago
status: 'completed',
type: 'tool-execution',
title: 'Testing API Endpoints',
content: 'Running tests against API endpoints...',
duration: 5000
}
]
},
{
id: "session-3",
name: "Bug Fixes",
created: new Date(Date.now() - 5 * 3600000), // 5 hours ago
updated: new Date(Date.now() - 4 * 3600000), // 4 hours ago
status: 'error',
steps: [
{
id: "bug-step-1",
timestamp: new Date(Date.now() - 5 * 3600000), // 5 hours ago
status: 'completed',
type: 'planning',
title: 'Bug Analysis',
content: 'Analyzing reported bugs from issue tracker...',
duration: 3600
},
{
id: "bug-step-2",
timestamp: new Date(Date.now() - 4.5 * 3600000), // 4.5 hours ago
status: 'error',
type: 'implementation',
title: 'Fixing Authentication Bug',
content: 'Error: Unable to resolve dependency conflict with auth package',
duration: 2500
}
]
}
];
}

View File

@ -1,28 +0,0 @@
/**
* Common types for agent UI components
*/
/**
* Represents a single step in the agent process
*/
export interface AgentStep {
id: string;
timestamp: Date;
status: 'completed' | 'in-progress' | 'error' | 'pending';
type: 'tool-execution' | 'thinking' | 'planning' | 'implementation' | 'user-input';
title: string;
content: string;
duration?: number; // in milliseconds
}
/**
* Represents a session with multiple steps
*/
export interface AgentSession {
id: string;
name: string;
created: Date;
updated: Date;
status: 'active' | 'completed' | 'error';
steps: AgentStep[];
}

Some files were not shown because too many files have changed in this diff Show More