Compare commits
No commits in common. "main" and "master" have entirely different histories.
206 changed files with 10975 additions and 77226 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
name: BotUI CI
|
name: GBCI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
@ -6,37 +6,18 @@ on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: ["main"]
|
branches: ["main"]
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_BUILD_JOBS: 6
|
|
||||||
CARGO_NET_RETRY: 10
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: gbo
|
runs-on: gbo
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Disable SSL verification
|
- name: Disable SSL verification (temporary)
|
||||||
run: git config --global http.sslVerify false
|
run: git config --global http.sslVerify false
|
||||||
|
|
||||||
- name: Setup Workspace
|
- uses: actions/checkout@v4
|
||||||
run: |
|
|
||||||
# Clone the main gb repository
|
|
||||||
git clone --depth 1 --branch main https://alm.pragmatismo.com.br/GeneralBots/gb.git workspace
|
|
||||||
cd workspace
|
|
||||||
git submodule update --init --depth 1 botlib
|
|
||||||
|
|
||||||
# Clone botui separately
|
- name: Clone botlib dependency
|
||||||
git clone --depth 1 --branch main https://alm.pragmatismo.com.br/GeneralBots/botui.git botui
|
run: git clone --depth 1 https://github.com/GeneralBots/botlib.git ../botlib
|
||||||
|
|
||||||
# Remove all members except botui and botlib from workspace
|
|
||||||
sed -i '/"botapp",/d' Cargo.toml
|
|
||||||
sed -i '/"botdevice",/d' Cargo.toml
|
|
||||||
sed -i '/"bottest",/d' Cargo.toml
|
|
||||||
sed -i '/"botserver",/d' Cargo.toml
|
|
||||||
sed -i '/"botbook",/d' Cargo.toml
|
|
||||||
sed -i '/"botmodels",/d' Cargo.toml
|
|
||||||
sed -i '/"botplugin",/d' Cargo.toml
|
|
||||||
sed -i '/"bottemplates",/d' Cargo.toml
|
|
||||||
|
|
||||||
- name: Cache Cargo registry
|
- name: Cache Cargo registry
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
|
@ -44,54 +25,34 @@ jobs:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
~/.cargo/git
|
~/.cargo/git
|
||||||
~/.cache/sccache
|
target
|
||||||
workspace/target
|
key: ${{ runner.os }}-cargo-botui-${{ hashFiles('**/Cargo.lock') }}
|
||||||
key: ${{ runner.os }}-cargo-v2-debug-ui-${{ hashFiles('**/Cargo.lock') }}
|
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-cargo-v2-debug-ui-
|
${{ runner.os }}-cargo-botui-
|
||||||
${{ runner.os }}-cargo-v2-debug-
|
|
||||||
|
|
||||||
- name: Install system dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y libpq-dev libssl-dev liblzma-dev pkg-config
|
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
run: |
|
run: |
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||||
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
echo "/root/.cargo/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Install sccache
|
|
||||||
run: |
|
|
||||||
wget https://github.com/mozilla/sccache/releases/download/v0.8.2/sccache-v0.8.2-x86_64-unknown-linux-musl.tar.gz
|
|
||||||
tar xzf sccache-v0.8.2-x86_64-unknown-linux-musl.tar.gz
|
|
||||||
mv sccache-v0.8.2-x86_64-unknown-linux-musl/sccache $HOME/.cargo/bin/sccache
|
|
||||||
chmod +x $HOME/.cargo/bin/sccache
|
|
||||||
echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV
|
|
||||||
$HOME/.cargo/bin/sccache --start-server || true
|
|
||||||
|
|
||||||
- name: Setup environment
|
- name: Setup environment
|
||||||
run: sudo cp /opt/gbo/bin/system/.env . 2>/dev/null || true
|
|
||||||
|
|
||||||
- name: Build BotUI
|
|
||||||
working-directory: workspace
|
|
||||||
run: |
|
run: |
|
||||||
cargo build --release -p botui --features embed-ui -j 8 2>&1 | tee /tmp/build.log
|
sudo cp /opt/gbo/bin/system/botui.env .env
|
||||||
ls -lh target/release/botui
|
|
||||||
sccache --show-stats || true
|
|
||||||
|
|
||||||
- name: Save build log
|
- name: Build Linux x86_64
|
||||||
if: always()
|
run: /root/.cargo/bin/cargo build --locked --release
|
||||||
run: |
|
|
||||||
sudo mkdir -p /opt/gbo/logs
|
|
||||||
sudo cp /tmp/build.log /opt/gbo/logs/botui-$(date +%Y%m%d-%H%M%S).log || true
|
|
||||||
|
|
||||||
- name: Deploy
|
- name: Prepare release artifacts
|
||||||
working-directory: workspace
|
|
||||||
run: |
|
run: |
|
||||||
lxc exec bot:pragmatismo-system -- systemctl stop ui || true
|
sudo mkdir -p /opt/gbo/releases/botui/linux-x86_64
|
||||||
|
sudo cp ./target/release/botui /opt/gbo/releases/botui/linux-x86_64/ || true
|
||||||
sudo cp target/release/botui /opt/gbo/bin/system/
|
sudo chmod -R 755 /opt/gbo/releases/botui/
|
||||||
sudo chmod +x /opt/gbo/bin/system/botui
|
|
||||||
|
- name: Deploy and restart local service
|
||||||
lxc exec bot:pragmatismo-system -- systemctl start ui || true# CI trigger: Fri Feb 6 10:57:04 AM -03 2026
|
run: |
|
||||||
|
lxc exec bot:pragmatismo-system -- systemctl stop botui
|
||||||
|
|
||||||
|
sudo cp ./target/release/botui /opt/gbo/bin/botui
|
||||||
|
sudo chmod +x /opt/gbo/bin/botui
|
||||||
|
|
||||||
|
lxc exec bot:pragmatismo-system -- systemctl start botui
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "botui"
|
name = "botui"
|
||||||
version = "6.1.2"
|
version = "6.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "General Bots UI - Pure web interface"
|
description = "General Bots UI - Pure web interface"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
|
|
@ -13,10 +13,8 @@ workspace = true
|
||||||
features = ["http-client"]
|
features = ["http-client"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["ui-server", "chat", "drive", "tasks", "admin"]
|
default = ["ui-server", "chat", "drive", "tasks"]
|
||||||
ui-server = []
|
ui-server = []
|
||||||
embed-ui = ["rust-embed"]
|
|
||||||
|
|
||||||
|
|
||||||
# App Features
|
# App Features
|
||||||
chat = []
|
chat = []
|
||||||
|
|
@ -58,10 +56,8 @@ anyhow = { workspace = true }
|
||||||
axum = { workspace = true }
|
axum = { workspace = true }
|
||||||
futures-util = { workspace = true }
|
futures-util = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
mime_guess.workspace = true
|
|
||||||
native-tls = { workspace = true }
|
native-tls = { workspace = true }
|
||||||
reqwest = { workspace = true, features = ["json"] }
|
reqwest = { workspace = true, features = ["json"] }
|
||||||
rust-embed = { workspace = true, optional = true }
|
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["full"] }
|
tokio = { workspace = true, features = ["full"] }
|
||||||
|
|
|
||||||
278
PROMPT.md
Normal file
278
PROMPT.md
Normal file
|
|
@ -0,0 +1,278 @@
|
||||||
|
# BotUI Development Guide
|
||||||
|
|
||||||
|
**Version:** 6.2.0
|
||||||
|
**Purpose:** Web UI server for General Bots (Axum + HTMX + CSS)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ZERO TOLERANCE POLICY
|
||||||
|
|
||||||
|
**EVERY SINGLE WARNING MUST BE FIXED. NO EXCEPTIONS.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ❌ ABSOLUTE PROHIBITIONS
|
||||||
|
|
||||||
|
```
|
||||||
|
❌ NEVER use #![allow()] or #[allow()] in source code
|
||||||
|
❌ NEVER use _ prefix for unused variables - DELETE or USE them
|
||||||
|
❌ NEVER use .unwrap() - use ? or proper error handling
|
||||||
|
❌ NEVER use .expect() - use ? or proper error handling
|
||||||
|
❌ NEVER use panic!() or unreachable!()
|
||||||
|
❌ NEVER use todo!() or unimplemented!()
|
||||||
|
❌ NEVER leave unused imports or dead code
|
||||||
|
❌ NEVER add comments - code must be self-documenting
|
||||||
|
❌ NEVER use CDN links - all assets must be local
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ ARCHITECTURE
|
||||||
|
|
||||||
|
### Dual Modes
|
||||||
|
|
||||||
|
| Mode | Command | Description |
|
||||||
|
|------|---------|-------------|
|
||||||
|
| Web | `cargo run` | Axum server on port 3000 |
|
||||||
|
| Desktop | `cargo tauri dev` | Tauri native window |
|
||||||
|
|
||||||
|
### Code Organization
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── main.rs # Entry point - mode detection
|
||||||
|
├── lib.rs # Feature-gated module exports
|
||||||
|
├── http_client.rs # HTTP wrapper for botserver
|
||||||
|
├── ui_server/
|
||||||
|
│ └── mod.rs # Axum router + UI serving
|
||||||
|
├── desktop/
|
||||||
|
│ ├── mod.rs # Desktop module organization
|
||||||
|
│ ├── drive.rs # File operations via Tauri
|
||||||
|
│ └── tray.rs # System tray
|
||||||
|
└── shared/
|
||||||
|
└── state.rs # Shared application state
|
||||||
|
|
||||||
|
ui/
|
||||||
|
├── suite/ # Main UI (HTML/CSS/JS)
|
||||||
|
│ ├── js/vendor/ # Local JS libraries
|
||||||
|
│ └── css/ # Stylesheets
|
||||||
|
└── minimal/ # Minimal chat UI
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 HTMX-FIRST FRONTEND
|
||||||
|
|
||||||
|
### Core Principle
|
||||||
|
- **Use HTMX** to minimize JavaScript
|
||||||
|
- **Server returns HTML fragments**, not JSON
|
||||||
|
- **Delegate ALL logic** to Rust server
|
||||||
|
|
||||||
|
### HTMX Usage
|
||||||
|
|
||||||
|
| Use Case | Solution |
|
||||||
|
|----------|----------|
|
||||||
|
| Data fetching | `hx-get`, `hx-post` |
|
||||||
|
| Form submission | `hx-post`, `hx-put` |
|
||||||
|
| Real-time updates | `hx-ext="ws"` |
|
||||||
|
| Content swapping | `hx-target`, `hx-swap` |
|
||||||
|
| Polling | `hx-trigger="every 5s"` |
|
||||||
|
| Loading states | `hx-indicator` |
|
||||||
|
|
||||||
|
### When JS is Required
|
||||||
|
|
||||||
|
| Use Case | Why JS Required |
|
||||||
|
|----------|-----------------|
|
||||||
|
| Modal show/hide | DOM manipulation |
|
||||||
|
| Toast notifications | Dynamic element creation |
|
||||||
|
| Clipboard operations | `navigator.clipboard` API |
|
||||||
|
| Keyboard shortcuts | `keydown` event handling |
|
||||||
|
| Complex animations | GSAP or custom |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 LOCAL ASSETS ONLY - NO CDN
|
||||||
|
|
||||||
|
```
|
||||||
|
ui/suite/js/vendor/
|
||||||
|
├── htmx.min.js
|
||||||
|
├── htmx-ws.js
|
||||||
|
├── marked.min.js
|
||||||
|
├── gsap.min.js
|
||||||
|
└── livekit-client.umd.min.js
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- ✅ CORRECT -->
|
||||||
|
<script src="js/vendor/htmx.min.js"></script>
|
||||||
|
|
||||||
|
<!-- ❌ WRONG -->
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 OFFICIAL ICONS - MANDATORY
|
||||||
|
|
||||||
|
**NEVER generate icons with LLM. Use official SVG icons:**
|
||||||
|
|
||||||
|
```
|
||||||
|
ui/suite/assets/icons/
|
||||||
|
├── gb-logo.svg # Main GB logo
|
||||||
|
├── gb-bot.svg # Bot/assistant
|
||||||
|
├── gb-analytics.svg # Analytics
|
||||||
|
├── gb-calendar.svg # Calendar
|
||||||
|
├── gb-chat.svg # Chat
|
||||||
|
├── gb-drive.svg # File storage
|
||||||
|
├── gb-mail.svg # Email
|
||||||
|
├── gb-meet.svg # Video meetings
|
||||||
|
├── gb-tasks.svg # Task management
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
All icons use `stroke="currentColor"` for CSS theming.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔒 SECURITY ARCHITECTURE
|
||||||
|
|
||||||
|
### Centralized Auth Engine
|
||||||
|
|
||||||
|
All authentication is handled by `security-bootstrap.js` which MUST be loaded immediately after HTMX:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<head>
|
||||||
|
<!-- 1. HTMX first -->
|
||||||
|
<script src="js/vendor/htmx.min.js"></script>
|
||||||
|
<script src="js/vendor/htmx-ws.js"></script>
|
||||||
|
|
||||||
|
<!-- 2. Security bootstrap immediately after -->
|
||||||
|
<script src="js/security-bootstrap.js"></script>
|
||||||
|
|
||||||
|
<!-- 3. Other scripts -->
|
||||||
|
<script src="js/api-client.js"></script>
|
||||||
|
</head>
|
||||||
|
```
|
||||||
|
|
||||||
|
### DO NOT Duplicate Auth Logic
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// ❌ WRONG - Don't add auth headers manually
|
||||||
|
fetch("/api/data", {
|
||||||
|
headers: { "Authorization": "Bearer " + token }
|
||||||
|
});
|
||||||
|
|
||||||
|
// ✅ CORRECT - Let security-bootstrap.js handle it
|
||||||
|
fetch("/api/data");
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 DESIGN SYSTEM
|
||||||
|
|
||||||
|
### Layout Standards
|
||||||
|
|
||||||
|
```css
|
||||||
|
.app-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 320px 1fr;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-panel {
|
||||||
|
overflow-y: scroll;
|
||||||
|
scrollbar-width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-panel {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Theme Variables Required
|
||||||
|
|
||||||
|
```css
|
||||||
|
[data-theme="your-theme"] {
|
||||||
|
--bg: #0a0a0a;
|
||||||
|
--surface: #161616;
|
||||||
|
--surface-hover: #1e1e1e;
|
||||||
|
--border: #2a2a2a;
|
||||||
|
--text: #ffffff;
|
||||||
|
--text-secondary: #888888;
|
||||||
|
--primary: #c5f82a;
|
||||||
|
--success: #22c55e;
|
||||||
|
--warning: #f59e0b;
|
||||||
|
--error: #ef4444;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ CODE PATTERNS
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ❌ WRONG
|
||||||
|
let value = something.unwrap();
|
||||||
|
|
||||||
|
// ✅ CORRECT
|
||||||
|
let value = something?;
|
||||||
|
let value = something.ok_or_else(|| Error::NotFound)?;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Self Usage
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl MyStruct {
|
||||||
|
fn new() -> Self { Self { } } // ✅ Not MyStruct
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Format Strings
|
||||||
|
|
||||||
|
```rust
|
||||||
|
format!("Hello {name}") // ✅ Not format!("{}", name)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Derive Eq with PartialEq
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[derive(PartialEq, Eq)] // ✅ Always both
|
||||||
|
struct MyStruct { }
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 KEY DEPENDENCIES
|
||||||
|
|
||||||
|
| Library | Version | Purpose |
|
||||||
|
|---------|---------|---------|
|
||||||
|
| axum | 0.7.5 | Web framework |
|
||||||
|
| reqwest | 0.12 | HTTP client |
|
||||||
|
| tokio | 1.41 | Async runtime |
|
||||||
|
| askama | 0.12 | HTML Templates |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔑 REMEMBER
|
||||||
|
|
||||||
|
- **ZERO WARNINGS** - Every clippy warning must be fixed
|
||||||
|
- **NO ALLOW IN CODE** - Never use #[allow()] in source files
|
||||||
|
- **NO DEAD CODE** - Delete unused code
|
||||||
|
- **NO UNWRAP/EXPECT** - Use ? operator
|
||||||
|
- **HTMX first** - Minimize JS, delegate to server
|
||||||
|
- **Local assets** - No CDN, all vendor files local
|
||||||
|
- **No business logic** - All logic in botserver
|
||||||
|
- **HTML responses** - Server returns fragments, not JSON
|
||||||
|
- **Version 6.2.0** - do not change without approval
|
||||||
317
README.md
317
README.md
|
|
@ -1,314 +1,39 @@
|
||||||
# BotUI - General Bots Web Interface
|
|
||||||
|
|
||||||
**Version:** 6.2.0
|
# General Bots Desktop
|
||||||
**Purpose:** Web UI server for General Bots (Axum + HTMX + CSS)
|
|
||||||
|
|
||||||
---
|
An AI-powered desktop automation tool that records and plays back user interactions useful for legacy systems and common desktop tasks. The BotDesktop automation tool fills a critical gap in the enterprise automation landscape by addressing legacy systems and desktop applications that lack modern APIs or integration capabilities. While botserver excels at creating conversational bots for modern channels like web, mobile and messaging platforms, many organizations still rely heavily on traditional desktop applications, mainframe systems, and custom internal tools that can only be accessed through their user interface. BotDesktop's ability to record and replay user interactions provides a practical bridge between these legacy systems and modern automation needs.
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
BotUI is a modern web interface for General Bots, built with Rust, Axum, and HTMX. It provides a clean, responsive interface for interacting with the General Bots platform, featuring real-time updates via WebSocket connections and a minimalist JavaScript approach powered by HTMX.
|

|
||||||
|
|
||||||
The interface supports multiple features including chat, file management, tasks, calendar, analytics, and more - all served through a fast, efficient Rust backend with a focus on server-rendered HTML and minimal client-side JavaScript.
|
|
||||||
|
|
||||||
For comprehensive documentation, see **[docs.pragmatismo.com.br](https://docs.pragmatismo.com.br)** or the **[BotBook](./botbook)** for detailed guides and API references.
|
The tool's AI-powered approach to desktop automation represents a significant advancement over traditional robotic process automation (RPA) tools. By leveraging machine learning to understand screen elements and user interactions, BotDesktop can adapt to minor UI changes and variations that would break conventional scripted automation. This resilience is particularly valuable in enterprise environments where applications receive regular updates or where slight variations exist between different versions or installations of the same software. The AI component also simplifies the creation of automation scripts - instead of requiring complex programming, users can simply demonstrate the desired actions which BotDesktop observes and learns to replicate.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Quick Start
|
From an integration perspective, BotDesktop complements botserver by enabling end-to-end automation scenarios that span both modern and legacy systems. For example, a bot created in botserver could collect information from users through a modern chat interface, then use BotDesktop to input that data into a legacy desktop application that lacks API access. This hybrid approach allows organizations to modernize their user interactions while still leveraging their existing IT investments. Additionally, BotDesktop can automate routine desktop tasks like file management, data entry, and application monitoring that fall outside the scope of conversational bot interactions.
|
||||||
|
|
||||||
|
|
||||||
|
The combined toolset of botserver and BotDesktop provides organizations with comprehensive automation capabilities across their entire technology stack. While botserver handles the modern, API-driven interactions with users across multiple channels, BotDesktop extends automation capabilities to the desktop environment where many critical business processes still reside. This dual approach allows organizations to progressively modernize their systems while maintaining operational efficiency through automation of both new and legacy components. The result is a more flexible and complete automation solution that can adapt to various technical environments and business needs.
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. Install dependencies:
|
||||||
```bash
|
```bash
|
||||||
# Development mode - starts Axum server on port 9000
|
npm install
|
||||||
cargo run
|
|
||||||
|
|
||||||
# Desktop mode (Tauri) - starts native window
|
|
||||||
cargo tauri dev
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Environment Variables
|
2. Create a .env file with your Azure OpenAI credentials
|
||||||
|
|
||||||
- `BOTUI_PORT` - Server port (default: 9000)
|
3. Development:
|
||||||
|
```bash
|
||||||
---
|
npm run dev
|
||||||
|
|
||||||
## ZERO TOLERANCE POLICY
|
|
||||||
|
|
||||||
**EVERY SINGLE WARNING MUST BE FIXED. NO EXCEPTIONS.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ❌ ABSOLUTE PROHIBITIONS
|
|
||||||
|
|
||||||
```
|
|
||||||
❌ NEVER use #![allow()] or #[allow()] in source code
|
|
||||||
❌ NEVER use _ prefix for unused variables - DELETE or USE them
|
|
||||||
❌ NEVER use .unwrap() - use ? or proper error handling
|
|
||||||
❌ NEVER use .expect() - use ? or proper error handling
|
|
||||||
❌ NEVER use panic!() or unreachable!()
|
|
||||||
❌ NEVER use todo!() or unimplemented!()
|
|
||||||
❌ NEVER leave unused imports or dead code
|
|
||||||
❌ NEVER add comments - code must be self-documenting
|
|
||||||
❌ NEVER use CDN links - all assets must be local
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
4. Build:
|
||||||
|
```bash
|
||||||
## 🏗️ ARCHITECTURE
|
npm run build
|
||||||
|
|
||||||
### Dual Modes
|
|
||||||
|
|
||||||
| Mode | Command | Description |
|
|
||||||
|------|---------|-------------|
|
|
||||||
| Web | `cargo run` | Axum server on port 9000 |
|
|
||||||
| Desktop | `cargo tauri dev` | Tauri native window |
|
|
||||||
|
|
||||||
### Code Organization
|
|
||||||
|
|
||||||
```
|
|
||||||
src/
|
|
||||||
├── main.rs # Entry point - mode detection
|
|
||||||
├── lib.rs # Feature-gated module exports
|
|
||||||
├── http_client.rs # HTTP wrapper for botserver
|
|
||||||
├── ui_server/
|
|
||||||
│ └── mod.rs # Axum router + UI serving
|
|
||||||
├── desktop/
|
|
||||||
│ ├── mod.rs # Desktop module organization
|
|
||||||
│ ├── drive.rs # File operations via Tauri
|
|
||||||
│ └── tray.rs # System tray
|
|
||||||
└── shared/
|
|
||||||
└── state.rs # Shared application state
|
|
||||||
|
|
||||||
ui/
|
|
||||||
├── suite/ # Main UI (HTML/CSS/JS)
|
|
||||||
│ ├── js/vendor/ # Local JS libraries
|
|
||||||
│ └── css/ # Stylesheets
|
|
||||||
└── minimal/ # Minimal chat UI
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
## Testing
|
||||||
|
```bash
|
||||||
## 🎨 HTMX-FIRST FRONTEND
|
npm test
|
||||||
|
|
||||||
### Core Principle
|
|
||||||
- **Use HTMX** to minimize JavaScript
|
|
||||||
- **Server returns HTML fragments**, not JSON
|
|
||||||
- **Delegate ALL logic** to Rust server
|
|
||||||
|
|
||||||
### HTMX Usage
|
|
||||||
|
|
||||||
| Use Case | Solution |
|
|
||||||
|----------|----------|
|
|
||||||
| Data fetching | `hx-get`, `hx-post` |
|
|
||||||
| Form submission | `hx-post`, `hx-put` |
|
|
||||||
| Real-time updates | `hx-ext="ws"` |
|
|
||||||
| Content swapping | `hx-target`, `hx-swap` |
|
|
||||||
| Polling | `hx-trigger="every 5s"` |
|
|
||||||
| Loading states | `hx-indicator` |
|
|
||||||
|
|
||||||
### When JS is Required
|
|
||||||
|
|
||||||
| Use Case | Why JS Required |
|
|
||||||
|----------|-----------------|
|
|
||||||
| Modal show/hide | DOM manipulation |
|
|
||||||
| Toast notifications | Dynamic element creation |
|
|
||||||
| Clipboard operations | `navigator.clipboard` API |
|
|
||||||
| Keyboard shortcuts | `keydown` event handling |
|
|
||||||
| Complex animations | GSAP or custom |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 LOCAL ASSETS ONLY - NO CDN
|
|
||||||
|
|
||||||
```
|
```
|
||||||
ui/suite/js/vendor/
|
|
||||||
├── htmx.min.js
|
|
||||||
├── htmx-ws.js
|
|
||||||
├── marked.min.js
|
|
||||||
├── gsap.min.js
|
|
||||||
└── livekit-client.umd.min.js
|
|
||||||
```
|
|
||||||
|
|
||||||
```html
|
|
||||||
<!-- ✅ CORRECT -->
|
|
||||||
<script src="js/vendor/htmx.min.js"></script>
|
|
||||||
|
|
||||||
<!-- ❌ WRONG -->
|
|
||||||
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 OFFICIAL ICONS - MANDATORY
|
|
||||||
|
|
||||||
**NEVER generate icons with LLM. Use official SVG icons:**
|
|
||||||
|
|
||||||
```
|
|
||||||
ui/suite/assets/icons/
|
|
||||||
├── gb-logo.svg # Main GB logo
|
|
||||||
├── gb-bot.svg # Bot/assistant
|
|
||||||
├── gb-analytics.svg # Analytics
|
|
||||||
├── gb-calendar.svg # Calendar
|
|
||||||
├── gb-chat.svg # Chat
|
|
||||||
├── gb-drive.svg # File storage
|
|
||||||
├── gb-mail.svg # Email
|
|
||||||
├── gb-meet.svg # Video meetings
|
|
||||||
├── gb-tasks.svg # Task management
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
All icons use `stroke="currentColor"` for CSS theming.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔒 SECURITY ARCHITECTURE
|
|
||||||
|
|
||||||
### Centralized Auth Engine
|
|
||||||
|
|
||||||
All authentication is handled by `security-bootstrap.js` which MUST be loaded immediately after HTMX:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<head>
|
|
||||||
<!-- 1. HTMX first -->
|
|
||||||
<script src="js/vendor/htmx.min.js"></script>
|
|
||||||
<script src="js/vendor/htmx-ws.js"></script>
|
|
||||||
|
|
||||||
<!-- 2. Security bootstrap immediately after -->
|
|
||||||
<script src="js/security-bootstrap.js"></script>
|
|
||||||
|
|
||||||
<!-- 3. Other scripts -->
|
|
||||||
<script src="js/api-client.js"></script>
|
|
||||||
</head>
|
|
||||||
```
|
|
||||||
|
|
||||||
### DO NOT Duplicate Auth Logic
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// ❌ WRONG - Don't add auth headers manually
|
|
||||||
fetch("/api/data", {
|
|
||||||
headers: { "Authorization": "Bearer " + token }
|
|
||||||
});
|
|
||||||
|
|
||||||
// ✅ CORRECT - Let security-bootstrap.js handle it
|
|
||||||
fetch("/api/data");
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 DESIGN SYSTEM
|
|
||||||
|
|
||||||
### Layout Standards
|
|
||||||
|
|
||||||
```css
|
|
||||||
.app-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100vh;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-content {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 320px 1fr;
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-panel {
|
|
||||||
overflow-y: scroll;
|
|
||||||
scrollbar-width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-panel {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Theme Variables Required
|
|
||||||
|
|
||||||
```css
|
|
||||||
[data-theme="your-theme"] {
|
|
||||||
--bg: #0a0a0a;
|
|
||||||
--surface: #161616;
|
|
||||||
--surface-hover: #1e1e1e;
|
|
||||||
--border: #2a2a2a;
|
|
||||||
--text: #ffffff;
|
|
||||||
--text-secondary: #888888;
|
|
||||||
--primary: #c5f82a;
|
|
||||||
--success: #22c55e;
|
|
||||||
--warning: #f59e0b;
|
|
||||||
--error: #ef4444;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ CODE PATTERNS
|
|
||||||
|
|
||||||
### Error Handling
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// ❌ WRONG
|
|
||||||
let value = something.unwrap();
|
|
||||||
|
|
||||||
// ✅ CORRECT
|
|
||||||
let value = something?;
|
|
||||||
let value = something.ok_or_else(|| Error::NotFound)?;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Self Usage
|
|
||||||
|
|
||||||
```rust
|
|
||||||
impl MyStruct {
|
|
||||||
fn new() -> Self { Self { } } // ✅ Not MyStruct
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Format Strings
|
|
||||||
|
|
||||||
```rust
|
|
||||||
format!("Hello {name}") // ✅ Not format!("{}", name)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Derive Eq with PartialEq
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#[derive(PartialEq, Eq)] // ✅ Always both
|
|
||||||
struct MyStruct { }
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 KEY DEPENDENCIES
|
|
||||||
|
|
||||||
| Library | Version | Purpose |
|
|
||||||
|---------|---------|---------|
|
|
||||||
| axum | 0.7.5 | Web framework |
|
|
||||||
| reqwest | 0.12 | HTTP client |
|
|
||||||
| tokio | 1.41 | Async runtime |
|
|
||||||
| askama | 0.12 | HTML Templates |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Documentation
|
|
||||||
|
|
||||||
For complete documentation, guides, and API references:
|
|
||||||
|
|
||||||
- **[docs.pragmatismo.com.br](https://docs.pragmatismo.com.br)** - Full online documentation
|
|
||||||
- **[BotBook](./botbook)** - Local comprehensive guide
|
|
||||||
- **[General Bots Repository](https://github.com/GeneralBots/BotServer)** - Main project repository
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔑 REMEMBER
|
|
||||||
|
|
||||||
- **ZERO WARNINGS** - Every clippy warning must be fixed
|
|
||||||
- **NO ALLOW IN CODE** - Never use #[allow()] in source files
|
|
||||||
- **NO DEAD CODE** - Delete unused code
|
|
||||||
- **NO UNWRAP/EXPECT** - Use ? operator
|
|
||||||
- **HTMX first** - Minimize JS, delegate to server
|
|
||||||
- **Local assets** - No CDN, all vendor files local
|
|
||||||
- **No business logic** - All logic in botserver
|
|
||||||
- **HTML responses** - Server returns fragments, not JSON
|
|
||||||
- **Version 6.2.0** - do not change without approval
|
|
||||||
6
build.rs
6
build.rs
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
}
|
||||||
let ui_path = std::path::Path::new(&manifest_dir).join("ui");
|
|
||||||
println!("cargo:rustc-env=BOTUI_UI_PATH={}", ui_path.display());
|
|
||||||
}
|
|
||||||
|
|
|
||||||
262
html3.html
262
html3.html
|
|
@ -1,262 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Dashboard - Build V3</title>
|
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700;800&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
||||||
<script>
|
|
||||||
tailwind.config = {
|
|
||||||
theme: {
|
|
||||||
extend: {
|
|
||||||
fontFamily: {
|
|
||||||
mono: ['"JetBrains Mono"', 'monospace'],
|
|
||||||
sans: ['Inter', 'sans-serif'],
|
|
||||||
},
|
|
||||||
colors: {
|
|
||||||
brand: {
|
|
||||||
50: '#f0fdf4',
|
|
||||||
100: '#dcfce7',
|
|
||||||
200: '#bbf7d0',
|
|
||||||
300: '#86efac',
|
|
||||||
400: '#4ade80',
|
|
||||||
500: '#22c55e',
|
|
||||||
600: '#16a34a',
|
|
||||||
700: '#15803d',
|
|
||||||
800: '#166534',
|
|
||||||
900: '#14532d',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
.app-icon {
|
|
||||||
background: linear-gradient(135deg, #4ade80 0%, #15803d 100%);
|
|
||||||
box-shadow:
|
|
||||||
inset 0px 2px 4px rgba(255,255,255,0.4),
|
|
||||||
inset 0px -2px 4px rgba(0,0,0,0.3),
|
|
||||||
0px 6px 12px rgba(0,0,0,0.15);
|
|
||||||
border: 1px solid #14532d;
|
|
||||||
border-bottom-width: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-bg {
|
|
||||||
background-color: #fafdfa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-grid {
|
|
||||||
background-image: linear-gradient(to right, #f0fdf4 1px, transparent 1px), linear-gradient(to bottom, #f0fdf4 1px, transparent 1px);
|
|
||||||
background-size: 40px 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Custom scrollbar for terminal */
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: #333;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: #555;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body class="h-screen w-screen overflow-hidden flex flex-col bg-[var(--bg,#ffffff)] text-[var(--text,#1f2937)] font-sans selection:bg-brand-200">
|
|
||||||
|
|
||||||
<div class="flex-1 flex overflow-hidden relative">
|
|
||||||
|
|
||||||
<!-- LEFT SIDEBAR -->
|
|
||||||
<aside class="w-14 shrink-0 bg-[var(--bg-secondary,#ffffff)] border-r border-[var(--border-color,#f3f4f6)] flex flex-col items-center py-6 z-20 relative">
|
|
||||||
<div class="flex flex-col space-y-8 text-[var(--text-secondary,#6b7280)]">
|
|
||||||
<button class="hover:text-[var(--primary,#16a34a)] transition-colors"><i class="fa-solid fa-chevron-right"></i></button>
|
|
||||||
<button class="hover:text-[var(--primary,#16a34a)] transition-colors text-xl"><i class="fa-solid fa-house"></i></button>
|
|
||||||
<button class="hover:text-[var(--primary,#16a34a)] transition-colors text-xl"><i class="fa-solid fa-magnifying-glass"></i></button>
|
|
||||||
<button class="hover:text-[var(--primary,#16a34a)] transition-colors text-xl"><i class="fa-solid fa-border-all"></i></button>
|
|
||||||
<button class="hover:text-[var(--primary,#16a34a)] transition-colors text-xl"><i class="fa-regular fa-user"></i></button>
|
|
||||||
<button class="hover:text-[var(--primary,#16a34a)] transition-colors text-xl"><i class="fa-solid fa-layer-group"></i></button>
|
|
||||||
<button class="hover:text-[var(--primary,#16a34a)] transition-colors text-xl"><i class="fa-solid fa-gear"></i></button>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<!-- MAIN CONTENT -->
|
|
||||||
<main class="flex-1 flex flex-col min-w-0 relative z-10">
|
|
||||||
|
|
||||||
<!-- TOP NAVIGATION PATH -->
|
|
||||||
<header class="h-12 shrink-0 bg-[var(--bg,#ffffff)] border-b border-[var(--border-color,#f3f4f6)] flex items-center px-6">
|
|
||||||
<div class="font-mono text-xs font-semibold tracking-wider flex space-x-3 items-center">
|
|
||||||
<span class="text-[var(--text-secondary,#9ca3af)]">// DASHBOARD</span>
|
|
||||||
<span class="text-[var(--text-muted,#d1d5db)]">></span>
|
|
||||||
<span class="text-[var(--text,#1f2937)]">// E-COMMERCE APP DEVELOPMENT</span>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<!-- STAGE NAVIGATION -->
|
|
||||||
<nav class="h-12 shrink-0 bg-[var(--bg,#ffffff)] border-b border-[var(--border-color,#f3f4f6)] flex items-center font-mono text-xs font-semibold z-10">
|
|
||||||
<div class="flex-1 flex justify-center border-r border-[var(--border-color,#f3f4f6)] py-3 hover:bg-[var(--bg-hover,#f9fafb)] cursor-pointer text-[var(--text-secondary,#9ca3af)] transition-colors">
|
|
||||||
// PLAN
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 flex justify-center border-r border-[var(--border-color,#f3f4f6)] py-3 bg-[var(--primary-bg,#f0fdf4)] text-[var(--primary,#16a34a)] cursor-pointer border-b-2 border-b-[var(--primary,#22c55e)] transition-colors shadow-[inset_0_2px_4px_rgba(34,197,94,0.05)]">
|
|
||||||
// BUILD
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 flex justify-center border-r border-[var(--border-color,#f3f4f6)] py-3 hover:bg-[var(--bg-hover,#f9fafb)] cursor-pointer text-[var(--text-secondary,#9ca3af)] transition-colors">
|
|
||||||
// REVIEW
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 flex justify-center border-r border-[var(--border-color,#f3f4f6)] py-3 hover:bg-[var(--bg-hover,#f9fafb)] cursor-pointer text-[var(--text-secondary,#9ca3af)] transition-colors">
|
|
||||||
// DEPLOY
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 flex justify-center py-3 hover:bg-[var(--bg-hover,#f9fafb)] cursor-pointer text-[var(--text-secondary,#9ca3af)] transition-colors">
|
|
||||||
// MONITOR
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<!-- WORKSPACE AREA -->
|
|
||||||
<div class="flex-1 relative overflow-hidden workspace-bg workspace-grid">
|
|
||||||
|
|
||||||
<!-- Subtly styled background lines mimicking the design's large cells -->
|
|
||||||
<svg class="absolute inset-0 w-full h-full pointer-events-none" preserveAspectRatio="none" viewBox="0 0 1000 800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M-100,200 Q200,200 300,50 T300,-100" stroke="#dcfce7" stroke-width="24" stroke-linecap="round" fill="none" opacity="0.6"/>
|
|
||||||
<path d="M300,50 Q450,300 650,200 T1000,100" stroke="#dcfce7" stroke-width="28" stroke-linecap="round" fill="none" opacity="0.6"/>
|
|
||||||
<path d="M200,900 Q300,500 600,600 T1200,500" stroke="#dcfce7" stroke-width="20" stroke-linecap="round" fill="none" opacity="0.6"/>
|
|
||||||
<path d="M650,200 Q500,450 600,600" stroke="#dcfce7" stroke-width="26" stroke-linecap="round" fill="none" opacity="0.6"/>
|
|
||||||
<path d="M300,900 Q200,500 -100,600" stroke="#dcfce7" stroke-width="24" stroke-linecap="round" fill="none" opacity="0.6"/>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<!-- Desktop Icons Grid -->
|
|
||||||
<div class="absolute top-10 left-8 flex flex-col space-y-7 z-10">
|
|
||||||
<!-- Mantis -->
|
|
||||||
<div class="flex flex-col items-center w-20 group cursor-pointer">
|
|
||||||
<div class="app-icon w-16 h-16 rounded-xl flex items-center justify-center text-white text-3xl group-hover:scale-105 transition-transform">
|
|
||||||
<i class="fa-solid fa-microchip drop-shadow-md"></i>
|
|
||||||
</div>
|
|
||||||
<span class="mt-2 text-xs font-mono font-medium text-gray-800 bg-white/70 px-1.5 py-0.5 rounded backdrop-blur-sm">Mantis</span>
|
|
||||||
</div>
|
|
||||||
<!-- Tasks -->
|
|
||||||
<div class="flex flex-col items-center w-20 group cursor-pointer">
|
|
||||||
<div class="app-icon w-16 h-16 rounded-xl flex items-center justify-center text-white text-3xl group-hover:scale-105 transition-transform">
|
|
||||||
<i class="fa-solid fa-clipboard-list drop-shadow-md"></i>
|
|
||||||
</div>
|
|
||||||
<span class="mt-2 text-xs font-mono font-medium text-gray-800 bg-white/70 px-1.5 py-0.5 rounded backdrop-blur-sm">Tasks</span>
|
|
||||||
</div>
|
|
||||||
<!-- Chat -->
|
|
||||||
<div class="flex flex-col items-center w-20 group cursor-pointer">
|
|
||||||
<div class="app-icon w-16 h-16 rounded-xl flex items-center justify-center text-white text-3xl group-hover:scale-105 transition-transform">
|
|
||||||
<i class="fa-solid fa-comment-dots drop-shadow-md"></i>
|
|
||||||
</div>
|
|
||||||
<span class="mt-2 text-xs font-mono font-medium text-gray-800 bg-white/70 px-1.5 py-0.5 rounded backdrop-blur-sm">Chat</span>
|
|
||||||
</div>
|
|
||||||
<!-- Terminal -->
|
|
||||||
<div class="flex flex-col items-center w-20 group cursor-pointer">
|
|
||||||
<div class="app-icon w-16 h-16 rounded-xl flex items-center justify-center text-white text-3xl group-hover:scale-105 transition-transform">
|
|
||||||
<i class="fa-solid fa-terminal drop-shadow-md"></i>
|
|
||||||
</div>
|
|
||||||
<span class="mt-2 text-xs font-mono font-medium text-gray-800 bg-white/70 px-1.5 py-0.5 rounded backdrop-blur-sm">Terminal</span>
|
|
||||||
</div>
|
|
||||||
<!-- Explorer -->
|
|
||||||
<div class="flex flex-col items-center w-20 group cursor-pointer">
|
|
||||||
<div class="app-icon w-16 h-16 rounded-xl flex items-center justify-center text-white text-3xl group-hover:scale-105 transition-transform">
|
|
||||||
<i class="fa-regular fa-folder-open drop-shadow-md"></i>
|
|
||||||
</div>
|
|
||||||
<span class="mt-2 text-xs font-mono font-medium text-gray-800 bg-white/70 px-1.5 py-0.5 rounded backdrop-blur-sm">Explorer</span>
|
|
||||||
</div>
|
|
||||||
<!-- Editor -->
|
|
||||||
<div class="flex flex-col items-center w-20 group cursor-pointer">
|
|
||||||
<div class="app-icon w-16 h-16 rounded-xl flex items-center justify-center text-white text-3xl group-hover:scale-105 transition-transform">
|
|
||||||
<i class="fa-solid fa-code drop-shadow-md"></i>
|
|
||||||
</div>
|
|
||||||
<span class="mt-2 text-xs font-mono font-medium text-gray-800 bg-white/70 px-1.5 py-0.5 rounded backdrop-blur-sm">Editor</span>
|
|
||||||
</div>
|
|
||||||
<!-- Browser -->
|
|
||||||
<div class="flex flex-col items-center w-20 group cursor-pointer">
|
|
||||||
<div class="app-icon w-16 h-16 rounded-xl flex items-center justify-center text-white text-3xl group-hover:scale-105 transition-transform">
|
|
||||||
<i class="fa-regular fa-compass drop-shadow-md"></i>
|
|
||||||
</div>
|
|
||||||
<span class="mt-2 text-xs font-mono font-medium text-gray-800 bg-white/70 px-1.5 py-0.5 rounded backdrop-blur-sm">Browser</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Floating Terminal Window -->
|
|
||||||
<div class="absolute bottom-12 left-40 w-[700px] bg-white rounded-lg shadow-2xl flex flex-col border border-gray-200 overflow-hidden z-20 hover:shadow-[0_25px_50px_rgba(0,0,0,0.15)] transition-shadow">
|
|
||||||
<!-- Window Header -->
|
|
||||||
<div class="h-10 bg-white/95 backdrop-blur flex items-center justify-between px-4 border-b border-gray-200 select-none cursor-move">
|
|
||||||
<div class="font-mono text-xs font-bold text-brand-600 tracking-wide flex items-center space-x-2">
|
|
||||||
<span>// TERMINAL</span>
|
|
||||||
</div>
|
|
||||||
<!-- Window Controls -->
|
|
||||||
<div class="flex space-x-3 text-gray-400">
|
|
||||||
<button class="hover:text-gray-600 transition-colors"><i class="fa-solid fa-minus"></i></button>
|
|
||||||
<button class="hover:text-gray-600 transition-colors"><i class="fa-regular fa-square"></i></button>
|
|
||||||
<button class="hover:text-red-500 transition-colors"><i class="fa-solid fa-xmark"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Window Body -->
|
|
||||||
<div class="bg-[#1a1a1a] p-6 font-mono text-sm leading-relaxed overflow-y-auto h-[260px]">
|
|
||||||
<div class="text-gray-300 whitespace-pre font-medium"> - @types/node
|
|
||||||
- @types/react
|
|
||||||
- @types/react-dom
|
|
||||||
- postcss
|
|
||||||
- tailwindcss
|
|
||||||
- eslint
|
|
||||||
- eslint-config-next
|
|
||||||
|
|
||||||
... [Success] Created project at /home/ecommerceapp
|
|
||||||
<span class="text-brand-400">▶</span> Initializing git repository...
|
|
||||||
<span class="text-brand-400">▶</span> Installing Prisma...
|
|
||||||
<span class="text-white">npm</span> install prisma --save-dev
|
|
||||||
<span class="text-white">npx</span> prisma init --datasource-provider sqlite</div>
|
|
||||||
<div class="mt-1 flex items-center">
|
|
||||||
<span class="text-brand-400 mr-2">/home/ecommerceapp $</span>
|
|
||||||
<div class="w-2.5 h-4 bg-brand-400 animate-pulse inline-block"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- BOTTOM TASKBAR -->
|
|
||||||
<footer class="h-14 shrink-0 bg-white/95 backdrop-blur-md border-t border-gray-200 flex items-center justify-between px-4 z-30 relative shadow-[0_-2px_10px_rgba(0,0,0,0.02)]">
|
|
||||||
|
|
||||||
<!-- Open Apps -->
|
|
||||||
<div class="flex items-center space-x-2 h-full pt-1">
|
|
||||||
<div class="h-10 w-12 flex items-center justify-center cursor-pointer hover:bg-gray-100 rounded border-b-2 border-transparent hover:border-brand-500 transition-all">
|
|
||||||
<div class="app-icon w-8 h-8 rounded-md flex items-center justify-center text-white text-xs shadow-sm">
|
|
||||||
<i class="fa-regular fa-folder-open"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="h-10 w-12 flex items-center justify-center cursor-pointer bg-brand-50 rounded border-b-2 border-brand-500 transition-all">
|
|
||||||
<div class="app-icon w-8 h-8 rounded-md flex items-center justify-center text-white text-xs shadow-sm">
|
|
||||||
<i class="fa-solid fa-terminal"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="h-10 w-12 flex items-center justify-center cursor-pointer hover:bg-gray-100 rounded border-b-2 border-transparent hover:border-brand-500 transition-all">
|
|
||||||
<div class="app-icon w-8 h-8 rounded-md flex items-center justify-center text-white text-xs shadow-sm">
|
|
||||||
<i class="fa-solid fa-comment-dots"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- System Tray -->
|
|
||||||
<div class="flex items-center space-x-6">
|
|
||||||
<div class="text-brand-400 text-xl opacity-80 cursor-help hover:text-brand-600 transition-colors">
|
|
||||||
<i class="fa-brands fa-envira"></i>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col items-end font-mono text-[11px] text-gray-800 tracking-tight leading-[1.3] mr-2">
|
|
||||||
<span class="font-bold text-[13px]">21:20</span>
|
|
||||||
<span class="text-gray-500">01/01/2026</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -153,7 +153,7 @@
|
||||||
<script>
|
<script>
|
||||||
// Configuration
|
// Configuration
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
serverUrl: window.BOTSERVER_URL || 'http://localhost:8080',
|
serverUrl: window.BOTSERVER_URL || 'http://localhost:8088',
|
||||||
maxMessages: 10, // Keep memory low
|
maxMessages: 10, // Keep memory low
|
||||||
maxMsgLen: 100, // Truncate long messages
|
maxMsgLen: 100, // Truncate long messages
|
||||||
};
|
};
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,73 +0,0 @@
|
||||||
/* Dark Theme for General Bots */
|
|
||||||
:root {
|
|
||||||
--color-primary: #d4f505;
|
|
||||||
--color-secondary: #00d4aa;
|
|
||||||
--color-accent: #818cf8;
|
|
||||||
|
|
||||||
--color-bg: #0f172a;
|
|
||||||
--color-bg-secondary: #1e293b;
|
|
||||||
--color-bg-tertiary: #334155;
|
|
||||||
|
|
||||||
--color-text: #f1f5f9;
|
|
||||||
--color-text-secondary: #cbd5e1;
|
|
||||||
--color-text-muted: #64748b;
|
|
||||||
|
|
||||||
--color-border: #334155;
|
|
||||||
--color-border-light: #1e293b;
|
|
||||||
|
|
||||||
--color-success: #22c55e;
|
|
||||||
--color-warning: #f59e0b;
|
|
||||||
--color-error: #ef4444;
|
|
||||||
--color-info: #3b82f6;
|
|
||||||
|
|
||||||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3);
|
|
||||||
--shadow: 0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.4);
|
|
||||||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4);
|
|
||||||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.5), 0 4px 6px -4px rgb(0 0 0 / 0.5);
|
|
||||||
|
|
||||||
--radius-sm: 0.25rem;
|
|
||||||
--radius: 0.375rem;
|
|
||||||
--radius-md: 0.5rem;
|
|
||||||
--radius-lg: 0.75rem;
|
|
||||||
--radius-xl: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: var(--color-bg);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--color-accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: var(--color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
background-color: var(--color-primary);
|
|
||||||
color: var(--color-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
background-color: var(--color-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background-color: var(--color-bg-secondary);
|
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
box-shadow: var(--shadow-sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
input, textarea, select {
|
|
||||||
background-color: var(--color-bg-secondary);
|
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
input:focus, textarea:focus, select:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: var(--color-primary);
|
|
||||||
box-shadow: 0 0 0 3px rgba(212, 245, 5, 0.1);
|
|
||||||
}
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
/* Light Theme for General Bots */
|
|
||||||
:root {
|
|
||||||
--color-primary: #d4f505;
|
|
||||||
--color-secondary: #00d4aa;
|
|
||||||
--color-accent: #6366f1;
|
|
||||||
|
|
||||||
--color-bg: #ffffff;
|
|
||||||
--color-bg-secondary: #f8fafc;
|
|
||||||
--color-bg-tertiary: #f1f5f9;
|
|
||||||
|
|
||||||
--color-text: #0f172a;
|
|
||||||
--color-text-secondary: #475569;
|
|
||||||
--color-text-muted: #94a3b8;
|
|
||||||
|
|
||||||
--color-border: #e2e8f0;
|
|
||||||
--color-border-light: #f1f5f9;
|
|
||||||
|
|
||||||
--color-success: #22c55e;
|
|
||||||
--color-warning: #f59e0b;
|
|
||||||
--color-error: #ef4444;
|
|
||||||
--color-info: #3b82f6;
|
|
||||||
|
|
||||||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
||||||
--shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
||||||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
||||||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
||||||
|
|
||||||
--radius-sm: 0.25rem;
|
|
||||||
--radius: 0.375rem;
|
|
||||||
--radius-md: 0.5rem;
|
|
||||||
--radius-lg: 0.75rem;
|
|
||||||
--radius-xl: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: var(--color-bg);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--color-accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: var(--color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
background-color: var(--color-primary);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
background-color: var(--color-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background-color: var(--color-bg);
|
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
box-shadow: var(--shadow-sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
input, textarea, select {
|
|
||||||
background-color: var(--color-bg);
|
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
input:focus, textarea:focus, select:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: var(--color-primary);
|
|
||||||
box-shadow: 0 0 0 3px rgba(212, 245, 5, 0.1);
|
|
||||||
}
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
/* Y2K Glow Theme for General Bots */
|
|
||||||
:root {
|
|
||||||
--color-primary: #ff00ff;
|
|
||||||
--color-secondary: #00ffff;
|
|
||||||
--color-accent: #ffff00;
|
|
||||||
|
|
||||||
--color-bg: #0a0a1a;
|
|
||||||
--color-bg-secondary: #1a0a2e;
|
|
||||||
--color-bg-tertiary: #2d1b4e;
|
|
||||||
|
|
||||||
--color-text: #00ff00;
|
|
||||||
--color-text-secondary: #ff00ff;
|
|
||||||
--color-text-muted: #00ffff;
|
|
||||||
|
|
||||||
--color-border: #ff00ff;
|
|
||||||
--color-border-light: #00ffff;
|
|
||||||
|
|
||||||
--color-success: #00ff00;
|
|
||||||
--color-warning: #ffff00;
|
|
||||||
--color-error: #ff0066;
|
|
||||||
--color-info: #00ffff;
|
|
||||||
|
|
||||||
--shadow-glow: 0 0 10px #ff00ff, 0 0 20px #ff00ff, 0 0 30px #ff00ff;
|
|
||||||
--shadow-sm: 0 0 5px rgba(255, 0, 255, 0.5);
|
|
||||||
--shadow: 0 0 10px rgba(255, 0, 255, 0.7);
|
|
||||||
--shadow-md: 0 0 15px rgba(255, 0, 255, 0.8);
|
|
||||||
--shadow-lg: 0 0 25px rgba(255, 0, 255, 0.9);
|
|
||||||
|
|
||||||
--radius-sm: 0.25rem;
|
|
||||||
--radius: 0.375rem;
|
|
||||||
--radius-md: 0.5rem;
|
|
||||||
--radius-lg: 0.75rem;
|
|
||||||
--radius-xl: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: var(--color-bg);
|
|
||||||
color: var(--color-text);
|
|
||||||
text-shadow: 0 0 5px var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--color-secondary);
|
|
||||||
text-shadow: 0 0 5px var(--color-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: var(--color-primary);
|
|
||||||
text-shadow: 0 0 10px var(--color-primary), 0 0 20px var(--color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
background: linear-gradient(45deg, var(--color-primary), var(--color-secondary));
|
|
||||||
color: var(--color-bg);
|
|
||||||
border: 2px solid var(--color-primary);
|
|
||||||
box-shadow: var(--shadow-glow);
|
|
||||||
text-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
background: linear-gradient(45deg, var(--color-secondary), var(--color-accent));
|
|
||||||
border-color: var(--color-secondary);
|
|
||||||
box-shadow: 0 0 15px var(--color-secondary), 0 0 30px var(--color-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background: linear-gradient(135deg, var(--color-bg-secondary), var(--color-bg-tertiary));
|
|
||||||
border: 2px solid var(--color-primary);
|
|
||||||
box-shadow: var(--shadow);
|
|
||||||
animation: glow 2s ease-in-out infinite alternate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes glow {
|
|
||||||
from {
|
|
||||||
box-shadow: 0 0 5px var(--color-primary), 0 0 10px var(--color-primary);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
box-shadow: 0 0 10px var(--color-secondary), 0 0 20px var(--color-secondary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input, textarea, select {
|
|
||||||
background: var(--color-bg-secondary);
|
|
||||||
border: 2px solid var(--color-border);
|
|
||||||
color: var(--color-text);
|
|
||||||
box-shadow: 0 0 5px var(--color-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
input:focus, textarea:focus, select:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: var(--color-accent);
|
|
||||||
box-shadow: 0 0 10px var(--color-accent), 0 0 20px var(--color-accent), 0 0 30px var(--color-accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input::placeholder, textarea::placeholder {
|
|
||||||
color: var(--color-text-muted);
|
|
||||||
text-shadow: 0 0 3px var(--color-text-muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background: var(--color-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: linear-gradient(var(--color-primary), var(--color-secondary));
|
|
||||||
border-radius: 6px;
|
|
||||||
box-shadow: 0 0 10px var(--color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: linear-gradient(var(--color-secondary), var(--color-accent));
|
|
||||||
}
|
|
||||||
|
|
@ -172,7 +172,7 @@
|
||||||
<div class="activity-list" hx-get="/api/admin/dashboard/activity" hx-trigger="load" hx-swap="innerHTML">
|
<div class="activity-list" hx-get="/api/admin/dashboard/activity" hx-trigger="load" hx-swap="innerHTML">
|
||||||
<div class="activity-item">
|
<div class="activity-item">
|
||||||
<div class="activity-avatar">
|
<div class="activity-avatar">
|
||||||
<img src="/suite/assets/avatars/default.svg" alt="User avatar">
|
<img src="/assets/avatars/default.svg" alt="User avatar">
|
||||||
</div>
|
</div>
|
||||||
<div class="activity-content">
|
<div class="activity-content">
|
||||||
<div class="activity-text">
|
<div class="activity-text">
|
||||||
|
|
@ -198,7 +198,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="activity-item">
|
<div class="activity-item">
|
||||||
<div class="activity-avatar">
|
<div class="activity-avatar">
|
||||||
<img src="/suite/assets/avatars/default.svg" alt="User avatar">
|
<img src="/assets/avatars/default.svg" alt="User avatar">
|
||||||
</div>
|
</div>
|
||||||
<div class="activity-content">
|
<div class="activity-content">
|
||||||
<div class="activity-text">
|
<div class="activity-text">
|
||||||
|
|
@ -222,7 +222,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="activity-item">
|
<div class="activity-item">
|
||||||
<div class="activity-avatar">
|
<div class="activity-avatar">
|
||||||
<img src="/suite/assets/avatars/default.svg" alt="User avatar">
|
<img src="/assets/avatars/default.svg" alt="User avatar">
|
||||||
</div>
|
</div>
|
||||||
<div class="activity-content">
|
<div class="activity-content">
|
||||||
<div class="activity-text">
|
<div class="activity-text">
|
||||||
|
|
@ -274,7 +274,7 @@
|
||||||
<div class="member-list" hx-get="/api/admin/dashboard/members" hx-trigger="load" hx-swap="innerHTML">
|
<div class="member-list" hx-get="/api/admin/dashboard/members" hx-trigger="load" hx-swap="innerHTML">
|
||||||
<div class="member-item">
|
<div class="member-item">
|
||||||
<div class="member-avatar">
|
<div class="member-avatar">
|
||||||
<img src="/suite/assets/avatars/default.svg" alt="User avatar">
|
<img src="/assets/avatars/default.svg" alt="User avatar">
|
||||||
<span class="status-indicator online"></span>
|
<span class="status-indicator online"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="member-info">
|
<div class="member-info">
|
||||||
|
|
@ -285,7 +285,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="member-item">
|
<div class="member-item">
|
||||||
<div class="member-avatar">
|
<div class="member-avatar">
|
||||||
<img src="/suite/assets/avatars/default.svg" alt="User avatar">
|
<img src="/assets/avatars/default.svg" alt="User avatar">
|
||||||
<span class="status-indicator online"></span>
|
<span class="status-indicator online"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="member-info">
|
<div class="member-info">
|
||||||
|
|
@ -296,7 +296,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="member-item">
|
<div class="member-item">
|
||||||
<div class="member-avatar">
|
<div class="member-avatar">
|
||||||
<img src="/suite/assets/avatars/default.svg" alt="User avatar">
|
<img src="/assets/avatars/default.svg" alt="User avatar">
|
||||||
<span class="status-indicator away"></span>
|
<span class="status-indicator away"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="member-info">
|
<div class="member-info">
|
||||||
|
|
@ -307,7 +307,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="member-item">
|
<div class="member-item">
|
||||||
<div class="member-avatar">
|
<div class="member-avatar">
|
||||||
<img src="/suite/assets/avatars/default.svg" alt="User avatar">
|
<img src="/assets/avatars/default.svg" alt="User avatar">
|
||||||
<span class="status-indicator offline"></span>
|
<span class="status-indicator offline"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="member-info">
|
<div class="member-info">
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="wizard-container">
|
<div class="wizard-container">
|
||||||
<div class="wizard-sidebar">
|
<div class="wizard-sidebar">
|
||||||
<div class="wizard-logo">
|
<div class="wizard-logo">
|
||||||
<img src="/suite/assets/icons/gb-logo.svg" alt="General Bots" width="48" height="48">
|
<img src="/assets/icons/gb-logo.svg" alt="General Bots" width="48" height="48">
|
||||||
</div>
|
</div>
|
||||||
<div class="wizard-steps">
|
<div class="wizard-steps">
|
||||||
<div class="wizard-step active" data-step="1">
|
<div class="wizard-step active" data-step="1">
|
||||||
|
|
|
||||||
|
|
@ -1322,6 +1322,7 @@
|
||||||
"WebSocket connected for attendant:",
|
"WebSocket connected for attendant:",
|
||||||
currentAttendantId,
|
currentAttendantId,
|
||||||
);
|
);
|
||||||
|
reconnectAttempts = 0;
|
||||||
showToast(
|
showToast(
|
||||||
"Connected to notification service",
|
"Connected to notification service",
|
||||||
"success",
|
"success",
|
||||||
|
|
@ -1366,7 +1367,6 @@
|
||||||
switch (msgType) {
|
switch (msgType) {
|
||||||
case "connected":
|
case "connected":
|
||||||
console.log("WebSocket connected:", data.message);
|
console.log("WebSocket connected:", data.message);
|
||||||
reconnectAttempts = 0;
|
|
||||||
break;
|
break;
|
||||||
case "new_conversation":
|
case "new_conversation":
|
||||||
showToast("New conversation in queue", "info");
|
showToast("New conversation in queue", "info");
|
||||||
|
|
|
||||||
|
|
@ -283,7 +283,7 @@
|
||||||
<body>
|
<body>
|
||||||
<div class="setup-container">
|
<div class="setup-container">
|
||||||
<div class="setup-header">
|
<div class="setup-header">
|
||||||
<div class="setup-logo"><img src="/suite/assets/icons/gb-logo.svg" alt="General Bots" width="48" height="48"></div>
|
<div class="setup-logo">🤖</div>
|
||||||
<h1 class="setup-title">Initial Setup</h1>
|
<h1 class="setup-title">Initial Setup</h1>
|
||||||
<p class="setup-subtitle">
|
<p class="setup-subtitle">
|
||||||
Create the first administrator account for your General Bots installation
|
Create the first administrator account for your General Bots installation
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Login - General Bots</title>
|
<title>Login - General Bots</title>
|
||||||
<script src="/suite/js/vendor/htmx.min.js"></script>
|
<script src="/js/vendor/htmx.min.js"></script>
|
||||||
<script src="/suite/js/vendor/htmx-json-enc.js"></script>
|
<script src="/js/vendor/htmx-json-enc.js"></script>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--primary: #3b82f6;
|
--primary: #3b82f6;
|
||||||
|
|
@ -75,18 +75,6 @@
|
||||||
box-shadow: 0 8px 32px rgba(59, 130, 246, 0.3);
|
box-shadow: 0 8px 32px rgba(59, 130, 246, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-logo img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: contain;
|
|
||||||
border-radius: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-logo:has(img[src]) {
|
|
||||||
background: transparent;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-title {
|
.login-title {
|
||||||
font-size: 1.75rem;
|
font-size: 1.75rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|
@ -597,12 +585,9 @@
|
||||||
<body>
|
<body>
|
||||||
<div class="login-container">
|
<div class="login-container">
|
||||||
<div class="login-header">
|
<div class="login-header">
|
||||||
<div class="login-logo" id="login-logo">
|
<div class="login-logo">🤖</div>
|
||||||
<img id="login-logo-img" src="" alt="Logo" style="display:none; width:100%; height:100%; object-fit:contain;">
|
<h1 class="login-title">Welcome Back</h1>
|
||||||
<span id="login-logo-default"><img src="/suite/assets/icons/gb-logo.svg" alt="General Bots" width="48" height="48"></span>
|
<p class="login-subtitle">
|
||||||
</div>
|
|
||||||
<h1 class="login-title" id="login-title">Welcome Back</h1>
|
|
||||||
<p class="login-subtitle" id="login-subtitle">
|
|
||||||
Sign in to your General Bots account
|
Sign in to your General Bots account
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1033,55 +1018,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Load bot config and apply logo/title
|
|
||||||
async function loadBotConfig() {
|
|
||||||
try {
|
|
||||||
// Get bot name from URL path
|
|
||||||
const pathParts = window.location.pathname.split('/');
|
|
||||||
const botName = pathParts[1] || 'default';
|
|
||||||
|
|
||||||
// Fetch bot config
|
|
||||||
const response = await fetch(`/api/bot/config?bot_name=${botName}`);
|
|
||||||
if (response.ok) {
|
|
||||||
const config = await response.json();
|
|
||||||
|
|
||||||
// Apply logo if provided
|
|
||||||
const logo = config.theme_logo || config["theme-logo"] || "";
|
|
||||||
if (logo) {
|
|
||||||
const logoImg = document.getElementById("login-logo-img");
|
|
||||||
const logoDefault = document.getElementById("login-logo-default");
|
|
||||||
const logoContainer = document.getElementById("login-logo");
|
|
||||||
|
|
||||||
if (logoImg) {
|
|
||||||
logoImg.src = logo;
|
|
||||||
logoImg.style.display = "block";
|
|
||||||
}
|
|
||||||
if (logoDefault) {
|
|
||||||
logoDefault.style.display = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply title if provided
|
|
||||||
const title = config.theme_title || config["theme-title"] || "";
|
|
||||||
if (title) {
|
|
||||||
const titleEl = document.getElementById("login-title");
|
|
||||||
if (titleEl) {
|
|
||||||
titleEl.textContent = title;
|
|
||||||
}
|
|
||||||
const subtitleEl = document.getElementById("login-subtitle");
|
|
||||||
if (subtitleEl) {
|
|
||||||
subtitleEl.textContent = "Sign in to your account";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Could not load bot config:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load bot config on page load
|
|
||||||
loadBotConfig();
|
|
||||||
|
|
||||||
// Password visibility toggle
|
// Password visibility toggle
|
||||||
function togglePassword() {
|
function togglePassword() {
|
||||||
const passwordInput = document.getElementById("password");
|
const passwordInput = document.getElementById("password");
|
||||||
|
|
@ -1328,18 +1264,12 @@
|
||||||
|
|
||||||
// Successful login - redirect
|
// Successful login - redirect
|
||||||
if (response.redirect || response.success) {
|
if (response.redirect || response.success) {
|
||||||
// Check for redirect parameter in URL
|
window.location.href = response.redirect || "/";
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
const redirectUrl = urlParams.get('redirect') || response.redirect;
|
|
||||||
window.location.href = redirectUrl ? redirectUrl : window.location.origin + "/#chat";
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// If response is not JSON, check for redirect header
|
// If response is not JSON, check for redirect header
|
||||||
if (event.detail.xhr.status === 200) {
|
if (event.detail.xhr.status === 200) {
|
||||||
// Check for redirect parameter in URL
|
window.location.href = "/";
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
const redirectUrl = urlParams.get('redirect');
|
|
||||||
window.location.href = redirectUrl ? redirectUrl : window.location.origin + "/#chat";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -557,7 +557,7 @@
|
||||||
<body>
|
<body>
|
||||||
<div class="register-container">
|
<div class="register-container">
|
||||||
<div class="register-header">
|
<div class="register-header">
|
||||||
<div class="register-logo"><img src="/suite/assets/icons/gb-logo.svg" alt="General Bots" width="48" height="48"></div>
|
<div class="register-logo">🤖</div>
|
||||||
<h1 class="register-title">Create Account</h1>
|
<h1 class="register-title">Create Account</h1>
|
||||||
<p class="register-subtitle">
|
<p class="register-subtitle">
|
||||||
Join General Bots and start building
|
Join General Bots and start building
|
||||||
|
|
|
||||||
983
ui/suite/base-layout-preview.html
Normal file
983
ui/suite/base-layout-preview.html
Normal file
|
|
@ -0,0 +1,983 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="pt-BR">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>BotUI Suite - Base Layout Preview</title>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
/* =============================================================================
|
||||||
|
SENTIENT THEME VARIABLES
|
||||||
|
============================================================================= */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--sentient-bg-primary: #0a0a0a;
|
||||||
|
--sentient-bg-secondary: #111111;
|
||||||
|
--sentient-bg-tertiary: #1a1a1a;
|
||||||
|
--sentient-bg-card: #141414;
|
||||||
|
--sentient-bg-hover: #1f1f1f;
|
||||||
|
--sentient-accent: #c5f82a;
|
||||||
|
--sentient-accent-dim: rgba(197, 248, 42, 0.15);
|
||||||
|
--sentient-accent-glow: rgba(197, 248, 42, 0.3);
|
||||||
|
--sentient-success: #22c55e;
|
||||||
|
--sentient-warning: #f59e0b;
|
||||||
|
--sentient-error: #ef4444;
|
||||||
|
--sentient-info: #3b82f6;
|
||||||
|
--sentient-text-primary: #ffffff;
|
||||||
|
--sentient-text-secondary: #a1a1a1;
|
||||||
|
--sentient-text-muted: #6b6b6b;
|
||||||
|
--sentient-border: #2a2a2a;
|
||||||
|
--sentient-border-hover: #3a3a3a;
|
||||||
|
--sentient-radius-sm: 6px;
|
||||||
|
--sentient-radius-md: 10px;
|
||||||
|
--sentient-radius-lg: 16px;
|
||||||
|
--sentient-font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: var(--sentient-font-family);
|
||||||
|
background: var(--sentient-bg-primary);
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
LAYOUT
|
||||||
|
============================================================================= */
|
||||||
|
|
||||||
|
.suite-app {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.suite-topbar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: var(--sentient-bg-primary);
|
||||||
|
border-bottom: 1px solid var(--sentient-border);
|
||||||
|
height: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-tab {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--sentient-border);
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
color: var(--sentient-text-secondary);
|
||||||
|
font-family: var(--sentient-font-family);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-tab:first-child {
|
||||||
|
border-radius: var(--sentient-radius-sm) 0 0 var(--sentient-radius-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-tab:last-child {
|
||||||
|
border-radius: 0 var(--sentient-radius-sm) var(--sentient-radius-sm) 0;
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-tab:hover {
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-tab.active {
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
border-color: var(--sentient-accent);
|
||||||
|
color: var(--sentient-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-app-launcher {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
background: var(--sentient-bg-secondary);
|
||||||
|
border-radius: var(--sentient-radius-lg);
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--sentient-radius-md);
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
font-size: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-icon:hover {
|
||||||
|
background: var(--sentient-bg-hover);
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-icon.active {
|
||||||
|
background: var(--sentient-accent-dim);
|
||||||
|
color: var(--sentient-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-btn-primary {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: var(--sentient-accent);
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
color: #000;
|
||||||
|
font-family: var(--sentient-font-family);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-btn-primary:hover {
|
||||||
|
background: #d4ff4a;
|
||||||
|
box-shadow: 0 0 20px var(--sentient-accent-glow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-btn-icon {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--sentient-border);
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
color: var(--sentient-text-secondary);
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-btn-icon:hover {
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.suite-main {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.suite-content-panel {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 20px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
AI PANEL
|
||||||
|
============================================================================= */
|
||||||
|
|
||||||
|
.suite-ai-panel {
|
||||||
|
width: 320px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: var(--sentient-bg-secondary);
|
||||||
|
border-left: 1px solid var(--sentient-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-panel-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 16px;
|
||||||
|
border-bottom: 1px solid var(--sentient-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-panel-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-avatar {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: var(--sentient-accent-dim);
|
||||||
|
border-radius: var(--sentient-radius-md);
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-panel-title h3 {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-panel-title .ai-status {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--sentient-text-muted);
|
||||||
|
margin: 2px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-panel-close {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
color: var(--sentient-text-muted);
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-panel-close:hover {
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-panel-messages {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 16px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-message {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-message.user { align-items: flex-end; }
|
||||||
|
.ai-message.assistant { align-items: flex-start; }
|
||||||
|
|
||||||
|
.ai-message-bubble {
|
||||||
|
max-width: 90%;
|
||||||
|
padding: 12px 14px;
|
||||||
|
border-radius: var(--sentient-radius-md);
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-message.user .ai-message-bubble {
|
||||||
|
background: var(--sentient-accent);
|
||||||
|
color: #000;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-message.assistant .ai-message-bubble {
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-message-action {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: var(--sentient-accent);
|
||||||
|
color: #000;
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-typing-indicator {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 12px 14px;
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
border-radius: var(--sentient-radius-md);
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-typing-indicator span {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background: var(--sentient-text-muted);
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: typing 1.4s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-typing-indicator span:nth-child(2) { animation-delay: 0.2s; }
|
||||||
|
.ai-typing-indicator span:nth-child(3) { animation-delay: 0.4s; }
|
||||||
|
|
||||||
|
@keyframes typing {
|
||||||
|
0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
|
||||||
|
30% { transform: translateY(-4px); opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-quick-actions {
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-top: 1px solid var(--sentient-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-actions-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--sentient-text-muted);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-actions-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-action-btn {
|
||||||
|
padding: 6px 10px;
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
border: 1px solid var(--sentient-border);
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
color: var(--sentient-text-secondary);
|
||||||
|
font-family: var(--sentient-font-family);
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-action-btn:hover {
|
||||||
|
background: var(--sentient-bg-hover);
|
||||||
|
border-color: var(--sentient-accent);
|
||||||
|
color: var(--sentient-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-panel-input {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-top: 1px solid var(--sentient-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px 14px;
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
border: 1px solid var(--sentient-border);
|
||||||
|
border-radius: var(--sentient-radius-md);
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
font-family: var(--sentient-font-family);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-input::placeholder { color: var(--sentient-text-muted); }
|
||||||
|
.ai-input:focus { outline: none; border-color: var(--sentient-accent); }
|
||||||
|
|
||||||
|
.ai-send-btn {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: var(--sentient-accent);
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--sentient-radius-md);
|
||||||
|
color: #000;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-send-btn:hover { background: #d4ff4a; }
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
STAT CARDS
|
||||||
|
============================================================================= */
|
||||||
|
|
||||||
|
.stat-cards {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 16px;
|
||||||
|
background: var(--sentient-bg-card);
|
||||||
|
border: 1px solid var(--sentient-border);
|
||||||
|
border-radius: var(--sentient-radius-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-content { flex: 1; }
|
||||||
|
|
||||||
|
.stat-card-label {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--sentient-text-muted);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-value {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.highlight {
|
||||||
|
border-color: var(--sentient-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.highlight .stat-card-value {
|
||||||
|
color: var(--sentient-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
APP HEADER
|
||||||
|
============================================================================= */
|
||||||
|
|
||||||
|
.app-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-title-section h1 {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0 0 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-title-section p {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--sentient-text-muted);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-btn-primary {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 10px 16px;
|
||||||
|
background: var(--sentient-accent);
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
color: #000;
|
||||||
|
font-family: var(--sentient-font-family);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-btn-primary:hover { background: #d4ff4a; }
|
||||||
|
|
||||||
|
.app-btn-secondary {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
border: 1px solid var(--sentient-border);
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
color: var(--sentient-text-secondary);
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-btn-secondary:hover {
|
||||||
|
background: var(--sentient-bg-hover);
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
DATA TABLE
|
||||||
|
============================================================================= */
|
||||||
|
|
||||||
|
.data-table-container {
|
||||||
|
flex: 1;
|
||||||
|
background: var(--sentient-bg-card);
|
||||||
|
border: 1px solid var(--sentient-border);
|
||||||
|
border-radius: var(--sentient-radius-lg);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table thead {
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table th {
|
||||||
|
padding: 12px 16px;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--sentient-text-muted);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
border-bottom: 1px solid var(--sentient-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table td {
|
||||||
|
padding: 14px 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
border-bottom: 1px solid var(--sentient-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table tbody tr:hover {
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table tbody tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.active {
|
||||||
|
background: rgba(34, 197, 94, 0.15);
|
||||||
|
color: var(--sentient-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.pending {
|
||||||
|
background: rgba(245, 158, 11, 0.15);
|
||||||
|
color: var(--sentient-warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.inactive {
|
||||||
|
background: rgba(239, 68, 68, 0.15);
|
||||||
|
color: var(--sentient-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-action-btn {
|
||||||
|
padding: 6px 12px;
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
border: 1px solid var(--sentient-border);
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
color: var(--sentient-text-secondary);
|
||||||
|
font-family: var(--sentient-font-family);
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-action-btn:hover {
|
||||||
|
background: var(--sentient-bg-hover);
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-action-btn.delete {
|
||||||
|
background: rgba(239, 68, 68, 0.1);
|
||||||
|
border-color: rgba(239, 68, 68, 0.3);
|
||||||
|
color: var(--sentient-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-action-btn.delete:hover {
|
||||||
|
background: rgba(239, 68, 68, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: var(--sentient-bg-tertiary);
|
||||||
|
border-top: 1px solid var(--sentient-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-info {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--sentient-text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-btn {
|
||||||
|
padding: 6px 12px;
|
||||||
|
background: var(--sentient-bg-card);
|
||||||
|
border: 1px solid var(--sentient-border);
|
||||||
|
border-radius: var(--sentient-radius-sm);
|
||||||
|
color: var(--sentient-text-secondary);
|
||||||
|
font-family: var(--sentient-font-family);
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-btn:hover {
|
||||||
|
background: var(--sentient-bg-hover);
|
||||||
|
color: var(--sentient-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-btn.active {
|
||||||
|
background: var(--sentient-accent);
|
||||||
|
border-color: var(--sentient-accent);
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
SCROLLBAR
|
||||||
|
============================================================================= */
|
||||||
|
|
||||||
|
::-webkit-scrollbar { width: 6px; height: 6px; }
|
||||||
|
::-webkit-scrollbar-track { background: var(--sentient-bg-secondary); }
|
||||||
|
::-webkit-scrollbar-thumb { background: var(--sentient-bg-tertiary); border-radius: 3px; }
|
||||||
|
::-webkit-scrollbar-thumb:hover { background: var(--sentient-border-hover); }
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="suite-app">
|
||||||
|
<!-- Top Header Bar -->
|
||||||
|
<header class="suite-topbar">
|
||||||
|
<div class="topbar-left">
|
||||||
|
<nav class="topbar-tabs">
|
||||||
|
<button class="topbar-tab active">Dashboard</button>
|
||||||
|
<button class="topbar-tab">Analytics</button>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="topbar-app-launcher">
|
||||||
|
<button class="app-icon" data-app="chat" title="Chat">💬</button>
|
||||||
|
<button class="app-icon active" data-app="files" title="Files">📁</button>
|
||||||
|
<button class="app-icon" data-app="terminal" title="Terminal">⌨️</button>
|
||||||
|
<button class="app-icon" data-app="tasks" title="Tasks">✓</button>
|
||||||
|
<button class="app-icon" data-app="calendar" title="Calendar">📅</button>
|
||||||
|
<button class="app-icon" data-app="docs" title="Docs">📄</button>
|
||||||
|
<button class="app-icon" data-app="settings" title="Settings">⚙️</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="topbar-right">
|
||||||
|
<button class="topbar-btn-primary">✨ New Intent</button>
|
||||||
|
<button class="topbar-btn-icon" title="Settings">⚙️</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Main Content Area -->
|
||||||
|
<main class="suite-main">
|
||||||
|
<!-- Left: Content Panel -->
|
||||||
|
<section class="suite-content-panel">
|
||||||
|
<!-- Stat Cards -->
|
||||||
|
<div class="stat-cards">
|
||||||
|
<div class="stat-card highlight">
|
||||||
|
<div class="stat-card-icon">📊</div>
|
||||||
|
<div class="stat-card-content">
|
||||||
|
<div class="stat-card-label">Total Records</div>
|
||||||
|
<div class="stat-card-value">12,847</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-card-icon">✅</div>
|
||||||
|
<div class="stat-card-content">
|
||||||
|
<div class="stat-card-label">Active</div>
|
||||||
|
<div class="stat-card-value">8,234</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-card-icon">⏳</div>
|
||||||
|
<div class="stat-card-content">
|
||||||
|
<div class="stat-card-label">Pending</div>
|
||||||
|
<div class="stat-card-value">2,156</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-card-icon">📈</div>
|
||||||
|
<div class="stat-card-content">
|
||||||
|
<div class="stat-card-label">Growth</div>
|
||||||
|
<div class="stat-card-value">+24%</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- App Header -->
|
||||||
|
<div class="app-header">
|
||||||
|
<div class="app-title-section">
|
||||||
|
<h1>Files Manager</h1>
|
||||||
|
<p>Manage your documents and media files</p>
|
||||||
|
</div>
|
||||||
|
<div class="app-actions">
|
||||||
|
<button class="app-btn-primary">+ Upload File</button>
|
||||||
|
<button class="app-btn-secondary">🔍</button>
|
||||||
|
<button class="app-btn-secondary">⋯</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Data Table -->
|
||||||
|
<div class="data-table-container">
|
||||||
|
<table class="data-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Size</th>
|
||||||
|
<th>Modified</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>project-report.pdf</td>
|
||||||
|
<td>PDF Document</td>
|
||||||
|
<td>2.4 MB</td>
|
||||||
|
<td>Dec 13, 2025</td>
|
||||||
|
<td><span class="status-badge active">Active</span></td>
|
||||||
|
<td>
|
||||||
|
<div class="table-actions">
|
||||||
|
<button class="table-action-btn">View</button>
|
||||||
|
<button class="table-action-btn">Edit</button>
|
||||||
|
<button class="table-action-btn delete">Delete</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>dashboard-mockup.fig</td>
|
||||||
|
<td>Figma File</td>
|
||||||
|
<td>8.1 MB</td>
|
||||||
|
<td>Dec 12, 2025</td>
|
||||||
|
<td><span class="status-badge pending">Pending</span></td>
|
||||||
|
<td>
|
||||||
|
<div class="table-actions">
|
||||||
|
<button class="table-action-btn">View</button>
|
||||||
|
<button class="table-action-btn">Edit</button>
|
||||||
|
<button class="table-action-btn delete">Delete</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>api-documentation.md</td>
|
||||||
|
<td>Markdown</td>
|
||||||
|
<td>156 KB</td>
|
||||||
|
<td>Dec 11, 2025</td>
|
||||||
|
<td><span class="status-badge active">Active</span></td>
|
||||||
|
<td>
|
||||||
|
<div class="table-actions">
|
||||||
|
<button class="table-action-btn">View</button>
|
||||||
|
<button class="table-action-btn">Edit</button>
|
||||||
|
<button class="table-action-btn delete">Delete</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>backup-2025-12.zip</td>
|
||||||
|
<td>Archive</td>
|
||||||
|
<td>45.2 MB</td>
|
||||||
|
<td>Dec 10, 2025</td>
|
||||||
|
<td><span class="status-badge inactive">Archived</span></td>
|
||||||
|
<td>
|
||||||
|
<div class="table-actions">
|
||||||
|
<button class="table-action-btn">View</button>
|
||||||
|
<button class="table-action-btn">Edit</button>
|
||||||
|
<button class="table-action-btn delete">Delete</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>user-analytics.csv</td>
|
||||||
|
<td>Spreadsheet</td>
|
||||||
|
<td>890 KB</td>
|
||||||
|
<td>Dec 9, 2025</td>
|
||||||
|
<td><span class="status-badge active">Active</span></td>
|
||||||
|
<td>
|
||||||
|
<div class="table-actions">
|
||||||
|
<button class="table-action-btn">View</button>
|
||||||
|
<button class="table-action-btn">Edit</button>
|
||||||
|
<button class="table-action-btn delete">Delete</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="data-table-footer">
|
||||||
|
<span class="pagination-info">Showing 1-5 of 847 files</span>
|
||||||
|
<div class="pagination-controls">
|
||||||
|
<button class="pagination-btn">←</button>
|
||||||
|
<button class="pagination-btn active">1</button>
|
||||||
|
<button class="pagination-btn">2</button>
|
||||||
|
<button class="pagination-btn">3</button>
|
||||||
|
<button class="pagination-btn">...</button>
|
||||||
|
<button class="pagination-btn">170</button>
|
||||||
|
<button class="pagination-btn">→</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Right: AI Assistant Panel -->
|
||||||
|
<aside class="suite-ai-panel">
|
||||||
|
<div class="ai-panel-header">
|
||||||
|
<div class="ai-panel-title">
|
||||||
|
<span class="ai-avatar">🤖</span>
|
||||||
|
<div>
|
||||||
|
<h3>AI Developer</h3>
|
||||||
|
<p class="ai-status">Desenvolvendo: CRM Deloitte</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="ai-panel-close">✕</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ai-panel-messages" id="ai-messages">
|
||||||
|
<div class="ai-message assistant">
|
||||||
|
<div class="ai-message-bubble">Olá! Sou o AI Developer. Como posso ajudar você hoje?</div>
|
||||||
|
</div>
|
||||||
|
<div class="ai-message assistant">
|
||||||
|
<div class="ai-message-bubble">Você pode me pedir para modificar campos, alterar cores, adicionar validações ou qualquer outra mudança no sistema.</div>
|
||||||
|
</div>
|
||||||
|
<div class="ai-message user">
|
||||||
|
<div class="ai-message-bubble">Adicione um campo de telefone no formulário de cadastro</div>
|
||||||
|
</div>
|
||||||
|
<div class="ai-message assistant">
|
||||||
|
<div class="ai-message-bubble">Perfeito! Adicionei o campo de telefone com máscara automática e validação de formato brasileiro.</div>
|
||||||
|
<span class="ai-message-action">Ver alterações</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ai-quick-actions">
|
||||||
|
<span class="quick-actions-label">AÇÕES RÁPIDAS</span>
|
||||||
|
<div class="quick-actions-grid">
|
||||||
|
<button class="quick-action-btn">Adicionar campo</button>
|
||||||
|
<button class="quick-action-btn">Mudar cor</button>
|
||||||
|
<button class="quick-action-btn">Adicionar validação</button>
|
||||||
|
<button class="quick-action-btn">Exportar dados</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ai-panel-input">
|
||||||
|
<input type="text" class="ai-input" placeholder="Digite suas modificações..." id="ai-input">
|
||||||
|
<button class="ai-send-btn">➤</button>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Tab switching
|
||||||
|
document.querySelectorAll('.topbar-tab').forEach(tab => {
|
||||||
|
tab.addEventListener('click', function() {
|
||||||
|
document.querySelectorAll('.topbar-tab').forEach(t => t.classList.remove('active'));
|
||||||
|
this.classList.add('active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// App icon switching
|
||||||
|
document.querySelectorAll('.app-icon').forEach(icon => {
|
||||||
|
icon.addEventListener('click', function() {
|
||||||
|
document.querySelectorAll('.app-icon').forEach(i => i.classList.remove('active'));
|
||||||
|
this.classList.add('active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Quick actions
|
||||||
|
document.querySelectorAll('.quick-action-btn').forEach(btn => {
|
||||||
|
btn.addEventListener('click', function() {
|
||||||
|
const action = this.textContent;
|
||||||
|
addMessage('user', action);
|
||||||
|
setTimeout(() => {
|
||||||
|
addMessage('assistant', `Ação "${action}" executada com sucesso!`);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Send message
|
||||||
|
document.querySelector('.ai-send-btn').addEventListener('click', sendMessage);
|
||||||
|
document.getElementById('ai-input').addEventListener('keypress', function(e) {
|
||||||
|
if (e.key === 'Enter') sendMessage();
|
||||||
|
});
|
||||||
|
|
||||||
|
function sendMessage() {
|
||||||
|
const input = document.getElementById('ai-input');
|
||||||
|
const message = input.value.trim();
|
||||||
|
if (!message) return;
|
||||||
|
|
||||||
|
addMessage('user', message);
|
||||||
|
input.value = '';
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
addMessage('assistant', `Entendido! Processando: "${message}"`);
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMessage(type, content) {
|
||||||
|
const container = document.getElementById('ai-messages');
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.className = `ai-message ${type}`;
|
||||||
|
div.innerHTML = `<div class="ai-message-bubble">${content}</div>`;
|
||||||
|
container.appendChild(div);
|
||||||
|
container.scrollTop = container.scrollHeight;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
98
ui/suite/base-layout.html
Normal file
98
ui/suite/base-layout.html
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
<!-- =============================================================================
|
||||||
|
BOTUI SUITE - BASE LAYOUT
|
||||||
|
Sentient Theme with AI Assistant Panel
|
||||||
|
============================================================================= -->
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/themes/sentient/sentient.css">
|
||||||
|
<link rel="stylesheet" href="/suite/base-layout.css">
|
||||||
|
|
||||||
|
<div class="suite-app sentient-theme">
|
||||||
|
<!-- Top Header Bar -->
|
||||||
|
<header class="suite-topbar">
|
||||||
|
<!-- Left: Navigation Tabs -->
|
||||||
|
<div class="topbar-left">
|
||||||
|
<nav class="topbar-tabs">
|
||||||
|
<button class="topbar-tab active">Dashboard</button>
|
||||||
|
<button class="topbar-tab">Analytics</button>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- App Launcher -->
|
||||||
|
<div class="topbar-app-launcher">
|
||||||
|
<button class="app-icon" data-app="chat" title="Chat">
|
||||||
|
<span>💬</span>
|
||||||
|
</button>
|
||||||
|
<button class="app-icon" data-app="files" title="Files">
|
||||||
|
<span>📁</span>
|
||||||
|
</button>
|
||||||
|
<button class="app-icon" data-app="terminal" title="Terminal">
|
||||||
|
<span>⌨️</span>
|
||||||
|
</button>
|
||||||
|
<button class="app-icon" data-app="tasks" title="Tasks">
|
||||||
|
<span>✓</span>
|
||||||
|
</button>
|
||||||
|
<button class="app-icon" data-app="calendar" title="Calendar">
|
||||||
|
<span>📅</span>
|
||||||
|
</button>
|
||||||
|
<button class="app-icon" data-app="docs" title="Docs">
|
||||||
|
<span>📄</span>
|
||||||
|
</button>
|
||||||
|
<button class="app-icon" data-app="settings" title="Settings">
|
||||||
|
<span>⚙️</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right: Actions -->
|
||||||
|
<div class="topbar-right">
|
||||||
|
<button class="topbar-btn-primary">
|
||||||
|
<span>✨</span> New Intent
|
||||||
|
</button>
|
||||||
|
<button class="topbar-btn-icon" title="Settings">⚙️</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Main Content Area -->
|
||||||
|
<main class="suite-main">
|
||||||
|
<!-- Left: Content Panel -->
|
||||||
|
<section class="suite-content-panel" id="suite-content">
|
||||||
|
<!-- App content goes here -->
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Right: AI Assistant Panel -->
|
||||||
|
<aside class="suite-ai-panel" id="ai-panel">
|
||||||
|
<div class="ai-panel-header">
|
||||||
|
<div class="ai-panel-title">
|
||||||
|
<span class="ai-avatar">🤖</span>
|
||||||
|
<div>
|
||||||
|
<h3>AI Developer</h3>
|
||||||
|
<p class="ai-status">Desenvolvendo: CRM Deloitte</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="ai-panel-close" onclick="toggleAIPanel()">✕</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ai-panel-messages" id="ai-messages">
|
||||||
|
<!-- Messages will be inserted here -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ai-quick-actions">
|
||||||
|
<span class="quick-actions-label">AÇÕES RÁPIDAS</span>
|
||||||
|
<div class="quick-actions-grid">
|
||||||
|
<button class="quick-action-btn">Adicionar campo</button>
|
||||||
|
<button class="quick-action-btn">Mudar cor</button>
|
||||||
|
<button class="quick-action-btn">Adicionar validação</button>
|
||||||
|
<button class="quick-action-btn">Exportar dados</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ai-panel-input">
|
||||||
|
<input type="text" class="ai-input" placeholder="Digite suas modificações..." id="ai-input">
|
||||||
|
<button class="ai-send-btn" onclick="sendAIMessage()">
|
||||||
|
<span>➤</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/suite/base-layout.js"></script>
|
||||||
1573
ui/suite/base.html
Normal file
1573
ui/suite/base.html
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,19 +0,0 @@
|
||||||
<div class="h-full flex flex-col bg-white overflow-hidden text-gray-800">
|
|
||||||
<div class="h-10 bg-gray-100 border-b border-gray-200 flex items-center px-4 space-x-2">
|
|
||||||
<button class="text-gray-400 hover:text-gray-600"><i class="fa-solid fa-arrow-left"></i></button>
|
|
||||||
<button class="text-gray-400 hover:text-gray-600"><i class="fa-solid fa-arrow-right"></i></button>
|
|
||||||
<button class="text-gray-400 hover:text-gray-600"><i class="fa-solid fa-rotate-right"></i></button>
|
|
||||||
<div class="flex-1 bg-white border border-gray-300 rounded px-3 py-1 flex items-center shadow-inner">
|
|
||||||
<i class="fa-solid fa-lock text-green-600 text-xs mr-2"></i>
|
|
||||||
<input type="text" class="flex-1 outline-none text-sm" value="https://generalbots.com" readonly>
|
|
||||||
</div>
|
|
||||||
<button class="text-gray-400 hover:text-gray-600"><i class="fa-solid fa-bars"></i></button>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 flex items-center justify-center bg-[#fafdfa]">
|
|
||||||
<div class="text-center text-gray-400">
|
|
||||||
<i class="fa-regular fa-compass text-5xl mb-4 text-brand-300"></i>
|
|
||||||
<h2 class="text-xl font-medium text-gray-600">Browser</h2>
|
|
||||||
<p class="mt-2 text-sm">Internet access starting soon...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<link rel="stylesheet" href="/suite/calendar/calendar.css" />
|
<link rel="stylesheet" href="calendar/calendar.css" />
|
||||||
|
|
||||||
<!-- Calendar - Event Management -->
|
<!-- Calendar - Event Management -->
|
||||||
<div class="calendar-container" id="calendar-app">
|
<div class="calendar-container" id="calendar-app">
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,18 +1,6 @@
|
||||||
<link rel="stylesheet" href="/suite/chat/chat.css?v=9" />
|
<link rel="stylesheet" href="chat/chat.css" />
|
||||||
<link rel="stylesheet" href="/suite/css/markdown-message.css" />
|
|
||||||
<script src="/suite/js/vendor/marked.min.js"></script>
|
|
||||||
|
|
||||||
<div class="chat-layout" id="chat-app">
|
<div class="chat-layout" id="chat-app">
|
||||||
<!-- Connection Status -->
|
|
||||||
<div
|
|
||||||
class="connection-status connecting"
|
|
||||||
id="connectionStatus"
|
|
||||||
style="display: none"
|
|
||||||
>
|
|
||||||
<span class="connection-status-dot"></span>
|
|
||||||
<span class="connection-text">Connecting...</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<main id="messages"></main>
|
<main id="messages"></main>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
|
|
@ -35,6 +23,14 @@
|
||||||
autofocus
|
autofocus
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
/>
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
id="voiceBtn"
|
||||||
|
title="Voice"
|
||||||
|
data-i18n-title="chat-voice"
|
||||||
|
>
|
||||||
|
🎤
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
id="sendBtn"
|
id="sendBtn"
|
||||||
|
|
@ -45,24 +41,7 @@
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</footer>
|
</footer>
|
||||||
<button
|
<button class="scroll-to-bottom" id="scrollToBottom">↓</button>
|
||||||
class="scroll-to-bottom"
|
|
||||||
id="scrollToBottom"
|
|
||||||
title="Scroll to bottom"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<polyline points="6 9 12 15 18 9"></polyline>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="entity-card-tooltip" id="entityCardTooltip">
|
<div class="entity-card-tooltip" id="entityCardTooltip">
|
||||||
|
|
@ -102,7 +81,7 @@
|
||||||
|
|
||||||
var WS_BASE_URL =
|
var WS_BASE_URL =
|
||||||
window.location.protocol === "https:" ? "wss://" : "ws://";
|
window.location.protocol === "https:" ? "wss://" : "ws://";
|
||||||
var WS_URL = WS_BASE_URL + window.location.host + "/ws";
|
var WS_URL = WS_BASE_URL + window.location.host;
|
||||||
|
|
||||||
var MessageType = {
|
var MessageType = {
|
||||||
EXTERNAL: 0,
|
EXTERNAL: 0,
|
||||||
|
|
@ -169,14 +148,11 @@
|
||||||
var currentSessionId = null;
|
var currentSessionId = null;
|
||||||
var currentUserId = null;
|
var currentUserId = null;
|
||||||
var currentBotId = "default";
|
var currentBotId = "default";
|
||||||
var currentBotName = "default";
|
|
||||||
var isStreaming = false;
|
var isStreaming = false;
|
||||||
var streamingMessageId = null;
|
var streamingMessageId = null;
|
||||||
var currentStreamingContent = "";
|
var currentStreamingContent = "";
|
||||||
var reconnectAttempts = 0;
|
var reconnectAttempts = 0;
|
||||||
var maxReconnectAttempts = 5;
|
var maxReconnectAttempts = 5;
|
||||||
var disconnectNotified = false;
|
|
||||||
var isUserScrolling = false;
|
|
||||||
|
|
||||||
var mentionState = {
|
var mentionState = {
|
||||||
active: false,
|
active: false,
|
||||||
|
|
@ -192,63 +168,6 @@
|
||||||
return div.innerHTML;
|
return div.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll handling
|
|
||||||
function scrollToBottom(animate) {
|
|
||||||
var messages = document.getElementById("messages");
|
|
||||||
if (messages) {
|
|
||||||
if (animate) {
|
|
||||||
messages.scrollTo({
|
|
||||||
top: messages.scrollHeight,
|
|
||||||
behavior: "smooth",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
messages.scrollTop = messages.scrollHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateScrollButton() {
|
|
||||||
var messages = document.getElementById("messages");
|
|
||||||
var scrollBtn = document.getElementById("scrollToBottom");
|
|
||||||
if (!messages || !scrollBtn) return;
|
|
||||||
|
|
||||||
var isNearBottom =
|
|
||||||
messages.scrollHeight -
|
|
||||||
messages.scrollTop -
|
|
||||||
messages.clientHeight <
|
|
||||||
100;
|
|
||||||
|
|
||||||
if (isNearBottom) {
|
|
||||||
scrollBtn.classList.remove("visible");
|
|
||||||
} else {
|
|
||||||
scrollBtn.classList.add("visible");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scroll-to-bottom button click
|
|
||||||
var scrollBtn = document.getElementById("scrollToBottom");
|
|
||||||
if (scrollBtn) {
|
|
||||||
scrollBtn.addEventListener("click", function () {
|
|
||||||
scrollToBottom(true);
|
|
||||||
isUserScrolling = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect user scrolling
|
|
||||||
var messagesEl = document.getElementById("messages");
|
|
||||||
if (messagesEl) {
|
|
||||||
messagesEl.addEventListener("scroll", function () {
|
|
||||||
isUserScrolling = true;
|
|
||||||
updateScrollButton();
|
|
||||||
|
|
||||||
// Reset isUserScrolling after 2 seconds of no scrolling
|
|
||||||
clearTimeout(messagesEl.scrollTimeout);
|
|
||||||
messagesEl.scrollTimeout = setTimeout(function () {
|
|
||||||
isUserScrolling = false;
|
|
||||||
}, 2000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderMentionInMessage(content) {
|
function renderMentionInMessage(content) {
|
||||||
return content.replace(
|
return content.replace(
|
||||||
/@(\w+):([^\s]+)/g,
|
/@(\w+):([^\s]+)/g,
|
||||||
|
|
@ -306,13 +225,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
messages.appendChild(div);
|
messages.appendChild(div);
|
||||||
|
messages.scrollTop = messages.scrollHeight;
|
||||||
// Auto-scroll to bottom unless user is manually scrolling
|
|
||||||
if (!isUserScrolling) {
|
|
||||||
scrollToBottom(true);
|
|
||||||
} else {
|
|
||||||
updateScrollButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
setupMentionClickHandlers(div);
|
setupMentionClickHandlers(div);
|
||||||
}
|
}
|
||||||
|
|
@ -757,20 +670,9 @@
|
||||||
if (isStreaming) {
|
if (isStreaming) {
|
||||||
finalizeStreaming();
|
finalizeStreaming();
|
||||||
} else {
|
} else {
|
||||||
if (data.content && data.content.trim() !== "") {
|
addMessage("bot", data.content);
|
||||||
addMessage("bot", data.content);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
isStreaming = false;
|
isStreaming = false;
|
||||||
|
|
||||||
// Render suggestions when message is complete
|
|
||||||
if (
|
|
||||||
data.suggestions &&
|
|
||||||
Array.isArray(data.suggestions) &&
|
|
||||||
data.suggestions.length > 0
|
|
||||||
) {
|
|
||||||
renderSuggestions(data.suggestions);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!isStreaming) {
|
if (!isStreaming) {
|
||||||
isStreaming = true;
|
isStreaming = true;
|
||||||
|
|
@ -788,103 +690,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render suggestion buttons
|
function sendMessage() {
|
||||||
function renderSuggestions(suggestions) {
|
|
||||||
var suggestionsEl = document.getElementById("suggestions");
|
|
||||||
if (!suggestionsEl) {
|
|
||||||
console.warn("Suggestions container not found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the footer element
|
|
||||||
var footer = suggestionsEl.closest("footer");
|
|
||||||
|
|
||||||
// Clear existing suggestions
|
|
||||||
suggestionsEl.innerHTML = "";
|
|
||||||
|
|
||||||
console.log("Rendering " + suggestions.length + " suggestions");
|
|
||||||
|
|
||||||
// Add or remove CSS class based on whether suggestions are displayed
|
|
||||||
if (footer) {
|
|
||||||
if (suggestions.length > 0) {
|
|
||||||
footer.classList.add("has-suggestions");
|
|
||||||
} else {
|
|
||||||
footer.classList.remove("has-suggestions");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suggestions.forEach(function (suggestion) {
|
|
||||||
var chip = document.createElement("button");
|
|
||||||
chip.className = "suggestion-chip";
|
|
||||||
chip.textContent = suggestion.text || "Suggestion";
|
|
||||||
|
|
||||||
// Use window.sendMessage which is already exposed
|
|
||||||
chip.onclick = (function (sugg) {
|
|
||||||
return function () {
|
|
||||||
console.log("Suggestion clicked:", sugg);
|
|
||||||
// Check if there's an action to parse
|
|
||||||
if (sugg.action) {
|
|
||||||
try {
|
|
||||||
var action =
|
|
||||||
typeof sugg.action === "string"
|
|
||||||
? JSON.parse(sugg.action)
|
|
||||||
: sugg.action;
|
|
||||||
|
|
||||||
console.log("Parsed action:", action);
|
|
||||||
|
|
||||||
if (action.type === "invoke_tool") {
|
|
||||||
// Send the display text so it shows correctly in chat
|
|
||||||
// The backend will recognize this as a tool request
|
|
||||||
window.sendMessage(sugg.text);
|
|
||||||
} else if (action.type === "send_message") {
|
|
||||||
window.sendMessage(
|
|
||||||
action.message || sugg.text,
|
|
||||||
);
|
|
||||||
} else if (action.type === "select_context") {
|
|
||||||
window.sendMessage(action.context);
|
|
||||||
} else {
|
|
||||||
window.sendMessage(sugg.text);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(
|
|
||||||
"Failed to parse action:",
|
|
||||||
e,
|
|
||||||
"falling back to text",
|
|
||||||
);
|
|
||||||
window.sendMessage(sugg.text);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No action, just send the text
|
|
||||||
window.sendMessage(sugg.text);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})(suggestion);
|
|
||||||
|
|
||||||
suggestionsEl.appendChild(chip);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendMessage(messageContent) {
|
|
||||||
var input = document.getElementById("messageInput");
|
var input = document.getElementById("messageInput");
|
||||||
if (!input) {
|
if (!input) {
|
||||||
console.error("Chat input not found");
|
console.error("Chat input not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no messageContent provided, read from input
|
var content = input.value.trim();
|
||||||
var content = messageContent || input.value.trim();
|
|
||||||
if (!content) {
|
if (!content) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If called from input field (no messageContent provided), clear input
|
hideMentionDropdown();
|
||||||
if (!messageContent) {
|
|
||||||
hideMentionDropdown();
|
|
||||||
input.value = "";
|
|
||||||
input.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
addMessage("user", content);
|
addMessage("user", content);
|
||||||
|
input.value = "";
|
||||||
|
input.focus();
|
||||||
|
|
||||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||||
ws.send(
|
ws.send(
|
||||||
|
|
@ -905,340 +726,51 @@
|
||||||
|
|
||||||
window.sendMessage = sendMessage;
|
window.sendMessage = sendMessage;
|
||||||
|
|
||||||
// Expose session info for suggestion clicks
|
|
||||||
window.getChatSessionInfo = function () {
|
|
||||||
return {
|
|
||||||
ws: ws,
|
|
||||||
currentBotId: currentBotId,
|
|
||||||
currentUserId: currentUserId,
|
|
||||||
currentSessionId: currentSessionId,
|
|
||||||
currentBotName: currentBotName,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
function connectWebSocket() {
|
function connectWebSocket() {
|
||||||
if (ws) {
|
if (ws) {
|
||||||
ws.close();
|
ws.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateConnectionStatus("connecting");
|
|
||||||
|
|
||||||
var url =
|
var url =
|
||||||
WS_URL +
|
WS_URL +
|
||||||
"?session_id=" +
|
"/ws?session_id=" +
|
||||||
currentSessionId +
|
currentSessionId +
|
||||||
"&user_id=" +
|
"&user_id=" +
|
||||||
currentUserId +
|
currentUserId;
|
||||||
"&bot_name=" +
|
|
||||||
currentBotName;
|
|
||||||
|
|
||||||
console.log("Connecting WebSocket to:", url);
|
|
||||||
ws = new WebSocket(url);
|
ws = new WebSocket(url);
|
||||||
|
|
||||||
// Add connection timeout to detect silent failures
|
|
||||||
var connectionTimeout = setTimeout(function () {
|
|
||||||
if (ws.readyState !== WebSocket.OPEN) {
|
|
||||||
console.error("WebSocket connection timeout");
|
|
||||||
ws.close();
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
ws.onopen = function () {
|
ws.onopen = function () {
|
||||||
clearTimeout(connectionTimeout);
|
console.log("WebSocket connected");
|
||||||
console.log("WebSocket connected to:", url);
|
reconnectAttempts = 0;
|
||||||
disconnectNotified = false;
|
|
||||||
updateConnectionStatus("connected");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onmessage = function (event) {
|
ws.onmessage = function (event) {
|
||||||
try {
|
try {
|
||||||
var data = JSON.parse(event.data);
|
var data = JSON.parse(event.data);
|
||||||
console.log("Chat WebSocket received:", data);
|
if (data.type === "connected") return;
|
||||||
|
|
||||||
// Ignore connection confirmation
|
|
||||||
if (data.type === "connected") {
|
|
||||||
reconnectAttempts = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process system events (theme changes, etc)
|
|
||||||
if (data.event) {
|
|
||||||
if (data.event === "change_theme") {
|
|
||||||
applyThemeData(data.data || {});
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if content contains theme change events (JSON strings)
|
|
||||||
if (data.content && typeof data.content === "string") {
|
|
||||||
try {
|
|
||||||
var contentObj = JSON.parse(data.content);
|
|
||||||
if (contentObj.event === "change_theme") {
|
|
||||||
applyThemeData(contentObj.data || {});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// Content is not JSON, continue processing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only process bot responses
|
|
||||||
if (data.message_type === MessageType.BOT_RESPONSE) {
|
if (data.message_type === MessageType.BOT_RESPONSE) {
|
||||||
console.log("Processing bot response:", data);
|
|
||||||
processMessage(data);
|
processMessage(data);
|
||||||
} else {
|
|
||||||
console.log("Ignoring non-bot message:", data);
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("WS message error:", e);
|
console.error("WS message error:", e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onclose = function (event) {
|
ws.onclose = function () {
|
||||||
clearTimeout(connectionTimeout);
|
notify("Disconnected from chat server", "error");
|
||||||
console.log("WebSocket closed:", event.code, event.reason);
|
|
||||||
updateConnectionStatus("disconnected");
|
|
||||||
if (!disconnectNotified) {
|
|
||||||
notify("Disconnected from chat server", "error");
|
|
||||||
disconnectNotified = true;
|
|
||||||
}
|
|
||||||
if (reconnectAttempts < maxReconnectAttempts) {
|
if (reconnectAttempts < maxReconnectAttempts) {
|
||||||
reconnectAttempts++;
|
reconnectAttempts++;
|
||||||
updateConnectionStatus("connecting");
|
|
||||||
setTimeout(connectWebSocket, 1000 * reconnectAttempts);
|
setTimeout(connectWebSocket, 1000 * reconnectAttempts);
|
||||||
} else {
|
|
||||||
console.error(
|
|
||||||
"Max reconnection attempts reached. Stopping reconnection.",
|
|
||||||
);
|
|
||||||
notify(
|
|
||||||
"Could not reconnect to chat server after multiple attempts",
|
|
||||||
"error",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onerror = function (e) {
|
ws.onerror = function (e) {
|
||||||
console.error("WebSocket error:", e);
|
console.error("WebSocket error:", e);
|
||||||
updateConnectionStatus("disconnected");
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply theme data from WebSocket events
|
|
||||||
function getContrastYIQ(hexcolor) {
|
|
||||||
if (!hexcolor) return "#ffffff";
|
|
||||||
|
|
||||||
// Handle named colors and variables by letting the browser resolve them
|
|
||||||
var temp = document.createElement("div");
|
|
||||||
temp.style.color = hexcolor;
|
|
||||||
temp.style.display = "none";
|
|
||||||
document.body.appendChild(temp);
|
|
||||||
var style = window.getComputedStyle(temp).color;
|
|
||||||
document.body.removeChild(temp);
|
|
||||||
|
|
||||||
var rgb = style.match(/\d+/g);
|
|
||||||
if (!rgb || rgb.length < 3) return "#ffffff";
|
|
||||||
|
|
||||||
var r = parseInt(rgb[0]);
|
|
||||||
var g = parseInt(rgb[1]);
|
|
||||||
var b = parseInt(rgb[2]);
|
|
||||||
|
|
||||||
var yiq = (r * 299 + g * 587 + b * 114) / 1000;
|
|
||||||
return yiq >= 128 ? "#000000" : "#ffffff";
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyThemeData(themeData) {
|
|
||||||
console.log("Applying theme data:", themeData);
|
|
||||||
|
|
||||||
var color1 = themeData.color1 || themeData.data?.color1 || "black";
|
|
||||||
var color2 = themeData.color2 || themeData.data?.color2 || "white";
|
|
||||||
var logo = themeData.logo_url || themeData.data?.logo_url || "";
|
|
||||||
var title =
|
|
||||||
themeData.title ||
|
|
||||||
themeData.data?.title ||
|
|
||||||
window.__INITIAL_BOT_NAME__ ||
|
|
||||||
"Chat";
|
|
||||||
|
|
||||||
// Set CSS variables for colors on document element
|
|
||||||
document.documentElement.style.setProperty("--chat-color1", color1);
|
|
||||||
document.documentElement.style.setProperty("--chat-color2", color2);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--suggestion-color",
|
|
||||||
color1,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--suggestion-bg",
|
|
||||||
color2,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Also set on root for better cascading
|
|
||||||
document.documentElement.style.setProperty("--color1", color1);
|
|
||||||
document.documentElement.style.setProperty("--color2", color2);
|
|
||||||
|
|
||||||
// Update suggestion button colors to match theme
|
|
||||||
document.documentElement.style.setProperty("--primary", color1);
|
|
||||||
document.documentElement.style.setProperty("--accent", color1);
|
|
||||||
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--chat-fg1",
|
|
||||||
getContrastYIQ(color1),
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--chat-fg2",
|
|
||||||
getContrastYIQ(color2),
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("Theme applied:", {
|
|
||||||
color1: color1,
|
|
||||||
color2: color2,
|
|
||||||
logo: logo,
|
|
||||||
title: title,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load bot config and apply colors/logo
|
|
||||||
function loadBotConfig() {
|
|
||||||
var botName = window.__INITIAL_BOT_NAME__ || "default";
|
|
||||||
|
|
||||||
fetch("/api/bot/config?bot_name=" + encodeURIComponent(botName))
|
|
||||||
.then(function (response) {
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(function (config) {
|
|
||||||
if (!config) return;
|
|
||||||
|
|
||||||
// Get the theme manager's theme for this bot to check if user selected a different theme
|
|
||||||
var botId = botName.toLowerCase();
|
|
||||||
var botThemeKey = "gb-theme-" + botId;
|
|
||||||
var botTheme = window.ThemeManager
|
|
||||||
? // Get bot-specific theme from theme manager's mapping
|
|
||||||
(window.ThemeManager.getAvailableThemes &&
|
|
||||||
window.ThemeManager.getAvailableThemes().find(
|
|
||||||
(t) => t.id === botId,
|
|
||||||
)) ||
|
|
||||||
// Fallback to localStorage
|
|
||||||
localStorage.getItem(botThemeKey)
|
|
||||||
: localStorage.getItem(botThemeKey);
|
|
||||||
|
|
||||||
// Check if bot config has a theme-base setting
|
|
||||||
var configThemeBase =
|
|
||||||
config.theme_base || config["theme-base"] || "light";
|
|
||||||
|
|
||||||
// Only use bot config colors if:
|
|
||||||
// 1. No theme has been explicitly selected by user (localStorage empty or default)
|
|
||||||
// 2. AND the bot config's theme-base matches the current theme
|
|
||||||
var localStorageTheme = localStorage.getItem(botThemeKey);
|
|
||||||
var useBotConfigColors =
|
|
||||||
!localStorageTheme ||
|
|
||||||
localStorageTheme === "default" ||
|
|
||||||
localStorageTheme === configThemeBase;
|
|
||||||
|
|
||||||
// Apply colors from config (API returns snake_case)
|
|
||||||
var color1 =
|
|
||||||
config.theme_color1 ||
|
|
||||||
config["theme-color1"] ||
|
|
||||||
config["Theme Color"] ||
|
|
||||||
"#3b82f6";
|
|
||||||
var color2 =
|
|
||||||
config.theme_color2 ||
|
|
||||||
config["theme-color2"] ||
|
|
||||||
"#f5deb3";
|
|
||||||
var title =
|
|
||||||
config.theme_title || config["theme-title"] || botName;
|
|
||||||
var logo = config.theme_logo || config["theme-logo"] || "";
|
|
||||||
|
|
||||||
// Only set bot config colors if user hasn't selected a different theme
|
|
||||||
if (useBotConfigColors) {
|
|
||||||
document.documentElement.setAttribute(
|
|
||||||
"data-has-bot-colors",
|
|
||||||
"true",
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--chat-color1",
|
|
||||||
color1,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--chat-color2",
|
|
||||||
color2,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--suggestion-color",
|
|
||||||
color1,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--suggestion-bg",
|
|
||||||
color2,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--color1",
|
|
||||||
color1,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--color2",
|
|
||||||
color2,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--primary",
|
|
||||||
color1,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--accent",
|
|
||||||
color1,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--chat-fg1",
|
|
||||||
getContrastYIQ(color1),
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--chat-fg2",
|
|
||||||
getContrastYIQ(color2),
|
|
||||||
);
|
|
||||||
console.log("Bot config colors applied:", {
|
|
||||||
color1: color1,
|
|
||||||
color2: color2,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log(
|
|
||||||
"Bot config colors skipped - user selected custom theme:",
|
|
||||||
localStorageTheme,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update logo if provided
|
|
||||||
if (logo) {
|
|
||||||
var logoImg = document.querySelector(".logo-icon-img");
|
|
||||||
if (logoImg) {
|
|
||||||
logoImg.src = logo;
|
|
||||||
logoImg.alt = title || botName;
|
|
||||||
logoImg.style.display = "block";
|
|
||||||
}
|
|
||||||
// Hide the SVG logo when image logo is used
|
|
||||||
var logoSvg = document.querySelector(".logo-icon-svg");
|
|
||||||
if (logoSvg) {
|
|
||||||
logoSvg.style.display = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Bot config loaded:", {
|
|
||||||
color1: color1,
|
|
||||||
color2: color2,
|
|
||||||
title: title,
|
|
||||||
logo: logo,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(function (e) {
|
|
||||||
console.log("Could not load bot config:", e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function initChat() {
|
function initChat() {
|
||||||
// Load bot config first
|
var botName = "default";
|
||||||
loadBotConfig();
|
|
||||||
// Just proceed with chat initialization - no auth check
|
|
||||||
proceedWithChatInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
function proceedWithChatInit() {
|
|
||||||
var botName = window.__INITIAL_BOT_NAME__ || "default";
|
|
||||||
fetch("/api/auth?bot_name=" + encodeURIComponent(botName))
|
fetch("/api/auth?bot_name=" + encodeURIComponent(botName))
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
return response.json();
|
return response.json();
|
||||||
|
|
@ -1247,61 +779,20 @@
|
||||||
currentUserId = auth.user_id;
|
currentUserId = auth.user_id;
|
||||||
currentSessionId = auth.session_id;
|
currentSessionId = auth.session_id;
|
||||||
currentBotId = auth.bot_id || "default";
|
currentBotId = auth.bot_id || "default";
|
||||||
currentBotName = botName;
|
|
||||||
console.log("Auth:", {
|
console.log("Auth:", {
|
||||||
currentUserId: currentUserId,
|
currentUserId: currentUserId,
|
||||||
currentSessionId: currentSessionId,
|
currentSessionId: currentSessionId,
|
||||||
currentBotId: currentBotId,
|
currentBotId: currentBotId,
|
||||||
currentBotName: currentBotName,
|
|
||||||
});
|
});
|
||||||
connectWebSocket();
|
connectWebSocket();
|
||||||
})
|
})
|
||||||
.catch(function (e) {
|
.catch(function (e) {
|
||||||
console.error("Auth failed:", e);
|
console.error("Auth failed:", e);
|
||||||
// Proceed with anonymous connection - WebSocket handler supports it
|
notify("Failed to connect to chat server", "error");
|
||||||
currentUserId = crypto.randomUUID
|
setTimeout(initChat, 3000);
|
||||||
? crypto.randomUUID()
|
|
||||||
: Date.now().toString();
|
|
||||||
currentSessionId = crypto.randomUUID
|
|
||||||
? crypto.randomUUID()
|
|
||||||
: Date.now().toString();
|
|
||||||
currentBotId = botName;
|
|
||||||
currentBotName = botName;
|
|
||||||
console.log("Anonymous chat:", {
|
|
||||||
currentUserId: currentUserId,
|
|
||||||
currentSessionId: currentSessionId,
|
|
||||||
currentBotId: currentBotId,
|
|
||||||
currentBotName: currentBotName,
|
|
||||||
});
|
|
||||||
connectWebSocket();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateConnectionStatus(status) {
|
|
||||||
var statusEl = document.getElementById("connectionStatus");
|
|
||||||
if (!statusEl) return;
|
|
||||||
|
|
||||||
statusEl.className = "connection-status " + status;
|
|
||||||
|
|
||||||
var statusText = statusEl.querySelector(".connection-text");
|
|
||||||
if (statusText) {
|
|
||||||
switch (status) {
|
|
||||||
case "connected":
|
|
||||||
statusText.textContent = "Connected";
|
|
||||||
statusEl.style.display = "none";
|
|
||||||
break;
|
|
||||||
case "disconnected":
|
|
||||||
statusText.textContent = "Disconnected";
|
|
||||||
statusEl.style.display = "flex";
|
|
||||||
break;
|
|
||||||
case "connecting":
|
|
||||||
statusText.textContent = "Connecting...";
|
|
||||||
statusEl.style.display = "flex";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupEventHandlers() {
|
function setupEventHandlers() {
|
||||||
var form = document.getElementById("chatForm");
|
var form = document.getElementById("chatForm");
|
||||||
var input = document.getElementById("messageInput");
|
var input = document.getElementById("messageInput");
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1085,27 +1085,9 @@ body {
|
||||||
|
|
||||||
.logo-icon {
|
.logo-icon {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 20px;
|
||||||
color: var(--text, var(--text-primary, #ffffff));
|
color: var(--text, var(--text-primary, #ffffff));
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Theme logo image - when src is set, show as image */
|
|
||||||
.logo-icon.logo-icon-img[src:not=""]] {
|
|
||||||
display: block;
|
|
||||||
width: auto;
|
|
||||||
height: 40px;
|
|
||||||
object-fit: contain;
|
|
||||||
filter: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hide SVG when logo image is shown */
|
|
||||||
.logo-icon.logo-icon-svg[style*="display: none"],
|
|
||||||
.logo-icon.logo-icon-svg.hidden {
|
|
||||||
display: none !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo-text {
|
.logo-text {
|
||||||
|
|
|
||||||
|
|
@ -472,15 +472,14 @@ body.no-animations .spinner {
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo-icon {
|
.logo-icon {
|
||||||
width: 40px;
|
width: 32px;
|
||||||
height: 40px;
|
height: 32px;
|
||||||
background: linear-gradient(135deg, var(--primary), #8b5cf6);
|
background: linear-gradient(135deg, var(--primary), #8b5cf6);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================ */
|
/* ============================================ */
|
||||||
|
|
|
||||||
|
|
@ -1,604 +0,0 @@
|
||||||
/* Chat Agent Mode — Z.ai toggle + OpenClaw multi-panel layout */
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
AGENT / CHAT MODE TOGGLE (Z.ai style)
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
.chat-mode-toggle {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 2px;
|
|
||||||
background: var(--surface, #1a1a24);
|
|
||||||
border: 1px solid var(--border, #2a2a2a);
|
|
||||||
border-radius: 20px;
|
|
||||||
padding: 2px;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-mode-btn {
|
|
||||||
padding: 5px 14px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 18px;
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
background: transparent;
|
|
||||||
color: var(--text-secondary, var(--text-muted));
|
|
||||||
letter-spacing: 0.3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-mode-btn.active {
|
|
||||||
background: var(--accent);
|
|
||||||
color: var(--bg);
|
|
||||||
box-shadow: 0 2px 8px rgba(132, 214, 105, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-mode-btn:not(.active):hover {
|
|
||||||
color: var(--text, var(--bg));
|
|
||||||
background: var(--hover, rgba(255, 255, 255, 0.05));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
QUICK ACTION CHIPS (Z.ai style)
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
.quick-actions-container {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 8px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
justify-content: center;
|
|
||||||
animation: quickActionsIn 0.4s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes quickActionsIn {
|
|
||||||
from { opacity: 0; transform: translateY(8px); }
|
|
||||||
to { opacity: 1; transform: translateY(0); }
|
|
||||||
}
|
|
||||||
|
|
||||||
.quick-action-chip {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
padding: 8px 16px;
|
|
||||||
border: 1px solid var(--border, #2a2a2a);
|
|
||||||
border-radius: 24px;
|
|
||||||
background: var(--surface, #1a1a24);
|
|
||||||
color: var(--text, var(--bg));
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 500;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quick-action-chip:hover {
|
|
||||||
border-color: var(--accent);
|
|
||||||
background: rgba(132, 214, 105, 0.08);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 12px rgba(132, 214, 105, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.quick-action-chip:active {
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.quick-action-icon {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
AGENT MODE — MULTI-PANEL LAYOUT
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
.chat-layout.agent-mode {
|
|
||||||
max-width: none;
|
|
||||||
padding: 0;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 48px 1fr 1fr;
|
|
||||||
grid-template-rows: 1fr auto auto;
|
|
||||||
gap: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Agent Mode Left Sidebar */
|
|
||||||
.agent-sidebar {
|
|
||||||
display: none;
|
|
||||||
grid-row: 1 / -1;
|
|
||||||
grid-column: 1;
|
|
||||||
background: var(--surface);
|
|
||||||
border-right: 1px solid var(--border);
|
|
||||||
flex-direction: column;
|
|
||||||
z-index: 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-mode .agent-sidebar {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-sidebar-item {
|
|
||||||
width: 48px;
|
|
||||||
height: 44px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.15s ease;
|
|
||||||
position: relative;
|
|
||||||
border-bottom: 1px solid var(--border);
|
|
||||||
background: transparent;
|
|
||||||
border-left: none;
|
|
||||||
border-right: none;
|
|
||||||
border-top: none;
|
|
||||||
color: var(--text-muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-sidebar-item:hover {
|
|
||||||
background: var(--bg);
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-sidebar-item.active {
|
|
||||||
background: var(--bg);
|
|
||||||
border-left: 3px solid var(--accent);
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-sidebar-badge {
|
|
||||||
position: absolute;
|
|
||||||
top: 4px;
|
|
||||||
right: 4px;
|
|
||||||
min-width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
padding: 0 4px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background: var(--accent);
|
|
||||||
color: var(--bg);
|
|
||||||
font-size: 9px;
|
|
||||||
font-weight: 700;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Chat Panel (in agent mode) */
|
|
||||||
.agent-mode #messages {
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-mode footer {
|
|
||||||
grid-column: 2 / -1;
|
|
||||||
padding: 8px 16px;
|
|
||||||
border-top: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
THOUGHT PROCESS BLOCK
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
.thought-process {
|
|
||||||
margin: 12px 0;
|
|
||||||
border: 1px solid var(--border, var(--border));
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
background: var(--surface, #f8f9fa);
|
|
||||||
}
|
|
||||||
|
|
||||||
.thought-process-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 10px 14px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--text, var(--text));
|
|
||||||
background: var(--surface, var(--border));
|
|
||||||
transition: background 0.15s;
|
|
||||||
border: none;
|
|
||||||
width: 100%;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thought-process-header:hover {
|
|
||||||
background: var(--hover, #e8e9ea);
|
|
||||||
}
|
|
||||||
|
|
||||||
.thought-process-toggle {
|
|
||||||
transition: transform 0.2s;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thought-process.expanded .thought-process-toggle {
|
|
||||||
transform: rotate(90deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.thought-process-body {
|
|
||||||
display: none;
|
|
||||||
padding: 12px 14px;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.6;
|
|
||||||
color: var(--text-secondary, var(--text-muted));
|
|
||||||
border-top: 1px solid var(--border, var(--border));
|
|
||||||
}
|
|
||||||
|
|
||||||
.thought-process.expanded .thought-process-body {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
BROWSER PANEL
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
.agent-browser-panel {
|
|
||||||
display: none;
|
|
||||||
grid-column: 3;
|
|
||||||
grid-row: 1;
|
|
||||||
border-left: 1px solid var(--border);
|
|
||||||
flex-direction: column;
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-mode .agent-browser-panel {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.browser-panel-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 8px 12px;
|
|
||||||
background: var(--surface);
|
|
||||||
border-bottom: 1px solid var(--border);
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.browser-url-bar {
|
|
||||||
flex: 1;
|
|
||||||
padding: 4px 10px;
|
|
||||||
background: var(--bg);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 4px;
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
.browser-panel-content {
|
|
||||||
flex: 1;
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.browser-panel-content iframe {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.browser-panel-empty {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 100%;
|
|
||||||
color: var(--text-muted);
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
TERMINAL PANEL
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
.agent-terminal-panel {
|
|
||||||
display: none;
|
|
||||||
grid-column: 2;
|
|
||||||
grid-row: 2;
|
|
||||||
border-top: 1px solid var(--border);
|
|
||||||
flex-direction: column;
|
|
||||||
max-height: 200px;
|
|
||||||
min-height: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-mode .agent-terminal-panel {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.terminal-panel-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 6px 12px;
|
|
||||||
background: #1e1e1e;
|
|
||||||
border-bottom: 1px solid #333;
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.terminal-panel-content {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
background: #1e1e1e;
|
|
||||||
padding: 8px 12px;
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.5;
|
|
||||||
color: #d4d4d4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.terminal-line {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.terminal-line.stderr {
|
|
||||||
color: #f87171;
|
|
||||||
}
|
|
||||||
|
|
||||||
.terminal-line.stdout {
|
|
||||||
color: #d4d4d4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
AGENT INFO CARD
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
.agent-info-card {
|
|
||||||
display: none;
|
|
||||||
grid-column: 3;
|
|
||||||
grid-row: 2;
|
|
||||||
border-top: 1px solid var(--border);
|
|
||||||
border-left: 1px solid var(--border);
|
|
||||||
padding: 12px 16px;
|
|
||||||
background: var(--surface);
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-mode .agent-info-card {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-info-name {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-info-dot {
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-level-badge {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 10px;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge-evolved {
|
|
||||||
background: var(--accent);
|
|
||||||
color: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge-bred {
|
|
||||||
background: #f59e0b;
|
|
||||||
color: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge-wild {
|
|
||||||
background: #ef4444;
|
|
||||||
color: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-info-model {
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-info-toggles {
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-toggle {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-toggle-switch {
|
|
||||||
width: 28px;
|
|
||||||
height: 16px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background: #ccc;
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background 0.2s;
|
|
||||||
border: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-toggle-switch.on {
|
|
||||||
background: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-toggle-switch::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
left: 2px;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--bg);
|
|
||||||
transition: transform 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-toggle-switch.on::after {
|
|
||||||
transform: translateX(12px);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
STEP COUNTER BAR
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
.agent-step-bar {
|
|
||||||
display: none;
|
|
||||||
grid-column: 1 / -1;
|
|
||||||
grid-row: 3;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 8px 16px;
|
|
||||||
background: var(--surface);
|
|
||||||
border-top: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-mode .agent-step-bar {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.step-counter {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.step-nav-btn {
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
background: var(--bg);
|
|
||||||
color: var(--text-muted);
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
transition: all 0.15s;
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.step-nav-btn:hover {
|
|
||||||
border-color: var(--accent);
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.step-action-btns {
|
|
||||||
display: flex;
|
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.step-action-btn {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: none;
|
|
||||||
background: var(--accent);
|
|
||||||
color: var(--bg);
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
transition: all 0.15s;
|
|
||||||
font-size: 16px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.step-action-btn:hover {
|
|
||||||
transform: scale(1.1);
|
|
||||||
box-shadow: 0 2px 8px rgba(132, 214, 105, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
TODO LIST (OpenClaw style)
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
.agent-todo-list {
|
|
||||||
margin: 12px 0;
|
|
||||||
border: 1px solid var(--border, var(--border));
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-todo-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 8px 14px;
|
|
||||||
background: var(--surface, var(--border));
|
|
||||||
font-family: 'Fira Code', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--text, var(--text));
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-todo-count {
|
|
||||||
background: var(--accent);
|
|
||||||
color: var(--bg);
|
|
||||||
padding: 1px 6px;
|
|
||||||
border-radius: 10px;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-todo-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
padding: 8px 14px;
|
|
||||||
border-top: 1px solid var(--border, var(--border));
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--text, var(--text));
|
|
||||||
transition: opacity 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-todo-item.done {
|
|
||||||
opacity: 0.5;
|
|
||||||
text-decoration: line-through;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-todo-check {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 2px solid #ccc;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.agent-todo-item.done .agent-todo-check {
|
|
||||||
background: var(--accent);
|
|
||||||
border-color: var(--accent);
|
|
||||||
color: var(--bg);
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
/* Config Color Overrides */
|
|
||||||
/* Maps theme-color1 and theme-color2 from config.csv to actual theme variables */
|
|
||||||
|
|
||||||
:root {
|
|
||||||
/* Use --color1 and --color2 from config.csv, with fallback defaults */
|
|
||||||
--sentient-accent: var(--color1, #3b82f6);
|
|
||||||
--primary: var(--color1, #3b82f6);
|
|
||||||
--primary-hover: color-mix(in srgb, var(--color1, #3b82f6) 85%, black);
|
|
||||||
--primary-light: color-mix(in srgb, var(--color1, #3b82f6) 10%, transparent);
|
|
||||||
--chart-1: var(--color1, #3b82f6);
|
|
||||||
--chart-2: var(--color2, #f59e0b);
|
|
||||||
--ring: var(--color1, #3b82f6);
|
|
||||||
|
|
||||||
/* Background can use color2 for subtle tint */
|
|
||||||
/* --sentient-bg-primary stays white/light for text readability */
|
|
||||||
}
|
|
||||||
|
|
@ -1,295 +0,0 @@
|
||||||
.app-icon {
|
|
||||||
background: var(--surface-hover, #ffffff);
|
|
||||||
border: 1px solid var(--border, #e5e7eb);
|
|
||||||
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.05);
|
|
||||||
/* removed border */
|
|
||||||
/* removed border bottom */
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-bg {
|
|
||||||
background-color: var(--bg, #fafdfa);
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-grid {
|
|
||||||
background-image:
|
|
||||||
linear-gradient(to right, var(--border, #f0fdf4) 1px, transparent 1px),
|
|
||||||
linear-gradient(to bottom, var(--border, #f0fdf4) 1px, transparent 1px);
|
|
||||||
background-size: 40px 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Custom scrollbar for terminal */
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: var(--surface-active, #333);
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: var(--border-hover, #555);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Window Manager Core Styles (replacing missing Tailwind classes) */
|
|
||||||
.window-element {
|
|
||||||
position: absolute;
|
|
||||||
width: 700px;
|
|
||||||
height: 500px;
|
|
||||||
background-color: var(--surface, white);
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
border: 1px solid var(--border, #e5e7eb);
|
|
||||||
overflow: hidden;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-header {
|
|
||||||
height: 40px;
|
|
||||||
background-color: var(--surface, #ffffff);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 16px;
|
|
||||||
border-bottom: 1px solid var(--border, #e5e7eb);
|
|
||||||
user-select: none;
|
|
||||||
cursor: move;
|
|
||||||
position: relative;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-header .font-mono {
|
|
||||||
font-family: "Fira Code", monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: var(--accent, #16a34a); /* brand-600 */
|
|
||||||
letter-spacing: 0.025em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-header-controls {
|
|
||||||
display: flex;
|
|
||||||
gap: 12px;
|
|
||||||
color: var(--text-muted, #9ca3af);
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-header button {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
color: inherit;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-header .btn-minimize:hover,
|
|
||||||
.window-header .btn-maximize:hover {
|
|
||||||
color: var(--text, #4b5563);
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-header .btn-close:hover {
|
|
||||||
color: var(--error, #ef4444);
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-body {
|
|
||||||
position: relative;
|
|
||||||
flex: 1 1 0%;
|
|
||||||
overflow-y: auto;
|
|
||||||
background-color: var(--bg, #fafdfa);
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-\[700px\] {
|
|
||||||
width: 700px;
|
|
||||||
}
|
|
||||||
.h-\[500px\] {
|
|
||||||
height: 500px;
|
|
||||||
}
|
|
||||||
.bg-white {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.rounded-lg {
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
}
|
|
||||||
.shadow-2xl {
|
|
||||||
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
.flex {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.flex-col {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.border {
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
}
|
|
||||||
.border-gray-200 {
|
|
||||||
border-color: #e5e7eb;
|
|
||||||
}
|
|
||||||
.overflow-hidden {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.absolute {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-10 {
|
|
||||||
height: 2.5rem;
|
|
||||||
}
|
|
||||||
.bg-white\/95 {
|
|
||||||
background-color: var(--surface, rgba(255, 255, 255, 0.95));
|
|
||||||
}
|
|
||||||
.backdrop-blur {
|
|
||||||
backdrop-filter: blur(8px);
|
|
||||||
}
|
|
||||||
.items-center {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.justify-between {
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.px-4 {
|
|
||||||
padding-left: 1rem;
|
|
||||||
padding-right: 1rem;
|
|
||||||
}
|
|
||||||
.border-b {
|
|
||||||
border-bottom-width: 1px;
|
|
||||||
}
|
|
||||||
.select-none {
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
.cursor-move {
|
|
||||||
cursor: move;
|
|
||||||
}
|
|
||||||
.font-mono {
|
|
||||||
font-family:
|
|
||||||
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
|
||||||
"Liberation Mono", "Courier New", monospace;
|
|
||||||
}
|
|
||||||
.text-xs {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
line-height: 1rem;
|
|
||||||
}
|
|
||||||
.font-bold {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
.text-brand-600 {
|
|
||||||
color: var(--accent, #84d669);
|
|
||||||
}
|
|
||||||
.tracking-wide {
|
|
||||||
letter-spacing: 0.025em;
|
|
||||||
}
|
|
||||||
.space-x-3 > :not([hidden]) ~ :not([hidden]) {
|
|
||||||
--tw-space-x-reverse: 0;
|
|
||||||
margin-right: calc(0.75rem * var(--tw-space-x-reverse));
|
|
||||||
margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
|
|
||||||
}
|
|
||||||
.text-gray-400 {
|
|
||||||
color: var(--text-muted, #9ca3af);
|
|
||||||
}
|
|
||||||
.hover\:text-gray-600:hover {
|
|
||||||
color: var(--text, #4b5563);
|
|
||||||
}
|
|
||||||
.hover\:text-red-500:hover {
|
|
||||||
color: var(--error, #ef4444);
|
|
||||||
}
|
|
||||||
.relative {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.flex-1 {
|
|
||||||
flex: 1 1 0%;
|
|
||||||
}
|
|
||||||
.overflow-y-auto {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.bg-\[\#fafdfa\] {
|
|
||||||
background-color: var(--bg, #fafdfa);
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-header {
|
|
||||||
height: 40px;
|
|
||||||
background-color: var(--surface, #ffffff);
|
|
||||||
border-bottom: 1px solid var(--border, #e5e7eb);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 16px;
|
|
||||||
user-select: none;
|
|
||||||
cursor: move;
|
|
||||||
position: relative;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
.window-header .font-mono {
|
|
||||||
font-family: "Fira Code", monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: var(--accent, #16a34a);
|
|
||||||
letter-spacing: 0.025em;
|
|
||||||
}
|
|
||||||
.window-header .flex {
|
|
||||||
display: flex;
|
|
||||||
gap: 12px;
|
|
||||||
color: var(--text-muted, #9ca3af);
|
|
||||||
}
|
|
||||||
.window-header button {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 0.15s ease;
|
|
||||||
}
|
|
||||||
.window-header button:hover {
|
|
||||||
color: var(--text, #4b5563);
|
|
||||||
}
|
|
||||||
.window-header .btn-close:hover {
|
|
||||||
color: var(--error, #ef4444);
|
|
||||||
}
|
|
||||||
.window-content {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
position: relative;
|
|
||||||
background-color: var(--bg, #ffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hide background content when window is maximized */
|
|
||||||
body.window-maximized .sidebar,
|
|
||||||
body.window-maximized .toolbar,
|
|
||||||
body.window-maximized .sidebar-item,
|
|
||||||
body.window-maximized .desktop-icon,
|
|
||||||
body.window-maximized .panel-grid,
|
|
||||||
body.window-maximized .workspace-grid,
|
|
||||||
body.window-maximized .bg-grid,
|
|
||||||
body.window-maximized .bg-svg {
|
|
||||||
display: none !important;
|
|
||||||
visibility: hidden !important;
|
|
||||||
opacity: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure maximized window fills the screen without minibar offset */
|
|
||||||
body.window-maximized .window-element {
|
|
||||||
z-index: 9998 !important; /* Lower than minibar's 9999 */
|
|
||||||
top: 0 !important; /* No minibar offset - start at top */
|
|
||||||
height: 100vh !important; /* Fill entire screen height */
|
|
||||||
width: 100vw !important; /* Fill entire screen width */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure window body is opaque */
|
|
||||||
.window-body {
|
|
||||||
background-color: var(--bg, #fafdfa) !important;
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure window element is fully opaque */
|
|
||||||
.window-element {
|
|
||||||
background-color: var(--surface, #ffffff) !important;
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fix theme dropdown background - use surface color to adapt to theme */
|
|
||||||
/* This overrides hardcoded black background from other CSS files */
|
|
||||||
#themeDropdown,
|
|
||||||
select.theme-dropdown {
|
|
||||||
background: var(--surface) !important;
|
|
||||||
}
|
|
||||||
|
|
@ -395,155 +395,3 @@
|
||||||
-webkit-line-clamp: 3;
|
-webkit-line-clamp: 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================ */
|
|
||||||
/* MARKDOWN MESSAGE STYLING */
|
|
||||||
/* ============================================ */
|
|
||||||
|
|
||||||
/* Lists in message content */
|
|
||||||
.message-content ul,
|
|
||||||
.message-content ol {
|
|
||||||
margin: 12px 0;
|
|
||||||
padding-left: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* List items with proper spacing from border */
|
|
||||||
.message-content li {
|
|
||||||
margin: 8px 0;
|
|
||||||
line-height: 1.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nested lists */
|
|
||||||
.message-content ul ul,
|
|
||||||
.message-content ol ol,
|
|
||||||
.message-content ul ol,
|
|
||||||
.message-content ol ul {
|
|
||||||
margin: 8px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bullet points */
|
|
||||||
.message-content ul li {
|
|
||||||
list-style-type: disc;
|
|
||||||
padding-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ul li::marker {
|
|
||||||
color: var(--chat-color1, var(--accent, var(--primary, #3b82f6)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nested bullets */
|
|
||||||
.message-content ul ul li {
|
|
||||||
list-style-type: circle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ul ul ul li {
|
|
||||||
list-style-type: square;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Numbered lists */
|
|
||||||
.message-content ol li {
|
|
||||||
list-style-type: decimal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nested numbered lists */
|
|
||||||
.message-content ol ol li {
|
|
||||||
list-style-type: lower-alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ol ol ol li {
|
|
||||||
list-style-type: lower-roman;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lists in user messages */
|
|
||||||
.message.user .message-content ul li::marker,
|
|
||||||
.message.user .message-content ol li::marker {
|
|
||||||
color: rgba(255, 255, 255, 0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lists in bot messages */
|
|
||||||
.message.bot .message-content ul li::marker,
|
|
||||||
.message.bot .message-content ol li::marker {
|
|
||||||
color: var(--chat-color1, var(--accent, var(--primary, #3b82f6)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Paragraphs in messages */
|
|
||||||
.message-content p {
|
|
||||||
margin: 8px 0;
|
|
||||||
line-height: 1.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* First and last paragraph spacing */
|
|
||||||
.message-content p:first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content p:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Headings in messages */
|
|
||||||
.message-content h1,
|
|
||||||
.message-content h2,
|
|
||||||
.message-content h3,
|
|
||||||
.message-content h4,
|
|
||||||
.message-content h5,
|
|
||||||
.message-content h6 {
|
|
||||||
margin: 16px 0 8px 0;
|
|
||||||
font-weight: 600;
|
|
||||||
line-height: 1.3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content h1 { font-size: 1.5em; }
|
|
||||||
.message-content h2 { font-size: 1.3em; }
|
|
||||||
.message-content h3 { font-size: 1.15em; }
|
|
||||||
.message-content h4 { font-size: 1.05em; }
|
|
||||||
|
|
||||||
/* Code blocks */
|
|
||||||
.message-content pre {
|
|
||||||
margin: 12px 0;
|
|
||||||
padding: 12px;
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow-x: auto;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inline code */
|
|
||||||
.message-content code {
|
|
||||||
padding: 2px 6px;
|
|
||||||
background: rgba(0, 0, 0, 0.15);
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message.user .message-content code {
|
|
||||||
background: rgba(255, 255, 255, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Blockquotes */
|
|
||||||
.message-content blockquote {
|
|
||||||
margin: 12px 0;
|
|
||||||
padding-left: 16px;
|
|
||||||
border-left: 3px solid var(--chat-color1, var(--accent, var(--primary, #3b82f6)));
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Horizontal rules */
|
|
||||||
.message-content hr {
|
|
||||||
margin: 16px 0;
|
|
||||||
border: none;
|
|
||||||
border-top: 1px solid rgba(128, 128, 128, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Links in messages */
|
|
||||||
.message-content a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: underline;
|
|
||||||
text-decoration-color: rgba(128, 128, 128, 0.5);
|
|
||||||
transition: text-decoration-color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content a:hover {
|
|
||||||
text-decoration-color: currentColor;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,241 +0,0 @@
|
||||||
/* Markdown Message Styling - Better lists and spacing for chat messages */
|
|
||||||
|
|
||||||
/* Lists in message content */
|
|
||||||
.message-content ul,
|
|
||||||
.message-content ol {
|
|
||||||
margin: 16px 0 !important;
|
|
||||||
padding-left: 28px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extra space between list container edge and bullets */
|
|
||||||
.message-content ul li,
|
|
||||||
.message-content ol li {
|
|
||||||
margin-left: 0px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* List items with better spacing */
|
|
||||||
.message-content li {
|
|
||||||
margin: 10px 0;
|
|
||||||
line-height: 1.8;
|
|
||||||
position: relative;
|
|
||||||
padding-left: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nested lists with visual hierarchy */
|
|
||||||
.message-content ul ul,
|
|
||||||
.message-content ol ol,
|
|
||||||
.message-content ul ol,
|
|
||||||
.message-content ol ul {
|
|
||||||
margin: 12px 0;
|
|
||||||
padding-left: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bullet points with better visual weight */
|
|
||||||
.message-content ul li {
|
|
||||||
list-style-type: disc;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ul li::marker {
|
|
||||||
color: var(--chat-color1, var(--accent, var(--primary, #3b82f6)));
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nested bullets with distinct styles */
|
|
||||||
.message-content ul ul li {
|
|
||||||
list-style-type: circle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ul ul li::marker {
|
|
||||||
font-size: 1em;
|
|
||||||
opacity: 0.85;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ul ul ul li {
|
|
||||||
list-style-type: square;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ul ul ul li::marker {
|
|
||||||
font-size: 0.95em;
|
|
||||||
opacity: 0.75;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Numbered lists with better styling */
|
|
||||||
.message-content ol li {
|
|
||||||
list-style-type: decimal;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ol li::marker {
|
|
||||||
color: var(--chat-color1, var(--accent, var(--primary, #3b82f6)));
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nested numbered lists with visual hierarchy */
|
|
||||||
.message-content ol ol li {
|
|
||||||
list-style-type: lower-alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ol ol li::marker {
|
|
||||||
font-weight: 500;
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ol ol ol li {
|
|
||||||
list-style-type: lower-roman;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content ol ol ol li::marker {
|
|
||||||
font-weight: 400;
|
|
||||||
opacity: 0.85;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lists in user messages (white text on colored background) */
|
|
||||||
.message.user .message-content ul li::marker,
|
|
||||||
.message.user .message-content ol li::marker {
|
|
||||||
color: rgba(255, 255, 255, 0.95);
|
|
||||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.message.user .message-content ul ul li::marker,
|
|
||||||
.message.user .message-content ol ol li::marker {
|
|
||||||
color: rgba(255, 255, 255, 0.85);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lists in bot messages with better contrast */
|
|
||||||
.message.bot .message-content ul li::marker,
|
|
||||||
.message.bot .message-content ol li::marker {
|
|
||||||
color: var(--chat-color1, var(--accent, var(--primary, #3b82f6)));
|
|
||||||
}
|
|
||||||
|
|
||||||
.message.bot .message-content ul ul li::marker,
|
|
||||||
.message.bot .message-content ol ol li::marker {
|
|
||||||
color: var(--chat-color1, var(--accent, var(--primary, #3b82f6)));
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Paragraphs in messages */
|
|
||||||
.message-content p {
|
|
||||||
margin: 10px 0;
|
|
||||||
line-height: 1.75;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* First and last paragraph spacing */
|
|
||||||
.message-content p:first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content p:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lists with better visual separation from paragraphs */
|
|
||||||
.message-content ul + p,
|
|
||||||
.message-content ol + p,
|
|
||||||
.message-content p + ul,
|
|
||||||
.message-content p + ol {
|
|
||||||
margin-top: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Headings in messages */
|
|
||||||
.message-content h1,
|
|
||||||
.message-content h2,
|
|
||||||
.message-content h3,
|
|
||||||
.message-content h4,
|
|
||||||
.message-content h5,
|
|
||||||
.message-content h6 {
|
|
||||||
margin: 18px 0 10px 0;
|
|
||||||
font-weight: 600;
|
|
||||||
line-height: 1.3;
|
|
||||||
letter-spacing: -0.01em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content h1 { font-size: 1.5em; }
|
|
||||||
.message-content h2 { font-size: 1.3em; }
|
|
||||||
.message-content h3 { font-size: 1.15em; }
|
|
||||||
.message-content h4 { font-size: 1.05em; }
|
|
||||||
|
|
||||||
/* Headings in user messages */
|
|
||||||
.message.user .message-content h1,
|
|
||||||
.message.user .message-content h2,
|
|
||||||
.message.user .message-content h3 {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Headings in bot messages */
|
|
||||||
.message.bot .message-content h1,
|
|
||||||
.message.bot .message-content h2,
|
|
||||||
.message.bot .message-content h3 {
|
|
||||||
color: #1a1a1a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Code blocks */
|
|
||||||
.message-content pre {
|
|
||||||
margin: 12px 0;
|
|
||||||
padding: 14px;
|
|
||||||
background: rgba(0, 0, 0, 0.15);
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow-x: auto;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.6;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inline code */
|
|
||||||
.message-content code {
|
|
||||||
padding: 3px 7px;
|
|
||||||
background: rgba(0, 0, 0, 0.12);
|
|
||||||
border-radius: 5px;
|
|
||||||
font-size: 0.9em;
|
|
||||||
font-family: "Monaco", "Menlo", "Consolas", monospace;
|
|
||||||
letter-spacing: 0.02em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message.user .message-content code {
|
|
||||||
background: rgba(255, 255, 255, 0.25);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.message.bot .message-content code {
|
|
||||||
background: rgba(0, 0, 0, 0.08);
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Blockquotes */
|
|
||||||
.message-content blockquote {
|
|
||||||
margin: 12px 0;
|
|
||||||
padding-left: 16px;
|
|
||||||
border-left: 3px solid var(--chat-color1, var(--accent, var(--primary, #3b82f6)));
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Horizontal rules */
|
|
||||||
.message-content hr {
|
|
||||||
margin: 16px 0;
|
|
||||||
border: none;
|
|
||||||
border-top: 1px solid rgba(128, 128, 128, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Links in messages */
|
|
||||||
.message-content a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: underline;
|
|
||||||
text-decoration-color: rgba(128, 128, 128, 0.5);
|
|
||||||
transition: text-decoration-color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-content a:hover {
|
|
||||||
text-decoration-color: currentColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Strong/bold text */
|
|
||||||
.message-content strong,
|
|
||||||
.message-content b {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emphasis/italic text */
|
|
||||||
.message-content em,
|
|
||||||
.message-content i {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
@ -876,7 +876,7 @@
|
||||||
[data-theme="sentient"] input,
|
[data-theme="sentient"] input,
|
||||||
[data-theme="sentient"] textarea,
|
[data-theme="sentient"] textarea,
|
||||||
[data-theme="sentient"] select {
|
[data-theme="sentient"] select {
|
||||||
background: var(--surface);
|
background: var(--input-bg);
|
||||||
border: 1px solid var(--input-border);
|
border: 1px solid var(--input-border);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|
@ -884,12 +884,6 @@
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure theme dropdown uses surface color in all themes */
|
|
||||||
[data-theme="sentient"] select.theme-dropdown,
|
|
||||||
[data-theme="sentient"] #themeDropdown {
|
|
||||||
background: var(--surface) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="sentient"] input:focus,
|
[data-theme="sentient"] input:focus,
|
||||||
[data-theme="sentient"] textarea:focus,
|
[data-theme="sentient"] textarea:focus,
|
||||||
[data-theme="sentient"] select:focus {
|
[data-theme="sentient"] select:focus {
|
||||||
|
|
|
||||||
9
ui/suite/css/vendor/all.min.css
vendored
9
ui/suite/css/vendor/all.min.css
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -12,10 +12,6 @@
|
||||||
|
|
||||||
<!-- Styles -->
|
<!-- Styles -->
|
||||||
<link rel="stylesheet" href="css/app.css" />
|
<link rel="stylesheet" href="css/app.css" />
|
||||||
<!-- Config color overrides -->
|
|
||||||
<link rel="stylesheet" href="css/config-colors.css" />
|
|
||||||
<!-- Markdown message styling -->
|
|
||||||
<link rel="stylesheet" href="css/markdown-message.css" />
|
|
||||||
|
|
||||||
<!-- Local Libraries (no external CDN dependencies) -->
|
<!-- Local Libraries (no external CDN dependencies) -->
|
||||||
<script src="js/vendor/gsap.min.js"></script>
|
<script src="js/vendor/gsap.min.js"></script>
|
||||||
|
|
@ -51,7 +47,10 @@
|
||||||
<!-- Right: Theme selector, Apps menu and user avatar -->
|
<!-- Right: Theme selector, Apps menu and user avatar -->
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<!-- Theme dropdown selector -->
|
<!-- Theme dropdown selector -->
|
||||||
|
<div
|
||||||
|
id="themeSelectorContainer"
|
||||||
|
aria-label="Theme selector"
|
||||||
|
></div>
|
||||||
|
|
||||||
<!-- Apps menu button -->
|
<!-- Apps menu button -->
|
||||||
<button
|
<button
|
||||||
|
|
@ -157,34 +156,34 @@
|
||||||
<!-- Application initialization -->
|
<!-- Application initialization -->
|
||||||
<script>
|
<script>
|
||||||
// Initialize application
|
// Initialize application
|
||||||
(function initApp() {
|
(function initApp() {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Initialize ThemeManager
|
// Initialize ThemeManager
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
console.log("🚀 Initializing General Bots Desktop...");
|
console.log("🚀 Initializing General Bots Desktop...");
|
||||||
|
|
||||||
// Initialize theme system
|
// Initialize theme system
|
||||||
if (window.ThemeManager) {
|
if (window.ThemeManager) {
|
||||||
ThemeManager.init();
|
ThemeManager.init();
|
||||||
console.log("✓ Theme Manager initialized");
|
console.log("✓ Theme Manager initialized");
|
||||||
} else {
|
} else {
|
||||||
console.warn("⚠ ThemeManager not found");
|
console.warn("⚠ ThemeManager not found");
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize apps menu
|
|
||||||
initAppsMenu();
|
|
||||||
|
|
||||||
// Hide loading overlay after initialization
|
|
||||||
setTimeout(() => {
|
|
||||||
const loadingOverlay =
|
|
||||||
document.getElementById("loadingOverlay");
|
|
||||||
if (loadingOverlay) {
|
|
||||||
loadingOverlay.classList.add("hidden");
|
|
||||||
console.log("✓ Application ready");
|
|
||||||
}
|
}
|
||||||
}, 500);
|
|
||||||
});
|
// Initialize apps menu
|
||||||
|
initAppsMenu();
|
||||||
|
|
||||||
|
// Hide loading overlay after initialization
|
||||||
|
setTimeout(() => {
|
||||||
|
const loadingOverlay =
|
||||||
|
document.getElementById("loadingOverlay");
|
||||||
|
if (loadingOverlay) {
|
||||||
|
loadingOverlay.classList.add("hidden");
|
||||||
|
console.log("✓ Application ready");
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
|
||||||
// Apps menu functionality
|
// Apps menu functionality
|
||||||
function initAppsMenu() {
|
function initAppsMenu() {
|
||||||
|
|
|
||||||
|
|
@ -1,733 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>General Bots Desktop</title>
|
|
||||||
|
|
||||||
<!-- Link to the existing compiled CSS -->
|
|
||||||
<link rel="stylesheet" href="/suite/css/app.css" />
|
|
||||||
<link rel="stylesheet" href="/suite/css/base.css" />
|
|
||||||
<link rel="stylesheet" href="/suite/css/theme-sentient.css" />
|
|
||||||
<link rel="stylesheet" href="/suite/css/desktop.css" />
|
|
||||||
|
|
||||||
<!-- Local JS requirements per AGENTS.md / UI.md -->
|
|
||||||
<script src="/suite/js/vendor/htmx.min.js"></script>
|
|
||||||
<script src="/suite/js/vendor/marked.min.js"></script>
|
|
||||||
<script src="/suite/js/window-manager.js?v=2"></script>
|
|
||||||
<script src="/suite/js/theme-manager.js"></script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: "Fira Code", "Fira Sans", Arial, sans-serif;
|
|
||||||
background: var(--bg, #ffffff);
|
|
||||||
color: var(--text, #333333);
|
|
||||||
overflow: hidden;
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Core Layout replicating BUILD V3 screenshot styling */
|
|
||||||
.build-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
background: var(--bg, #ffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Left Sidebar */
|
|
||||||
.sidebar {
|
|
||||||
width: 51px;
|
|
||||||
height: 100%;
|
|
||||||
background: var(--bg-secondary, #f8f8f8);
|
|
||||||
border-right: 1px solid #d1d5db;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-item {
|
|
||||||
width: 51px;
|
|
||||||
height: 50px;
|
|
||||||
border-bottom: 1px solid var(--border-color, #f0f1f2);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-item:hover {
|
|
||||||
background: var(--bg, #ffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-item.active {
|
|
||||||
background: var(--bg, #ffffff);
|
|
||||||
border-left: 3px solid var(--primary, #84d669);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-icon {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
stroke: var(--text-secondary, #3b3b3b);
|
|
||||||
opacity: 0.6;
|
|
||||||
transition:
|
|
||||||
stroke 0.15s ease,
|
|
||||||
opacity 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-item:hover .sidebar-icon {
|
|
||||||
opacity: 1;
|
|
||||||
stroke: var(--text, #3b3b3b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main Content wrapper */
|
|
||||||
.main-wrapper {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Top Navigation Tabs - Removed (already in Vibe) */
|
|
||||||
|
|
||||||
/* Workspace (Where windows float) */
|
|
||||||
.workspace {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
background: var(--bg, #ffffff);
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The Panel Grid (Desktop Icons) */
|
|
||||||
.panel-section {
|
|
||||||
flex: 1;
|
|
||||||
padding: 26px 33px;
|
|
||||||
overflow-y: auto;
|
|
||||||
z-index: 10;
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Interactive Desktop Icons triggering HTMX */
|
|
||||||
.desktop-icons-container {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 20px;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: flex-end;
|
|
||||||
width: auto;
|
|
||||||
pointer-events: auto;
|
|
||||||
position: absolute;
|
|
||||||
right: 33px;
|
|
||||||
top: 26px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.desktop-icon {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
width: 80px;
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-icon {
|
|
||||||
width: 64px;
|
|
||||||
height: 64px;
|
|
||||||
border-radius: 16px;
|
|
||||||
background: var(--surface-hover, #ffffff);
|
|
||||||
border: 1px solid var(--border, #e5e7eb);
|
|
||||||
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.05);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
transition: transform 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.desktop-icon:hover .app-icon {
|
|
||||||
transform: scale(1.05);
|
|
||||||
border-color: var(--accent, #84d669);
|
|
||||||
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-icon svg {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
stroke: var(--text, #374151);
|
|
||||||
transition: stroke 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.desktop-icon:hover .app-icon svg {
|
|
||||||
stroke: var(--accent, #84d669);
|
|
||||||
}
|
|
||||||
|
|
||||||
.desktop-icon-label {
|
|
||||||
font-family: "Fira Code", monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--text-secondary, #374151);
|
|
||||||
background: transparent;
|
|
||||||
backdrop-filter: blur(4px);
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-grid {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-svg {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bottom Taskbar */
|
|
||||||
.toolbar {
|
|
||||||
height: 50px;
|
|
||||||
background: var(--surface);
|
|
||||||
border-top: 1px solid var(--border);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 8px;
|
|
||||||
z-index: 100;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#taskbar-apps {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-time {
|
|
||||||
font-family: "Fira Code", monospace;
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--text-secondary, #3b3b3b);
|
|
||||||
text-align: right;
|
|
||||||
line-height: 1.4;
|
|
||||||
padding: 0 10px;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Taskbar Items generated by WindowManager */
|
|
||||||
.taskbar-item {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.15s ease;
|
|
||||||
border-bottom: 2px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Fullscreen Mode Styles */
|
|
||||||
body.fullscreen .sidebar {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.fullscreen .toolbar {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.fullscreen .panel-section {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.fullscreen .workspace {
|
|
||||||
height: 100vh !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.fullscreen .main-wrapper {
|
|
||||||
height: 100vh !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.fullscreen .window-titlebar {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.fullscreen .window {
|
|
||||||
border: none !important;
|
|
||||||
border-radius: 0 !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hide window title bar and controls in fullscreen */
|
|
||||||
body.fullscreen .window > div:first-child {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.fullscreen .window > div:nth-child(2) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- Minibar removed - login moved to taskbar -->
|
|
||||||
|
|
||||||
<div class="build-container">
|
|
||||||
<!-- Left Sidebar -->
|
|
||||||
<aside class="sidebar">
|
|
||||||
<div
|
|
||||||
class="sidebar-item active"
|
|
||||||
title="Home"
|
|
||||||
onclick="if(window.wm) window.wm.open('home', 'Home', '<div style=\'padding:20px;text-align:center;\'><h2>Welcome to General Bots Desktop</h2></div>');"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"
|
|
||||||
></path>
|
|
||||||
<polyline points="9 22 9 12 15 12 15 22"></polyline>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sidebar-item"
|
|
||||||
title="Search"
|
|
||||||
onclick="alert('Search coming soon');"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<circle cx="11" cy="11" r="8"></circle>
|
|
||||||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sidebar-item"
|
|
||||||
title="Terminal"
|
|
||||||
onclick="fetch('/suite/terminal/terminal.html').then(r=>r.text()).then(html=>{if(window.wm)window.wm.open('terminal','Terminal',html);});"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<polyline points="4 17 10 11 4 5"></polyline>
|
|
||||||
<line x1="12" y1="19" x2="20" y2="19"></line>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sidebar-item"
|
|
||||||
title="User"
|
|
||||||
onclick="alert('User profile coming soon');"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"
|
|
||||||
></path>
|
|
||||||
<circle cx="12" cy="7" r="4"></circle>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sidebar-item"
|
|
||||||
title="Apps"
|
|
||||||
onclick="if(window.wm) window.wm.open('apps', 'Applications', '<div style=\'padding:20px;\'><h3>Installed Applications</h3><p>Click desktop icons to launch apps.</p></div>');"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<rect x="3" y="3" width="7" height="7"></rect>
|
|
||||||
<rect x="14" y="3" width="7" height="7"></rect>
|
|
||||||
<rect x="14" y="14" width="7" height="7"></rect>
|
|
||||||
<rect x="3" y="14" width="7" height="7"></rect>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sidebar-item"
|
|
||||||
style="margin-top: auto"
|
|
||||||
title="Settings"
|
|
||||||
onclick="fetch('/suite/admin/organization-settings.html').then(r=>r.text()).then(html=>{if(window.wm)window.wm.open('settings','Settings',html);}).catch(e=>alert('Settings page not found'));"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<circle cx="12" cy="12" r="3"></circle>
|
|
||||||
<path
|
|
||||||
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<!-- Main Wrapper -->
|
|
||||||
<div class="main-wrapper">
|
|
||||||
<!-- Top Navigation Tabs - Removed (already in Vibe) -->
|
|
||||||
|
|
||||||
<!-- Workspace container where WindowManager operates -->
|
|
||||||
<div class="workspace" id="desktop-content">
|
|
||||||
<!-- Background Pattern -->
|
|
||||||
|
|
||||||
<div class="panel-section">
|
|
||||||
<div class="desktop-icons-container">
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="vibe"
|
|
||||||
data-app-title="Vibe"
|
|
||||||
hx-get="/suite/partials/vibe.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Vibe</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="tasks"
|
|
||||||
data-app-title="Tasks"
|
|
||||||
hx-get="/suite/tasks/task-window.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path d="M9 11l3 3L22 4" />
|
|
||||||
<path
|
|
||||||
d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Tasks</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="chat"
|
|
||||||
data-app-title="Chat"
|
|
||||||
hx-get="/suite/partials/chat.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Chat</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="terminal"
|
|
||||||
data-app-title="Terminal"
|
|
||||||
hx-get="/suite/terminal/terminal.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<polyline points="4 17 10 11 4 5" />
|
|
||||||
<line x1="12" y1="19" x2="20" y2="19" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Terminal</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="drive"
|
|
||||||
data-app-title="Explorer"
|
|
||||||
hx-get="/suite/drive/drive.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Explorer</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="editor"
|
|
||||||
data-app-title="Editor"
|
|
||||||
hx-get="/suite/editor.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<polyline points="16 18 22 12 16 6" />
|
|
||||||
<polyline points="8 6 2 12 8 18" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Editor</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="browser"
|
|
||||||
data-app-title="Browser"
|
|
||||||
hx-get="/suite/browser/browser.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<circle cx="12" cy="12" r="10" />
|
|
||||||
<polygon
|
|
||||||
points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Browser</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Bottom Taskbar -->
|
|
||||||
<footer class="toolbar" id="taskbar">
|
|
||||||
<div id="taskbar-apps">
|
|
||||||
<!-- Taskbar items populated automatically by window-manager.js -->
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="toolbar-time"
|
|
||||||
style="display: flex; align-items: center; gap: 15px"
|
|
||||||
>
|
|
||||||
<div id="themeSelectorContainer"></div>
|
|
||||||
<button
|
|
||||||
id="loginBtn"
|
|
||||||
onclick="window.location.href='/suite/auth/login.html'"
|
|
||||||
style="
|
|
||||||
background: var(--primary, #84d669);
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 6px 12px;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
cursor: pointer;
|
|
||||||
font-family: "Fira Code", monospace;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Sign In
|
|
||||||
</button>
|
|
||||||
<div style="text-align: right">
|
|
||||||
<div id="clock-time">00:00</div>
|
|
||||||
<div id="clock-date">01/01/2026</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- HTMX Intercepts and WindowManager Init as described in UI.md Phase 3 -->
|
|
||||||
<script>
|
|
||||||
// Check for fullscreen mode
|
|
||||||
(function() {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
if (urlParams.get('fullscreen') === 'true') {
|
|
||||||
document.body.classList.add('fullscreen');
|
|
||||||
console.log('Fullscreen mode activated');
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", async () => {
|
|
||||||
// Initialize WindowManager
|
|
||||||
if (typeof window.WindowManager !== "undefined") {
|
|
||||||
window.wm = window.WindowManager;
|
|
||||||
} else {
|
|
||||||
console.error(
|
|
||||||
"WindowManager class not loaded from window-manager.js",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize ThemeManager
|
|
||||||
if (typeof window.ThemeManager !== "undefined") {
|
|
||||||
window.ThemeManager.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-open Chat window maximized on desktop load
|
|
||||||
if (window.wm) {
|
|
||||||
try {
|
|
||||||
const response = await fetch(
|
|
||||||
"/suite/partials/chat.html",
|
|
||||||
);
|
|
||||||
if (response.ok) {
|
|
||||||
const htmlContent = await response.text();
|
|
||||||
window.wm.open("chat", "Chat", htmlContent);
|
|
||||||
// Maximize the chat window after opening
|
|
||||||
setTimeout(() => {
|
|
||||||
window.wm.toggleMaximize("chat");
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Failed to auto-open chat:", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Listen to HTMX afterRequest event
|
|
||||||
document.body.addEventListener("htmx:afterRequest", function (evt) {
|
|
||||||
const target = evt.detail.elt;
|
|
||||||
|
|
||||||
// Check if the click came from a desktop icon
|
|
||||||
if (target.classList.contains("desktop-icon")) {
|
|
||||||
const appId = target.getAttribute("data-app-id");
|
|
||||||
const title = target.getAttribute("data-app-title");
|
|
||||||
const htmlContent = evt.detail.xhr.response;
|
|
||||||
|
|
||||||
// Tell WindowManager to open it
|
|
||||||
if (window.wm) {
|
|
||||||
window.wm.open(appId, title, htmlContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure Theme dropdown is re-injected if wiped
|
|
||||||
if (window.ThemeManager) {
|
|
||||||
const container = document.getElementById(
|
|
||||||
"themeSelectorContainer",
|
|
||||||
);
|
|
||||||
if (container && !container.hasChildNodes()) {
|
|
||||||
// Quick and dirty way to re-init
|
|
||||||
window.ThemeManager.init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update login button based on auth state
|
|
||||||
function updateLoginButton() {
|
|
||||||
var token =
|
|
||||||
localStorage.getItem("gb-access-token") ||
|
|
||||||
sessionStorage.getItem("gb-access-token");
|
|
||||||
var loginBtn = document.getElementById("loginBtn");
|
|
||||||
if (token && loginBtn) {
|
|
||||||
loginBtn.textContent = "Sign Out";
|
|
||||||
loginBtn.onclick = function () {
|
|
||||||
fetch("/api/auth/logout", { method: "POST" }).finally(
|
|
||||||
function () {
|
|
||||||
localStorage.removeItem("gb-access-token");
|
|
||||||
sessionStorage.removeItem("gb-access-token");
|
|
||||||
window.location.reload();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check login state on load
|
|
||||||
setTimeout(updateLoginButton, 500);
|
|
||||||
|
|
||||||
// Simple Clock implementation matching the screenshot bottom right corner
|
|
||||||
setInterval(() => {
|
|
||||||
const now = new Date();
|
|
||||||
document.getElementById("clock-time").textContent =
|
|
||||||
now.toLocaleTimeString([], {
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit",
|
|
||||||
});
|
|
||||||
document.getElementById("clock-date").textContent =
|
|
||||||
now.toLocaleDateString();
|
|
||||||
}, 1000);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,680 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>General Bots Desktop</title>
|
|
||||||
|
|
||||||
<!-- Link to the existing compiled CSS -->
|
|
||||||
<link rel="stylesheet" href="/suite/css/app.css" />
|
|
||||||
<link rel="stylesheet" href="/suite/css/base.css" />
|
|
||||||
<link rel="stylesheet" href="/suite/css/theme-sentient.css" />
|
|
||||||
<link rel="stylesheet" href="/suite/css/desktop.css" />
|
|
||||||
|
|
||||||
<!-- Local JS requirements per AGENTS.md / UI.md -->
|
|
||||||
<script src="/suite/js/vendor/htmx.min.js"></script>
|
|
||||||
<script src="/suite/js/vendor/marked.min.js"></script>
|
|
||||||
<script src="/suite/js/window-manager.js?v=2"></script>
|
|
||||||
<script src="/suite/js/theme-manager.js"></script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: "Fira Code", "Fira Sans", Arial, sans-serif;
|
|
||||||
background: var(--bg, #ffffff);
|
|
||||||
color: var(--text, #333333);
|
|
||||||
overflow: hidden;
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Core Layout replicating BUILD V3 screenshot styling */
|
|
||||||
.build-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
background: var(--bg, #ffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Left Sidebar */
|
|
||||||
.sidebar {
|
|
||||||
width: 51px;
|
|
||||||
height: 100%;
|
|
||||||
background: var(--bg-secondary, #f8f8f8);
|
|
||||||
border-right: 1px solid #d1d5db;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-item {
|
|
||||||
width: 51px;
|
|
||||||
height: 50px;
|
|
||||||
border-bottom: 1px solid var(--border-color, #f0f1f2);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-item:hover {
|
|
||||||
background: var(--bg, #ffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-item.active {
|
|
||||||
background: var(--bg, #ffffff);
|
|
||||||
border-left: 3px solid var(--primary, #84d669);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-icon {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
stroke: var(--text-secondary, #3b3b3b);
|
|
||||||
opacity: 0.6;
|
|
||||||
transition:
|
|
||||||
stroke 0.15s ease,
|
|
||||||
opacity 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-item:hover .sidebar-icon {
|
|
||||||
opacity: 1;
|
|
||||||
stroke: var(--text, #3b3b3b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main Content wrapper */
|
|
||||||
.main-wrapper {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Top Navigation Tabs - Removed (already in Vibe) */
|
|
||||||
|
|
||||||
/* Workspace (Where windows float) */
|
|
||||||
.workspace {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
background: var(--bg, #ffffff);
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The Panel Grid (Desktop Icons) */
|
|
||||||
.panel-section {
|
|
||||||
flex: 1;
|
|
||||||
padding: 26px 33px;
|
|
||||||
overflow-y: auto;
|
|
||||||
z-index: 10;
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Interactive Desktop Icons triggering HTMX */
|
|
||||||
.desktop-icons-container {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 20px;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: flex-end;
|
|
||||||
width: auto;
|
|
||||||
pointer-events: auto;
|
|
||||||
position: absolute;
|
|
||||||
right: 33px;
|
|
||||||
top: 26px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.desktop-icon {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
width: 80px;
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-icon {
|
|
||||||
width: 64px;
|
|
||||||
height: 64px;
|
|
||||||
border-radius: 16px;
|
|
||||||
background: var(--surface-hover, #ffffff);
|
|
||||||
border: 1px solid var(--border, #e5e7eb);
|
|
||||||
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.05);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
transition: transform 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.desktop-icon:hover .app-icon {
|
|
||||||
transform: scale(1.05);
|
|
||||||
border-color: var(--accent, #84d669);
|
|
||||||
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-icon svg {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
stroke: var(--text, #374151);
|
|
||||||
transition: stroke 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.desktop-icon:hover .app-icon svg {
|
|
||||||
stroke: var(--accent, #84d669);
|
|
||||||
}
|
|
||||||
|
|
||||||
.desktop-icon-label {
|
|
||||||
font-family: "Fira Code", monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--text-secondary, #374151);
|
|
||||||
background: transparent;
|
|
||||||
backdrop-filter: blur(4px);
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-grid {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-svg {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bottom Taskbar */
|
|
||||||
.toolbar {
|
|
||||||
height: 50px;
|
|
||||||
background: var(--surface);
|
|
||||||
border-top: 1px solid var(--border);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 8px;
|
|
||||||
z-index: 100;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#taskbar-apps {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-time {
|
|
||||||
font-family: "Fira Code", monospace;
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--text-secondary, #3b3b3b);
|
|
||||||
text-align: right;
|
|
||||||
line-height: 1.4;
|
|
||||||
padding: 0 10px;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Taskbar Items generated by WindowManager */
|
|
||||||
.taskbar-item {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.15s ease;
|
|
||||||
border-bottom: 2px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- Minibar removed - login moved to taskbar -->
|
|
||||||
|
|
||||||
<div class="build-container">
|
|
||||||
<!-- Left Sidebar -->
|
|
||||||
<aside class="sidebar">
|
|
||||||
<div
|
|
||||||
class="sidebar-item active"
|
|
||||||
title="Home"
|
|
||||||
onclick="if(window.wm) window.wm.open('home', 'Home', '<div style=\'padding:20px;text-align:center;\'><h2>Welcome to General Bots Desktop</h2></div>');"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"
|
|
||||||
></path>
|
|
||||||
<polyline points="9 22 9 12 15 12 15 22"></polyline>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sidebar-item"
|
|
||||||
title="Search"
|
|
||||||
onclick="alert('Search coming soon');"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<circle cx="11" cy="11" r="8"></circle>
|
|
||||||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sidebar-item"
|
|
||||||
title="Terminal"
|
|
||||||
onclick="fetch('/suite/terminal/terminal.html').then(r=>r.text()).then(html=>{if(window.wm)window.wm.open('terminal','Terminal',html);});"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<polyline points="4 17 10 11 4 5"></polyline>
|
|
||||||
<line x1="12" y1="19" x2="20" y2="19"></line>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sidebar-item"
|
|
||||||
title="User"
|
|
||||||
onclick="alert('User profile coming soon');"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"
|
|
||||||
></path>
|
|
||||||
<circle cx="12" cy="7" r="4"></circle>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sidebar-item"
|
|
||||||
title="Apps"
|
|
||||||
onclick="if(window.wm) window.wm.open('apps', 'Applications', '<div style=\'padding:20px;\'><h3>Installed Applications</h3><p>Click desktop icons to launch apps.</p></div>');"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<rect x="3" y="3" width="7" height="7"></rect>
|
|
||||||
<rect x="14" y="3" width="7" height="7"></rect>
|
|
||||||
<rect x="14" y="14" width="7" height="7"></rect>
|
|
||||||
<rect x="3" y="14" width="7" height="7"></rect>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sidebar-item"
|
|
||||||
style="margin-top: auto"
|
|
||||||
title="Settings"
|
|
||||||
onclick="fetch('/suite/admin/organization-settings.html').then(r=>r.text()).then(html=>{if(window.wm)window.wm.open('settings','Settings',html);}).catch(e=>alert('Settings page not found'));"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="sidebar-icon"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<circle cx="12" cy="12" r="3"></circle>
|
|
||||||
<path
|
|
||||||
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<!-- Main Wrapper -->
|
|
||||||
<div class="main-wrapper">
|
|
||||||
<!-- Top Navigation Tabs - Removed (already in Vibe) -->
|
|
||||||
|
|
||||||
<!-- Workspace container where WindowManager operates -->
|
|
||||||
<div class="workspace" id="desktop-content">
|
|
||||||
<!-- Background Pattern -->
|
|
||||||
|
|
||||||
<div class="panel-section">
|
|
||||||
<div class="desktop-icons-container">
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="vibe"
|
|
||||||
data-app-title="Vibe"
|
|
||||||
hx-get="/suite/partials/vibe.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Vibe</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="tasks"
|
|
||||||
data-app-title="Tasks"
|
|
||||||
hx-get="/suite/tasks/task-window.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path d="M9 11l3 3L22 4" />
|
|
||||||
<path
|
|
||||||
d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Tasks</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="chat"
|
|
||||||
data-app-title="Chat"
|
|
||||||
hx-get="/suite/partials/chat.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Chat</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="terminal"
|
|
||||||
data-app-title="Terminal"
|
|
||||||
hx-get="/suite/terminal/terminal.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<polyline points="4 17 10 11 4 5" />
|
|
||||||
<line x1="12" y1="19" x2="20" y2="19" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Terminal</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="drive"
|
|
||||||
data-app-title="Explorer"
|
|
||||||
hx-get="/suite/drive/drive.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Explorer</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="editor"
|
|
||||||
data-app-title="Editor"
|
|
||||||
hx-get="/suite/editor.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<polyline points="16 18 22 12 16 6" />
|
|
||||||
<polyline points="8 6 2 12 8 18" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Editor</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="desktop-icon"
|
|
||||||
data-app-id="browser"
|
|
||||||
data-app-title="Browser"
|
|
||||||
hx-get="/suite/browser/browser.html"
|
|
||||||
hx-swap="none"
|
|
||||||
>
|
|
||||||
<div class="app-icon">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<circle cx="12" cy="12" r="10" />
|
|
||||||
<polygon
|
|
||||||
points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span class="desktop-icon-label">Browser</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Bottom Taskbar -->
|
|
||||||
<footer class="toolbar" id="taskbar">
|
|
||||||
<div id="taskbar-apps">
|
|
||||||
<!-- Taskbar items populated automatically by window-manager.js -->
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="toolbar-time"
|
|
||||||
style="display: flex; align-items: center; gap: 15px"
|
|
||||||
>
|
|
||||||
<div id="themeSelectorContainer"></div>
|
|
||||||
<button
|
|
||||||
id="loginBtn"
|
|
||||||
onclick="window.location.href='/suite/auth/login.html'"
|
|
||||||
style="
|
|
||||||
background: var(--primary, #84d669);
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 6px 12px;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
cursor: pointer;
|
|
||||||
font-family: "Fira Code", monospace;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Sign In
|
|
||||||
</button>
|
|
||||||
<div style="text-align: right">
|
|
||||||
<div id="clock-time">00:00</div>
|
|
||||||
<div id="clock-date">01/01/2026</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- HTMX Intercepts and WindowManager Init as described in UI.md Phase 3 -->
|
|
||||||
<script>
|
|
||||||
document.addEventListener("DOMContentLoaded", async () => {
|
|
||||||
// Initialize WindowManager
|
|
||||||
if (typeof window.WindowManager !== "undefined") {
|
|
||||||
window.wm = window.WindowManager;
|
|
||||||
} else {
|
|
||||||
console.error(
|
|
||||||
"WindowManager class not loaded from window-manager.js",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize ThemeManager
|
|
||||||
if (typeof window.ThemeManager !== "undefined") {
|
|
||||||
window.ThemeManager.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-open Chat window maximized on desktop load
|
|
||||||
if (window.wm) {
|
|
||||||
try {
|
|
||||||
const response = await fetch(
|
|
||||||
"/suite/partials/chat.html",
|
|
||||||
);
|
|
||||||
if (response.ok) {
|
|
||||||
const htmlContent = await response.text();
|
|
||||||
window.wm.open("chat", "Chat", htmlContent);
|
|
||||||
// Maximize the chat window after opening
|
|
||||||
setTimeout(() => {
|
|
||||||
window.wm.toggleMaximize("chat");
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Failed to auto-open chat:", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Listen to HTMX afterRequest event
|
|
||||||
document.body.addEventListener("htmx:afterRequest", function (evt) {
|
|
||||||
const target = evt.detail.elt;
|
|
||||||
|
|
||||||
// Check if the click came from a desktop icon
|
|
||||||
if (target.classList.contains("desktop-icon")) {
|
|
||||||
const appId = target.getAttribute("data-app-id");
|
|
||||||
const title = target.getAttribute("data-app-title");
|
|
||||||
const htmlContent = evt.detail.xhr.response;
|
|
||||||
|
|
||||||
// Tell WindowManager to open it
|
|
||||||
if (window.wm) {
|
|
||||||
window.wm.open(appId, title, htmlContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure Theme dropdown is re-injected if wiped
|
|
||||||
if (window.ThemeManager) {
|
|
||||||
const container = document.getElementById(
|
|
||||||
"themeSelectorContainer",
|
|
||||||
);
|
|
||||||
if (container && !container.hasChildNodes()) {
|
|
||||||
// Quick and dirty way to re-init
|
|
||||||
window.ThemeManager.init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update login button based on auth state
|
|
||||||
function updateLoginButton() {
|
|
||||||
var token =
|
|
||||||
localStorage.getItem("gb-access-token") ||
|
|
||||||
sessionStorage.getItem("gb-access-token");
|
|
||||||
var loginBtn = document.getElementById("loginBtn");
|
|
||||||
if (token && loginBtn) {
|
|
||||||
loginBtn.textContent = "Sign Out";
|
|
||||||
loginBtn.onclick = function () {
|
|
||||||
fetch("/api/auth/logout", { method: "POST" }).finally(
|
|
||||||
function () {
|
|
||||||
localStorage.removeItem("gb-access-token");
|
|
||||||
sessionStorage.removeItem("gb-access-token");
|
|
||||||
window.location.reload();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check login state on load
|
|
||||||
setTimeout(updateLoginButton, 500);
|
|
||||||
|
|
||||||
// Simple Clock implementation matching the screenshot bottom right corner
|
|
||||||
setInterval(() => {
|
|
||||||
const now = new Date();
|
|
||||||
document.getElementById("clock-time").textContent =
|
|
||||||
now.toLocaleTimeString([], {
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit",
|
|
||||||
});
|
|
||||||
document.getElementById("clock-date").textContent =
|
|
||||||
now.toLocaleDateString();
|
|
||||||
}, 1000);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<!-- Drive - File Management v1.0 -->
|
<!-- Drive - File Management v1.0 -->
|
||||||
<link rel="stylesheet" href="/suite/drive/drive.css" />
|
<link rel="stylesheet" href="drive/drive.css" />
|
||||||
|
|
||||||
<div class="drive-container" id="drive-app">
|
<div class="drive-container" id="drive-app">
|
||||||
<!-- Sidebar -->
|
<!-- Sidebar -->
|
||||||
|
|
@ -348,4 +348,4 @@
|
||||||
<!-- Context Menu (dynamically populated by JS) -->
|
<!-- Context Menu (dynamically populated by JS) -->
|
||||||
<div id="context-menu" class="context-menu hidden"></div>
|
<div id="context-menu" class="context-menu hidden"></div>
|
||||||
|
|
||||||
<script src="/suite/drive/drive.js"></script>
|
<script src="drive/drive.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
<nav class="nav-section">
|
<nav class="nav-section">
|
||||||
<div class="nav-item active"
|
<div class="nav-item active"
|
||||||
hx-get="/api/drive/files?path=/"
|
hx-get="/api/drive/files?path=/"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
onclick="setActiveNav(this)">
|
onclick="setActiveNav(this)">
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
<div class="nav-item"
|
<div class="nav-item"
|
||||||
hx-get="/api/drive/files?filter=shared"
|
hx-get="/api/drive/files?filter=shared"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
onclick="setActiveNav(this)">
|
onclick="setActiveNav(this)">
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
<div class="nav-item"
|
<div class="nav-item"
|
||||||
hx-get="/api/drive/files?filter=recent"
|
hx-get="/api/drive/files?filter=recent"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
onclick="setActiveNav(this)">
|
onclick="setActiveNav(this)">
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
|
|
||||||
<div class="nav-item"
|
<div class="nav-item"
|
||||||
hx-get="/api/drive/files?filter=starred"
|
hx-get="/api/drive/files?filter=starred"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
onclick="setActiveNav(this)">
|
onclick="setActiveNav(this)">
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
|
|
||||||
<div class="nav-item"
|
<div class="nav-item"
|
||||||
hx-get="/api/drive/files?filter=trash"
|
hx-get="/api/drive/files?filter=trash"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
onclick="setActiveNav(this)">
|
onclick="setActiveNav(this)">
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
|
@ -174,7 +174,7 @@
|
||||||
|
|
||||||
<select class="sort-dropdown" id="sort-dropdown"
|
<select class="sort-dropdown" id="sort-dropdown"
|
||||||
hx-get="/api/drive/files"
|
hx-get="/api/drive/files"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-include="[name='path']">
|
hx-include="[name='path']">
|
||||||
<option value="name">Name</option>
|
<option value="name">Name</option>
|
||||||
|
|
@ -264,7 +264,7 @@
|
||||||
hx-delete="/api/drive/files"
|
hx-delete="/api/drive/files"
|
||||||
hx-include=".file-checkbox:checked"
|
hx-include=".file-checkbox:checked"
|
||||||
hx-confirm="Move selected items to trash?"
|
hx-confirm="Move selected items to trash?"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML">
|
hx-swap="innerHTML">
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
<polyline points="3 6 5 6 21 6"></polyline>
|
<polyline points="3 6 5 6 21 6"></polyline>
|
||||||
|
|
@ -322,7 +322,7 @@
|
||||||
<div class="upload-zone" id="upload-zone"
|
<div class="upload-zone" id="upload-zone"
|
||||||
hx-post="/api/drive/upload"
|
hx-post="/api/drive/upload"
|
||||||
hx-encoding="multipart/form-data"
|
hx-encoding="multipart/form-data"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML">
|
hx-swap="innerHTML">
|
||||||
<input type="file" id="file-input" name="files" multiple hidden>
|
<input type="file" id="file-input" name="files" multiple hidden>
|
||||||
<input type="hidden" name="path" id="upload-path" value="/">
|
<input type="hidden" name="path" id="upload-path" value="/">
|
||||||
|
|
@ -352,7 +352,7 @@
|
||||||
<dialog class="modal" id="folder-modal">
|
<dialog class="modal" id="folder-modal">
|
||||||
<form class="modal-content"
|
<form class="modal-content"
|
||||||
hx-post="/api/drive/folder"
|
hx-post="/api/drive/folder"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-on::after-request="document.getElementById('folder-modal').close()">
|
hx-on::after-request="document.getElementById('folder-modal').close()">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
|
@ -418,7 +418,7 @@
|
||||||
<dialog class="modal" id="copy-modal">
|
<dialog class="modal" id="copy-modal">
|
||||||
<form class="modal-content"
|
<form class="modal-content"
|
||||||
hx-post="/files/copy"
|
hx-post="/files/copy"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-on::after-request="document.getElementById('copy-modal').close()">
|
hx-on::after-request="document.getElementById('copy-modal').close()">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
|
@ -453,7 +453,7 @@
|
||||||
<dialog class="modal" id="move-modal">
|
<dialog class="modal" id="move-modal">
|
||||||
<form class="modal-content"
|
<form class="modal-content"
|
||||||
hx-post="/files/move"
|
hx-post="/files/move"
|
||||||
hx-target="closest .window-body #file-grid"
|
hx-target="#file-grid"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-on::after-request="document.getElementById('move-modal').close()">
|
hx-on::after-request="document.getElementById('move-modal').close()">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
|
@ -562,7 +562,7 @@
|
||||||
</h3>
|
</h3>
|
||||||
<p>Combine multiple documents into one</p>
|
<p>Combine multiple documents into one</p>
|
||||||
<form hx-post="/docs/merge"
|
<form hx-post="/docs/merge"
|
||||||
hx-target="closest .window-body #docs-result"
|
hx-target="#docs-result"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-encoding="multipart/form-data">
|
hx-encoding="multipart/form-data">
|
||||||
<input type="file" name="files" multiple accept=".pdf,.docx,.doc,.txt" class="form-group" style="margin-bottom: 8px;">
|
<input type="file" name="files" multiple accept=".pdf,.docx,.doc,.txt" class="form-group" style="margin-bottom: 8px;">
|
||||||
|
|
@ -584,7 +584,7 @@
|
||||||
</h3>
|
</h3>
|
||||||
<p>Convert between document formats</p>
|
<p>Convert between document formats</p>
|
||||||
<form hx-post="/docs/convert"
|
<form hx-post="/docs/convert"
|
||||||
hx-target="closest .window-body #docs-result"
|
hx-target="#docs-result"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-encoding="multipart/form-data">
|
hx-encoding="multipart/form-data">
|
||||||
<input type="file" name="file" accept=".pdf,.docx,.doc,.txt,.md,.html" class="form-group" style="margin-bottom: 8px;">
|
<input type="file" name="file" accept=".pdf,.docx,.doc,.txt,.md,.html" class="form-group" style="margin-bottom: 8px;">
|
||||||
|
|
@ -612,7 +612,7 @@
|
||||||
</h3>
|
</h3>
|
||||||
<p>Populate template with data</p>
|
<p>Populate template with data</p>
|
||||||
<form hx-post="/docs/fill"
|
<form hx-post="/docs/fill"
|
||||||
hx-target="closest .window-body #docs-result"
|
hx-target="#docs-result"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-encoding="multipart/form-data">
|
hx-encoding="multipart/form-data">
|
||||||
<input type="file" name="template" accept=".docx,.doc" class="form-group" style="margin-bottom: 8px;">
|
<input type="file" name="template" accept=".docx,.doc" class="form-group" style="margin-bottom: 8px;">
|
||||||
|
|
@ -633,7 +633,7 @@
|
||||||
</h3>
|
</h3>
|
||||||
<p>Export document in specified format</p>
|
<p>Export document in specified format</p>
|
||||||
<form hx-post="/docs/export"
|
<form hx-post="/docs/export"
|
||||||
hx-target="closest .window-body #docs-result"
|
hx-target="#docs-result"
|
||||||
hx-swap="innerHTML">
|
hx-swap="innerHTML">
|
||||||
<input type="text" name="path" placeholder="File path (e.g., /documents/report.docx)" class="form-group" style="width: 100%; margin-bottom: 8px;">
|
<input type="text" name="path" placeholder="File path (e.g., /documents/report.docx)" class="form-group" style="width: 100%; margin-bottom: 8px;">
|
||||||
<select name="format" class="sort-dropdown" style="width: 100%; margin-bottom: 8px;">
|
<select name="format" class="sort-dropdown" style="width: 100%; margin-bottom: 8px;">
|
||||||
|
|
@ -657,7 +657,7 @@
|
||||||
</h3>
|
</h3>
|
||||||
<p>Import document from URL or upload</p>
|
<p>Import document from URL or upload</p>
|
||||||
<form hx-post="/docs/import"
|
<form hx-post="/docs/import"
|
||||||
hx-target="closest .window-body #docs-result"
|
hx-target="#docs-result"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-encoding="multipart/form-data">
|
hx-encoding="multipart/form-data">
|
||||||
<input type="url" name="url" placeholder="Document URL (optional)" class="form-group" style="width: 100%; margin-bottom: 8px;">
|
<input type="url" name="url" placeholder="Document URL (optional)" class="form-group" style="width: 100%; margin-bottom: 8px;">
|
||||||
|
|
|
||||||
1094
ui/suite/home.html
Normal file
1094
ui/suite/home.html
Normal file
File diff suppressed because it is too large
Load diff
1391
ui/suite/index.html
Normal file
1391
ui/suite/index.html
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -351,8 +351,8 @@
|
||||||
this.clearAuth();
|
this.clearAuth();
|
||||||
this.emit("tokenExpired");
|
this.emit("tokenExpired");
|
||||||
|
|
||||||
const currentPath = window.location.pathname + window.location.hash;
|
const currentPath = window.location.pathname;
|
||||||
if (!window.location.pathname.startsWith("/auth/")) {
|
if (!currentPath.startsWith("/auth/")) {
|
||||||
window.location.href =
|
window.location.href =
|
||||||
"/auth/login.html?expired=1&redirect=" +
|
"/auth/login.html?expired=1&redirect=" +
|
||||||
encodeURIComponent(currentPath);
|
encodeURIComponent(currentPath);
|
||||||
|
|
|
||||||
|
|
@ -47,15 +47,12 @@ function applyProductConfig(config) {
|
||||||
// Check if we have compiled_features info to filter even further
|
// Check if we have compiled_features info to filter even further
|
||||||
// This ensures we don't show apps that are enabled in config but not compiled in binary
|
// This ensures we don't show apps that are enabled in config but not compiled in binary
|
||||||
if (config.compiled_features && Array.isArray(config.compiled_features)) {
|
if (config.compiled_features && Array.isArray(config.compiled_features)) {
|
||||||
const compiledSet = new Set(
|
const compiledSet = new Set(config.compiled_features.map(f => f.toLowerCase()));
|
||||||
config.compiled_features.map((f) => f.toLowerCase()),
|
effectiveApps = effectiveApps.filter(app =>
|
||||||
);
|
compiledSet.has(app.toLowerCase()) ||
|
||||||
effectiveApps = effectiveApps.filter(
|
app.toLowerCase() === 'settings' ||
|
||||||
(app) =>
|
app.toLowerCase() === 'auth' ||
|
||||||
compiledSet.has(app.toLowerCase()) ||
|
app.toLowerCase() === 'admin' // Admin usually contains settings which is always there
|
||||||
app.toLowerCase() === "settings" ||
|
|
||||||
app.toLowerCase() === "auth" ||
|
|
||||||
app.toLowerCase() === "admin", // Admin usually contains settings which is always there
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Also call a helper to hide UI elements for non-compiled features explicitly
|
// Also call a helper to hide UI elements for non-compiled features explicitly
|
||||||
|
|
@ -64,33 +61,6 @@ function applyProductConfig(config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
filterAppsByConfig(effectiveApps);
|
filterAppsByConfig(effectiveApps);
|
||||||
|
|
||||||
// Check if there are any visible apps after filtering
|
|
||||||
const hasVisibleApps = effectiveApps.length > 0;
|
|
||||||
|
|
||||||
// Hide apps menu button if menu launcher is disabled or if there are no apps to show
|
|
||||||
if (config.menu_launcher_enabled === false || !hasVisibleApps) {
|
|
||||||
const appsButton = document.getElementById("appsButton");
|
|
||||||
if (appsButton) {
|
|
||||||
appsButton.style.display = "none";
|
|
||||||
}
|
|
||||||
const appsMenuContainer = document.querySelector(".apps-menu-container");
|
|
||||||
if (appsMenuContainer) {
|
|
||||||
appsMenuContainer.style.display = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide omnibox if search is disabled
|
|
||||||
if (config.search_enabled === false) {
|
|
||||||
const omnibox = document.getElementById("omnibox");
|
|
||||||
if (omnibox) {
|
|
||||||
omnibox.style.display = "none";
|
|
||||||
}
|
|
||||||
const headerCenter = document.querySelector(".header-center");
|
|
||||||
if (headerCenter) {
|
|
||||||
headerCenter.style.display = "none";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply custom logo
|
// Apply custom logo
|
||||||
|
|
@ -125,25 +95,21 @@ function applyProductConfig(config) {
|
||||||
// Hide UI elements that require features not compiled in the binary
|
// Hide UI elements that require features not compiled in the binary
|
||||||
function hideNonCompiledUI(compiledSet) {
|
function hideNonCompiledUI(compiledSet) {
|
||||||
// Hide elements with data-feature attribute that aren't in compiled set
|
// Hide elements with data-feature attribute that aren't in compiled set
|
||||||
document.querySelectorAll("[data-feature]").forEach((el) => {
|
document.querySelectorAll('[data-feature]').forEach(el => {
|
||||||
const feature = el.getAttribute("data-feature").toLowerCase();
|
const feature = el.getAttribute('data-feature').toLowerCase();
|
||||||
// Allow settings/admin as they are usually core
|
// Allow settings/admin as they are usually core
|
||||||
if (
|
if (!compiledSet.has(feature) && feature !== 'settings' && feature !== 'admin') {
|
||||||
!compiledSet.has(feature) &&
|
el.style.display = 'none';
|
||||||
feature !== "settings" &&
|
el.classList.add('hidden-uncompiled');
|
||||||
feature !== "admin"
|
|
||||||
) {
|
|
||||||
el.style.display = "none";
|
|
||||||
el.classList.add("hidden-uncompiled");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Also look for specific sections that might map to features
|
// Also look for specific sections that might map to features
|
||||||
// e.g. .feature-mail, .feature-meet classes
|
// e.g. .feature-mail, .feature-meet classes
|
||||||
compiledSet.forEach((feature) => {
|
compiledSet.forEach(feature => {
|
||||||
// This loop defines what IS available.
|
// This loop defines what IS available.
|
||||||
// Logic should be inverse: find all feature- classes and hide if not in set
|
// Logic should be inverse: find all feature- classes and hide if not in set
|
||||||
// But scanning all classes is expensive.
|
// But scanning all classes is expensive.
|
||||||
// Better to rely on data-feature or explicit app hiding which filterAppsByConfig does.
|
// Better to rely on data-feature or explicit app hiding which filterAppsByConfig does.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,302 +0,0 @@
|
||||||
/**
|
|
||||||
* Chat Agent Mode — handles toggling between Agent and Chat mode,
|
|
||||||
* multi-panel layout management, and WebSocket message routing
|
|
||||||
* for thought process, terminal output, browser preview, and step tracking.
|
|
||||||
*/
|
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var agentMode = false;
|
|
||||||
var currentStep = 0;
|
|
||||||
var totalSteps = 0;
|
|
||||||
var terminalLineCount = 0;
|
|
||||||
|
|
||||||
function initAgentMode() {
|
|
||||||
setupModeToggle();
|
|
||||||
setupToggleSwitches();
|
|
||||||
setupStepNavigation();
|
|
||||||
setupQuickActions();
|
|
||||||
setupSidebarItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupModeToggle() {
|
|
||||||
var agentBtn = document.getElementById("modeAgentBtn");
|
|
||||||
var chatBtn = document.getElementById("modeChatBtn");
|
|
||||||
if (!agentBtn || !chatBtn) return;
|
|
||||||
|
|
||||||
agentBtn.addEventListener("click", function () {
|
|
||||||
setMode("agent");
|
|
||||||
});
|
|
||||||
chatBtn.addEventListener("click", function () {
|
|
||||||
setMode("chat");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setMode(mode) {
|
|
||||||
var chatApp = document.getElementById("chat-app");
|
|
||||||
var agentBtn = document.getElementById("modeAgentBtn");
|
|
||||||
var chatBtn = document.getElementById("modeChatBtn");
|
|
||||||
var quickActions = document.getElementById("quickActions");
|
|
||||||
|
|
||||||
if (!chatApp || !agentBtn || !chatBtn) return;
|
|
||||||
|
|
||||||
agentMode = mode === "agent";
|
|
||||||
|
|
||||||
agentBtn.classList.toggle("active", agentMode);
|
|
||||||
chatBtn.classList.toggle("active", !agentMode);
|
|
||||||
|
|
||||||
if (agentMode) {
|
|
||||||
chatApp.classList.add("agent-mode");
|
|
||||||
if (quickActions) quickActions.style.display = "none";
|
|
||||||
} else {
|
|
||||||
chatApp.classList.remove("agent-mode");
|
|
||||||
if (quickActions) quickActions.style.display = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupToggleSwitches() {
|
|
||||||
var planToggle = document.getElementById("togglePlan");
|
|
||||||
var yoloToggle = document.getElementById("toggleYolo");
|
|
||||||
|
|
||||||
if (planToggle) {
|
|
||||||
planToggle.addEventListener("click", function () {
|
|
||||||
this.classList.toggle("on");
|
|
||||||
emitModeChange();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (yoloToggle) {
|
|
||||||
yoloToggle.addEventListener("click", function () {
|
|
||||||
this.classList.toggle("on");
|
|
||||||
emitModeChange();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function emitModeChange() {
|
|
||||||
var planOn = document.getElementById("togglePlan");
|
|
||||||
var yoloOn = document.getElementById("toggleYolo");
|
|
||||||
var mode = "plan";
|
|
||||||
if (yoloOn && yoloOn.classList.contains("on")) {
|
|
||||||
mode = "yolo";
|
|
||||||
}
|
|
||||||
if (window.ws && window.ws.readyState === WebSocket.OPEN) {
|
|
||||||
window.ws.send(JSON.stringify({
|
|
||||||
type: "toggle_mode",
|
|
||||||
mode: mode
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupStepNavigation() {
|
|
||||||
var prevBtn = document.getElementById("stepPrev");
|
|
||||||
var nextBtn = document.getElementById("stepNext");
|
|
||||||
|
|
||||||
if (prevBtn) {
|
|
||||||
prevBtn.addEventListener("click", function () {
|
|
||||||
if (currentStep > 1) {
|
|
||||||
currentStep--;
|
|
||||||
updateStepCounter();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (nextBtn) {
|
|
||||||
nextBtn.addEventListener("click", function () {
|
|
||||||
if (currentStep < totalSteps) {
|
|
||||||
currentStep++;
|
|
||||||
updateStepCounter();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStepCounter() {
|
|
||||||
var display = document.getElementById("stepCounterText");
|
|
||||||
if (display) {
|
|
||||||
display.textContent = currentStep + " / " + totalSteps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupQuickActions() {
|
|
||||||
var chips = document.querySelectorAll(".quick-action-chip");
|
|
||||||
chips.forEach(function (chip) {
|
|
||||||
chip.addEventListener("click", function () {
|
|
||||||
var action = this.getAttribute("data-action");
|
|
||||||
var prompts = {
|
|
||||||
"full-stack": "Create a full-stack web application",
|
|
||||||
"writing": "Help me write ",
|
|
||||||
"data-insight": "Analyze data and provide insights",
|
|
||||||
"magic-design": "Design a beautiful UI for "
|
|
||||||
};
|
|
||||||
var input = document.getElementById("messageInput");
|
|
||||||
if (input && prompts[action]) {
|
|
||||||
input.value = prompts[action];
|
|
||||||
input.focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupSidebarItems() {
|
|
||||||
var items = document.querySelectorAll(".agent-sidebar-item");
|
|
||||||
items.forEach(function (item) {
|
|
||||||
item.addEventListener("click", function () {
|
|
||||||
items.forEach(function (i) { i.classList.remove("active"); });
|
|
||||||
this.classList.add("active");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===========================================
|
|
||||||
Agent Mode WebSocket Message Handlers
|
|
||||||
=========================================== */
|
|
||||||
|
|
||||||
function handleAgentMessage(data) {
|
|
||||||
if (!agentMode) return;
|
|
||||||
|
|
||||||
switch (data.type) {
|
|
||||||
case "thought_process":
|
|
||||||
renderThoughtProcess(data.content);
|
|
||||||
break;
|
|
||||||
case "terminal_output":
|
|
||||||
appendTerminalLine(data.line, data.stream);
|
|
||||||
break;
|
|
||||||
case "browser_ready":
|
|
||||||
showBrowserPreview(data.url);
|
|
||||||
break;
|
|
||||||
case "step_progress":
|
|
||||||
currentStep = data.current;
|
|
||||||
totalSteps = data.total;
|
|
||||||
updateStepCounter();
|
|
||||||
break;
|
|
||||||
case "step_complete":
|
|
||||||
break;
|
|
||||||
case "todo_update":
|
|
||||||
renderTodoList(data.todos);
|
|
||||||
break;
|
|
||||||
case "agent_status":
|
|
||||||
updateAgentInfo(data);
|
|
||||||
break;
|
|
||||||
case "file_created":
|
|
||||||
incrementBadge("explorerBadge");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderThoughtProcess(content) {
|
|
||||||
var messages = document.getElementById("messages");
|
|
||||||
if (!messages) return;
|
|
||||||
|
|
||||||
var block = document.createElement("div");
|
|
||||||
block.className = "thought-process";
|
|
||||||
block.innerHTML =
|
|
||||||
'<button class="thought-process-header">' +
|
|
||||||
'<span class="thought-process-toggle">▶</span>' +
|
|
||||||
'<span>Thought Process</span>' +
|
|
||||||
"</button>" +
|
|
||||||
'<div class="thought-process-body">' + escapeForHtml(content) + "</div>";
|
|
||||||
|
|
||||||
var header = block.querySelector(".thought-process-header");
|
|
||||||
header.addEventListener("click", function () {
|
|
||||||
block.classList.toggle("expanded");
|
|
||||||
});
|
|
||||||
|
|
||||||
messages.appendChild(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
function appendTerminalLine(text, stream) {
|
|
||||||
var terminal = document.getElementById("terminalPanelContent");
|
|
||||||
if (!terminal) return;
|
|
||||||
|
|
||||||
var line = document.createElement("div");
|
|
||||||
line.className = "terminal-line " + (stream || "stdout");
|
|
||||||
line.textContent = text;
|
|
||||||
terminal.appendChild(line);
|
|
||||||
terminal.scrollTop = terminal.scrollHeight;
|
|
||||||
|
|
||||||
terminalLineCount++;
|
|
||||||
incrementBadge("terminalBadge");
|
|
||||||
}
|
|
||||||
|
|
||||||
function showBrowserPreview(url) {
|
|
||||||
var content = document.getElementById("browserPanelContent");
|
|
||||||
var urlBar = document.getElementById("browserUrlBar");
|
|
||||||
if (!content || !urlBar) return;
|
|
||||||
|
|
||||||
urlBar.value = url;
|
|
||||||
content.innerHTML = '<iframe src="' + url + '" sandbox="allow-scripts allow-same-origin"></iframe>';
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderTodoList(todos) {
|
|
||||||
var messages = document.getElementById("messages");
|
|
||||||
if (!messages) return;
|
|
||||||
|
|
||||||
var existing = messages.querySelector(".agent-todo-list:last-child");
|
|
||||||
if (existing) existing.remove();
|
|
||||||
|
|
||||||
var list = document.createElement("div");
|
|
||||||
list.className = "agent-todo-list";
|
|
||||||
|
|
||||||
var headerHtml = '<div class="agent-todo-header">' +
|
|
||||||
'<span>📋 Todos</span>' +
|
|
||||||
'<span class="agent-todo-count">' + todos.length + "</span>" +
|
|
||||||
"</div>";
|
|
||||||
|
|
||||||
var itemsHtml = todos.map(function (todo) {
|
|
||||||
var doneClass = todo.done ? " done" : "";
|
|
||||||
var checkMark = todo.done ? "✓" : "";
|
|
||||||
return '<div class="agent-todo-item' + doneClass + '">' +
|
|
||||||
'<span class="agent-todo-check">' + checkMark + "</span>" +
|
|
||||||
'<span>' + escapeForHtml(todo.text) + "</span>" +
|
|
||||||
"</div>";
|
|
||||||
}).join("");
|
|
||||||
|
|
||||||
list.innerHTML = headerHtml + itemsHtml;
|
|
||||||
messages.appendChild(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateAgentInfo(data) {
|
|
||||||
var nameEl = document.getElementById("agentNameDisplay");
|
|
||||||
var levelEl = document.getElementById("agentLevelBadge");
|
|
||||||
var modelEl = document.getElementById("agentModelDisplay");
|
|
||||||
|
|
||||||
if (nameEl && data.name) nameEl.textContent = data.name;
|
|
||||||
if (levelEl && data.level) {
|
|
||||||
levelEl.textContent = data.level;
|
|
||||||
levelEl.className = "agent-level-badge badge-" + data.level.toLowerCase();
|
|
||||||
}
|
|
||||||
if (modelEl && data.model) {
|
|
||||||
modelEl.textContent = data.model + " — " + (data.usage || 0) + "%";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function incrementBadge(badgeId) {
|
|
||||||
var badge = document.getElementById(badgeId);
|
|
||||||
if (!badge) return;
|
|
||||||
var count = parseInt(badge.textContent, 10) || 0;
|
|
||||||
badge.textContent = count + 1;
|
|
||||||
badge.style.display = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function escapeForHtml(text) {
|
|
||||||
var div = document.createElement("div");
|
|
||||||
div.textContent = text || "";
|
|
||||||
return div.innerHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===========================================
|
|
||||||
Expose to global scope
|
|
||||||
=========================================== */
|
|
||||||
|
|
||||||
window.AgentMode = {
|
|
||||||
init: initAgentMode,
|
|
||||||
handleMessage: handleAgentMessage,
|
|
||||||
setMode: setMode,
|
|
||||||
isActive: function () { return agentMode; }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (document.readyState === "loading") {
|
|
||||||
document.addEventListener("DOMContentLoaded", initAgentMode);
|
|
||||||
} else {
|
|
||||||
initAgentMode();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const MAX_ERRORS = 50;
|
|
||||||
const REPORT_ENDPOINT = '/api/client-errors';
|
|
||||||
let errorQueue = [];
|
|
||||||
let isReporting = false;
|
|
||||||
|
|
||||||
function formatError(error, context = {}) {
|
|
||||||
return {
|
|
||||||
type: error.name || 'Error',
|
|
||||||
message: error.message || String(error),
|
|
||||||
stack: error.stack,
|
|
||||||
url: window.location.href,
|
|
||||||
userAgent: navigator.userAgent,
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
context: context
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function reportErrors() {
|
|
||||||
if (isReporting || errorQueue.length === 0) return;
|
|
||||||
|
|
||||||
isReporting = true;
|
|
||||||
const errorsToReport = errorQueue.splice(0, MAX_ERRORS);
|
|
||||||
errorQueue = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(REPORT_ENDPOINT, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ errors: errorsToReport })
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
console.warn('[ErrorReporter] Failed to send errors:', response.status);
|
|
||||||
} else {
|
|
||||||
console.log('[ErrorReporter] Sent', errorsToReport.length, 'errors to server');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('[ErrorReporter] Failed to send errors:', e.message);
|
|
||||||
errorQueue.unshift(...errorsToReport);
|
|
||||||
} finally {
|
|
||||||
isReporting = false;
|
|
||||||
|
|
||||||
if (errorQueue.length > 0) {
|
|
||||||
setTimeout(reportErrors, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function queueError(errorData) {
|
|
||||||
errorQueue.push(errorData);
|
|
||||||
if (errorQueue.length >= 10) {
|
|
||||||
reportErrors();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('error', (event) => {
|
|
||||||
const errorData = formatError(event.error || new Error(event.message), {
|
|
||||||
filename: event.filename,
|
|
||||||
lineno: event.lineno,
|
|
||||||
colno: event.colno
|
|
||||||
});
|
|
||||||
queueError(errorData);
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener('unhandledrejection', (event) => {
|
|
||||||
const errorData = formatError(event.reason || new Error(String(event.reason)), {
|
|
||||||
type: 'unhandledRejection'
|
|
||||||
});
|
|
||||||
queueError(errorData);
|
|
||||||
});
|
|
||||||
|
|
||||||
window.ErrorReporter = {
|
|
||||||
report: function(error, context) {
|
|
||||||
queueError(formatError(error, context));
|
|
||||||
},
|
|
||||||
reportNetworkError: function(url, status, statusText) {
|
|
||||||
queueError({
|
|
||||||
type: 'NetworkError',
|
|
||||||
message: `Failed to load ${url}: ${status} ${statusText}`,
|
|
||||||
url: window.location.href,
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
context: { url, status, statusText }
|
|
||||||
});
|
|
||||||
},
|
|
||||||
flush: function() {
|
|
||||||
reportErrors();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (document.readyState === 'complete') {
|
|
||||||
setTimeout(reportErrors, 1000);
|
|
||||||
} else {
|
|
||||||
window.addEventListener('load', () => {
|
|
||||||
setTimeout(reportErrors, 1000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('[ErrorReporter] Client-side error reporting initialized');
|
|
||||||
|
|
||||||
window.NavigationLogger = {
|
|
||||||
log: function(from, to, method) {
|
|
||||||
const navEvent = {
|
|
||||||
type: 'navigation',
|
|
||||||
from: from,
|
|
||||||
to: to,
|
|
||||||
method: method,
|
|
||||||
url: window.location.href,
|
|
||||||
timestamp: new Date().toISOString()
|
|
||||||
};
|
|
||||||
|
|
||||||
queueError({
|
|
||||||
name: 'Navigation',
|
|
||||||
message: `${method}: ${from} -> ${to}`,
|
|
||||||
stack: undefined
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function initNavigationTracking() {
|
|
||||||
if (!document.body) {
|
|
||||||
setTimeout(initNavigationTracking, 50);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (document.body) {
|
|
||||||
document.body.addEventListener('click', function(e) {
|
|
||||||
const target = e.target.closest('[data-section]');
|
|
||||||
if (target) {
|
|
||||||
const section = target.getAttribute('data-section');
|
|
||||||
const currentHash = window.location.hash.slice(1) || '';
|
|
||||||
if (section !== currentHash) {
|
|
||||||
setTimeout(() => {
|
|
||||||
window.NavigationLogger.log(currentHash || 'home', section, 'click');
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('hashchange', function(e) {
|
|
||||||
const oldURL = new URL(e.oldURL);
|
|
||||||
const newURL = new URL(e.newURL);
|
|
||||||
const fromHash = oldURL.hash.slice(1) || '';
|
|
||||||
const toHash = newURL.hash.slice(1) || '';
|
|
||||||
window.NavigationLogger.log(fromHash || 'home', toHash, 'hashchange');
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('[NavigationLogger] Navigation tracking initialized');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
|
||||||
document.addEventListener('DOMContentLoaded', initNavigationTracking);
|
|
||||||
} else {
|
|
||||||
initNavigationTracking();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Intercept link onload/onerror events to catch CSS/image load failures
|
|
||||||
const originalCreateElement = document.createElement;
|
|
||||||
document.createElement = function(tagName) {
|
|
||||||
const element = originalCreateElement.call(document, tagName);
|
|
||||||
if (tagName.toLowerCase() === 'link') {
|
|
||||||
element.addEventListener('error', function() {
|
|
||||||
if (this.href && window.ErrorReporter && window.ErrorReporter.reportNetworkError) {
|
|
||||||
window.ErrorReporter.reportNetworkError(this.href, 'LOAD_FAILED', 'Resource failed to load');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return element;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener('load', () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const failedResources = performance.getEntriesByType('resource').filter(entry =>
|
|
||||||
entry.transferSize === 0 && entry.decodedBodySize > 0 && !entry.name.includes('anon') && entry.duration > 100
|
|
||||||
);
|
|
||||||
|
|
||||||
if (failedResources.length > 0) {
|
|
||||||
console.warn('[ErrorReporter] Detected potentially failed resources:', failedResources);
|
|
||||||
failedResources.forEach(resource => {
|
|
||||||
window.ErrorReporter.reportNetworkError(resource.name, 'FAILED', 'Resource load timeout/failure');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
@ -192,6 +192,7 @@
|
||||||
|
|
||||||
document.body.addEventListener("htmx:wsOpen", () => {
|
document.body.addEventListener("htmx:wsOpen", () => {
|
||||||
updateConnectionStatus("connected");
|
updateConnectionStatus("connected");
|
||||||
|
reconnectAttempts = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.addEventListener("htmx:wsClose", () => {
|
document.body.addEventListener("htmx:wsClose", () => {
|
||||||
|
|
@ -202,29 +203,7 @@
|
||||||
|
|
||||||
// Handle WebSocket messages
|
// Handle WebSocket messages
|
||||||
function handleWebSocketMessage(message) {
|
function handleWebSocketMessage(message) {
|
||||||
const messageType = message.type || message.event;
|
switch (message.type) {
|
||||||
|
|
||||||
if (messageType === "connected") {
|
|
||||||
reconnectAttempts = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug logging
|
|
||||||
console.log("handleWebSocketMessage called with:", { messageType, message });
|
|
||||||
|
|
||||||
// Hide initial loading overlay when first bot message arrives
|
|
||||||
if (window.hideLoadingOverlay) {
|
|
||||||
setTimeout(window.hideLoadingOverlay, 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle suggestions array from BotResponse
|
|
||||||
if (message.suggestions && Array.isArray(message.suggestions) && message.suggestions.length > 0) {
|
|
||||||
clearSuggestions();
|
|
||||||
message.suggestions.forEach(suggestion => {
|
|
||||||
addSuggestionButton(suggestion.text, suggestion.value || suggestion.text);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (messageType) {
|
|
||||||
case "message":
|
case "message":
|
||||||
appendMessage(message);
|
appendMessage(message);
|
||||||
break;
|
break;
|
||||||
|
|
@ -237,48 +216,11 @@
|
||||||
case "suggestion":
|
case "suggestion":
|
||||||
addSuggestion(message.text);
|
addSuggestion(message.text);
|
||||||
break;
|
break;
|
||||||
case "change_theme":
|
|
||||||
console.log("Processing change_theme event, not appending to chat");
|
|
||||||
if (message.data) {
|
|
||||||
ThemeManager.setThemeFromServer(message.data);
|
|
||||||
}
|
|
||||||
return; // Don't append theme events to chat
|
|
||||||
default:
|
default:
|
||||||
// Only append unknown message types to chat if they have text content
|
console.log("Unknown message type:", message.type);
|
||||||
if (message.text || message.content) {
|
|
||||||
console.log("Unknown message type, treating as chat message:", messageType);
|
|
||||||
appendMessage(message);
|
|
||||||
} else {
|
|
||||||
console.log("Unknown message type:", messageType, message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all suggestions
|
|
||||||
function clearSuggestions() {
|
|
||||||
const suggestionsEl = document.getElementById("suggestions");
|
|
||||||
if (suggestionsEl) {
|
|
||||||
suggestionsEl.innerHTML = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add suggestion button with value
|
|
||||||
function addSuggestionButton(text, value) {
|
|
||||||
const suggestionsEl = document.getElementById("suggestions");
|
|
||||||
if (!suggestionsEl) return;
|
|
||||||
|
|
||||||
const chip = document.createElement("button");
|
|
||||||
chip.className = "suggestion-chip";
|
|
||||||
chip.textContent = text;
|
|
||||||
chip.setAttribute("hx-post", "/api/sessions/current/message");
|
|
||||||
chip.setAttribute("hx-vals", JSON.stringify({ content: value }));
|
|
||||||
chip.setAttribute("hx-target", "#messages");
|
|
||||||
chip.setAttribute("hx-swap", "beforeend");
|
|
||||||
|
|
||||||
suggestionsEl.appendChild(chip);
|
|
||||||
htmx.process(chip);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append message to chat
|
// Append message to chat
|
||||||
function appendMessage(message) {
|
function appendMessage(message) {
|
||||||
const messagesEl = document.getElementById("messages");
|
const messagesEl = document.getElementById("messages");
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,8 @@
|
||||||
|
|
||||||
const DEFAULT_LOCALE = "en";
|
const DEFAULT_LOCALE = "en";
|
||||||
const STORAGE_KEY = "gb-locale";
|
const STORAGE_KEY = "gb-locale";
|
||||||
const CACHE_VERSION = "v2";
|
|
||||||
const CACHE_TTL_MS = 3600000;
|
const CACHE_TTL_MS = 3600000;
|
||||||
|
|
||||||
// IMPORTANT: Increment CACHE_VERSION when translation structure changes
|
|
||||||
// to invalidate all user caches and force fresh API fetches
|
|
||||||
// v2: Invalidated cache to fix placeholder translations after i18n embed fix
|
|
||||||
|
|
||||||
const MINIMAL_FALLBACK = {
|
const MINIMAL_FALLBACK = {
|
||||||
"label-loading": "Loading...",
|
"label-loading": "Loading...",
|
||||||
"status-error": "Error",
|
"status-error": "Error",
|
||||||
|
|
@ -41,7 +36,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCacheKey(locale) {
|
function getCacheKey(locale) {
|
||||||
return `gb-i18n-cache-${locale}}-${CACHE_VERSION}`;
|
return `gb-i18n-cache-${locale}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCachedTranslations(locale) {
|
function getCachedTranslations(locale) {
|
||||||
|
|
@ -49,9 +44,7 @@
|
||||||
const cached = localStorage.getItem(getCacheKey(locale));
|
const cached = localStorage.getItem(getCacheKey(locale));
|
||||||
if (cached) {
|
if (cached) {
|
||||||
const { data, timestamp } = JSON.parse(cached);
|
const { data, timestamp } = JSON.parse(cached);
|
||||||
const age = Date.now() - timestamp;
|
if (Date.now() - timestamp < CACHE_TTL_MS) {
|
||||||
console.log(`i18n: Cache check for ${locale}: age=${Math.round(age/1000)}s, valid=${age < CACHE_TTL_MS}, keys=${Object.keys(data || {}).length}`);
|
|
||||||
if (age < CACHE_TTL_MS) {
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +70,6 @@
|
||||||
|
|
||||||
async function fetchTranslations(locale) {
|
async function fetchTranslations(locale) {
|
||||||
try {
|
try {
|
||||||
console.log(`i18n: Fetching translations for locale: ${locale}`);
|
|
||||||
const response = await fetch(`/api/i18n/${locale}`, {
|
const response = await fetch(`/api/i18n/${locale}`, {
|
||||||
headers: { Accept: "application/json" },
|
headers: { Accept: "application/json" },
|
||||||
});
|
});
|
||||||
|
|
@ -87,25 +79,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
console.log(`i18n: Loaded ${Object.keys(result.translations || {}).length} translations for ${locale}`);
|
|
||||||
return result.translations || {};
|
return result.translations || {};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`i18n: Failed to fetch translations for ${locale}`, e);
|
console.warn(`i18n: Failed to fetch translations for ${locale}`, e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadTranslations(locale) {
|
async function loadTranslations(locale) {
|
||||||
console.log(`i18n: loadTranslations called for locale: ${locale}`);
|
|
||||||
const cached = getCachedTranslations(locale);
|
const cached = getCachedTranslations(locale);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
console.log(`i18n: Using cached translations for ${locale}`);
|
|
||||||
translations = cached;
|
translations = cached;
|
||||||
currentLocale = locale;
|
currentLocale = locale;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`i18n: Cache miss, fetching from API for ${locale}`);
|
|
||||||
const fetched = await fetchTranslations(locale);
|
const fetched = await fetchTranslations(locale);
|
||||||
if (fetched && Object.keys(fetched).length > 0) {
|
if (fetched && Object.keys(fetched).length > 0) {
|
||||||
translations = fetched;
|
translations = fetched;
|
||||||
|
|
@ -119,7 +107,6 @@
|
||||||
return loadTranslations(DEFAULT_LOCALE);
|
return loadTranslations(DEFAULT_LOCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.warn(`i18n: No translations found, using minimal fallback`);
|
|
||||||
translations = MINIMAL_FALLBACK;
|
translations = MINIMAL_FALLBACK;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -127,10 +114,6 @@
|
||||||
function t(key, params) {
|
function t(key, params) {
|
||||||
let text = translations[key] || MINIMAL_FALLBACK[key] || key;
|
let text = translations[key] || MINIMAL_FALLBACK[key] || key;
|
||||||
|
|
||||||
if (!translations[key] && !MINIMAL_FALLBACK[key]) {
|
|
||||||
console.warn(`i18n: Missing translation key: ${key}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params && typeof params === "object") {
|
if (params && typeof params === "object") {
|
||||||
Object.keys(params).forEach((param) => {
|
Object.keys(params).forEach((param) => {
|
||||||
text = text.replace(
|
text = text.replace(
|
||||||
|
|
@ -249,18 +232,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
console.log("i18n: Initialization started");
|
|
||||||
if (isInitialized) {
|
if (isInitialized) {
|
||||||
console.log("i18n: Already initialized, skipping");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const locale = detectBrowserLocale();
|
const locale = detectBrowserLocale();
|
||||||
console.log(`i18n: Detected locale: ${locale}`);
|
|
||||||
await loadTranslations(locale);
|
await loadTranslations(locale);
|
||||||
|
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
console.log(`i18n: Initialization complete, current locale: ${currentLocale}`);
|
|
||||||
|
|
||||||
if (document.readyState === "loading") {
|
if (document.readyState === "loading") {
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
|
@ -297,7 +276,6 @@
|
||||||
localStorage.removeItem(key);
|
localStorage.removeItem(key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log("i18n: Cleared all translation caches");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.i18n = {
|
window.i18n = {
|
||||||
|
|
|
||||||
|
|
@ -210,14 +210,10 @@
|
||||||
return originalFetch
|
return originalFetch
|
||||||
.call(window, input, init)
|
.call(window, input, init)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
var url = typeof input === "string" ? input : input.url;
|
|
||||||
|
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
|
var url = typeof input === "string" ? input : input.url;
|
||||||
self.handleUnauthorized(url);
|
self.handleUnauthorized(url);
|
||||||
} else if (!response.ok && window.ErrorReporter && window.ErrorReporter.reportNetworkError) {
|
|
||||||
window.ErrorReporter.reportNetworkError(url, response.status, response.statusText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -299,12 +295,6 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("gb:auth:expired", function (event) {
|
window.addEventListener("gb:auth:expired", function (event) {
|
||||||
// Check if current bot is public - if so, skip redirect
|
|
||||||
if (window.__BOT_IS_PUBLIC__ === true) {
|
|
||||||
console.log("[GBSecurity] Bot is public, skipping auth redirect");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"[GBSecurity] Auth expired, clearing tokens and redirecting",
|
"[GBSecurity] Auth expired, clearing tokens and redirecting",
|
||||||
);
|
);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -3,27 +3,6 @@ const ThemeManager = (() => {
|
||||||
let currentThemeId = "default";
|
let currentThemeId = "default";
|
||||||
let subscribers = [];
|
let subscribers = [];
|
||||||
|
|
||||||
// Bot ID to theme mapping (configured via config.csv theme-base field)
|
|
||||||
const botThemeMap = {
|
|
||||||
// Default bot uses light theme with brown accents
|
|
||||||
default: "light",
|
|
||||||
// Cristo bot uses typewriter theme (classic typewriter style)
|
|
||||||
cristo: "typewriter",
|
|
||||||
// Salesianos bot uses light theme with blue accents
|
|
||||||
salesianos: "light",
|
|
||||||
};
|
|
||||||
|
|
||||||
// Detect current bot from URL path
|
|
||||||
function getCurrentBotId() {
|
|
||||||
const path = window.location.pathname;
|
|
||||||
// Match patterns like /bot/cristo, /cristo, etc.
|
|
||||||
const match = path.match(/(?:\/bot\/)?([a-z0-9-]+)/i);
|
|
||||||
if (match && match[1]) {
|
|
||||||
return match[1].toLowerCase();
|
|
||||||
}
|
|
||||||
return "default";
|
|
||||||
}
|
|
||||||
|
|
||||||
const themes = [
|
const themes = [
|
||||||
{ id: "default", name: "🎨 Default", file: "light.css" },
|
{ id: "default", name: "🎨 Default", file: "light.css" },
|
||||||
{ id: "light", name: "☀️ Light", file: "light.css" },
|
{ id: "light", name: "☀️ Light", file: "light.css" },
|
||||||
|
|
@ -67,10 +46,7 @@ const ThemeManager = (() => {
|
||||||
|
|
||||||
if (!theme.file) {
|
if (!theme.file) {
|
||||||
currentThemeId = "default";
|
currentThemeId = "default";
|
||||||
const botId = getCurrentBotId();
|
localStorage.setItem("gb-theme", "default");
|
||||||
localStorage.setItem(`gb-theme-${botId}`, "default");
|
|
||||||
// Re-enable sentient theme for default
|
|
||||||
document.documentElement.setAttribute("data-theme", "sentient");
|
|
||||||
updateDropdown();
|
updateDropdown();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -78,217 +54,21 @@ const ThemeManager = (() => {
|
||||||
const link = document.createElement("link");
|
const link = document.createElement("link");
|
||||||
link.id = "theme-css";
|
link.id = "theme-css";
|
||||||
link.rel = "stylesheet";
|
link.rel = "stylesheet";
|
||||||
link.href = `/suite/public/themes/${theme.file}`;
|
link.href = `public/themes/${theme.file}`;
|
||||||
link.onload = () => {
|
link.onload = () => {
|
||||||
console.log("✓ Theme loaded:", theme.name);
|
console.log("✓ Theme loaded:", theme.name);
|
||||||
currentThemeId = id;
|
currentThemeId = id;
|
||||||
const botId = getCurrentBotId();
|
localStorage.setItem("gb-theme", id);
|
||||||
localStorage.setItem(`gb-theme-${botId}`, id);
|
updateDropdown();
|
||||||
|
subscribers.forEach((cb) => cb({ themeId: id, themeName: theme.name }));
|
||||||
// Keep data-theme="sentient" on html so CSS selectors work
|
|
||||||
// The inline styles will override the colors
|
|
||||||
if (!document.documentElement.getAttribute("data-theme")) {
|
|
||||||
document.documentElement.setAttribute("data-theme", "sentient");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove data-theme from body to prevent base.css theme rules from overriding
|
|
||||||
document.body.removeAttribute("data-theme");
|
|
||||||
|
|
||||||
// Small delay to ensure CSS variables are applied
|
|
||||||
setTimeout(() => {
|
|
||||||
// Get the theme's colors from CSS variables
|
|
||||||
const rootStyle = getComputedStyle(document.documentElement);
|
|
||||||
const primary =
|
|
||||||
rootStyle.getPropertyValue("--primary")?.trim() || "#3b82f6";
|
|
||||||
const background =
|
|
||||||
rootStyle.getPropertyValue("--background")?.trim() || "0 0% 100%";
|
|
||||||
const foreground =
|
|
||||||
rootStyle.getPropertyValue("--foreground")?.trim() || "222 47% 11%";
|
|
||||||
const card = rootStyle.getPropertyValue("--card")?.trim() || "0 0% 98%";
|
|
||||||
const border =
|
|
||||||
rootStyle.getPropertyValue("--border")?.trim() || "214 32% 91%";
|
|
||||||
|
|
||||||
// Convert HSL values to hex format for app compatibility
|
|
||||||
const hslToHex = (h, s, l) => {
|
|
||||||
l /= 100;
|
|
||||||
const a = (s * Math.min(l, 1 - l)) / 100;
|
|
||||||
const f = (n) => {
|
|
||||||
const k = (n + h / 30) % 12;
|
|
||||||
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
||||||
return Math.round(255 * color)
|
|
||||||
.toString(16)
|
|
||||||
.padStart(2, "0");
|
|
||||||
};
|
|
||||||
return `#${f(0)}${f(8)}${f(4)}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const parseHsl = (hslStr) => {
|
|
||||||
if (!hslStr) return null;
|
|
||||||
const match = hslStr
|
|
||||||
.trim()
|
|
||||||
.match(/([0-9.]+)\s+([0-9.]+)%\s+([0-9.]+)%/);
|
|
||||||
if (match) {
|
|
||||||
return [
|
|
||||||
parseFloat(match[1]),
|
|
||||||
parseFloat(match[2]),
|
|
||||||
parseFloat(match[3]),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getContrastYIQ = (hexcolor) => {
|
|
||||||
if (!hexcolor) return "#ffffff";
|
|
||||||
hexcolor = hexcolor.replace("#", "");
|
|
||||||
if (hexcolor.length === 3) {
|
|
||||||
hexcolor = hexcolor
|
|
||||||
.split("")
|
|
||||||
.map((c) => c + c)
|
|
||||||
.join("");
|
|
||||||
}
|
|
||||||
if (hexcolor.length !== 6) return "#ffffff";
|
|
||||||
var r = parseInt(hexcolor.substr(0, 2), 16);
|
|
||||||
var g = parseInt(hexcolor.substr(2, 2), 16);
|
|
||||||
var b = parseInt(hexcolor.substr(4, 2), 16);
|
|
||||||
var yiq = (r * 299 + g * 587 + b * 114) / 1000;
|
|
||||||
return yiq >= 128 ? "#000000" : "#ffffff";
|
|
||||||
};
|
|
||||||
|
|
||||||
const bgHsl = parseHsl(background);
|
|
||||||
const fgHsl = parseHsl(foreground);
|
|
||||||
const cardHsl = parseHsl(card);
|
|
||||||
const borderHsl = parseHsl(border);
|
|
||||||
|
|
||||||
let calculatedTextHex = "#ffffff";
|
|
||||||
|
|
||||||
if (bgHsl) {
|
|
||||||
const bgHex = hslToHex(...bgHsl);
|
|
||||||
document.documentElement.style.setProperty("--bg", bgHex);
|
|
||||||
document.documentElement.style.setProperty("--bg-secondary", bgHex);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--primary-bg",
|
|
||||||
`hsl(${background})`,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty("--header-bg", bgHex);
|
|
||||||
document.documentElement.style.setProperty("--glass-bg", bgHex);
|
|
||||||
document.documentElement.style.setProperty("--sidebar-bg", bgHex);
|
|
||||||
calculatedTextHex = getContrastYIQ(bgHex);
|
|
||||||
}
|
|
||||||
if (fgHsl) {
|
|
||||||
const textHex = hslToHex(...fgHsl);
|
|
||||||
document.documentElement.style.setProperty("--text", textHex);
|
|
||||||
document.documentElement.style.setProperty("--text-primary", textHex);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--text-secondary",
|
|
||||||
textHex,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty("--text-muted", textHex);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--primary-fg",
|
|
||||||
`hsl(${foreground})`,
|
|
||||||
);
|
|
||||||
} else if (bgHsl) {
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--text",
|
|
||||||
calculatedTextHex,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--text-primary",
|
|
||||||
calculatedTextHex,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--text-secondary",
|
|
||||||
calculatedTextHex,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--text-muted",
|
|
||||||
calculatedTextHex,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (cardHsl) {
|
|
||||||
const surfaceHex = hslToHex(...cardHsl);
|
|
||||||
document.documentElement.style.setProperty("--surface", surfaceHex);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--surface-hover",
|
|
||||||
surfaceHex,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--surface-active",
|
|
||||||
surfaceHex,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty("--card-bg", surfaceHex);
|
|
||||||
}
|
|
||||||
if (borderHsl) {
|
|
||||||
const borderHex = hslToHex(...borderHsl);
|
|
||||||
document.documentElement.style.setProperty("--border", borderHex);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--border-light",
|
|
||||||
borderHex,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Check if config.csv already set the primary color, we shouldn't wipe it
|
|
||||||
// Only update color and suggestion variables if they aren't marked as bot-config
|
|
||||||
if (
|
|
||||||
document.documentElement.getAttribute("data-has-bot-colors") !==
|
|
||||||
"true"
|
|
||||||
) {
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--chat-color1",
|
|
||||||
`hsl(${primary})`,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--chat-color2",
|
|
||||||
`hsl(${card})`,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--suggestion-color",
|
|
||||||
`hsl(${primary})`,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--suggestion-bg",
|
|
||||||
`hsl(${card})`,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--color1",
|
|
||||||
`hsl(${primary})`,
|
|
||||||
);
|
|
||||||
document.documentElement.style.setProperty(
|
|
||||||
"--color2",
|
|
||||||
`hsl(${card})`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("✓ Theme colors applied:", {
|
|
||||||
bg: background,
|
|
||||||
primary: primary,
|
|
||||||
});
|
|
||||||
updateDropdown();
|
|
||||||
|
|
||||||
// Fix theme dropdown background to use surface color
|
|
||||||
const themeDropdown = document.getElementById("themeDropdown");
|
|
||||||
if (themeDropdown) {
|
|
||||||
const surfaceColor = getComputedStyle(document.documentElement)
|
|
||||||
.getPropertyValue("--surface")
|
|
||||||
.trim();
|
|
||||||
if (surfaceColor) {
|
|
||||||
themeDropdown.style.setProperty(
|
|
||||||
"background",
|
|
||||||
surfaceColor,
|
|
||||||
"important",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subscribers.forEach((cb) => cb({ themeId: id, themeName: theme.name }));
|
|
||||||
}, 50);
|
|
||||||
};
|
};
|
||||||
link.onerror = () => console.error("✗ Failed:", theme.name);
|
link.onerror = () => console.error("✗ Failed:", theme.name);
|
||||||
document.head.appendChild(link);
|
document.head.appendChild(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDropdown() {
|
function updateDropdown() {
|
||||||
const select = document.getElementById("themeDropdown");
|
const dd = document.getElementById("themeDropdown");
|
||||||
if (select) select.value = currentThemeId;
|
if (dd) dd.value = currentThemeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDropdown() {
|
function createDropdown() {
|
||||||
|
|
@ -307,96 +87,33 @@ const ThemeManager = (() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
// Ensure data-theme is set on html element so CSS selectors work
|
let saved = localStorage.getItem("gb-theme") || "default";
|
||||||
if (!document.documentElement.getAttribute("data-theme")) {
|
|
||||||
document.documentElement.setAttribute("data-theme", "sentient");
|
|
||||||
}
|
|
||||||
|
|
||||||
// First, load saved bot theme from config.csv (if available)
|
|
||||||
loadSavedTheme();
|
|
||||||
|
|
||||||
// Then load the UI theme (CSS theme)
|
|
||||||
// Priority: 1) localStorage user preference, 2) bot-specific theme, 3) default
|
|
||||||
const botId = getCurrentBotId();
|
|
||||||
let saved = localStorage.getItem(`gb-theme-${botId}`);
|
|
||||||
if (!saved || !themes.find((t) => t.id === saved)) {
|
|
||||||
// No user preference, try bot-specific theme
|
|
||||||
saved = botThemeMap[botId] || "light";
|
|
||||||
// Save to localStorage so it persists
|
|
||||||
localStorage.setItem(`gb-theme-${botId}`, saved);
|
|
||||||
}
|
|
||||||
if (!themes.find((t) => t.id === saved)) saved = "default";
|
if (!themes.find((t) => t.id === saved)) saved = "default";
|
||||||
currentThemeId = saved;
|
currentThemeId = saved;
|
||||||
loadTheme(saved);
|
loadTheme(saved);
|
||||||
|
|
||||||
// Dropdown injection restored for the window manager
|
|
||||||
const container = document.getElementById("themeSelectorContainer");
|
const container = document.getElementById("themeSelectorContainer");
|
||||||
if (container) {
|
if (container) container.appendChild(createDropdown());
|
||||||
container.innerHTML = "";
|
|
||||||
container.appendChild(createDropdown());
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("✓ Theme Manager initialized");
|
console.log("✓ Theme Manager initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setThemeFromServer(data) {
|
function setThemeFromServer(data) {
|
||||||
// Save theme to localStorage for persistence across page loads
|
|
||||||
const botId = getCurrentBotId();
|
|
||||||
localStorage.setItem(`gb-theme-data-${botId}`, JSON.stringify(data));
|
|
||||||
|
|
||||||
// Load base theme if specified
|
|
||||||
if (data.theme_base) {
|
|
||||||
loadTheme(data.theme_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.logo_url) {
|
if (data.logo_url) {
|
||||||
// For img elements - set src and show, hide SVG
|
document
|
||||||
const logoImg = document.querySelector(".logo-icon-img");
|
.querySelectorAll(".logo-icon, .assistant-avatar")
|
||||||
const logoSvg = document.querySelector(".logo-icon-svg");
|
.forEach((el) => {
|
||||||
if (logoImg && logoSvg) {
|
el.style.backgroundImage = `url("${data.logo_url}")`;
|
||||||
logoImg.src = data.logo_url;
|
});
|
||||||
logoImg.alt = data.title || "Logo";
|
|
||||||
logoImg.style.display = "block";
|
|
||||||
logoSvg.style.display = "none";
|
|
||||||
}
|
|
||||||
|
|
||||||
// For elements that use background image
|
|
||||||
document.querySelectorAll(".assistant-avatar").forEach((el) => {
|
|
||||||
el.style.backgroundImage = `url("${data.logo_url}")`;
|
|
||||||
el.style.backgroundSize = "contain";
|
|
||||||
el.style.backgroundRepeat = "no-repeat";
|
|
||||||
el.style.backgroundPosition = "center";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (data.color1) {
|
|
||||||
document.documentElement.style.setProperty("--color1", data.color1);
|
|
||||||
}
|
|
||||||
if (data.color2) {
|
|
||||||
document.documentElement.style.setProperty("--color2", data.color2);
|
|
||||||
}
|
}
|
||||||
if (data.title) document.title = data.title;
|
if (data.title) document.title = data.title;
|
||||||
if (data.logo_text) {
|
if (data.logo_text) {
|
||||||
document.querySelectorAll(".logo span, .logo-text").forEach((el) => {
|
document.querySelectorAll(".logo-text").forEach((el) => {
|
||||||
el.textContent = data.logo_text;
|
el.textContent = data.logo_text;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load saved theme from localStorage on page load
|
|
||||||
function loadSavedTheme() {
|
|
||||||
const botId = getCurrentBotId();
|
|
||||||
const savedTheme = localStorage.getItem(`gb-theme-data-${botId}`);
|
|
||||||
if (savedTheme) {
|
|
||||||
try {
|
|
||||||
const data = JSON.parse(savedTheme);
|
|
||||||
setThemeFromServer(data);
|
|
||||||
console.log(`✓ Theme loaded from localStorage for ${botId}`);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("Failed to load saved theme:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyCustomizations() {
|
function applyCustomizations() {
|
||||||
// Called by modules if needed
|
// Called by modules if needed
|
||||||
}
|
}
|
||||||
|
|
@ -409,7 +126,6 @@ const ThemeManager = (() => {
|
||||||
init,
|
init,
|
||||||
loadTheme,
|
loadTheme,
|
||||||
setThemeFromServer,
|
setThemeFromServer,
|
||||||
loadSavedTheme,
|
|
||||||
applyCustomizations,
|
applyCustomizations,
|
||||||
subscribe,
|
subscribe,
|
||||||
getAvailableThemes: () => themes,
|
getAvailableThemes: () => themes,
|
||||||
|
|
|
||||||
83
ui/suite/js/vendor/tailwindcss.js
vendored
83
ui/suite/js/vendor/tailwindcss.js
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -1,8 +0,0 @@
|
||||||
/*!-----------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.de",{"vs/base/common/platform":["_"],"vs/editor/common/languages":["Array","Boolescher Wert","Klasse","Konstante","Konstruktor","Enumeration","Enumerationsmember","Ereignis","Feld","Datei","Funktion","Schnittstelle","Schl\xFCssel","Methode","Modul","Namespace","NULL","Zahl","Objekt","Operator","Paket","Eigenschaft","Zeichenfolge","Struktur","Typparameter","Variable","{0} ({1})"]});
|
|
||||||
|
|
||||||
//# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.de.js.map
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/*!-----------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.es",{"vs/base/common/platform":["_"],"vs/editor/common/languages":["matriz","booleano","clase","constante","constructor","enumeraci\xF3n","miembro de la enumeraci\xF3n","evento","campo","archivo","funci\xF3n","interfaz","clave","m\xE9todo","m\xF3dulo","espacio de nombres","NULL","n\xFAmero","objeto","operador","paquete","propiedad","cadena","estructura","par\xE1metro de tipo","variable","{0} ({1})"]});
|
|
||||||
|
|
||||||
//# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.es.js.map
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/*!-----------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.fr",{"vs/base/common/platform":["_"],"vs/editor/common/languages":["tableau","bool\xE9en","classe","constante","constructeur","\xE9num\xE9ration","membre d'\xE9num\xE9ration","\xE9v\xE9nement","champ","fichier","fonction","interface","cl\xE9","m\xE9thode","module","espace de noms","NULL","nombre","objet","op\xE9rateur","package","propri\xE9t\xE9","cha\xEEne","struct","param\xE8tre de type","variable","{0} ({1})"]});
|
|
||||||
|
|
||||||
//# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.fr.js.map
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/*!-----------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.it",{"vs/base/common/platform":["_"],"vs/editor/common/languages":["matrice","valore booleano","classe","costante","costruttore","enumerazione","membro di enumerazione","evento","campo","file","funzione","interfaccia","chiave","metodo","modulo","spazio dei nomi","Null","numero","oggetto","operatore","pacchetto","propriet\xE0","stringa","struct","parametro di tipo","variabile","{0} ({1})"]});
|
|
||||||
|
|
||||||
//# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.it.js.map
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/*!-----------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.ja",{"vs/base/common/platform":["_"],"vs/editor/common/languages":["\u914D\u5217","\u30D6\u30FC\u30EB\u5024","\u30AF\u30E9\u30B9","\u5B9A\u6570","\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u30FC","\u5217\u6319\u578B","\u5217\u6319\u578B\u30E1\u30F3\u30D0\u30FC","\u30A4\u30D9\u30F3\u30C8","\u30D5\u30A3\u30FC\u30EB\u30C9","\u30D5\u30A1\u30A4\u30EB","\u95A2\u6570","\u30A4\u30F3\u30BF\u30FC\u30D5\u30A7\u30A4\u30B9","\u30AD\u30FC","\u30E1\u30BD\u30C3\u30C9","\u30E2\u30B8\u30E5\u30FC\u30EB","\u540D\u524D\u7A7A\u9593","NULL","\u6570\u5024","\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8","\u6F14\u7B97\u5B50","\u30D1\u30C3\u30B1\u30FC\u30B8","\u30D7\u30ED\u30D1\u30C6\u30A3","\u6587\u5B57\u5217","\u69CB\u9020\u4F53","\u578B\u30D1\u30E9\u30E1\u30FC\u30BF\u30FC","\u5909\u6570","{0} ({1})"]});
|
|
||||||
|
|
||||||
//# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.ja.js.map
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/*!-----------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls",{"vs/base/common/platform":["_"],"vs/editor/common/languages":["array","boolean","class","constant","constructor","enumeration","enumeration member","event","field","file","function","interface","key","method","module","namespace","null","number","object","operator","package","property","string","struct","type parameter","variable","{0} ({1})"]});
|
|
||||||
|
|
||||||
//# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.js.map
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/*!-----------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.ko",{"vs/base/common/platform":["_"],"vs/editor/common/languages":["\uBC30\uC5F4","\uBD80\uC6B8","\uD074\uB798\uC2A4","\uC0C1\uC218","\uC0DD\uC131\uC790","\uC5F4\uAC70\uD615","\uC5F4\uAC70\uD615 \uBA64\uBC84","\uC774\uBCA4\uD2B8","\uD544\uB4DC","\uD30C\uC77C","\uD568\uC218","\uC778\uD130\uD398\uC774\uC2A4","\uD0A4","\uBA54\uC11C\uB4DC","\uBAA8\uB4C8","\uB124\uC784\uC2A4\uD398\uC774\uC2A4","Null","\uC22B\uC790","\uAC1C\uCCB4","\uC5F0\uC0B0\uC790","\uD328\uD0A4\uC9C0","\uC18D\uC131","\uBB38\uC790\uC5F4","\uAD6C\uC870\uCCB4","\uD615\uC2DD \uB9E4\uAC1C \uBCC0\uC218","\uBCC0\uC218","{0}({1})"]});
|
|
||||||
|
|
||||||
//# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.ko.js.map
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/*!-----------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.ru",{"vs/base/common/platform":["_"],"vs/editor/common/languages":["\u043C\u0430\u0441\u0441\u0438\u0432","\u043B\u043E\u0433\u0438\u0447\u0435\u0441\u043A\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435","\u043A\u043B\u0430\u0441\u0441","\u043A\u043E\u043D\u0441\u0442\u0430\u043D\u0442\u0430","\u043A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u043E\u0440","\u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u0435","\u044D\u043B\u0435\u043C\u0435\u043D\u0442 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F","\u0441\u043E\u0431\u044B\u0442\u0438\u0435","\u043F\u043E\u043B\u0435","\u0444\u0430\u0439\u043B","\u0444\u0443\u043D\u043A\u0446\u0438\u044F","\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441","\u043A\u043B\u044E\u0447","\u043C\u0435\u0442\u043E\u0434","\u043C\u043E\u0434\u0443\u043B\u044C","\u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0441\u0442\u0432\u043E \u0438\u043C\u0435\u043D","NULL","\u0447\u0438\u0441\u043B\u043E","\u043E\u0431\u044A\u0435\u043A\u0442","\u043E\u043F\u0435\u0440\u0430\u0442\u043E\u0440","\u043F\u0430\u043A\u0435\u0442","\u0441\u0432\u043E\u0439\u0441\u0442\u0432\u043E","\u0441\u0442\u0440\u043E\u043A\u0430","\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430","\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440 \u0442\u0438\u043F\u0430","\u041F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u0430\u044F","{0} ({1})"]});
|
|
||||||
|
|
||||||
//# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.ru.js.map
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/*!-----------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.zh-cn",{"vs/base/common/platform":["_"],"vs/editor/common/languages":["\u6570\u7EC4","\u5E03\u5C14\u503C","\u7C7B","\u5E38\u6570","\u6784\u9020\u51FD\u6570","\u679A\u4E3E","\u679A\u4E3E\u6210\u5458","\u4E8B\u4EF6","\u5B57\u6BB5","\u6587\u4EF6","\u51FD\u6570","\u63A5\u53E3","\u952E","\u65B9\u6CD5","\u6A21\u5757","\u547D\u540D\u7A7A\u95F4","Null","\u6570\u5B57","\u5BF9\u8C61","\u8FD0\u7B97\u7B26","\u5305","\u5C5E\u6027","\u5B57\u7B26\u4E32","\u7ED3\u6784","\u7C7B\u578B\u53C2\u6570","\u53D8\u91CF","{0} ({1})"]});
|
|
||||||
|
|
||||||
//# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.zh-cn.js.map
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/*!-----------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/vscode/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls.zh-tw",{"vs/base/common/platform":["_"],"vs/editor/common/languages":["\u9663\u5217","\u5E03\u6797\u503C","\u985E\u5225","\u5E38\u6578","\u5EFA\u69CB\u51FD\u5F0F","\u5217\u8209","\u5217\u8209\u6210\u54E1","\u4E8B\u4EF6","\u6B04\u4F4D","\u6A94\u6848","\u51FD\u5F0F","\u4ECB\u9762","\u7D22\u5F15\u9375","\u65B9\u6CD5","\u6A21\u7D44","\u547D\u540D\u7A7A\u9593","null","\u6578\u5B57","\u7269\u4EF6","\u904B\u7B97\u5B50","\u5957\u4EF6","\u5C6C\u6027","\u5B57\u4E32","\u7D50\u69CB","\u578B\u5225\u53C3\u6578","\u8B8A\u6578","{0} ({1})"]});
|
|
||||||
|
|
||||||
//# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.zh-tw.js.map
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/apex/apex", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var i=Object.defineProperty;var r=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var d=(e,t)=>{for(var s in t)i(e,s,{get:t[s],enumerable:!0})},g=(e,t,s,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of c(t))!l.call(e,o)&&o!==s&&i(e,o,{get:()=>t[o],enumerable:!(a=r(t,o))||a.enumerable});return e};var p=e=>g(i({},"__esModule",{value:!0}),e);var h={};d(h,{conf:()=>m,language:()=>b});var m={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"<",close:">"}],folding:{markers:{start:new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:<editor-fold\\b))"),end:new RegExp("^\\s*//\\s*(?:(?:#?endregion\\b)|(?:</editor-fold>))")}}},u=["abstract","activate","and","any","array","as","asc","assert","autonomous","begin","bigdecimal","blob","boolean","break","bulk","by","case","cast","catch","char","class","collect","commit","const","continue","convertcurrency","decimal","default","delete","desc","do","double","else","end","enum","exception","exit","export","extends","false","final","finally","float","for","from","future","get","global","goto","group","having","hint","if","implements","import","in","inner","insert","instanceof","int","interface","into","join","last_90_days","last_month","last_n_days","last_week","like","limit","list","long","loop","map","merge","native","new","next_90_days","next_month","next_n_days","next_week","not","null","nulls","number","object","of","on","or","outer","override","package","parallel","pragma","private","protected","public","retrieve","return","returning","rollback","savepoint","search","select","set","short","sort","stat","static","strictfp","super","switch","synchronized","system","testmethod","then","this","this_month","this_week","throw","throws","today","tolabel","tomorrow","transaction","transient","trigger","true","try","type","undelete","update","upsert","using","virtual","void","volatile","webservice","when","where","while","yesterday"],f=e=>e.charAt(0).toUpperCase()+e.substr(1),n=[];u.forEach(e=>{n.push(e),n.push(e.toUpperCase()),n.push(f(e))});var b={defaultToken:"",tokenPostfix:".apex",keywords:n,operators:["=",">","<","!","~","?",":","==","<=",">=","!=","&&","||","++","--","+","-","*","/","&","|","^","%","<<",">>",">>>","+=","-=","*=","/=","&=","|=","^=","%=","<<=",">>=",">>>="],symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,digits:/\d+(_+\d+)*/,octaldigits:/[0-7]+(_+[0-7]+)*/,binarydigits:/[0-1]+(_+[0-1]+)*/,hexdigits:/[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,tokenizer:{root:[[/[a-z_$][\w$]*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],[/[A-Z][\w\$]*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"type.identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/@\s*[a-zA-Z_\$][\w\$]*/,"annotation"],[/(@digits)[eE]([\-+]?(@digits))?[fFdD]?/,"number.float"],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?[fFdD]?/,"number.float"],[/(@digits)[fFdD]/,"number.float"],[/(@digits)[lL]?/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/"/,"string",'@string."'],[/'/,"string","@string.'"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@apexdoc"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],apexdoc:[[/[^\/*]+/,"comment.doc"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],string:[[/[^\\"']+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/["']/,{cases:{"$#==$S2":{token:"string",next:"@pop"},"@default":"string"}}]]}};return p(h);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/azcli/azcli", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var s=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var r=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var c=(t,e)=>{for(var o in e)s(t,o,{get:e[o],enumerable:!0})},k=(t,e,o,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of r(e))!l.call(t,n)&&n!==o&&s(t,n,{get:()=>e[n],enumerable:!(a=i(e,n))||a.enumerable});return t};var p=t=>k(s({},"__esModule",{value:!0}),t);var d={};c(d,{conf:()=>f,language:()=>g});var f={comments:{lineComment:"#"}},g={defaultToken:"keyword",ignoreCase:!0,tokenPostfix:".azcli",str:/[^#\s]/,tokenizer:{root:[{include:"@comment"},[/\s-+@str*\s*/,{cases:{"@eos":{token:"key.identifier",next:"@popall"},"@default":{token:"key.identifier",next:"@type"}}}],[/^-+@str*\s*/,{cases:{"@eos":{token:"key.identifier",next:"@popall"},"@default":{token:"key.identifier",next:"@type"}}}]],type:[{include:"@comment"},[/-+@str*\s*/,{cases:{"@eos":{token:"key.identifier",next:"@popall"},"@default":"key.identifier"}}],[/@str+\s*/,{cases:{"@eos":{token:"string",next:"@popall"},"@default":"string"}}]],comment:[[/#.*$/,{cases:{"@eos":{token:"comment",next:"@popall"}}}]]}};return p(d);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/bat/bat", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var n=Object.defineProperty;var r=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var g=(o,e)=>{for(var t in e)n(o,t,{get:e[t],enumerable:!0})},c=(o,e,t,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of l(e))!i.call(o,s)&&s!==t&&n(o,s,{get:()=>e[s],enumerable:!(a=r(e,s))||a.enumerable});return o};var p=o=>c(n({},"__esModule",{value:!0}),o);var k={};g(k,{conf:()=>d,language:()=>m});var d={comments:{lineComment:"REM"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],surroundingPairs:[{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],folding:{markers:{start:new RegExp("^\\s*(::\\s*|REM\\s+)#region"),end:new RegExp("^\\s*(::\\s*|REM\\s+)#endregion")}}},m={defaultToken:"",ignoreCase:!0,tokenPostfix:".bat",brackets:[{token:"delimiter.bracket",open:"{",close:"}"},{token:"delimiter.parenthesis",open:"(",close:")"},{token:"delimiter.square",open:"[",close:"]"}],keywords:/call|defined|echo|errorlevel|exist|for|goto|if|pause|set|shift|start|title|not|pushd|popd/,symbols:/[=><!~?&|+\-*\/\^;\.,]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[[/^(\s*)(rem(?:\s.*|))$/,["","comment"]],[/(\@?)(@keywords)(?!\w)/,[{token:"keyword"},{token:"keyword.$2"}]],[/[ \t\r\n]+/,""],[/setlocal(?!\w)/,"keyword.tag-setlocal"],[/endlocal(?!\w)/,"keyword.tag-setlocal"],[/[a-zA-Z_]\w*/,""],[/:\w*/,"metatag"],[/%[^%]+%/,"variable"],[/%%[\w]+(?!\w)/,"variable"],[/[{}()\[\]]/,"@brackets"],[/@symbols/,"delimiter"],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F_]*[0-9a-fA-F]/,"number.hex"],[/\d+/,"number"],[/[;,.]/,"delimiter"],[/"/,"string",'@string."'],[/'/,"string","@string.'"]],string:[[/[^\\"'%]+/,{cases:{"@eos":{token:"string",next:"@popall"},"@default":"string"}}],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/%[\w ]+%/,"variable"],[/%%[\w]+(?!\w)/,"variable"],[/["']/,{cases:{"$#==$S2":{token:"string",next:"@pop"},"@default":"string"}}],[/$/,"string","@popall"]]}};return p(k);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/bicep/bicep", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var r=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var g=(e,n)=>{for(var o in n)r(e,o,{get:n[o],enumerable:!0})},l=(e,n,o,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of c(n))!a.call(e,t)&&t!==o&&r(e,t,{get:()=>n[t],enumerable:!(i=s(n,t))||i.enumerable});return e};var m=e=>l(r({},"__esModule",{value:!0}),e);var y={};g(y,{conf:()=>$,language:()=>w});var p=e=>`\\b${e}\\b`,k="[_a-zA-Z]",x="[_a-zA-Z0-9]",u=p(`${k}${x}*`),d=["targetScope","resource","module","param","var","output","for","in","if","existing"],b=["true","false","null"],f="[ \\t\\r\\n]",C="[0-9]+",$={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"'",close:"'"},{open:"'''",close:"'''"}],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"'",close:"'",notIn:["string","comment"]},{open:"'''",close:"'''",notIn:["string","comment"]}],autoCloseBefore:`:.,=}])'
|
|
||||||
`,indentationRules:{increaseIndentPattern:new RegExp("^((?!\\/\\/).)*(\\{[^}\"'`]*|\\([^)\"'`]*|\\[[^\\]\"'`]*)$"),decreaseIndentPattern:new RegExp("^((?!.*?\\/\\*).*\\*/)?\\s*[\\}\\]].*$")}},w={defaultToken:"",tokenPostfix:".bicep",brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"}],symbols:/[=><!~?:&|+\-*/^%]+/,keywords:d,namedLiterals:b,escapes:"\\\\(u{[0-9A-Fa-f]+}|n|r|t|\\\\|'|\\${)",tokenizer:{root:[{include:"@expression"},{include:"@whitespace"}],stringVerbatim:[{regex:"(|'|'')[^']",action:{token:"string"}},{regex:"'''",action:{token:"string.quote",next:"@pop"}}],stringLiteral:[{regex:"\\${",action:{token:"delimiter.bracket",next:"@bracketCounting"}},{regex:"[^\\\\'$]+",action:{token:"string"}},{regex:"@escapes",action:{token:"string.escape"}},{regex:"\\\\.",action:{token:"string.escape.invalid"}},{regex:"'",action:{token:"string",next:"@pop"}}],bracketCounting:[{regex:"{",action:{token:"delimiter.bracket",next:"@bracketCounting"}},{regex:"}",action:{token:"delimiter.bracket",next:"@pop"}},{include:"expression"}],comment:[{regex:"[^\\*]+",action:{token:"comment"}},{regex:"\\*\\/",action:{token:"comment",next:"@pop"}},{regex:"[\\/*]",action:{token:"comment"}}],whitespace:[{regex:f},{regex:"\\/\\*",action:{token:"comment",next:"@comment"}},{regex:"\\/\\/.*$",action:{token:"comment"}}],expression:[{regex:"'''",action:{token:"string.quote",next:"@stringVerbatim"}},{regex:"'",action:{token:"string.quote",next:"@stringLiteral"}},{regex:C,action:{token:"number"}},{regex:u,action:{cases:{"@keywords":{token:"keyword"},"@namedLiterals":{token:"keyword"},"@default":{token:"identifier"}}}}]}};return m(y);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/cameligo/cameligo", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var s=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var c=(o,e)=>{for(var n in e)s(o,n,{get:e[n],enumerable:!0})},m=(o,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of a(e))!l.call(o,t)&&t!==n&&s(o,t,{get:()=>e[t],enumerable:!(r=i(e,t))||r.enumerable});return o};var p=o=>m(s({},"__esModule",{value:!0}),o);var u={};c(u,{conf:()=>d,language:()=>g});var d={comments:{lineComment:"//",blockComment:["(*","*)"]},brackets:[["{","}"],["[","]"],["(",")"],["<",">"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'},{open:"(*",close:"*)"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'},{open:"(*",close:"*)"}]},g={defaultToken:"",tokenPostfix:".cameligo",ignoreCase:!0,brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],keywords:["abs","assert","block","Bytes","case","Crypto","Current","else","failwith","false","for","fun","if","in","let","let%entry","let%init","List","list","Map","map","match","match%nat","mod","not","operation","Operation","of","record","Set","set","sender","skip","source","String","then","to","true","type","with"],typeKeywords:["int","unit","string","tz","nat","bool"],operators:["=",">","<","<=",">=","<>",":",":=","and","mod","or","+","-","*","/","@","&","^","%","->","<-","&&","||"],symbols:/[=><:@\^&|+\-*\/\^%]+/,tokenizer:{root:[[/[a-zA-Z_][\w]*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/\$[0-9a-fA-F]{1,16}/,"number.hex"],[/\d+/,"number"],[/[;,.]/,"delimiter"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/'/,"string","@string"],[/'[^\\']'/,"string"],[/'/,"string.invalid"],[/\#\d+/,"string"]],comment:[[/[^\(\*]+/,"comment"],[/\*\)/,"comment","@pop"],[/\(\*/,"comment"]],string:[[/[^\\']+/,"string"],[/\\./,"string.escape.invalid"],[/'/,{token:"string.quote",bracket:"@close",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,"white"],[/\(\*/,"comment","@comment"],[/\/\/.*$/,"comment"]]}};return p(u);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/coffee/coffee", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var s=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var l=(n,e)=>{for(var t in e)s(n,t,{get:e[t],enumerable:!0})},p=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of g(e))!a.call(n,r)&&r!==t&&s(n,r,{get:()=>e[r],enumerable:!(o=i(e,r))||o.enumerable});return n};var c=n=>p(s({},"__esModule",{value:!0}),n);var m={};l(m,{conf:()=>d,language:()=>x});var d={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\#%\^\&\*\(\)\=\$\-\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{blockComment:["###","###"],lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],folding:{markers:{start:new RegExp("^\\s*#region\\b"),end:new RegExp("^\\s*#endregion\\b")}}},x={defaultToken:"",ignoreCase:!0,tokenPostfix:".coffee",brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"}],regEx:/\/(?!\/\/)(?:[^\/\\]|\\.)*\/[igm]*/,keywords:["and","or","is","isnt","not","on","yes","@","no","off","true","false","null","this","new","delete","typeof","in","instanceof","return","throw","break","continue","debugger","if","else","switch","for","while","do","try","catch","finally","class","extends","super","undefined","then","unless","until","loop","of","by","when"],symbols:/[=><!~?&%|+\-*\/\^\.,\:]+/,escapes:/\\(?:[abfnrtv\\"'$]|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[[/\@[a-zA-Z_]\w*/,"variable.predefined"],[/[a-zA-Z_]\w*/,{cases:{this:"variable.predefined","@keywords":{token:"keyword.$0"},"@default":""}}],[/[ \t\r\n]+/,""],[/###/,"comment","@comment"],[/#.*$/,"comment"],["///",{token:"regexp",next:"@hereregexp"}],[/^(\s*)(@regEx)/,["","regexp"]],[/(\()(\s*)(@regEx)/,["@brackets","","regexp"]],[/(\,)(\s*)(@regEx)/,["delimiter","","regexp"]],[/(\=)(\s*)(@regEx)/,["delimiter","","regexp"]],[/(\:)(\s*)(@regEx)/,["delimiter","","regexp"]],[/(\[)(\s*)(@regEx)/,["@brackets","","regexp"]],[/(\!)(\s*)(@regEx)/,["delimiter","","regexp"]],[/(\&)(\s*)(@regEx)/,["delimiter","","regexp"]],[/(\|)(\s*)(@regEx)/,["delimiter","","regexp"]],[/(\?)(\s*)(@regEx)/,["delimiter","","regexp"]],[/(\{)(\s*)(@regEx)/,["@brackets","","regexp"]],[/(\;)(\s*)(@regEx)/,["","","regexp"]],[/}/,{cases:{"$S2==interpolatedstring":{token:"string",next:"@pop"},"@default":"@brackets"}}],[/[{}()\[\]]/,"@brackets"],[/@symbols/,"delimiter"],[/\d+[eE]([\-+]?\d+)?/,"number.float"],[/\d+\.\d+([eE][\-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F]+/,"number.hex"],[/0[0-7]+(?!\d)/,"number.octal"],[/\d+/,"number"],[/[,.]/,"delimiter"],[/"""/,"string",'@herestring."""'],[/'''/,"string","@herestring.'''"],[/"/,{cases:{"@eos":"string","@default":{token:"string",next:'@string."'}}}],[/'/,{cases:{"@eos":"string","@default":{token:"string",next:"@string.'"}}}]],string:[[/[^"'\#\\]+/,"string"],[/@escapes/,"string.escape"],[/\./,"string.escape.invalid"],[/\./,"string.escape.invalid"],[/#{/,{cases:{'$S2=="':{token:"string",next:"root.interpolatedstring"},"@default":"string"}}],[/["']/,{cases:{"$#==$S2":{token:"string",next:"@pop"},"@default":"string"}}],[/#/,"string"]],herestring:[[/("""|''')/,{cases:{"$1==$S2":{token:"string",next:"@pop"},"@default":"string"}}],[/[^#\\'"]+/,"string"],[/['"]+/,"string"],[/@escapes/,"string.escape"],[/\./,"string.escape.invalid"],[/#{/,{token:"string.quote",next:"root.interpolatedstring"}],[/#/,"string"]],comment:[[/[^#]+/,"comment"],[/###/,"comment","@pop"],[/#/,"comment"]],hereregexp:[[/[^\\\/#]+/,"regexp"],[/\\./,"regexp"],[/#.*$/,"comment"],["///[igm]*",{token:"regexp",next:"@pop"}],[/\//,"regexp"]]}};return c(m);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/csharp/csharp", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var s=Object.defineProperty;var r=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var l=(t,e)=>{for(var o in e)s(t,o,{get:e[o],enumerable:!0})},p=(t,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of a(e))!c.call(t,n)&&n!==o&&s(t,n,{get:()=>e[n],enumerable:!(i=r(e,n))||i.enumerable});return t};var g=t=>p(s({},"__esModule",{value:!0}),t);var u={};l(u,{conf:()=>d,language:()=>m});var d={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"'",close:"'",notIn:["string","comment"]},{open:'"',close:'"',notIn:["string","comment"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"},{open:'"',close:'"'}],folding:{markers:{start:new RegExp("^\\s*#region\\b"),end:new RegExp("^\\s*#endregion\\b")}}},m={defaultToken:"",tokenPostfix:".cs",brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],keywords:["extern","alias","using","bool","decimal","sbyte","byte","short","ushort","int","uint","long","ulong","char","float","double","object","dynamic","string","assembly","is","as","ref","out","this","base","new","typeof","void","checked","unchecked","default","delegate","var","const","if","else","switch","case","while","do","for","foreach","in","break","continue","goto","return","throw","try","catch","finally","lock","yield","from","let","where","join","on","equals","into","orderby","ascending","descending","select","group","by","namespace","partial","class","field","event","method","param","public","protected","internal","private","abstract","sealed","static","struct","readonly","volatile","virtual","override","params","get","set","add","remove","operator","true","false","implicit","explicit","interface","enum","null","async","await","fixed","sizeof","stackalloc","unsafe","nameof","when"],namespaceFollows:["namespace","using"],parenFollows:["if","for","while","switch","foreach","using","catch","when"],operators:["=","??","||","&&","|","^","&","==","!=","<=",">=","<<","+","-","*","/","%","!","~","++","--","+=","-=","*=","/=","%=","&=","|=","^=","<<=",">>=",">>","=>"],symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[[/\@?[a-zA-Z_]\w*/,{cases:{"@namespaceFollows":{token:"keyword.$0",next:"@namespace"},"@keywords":{token:"keyword.$0",next:"@qualified"},"@default":{token:"identifier",next:"@qualified"}}}],{include:"@whitespace"},[/}/,{cases:{"$S2==interpolatedstring":{token:"string.quote",next:"@pop"},"$S2==litinterpstring":{token:"string.quote",next:"@pop"},"@default":"@brackets"}}],[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/[0-9_]*\.[0-9_]+([eE][\-+]?\d+)?[fFdD]?/,"number.float"],[/0[xX][0-9a-fA-F_]+/,"number.hex"],[/0[bB][01_]+/,"number.hex"],[/[0-9_]+/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,{token:"string.quote",next:"@string"}],[/\$\@"/,{token:"string.quote",next:"@litinterpstring"}],[/\@"/,{token:"string.quote",next:"@litstring"}],[/\$"/,{token:"string.quote",next:"@interpolatedstring"}],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],qualified:[[/[a-zA-Z_][\w]*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],[/\./,"delimiter"],["","","@pop"]],namespace:[{include:"@whitespace"},[/[A-Z]\w*/,"namespace"],[/[\.=]/,"delimiter"],["","","@pop"]],comment:[[/[^\/*]+/,"comment"],["\\*/","comment","@pop"],[/[\/*]/,"comment"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,{token:"string.quote",next:"@pop"}]],litstring:[[/[^"]+/,"string"],[/""/,"string.escape"],[/"/,{token:"string.quote",next:"@pop"}]],litinterpstring:[[/[^"{]+/,"string"],[/""/,"string.escape"],[/{{/,"string.escape"],[/}}/,"string.escape"],[/{/,{token:"string.quote",next:"root.litinterpstring"}],[/"/,{token:"string.quote",next:"@pop"}]],interpolatedstring:[[/[^\\"{]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/{{/,"string.escape"],[/}}/,"string.escape"],[/{/,{token:"string.quote",next:"root.interpolatedstring"}],[/"/,{token:"string.quote",next:"@pop"}]],whitespace:[[/^[ \t\v\f]*#((r)|(load))(?=\s)/,"directive.csx"],[/^[ \t\v\f]*#\w.*$/,"namespace.cpp"],[/[ \t\v\f\r\n]+/,""],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]]}};return g(u);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/csp/csp", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var o=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.prototype.hasOwnProperty;var a=(r,t)=>{for(var s in t)o(r,s,{get:t[s],enumerable:!0})},c=(r,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of u(t))!g.call(r,e)&&e!==s&&o(r,e,{get:()=>t[e],enumerable:!(n=i(t,e))||n.enumerable});return r};var q=r=>c(o({},"__esModule",{value:!0}),r);var p={};a(p,{conf:()=>f,language:()=>l});var f={brackets:[],autoClosingPairs:[],surroundingPairs:[]},l={keywords:[],typeKeywords:[],tokenPostfix:".csp",operators:[],symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[[/child-src/,"string.quote"],[/connect-src/,"string.quote"],[/default-src/,"string.quote"],[/font-src/,"string.quote"],[/frame-src/,"string.quote"],[/img-src/,"string.quote"],[/manifest-src/,"string.quote"],[/media-src/,"string.quote"],[/object-src/,"string.quote"],[/script-src/,"string.quote"],[/style-src/,"string.quote"],[/worker-src/,"string.quote"],[/base-uri/,"string.quote"],[/plugin-types/,"string.quote"],[/sandbox/,"string.quote"],[/disown-opener/,"string.quote"],[/form-action/,"string.quote"],[/frame-ancestors/,"string.quote"],[/report-uri/,"string.quote"],[/report-to/,"string.quote"],[/upgrade-insecure-requests/,"string.quote"],[/block-all-mixed-content/,"string.quote"],[/require-sri-for/,"string.quote"],[/reflected-xss/,"string.quote"],[/referrer/,"string.quote"],[/policy-uri/,"string.quote"],[/'self'/,"string.quote"],[/'unsafe-inline'/,"string.quote"],[/'unsafe-eval'/,"string.quote"],[/'strict-dynamic'/,"string.quote"],[/'unsafe-hashed-attributes'/,"string.quote"]]}};return q(p);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/css/css", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var r=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var m=(t,e)=>{for(var o in e)r(t,o,{get:e[o],enumerable:!0})},c=(t,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of s(e))!l.call(t,n)&&n!==o&&r(t,n,{get:()=>e[n],enumerable:!(i=a(e,n))||i.enumerable});return t};var d=t=>c(r({},"__esModule",{value:!0}),t);var k={};m(k,{conf:()=>u,language:()=>p});var u={wordPattern:/(#?-?\d*\.\d\w*%?)|((::|[@#.!:])?[\w-?]+%?)|::|[@#.!:]/g,comments:{blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}",notIn:["string","comment"]},{open:"[",close:"]",notIn:["string","comment"]},{open:"(",close:")",notIn:["string","comment"]},{open:'"',close:'"',notIn:["string","comment"]},{open:"'",close:"'",notIn:["string","comment"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],folding:{markers:{start:new RegExp("^\\s*\\/\\*\\s*#region\\b\\s*(.*?)\\s*\\*\\/"),end:new RegExp("^\\s*\\/\\*\\s*#endregion\\b.*\\*\\/")}}},p={defaultToken:"",tokenPostfix:".css",ws:`[
|
|
||||||
\r\f]*`,identifier:"-?-?([a-zA-Z]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))([\\w\\-]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))*",brackets:[{open:"{",close:"}",token:"delimiter.bracket"},{open:"[",close:"]",token:"delimiter.bracket"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],tokenizer:{root:[{include:"@selector"}],selector:[{include:"@comments"},{include:"@import"},{include:"@strings"},["[@](keyframes|-webkit-keyframes|-moz-keyframes|-o-keyframes)",{token:"keyword",next:"@keyframedeclaration"}],["[@](page|content|font-face|-moz-document)",{token:"keyword"}],["[@](charset|namespace)",{token:"keyword",next:"@declarationbody"}],["(url-prefix)(\\()",["attribute.value",{token:"delimiter.parenthesis",next:"@urldeclaration"}]],["(url)(\\()",["attribute.value",{token:"delimiter.parenthesis",next:"@urldeclaration"}]],{include:"@selectorname"},["[\\*]","tag"],["[>\\+,]","delimiter"],["\\[",{token:"delimiter.bracket",next:"@selectorattribute"}],["{",{token:"delimiter.bracket",next:"@selectorbody"}]],selectorbody:[{include:"@comments"},["[*_]?@identifier@ws:(?=(\\s|\\d|[^{;}]*[;}]))","attribute.name","@rulevalue"],["}",{token:"delimiter.bracket",next:"@pop"}]],selectorname:[["(\\.|#(?=[^{])|%|(@identifier)|:)+","tag"]],selectorattribute:[{include:"@term"},["]",{token:"delimiter.bracket",next:"@pop"}]],term:[{include:"@comments"},["(url-prefix)(\\()",["attribute.value",{token:"delimiter.parenthesis",next:"@urldeclaration"}]],["(url)(\\()",["attribute.value",{token:"delimiter.parenthesis",next:"@urldeclaration"}]],{include:"@functioninvocation"},{include:"@numbers"},{include:"@name"},{include:"@strings"},["([<>=\\+\\-\\*\\/\\^\\|\\~,])","delimiter"],[",","delimiter"]],rulevalue:[{include:"@comments"},{include:"@strings"},{include:"@term"},["!important","keyword"],[";","delimiter","@pop"],["(?=})",{token:"",next:"@pop"}]],warndebug:[["[@](warn|debug)",{token:"keyword",next:"@declarationbody"}]],import:[["[@](import)",{token:"keyword",next:"@declarationbody"}]],urldeclaration:[{include:"@strings"},[`[^)\r
|
|
||||||
]+`,"string"],["\\)",{token:"delimiter.parenthesis",next:"@pop"}]],parenthizedterm:[{include:"@term"},["\\)",{token:"delimiter.parenthesis",next:"@pop"}]],declarationbody:[{include:"@term"},[";","delimiter","@pop"],["(?=})",{token:"",next:"@pop"}]],comments:[["\\/\\*","comment","@comment"],["\\/\\/+.*","comment"]],comment:[["\\*\\/","comment","@pop"],[/[^*/]+/,"comment"],[/./,"comment"]],name:[["@identifier","attribute.value"]],numbers:[["-?(\\d*\\.)?\\d+([eE][\\-+]?\\d+)?",{token:"attribute.value.number",next:"@units"}],["#[0-9a-fA-F_]+(?!\\w)","attribute.value.hex"]],units:[["(em|ex|ch|rem|fr|vmin|vmax|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?","attribute.value.unit","@pop"]],keyframedeclaration:[["@identifier","attribute.value"],["{",{token:"delimiter.bracket",switchTo:"@keyframebody"}]],keyframebody:[{include:"@term"},["{",{token:"delimiter.bracket",next:"@selectorbody"}],["}",{token:"delimiter.bracket",next:"@pop"}]],functioninvocation:[["@identifier\\(",{token:"attribute.value",next:"@functionarguments"}]],functionarguments:[["\\$@identifier@ws:","attribute.name"],["[,]","delimiter"],{include:"@term"},["\\)",{token:"attribute.value",next:"@pop"}]],strings:[['~?"',{token:"string",next:"@stringenddoublequote"}],["~?'",{token:"string",next:"@stringendquote"}]],stringenddoublequote:[["\\\\.","string"],['"',{token:"string",next:"@pop"}],[/[^\\"]+/,"string"],[".","string"]],stringendquote:[["\\\\.","string"],["'",{token:"string",next:"@pop"}],[/[^\\']+/,"string"],[".","string"]]}};return d(k);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/cypher/cypher", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var s=Object.defineProperty;var r=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var c=(i,e)=>{for(var n in e)s(i,n,{get:e[n],enumerable:!0})},g=(i,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of a(e))!l.call(i,t)&&t!==n&&s(i,t,{get:()=>e[t],enumerable:!(o=r(e,t))||o.enumerable});return i};var p=i=>g(s({},"__esModule",{value:!0}),i);var u={};c(u,{conf:()=>d,language:()=>m});var d={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"`",close:"`"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"`",close:"`"}]},m={defaultToken:"",tokenPostfix:".cypher",ignoreCase:!0,brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.bracket"},{open:"(",close:")",token:"delimiter.parenthesis"}],keywords:["ALL","AND","AS","ASC","ASCENDING","BY","CALL","CASE","CONTAINS","CREATE","DELETE","DESC","DESCENDING","DETACH","DISTINCT","ELSE","END","ENDS","EXISTS","IN","IS","LIMIT","MANDATORY","MATCH","MERGE","NOT","ON","ON","OPTIONAL","OR","ORDER","REMOVE","RETURN","SET","SKIP","STARTS","THEN","UNION","UNWIND","WHEN","WHERE","WITH","XOR","YIELD"],builtinLiterals:["true","TRUE","false","FALSE","null","NULL"],builtinFunctions:["abs","acos","asin","atan","atan2","avg","ceil","coalesce","collect","cos","cot","count","degrees","e","endNode","exists","exp","floor","head","id","keys","labels","last","left","length","log","log10","lTrim","max","min","nodes","percentileCont","percentileDisc","pi","properties","radians","rand","range","relationships","replace","reverse","right","round","rTrim","sign","sin","size","split","sqrt","startNode","stDev","stDevP","substring","sum","tail","tan","timestamp","toBoolean","toFloat","toInteger","toLower","toString","toUpper","trim","type"],operators:["+","-","*","/","%","^","=","<>","<",">","<=",">=","->","<-","-->","<--"],escapes:/\\(?:[tbnrf\\"'`]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,digits:/\d+/,octaldigits:/[0-7]+/,hexdigits:/[0-9a-fA-F]+/,tokenizer:{root:[[/[{}[\]()]/,"@brackets"],{include:"common"}],common:[{include:"@whitespace"},{include:"@numbers"},{include:"@strings"},[/:[a-zA-Z_][\w]*/,"type.identifier"],[/[a-zA-Z_][\w]*(?=\()/,{cases:{"@builtinFunctions":"predefined.function"}}],[/[a-zA-Z_$][\w$]*/,{cases:{"@keywords":"keyword","@builtinLiterals":"predefined.literal","@default":"identifier"}}],[/`/,"identifier.escape","@identifierBacktick"],[/[;,.:|]/,"delimiter"],[/[<>=%+\-*/^]+/,{cases:{"@operators":"delimiter","@default":""}}]],numbers:[[/-?(@digits)[eE](-?(@digits))?/,"number.float"],[/-?(@digits)?\.(@digits)([eE]-?(@digits))?/,"number.float"],[/-?0x(@hexdigits)/,"number.hex"],[/-?0(@octaldigits)/,"number.octal"],[/-?(@digits)/,"number"]],strings:[[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/"/,"string","@stringDouble"],[/'/,"string","@stringSingle"]],whitespace:[[/[ \t\r\n]+/,"white"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/\/\/.*/,"comment"],[/[^/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[/*]/,"comment"]],stringDouble:[[/[^\\"]+/,"string"],[/@escapes/,"string"],[/\\./,"string.invalid"],[/"/,"string","@pop"]],stringSingle:[[/[^\\']+/,"string"],[/@escapes/,"string"],[/\\./,"string.invalid"],[/'/,"string","@pop"]],identifierBacktick:[[/[^\\`]+/,"identifier.escape"],[/@escapes/,"identifier.escape"],[/\\./,"identifier.escape.invalid"],[/`/,"identifier.escape","@pop"]]}};return p(u);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/dart/dart", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var r=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var p=(n,e)=>{for(var t in e)r(n,t,{get:e[t],enumerable:!0})},g=(n,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of c(e))!a.call(n,o)&&o!==t&&r(n,o,{get:()=>e[o],enumerable:!(s=i(e,o))||s.enumerable});return n};var l=n=>g(r({},"__esModule",{value:!0}),n);var x={};p(x,{conf:()=>d,language:()=>m});var d={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"'",close:"'",notIn:["string","comment"]},{open:'"',close:'"',notIn:["string"]},{open:"`",close:"`",notIn:["string","comment"]},{open:"/**",close:" */",notIn:["string"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"<",close:">"},{open:"'",close:"'"},{open:"(",close:")"},{open:'"',close:'"'},{open:"`",close:"`"}],folding:{markers:{start:/^\s*\s*#?region\b/,end:/^\s*\s*#?endregion\b/}}},m={defaultToken:"invalid",tokenPostfix:".dart",keywords:["abstract","dynamic","implements","show","as","else","import","static","assert","enum","in","super","async","export","interface","switch","await","extends","is","sync","break","external","library","this","case","factory","mixin","throw","catch","false","new","true","class","final","null","try","const","finally","on","typedef","continue","for","operator","var","covariant","Function","part","void","default","get","rethrow","while","deferred","hide","return","with","do","if","set","yield"],typeKeywords:["int","double","String","bool"],operators:["+","-","*","/","~/","%","++","--","==","!=",">","<",">=","<=","=","-=","/=","%=",">>=","^=","+=","*=","~/=","<<=","&=","!=","||","&&","&","|","^","~","<<",">>","!",">>>","??","?",":","|="],symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,digits:/\d+(_+\d+)*/,octaldigits:/[0-7]+(_+[0-7]+)*/,binarydigits:/[0-1]+(_+[0-1]+)*/,hexdigits:/[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,regexpctl:/[(){}\[\]\$\^|\-*+?\.]/,regexpesc:/\\(?:[bBdDfnrstvwWn0\\\/]|@regexpctl|c[A-Z]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})/,tokenizer:{root:[[/[{}]/,"delimiter.bracket"],{include:"common"}],common:[[/[a-z_$][\w$]*/,{cases:{"@typeKeywords":"type.identifier","@keywords":"keyword","@default":"identifier"}}],[/[A-Z_$][\w\$]*/,"type.identifier"],{include:"@whitespace"},[/\/(?=([^\\\/]|\\.)+\/([gimsuy]*)(\s*)(\.|;|,|\)|\]|\}|$))/,{token:"regexp",bracket:"@open",next:"@regexp"}],[/@[a-zA-Z]+/,"annotation"],[/[()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/!(?=([^=]|$))/,"delimiter"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/(@digits)[eE]([\-+]?(@digits))?/,"number.float"],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?/,"number.float"],[/0[xX](@hexdigits)n?/,"number.hex"],[/0[oO]?(@octaldigits)n?/,"number.octal"],[/0[bB](@binarydigits)n?/,"number.binary"],[/(@digits)n?/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string_double"],[/'/,"string","@string_single"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@jsdoc"],[/\/\*/,"comment","@comment"],[/\/\/\/.*$/,"comment.doc"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],jsdoc:[[/[^\/*]+/,"comment.doc"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],regexp:[[/(\{)(\d+(?:,\d*)?)(\})/,["regexp.escape.control","regexp.escape.control","regexp.escape.control"]],[/(\[)(\^?)(?=(?:[^\]\\\/]|\\.)+)/,["regexp.escape.control",{token:"regexp.escape.control",next:"@regexrange"}]],[/(\()(\?:|\?=|\?!)/,["regexp.escape.control","regexp.escape.control"]],[/[()]/,"regexp.escape.control"],[/@regexpctl/,"regexp.escape.control"],[/[^\\\/]/,"regexp"],[/@regexpesc/,"regexp.escape"],[/\\\./,"regexp.invalid"],[/(\/)([gimsuy]*)/,[{token:"regexp",bracket:"@close",next:"@pop"},"keyword.other"]]],regexrange:[[/-/,"regexp.escape.control"],[/\^/,"regexp.invalid"],[/@regexpesc/,"regexp.escape"],[/[^\]]/,"regexp"],[/\]/,{token:"regexp.escape.control",next:"@pop",bracket:"@close"}]],string_double:[[/[^\\"\$]+/,"string"],[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"],[/\$\w+/,"identifier"]],string_single:[[/[^\\'\$]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/'/,"string","@pop"],[/\$\w+/,"identifier"]]}};return l(x);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/dockerfile/dockerfile", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var a=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var r=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var p=(o,e)=>{for(var s in e)a(o,s,{get:e[s],enumerable:!0})},g=(o,e,s,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of r(e))!i.call(o,n)&&n!==s&&a(o,n,{get:()=>e[n],enumerable:!(t=l(e,n))||t.enumerable});return o};var c=o=>g(a({},"__esModule",{value:!0}),o);var k={};p(k,{conf:()=>u,language:()=>d});var u={brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}]},d={defaultToken:"",tokenPostfix:".dockerfile",variable:/\${?[\w]+}?/,tokenizer:{root:[{include:"@whitespace"},{include:"@comment"},[/(ONBUILD)(\s+)/,["keyword",""]],[/(ENV)(\s+)([\w]+)/,["keyword","",{token:"variable",next:"@arguments"}]],[/(FROM|MAINTAINER|RUN|EXPOSE|ENV|ADD|ARG|VOLUME|LABEL|USER|WORKDIR|COPY|CMD|STOPSIGNAL|SHELL|HEALTHCHECK|ENTRYPOINT)/,{token:"keyword",next:"@arguments"}]],arguments:[{include:"@whitespace"},{include:"@strings"},[/(@variable)/,{cases:{"@eos":{token:"variable",next:"@popall"},"@default":"variable"}}],[/\\/,{cases:{"@eos":"","@default":""}}],[/./,{cases:{"@eos":{token:"",next:"@popall"},"@default":""}}]],whitespace:[[/\s+/,{cases:{"@eos":{token:"",next:"@popall"},"@default":""}}]],comment:[[/(^#.*$)/,"comment","@popall"]],strings:[[/\\'$/,"","@popall"],[/\\'/,""],[/'$/,"string","@popall"],[/'/,"string","@stringBody"],[/"$/,"string","@popall"],[/"/,"string","@dblStringBody"]],stringBody:[[/[^\\\$']/,{cases:{"@eos":{token:"string",next:"@popall"},"@default":"string"}}],[/\\./,"string.escape"],[/'$/,"string","@popall"],[/'/,"string","@pop"],[/(@variable)/,"variable"],[/\\$/,"string"],[/$/,"string","@popall"]],dblStringBody:[[/[^\\\$"]/,{cases:{"@eos":{token:"string",next:"@popall"},"@default":"string"}}],[/\\./,"string.escape"],[/"$/,"string","@popall"],[/"/,"string","@pop"],[/(@variable)/,"variable"],[/\\$/,"string"],[/$/,"string","@popall"]]}};return c(k);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/flow9/flow9", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var s=Object.defineProperty;var r=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var c=(o,e)=>{for(var t in e)s(o,t,{get:e[t],enumerable:!0})},m=(o,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of a(e))!l.call(o,n)&&n!==t&&s(o,n,{get:()=>e[n],enumerable:!(i=r(e,n))||i.enumerable});return o};var p=o=>m(s({},"__esModule",{value:!0}),o);var u={};c(u,{conf:()=>g,language:()=>f});var g={comments:{blockComment:["/*","*/"],lineComment:"//"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}",notIn:["string"]},{open:"[",close:"]",notIn:["string"]},{open:"(",close:")",notIn:["string"]},{open:'"',close:'"',notIn:["string"]},{open:"'",close:"'",notIn:["string"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"<",close:">"}]},f={defaultToken:"",tokenPostfix:".flow",keywords:["import","require","export","forbid","native","if","else","cast","unsafe","switch","default"],types:["io","mutable","bool","int","double","string","flow","void","ref","true","false","with"],operators:["=",">","<","<=",">=","==","!","!=",":=","::=","&&","||","+","-","*","/","@","&","%",":","->","\\","$","??","^"],symbols:/[@$=><!~?:&|+\-*\\\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[[/[a-zA-Z_]\w*/,{cases:{"@keywords":"keyword","@types":"type","@default":"identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"delimiter"],[/[<>](?!@symbols)/,"delimiter"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]]}};return p(u);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/fsharp/fsharp", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var s=Object.defineProperty;var r=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var c=(n,e)=>{for(var o in e)s(n,o,{get:e[o],enumerable:!0})},g=(n,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of a(e))!l.call(n,t)&&t!==o&&s(n,t,{get:()=>e[t],enumerable:!(i=r(e,t))||i.enumerable});return n};var f=n=>g(s({},"__esModule",{value:!0}),n);var d={};c(d,{conf:()=>m,language:()=>u});var m={comments:{lineComment:"//",blockComment:["(*","*)"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],folding:{markers:{start:new RegExp("^\\s*//\\s*#region\\b|^\\s*\\(\\*\\s*#region(.*)\\*\\)"),end:new RegExp("^\\s*//\\s*#endregion\\b|^\\s*\\(\\*\\s*#endregion\\s*\\*\\)")}}},u={defaultToken:"",tokenPostfix:".fs",keywords:["abstract","and","atomic","as","assert","asr","base","begin","break","checked","component","const","constraint","constructor","continue","class","default","delegate","do","done","downcast","downto","elif","else","end","exception","eager","event","external","extern","false","finally","for","fun","function","fixed","functor","global","if","in","include","inherit","inline","interface","internal","land","lor","lsl","lsr","lxor","lazy","let","match","member","mod","module","mutable","namespace","method","mixin","new","not","null","of","open","or","object","override","private","parallel","process","protected","pure","public","rec","return","static","sealed","struct","sig","then","to","true","tailcall","trait","try","type","upcast","use","val","void","virtual","volatile","when","while","with","yield"],symbols:/[=><!~?:&|+\-*\^%;\.,\/]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,integersuffix:/[uU]?[yslnLI]?/,floatsuffix:/[fFmM]?/,tokenizer:{root:[[/[a-zA-Z_]\w*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],{include:"@whitespace"},[/\[<.*>\]/,"annotation"],[/^#(if|else|endif)/,"keyword"],[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,"delimiter"],[/\d*\d+[eE]([\-+]?\d+)?(@floatsuffix)/,"number.float"],[/\d*\.\d+([eE][\-+]?\d+)?(@floatsuffix)/,"number.float"],[/0x[0-9a-fA-F]+LF/,"number.float"],[/0x[0-9a-fA-F]+(@integersuffix)/,"number.hex"],[/0b[0-1]+(@integersuffix)/,"number.bin"],[/\d+(@integersuffix)/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"""/,"string",'@string."""'],[/"/,"string",'@string."'],[/\@"/,{token:"string.quote",next:"@litstring"}],[/'[^\\']'B?/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\(\*(?!\))/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^*(]+/,"comment"],[/\*\)/,"comment","@pop"],[/\*/,"comment"],[/\(\*\)/,"comment"],[/\(/,"comment"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/("""|"B?)/,{cases:{"$#==$S2":{token:"string",next:"@pop"},"@default":"string"}}]],litstring:[[/[^"]+/,"string"],[/""/,"string.escape"],[/"/,{token:"string.quote",next:"@pop"}]]}};return f(d);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/go/go", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var s=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var m=(n,e)=>{for(var t in e)s(n,t,{get:e[t],enumerable:!0})},l=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of a(e))!c.call(n,o)&&o!==t&&s(n,o,{get:()=>e[o],enumerable:!(r=i(e,o))||r.enumerable});return n};var g=n=>l(s({},"__esModule",{value:!0}),n);var d={};m(d,{conf:()=>p,language:()=>u});var p={comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"`",close:"`",notIn:["string"]},{open:'"',close:'"',notIn:["string"]},{open:"'",close:"'",notIn:["string","comment"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:"`",close:"`"},{open:'"',close:'"'},{open:"'",close:"'"}]},u={defaultToken:"",tokenPostfix:".go",keywords:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var","bool","true","false","uint8","uint16","uint32","uint64","int8","int16","int32","int64","float32","float64","complex64","complex128","byte","rune","uint","int","uintptr","string","nil"],operators:["+","-","*","/","%","&","|","^","<<",">>","&^","+=","-=","*=","/=","%=","&=","|=","^=","<<=",">>=","&^=","&&","||","<-","++","--","==","<",">","=","!","!=","<=",">=",":=","...","(",")","","]","{","}",",",";",".",":"],symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[[/[a-zA-Z_]\w*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],{include:"@whitespace"},[/\[\[.*\]\]/,"annotation"],[/^\s*#\w+/,"keyword"],[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/\d*\d+[eE]([\-+]?\d+)?/,"number.float"],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F']*[0-9a-fA-F]/,"number.hex"],[/0[0-7']*[0-7]/,"number.octal"],[/0[bB][0-1']*[0-1]/,"number.binary"],[/\d[\d']*/,"number"],[/\d/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"],[/`/,"string","@rawstring"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@doccomment"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],doccomment:[[/[^\/*]+/,"comment.doc"],[/\/\*/,"comment.doc.invalid"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]],rawstring:[[/[^\`]/,"string"],[/`/,"string","@pop"]]}};return g(d);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/graphql/graphql", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var s=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var c=(n,e)=>{for(var t in e)s(n,t,{get:e[t],enumerable:!0})},d=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of i(e))!l.call(n,o)&&o!==t&&s(n,o,{get:()=>e[o],enumerable:!(r=a(e,o))||r.enumerable});return n};var p=n=>d(s({},"__esModule",{value:!0}),n);var u={};c(u,{conf:()=>g,language:()=>I});var g={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"""',close:'"""',notIn:["string","comment"]},{open:'"',close:'"',notIn:["string","comment"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"""',close:'"""'},{open:'"',close:'"'}],folding:{offSide:!0}},I={defaultToken:"invalid",tokenPostfix:".gql",keywords:["null","true","false","query","mutation","subscription","extend","schema","directive","scalar","type","interface","union","enum","input","implements","fragment","on"],typeKeywords:["Int","Float","String","Boolean","ID"],directiveLocations:["SCHEMA","SCALAR","OBJECT","FIELD_DEFINITION","ARGUMENT_DEFINITION","INTERFACE","UNION","ENUM","ENUM_VALUE","INPUT_OBJECT","INPUT_FIELD_DEFINITION","QUERY","MUTATION","SUBSCRIPTION","FIELD","FRAGMENT_DEFINITION","FRAGMENT_SPREAD","INLINE_FRAGMENT","VARIABLE_DEFINITION"],operators:["=","!","?",":","&","|"],symbols:/[=!?:&|]+/,escapes:/\\(?:["\\\/bfnrt]|u[0-9A-Fa-f]{4})/,tokenizer:{root:[[/[a-z_][\w$]*/,{cases:{"@keywords":"keyword","@default":"key.identifier"}}],[/[$][\w$]*/,{cases:{"@keywords":"keyword","@default":"argument.identifier"}}],[/[A-Z][\w\$]*/,{cases:{"@typeKeywords":"keyword","@default":"type.identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"@brackets"],[/@symbols/,{cases:{"@operators":"operator","@default":""}}],[/@\s*[a-zA-Z_\$][\w\$]*/,{token:"annotation",log:"annotation token: $0"}],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F]+/,"number.hex"],[/\d+/,"number"],[/[;,.]/,"delimiter"],[/"""/,{token:"string",next:"@mlstring",nextEmbedded:"markdown"}],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,{token:"string.quote",bracket:"@open",next:"@string"}]],mlstring:[[/[^"]+/,"string"],['"""',{token:"string",next:"@pop",nextEmbedded:"@pop"}]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,{token:"string.quote",bracket:"@close",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,""],[/#.*$/,"comment"]]}};return p(u);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/hcl/hcl", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var r=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var l=(t,e)=>{for(var o in e)r(t,o,{get:e[o],enumerable:!0})},d=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of i(e))!c.call(t,s)&&s!==o&&r(t,s,{get:()=>e[s],enumerable:!(n=a(e,s))||n.enumerable});return t};var m=t=>d(r({},"__esModule",{value:!0}),t);var f={};l(f,{conf:()=>p,language:()=>g});var p={comments:{lineComment:"#",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"',notIn:["string"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}]},g={defaultToken:"",tokenPostfix:".hcl",keywords:["var","local","path","for_each","any","string","number","bool","true","false","null","if ","else ","endif ","for ","in","endfor"],operators:["=",">=","<=","==","!=","+","-","*","/","%","&&","||","!","<",">","?","...",":"],symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,terraformFunctions:/(abs|ceil|floor|log|max|min|pow|signum|chomp|format|formatlist|indent|join|lower|regex|regexall|replace|split|strrev|substr|title|trimspace|upper|chunklist|coalesce|coalescelist|compact|concat|contains|distinct|element|flatten|index|keys|length|list|lookup|map|matchkeys|merge|range|reverse|setintersection|setproduct|setunion|slice|sort|transpose|values|zipmap|base64decode|base64encode|base64gzip|csvdecode|jsondecode|jsonencode|urlencode|yamldecode|yamlencode|abspath|dirname|pathexpand|basename|file|fileexists|fileset|filebase64|templatefile|formatdate|timeadd|timestamp|base64sha256|base64sha512|bcrypt|filebase64sha256|filebase64sha512|filemd5|filemd1|filesha256|filesha512|md5|rsadecrypt|sha1|sha256|sha512|uuid|uuidv5|cidrhost|cidrnetmask|cidrsubnet|tobool|tolist|tomap|tonumber|toset|tostring)/,terraformMainBlocks:/(module|data|terraform|resource|provider|variable|output|locals)/,tokenizer:{root:[[/^@terraformMainBlocks([ \t]*)([\w-]+|"[\w-]+"|)([ \t]*)([\w-]+|"[\w-]+"|)([ \t]*)(\{)/,["type","","string","","string","","@brackets"]],[/(\w+[ \t]+)([ \t]*)([\w-]+|"[\w-]+"|)([ \t]*)([\w-]+|"[\w-]+"|)([ \t]*)(\{)/,["identifier","","string","","string","","@brackets"]],[/(\w+[ \t]+)([ \t]*)([\w-]+|"[\w-]+"|)([ \t]*)([\w-]+|"[\w-]+"|)(=)(\{)/,["identifier","","string","","operator","","@brackets"]],{include:"@terraform"}],terraform:[[/@terraformFunctions(\()/,["type","@brackets"]],[/[a-zA-Z_]\w*-*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"variable"}}],{include:"@whitespace"},{include:"@heredoc"},[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"operator","@default":""}}],[/\d*\d+[eE]([\-+]?\d+)?/,"number.float"],[/\d*\.\d+([eE][\-+]?\d+)?/,"number.float"],[/\d[\d']*/,"number"],[/\d/,"number"],[/[;,.]/,"delimiter"],[/"/,"string","@string"],[/'/,"invalid"]],heredoc:[[/<<[-]*\s*["]?([\w\-]+)["]?/,{token:"string.heredoc.delimiter",next:"@heredocBody.$1"}]],heredocBody:[[/([\w\-]+)$/,{cases:{"$1==$S2":[{token:"string.heredoc.delimiter",next:"@popall"}],"@default":"string.heredoc"}}],[/./,"string.heredoc"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"],[/#.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],string:[[/\$\{/,{token:"delimiter",next:"@stringExpression"}],[/[^\\"\$]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@popall"]],stringInsideExpression:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]],stringExpression:[[/\}/,{token:"delimiter",next:"@pop"}],[/"/,"string","@stringInsideExpression"],{include:"@terraform"}]}};return m(f);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/ini/ini", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var t=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var r=Object.getOwnPropertyNames;var g=Object.prototype.hasOwnProperty;var c=(n,e)=>{for(var s in e)t(n,s,{get:e[s],enumerable:!0})},l=(n,e,s,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of r(e))!g.call(n,o)&&o!==s&&t(n,o,{get:()=>e[o],enumerable:!(a=i(e,o))||a.enumerable});return n};var p=n=>l(t({},"__esModule",{value:!0}),n);var f={};c(f,{conf:()=>u,language:()=>m});var u={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}]},m={defaultToken:"",tokenPostfix:".ini",escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[[/^\[[^\]]*\]/,"metatag"],[/(^\w+)(\s*)(\=)/,["key","","delimiter"]],{include:"@whitespace"},[/\d+/,"number"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/"/,"string",'@string."'],[/'/,"string","@string.'"]],whitespace:[[/[ \t\r\n]+/,""],[/^\s*[#;].*$/,"comment"]],string:[[/[^\\"']+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/["']/,{cases:{"$#==$S2":{token:"string",next:"@pop"},"@default":"string"}}]]}};return p(f);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/java/java", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var s=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var r=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var l=(t,e)=>{for(var o in e)s(t,o,{get:e[o],enumerable:!0})},d=(t,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of r(e))!c.call(t,n)&&n!==o&&s(t,n,{get:()=>e[n],enumerable:!(i=a(e,n))||i.enumerable});return t};var g=t=>d(s({},"__esModule",{value:!0}),t);var f={};l(f,{conf:()=>m,language:()=>p});var m={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"<",close:">"}],folding:{markers:{start:new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:<editor-fold\\b))"),end:new RegExp("^\\s*//\\s*(?:(?:#?endregion\\b)|(?:</editor-fold>))")}}},p={defaultToken:"",tokenPostfix:".java",keywords:["abstract","continue","for","new","switch","assert","default","goto","package","synchronized","boolean","do","if","private","this","break","double","implements","protected","throw","byte","else","import","public","throws","case","enum","instanceof","return","transient","catch","extends","int","short","try","char","final","interface","static","void","class","finally","long","strictfp","volatile","const","float","native","super","while","true","false","yield","record","sealed","non-sealed","permits"],operators:["=",">","<","!","~","?",":","==","<=",">=","!=","&&","||","++","--","+","-","*","/","&","|","^","%","<<",">>",">>>","+=","-=","*=","/=","&=","|=","^=","%=","<<=",">>=",">>>="],symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,digits:/\d+(_+\d+)*/,octaldigits:/[0-7]+(_+[0-7]+)*/,binarydigits:/[0-1]+(_+[0-1]+)*/,hexdigits:/[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,tokenizer:{root:[["non-sealed","keyword.non-sealed"],[/[a-zA-Z_$][\w$]*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/@\s*[a-zA-Z_\$][\w\$]*/,"annotation"],[/(@digits)[eE]([\-+]?(@digits))?[fFdD]?/,"number.float"],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?[fFdD]?/,"number.float"],[/0[xX](@hexdigits)[Ll]?/,"number.hex"],[/0(@octaldigits)[Ll]?/,"number.octal"],[/0[bB](@binarydigits)[Ll]?/,"number.binary"],[/(@digits)[fFdD]/,"number.float"],[/(@digits)[lL]?/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"""/,"string","@multistring"],[/"/,"string","@string"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@javadoc"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],javadoc:[[/[^\/*]+/,"comment.doc"],[/\/\*/,"comment.doc.invalid"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]],multistring:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"""/,"string","@pop"],[/./,"string"]]}};return g(f);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/kotlin/kotlin", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var o=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var r=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var l=(n,e)=>{for(var i in e)o(n,i,{get:e[i],enumerable:!0})},d=(n,e,i,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of r(e))!c.call(n,t)&&t!==i&&o(n,t,{get:()=>e[t],enumerable:!(s=a(e,t))||s.enumerable});return n};var g=n=>d(o({},"__esModule",{value:!0}),n);var f={};l(f,{conf:()=>m,language:()=>p});var m={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:"//",blockComment:["/*","*/"]},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"<",close:">"}],folding:{markers:{start:new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:<editor-fold\\b))"),end:new RegExp("^\\s*//\\s*(?:(?:#?endregion\\b)|(?:</editor-fold>))")}}},p={defaultToken:"",tokenPostfix:".kt",keywords:["as","as?","break","class","continue","do","else","false","for","fun","if","in","!in","interface","is","!is","null","object","package","return","super","this","throw","true","try","typealias","val","var","when","while","by","catch","constructor","delegate","dynamic","field","file","finally","get","import","init","param","property","receiver","set","setparam","where","actual","abstract","annotation","companion","const","crossinline","data","enum","expect","external","final","infix","inline","inner","internal","lateinit","noinline","open","operator","out","override","private","protected","public","reified","sealed","suspend","tailrec","vararg","field","it"],operators:["+","-","*","/","%","=","+=","-=","*=","/=","%=","++","--","&&","||","!","==","!=","===","!==",">","<","<=",">=","[","]","!!","?.","?:","::","..",":","?","->","@",";","$","_"],symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,digits:/\d+(_+\d+)*/,octaldigits:/[0-7]+(_+[0-7]+)*/,binarydigits:/[0-1]+(_+[0-1]+)*/,hexdigits:/[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,tokenizer:{root:[[/[A-Z][\w\$]*/,"type.identifier"],[/[a-zA-Z_$][\w$]*/,{cases:{"@keywords":{token:"keyword.$0"},"@default":"identifier"}}],{include:"@whitespace"},[/[{}()\[\]]/,"@brackets"],[/[<>](?!@symbols)/,"@brackets"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/@\s*[a-zA-Z_\$][\w\$]*/,"annotation"],[/(@digits)[eE]([\-+]?(@digits))?[fFdD]?/,"number.float"],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?[fFdD]?/,"number.float"],[/0[xX](@hexdigits)[Ll]?/,"number.hex"],[/0(@octaldigits)[Ll]?/,"number.octal"],[/0[bB](@binarydigits)[Ll]?/,"number.binary"],[/(@digits)[fFdD]/,"number.float"],[/(@digits)[lL]?/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"""/,"string","@multistring"],[/"/,"string","@string"],[/'[^\\']'/,"string"],[/(')(@escapes)(')/,["string","string.escape","string"]],[/'/,"string.invalid"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*\*(?!\/)/,"comment.doc","@javadoc"],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\/\*/,"comment","@comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],javadoc:[[/[^\/*]+/,"comment.doc"],[/\/\*/,"comment.doc","@push"],[/\/\*/,"comment.doc.invalid"],[/\*\//,"comment.doc","@pop"],[/[\/*]/,"comment.doc"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]],multistring:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"""/,"string","@pop"],[/./,"string"]]}};return g(f);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
"use strict";/*!-----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Version: 0.45.0(5e5af013f8d295555a7210df0d5f2cea0bf5dd56)
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
|
|
||||||
*-----------------------------------------------------------------------------*/
|
|
||||||
define("vs/basic-languages/less/less", ["require","require"],(require)=>{
|
|
||||||
var moduleExports=(()=>{var r=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var d=(t,e)=>{for(var i in e)r(t,i,{get:e[i],enumerable:!0})},u=(t,e,i,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of a(e))!l.call(t,n)&&n!==i&&r(t,n,{get:()=>e[n],enumerable:!(o=s(e,n))||o.enumerable});return t};var c=t=>u(r({},"__esModule",{value:!0}),t);var p={};d(p,{conf:()=>m,language:()=>g});var m={wordPattern:/(#?-?\d*\.\d\w*%?)|([@#!.:]?[\w-?]+%?)|[@#!.]/g,comments:{blockComment:["/*","*/"],lineComment:"//"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}",notIn:["string","comment"]},{open:"[",close:"]",notIn:["string","comment"]},{open:"(",close:")",notIn:["string","comment"]},{open:'"',close:'"',notIn:["string","comment"]},{open:"'",close:"'",notIn:["string","comment"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],folding:{markers:{start:new RegExp("^\\s*\\/\\*\\s*#region\\b\\s*(.*?)\\s*\\*\\/"),end:new RegExp("^\\s*\\/\\*\\s*#endregion\\b.*\\*\\/")}}},g={defaultToken:"",tokenPostfix:".less",identifier:"-?-?([a-zA-Z]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))([\\w\\-]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))*",identifierPlus:"-?-?([a-zA-Z:.]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))([\\w\\-:.]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))*",brackets:[{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.bracket"},{open:"(",close:")",token:"delimiter.parenthesis"},{open:"<",close:">",token:"delimiter.angle"}],tokenizer:{root:[{include:"@nestedJSBegin"},["[ \\t\\r\\n]+",""],{include:"@comments"},{include:"@keyword"},{include:"@strings"},{include:"@numbers"},["[*_]?[a-zA-Z\\-\\s]+(?=:.*(;|(\\\\$)))","attribute.name","@attribute"],["url(\\-prefix)?\\(",{token:"tag",next:"@urldeclaration"}],["[{}()\\[\\]]","@brackets"],["[,:;]","delimiter"],["#@identifierPlus","tag.id"],["&","tag"],["\\.@identifierPlus(?=\\()","tag.class","@attribute"],["\\.@identifierPlus","tag.class"],["@identifierPlus","tag"],{include:"@operators"},["@(@identifier(?=[:,\\)]))","variable","@attribute"],["@(@identifier)","variable"],["@","key","@atRules"]],nestedJSBegin:[["``","delimiter.backtick"],["`",{token:"delimiter.backtick",next:"@nestedJSEnd",nextEmbedded:"text/javascript"}]],nestedJSEnd:[["`",{token:"delimiter.backtick",next:"@pop",nextEmbedded:"@pop"}]],operators:[["[<>=\\+\\-\\*\\/\\^\\|\\~]","operator"]],keyword:[["(@[\\s]*import|![\\s]*important|true|false|when|iscolor|isnumber|isstring|iskeyword|isurl|ispixel|ispercentage|isem|hue|saturation|lightness|alpha|lighten|darken|saturate|desaturate|fadein|fadeout|fade|spin|mix|round|ceil|floor|percentage)\\b","keyword"]],urldeclaration:[{include:"@strings"},[`[^)\r
|
|
||||||
]+`,"string"],["\\)",{token:"tag",next:"@pop"}]],attribute:[{include:"@nestedJSBegin"},{include:"@comments"},{include:"@strings"},{include:"@numbers"},{include:"@keyword"},["[a-zA-Z\\-]+(?=\\()","attribute.value","@attribute"],[">","operator","@pop"],["@identifier","attribute.value"],{include:"@operators"},["@(@identifier)","variable"],["[)\\}]","@brackets","@pop"],["[{}()\\[\\]>]","@brackets"],["[;]","delimiter","@pop"],["[,=:]","delimiter"],["\\s",""],[".","attribute.value"]],comments:[["\\/\\*","comment","@comment"],["\\/\\/+.*","comment"]],comment:[["\\*\\/","comment","@pop"],[".","comment"]],numbers:[["(\\d*\\.)?\\d+([eE][\\-+]?\\d+)?",{token:"attribute.value.number",next:"@units"}],["#[0-9a-fA-F_]+(?!\\w)","attribute.value.hex"]],units:[["(em|ex|ch|rem|fr|vmin|vmax|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?","attribute.value.unit","@pop"]],strings:[['~?"',{token:"string.delimiter",next:"@stringsEndDoubleQuote"}],["~?'",{token:"string.delimiter",next:"@stringsEndQuote"}]],stringsEndDoubleQuote:[['\\\\"',"string"],['"',{token:"string.delimiter",next:"@popall"}],[".","string"]],stringsEndQuote:[["\\\\'","string"],["'",{token:"string.delimiter",next:"@popall"}],[".","string"]],atRules:[{include:"@comments"},{include:"@strings"},["[()]","delimiter"],["[\\{;]","delimiter","@pop"],[".","key"]]}};return c(p);})();
|
|
||||||
return moduleExports;
|
|
||||||
});
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue