diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index 46c5e03c..6733fd20 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -1,45 +1,45 @@
-{
- "permissions": {
- "allow": [
- "Bash(xargs grep:*)",
- "Bash(dotnet build:*)",
- "Bash(dotnet run:*)",
- "Bash(dotnet format:*)",
- "Bash(dotnet new:*)",
- "Bash(dotnet tool:*)",
- "Bash(dotnet csharpier:*)",
- "Bash(dotnet fsi:*)",
- "Bash(grep -r MaterialIconKind. /home/erickazevedo/Downloads/files/src/lude=*.cs)",
- "Bash(python3 -c \":*)",
- "Bash(grep -n \"InvalidateWires\\\\|Dispatcher\" /home/erickazevedo/Downloads/files/src/ndow.axaml.cs /home/erickazevedo/Downloads/files/src/DBWeaver.U
- "WebFetch(domain:docs.avaloniaui.net)",
- "Bash(git fsck:*)",
- "Bash(find .git/objects -type f -empty -delete)",
- "Bash(git update-ref:*)",
- "Bash(git fetch:*)",
- "Bash(git add:*)",
- "Bash(python3:*)",
- "Bash(git commit:*)",
- "Bash(dotnet test:*)",
- "Bash(xargs wc:*)",
- "Bash(find /c/Users/azeve/Documents/VisualSqlArchtect/tests -type f -name *.cs)",
- "Bash(grep -rn \"\\\\b[0-9]{3,}\\\\b\" /c/Users/azeve/Documents/VisualSqlArchtect/src --include=\"*.cs\")",
- "Bash(grep -v \"///\")",
- "Bash(rm \"c:/Users/azeve/Documents/VisualSqlArchtect/src/ls/BezierWireLayer.cs\")",
- "Bash(rm \"c:/Users/azeve/Documents/VisualSqlArchtect/src/ls/PinDragInteraction.cs\")",
- "Bash(grep -v \"private\\\\|//\")",
- "Bash(grep -v \"//\")",
- "Bash(find \"c:\\\\Users\\\\azeve\\\\Documents\\\\VisualSqlArchtect/src/ls/InfiniteCanvas\" -name \"*.cs\" -exec wc -l {} \\\\;)",
- "Bash(wc -l /home/erickazevedo/Documentos/VisualSqlArchtect/src//*.cs)",
- "Bash(grep -E \"\\\\.cs$\")",
- "Bash(grep -n \"class NodeDefinitionRegistry\\\\|static class NodeDefinitionRegistry\" /home/erickazevedo/Documentos/VisualSqlArchtect/src/s)",
- "Read(//tmp/**)",
- "Bash(sqlite3 --version)",
- "Bash(/home/erickazevedo/.claude/plugins/cache/claude-plugins-official/superpowers/5.0.7/skills/brainstorming/scripts/start-server.sh --project-dir /home/erickazevedo/Documentos/VisualSqlArchtect)",
- "Bash(git worktree:*)",
- "Bash(git -C /home/erickazevedo/Documentos/VisualSqlArchtect/.worktrees/ui-design-system-overhaul commit -m ':*)",
- "Bash(git stash:*)",
- "Bash(grep -v \"^$\")"
- ]
- }
-}
+{
+ "permissions": {
+ "allow": [
+ "Bash(xargs grep:*)",
+ "Bash(dotnet build:*)",
+ "Bash(dotnet run:*)",
+ "Bash(dotnet format:*)",
+ "Bash(dotnet new:*)",
+ "Bash(dotnet tool:*)",
+ "Bash(dotnet csharpier:*)",
+ "Bash(dotnet fsi:*)",
+ "Bash(grep -r MaterialIconKind. /home/erickazevedo/Downloads/files/src/lude=*.cs)",
+ "Bash(python3 -c \":*)",
+ "Bash(grep -n \"InvalidateWires\\\\|Dispatcher\" /home/erickazevedo/Downloads/files/src/ndow.axaml.cs /home/erickazevedo/Downloads/files/src/AkkornStudio.U
+ "WebFetch(domain:docs.avaloniaui.net)",
+ "Bash(git fsck:*)",
+ "Bash(find .git/objects -type f -empty -delete)",
+ "Bash(git update-ref:*)",
+ "Bash(git fetch:*)",
+ "Bash(git add:*)",
+ "Bash(python3:*)",
+ "Bash(git commit:*)",
+ "Bash(dotnet test:*)",
+ "Bash(xargs wc:*)",
+ "Bash(find /c/Users/azeve/Documents/VisualSqlArchtect/tests -type f -name *.cs)",
+ "Bash(grep -rn \"\\\\b[0-9]{3,}\\\\b\" /c/Users/azeve/Documents/VisualSqlArchtect/src --include=\"*.cs\")",
+ "Bash(grep -v \"///\")",
+ "Bash(rm \"c:/Users/azeve/Documents/VisualSqlArchtect/src/ls/BezierWireLayer.cs\")",
+ "Bash(rm \"c:/Users/azeve/Documents/VisualSqlArchtect/src/ls/PinDragInteraction.cs\")",
+ "Bash(grep -v \"private\\\\|//\")",
+ "Bash(grep -v \"//\")",
+ "Bash(find \"c:\\\\Users\\\\azeve\\\\Documents\\\\VisualSqlArchtect/src/ls/InfiniteCanvas\" -name \"*.cs\" -exec wc -l {} \\\\;)",
+ "Bash(wc -l /home/erickazevedo/Documentos/VisualSqlArchtect/src//*.cs)",
+ "Bash(grep -E \"\\\\.cs$\")",
+ "Bash(grep -n \"class NodeDefinitionRegistry\\\\|static class NodeDefinitionRegistry\" /home/erickazevedo/Documentos/VisualSqlArchtect/src/s)",
+ "Read(//tmp/**)",
+ "Bash(sqlite3 --version)",
+ "Bash(/home/erickazevedo/.claude/plugins/cache/claude-plugins-official/superpowers/5.0.7/skills/brainstorming/scripts/start-server.sh --project-dir /home/erickazevedo/Documentos/VisualSqlArchtect)",
+ "Bash(git worktree:*)",
+ "Bash(git -C /home/erickazevedo/Documentos/VisualSqlArchtect/.worktrees/ui-design-system-overhaul commit -m ':*)",
+ "Bash(git stash:*)",
+ "Bash(grep -v \"^$\")"
+ ]
+ }
+}
diff --git a/.gitignore b/.gitignore
index 1ec7cd89..a01e7159 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,8 @@ claude/settings.local.json
archive/*
.codex
*.log
-.superpowers/*
-.worktrees/
-dbweaver_app/*
-*.md
+.superpowers/*
+.worktrees/
+dbweaver_app/*
+*.md
+node_modules/
diff --git a/README.md b/README.md
index 7f5a6b2e..0b783ca7 100644
--- a/README.md
+++ b/README.md
@@ -1,362 +1,245 @@
-
-
-# DBWeaver
-
-**Crie consultas SQL visualmente - sem precisar digitar.**
-
-Um designer SQL baseado em nós e canvas infinito que compila para SQL real e parametrizado em SQL Server, PostgreSQL, MySQL e SQLite.
-
-[](https://github.com/TheyCallMeErick/VisualSqlArchtect/actions/workflows/ci.yml)
-[](https://github.com/TheyCallMeErick/VisualSqlArchtect/releases)
-[](https://dotnet.microsoft.com)
-[](https://avaloniaui.net)
-
-
-
----
-
-
-
-
-**Idioma / Language:** 🇧🇷 [Português (PT-BR)](#pt-br) · 🇺🇸 [English](#english)
-
-**Status / Backlog:** [PROJECT_BACKLOG.md](PROJECT_BACKLOG.md)
-
-## O que é?
-
-O DBWeaver permite arrastar nós para o canvas e conectá-los para montar consultas SQL. Cada conexão vira um JOIN, cada nó de filtro vira uma cláusula WHERE, e o resultado aparece instantaneamente como SQL ao vivo abaixo do canvas - sem digitação, sem erros de sintaxe e sem dor de cabeça com dialetos.
-
-Diagrama visual do fluxo (query por nós): veja [Diagramas compartilhados](#shared-diagrams).
-
----
-
-## Funcionalidades
-
-### Canvas
-- **Pan e zoom infinitos** - pan com botão do meio, zoom com scroll e atalhos de teclado
-- **Nós por arrastar e soltar** - paleta de busca com fuzzy find e fluxo keyboard-first
-- **Conexões por fios** - curvas Bézier com validação em tempo real e pinos com checagem de tipo
-- **Multi-seleção e alinhamento** - selecione, mova, exclua e alinhe grupos de nós
-- **Auto-layout** - um clique para organizar um grafo bagunçado em uma árvore limpa
-- **Desfazer / refazer** - pilha de comandos granular, Ctrl+Z / Ctrl+Y
-- **Salvar / carregar sessões** - persistência do canvas em JSON e do workspace (query + DDL)
-
-### Geração de SQL
-- **Pré-visualização SQL em tempo real** - cada edição atualiza a barra de SQL instantaneamente
-- **Multi-dialeto** - SQL Server, PostgreSQL, MySQL e SQLite
-- **Preview seguro** - `ExecutePreviewAsync` sempre faz rollback; nunca altera dados
-- **Plano EXPLAIN** - um clique para visualizar o plano de execução retornado pelo servidor
-- **Importador SQL** - cole SQL existente e importe de volta como grafo de nós
-
-### Biblioteca de nós
-
-| Categoria | Nós |
-|---|---|
-| **Fonte de dados** | Tabela, Raw SQL |
-| **Comparação** | =, ≠, >, ≥, <, ≤, BETWEEN, LIKE, IS NULL |
-| **Portas lógicas** | AND, OR, NOT |
-| **Agregações** | SUM, COUNT, AVG, MIN, MAX, COUNT DISTINCT |
-| **Matemática** | +, −, ×, ÷, ROUND, ABS, MOD, POWER |
-| **String** | UPPER, LOWER, TRIM, LENGTH, CONCAT, REPLACE, SUBSTRING, REGEX |
-| **Condicionais** | CASE WHEN, IIF / COALESCE |
-| **JSON** | JSON Extract, JSON Value, JSON Array Length |
-| **Tipos** | CAST / CONVERT |
-| **Modificadores de resultado** | ORDER BY, LIMIT / TOP, DISTINCT, GROUP BY, HAVING |
-
-### Sistema de tipos de pino
-
-Cada pino tem **forma + cor** que identificam o que ele carrega. Forma indica a família semântica; cor indica o tipo específico.
-
-| Família | Forma | Tipos | Cor |
-|---|---|---|---|
-| Escalar | Círculo `●` | Text, Integer, Decimal, Boolean, DateTime, Json | Azul · Verde · Âmbar · Ciano · Índigo |
-| Referência de coluna | Losango `◆` | ColumnRef | Laranja |
-| Lista de colunas | Losango vazado `◇` | ColumnSet | Ouro |
-| Conjunto de linhas | Losango achatado `⬥` | RowSet | Rosa |
-| SQL bruto | Círculo tracejado `○` | Expression | Cinza |
-
-Pinos incompatíveis ficam apagados durante o drag. Vermelho é reservado para erros de validação estática (pino obrigatório sem conexão).
-
-Referência completa: [docs/PIN_TYPES_REFERENCE.md](docs/PIN_TYPES_REFERENCE.md)
-
----
-
-### Integração com banco de dados
-- **Gerenciador de conexões** - salve e nomeie múltiplas conexões, com teste em um clique
-- **Fluxo de conexão com confirmação** - ao conectar, você pode manter o canvas atual ou limpá-lo antes de carregar o novo contexto de banco
-- **Explorador de schema** - navegue por schemas, tabelas e colunas em árvore lateral
-- **Carregamento automático de tabelas** - ao conectar com sucesso, os metadados são carregados e as tabelas ficam disponíveis imediatamente no menu de busca
-- **Detecção automática de joins** - detecta relacionamentos FK e convenções de nome (`orders.customer_id -> customers.id`) e sugere o join correto
-- **Biblioteca de templates de consulta** - salve e carregue snippets reutilizáveis de grafos
-
-### Ferramentas para desenvolvimento
-- **Painel de diagnóstico** - memória em tempo real, FPS e estado da conexão
-- **Overlay de benchmark** - mede tempo de renderização e compilação
-- **Suíte automatizada de testes** - compiladores de nós, emissão por dialeto, heurísticas de metadados e segurança de ciclo de vida/UX
-
-### Atualizações recentes
-- **Hardening do preview SQL** - o SQL de preview evita placeholders bound no caminho de execução que exige SQL literal-safe
-- **Sincronização segura de provider** - o provider do Live SQL é sincronizado com o provider da conexão ativa para evitar erros entre dialetos
-- **Consistência de UX em modais** - diálogos de overlay podem ser fechados por clique no backdrop e com `Esc`
-
----
-
-## Download
-
-Baixe o binário self-contained mais recente em [Releases](https://github.com/TheyCallMeErick/VisualSqlArchtect/releases) - sem necessidade de instalar .NET.
-
-| Plataforma | Binário |
-|---|---|
-| Windows x64 | `xe` |
-| Linux x64 | `` |
-| macOS x64 | `|
-
----
-
-## Compilar do código-fonte
-
-**Pré-requisitos:** [.NET 9 SDK](https://dotnet.microsoft.com/download/dotnet/9.0)
-
-```bash
-git clone https://github.com/TheyCallMeErick/VisualSqlArchtect.git
-cd VisualSqlArchtect
-
-# Executar a aplicação
-dotnet run --project src/xecutar a suíte de testes
-dotnet test files.sln
-```
-
----
-
-## Arquitetura
-
-Diagrama de arquitetura: veja [Diagramas compartilhados](#shared-diagrams).
-
----
-
-## Estrutura do projeto
-
-Diagrama da estrutura do projeto: veja [Diagramas compartilhados](#shared-diagrams).
-
----
-
-## Contribuição
-
-1. Faça um fork do repositório
-2. Crie uma branch de feature a partir de `main`
-3. Execute `dotnet test files.sln` - todos os testes devem passar
-4. Abra um pull request
-
-O pipeline de CI roda em todo PR; o pipeline de release publica binários automaticamente quando uma tag `v*` é enviada.
-
----
-
-## English
-
-### What is it?
-
-DBWeaver is a node-based SQL designer with an infinite canvas. You connect nodes to compose queries visually: connections become JOINs, filter nodes become WHERE clauses, and the generated SQL is shown live below the canvas.
-
-### Features
-
-#### Canvas
-- **Infinite pan & zoom** - middle-mouse pan, scroll-wheel zoom, keyboard shortcuts
-- **Drag-and-drop nodes** - searchable palette with fuzzy find and keyboard-first workflow
-- **Wired connections** - bezier curves with live validation and type-checked pins
-- **Multi-select & align** - move, delete and align node groups
-- **Auto-layout** - one-click graph organization
-- **Undo / redo** - granular command stack (`Ctrl+Z` / `Ctrl+Y`)
-- **Save / load sessions** - JSON canvas persistence and workspace persistence (query + DDL)
-
-#### SQL Generation
-- **Real-time SQL preview** - updates instantly as the graph changes
-- **Multi-dialect** - SQL Server, PostgreSQL, MySQL and SQLite
-- **Safe previews** - `ExecutePreviewAsync` always rolls back (no data mutations)
-- **EXPLAIN plan** - visualize execution plans returned by the database
-- **SQL importer** - paste SQL and rebuild it as a node graph
-
-#### Pin type system
-
-Every pin has a **shape + color** that communicates what it carries. Shape encodes the semantic family; color encodes the specific type.
-
-| Family | Shape | Types | Color |
-|---|---|---|---|
-| Scalar | Circle `●` | Text, Integer, Decimal, Boolean, DateTime, Json | Blue · Green · Amber · Cyan · Indigo |
-| Column reference | Diamond `◆` | ColumnRef | Orange |
-| Column list | Hollow diamond `◇` | ColumnSet | Gold |
-| Row set | Flat diamond `⬥` | RowSet | Pink |
-| Raw SQL | Dashed circle `○` | Expression | Gray |
-
-Incompatible pins fade out during drag. Red is reserved for static validation errors (required pin with no connection).
-
-Full reference: [docs/PIN_TYPES_REFERENCE.md](docs/PIN_TYPES_REFERENCE.md)
-
----
-
-#### Database Integration
-- **Connection manager** - store and test multiple connections quickly
-- **Connect confirmation flow** - choose whether to keep or clear the current canvas when connecting
-- **Schema explorer** - browse schemas, tables and columns
-- **Automatic table loading** - metadata loads on connect and tables become immediately available in search
-- **Auto-join detection** - infers relationships from FK metadata and naming conventions
-- **Query template library** - save reusable graph snippets
-
-#### Developer Tooling
-- **Diagnostics panel** - memory, FPS and connection state
-- **Benchmark overlay** - render/compile timing insights
-- **Automated tests** - coverage for node compilation, dialect emission, metadata heuristics and lifecycle/UX safety
-
-#### Recent updates
-- **Preview SQL hardening** - avoids bound placeholders on literal-safe preview execution paths
-- **Provider synchronization** - Live SQL provider now follows the active connection provider to prevent cross-dialect issues
-- **Modal UX consistency** - overlay dialogs close via backdrop click and `Esc`
-
-### Download
-
-Get the latest self-contained binaries from [Releases](https://github.com/TheyCallMeErick/VisualSqlArchtect/releases).
-
-| Platform | Binary |
-|---|---|
-| Windows x64 | `xe` |
-| Linux x64 | `` |
-| macOS x64 | `|
-
-### Build from source
-
-**Prerequisites:** [.NET 9 SDK](https://dotnet.microsoft.com/download/dotnet/9.0)
-
-```bash
-git clone https://github.com/TheyCallMeErick/VisualSqlArchtect.git
-cd VisualSqlArchtect
-
-# Run the app
-dotnet run --project src/un tests
-dotnet test files.sln
-```
-
-### Architecture
-
-The architecture and project-structure diagrams are shared for both languages below: [Shared Diagrams](#shared-diagrams).
-
-### Contributing
-
-1. Fork the repository
-2. Create a feature branch from `main`
-3. Run `dotnet test files.sln` (all tests must pass)
-4. Open a pull request
-
-CI runs on every PR, and the release pipeline publishes binaries automatically for `v*` tags.
-
----
-
-
-
-## Diagramas compartilhados / Shared diagrams
-
-### Fluxo visual de query / Visual query flow
-
-```mermaid
-flowchart TD
- O[orders]
- C[customers]
- W[where status active]
- S[select id name total]
- L["Live SQL Bar
-SELECT o.id c.name o.total
-FROM orders o
-LEFT JOIN customers c
-WHERE status active"]
-
- O --> S
- C --> S
- W --> S
- S --> L
-```
-
-### Arquitetura / Architecture
-
-```mermaid
-flowchart TB
- UI[UI Avalonia Canvas]
- NC[NodeControl]
- BWL[BezierWireLayer]
- SC[SidebarControl]
- LSB[LiveSqlBar]
-
- NG[NodeGraph]
- NGC[NodeGraphCompiler]
- NCF[NodeCompilerFactory]
- DSC[DataSourceCompiler]
- CC[ComparisonCompiler]
- LGC[LogicGateCompiler]
- AC[AggregateCompiler]
- JC[JsonCompiler]
- CNG[CompiledNodeGraph]
-
- QBS[QueryBuilderService SqlKata]
- ISD[SqlDialectRegistry]
- ISF[SqlFunctionRegistry]
- CQ[CompiledQuery]
-
- DBO[DbOrchestrator]
- OPS[Preview Schema Explain]
- DBS[SQL Server PostgreSQL MySQL SQLite]
-
- UI --> NC
- UI --> BWL
- UI --> SC
- UI --> LSB
- UI --> NG
-
- NG --> NGC
- NGC --> NCF
- NCF --> DSC
- NCF --> CC
- NCF --> LGC
- NCF --> AC
- NCF --> JC
- DSC --> CNG
- CC --> CNG
- LGC --> CNG
- AC --> CNG
- JC --> CNG
-
- CNG --> QBS
- ISD --> QBS
- ISF --> QBS
- QBS --> CQ
-
- CQ --> DBO
- OPS --> DBO
- DBO --> DBS
-```
-
-### Estrutura do projeto / Project structure
-
-```mermaid
-flowchart TD
- ROOT[VisualSqlArchtect]
-
- ROOT --> SRC[src]
- ROOT --> TESTS[tests]
-
- SRC --> CORE[ SRC --> UI[ CORE --> NODES[Nodes]
- CORE --> EXPR[Expressions]
- CORE --> META[Metadata]
- CORE --> PROV[Providers]
- CORE --> QE[QueryEngine]
- CORE --> REG[Registry]
-
- UI --> CONTROLS[Controls]
- UI --> VMS[ViewModels]
- UI --> SERVICES[Services]
- UI --> SERIAL[Serialization]
-
- TESTS --> TESTPROJ[``
-
----
-
-
-Construído com Avalonia UI · .NET 9 · SqlKata
-Built with Avalonia UI · .NET 9 · SqlKata
-
+
+
+
+
+# AkkornStudio
+
+### Monte consultas SQL arrastando nós — veja o SQL ao vivo enquanto você cria.
+
+
+
+[](https://github.com/TheyCallMeErick/VisualSqlArchtect/actions/workflows/ci.yml)
+[](https://github.com/TheyCallMeErick/VisualSqlArchtect/releases)
+[](https://dotnet.microsoft.com)
+[](https://avaloniaui.net)
+[](LICENSE)
+
+
+
+[**Download**](#-download) · [**Como usar**](#-como-usar) · [**Features**](#-features) · [**Build**](#-compilar-do-código-fonte)
+
+
+
+
+
+---
+
+## O que é?
+
+O **AkkornStudio** é um designer SQL visual baseado em nós e canvas infinito. Você conecta blocos — tabelas, filtros, funções — e o SQL vai sendo gerado em tempo real, sem precisar digitar uma linha.
+
+```
+┌──────────┐ ┌─────────────┐ ┌──────────────┐
+│ orders │──▶│ JOIN ON │──▶│ SELECT │──▶ SQL ao vivo
+│ (tabela) │ │ customer_id│ │ id, nome, │
+└──────────┘ └─────────────┘ │ total │
+ └──────────────┘
+┌──────────┐ ▲
+│customers │─────────┘
+│ (tabela) │
+└──────────┘
+```
+
+O resultado aparece instantaneamente na **barra de SQL ao vivo** abaixo do canvas. Clique em executar para rodar direto no banco. Pronto.
+
+---
+
+## ✨ Features
+
+### 🎨 Canvas infinito
+
+Um ambiente de trabalho sem limites onde você monta consultas visualmente.
+
+| | |
+|---|---|
+| **Pan & zoom** | Scroll para zoom · botão do meio para pan · `Space` para modo mão |
+| **Arrastar e soltar** | Paleta de nós com busca fuzzy · fluxo keyboard-first |
+| **Fios Bézier** | Curvas suaves com validação de tipo em tempo real |
+| **Seleção múltipla** | Rubber-band selection · mover, alinhar e deletar grupos |
+| **Auto-layout** | Um clique para organizar o grafo automaticamente |
+| **Guias de alinhamento** | Snap em 6 pontos com guias visuais |
+| **Fios flexíveis** | Estilos Bézier, reto e ortogonal · edição de breakpoints |
+| **Desfazer / refazer** | Pilha de comandos granular `Ctrl+Z` / `Ctrl+Y` |
+| **Salvar sessões** | Persistência completa do canvas em JSON |
+
+---
+
+### 🧩 Biblioteca de nós
+
+Mais de 48 nós organizados por função:
+
+
+Categoria Nós
+
+ Fonte de dados
+ Tabela, Raw SQL, Alias
+
+
+ Comparação
+ =, ≠, >, ≥, <, ≤, BETWEEN, LIKE, IS NULL, IS NOT NULL
+
+
+ Lógica
+ AND, OR, NOT
+
+
+ Agregações
+ SUM, COUNT, COUNT DISTINCT, AVG, MIN, MAX
+
+
+ Matemática
+ +, −, ×, ÷, ROUND, ABS, CEIL, FLOOR
+
+
+ String
+ UPPER, LOWER, TRIM, LENGTH, CONCAT, REPLACE, SUBSTRING, REGEX Match/Replace/Extract
+
+
+ Condicionais
+ NULL Fill, Empty Fill, Value Map (CASE WHEN), CAST, Scalar From Column
+
+
+ JSON
+ JSON Extract, JSON Array Length
+
+
+ Resultado
+ ORDER BY, LIMIT / TOP, DISTINCT, GROUP BY, HAVING, ColumnSet Merge
+
+
+ Literais
+ Número, String, Data/DateTime, Booleano
+
+
+ Exportação
+ JSON, CSV, Excel
+
+
+
+---
+
+### ⚡ SQL ao vivo
+
+- **Pré-visualização instantânea** — cada nó conectado atualiza o SQL na hora
+- **Multi-dialeto** — SQL Server, PostgreSQL, MySQL e SQLite
+- **Execução segura** — preview sempre faz rollback; nunca altera dados
+- **Plano EXPLAIN** — visualize o plano de execução com um clique
+- **Importar SQL** — cole uma query existente e ela vira um grafo de nós automaticamente
+
+---
+
+### 🏗️ Modo DDL
+
+Construa e modifique sua estrutura de banco de dados visualmente:
+
+- `CREATE TABLE`, `CREATE VIEW`, `CREATE INDEX`, `CREATE SEQUENCE`
+- `ALTER TABLE` — adicionar, remover, renomear e alterar colunas
+- Gerenciamento de constraints — PK, FK, UNIQUE, CHECK, DEFAULT
+- Definições de tipo customizadas
+- Compilação e validação completas antes de executar
+
+---
+
+### 🔬 Schema Analysis
+
+Conecte ao banco e receba um relatório automático da qualidade do seu schema:
+
+| Regra | O que detecta |
+|---|---|
+| `MISSING_FK` | Relacionamentos sem foreign key declarada |
+| `FK_CATALOG_INCONSISTENT` | FKs com inconsistências de integridade referencial |
+| `NAMING_CONVENTION_VIOLATION` | Violações de convenção (snake_case, camelCase, PascalCase) |
+| `LOW_SEMANTIC_NAME` | Colunas e tabelas com nomes pouco descritivos |
+| `MISSING_REQUIRED_COMMENT` | Objetos sem documentação obrigatória |
+| `NF1_HINT_MULTI_VALUED` | Indícios de violação da 1ª Forma Normal |
+| `NF2_HINT_PARTIAL_DEPENDENCY` | Indícios de violação da 2ª Forma Normal |
+| `NF3_HINT_TRANSITIVE_DEPENDENCY` | Indícios de violação da 3ª Forma Normal |
+
+Cada issue vem com sugestão de SQL para corrigir.
+
+---
+
+### 🔌 Conexão com o banco
+
+- **Gerenciador de conexões** — salve múltiplas conexões com nome
+- **Explorador de schema** — navegue por schemas, tabelas e colunas
+- **Auto-join** — detecta FKs e convenções de nome e sugere o join correto
+- **Templates** — salve e reutilize grafos de consulta
+
+---
+
+### ⌨️ Atalhos de teclado
+
+| Atalho | Ação |
+|---|---|
+| `Space` | Modo pan (segurar) |
+| `F` | Centralizar seleção |
+| `Shift+F` | Fit da seleção na tela |
+| `Arrow Keys` | Mover nós (1px) |
+| `Shift+Arrow` | Mover nós (10px) |
+| `Ctrl+Z / Ctrl+Y` | Desfazer / refazer |
+| `Ctrl+Shift+X` | Bypass do nó selecionado |
+| `Alt+Q / Alt+E` | Selecionar upstream / downstream |
+| `Ctrl+Click (fio)` | Deletar fio |
+| `Delete / Backspace` | Deletar seleção |
+| `Esc` | Deselecionar tudo |
+
+---
+
+## 📥 Download
+
+Baixe o binário self-contained em [**Releases**](https://github.com/TheyCallMeErick/VisualSqlArchtect/releases) — sem necessidade de instalar o .NET.
+
+| Plataforma | Arquivo |
+|---|---|
+| Windows x64 | `AkkornStudio-win-x64.exe` |
+| Linux x64 | `AkkornStudio-linux-x64` |
+| macOS x64 | `AkkornStudio-osx-x64` |
+
+---
+
+## 🛠️ Compilar do código-fonte
+
+**Pré-requisito:** [.NET 9 SDK](https://dotnet.microsoft.com/download/dotnet/9.0)
+
+```bash
+git clone https://github.com/TheyCallMeErick/VisualSqlArchtect.git
+cd VisualSqlArchtect
+
+# Executar o app
+dotnet run --project src/AkkornStudio.UI
+
+# Rodar os testes
+dotnet test files.sln
+```
+
+---
+
+## 🤝 Contribuição
+
+1. Fork do repositório
+2. Branch a partir de `main`
+3. `dotnet test files.sln` — todos os testes devem passar
+4. Abra um pull request
+
+O pipeline de CI roda em todo PR. O pipeline de release publica binários automaticamente para tags `v*`.
+
+---
+
+## 💡 Como usar
+
+```
+1. Abra o app e conecte ao seu banco de dados
+2. Arraste uma tabela do explorador de schema para o canvas
+3. Adicione nós de filtro, agregação ou função da paleta
+4. Conecte os pinos — o SQL aparece na barra abaixo
+5. Clique em Executar para rodar (preview é sempre seguro)
+```
+
+---
+
+
+
+Construído com **Avalonia UI** · **.NET 9** · **SqlKata**
+
+
diff --git a/STRUCTURE.md b/STRUCTURE.md
index 7c7840e2..5f629219 100644
--- a/STRUCTURE.md
+++ b/STRUCTURE.md
@@ -1,132 +1,132 @@
-# Estrutura do Projeto DBWeaver
-
-## Organização da Solução
-
-```
-.
-├── files.sln # Arquivo de solução principal
-├── README.md # Documentação do projeto
-├── STRUCTURE.md # Este arquivo
-│
-├── src/ # Código-fonte principal
-│ ├── Projeto Core (DBWeaver.c─ Core/ # Orquestradores principais
-│ │ │ ├── BaseDbOrchestrator.cs
-│ │ │ └── IDbOrchestrator.cs
-│ │ │
-│ │ ├── Metadata/ # Serviços de metadados
-│ │ │ ├── MetadataService.cs
-│ │ │ ├── DbMetadata.cs
-│ │ │ ├── IDatabaseInspector.cs
-│ │ │ ├── AutoJoinDetector.cs
-│ │ │ └── Inspectors/ # Adaptadores para cada banco
-│ │ │ ├── MySqlInspector.cs
-│ │ │ ├── PostgresInspector.cs
-│ │ │ └── SqlServerInspector.cs
-│ │ │
-│ │ ├── Nodes/ # Modelo de nós do grafo
-│ │ │ ├── NodeDefinition.cs
-│ │ │ ├── NodeGraph.cs
-│ │ │ ├── NodeGraphCompiler.cs
-│ │ │ └── ISqlExpression.cs
-│ │ │
-│ │ ├── Providers/ # Orquestradores específicos por BD
-│ │ │ ├── MySqlOrchestrator.cs
-│ │ │ ├── PostgresOrchestrator.cs
-│ │ │ └── SqlServerOrchestrator.cs
-│ │ │
-│ │ ├── QueryEngine/ # Serviços de construção de queries
-│ │ │ ├── QueryBuilderService.cs
-│ │ │ └── QueryGeneratorService.cs
-│ │ │
-│ │ ├── Registry/ # Registro de funções SQL
-│ │ │ └── SqlFunctionRegistry.cs
-│ │ │
-│ │ ├── ServiceRegistration.cs # Configuração de injeção dependência
-│ │ └── │
-│ └── Projeto UI (DBWeaver.U ├── App.axaml # Arquivo XAML principal
-│ ├── App.axaml.cs # Code-behind da aplicação
-│ ├── MainWindow.axaml # Janela principal
-│ ├── MainWindow.axaml.cs
-│ │
-│ ├── Assets/ # Recursos
-│ │ └── Themes/ # Temas de cores
-│ │ ├── AppStyles.axaml
-│ │ └── DesignTokens.axaml
-│ │
-│ ├── Controls/ # Controles Avalonia customizados
-│ │ ├── NodeControl.axaml
-│ │ ├── NodeControl.axaml.cs
-│ │ ├── InfiniteCanvas.cs
-│ │ ├── PropertyPanelControl.axaml
-│ │ ├── PropertyPanelControl.axaml.cs
-│ │ ├── LiveSqlBar.axaml
-│ │ ├── LiveSqlBar.axaml.cs
-│ │ ├── AutoJoinOverlay.axaml
-│ │ ├── AutoJoinOverlay.axaml.cs
-│ │ ├── SearchMenuControl.axaml
-│ │ ├── SearchMenuControl.axaml.cs
-│ │ ├── BezierWireLayer.cs
-│ │ └── PinDragInteraction.cs
-│ │
-│ ├── ViewModels/ # ViewModels MVVM
-│ │ ├── CanvasViewModel.cs
-│ │ ├── LiveSqlBarViewModel.cs
-│ │ ├── PropertyPanelViewModel.cs
-│ │ ├── AutoJoinOverlayViewModel.cs
-│ │ └── UndoRedoStack.cs
-│ │
-│ ├── Serialization/ # Serviços de serialização
-│ │ └── CanvasSerializer.cs
-│ │
-│ ├── DataPreviewPanel.axaml
-│ └──
-│
-└── tests/ # Projetos de testes
- └── Projeto de Testes (DBWeaver.T ├── ArchitectureTests.cs
- ├── AtomicNodeTests.cs
- ├── MetadataTests.cs
- └── roj
-```
-
-## Namespaces
-
-### Core (- `nterfaces e classes base
-- ` - Serviços de metadados
-- `Inspectors` - Inspetores específicos por BD
-- `Modelo de nós
-- `` - Implementações de orquestradores
-- `ne` - Serviços de queries
-- ` - Registro de funções
-
-### UI ()
-- `igo principal da aplicação
-- `ls` - Controles customizados
-- `dels` - ViewModels
-- `ization` - Serviços de serialização
-
-### Testes (roj)
-- `Testes unitários
-
-## Dependências do Projeto
-
-### DBWeaver (Core)
-- ✅ Independente de UI
-- Depende de: SqlKata, database drivers
-
-### DBWeaver.UI
-- Depende de: Core + Avalonia
-
-### DBWeaver.Tests
-- Depende de: Core + xUnit
-
-## Compilação
-
-```bash
-# Build completo
-dotnet build
-
-# Build apenas do Core
-dotnet build src/cpenas da UI
-dotnet build src/er.Ud e executa testes
-dotnet test
-```
+# Estrutura do Projeto AkkornStudio
+
+## Organização da Solução
+
+```
+.
+├── files.sln # Arquivo de solução principal
+├── README.md # Documentação do projeto
+├── STRUCTURE.md # Este arquivo
+│
+├── src/ # Código-fonte principal
+│ ├── Projeto Core (AkkornStudio.c─ Core/ # Orquestradores principais
+│ │ │ ├── BaseDbOrchestrator.cs
+│ │ │ └── IDbOrchestrator.cs
+│ │ │
+│ │ ├── Metadata/ # Serviços de metadados
+│ │ │ ├── MetadataService.cs
+│ │ │ ├── DbMetadata.cs
+│ │ │ ├── IDatabaseInspector.cs
+│ │ │ ├── AutoJoinDetector.cs
+│ │ │ └── Inspectors/ # Adaptadores para cada banco
+│ │ │ ├── MySqlInspector.cs
+│ │ │ ├── PostgresInspector.cs
+│ │ │ └── SqlServerInspector.cs
+│ │ │
+│ │ ├── Nodes/ # Modelo de nós do grafo
+│ │ │ ├── NodeDefinition.cs
+│ │ │ ├── NodeGraph.cs
+│ │ │ ├── NodeGraphCompiler.cs
+│ │ │ └── ISqlExpression.cs
+│ │ │
+│ │ ├── Providers/ # Orquestradores específicos por BD
+│ │ │ ├── MySqlOrchestrator.cs
+│ │ │ ├── PostgresOrchestrator.cs
+│ │ │ └── SqlServerOrchestrator.cs
+│ │ │
+│ │ ├── QueryEngine/ # Serviços de construção de queries
+│ │ │ ├── QueryBuilderService.cs
+│ │ │ └── QueryGeneratorService.cs
+│ │ │
+│ │ ├── Registry/ # Registro de funções SQL
+│ │ │ └── SqlFunctionRegistry.cs
+│ │ │
+│ │ ├── ServiceRegistration.cs # Configuração de injeção dependência
+│ │ └── │
+│ └── Projeto UI (AkkornStudio.U ├── App.axaml # Arquivo XAML principal
+│ ├── App.axaml.cs # Code-behind da aplicação
+│ ├── MainWindow.axaml # Janela principal
+│ ├── MainWindow.axaml.cs
+│ │
+│ ├── Assets/ # Recursos
+│ │ └── Themes/ # Temas de cores
+│ │ ├── AppStyles.axaml
+│ │ └── DesignTokens.axaml
+│ │
+│ ├── Controls/ # Controles Avalonia customizados
+│ │ ├── NodeControl.axaml
+│ │ ├── NodeControl.axaml.cs
+│ │ ├── InfiniteCanvas.cs
+│ │ ├── PropertyPanelControl.axaml
+│ │ ├── PropertyPanelControl.axaml.cs
+│ │ ├── LiveSqlBar.axaml
+│ │ ├── LiveSqlBar.axaml.cs
+│ │ ├── AutoJoinOverlay.axaml
+│ │ ├── AutoJoinOverlay.axaml.cs
+│ │ ├── SearchMenuControl.axaml
+│ │ ├── SearchMenuControl.axaml.cs
+│ │ ├── BezierWireLayer.cs
+│ │ └── PinDragInteraction.cs
+│ │
+│ ├── ViewModels/ # ViewModels MVVM
+│ │ ├── CanvasViewModel.cs
+│ │ ├── LiveSqlBarViewModel.cs
+│ │ ├── PropertyPanelViewModel.cs
+│ │ ├── AutoJoinOverlayViewModel.cs
+│ │ └── UndoRedoStack.cs
+│ │
+│ ├── Serialization/ # Serviços de serialização
+│ │ └── CanvasSerializer.cs
+│ │
+│ ├── DataPreviewPanel.axaml
+│ └──
+│
+└── tests/ # Projetos de testes
+ └── Projeto de Testes (AkkornStudio.T ├── ArchitectureTests.cs
+ ├── AtomicNodeTests.cs
+ ├── MetadataTests.cs
+ └── roj
+```
+
+## Namespaces
+
+### Core (- `nterfaces e classes base
+- ` - Serviços de metadados
+- `Inspectors` - Inspetores específicos por BD
+- `Modelo de nós
+- `` - Implementações de orquestradores
+- `ne` - Serviços de queries
+- ` - Registro de funções
+
+### UI ()
+- `igo principal da aplicação
+- `ls` - Controles customizados
+- `dels` - ViewModels
+- `ization` - Serviços de serialização
+
+### Testes (roj)
+- `Testes unitários
+
+## Dependências do Projeto
+
+### AkkornStudio (Core)
+- ✅ Independente de UI
+- Depende de: SqlKata, database drivers
+
+### AkkornStudio.UI
+- Depende de: Core + Avalonia
+
+### AkkornStudio.Tests
+- Depende de: Core + xUnit
+
+## Compilação
+
+```bash
+# Build completo
+dotnet build
+
+# Build apenas do Core
+dotnet build src/cpenas da UI
+dotnet build src/er.Ud e executa testes
+dotnet test
+```
diff --git a/docs/CODE_CONVENTIONS.md b/docs/CODE_CONVENTIONS.md
index 1b3b8702..d5a0beb9 100644
--- a/docs/CODE_CONVENTIONS.md
+++ b/docs/CODE_CONVENTIONS.md
@@ -1,39 +1,39 @@
-# Convenções de Código — 2026-04-01
-
-## Objetivo
-
-Padronizar estilo mínimo em arquivos novos e arquivos tocados por refactor, reduzindo inconsistência e warnings evitáveis.
-
-## Regras
-
-1. Strings vazias/brancas
-- Preferir `string.IsNullOrWhiteSpace` para entradas de usuário, texto de UI e SQL livre.
-- Usar `string.IsNullOrEmpty` apenas quando espaço em branco for valor válido.
-
-2. Inicializadores de coleção
-- Em código moderno (C# 12), preferir `[]` quando o tipo já estiver explícito no lado esquerdo.
-- Em APIs públicas com legibilidade sensível, manter inicializador clássico se melhorar clareza.
-
-3. Nullable reference types
-- Tratar warnings de nullability como dívida técnica ativa em arquivos tocados.
-- Evitar `!` sem comentário/justificativa.
-- Em parâmetros opcionais, preferir anotação explícita (`string?`, `ILogger?`).
-
-4. Logging
-- Evitar `Debug.WriteLine` em fluxos de produção.
-- Preferir `ILogger` com mensagens estruturadas (`{Token}`).
-- Nível recomendado:
- - `LogDebug`: detalhe técnico de execução
- - `LogInformation`: milestones funcionais
- - `LogWarning`: comportamento degradado sem falha total
- - `LogError`: falha com exceção
-
-5. XML docs em API pública
-- Toda classe/interface/enum pública nova deve ter ``.
-- Para membros públicos principais, adicionar `` e ` ` quando útil.
-
-## Aplicação incremental
-
-- Não reformatar o projeto inteiro de uma vez.
-- Aplicar essas regras em cada PR nos arquivos modificados.
-- Revisores devem recusar novos `Debug.WriteLine` em caminhos críticos.
+# Convenções de Código — 2026-04-01
+
+## Objetivo
+
+Padronizar estilo mínimo em arquivos novos e arquivos tocados por refactor, reduzindo inconsistência e warnings evitáveis.
+
+## Regras
+
+1. Strings vazias/brancas
+- Preferir `string.IsNullOrWhiteSpace` para entradas de usuário, texto de UI e SQL livre.
+- Usar `string.IsNullOrEmpty` apenas quando espaço em branco for valor válido.
+
+2. Inicializadores de coleção
+- Em código moderno (C# 12), preferir `[]` quando o tipo já estiver explícito no lado esquerdo.
+- Em APIs públicas com legibilidade sensível, manter inicializador clássico se melhorar clareza.
+
+3. Nullable reference types
+- Tratar warnings de nullability como dívida técnica ativa em arquivos tocados.
+- Evitar `!` sem comentário/justificativa.
+- Em parâmetros opcionais, preferir anotação explícita (`string?`, `ILogger?`).
+
+4. Logging
+- Evitar `Debug.WriteLine` em fluxos de produção.
+- Preferir `ILogger` com mensagens estruturadas (`{Token}`).
+- Nível recomendado:
+ - `LogDebug`: detalhe técnico de execução
+ - `LogInformation`: milestones funcionais
+ - `LogWarning`: comportamento degradado sem falha total
+ - `LogError`: falha com exceção
+
+5. XML docs em API pública
+- Toda classe/interface/enum pública nova deve ter ``.
+- Para membros públicos principais, adicionar `` e ` ` quando útil.
+
+## Aplicação incremental
+
+- Não reformatar o projeto inteiro de uma vez.
+- Aplicar essas regras em cada PR nos arquivos modificados.
+- Revisores devem recusar novos `Debug.WriteLine` em caminhos críticos.
diff --git a/docs/EXCEPTION_HANDLING_STRATEGY.md b/docs/EXCEPTION_HANDLING_STRATEGY.md
index 28822aa2..4df6c887 100644
--- a/docs/EXCEPTION_HANDLING_STRATEGY.md
+++ b/docs/EXCEPTION_HANDLING_STRATEGY.md
@@ -1,47 +1,47 @@
-# Estratégia de Tratamento de Exceções — 2026-04-01
-Escopo: domínio, infraestrutura e UI
-
-## Objetivo
-
-Padronizar como falhas são propagadas, logadas e exibidas ao usuário para evitar combinações contraditórias entre módulos.
-
-## Contrato por camada
-
-1. Domínio/Core (`ações de validação e configuração inválida devem lançar exceção.
-- Operações de execução tolerante (ex.: preview/teste de conexão) podem retornar `Result` com `Success=false` quando a falha for operacional esperada.
-- Nunca engolir exceções sem transformar em sinal explícito (`Result` ou evento de warning).
-
-2. Infraestrutura/Serviços (`es`)
-- Serviços de execução devem usar `ILogger` para logs estruturados.
-- Exceções inesperadas devem ser logadas em `LogError` e repropagadas quando o chamador tiver contexto para decisão de UX.
-- Em persistência local de melhor-esforço, emitir warning observável (evento/callback) em vez de falha silenciosa.
-
-3. UI/ViewModels
-- A UI é o limite de apresentação: capturar exceções e converter para mensagem amigável (`DataPreview.ShowError` ou status equivalente).
-- Não expor stack trace ao usuário final.
-
-## Regras práticas
-
-- `ArgumentException` / `InvalidOperationException`: para uso incorreto de API e pré-condições.
-- `OperationCanceledException`: não tratar como erro; registrar em nível `Information` e encerrar fluxo.
-- `Exception` genérica: somente no boundary de serviço/UI, sempre com log estruturado.
-
-## Logging
-
-- `LogDebug`: detalhe técnico de execução.
-- `LogInformation`: marco funcional e cancelamento esperado.
-- `LogWarning`: degradação controlada, fallback, dados corrompidos recuperáveis.
-- `LogError`: falha inesperada com exceção.
-
-## Padrões de retorno recomendados
-
-- Core read-model e probes: `Result` (`Success`, `ErrorMessage`, métricas).
-- Serviços de execução síncronos/assíncronos críticos: lançar após log para o boundary de UI.
-- Persistência local best-effort: retornar fallback + `WarningRaised`.
-
-## Checklist para PR
-
-- Existe um boundary claro de captura de exceção?
-- Há log estruturado no nível correto?
-- Há consistência com o contrato da camada?
-- Existe teste cobrindo o caminho de falha?
+# Estratégia de Tratamento de Exceções — 2026-04-01
+Escopo: domínio, infraestrutura e UI
+
+## Objetivo
+
+Padronizar como falhas são propagadas, logadas e exibidas ao usuário para evitar combinações contraditórias entre módulos.
+
+## Contrato por camada
+
+1. Domínio/Core (`ações de validação e configuração inválida devem lançar exceção.
+- Operações de execução tolerante (ex.: preview/teste de conexão) podem retornar `Result` com `Success=false` quando a falha for operacional esperada.
+- Nunca engolir exceções sem transformar em sinal explícito (`Result` ou evento de warning).
+
+2. Infraestrutura/Serviços (`es`)
+- Serviços de execução devem usar `ILogger` para logs estruturados.
+- Exceções inesperadas devem ser logadas em `LogError` e repropagadas quando o chamador tiver contexto para decisão de UX.
+- Em persistência local de melhor-esforço, emitir warning observável (evento/callback) em vez de falha silenciosa.
+
+3. UI/ViewModels
+- A UI é o limite de apresentação: capturar exceções e converter para mensagem amigável (`DataPreview.ShowError` ou status equivalente).
+- Não expor stack trace ao usuário final.
+
+## Regras práticas
+
+- `ArgumentException` / `InvalidOperationException`: para uso incorreto de API e pré-condições.
+- `OperationCanceledException`: não tratar como erro; registrar em nível `Information` e encerrar fluxo.
+- `Exception` genérica: somente no boundary de serviço/UI, sempre com log estruturado.
+
+## Logging
+
+- `LogDebug`: detalhe técnico de execução.
+- `LogInformation`: marco funcional e cancelamento esperado.
+- `LogWarning`: degradação controlada, fallback, dados corrompidos recuperáveis.
+- `LogError`: falha inesperada com exceção.
+
+## Padrões de retorno recomendados
+
+- Core read-model e probes: `Result` (`Success`, `ErrorMessage`, métricas).
+- Serviços de execução síncronos/assíncronos críticos: lançar após log para o boundary de UI.
+- Persistência local best-effort: retornar fallback + `WarningRaised`.
+
+## Checklist para PR
+
+- Existe um boundary claro de captura de exceção?
+- Há log estruturado no nível correto?
+- Há consistência com o contrato da camada?
+- Existe teste cobrindo o caminho de falha?
diff --git a/docs/INDEX.md b/docs/INDEX.md
index 223471ea..efda4aab 100644
--- a/docs/INDEX.md
+++ b/docs/INDEX.md
@@ -1,93 +1,93 @@
-# 📚 Documentação — DbWeaver
-
-Este é o índice principal da documentação ativa do projeto DbWeaver.
-
-## 🎯 Organização Atual
-
-A documentação ativa está dividida em dois níveis:
-
-1. `/docs` concentra referências base e documentação transversal;
-2. `/docs/next` concentra especificações ativas de arquitetura, canvas e evolução estrutural.
-
----
-
-## 📘 Documentação Base em `/docs`
-
-### 🛠️ Engenharia
-
-- **[CODE_CONVENTIONS.md](CODE_CONVENTIONS.md)** — Convenções de código, naming e estrutura geral
-- **[EXCEPTION_HANDLING_STRATEGY.md](EXCEPTION_HANDLING_STRATEGY.md)** — Estratégia de tratamento de erros e falhas
-- **[SEARCH_FILTERING_GUIDELINE.md](SEARCH_FILTERING_GUIDELINE.md)** — Padrão de busca textual centralizada (fuzzy vs estrito) para UI
-- **[LIST_RENDERING_PERFORMANCE_GUIDELINE.md](LIST_RENDERING_PERFORMANCE_GUIDELINE.md)** — Regras normativas para listas/listagens performáticas (virtualização, cache, debounce e invalidação)
-- **[MODAL_LAYOUT_GUIDELINE.md](MODAL_LAYOUT_GUIDELINE.md)** — Guideline normativa para estrutura de modais (header + body rolável + footer fixo)
-- **[MODAL_ADOPTION_MAP.md](MODAL_ADOPTION_MAP.md)** — Inventário de modais e status de adoção da guideline
-- **[SQL_EDITOR_UX_IMPROVEMENT_IMPLEMENTATION_SPRINT_PLAN.md](SQL_EDITOR_UX_IMPROVEMENT_IMPLEMENTATION_SPRINT_PLAN.md)** — Plano de execução e checklist concluído do review de UX do SQL Editor
-- **[SQL_TO_NODE_INTERMEDIATE_LAYER_SPEC.md](SQL_TO_NODE_INTERMEDIATE_LAYER_SPEC.md)** — Especificação básica da camada intermediária SQL → IR → Nodes
-
-### 🧱 DDL Schema Structure Analysis
-
-- **[spec_ddl_schema_structure/SPEC_DDL_SCHEMA_STRUCTURE_ANALYSIS_INFERABLE_FINAL.md](spec_ddl_schema_structure/SPEC_DDL_SCHEMA_STRUCTURE_ANALYSIS_INFERABLE_FINAL.md)** — Especificação normativa executável do modo inferível
-- **[spec_ddl_schema_structure/DDL_SCHEMA_STRUCTURE_ANALYSIS_IMPLEMENTATION_BREAKDOWN.md](spec_ddl_schema_structure/DDL_SCHEMA_STRUCTURE_ANALYSIS_IMPLEMENTATION_BREAKDOWN.md)** — Breakdown de implementação por fases e tarefas
-- **[spec_ddl_schema_structure/DDL_SCHEMA_STRUCTURE_ANALYSIS_ACCEPTANCE_CHECKLIST.md](spec_ddl_schema_structure/DDL_SCHEMA_STRUCTURE_ANALYSIS_ACCEPTANCE_CHECKLIST.md)** — Checklist final de aceite com evidências
-- **[spec_ddl_schema_structure/2026-04-13-ddl-schema-analysis-release-note.md](spec_ddl_schema_structure/2026-04-13-ddl-schema-analysis-release-note.md)** — Nota de release da entrega consolidada
-
-### 🎨 Canvas, Pins e Tema
-
-- **[PIN_TYPES_REFERENCE.md](PIN_TYPES_REFERENCE.md)** — Referência visual dos tipos de pino, formas, cores e semântica estrutural
-- **[THEME_JSON_SCHEMA.md](THEME_JSON_SCHEMA.md)** — Schema JSON para customização de temas
-- **[THEME_VISUAL_VALIDATION_CHECKLIST.md](THEME_VISUAL_VALIDATION_CHECKLIST.md)** — Checklist de validação visual do tema
-
----
-
-## 🧭 Especificações Ativas em `/docs/next`
-
-### 🏗️ Arquitetura e Workspace
-
-- **[DOCUMENT_ORIENTED_WORKSPACE_ARCHITECTURE_SPEC.md](next/DOCUMENT_ORIENTED_WORKSPACE_ARCHITECTURE_SPEC.md)** — Especificação formal da arquitetura orientada a documento para Query, DDL e SQL Editor
-
-### 🧩 Nodes, Pins e Canvas
-
-- **[NODES_GENERAL_SURVEY.md](next/NODES_GENERAL_SURVEY.md)** — Especificação normativa do modelo graph-first de nodes, contratos semânticos, UX operacional e overhaul das famílias problemáticas
-- **[PIN_OBJECT_MODEL_MIGRATION_SPEC.md](next/PIN_OBJECT_MODEL_MIGRATION_SPEC.md)** — Especificação formal da migração do domínio de pins, compatibilidade, contracts e testes
-- **[WIRE_SYSTEM_OVERHAUL_SPEC.md](next/WIRE_SYSTEM_OVERHAUL_SPEC.md)** — Overhaul do sistema de wires, seleção, tooltip, roteamento e affordances do canvas
-
-### ⌨️ Comandos e Atalhos
-
-- **[SHORTCUT_REGISTRY_CUSTOMIZATION_SPEC.md](next/SHORTCUT_REGISTRY_CUSTOMIZATION_SPEC.md)** — Especificação do registry central de atalhos, customização e contexts de comando
-- **[SHORTCUT_REGISTRY_IMPLEMENTATION_BACKLOG.md](next/SHORTCUT_REGISTRY_IMPLEMENTATION_BACKLOG.md)** — Backlog executável da implementação do sistema de atalhos
-
-### 🌐 Expansão de Paradigma
-
-- **[NOSQL_EXPANSION_ROADMAP.md](next/NOSQL_EXPANSION_ROADMAP.md)** — Roadmap de expansão para múltiplos paradigmas e pipeline documental
-
-### 📑 Índice Prioritário das Specs
-
-- **[next/index.md](next/index.md)** — Priorização, dependências e ordem recomendada de execução das specs em `/docs/next`
-
----
-
-## 📦 Histórico e Material de Apoio
-
-- **[../archive/](../archive/)** — Planejamentos, análises, roadmaps e documentação histórica do projeto
-- **[superpowers/](superpowers/)** — Material exploratório, planos e estudos complementares
-
----
-
-## 🚀 Quick Links
-
-- **Começar:** Veja [../README.md](../README.md)
-- **Testes:** Veja [../tests/TESTS.md](../tests/TESTS.md)
-
----
-
-## 📝 Regras para Atualização do Índice
-
-1. Documentação transversal e referências estáveis devem permanecer em `/docs`.
-2. Especificações ativas de arquitetura, canvas e evolução estrutural devem ficar em `/docs/next`.
-3. Materiais históricos, análises concluídas e backlog antigo devem permanecer em `/archive`.
-4. Este `INDEX.md` deve refletir apenas arquivos que existam de fato no repositório.
-5. Sempre que uma nova spec ativa for adicionada em `/docs/next`, ela deve aparecer também aqui.
-
----
-
-*Última atualização: 15 de abril de 2026*
+# 📚 Documentação — AkkornStudio
+
+Este é o índice principal da documentação ativa do projeto AkkornStudio.
+
+## 🎯 Organização Atual
+
+A documentação ativa está dividida em dois níveis:
+
+1. `/docs` concentra referências base e documentação transversal;
+2. `/docs/next` concentra especificações ativas de arquitetura, canvas e evolução estrutural.
+
+---
+
+## 📘 Documentação Base em `/docs`
+
+### 🛠️ Engenharia
+
+- **[CODE_CONVENTIONS.md](CODE_CONVENTIONS.md)** — Convenções de código, naming e estrutura geral
+- **[EXCEPTION_HANDLING_STRATEGY.md](EXCEPTION_HANDLING_STRATEGY.md)** — Estratégia de tratamento de erros e falhas
+- **[SEARCH_FILTERING_GUIDELINE.md](SEARCH_FILTERING_GUIDELINE.md)** — Padrão de busca textual centralizada (fuzzy vs estrito) para UI
+- **[LIST_RENDERING_PERFORMANCE_GUIDELINE.md](LIST_RENDERING_PERFORMANCE_GUIDELINE.md)** — Regras normativas para listas/listagens performáticas (virtualização, cache, debounce e invalidação)
+- **[MODAL_LAYOUT_GUIDELINE.md](MODAL_LAYOUT_GUIDELINE.md)** — Guideline normativa para estrutura de modais (header + body rolável + footer fixo)
+- **[MODAL_ADOPTION_MAP.md](MODAL_ADOPTION_MAP.md)** — Inventário de modais e status de adoção da guideline
+- **[SQL_EDITOR_UX_IMPROVEMENT_IMPLEMENTATION_SPRINT_PLAN.md](SQL_EDITOR_UX_IMPROVEMENT_IMPLEMENTATION_SPRINT_PLAN.md)** — Plano de execução e checklist concluído do review de UX do SQL Editor
+- **[SQL_TO_NODE_INTERMEDIATE_LAYER_SPEC.md](SQL_TO_NODE_INTERMEDIATE_LAYER_SPEC.md)** — Especificação básica da camada intermediária SQL → IR → Nodes
+
+### 🧱 DDL Schema Structure Analysis
+
+- **[spec_ddl_schema_structure/SPEC_DDL_SCHEMA_STRUCTURE_ANALYSIS_INFERABLE_FINAL.md](spec_ddl_schema_structure/SPEC_DDL_SCHEMA_STRUCTURE_ANALYSIS_INFERABLE_FINAL.md)** — Especificação normativa executável do modo inferível
+- **[spec_ddl_schema_structure/DDL_SCHEMA_STRUCTURE_ANALYSIS_IMPLEMENTATION_BREAKDOWN.md](spec_ddl_schema_structure/DDL_SCHEMA_STRUCTURE_ANALYSIS_IMPLEMENTATION_BREAKDOWN.md)** — Breakdown de implementação por fases e tarefas
+- **[spec_ddl_schema_structure/DDL_SCHEMA_STRUCTURE_ANALYSIS_ACCEPTANCE_CHECKLIST.md](spec_ddl_schema_structure/DDL_SCHEMA_STRUCTURE_ANALYSIS_ACCEPTANCE_CHECKLIST.md)** — Checklist final de aceite com evidências
+- **[spec_ddl_schema_structure/2026-04-13-ddl-schema-analysis-release-note.md](spec_ddl_schema_structure/2026-04-13-ddl-schema-analysis-release-note.md)** — Nota de release da entrega consolidada
+
+### 🎨 Canvas, Pins e Tema
+
+- **[PIN_TYPES_REFERENCE.md](PIN_TYPES_REFERENCE.md)** — Referência visual dos tipos de pino, formas, cores e semântica estrutural
+- **[THEME_JSON_SCHEMA.md](THEME_JSON_SCHEMA.md)** — Schema JSON para customização de temas
+- **[THEME_VISUAL_VALIDATION_CHECKLIST.md](THEME_VISUAL_VALIDATION_CHECKLIST.md)** — Checklist de validação visual do tema
+
+---
+
+## 🧭 Especificações Ativas em `/docs/next`
+
+### 🏗️ Arquitetura e Workspace
+
+- **[DOCUMENT_ORIENTED_WORKSPACE_ARCHITECTURE_SPEC.md](next/DOCUMENT_ORIENTED_WORKSPACE_ARCHITECTURE_SPEC.md)** — Especificação formal da arquitetura orientada a documento para Query, DDL e SQL Editor
+
+### 🧩 Nodes, Pins e Canvas
+
+- **[NODES_GENERAL_SURVEY.md](next/NODES_GENERAL_SURVEY.md)** — Especificação normativa do modelo graph-first de nodes, contratos semânticos, UX operacional e overhaul das famílias problemáticas
+- **[PIN_OBJECT_MODEL_MIGRATION_SPEC.md](next/PIN_OBJECT_MODEL_MIGRATION_SPEC.md)** — Especificação formal da migração do domínio de pins, compatibilidade, contracts e testes
+- **[WIRE_SYSTEM_OVERHAUL_SPEC.md](next/WIRE_SYSTEM_OVERHAUL_SPEC.md)** — Overhaul do sistema de wires, seleção, tooltip, roteamento e affordances do canvas
+
+### ⌨️ Comandos e Atalhos
+
+- **[SHORTCUT_REGISTRY_CUSTOMIZATION_SPEC.md](next/SHORTCUT_REGISTRY_CUSTOMIZATION_SPEC.md)** — Especificação do registry central de atalhos, customização e contexts de comando
+- **[SHORTCUT_REGISTRY_IMPLEMENTATION_BACKLOG.md](next/SHORTCUT_REGISTRY_IMPLEMENTATION_BACKLOG.md)** — Backlog executável da implementação do sistema de atalhos
+
+### 🌐 Expansão de Paradigma
+
+- **[NOSQL_EXPANSION_ROADMAP.md](next/NOSQL_EXPANSION_ROADMAP.md)** — Roadmap de expansão para múltiplos paradigmas e pipeline documental
+
+### 📑 Índice Prioritário das Specs
+
+- **[next/index.md](next/index.md)** — Priorização, dependências e ordem recomendada de execução das specs em `/docs/next`
+
+---
+
+## 📦 Histórico e Material de Apoio
+
+- **[../archive/](../archive/)** — Planejamentos, análises, roadmaps e documentação histórica do projeto
+- **[superpowers/](superpowers/)** — Material exploratório, planos e estudos complementares
+
+---
+
+## 🚀 Quick Links
+
+- **Começar:** Veja [../README.md](../README.md)
+- **Testes:** Veja [../tests/TESTS.md](../tests/TESTS.md)
+
+---
+
+## 📝 Regras para Atualização do Índice
+
+1. Documentação transversal e referências estáveis devem permanecer em `/docs`.
+2. Especificações ativas de arquitetura, canvas e evolução estrutural devem ficar em `/docs/next`.
+3. Materiais históricos, análises concluídas e backlog antigo devem permanecer em `/archive`.
+4. Este `INDEX.md` deve refletir apenas arquivos que existam de fato no repositório.
+5. Sempre que uma nova spec ativa for adicionada em `/docs/next`, ela deve aparecer também aqui.
+
+---
+
+*Última atualização: 15 de abril de 2026*
diff --git a/docs/THEME_JSON_SCHEMA.md b/docs/THEME_JSON_SCHEMA.md
index c81ef6eb..394dbc41 100644
--- a/docs/THEME_JSON_SCHEMA.md
+++ b/docs/THEME_JSON_SCHEMA.md
@@ -1,87 +1,87 @@
-# Theme JSON Schema (Fase 5)
-
-Arquivo padrao: `src/DBWeaver.UI/Assets/Themes/user-theme.json`
-
-Objetivo:
-- Permitir customizacao de tokens macro sem editar AXAML.
-- Manter fallback seguro para valores invalidos.
-
-## Estrutura
-
-```json
-{
- "meta": {
- "name": "Studio Dark",
- "version": "1.0"
- },
- "colors": {
- "bg0": "#090B14",
- "bg1": "#0F1220",
- "bg2": "#151A2C",
- "bg3": "#1C2338",
- "bg4": "#252F49",
- "textPrimary": "#E7ECFF",
- "textSecondary": "#AEB9D9",
- "textMuted": "#7F8AAE",
- "textDisabled": "#66708F",
- "textInverse": "#0B0F1D",
- "textAccent": "#8FA7FF",
- "btnPrimaryBg": "#2563EB",
- "btnPrimaryFg": "#F8FAFC",
- "btnWarningBg": "#7C2D12",
- "btnWarningFg": "#FED7AA"
- },
- "typography": {
- "uiFont": "Manrope,Sora,Segoe UI,Arial,sans-serif",
- "nodeFont": "Space Grotesk,Manrope,Segoe UI,Arial,sans-serif",
- "monoFont": "JetBrainsMono Nerd Font,JetBrains Mono,Cascadia Code,Consolas,monospace",
- "displaySize": 24,
- "headingSize": 18,
- "titleSize": 15,
- "nodeTitleSize": 14,
- "labelSize": 13,
- "bodySize": 12,
- "captionSize": 11,
- "monoBodySize": 12,
- "monoSmallSize": 11
- }
-}
-```
-
-## Mapeamento de chaves
-
-- `colors.bg0` -> `Bg0`, `Bg0Brush`
-- `colors.bg1` -> `Bg1`, `Bg1Brush`
-- `colors.bg2` -> `Bg2`, `Bg2Brush`
-- `colors.bg3` -> `Bg3`, `Bg3Brush`
-- `colors.bg4` -> `Bg4`, `Bg4Brush`
-- `colors.textPrimary` -> `TextPrimary`, `TextPrimaryBrush`
-- `colors.textSecondary` -> `TextSecondary`, `TextSecondaryBrush`
-- `colors.textMuted` -> `TextMuted`, `TextMutedBrush`
-- `colors.textDisabled` -> `TextDisabled`, `TextDisabledBrush`
-- `colors.textInverse` -> `TextInverse`, `TextInverseBrush`
-- `colors.textAccent` -> `TextAccent`, `TextAccentBrush`
-- `colors.btnPrimaryBg` -> `BtnPrimaryBg`, `BtnPrimaryBgBrush`
-- `colors.btnPrimaryFg` -> `BtnPrimaryFg`, `BtnPrimaryFgBrush`
-- `colors.btnWarningBg` -> `BtnWarningBg`, `BtnWarningBgBrush`
-- `colors.btnWarningFg` -> `BtnWarningFg`, `BtnWarningFgBrush`
-- `typography.uiFont` -> `UIFont`
-- `typography.nodeFont` -> `NodeFont`
-- `typography.monoFont` -> `MonoFont`
-- `typography.displaySize` -> `FontSizeDisplay`
-- `typography.headingSize` -> `FontSizeHeading`
-- `typography.titleSize` -> `FontSizeTitle`
-- `typography.nodeTitleSize` -> `FontSizeNodeTitle`
-- `typography.labelSize` -> `FontSizeLabel`
-- `typography.bodySize` -> `FontSizeBody`
-- `typography.captionSize` -> `FontSizeCaption`
-- `typography.monoBodySize` -> `FontSizeMonoBody`
-- `typography.monoSmallSize` -> `FontSizeMonoSmall`
-
-## Regras de seguranca
-
-- Arquivo ausente: aplica tema padrao (sem erro).
-- JSON invalido: fallback para tema padrao.
-- Chave invalida (cor/tamanho): ignorada individualmente com warning.
-- Tokens sem valor valido permanecem no padrao.
-- Escopo atual: tokens de shell, tipografia global e hierarchy de texto.
+# Theme JSON Schema (Fase 5)
+
+Arquivo padrao: `src/AkkornStudio.UI/Assets/Themes/user-theme.json`
+
+Objetivo:
+- Permitir customizacao de tokens macro sem editar AXAML.
+- Manter fallback seguro para valores invalidos.
+
+## Estrutura
+
+```json
+{
+ "meta": {
+ "name": "Studio Dark",
+ "version": "1.0"
+ },
+ "colors": {
+ "bg0": "#090B14",
+ "bg1": "#0F1220",
+ "bg2": "#151A2C",
+ "bg3": "#1C2338",
+ "bg4": "#252F49",
+ "textPrimary": "#E7ECFF",
+ "textSecondary": "#AEB9D9",
+ "textMuted": "#7F8AAE",
+ "textDisabled": "#66708F",
+ "textInverse": "#0B0F1D",
+ "textAccent": "#8FA7FF",
+ "btnPrimaryBg": "#2563EB",
+ "btnPrimaryFg": "#F8FAFC",
+ "btnWarningBg": "#7C2D12",
+ "btnWarningFg": "#FED7AA"
+ },
+ "typography": {
+ "uiFont": "Manrope,Sora,Segoe UI,Arial,sans-serif",
+ "nodeFont": "Space Grotesk,Manrope,Segoe UI,Arial,sans-serif",
+ "monoFont": "JetBrainsMono Nerd Font,JetBrains Mono,Cascadia Code,Consolas,monospace",
+ "displaySize": 24,
+ "headingSize": 18,
+ "titleSize": 15,
+ "nodeTitleSize": 14,
+ "labelSize": 13,
+ "bodySize": 12,
+ "captionSize": 11,
+ "monoBodySize": 12,
+ "monoSmallSize": 11
+ }
+}
+```
+
+## Mapeamento de chaves
+
+- `colors.bg0` -> `Bg0`, `Bg0Brush`
+- `colors.bg1` -> `Bg1`, `Bg1Brush`
+- `colors.bg2` -> `Bg2`, `Bg2Brush`
+- `colors.bg3` -> `Bg3`, `Bg3Brush`
+- `colors.bg4` -> `Bg4`, `Bg4Brush`
+- `colors.textPrimary` -> `TextPrimary`, `TextPrimaryBrush`
+- `colors.textSecondary` -> `TextSecondary`, `TextSecondaryBrush`
+- `colors.textMuted` -> `TextMuted`, `TextMutedBrush`
+- `colors.textDisabled` -> `TextDisabled`, `TextDisabledBrush`
+- `colors.textInverse` -> `TextInverse`, `TextInverseBrush`
+- `colors.textAccent` -> `TextAccent`, `TextAccentBrush`
+- `colors.btnPrimaryBg` -> `BtnPrimaryBg`, `BtnPrimaryBgBrush`
+- `colors.btnPrimaryFg` -> `BtnPrimaryFg`, `BtnPrimaryFgBrush`
+- `colors.btnWarningBg` -> `BtnWarningBg`, `BtnWarningBgBrush`
+- `colors.btnWarningFg` -> `BtnWarningFg`, `BtnWarningFgBrush`
+- `typography.uiFont` -> `UIFont`
+- `typography.nodeFont` -> `NodeFont`
+- `typography.monoFont` -> `MonoFont`
+- `typography.displaySize` -> `FontSizeDisplay`
+- `typography.headingSize` -> `FontSizeHeading`
+- `typography.titleSize` -> `FontSizeTitle`
+- `typography.nodeTitleSize` -> `FontSizeNodeTitle`
+- `typography.labelSize` -> `FontSizeLabel`
+- `typography.bodySize` -> `FontSizeBody`
+- `typography.captionSize` -> `FontSizeCaption`
+- `typography.monoBodySize` -> `FontSizeMonoBody`
+- `typography.monoSmallSize` -> `FontSizeMonoSmall`
+
+## Regras de seguranca
+
+- Arquivo ausente: aplica tema padrao (sem erro).
+- JSON invalido: fallback para tema padrao.
+- Chave invalida (cor/tamanho): ignorada individualmente com warning.
+- Tokens sem valor valido permanecem no padrao.
+- Escopo atual: tokens de shell, tipografia global e hierarchy de texto.
diff --git a/files.sln b/files.sln
index 89d9e0f0..bcf302cc 100644
--- a/files.sln
+++ b/files.sln
@@ -1,41 +1,41 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.5.2.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBWeaver", "src/DBWeaver/DBWeaver.csproj", "{EC6D5DCC-55C8-E541-BE7C-72475C926523}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBWeaver.UI", "src/DBWeaver.UI/DBWeaver.UI.csproj", "{91EC5804-A179-27A6-1C39-B4C629B2AD06}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBWeaver.Canvas", "src/DBWeaver.Canvas/DBWeaver.Canvas.csproj", "{FD5E9E45-6012-4E74-A39B-3AC1DC9564EA}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{890483B4-9539-40F5-93DA-57728571BDC0}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {EC6D5DCC-55C8-E541-BE7C-72475C926523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EC6D5DCC-55C8-E541-BE7C-72475C926523}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EC6D5DCC-55C8-E541-BE7C-72475C926523}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EC6D5DCC-55C8-E541-BE7C-72475C926523}.Release|Any CPU.Build.0 = Release|Any CPU
- {91EC5804-A179-27A6-1C39-B4C629B2AD06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {91EC5804-A179-27A6-1C39-B4C629B2AD06}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {91EC5804-A179-27A6-1C39-B4C629B2AD06}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {91EC5804-A179-27A6-1C39-B4C629B2AD06}.Release|Any CPU.Build.0 = Release|Any CPU
- {FD5E9E45-6012-4E74-A39B-3AC1DC9564EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FD5E9E45-6012-4E74-A39B-3AC1DC9564EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FD5E9E45-6012-4E74-A39B-3AC1DC9564EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {FD5E9E45-6012-4E74-A39B-3AC1DC9564EA}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {C1E38B04-3BCD-4392-A686-DD464894A34C}
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {FD5E9E45-6012-4E74-A39B-3AC1DC9564EA} = {890483B4-9539-40F5-93DA-57728571BDC0}
- EndGlobalSection
-EndGlobal
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.2.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AkkornStudio", "src/AkkornStudio/AkkornStudio.csproj", "{EC6D5DCC-55C8-E541-BE7C-72475C926523}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AkkornStudio.UI", "src/AkkornStudio.UI/AkkornStudio.UI.csproj", "{91EC5804-A179-27A6-1C39-B4C629B2AD06}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AkkornStudio.Canvas", "src/AkkornStudio.Canvas/AkkornStudio.Canvas.csproj", "{FD5E9E45-6012-4E74-A39B-3AC1DC9564EA}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{890483B4-9539-40F5-93DA-57728571BDC0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EC6D5DCC-55C8-E541-BE7C-72475C926523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC6D5DCC-55C8-E541-BE7C-72475C926523}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC6D5DCC-55C8-E541-BE7C-72475C926523}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC6D5DCC-55C8-E541-BE7C-72475C926523}.Release|Any CPU.Build.0 = Release|Any CPU
+ {91EC5804-A179-27A6-1C39-B4C629B2AD06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {91EC5804-A179-27A6-1C39-B4C629B2AD06}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {91EC5804-A179-27A6-1C39-B4C629B2AD06}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {91EC5804-A179-27A6-1C39-B4C629B2AD06}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FD5E9E45-6012-4E74-A39B-3AC1DC9564EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FD5E9E45-6012-4E74-A39B-3AC1DC9564EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FD5E9E45-6012-4E74-A39B-3AC1DC9564EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FD5E9E45-6012-4E74-A39B-3AC1DC9564EA}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C1E38B04-3BCD-4392-A686-DD464894A34C}
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {FD5E9E45-6012-4E74-A39B-3AC1DC9564EA} = {890483B4-9539-40F5-93DA-57728571BDC0}
+ EndGlobalSection
+EndGlobal
diff --git a/src/DBWeaver.Canvas/.gitignore b/src/AkkornStudio.Canvas/.gitignore
similarity index 100%
rename from src/DBWeaver.Canvas/.gitignore
rename to src/AkkornStudio.Canvas/.gitignore
diff --git a/src/AkkornStudio.Canvas/AkkornStudio.Canvas.csproj b/src/AkkornStudio.Canvas/AkkornStudio.Canvas.csproj
new file mode 100644
index 00000000..25776aaa
--- /dev/null
+++ b/src/AkkornStudio.Canvas/AkkornStudio.Canvas.csproj
@@ -0,0 +1,6 @@
+
+
+ AkkornStudio.CanvasKit
+ AkkornStudio.Canvas
+
+
diff --git a/src/DBWeaver.Canvas/CanvasAutoJoinSemantics.cs b/src/AkkornStudio.Canvas/CanvasAutoJoinSemantics.cs
similarity index 95%
rename from src/DBWeaver.Canvas/CanvasAutoJoinSemantics.cs
rename to src/AkkornStudio.Canvas/CanvasAutoJoinSemantics.cs
index 1b783df2..06fc7255 100644
--- a/src/DBWeaver.Canvas/CanvasAutoJoinSemantics.cs
+++ b/src/AkkornStudio.Canvas/CanvasAutoJoinSemantics.cs
@@ -1,100 +1,100 @@
-namespace DBWeaver.CanvasKit;
-
-public static class CanvasAutoJoinSemantics
-{
- public static bool TrySplitJoinClauseOnEquality(
- string? clause,
- out string left,
- out string right)
- {
- left = string.Empty;
- right = string.Empty;
-
- if (string.IsNullOrWhiteSpace(clause))
- return false;
-
- string text = clause.Trim();
- int eq = text.IndexOf('=');
- if (eq <= 0 || eq >= text.Length - 1)
- return false;
-
- // Accept only a single plain equality operator (no >=, <=, !=, ==, chained expressions).
- if (text.Contains(">=", StringComparison.Ordinal)
- || text.Contains("<=", StringComparison.Ordinal)
- || text.Contains("!=", StringComparison.Ordinal)
- || text.Contains("==", StringComparison.Ordinal))
- {
- return false;
- }
-
- if (text.IndexOf('=', eq + 1) >= 0)
- return false;
-
- left = text[..eq].Trim();
- right = text[(eq + 1)..].Trim();
-
- return left.Length > 0 && right.Length > 0;
- }
-
- public static string BuildSuggestionPairKey(
- string existingTable,
- string newTable,
- string leftColumn,
- string rightColumn)
- {
- string[] pair = [existingTable ?? string.Empty, newTable ?? string.Empty];
- Array.Sort(pair, StringComparer.OrdinalIgnoreCase);
- return $"{pair[0]}|{pair[1]}|{leftColumn}|{rightColumn}";
- }
-
- public static bool TryParseQualifiedColumn(
- string expression,
- out string? source,
- out string column)
- {
- source = null;
- column = string.Empty;
-
- if (string.IsNullOrWhiteSpace(expression))
- return false;
-
- string normalized = expression.Trim();
- int lastDot = normalized.LastIndexOf('.');
- if (lastDot <= 0 || lastDot >= normalized.Length - 1)
- return false;
-
- source = normalized[..lastDot].Trim();
- column = normalized[(lastDot + 1)..].Trim();
-
- if (column.Length == 0)
- return false;
-
- source = source.Trim('"').Trim('`').Trim('[', ']');
- column = column.Trim('"').Trim('`').Trim('[', ']');
-
- return source.Length > 0 && column.Length > 0;
- }
-
- public static bool MatchesSource(
- string fullName,
- string shortName,
- string? alias,
- string sourceRef)
- {
- if (string.IsNullOrWhiteSpace(sourceRef))
- return false;
-
- if (fullName.Equals(sourceRef, StringComparison.OrdinalIgnoreCase))
- return true;
-
- if (shortName.Equals(sourceRef, StringComparison.OrdinalIgnoreCase))
- return true;
-
- if (!string.IsNullOrWhiteSpace(alias)
- && alias.Equals(sourceRef, StringComparison.OrdinalIgnoreCase))
- return true;
-
- string fullShort = fullName.Split('.').Last();
- return fullShort.Equals(sourceRef, StringComparison.OrdinalIgnoreCase);
- }
-}
+namespace AkkornStudio.CanvasKit;
+
+public static class CanvasAutoJoinSemantics
+{
+ public static bool TrySplitJoinClauseOnEquality(
+ string? clause,
+ out string left,
+ out string right)
+ {
+ left = string.Empty;
+ right = string.Empty;
+
+ if (string.IsNullOrWhiteSpace(clause))
+ return false;
+
+ string text = clause.Trim();
+ int eq = text.IndexOf('=');
+ if (eq <= 0 || eq >= text.Length - 1)
+ return false;
+
+ // Accept only a single plain equality operator (no >=, <=, !=, ==, chained expressions).
+ if (text.Contains(">=", StringComparison.Ordinal)
+ || text.Contains("<=", StringComparison.Ordinal)
+ || text.Contains("!=", StringComparison.Ordinal)
+ || text.Contains("==", StringComparison.Ordinal))
+ {
+ return false;
+ }
+
+ if (text.IndexOf('=', eq + 1) >= 0)
+ return false;
+
+ left = text[..eq].Trim();
+ right = text[(eq + 1)..].Trim();
+
+ return left.Length > 0 && right.Length > 0;
+ }
+
+ public static string BuildSuggestionPairKey(
+ string existingTable,
+ string newTable,
+ string leftColumn,
+ string rightColumn)
+ {
+ string[] pair = [existingTable ?? string.Empty, newTable ?? string.Empty];
+ Array.Sort(pair, StringComparer.OrdinalIgnoreCase);
+ return $"{pair[0]}|{pair[1]}|{leftColumn}|{rightColumn}";
+ }
+
+ public static bool TryParseQualifiedColumn(
+ string expression,
+ out string? source,
+ out string column)
+ {
+ source = null;
+ column = string.Empty;
+
+ if (string.IsNullOrWhiteSpace(expression))
+ return false;
+
+ string normalized = expression.Trim();
+ int lastDot = normalized.LastIndexOf('.');
+ if (lastDot <= 0 || lastDot >= normalized.Length - 1)
+ return false;
+
+ source = normalized[..lastDot].Trim();
+ column = normalized[(lastDot + 1)..].Trim();
+
+ if (column.Length == 0)
+ return false;
+
+ source = source.Trim('"').Trim('`').Trim('[', ']');
+ column = column.Trim('"').Trim('`').Trim('[', ']');
+
+ return source.Length > 0 && column.Length > 0;
+ }
+
+ public static bool MatchesSource(
+ string fullName,
+ string shortName,
+ string? alias,
+ string sourceRef)
+ {
+ if (string.IsNullOrWhiteSpace(sourceRef))
+ return false;
+
+ if (fullName.Equals(sourceRef, StringComparison.OrdinalIgnoreCase))
+ return true;
+
+ if (shortName.Equals(sourceRef, StringComparison.OrdinalIgnoreCase))
+ return true;
+
+ if (!string.IsNullOrWhiteSpace(alias)
+ && alias.Equals(sourceRef, StringComparison.OrdinalIgnoreCase))
+ return true;
+
+ string fullShort = fullName.Split('.').Last();
+ return fullShort.Equals(sourceRef, StringComparison.OrdinalIgnoreCase);
+ }
+}
diff --git a/src/DBWeaver.Canvas/CanvasLayerOrdering.cs b/src/AkkornStudio.Canvas/CanvasLayerOrdering.cs
similarity index 95%
rename from src/DBWeaver.Canvas/CanvasLayerOrdering.cs
rename to src/AkkornStudio.Canvas/CanvasLayerOrdering.cs
index c1a7cdd9..df9ad473 100644
--- a/src/DBWeaver.Canvas/CanvasLayerOrdering.cs
+++ b/src/AkkornStudio.Canvas/CanvasLayerOrdering.cs
@@ -1,74 +1,74 @@
-namespace DBWeaver.CanvasKit;
-
-public interface ICanvasLayerNode
-{
- bool IsSelected { get; }
- int ZOrder { get; }
-}
-
-public static class CanvasLayerOrdering
-{
- public static List OrderByZ(IEnumerable nodes)
- where TNode : ICanvasLayerNode =>
- [.. nodes.OrderBy(n => n.ZOrder)];
-
- public static List BringToFront(IEnumerable nodes)
- where TNode : ICanvasLayerNode
- {
- List ordered = OrderByZ(nodes);
- HashSet selected = ordered.Where(n => n.IsSelected).ToHashSet();
- var back = ordered.Where(n => !selected.Contains(n)).ToList();
- var front = ordered.Where(n => selected.Contains(n)).ToList();
- return [.. back, .. front];
- }
-
- public static List SendToBack(IEnumerable nodes)
- where TNode : ICanvasLayerNode
- {
- List ordered = OrderByZ(nodes);
- HashSet selected = ordered.Where(n => n.IsSelected).ToHashSet();
- var back = ordered.Where(n => selected.Contains(n)).ToList();
- var front = ordered.Where(n => !selected.Contains(n)).ToList();
- return [.. back, .. front];
- }
-
- public static List BringForward(IEnumerable nodes)
- where TNode : ICanvasLayerNode
- {
- List ordered = OrderByZ(nodes);
- for (int i = ordered.Count - 2; i >= 0; i--)
- {
- if (!ordered[i].IsSelected)
- continue;
- if (ordered[i + 1].IsSelected)
- continue;
- (ordered[i], ordered[i + 1]) = (ordered[i + 1], ordered[i]);
- }
- return ordered;
- }
-
- public static List SendBackward(IEnumerable nodes)
- where TNode : ICanvasLayerNode
- {
- List ordered = OrderByZ(nodes);
- for (int i = 1; i < ordered.Count; i++)
- {
- if (!ordered[i].IsSelected)
- continue;
- if (ordered[i - 1].IsSelected)
- continue;
- (ordered[i - 1], ordered[i]) = (ordered[i], ordered[i - 1]);
- }
- return ordered;
- }
-
- public static Dictionary BuildNormalizedMap(IEnumerable ordered)
- where TNode : ICanvasLayerNode
- {
- Dictionary map = [];
- int z = 0;
- foreach (TNode node in ordered)
- map[node] = z++;
- return map;
- }
-}
+namespace AkkornStudio.CanvasKit;
+
+public interface ICanvasLayerNode
+{
+ bool IsSelected { get; }
+ int ZOrder { get; }
+}
+
+public static class CanvasLayerOrdering
+{
+ public static List OrderByZ(IEnumerable nodes)
+ where TNode : ICanvasLayerNode =>
+ [.. nodes.OrderBy(n => n.ZOrder)];
+
+ public static List BringToFront(IEnumerable nodes)
+ where TNode : ICanvasLayerNode
+ {
+ List ordered = OrderByZ(nodes);
+ HashSet selected = ordered.Where(n => n.IsSelected).ToHashSet();
+ var back = ordered.Where(n => !selected.Contains(n)).ToList();
+ var front = ordered.Where(n => selected.Contains(n)).ToList();
+ return [.. back, .. front];
+ }
+
+ public static List SendToBack(IEnumerable nodes)
+ where TNode : ICanvasLayerNode
+ {
+ List ordered = OrderByZ(nodes);
+ HashSet selected = ordered.Where(n => n.IsSelected).ToHashSet();
+ var back = ordered.Where(n => selected.Contains(n)).ToList();
+ var front = ordered.Where(n => !selected.Contains(n)).ToList();
+ return [.. back, .. front];
+ }
+
+ public static List BringForward(IEnumerable nodes)
+ where TNode : ICanvasLayerNode
+ {
+ List ordered = OrderByZ(nodes);
+ for (int i = ordered.Count - 2; i >= 0; i--)
+ {
+ if (!ordered[i].IsSelected)
+ continue;
+ if (ordered[i + 1].IsSelected)
+ continue;
+ (ordered[i], ordered[i + 1]) = (ordered[i + 1], ordered[i]);
+ }
+ return ordered;
+ }
+
+ public static List SendBackward(IEnumerable nodes)
+ where TNode : ICanvasLayerNode
+ {
+ List ordered = OrderByZ(nodes);
+ for (int i = 1; i < ordered.Count; i++)
+ {
+ if (!ordered[i].IsSelected)
+ continue;
+ if (ordered[i - 1].IsSelected)
+ continue;
+ (ordered[i - 1], ordered[i]) = (ordered[i], ordered[i - 1]);
+ }
+ return ordered;
+ }
+
+ public static Dictionary BuildNormalizedMap(IEnumerable ordered)
+ where TNode : ICanvasLayerNode
+ {
+ Dictionary map = [];
+ int z = 0;
+ foreach (TNode node in ordered)
+ map[node] = z++;
+ return map;
+ }
+}
diff --git a/src/DBWeaver.Canvas/CanvasSubEditorStateMachine.cs b/src/AkkornStudio.Canvas/CanvasSubEditorStateMachine.cs
similarity index 94%
rename from src/DBWeaver.Canvas/CanvasSubEditorStateMachine.cs
rename to src/AkkornStudio.Canvas/CanvasSubEditorStateMachine.cs
index e1f27a73..b3c21eee 100644
--- a/src/DBWeaver.Canvas/CanvasSubEditorStateMachine.cs
+++ b/src/AkkornStudio.Canvas/CanvasSubEditorStateMachine.cs
@@ -1,30 +1,30 @@
-namespace DBWeaver.CanvasKit;
-
-public enum CanvasSubEditorMode
-{
- None,
- Cte,
- View,
-}
-
-public sealed record CanvasSubEditorSessionState(CanvasSubEditorMode Mode, string DisplayName)
-{
- public static readonly CanvasSubEditorSessionState Empty = new(CanvasSubEditorMode.None, string.Empty);
-
- public bool IsActive => Mode != CanvasSubEditorMode.None;
- public bool IsViewEditor => Mode == CanvasSubEditorMode.View;
-}
-
-public static class CanvasSubEditorStateMachine
-{
- public static CanvasSubEditorSessionState EnterCte(string displayName) =>
- new(CanvasSubEditorMode.Cte, NormalizeDisplayName(displayName));
-
- public static CanvasSubEditorSessionState EnterView(string displayName) =>
- new(CanvasSubEditorMode.View, NormalizeDisplayName(displayName));
-
- public static CanvasSubEditorSessionState Exit() => CanvasSubEditorSessionState.Empty;
-
- private static string NormalizeDisplayName(string displayName) =>
- string.IsNullOrWhiteSpace(displayName) ? string.Empty : displayName.Trim();
-}
+namespace AkkornStudio.CanvasKit;
+
+public enum CanvasSubEditorMode
+{
+ None,
+ Cte,
+ View,
+}
+
+public sealed record CanvasSubEditorSessionState(CanvasSubEditorMode Mode, string DisplayName)
+{
+ public static readonly CanvasSubEditorSessionState Empty = new(CanvasSubEditorMode.None, string.Empty);
+
+ public bool IsActive => Mode != CanvasSubEditorMode.None;
+ public bool IsViewEditor => Mode == CanvasSubEditorMode.View;
+}
+
+public static class CanvasSubEditorStateMachine
+{
+ public static CanvasSubEditorSessionState EnterCte(string displayName) =>
+ new(CanvasSubEditorMode.Cte, NormalizeDisplayName(displayName));
+
+ public static CanvasSubEditorSessionState EnterView(string displayName) =>
+ new(CanvasSubEditorMode.View, NormalizeDisplayName(displayName));
+
+ public static CanvasSubEditorSessionState Exit() => CanvasSubEditorSessionState.Empty;
+
+ private static string NormalizeDisplayName(string displayName) =>
+ string.IsNullOrWhiteSpace(displayName) ? string.Empty : displayName.Trim();
+}
diff --git a/src/DBWeaver.Canvas/CanvasTableHighlightEngine.cs b/src/AkkornStudio.Canvas/CanvasTableHighlightEngine.cs
similarity index 95%
rename from src/DBWeaver.Canvas/CanvasTableHighlightEngine.cs
rename to src/AkkornStudio.Canvas/CanvasTableHighlightEngine.cs
index a560f6d4..cd6f1669 100644
--- a/src/DBWeaver.Canvas/CanvasTableHighlightEngine.cs
+++ b/src/AkkornStudio.Canvas/CanvasTableHighlightEngine.cs
@@ -1,88 +1,88 @@
-namespace DBWeaver.CanvasKit;
-
-public interface ICanvasTableNode
-{
- bool IsTableSource { get; }
- bool IsHighlighted { get; set; }
- string? FullName { get; }
- string? Title { get; }
- string? Alias { get; }
-}
-
-public static class CanvasTableHighlightEngine
-{
- public static void ApplyHighlight(IEnumerable nodes, string? highlightedTableName)
- {
- ArgumentNullException.ThrowIfNull(nodes);
-
- string? normalizedFull = NormalizeTableReference(highlightedTableName);
- string? normalizedShort = normalizedFull is null ? null : normalizedFull.Split('.').Last();
-
- foreach (ICanvasTableNode node in nodes)
- {
- if (!node.IsTableSource)
- {
- node.IsHighlighted = false;
- continue;
- }
-
- node.IsHighlighted = normalizedShort is not null
- && MatchesHighlightedTable(node, normalizedFull!, normalizedShort);
- }
- }
-
- public static bool MatchesHighlightedTable(
- ICanvasTableNode node,
- string normalizedFull,
- string normalizedShort
- )
- {
- ArgumentNullException.ThrowIfNull(node);
- ArgumentException.ThrowIfNullOrWhiteSpace(normalizedFull);
- ArgumentException.ThrowIfNullOrWhiteSpace(normalizedShort);
-
- string? nodeFull = NormalizeTableReference(node.FullName);
- if (nodeFull is not null && nodeFull.Equals(normalizedFull, StringComparison.OrdinalIgnoreCase))
- return true;
-
- string? nodeTitle = NormalizeTableReference(node.Title);
- if (nodeTitle is not null
- && nodeTitle.Split('.').Last().Equals(normalizedShort, StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
-
- string? nodeAlias = NormalizeTableReference(node.Alias);
- if (nodeAlias is not null
- && nodeAlias.Split('.').Last().Equals(normalizedShort, StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
-
- return false;
- }
-
- public static string? NormalizeTableReference(string? value)
- {
- if (string.IsNullOrWhiteSpace(value))
- return null;
-
- string raw = value.Trim();
- if (raw.Length == 0)
- return null;
-
- string firstToken = raw.Split(
- ' ',
- StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[0];
- string[] parts = firstToken.Split(
- '.',
- StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
- if (parts.Length == 0)
- return null;
-
- for (int i = 0; i < parts.Length; i++)
- parts[i] = parts[i].Trim('"').Trim('`').Trim('[', ']');
-
- return string.Join('.', parts);
- }
-}
+namespace AkkornStudio.CanvasKit;
+
+public interface ICanvasTableNode
+{
+ bool IsTableSource { get; }
+ bool IsHighlighted { get; set; }
+ string? FullName { get; }
+ string? Title { get; }
+ string? Alias { get; }
+}
+
+public static class CanvasTableHighlightEngine
+{
+ public static void ApplyHighlight(IEnumerable nodes, string? highlightedTableName)
+ {
+ ArgumentNullException.ThrowIfNull(nodes);
+
+ string? normalizedFull = NormalizeTableReference(highlightedTableName);
+ string? normalizedShort = normalizedFull is null ? null : normalizedFull.Split('.').Last();
+
+ foreach (ICanvasTableNode node in nodes)
+ {
+ if (!node.IsTableSource)
+ {
+ node.IsHighlighted = false;
+ continue;
+ }
+
+ node.IsHighlighted = normalizedShort is not null
+ && MatchesHighlightedTable(node, normalizedFull!, normalizedShort);
+ }
+ }
+
+ public static bool MatchesHighlightedTable(
+ ICanvasTableNode node,
+ string normalizedFull,
+ string normalizedShort
+ )
+ {
+ ArgumentNullException.ThrowIfNull(node);
+ ArgumentException.ThrowIfNullOrWhiteSpace(normalizedFull);
+ ArgumentException.ThrowIfNullOrWhiteSpace(normalizedShort);
+
+ string? nodeFull = NormalizeTableReference(node.FullName);
+ if (nodeFull is not null && nodeFull.Equals(normalizedFull, StringComparison.OrdinalIgnoreCase))
+ return true;
+
+ string? nodeTitle = NormalizeTableReference(node.Title);
+ if (nodeTitle is not null
+ && nodeTitle.Split('.').Last().Equals(normalizedShort, StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+
+ string? nodeAlias = NormalizeTableReference(node.Alias);
+ if (nodeAlias is not null
+ && nodeAlias.Split('.').Last().Equals(normalizedShort, StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public static string? NormalizeTableReference(string? value)
+ {
+ if (string.IsNullOrWhiteSpace(value))
+ return null;
+
+ string raw = value.Trim();
+ if (raw.Length == 0)
+ return null;
+
+ string firstToken = raw.Split(
+ ' ',
+ StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[0];
+ string[] parts = firstToken.Split(
+ '.',
+ StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
+ if (parts.Length == 0)
+ return null;
+
+ for (int i = 0; i < parts.Length; i++)
+ parts[i] = parts[i].Trim('"').Trim('`').Trim('[', ']');
+
+ return string.Join('.', parts);
+ }
+}
diff --git a/src/DBWeaver.Canvas/CanvasViewportMath.cs b/src/AkkornStudio.Canvas/CanvasViewportMath.cs
similarity index 95%
rename from src/DBWeaver.Canvas/CanvasViewportMath.cs
rename to src/AkkornStudio.Canvas/CanvasViewportMath.cs
index fc235e38..9b5d5064 100644
--- a/src/DBWeaver.Canvas/CanvasViewportMath.cs
+++ b/src/AkkornStudio.Canvas/CanvasViewportMath.cs
@@ -1,74 +1,74 @@
-namespace DBWeaver.CanvasKit;
-
-public readonly record struct CanvasViewportPoint(double X, double Y);
-
-public readonly record struct CanvasViewportSize(double Width, double Height);
-
-public readonly record struct CanvasViewportNodeFrame(double X, double Y, double Width, double Height);
-
-public readonly record struct CanvasSelectionBounds(double MinX, double MinY, double MaxX, double MaxY)
-{
- public double Width => Math.Max(1, MaxX - MinX);
- public double Height => Math.Max(1, MaxY - MinY);
- public CanvasViewportPoint Center => new((MinX + MaxX) / 2.0, (MinY + MaxY) / 2.0);
-}
-
-public static class CanvasViewportMath
-{
- public static bool TryGetSelectionBounds(
- IEnumerable selected,
- out CanvasSelectionBounds bounds)
- {
- bounds = default;
-
- List nodes = selected.ToList();
- if (nodes.Count == 0)
- return false;
-
- double minX = double.MaxValue;
- double minY = double.MaxValue;
- double maxX = double.MinValue;
- double maxY = double.MinValue;
-
- foreach (CanvasViewportNodeFrame n in nodes)
- {
- minX = Math.Min(minX, n.X);
- minY = Math.Min(minY, n.Y);
- maxX = Math.Max(maxX, n.X + Math.Max(1, n.Width));
- maxY = Math.Max(maxY, n.Y + Math.Max(1, n.Height));
- }
-
- bounds = new CanvasSelectionBounds(minX, minY, maxX, maxY);
- return true;
- }
-
- public static CanvasViewportPoint ComputeCenterPan(
- CanvasSelectionBounds bounds,
- CanvasViewportSize viewport,
- double zoom)
- {
- CanvasViewportPoint center = bounds.Center;
- return new CanvasViewportPoint(
- viewport.Width / 2.0 - center.X * zoom,
- viewport.Height / 2.0 - center.Y * zoom
- );
- }
-
- public static (double Zoom, CanvasViewportPoint Pan) ComputeFit(
- CanvasSelectionBounds bounds,
- CanvasViewportSize viewport,
- double padding,
- double minZoom = 0.15,
- double maxZoom = 4.0)
- {
- double contentW = Math.Max(1, bounds.Width + padding * 2);
- double contentH = Math.Max(1, bounds.Height + padding * 2);
-
- double zoomX = viewport.Width / contentW;
- double zoomY = viewport.Height / contentH;
- double zoom = Math.Clamp(Math.Min(zoomX, zoomY), minZoom, maxZoom);
-
- CanvasViewportPoint pan = ComputeCenterPan(bounds, viewport, zoom);
- return (zoom, pan);
- }
-}
+namespace AkkornStudio.CanvasKit;
+
+public readonly record struct CanvasViewportPoint(double X, double Y);
+
+public readonly record struct CanvasViewportSize(double Width, double Height);
+
+public readonly record struct CanvasViewportNodeFrame(double X, double Y, double Width, double Height);
+
+public readonly record struct CanvasSelectionBounds(double MinX, double MinY, double MaxX, double MaxY)
+{
+ public double Width => Math.Max(1, MaxX - MinX);
+ public double Height => Math.Max(1, MaxY - MinY);
+ public CanvasViewportPoint Center => new((MinX + MaxX) / 2.0, (MinY + MaxY) / 2.0);
+}
+
+public static class CanvasViewportMath
+{
+ public static bool TryGetSelectionBounds(
+ IEnumerable selected,
+ out CanvasSelectionBounds bounds)
+ {
+ bounds = default;
+
+ List nodes = selected.ToList();
+ if (nodes.Count == 0)
+ return false;
+
+ double minX = double.MaxValue;
+ double minY = double.MaxValue;
+ double maxX = double.MinValue;
+ double maxY = double.MinValue;
+
+ foreach (CanvasViewportNodeFrame n in nodes)
+ {
+ minX = Math.Min(minX, n.X);
+ minY = Math.Min(minY, n.Y);
+ maxX = Math.Max(maxX, n.X + Math.Max(1, n.Width));
+ maxY = Math.Max(maxY, n.Y + Math.Max(1, n.Height));
+ }
+
+ bounds = new CanvasSelectionBounds(minX, minY, maxX, maxY);
+ return true;
+ }
+
+ public static CanvasViewportPoint ComputeCenterPan(
+ CanvasSelectionBounds bounds,
+ CanvasViewportSize viewport,
+ double zoom)
+ {
+ CanvasViewportPoint center = bounds.Center;
+ return new CanvasViewportPoint(
+ viewport.Width / 2.0 - center.X * zoom,
+ viewport.Height / 2.0 - center.Y * zoom
+ );
+ }
+
+ public static (double Zoom, CanvasViewportPoint Pan) ComputeFit(
+ CanvasSelectionBounds bounds,
+ CanvasViewportSize viewport,
+ double padding,
+ double minZoom = 0.15,
+ double maxZoom = 4.0)
+ {
+ double contentW = Math.Max(1, bounds.Width + padding * 2);
+ double contentH = Math.Max(1, bounds.Height + padding * 2);
+
+ double zoomX = viewport.Width / contentW;
+ double zoomY = viewport.Height / contentH;
+ double zoom = Math.Clamp(Math.Min(zoomX, zoomY), minZoom, maxZoom);
+
+ CanvasViewportPoint pan = ComputeCenterPan(bounds, viewport, zoom);
+ return (zoom, pan);
+ }
+}
diff --git a/src/DBWeaver.Canvas/CanvasWireGeometry.cs b/src/AkkornStudio.Canvas/CanvasWireGeometry.cs
similarity index 90%
rename from src/DBWeaver.Canvas/CanvasWireGeometry.cs
rename to src/AkkornStudio.Canvas/CanvasWireGeometry.cs
index 066fe8b8..34f234bd 100644
--- a/src/DBWeaver.Canvas/CanvasWireGeometry.cs
+++ b/src/AkkornStudio.Canvas/CanvasWireGeometry.cs
@@ -1,17 +1,17 @@
-namespace DBWeaver.CanvasKit;
-
-using System.Globalization;
-
-public static class CanvasWireGeometry
-{
- public static string BuildBezierPath(double fromX, double fromY, double toX, double toY)
- {
- double dx = Math.Abs(toX - fromX);
- double offset = Math.Max(60, dx * 0.5);
-
- return string.Create(
- CultureInfo.InvariantCulture,
- $"M {fromX:F1},{fromY:F1} C {fromX + offset:F1},{fromY:F1} {toX - offset:F1},{toY:F1} {toX:F1},{toY:F1}"
- );
- }
-}
+namespace AkkornStudio.CanvasKit;
+
+using System.Globalization;
+
+public static class CanvasWireGeometry
+{
+ public static string BuildBezierPath(double fromX, double fromY, double toX, double toY)
+ {
+ double dx = Math.Abs(toX - fromX);
+ double offset = Math.Max(60, dx * 0.5);
+
+ return string.Create(
+ CultureInfo.InvariantCulture,
+ $"M {fromX:F1},{fromY:F1} C {fromX + offset:F1},{fromY:F1} {toX - offset:F1},{toY:F1} {toX:F1},{toY:F1}"
+ );
+ }
+}
diff --git a/src/DBWeaver.Canvas/CanvasWireStylePolicy.cs b/src/AkkornStudio.Canvas/CanvasWireStylePolicy.cs
similarity index 88%
rename from src/DBWeaver.Canvas/CanvasWireStylePolicy.cs
rename to src/AkkornStudio.Canvas/CanvasWireStylePolicy.cs
index 480a6e61..04b3f942 100644
--- a/src/DBWeaver.Canvas/CanvasWireStylePolicy.cs
+++ b/src/AkkornStudio.Canvas/CanvasWireStylePolicy.cs
@@ -1,20 +1,20 @@
-namespace DBWeaver.CanvasKit;
-
-public enum CanvasWireDashKind
-{
- Solid,
- ShortDash,
- MediumDash,
- LongDash,
- WideDash,
- Dotted,
-}
-
-public static class CanvasWireStylePolicy
-{
- public static double ResolveThickness(
- double baseThickness,
- bool isHighlighted,
- double highlightBoost = 0.7
- ) => isHighlighted ? baseThickness + highlightBoost : baseThickness;
-}
+namespace AkkornStudio.CanvasKit;
+
+public enum CanvasWireDashKind
+{
+ Solid,
+ ShortDash,
+ MediumDash,
+ LongDash,
+ WideDash,
+ Dotted,
+}
+
+public static class CanvasWireStylePolicy
+{
+ public static double ResolveThickness(
+ double baseThickness,
+ bool isHighlighted,
+ double highlightBoost = 0.7
+ ) => isHighlighted ? baseThickness + highlightBoost : baseThickness;
+}
diff --git a/src/DBWeaver.UI/.gitignore b/src/AkkornStudio.UI/.gitignore
similarity index 100%
rename from src/DBWeaver.UI/.gitignore
rename to src/AkkornStudio.UI/.gitignore
diff --git a/src/DBWeaver.UI/DBWeaver.UI.csproj b/src/AkkornStudio.UI/AkkornStudio.UI.csproj
similarity index 88%
rename from src/DBWeaver.UI/DBWeaver.UI.csproj
rename to src/AkkornStudio.UI/AkkornStudio.UI.csproj
index bf02a673..7ac34b02 100644
--- a/src/DBWeaver.UI/DBWeaver.UI.csproj
+++ b/src/AkkornStudio.UI/AkkornStudio.UI.csproj
@@ -1,69 +1,71 @@
-
-
- WinExe
- DBWeaver.UI
- DBWeaver.UI
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PreserveNewest
- PreserveNewest
-
-
- PreserveNewest
- PreserveNewest
-
-
-
-
-
+
+
+ WinExe
+ AkkornStudio.UI
+ AkkornStudio.UI
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ PreserveNewest
+
+
+ PreserveNewest
+ PreserveNewest
+
+
+
+
+
diff --git a/src/DBWeaver.UI/DBWeaver.UI.sln b/src/AkkornStudio.UI/AkkornStudio.UI.sln
similarity index 87%
rename from src/DBWeaver.UI/DBWeaver.UI.sln
rename to src/AkkornStudio.UI/AkkornStudio.UI.sln
index 071af49f..f908a951 100644
--- a/src/DBWeaver.UI/DBWeaver.UI.sln
+++ b/src/AkkornStudio.UI/AkkornStudio.UI.sln
@@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBWeaver.UI", "DBWeaver.UI.csproj", "{F8B2CBCC-CEEE-903A-A800-7E1ACB0C4291}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AkkornStudio.UI", "AkkornStudio.UI.csproj", "{F8B2CBCC-CEEE-903A-A800-7E1ACB0C4291}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/src/DBWeaver.UI/App.axaml b/src/AkkornStudio.UI/App.axaml
similarity index 89%
rename from src/DBWeaver.UI/App.axaml
rename to src/AkkornStudio.UI/App.axaml
index f1494caf..bfdab645 100644
--- a/src/DBWeaver.UI/App.axaml
+++ b/src/AkkornStudio.UI/App.axaml
@@ -1,17 +1,17 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
@@ -53,22 +53,22 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/App.axaml.cs b/src/AkkornStudio.UI/App.axaml.cs
similarity index 91%
rename from src/DBWeaver.UI/App.axaml.cs
rename to src/AkkornStudio.UI/App.axaml.cs
index 402e8920..2417446c 100644
--- a/src/DBWeaver.UI/App.axaml.cs
+++ b/src/AkkornStudio.UI/App.axaml.cs
@@ -1,140 +1,140 @@
-using Avalonia;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Markup.Xaml;
-using Avalonia.Styling;
-using DBWeaver.UI.Services.ConnectionManager;
-using DBWeaver.UI.Services.ConnectionManager.Contracts;
-using DBWeaver.UI.Services.Localization;
-using DBWeaver.UI.Services.Modal;
-using DBWeaver.UI.Services.Settings;
-using DBWeaver.UI.Services.Theming;
-using DBWeaver.UI.ViewModels.Validation.Conventions;
-using DBWeaver.UI.ViewModels.Validation.Conventions.Implementations;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
-
-namespace DBWeaver.UI;
-
-public partial class App : Application
-{
- private static readonly ILogger _logger = NullLogger.Instance;
- private IServiceProvider? _services;
-
- public override void Initialize() => AvaloniaXamlLoader.Load(this);
-
- public override void OnFrameworkInitializationCompleted()
- {
- ApplySavedThemeVariant();
- ApplyUserThemeIfPresent();
-
- _services = BuildServices();
-
- if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- desktop.MainWindow = _services.GetRequiredService();
-
- base.OnFrameworkInitializationCompleted();
- }
-
- private static IServiceProvider BuildServices()
- {
- var services = new ServiceCollection();
-
- services.AddSingleton(_ => NullLoggerFactory.Instance);
- services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>));
- services.AddDBWeaver();
- services.AddSingleton(_ => LocalizationService.Instance);
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton(sp =>
- new FireAndForgetSafetyExecutor(sp.GetRequiredService>()));
- services.AddSingleton(sp =>
- new ConnectionHealthLifecycleCoordinator(sp.GetRequiredService()));
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton(_ => GlobalModalManager.Instance);
- services.AddSingleton();
- services.AddTransient();
- services.AddTransient();
-
- return services.BuildServiceProvider();
- }
-
- private static void ApplySavedThemeVariant()
- {
- if (Application.Current is null)
- return;
-
- AppSettings settings = AppSettingsStore.Load();
- Application.Current.RequestedThemeVariant =
- settings.ThemeVariant.Equals("Light", StringComparison.OrdinalIgnoreCase)
- ? ThemeVariant.Light
- : ThemeVariant.Dark;
- }
-
- private static void ApplyUserThemeIfPresent()
- {
- string path = ThemeLoader.GetDefaultThemePath();
- ThemeLoadResult load = ThemeLoader.LoadFromPath(path);
- if (load.Status == ThemeLoadStatus.NotFound)
- return;
-
- if (load.Status != ThemeLoadStatus.Loaded || load.Config is null)
- {
- _logger.LogWarning("Theme fallback: {Status} - {Message}", load.Status, load.Message);
- return;
- }
-
- ThemeValidationResult validation = ThemeValidator.Validate(load.Config);
- foreach (string error in validation.Errors)
- _logger.LogError("Theme validation error: {Error}", error);
- foreach (string warning in validation.Warnings)
- _logger.LogWarning("Theme validation warning: {Warning}", warning);
-
- if (!validation.IsValid)
- {
- _logger.LogWarning("Theme fallback: invalid configuration");
- return;
- }
-
- ThemeTokenMapResult mapped = ThemeTokenMapper.Map(load.Config);
- foreach (string warning in mapped.Warnings)
- _logger.LogWarning("Theme mapping warning: {Warning}", warning);
-
- int applied = ThemeRuntimeApplier.ApplyToCurrentApplication(mapped.TokenOverrides);
- _logger.LogInformation("Theme loaded: applied {AppliedCount} token override(s) from {Path}", applied, path);
- }
-}
-
-// ── Program entry point ───────────────────────────────────────────────────────
-
-internal static class Program
-{
- [STAThread]
- public static void Main(string[] args) =>
- BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
-
- public static AppBuilder BuildAvaloniaApp() =>
- AppBuilder
- .Configure()
- .UsePlatformDetect()
- .LogToTrace();
-}
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+using Avalonia.Styling;
+using AkkornStudio.UI.Services.ConnectionManager;
+using AkkornStudio.UI.Services.ConnectionManager.Contracts;
+using AkkornStudio.UI.Services.Localization;
+using AkkornStudio.UI.Services.Modal;
+using AkkornStudio.UI.Services.Settings;
+using AkkornStudio.UI.Services.Theming;
+using AkkornStudio.UI.ViewModels.Validation.Conventions;
+using AkkornStudio.UI.ViewModels.Validation.Conventions.Implementations;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+
+namespace AkkornStudio.UI;
+
+public partial class App : Application
+{
+ private static readonly ILogger _logger = NullLogger.Instance;
+ private IServiceProvider? _services;
+
+ public override void Initialize() => AvaloniaXamlLoader.Load(this);
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ ApplySavedThemeVariant();
+ ApplyUserThemeIfPresent();
+
+ _services = BuildServices();
+
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ desktop.MainWindow = _services.GetRequiredService();
+
+ base.OnFrameworkInitializationCompleted();
+ }
+
+ private static IServiceProvider BuildServices()
+ {
+ var services = new ServiceCollection();
+
+ services.AddSingleton(_ => NullLoggerFactory.Instance);
+ services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>));
+ services.AddAkkornStudio();
+ services.AddSingleton(_ => LocalizationService.Instance);
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton(sp =>
+ new FireAndForgetSafetyExecutor(sp.GetRequiredService>()));
+ services.AddSingleton(sp =>
+ new ConnectionHealthLifecycleCoordinator(sp.GetRequiredService()));
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton(_ => GlobalModalManager.Instance);
+ services.AddSingleton();
+ services.AddTransient();
+ services.AddTransient();
+
+ return services.BuildServiceProvider();
+ }
+
+ private static void ApplySavedThemeVariant()
+ {
+ if (Application.Current is null)
+ return;
+
+ AppSettings settings = AppSettingsStore.Load();
+ Application.Current.RequestedThemeVariant =
+ settings.ThemeVariant.Equals("Light", StringComparison.OrdinalIgnoreCase)
+ ? ThemeVariant.Light
+ : ThemeVariant.Dark;
+ }
+
+ private static void ApplyUserThemeIfPresent()
+ {
+ string path = ThemeLoader.GetDefaultThemePath();
+ ThemeLoadResult load = ThemeLoader.LoadFromPath(path);
+ if (load.Status == ThemeLoadStatus.NotFound)
+ return;
+
+ if (load.Status != ThemeLoadStatus.Loaded || load.Config is null)
+ {
+ _logger.LogWarning("Theme fallback: {Status} - {Message}", load.Status, load.Message);
+ return;
+ }
+
+ ThemeValidationResult validation = ThemeValidator.Validate(load.Config);
+ foreach (string error in validation.Errors)
+ _logger.LogError("Theme validation error: {Error}", error);
+ foreach (string warning in validation.Warnings)
+ _logger.LogWarning("Theme validation warning: {Warning}", warning);
+
+ if (!validation.IsValid)
+ {
+ _logger.LogWarning("Theme fallback: invalid configuration");
+ return;
+ }
+
+ ThemeTokenMapResult mapped = ThemeTokenMapper.Map(load.Config);
+ foreach (string warning in mapped.Warnings)
+ _logger.LogWarning("Theme mapping warning: {Warning}", warning);
+
+ int applied = ThemeRuntimeApplier.ApplyToCurrentApplication(mapped.TokenOverrides);
+ _logger.LogInformation("Theme loaded: applied {AppliedCount} token override(s) from {Path}", applied, path);
+ }
+}
+
+// ── Program entry point ───────────────────────────────────────────────────────
+
+internal static class Program
+{
+ [STAThread]
+ public static void Main(string[] args) =>
+ BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
+
+ public static AppBuilder BuildAvaloniaApp() =>
+ AppBuilder
+ .Configure()
+ .UsePlatformDetect()
+ .LogToTrace();
+}
diff --git a/src/DBWeaver.UI/AppConstants.cs b/src/AkkornStudio.UI/AppConstants.cs
similarity index 93%
rename from src/DBWeaver.UI/AppConstants.cs
rename to src/AkkornStudio.UI/AppConstants.cs
index eaa90752..802a8d2e 100644
--- a/src/DBWeaver.UI/AppConstants.cs
+++ b/src/AkkornStudio.UI/AppConstants.cs
@@ -1,58 +1,58 @@
-namespace DBWeaver.UI;
-
-///
-/// Application-wide constants and default values.
-/// Centralises configuration that was previously spread across multiple view models and services.
-///
-public static class AppConstants
-{
- // ── App ──────────────────────────────────────────────────────────────────
-
- /// Internal app name used in storage paths.
- public const string AppName = "DBWeaver";
-
- /// Display name shown in window titles and UI labels.
- public const string AppDisplayName = "DBWeaver";
-
- /// Base directory under AppData for local app persistence.
- public static string AppDataDirectory => Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
- AppName
- );
-
- /// Application version embedded in saved canvas files.
- public const string AppVersion = "1.0.0";
-
- // ── Connection defaults ───────────────────────────────────────────────────
-
- /// Default hostname shown in new and reset connection profiles.
- public const string DefaultHost = "localhost";
-
- /// Seconds between background connection health-check pings.
- public const int HealthCheckIntervalSeconds = 60;
-
- // ── SQL import ────────────────────────────────────────────────────────────
-
- /// Maximum characters accepted in the SQL import text box.
- public const int DefaultMaxSqlInputLength = 50_000;
-
- /// Default timeout for a single SQL import operation.
- public static readonly TimeSpan DefaultImportTimeout = TimeSpan.FromSeconds(10);
-
- ///
- /// Milliseconds to yield to the UI thread before starting heavy SQL import work,
- /// allowing the "Importing…" indicator to render before the CPU-bound parse begins.
- ///
- public const int DefaultImportStartDelayMs = 80;
-
- // ── UI timing ─────────────────────────────────────────────────────────────
-
- ///
- /// Milliseconds to wait after the last query-graph change before triggering a
- /// live SQL preview refresh (debounce window).
- ///
- public const int PreviewDebounceMs = 500;
-
- /// Milliseconds debounce before re-running canvas validation.
- public const int ValidationDebounceMs = 200;
-}
+namespace AkkornStudio.UI;
+
+///
+/// Application-wide constants and default values.
+/// Centralises configuration that was previously spread across multiple view models and services.
+///
+public static class AppConstants
+{
+ // ── App ──────────────────────────────────────────────────────────────────
+
+ /// Internal app name used in storage paths.
+ public const string AppName = "AkkornStudio";
+
+ /// Display name shown in window titles and UI labels.
+ public const string AppDisplayName = "AkkornStudio";
+
+ /// Base directory under AppData for local app persistence.
+ public static string AppDataDirectory => Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
+ AppName
+ );
+
+ /// Application version embedded in saved canvas files.
+ public const string AppVersion = "1.0.0";
+
+ // ── Connection defaults ───────────────────────────────────────────────────
+
+ /// Default hostname shown in new and reset connection profiles.
+ public const string DefaultHost = "localhost";
+
+ /// Seconds between background connection health-check pings.
+ public const int HealthCheckIntervalSeconds = 60;
+
+ // ── SQL import ────────────────────────────────────────────────────────────
+
+ /// Maximum characters accepted in the SQL import text box.
+ public const int DefaultMaxSqlInputLength = 50_000;
+
+ /// Default timeout for a single SQL import operation.
+ public static readonly TimeSpan DefaultImportTimeout = TimeSpan.FromSeconds(10);
+
+ ///
+ /// Milliseconds to yield to the UI thread before starting heavy SQL import work,
+ /// allowing the "Importing…" indicator to render before the CPU-bound parse begins.
+ ///
+ public const int DefaultImportStartDelayMs = 80;
+
+ // ── UI timing ─────────────────────────────────────────────────────────────
+
+ ///
+ /// Milliseconds to wait after the last query-graph change before triggering a
+ /// live SQL preview refresh (debounce window).
+ ///
+ public const int PreviewDebounceMs = 500;
+
+ /// Milliseconds debounce before re-running canvas validation.
+ public const int ValidationDebounceMs = 200;
+}
diff --git a/src/DBWeaver.UI/Assets/Localization/en-US.json b/src/AkkornStudio.UI/Assets/Localization/en-US.json
similarity index 98%
rename from src/DBWeaver.UI/Assets/Localization/en-US.json
rename to src/AkkornStudio.UI/Assets/Localization/en-US.json
index 7e2041cf..11318a0e 100644
--- a/src/DBWeaver.UI/Assets/Localization/en-US.json
+++ b/src/AkkornStudio.UI/Assets/Localization/en-US.json
@@ -1,1151 +1,1151 @@
-{
- "main.brand": "DBWeaver",
- "main.tab.query1": "Query 1",
- "main.new": "New",
- "main.open": "Open",
- "main.save": "Save",
- "main.history": "History",
- "main.layout": "Layout",
- "main.preview": "Preview",
- "main.undo": "Undo",
- "main.redo": "Redo",
- "main.cleanupOrphans": "Cleanup orphan nodes",
- "main.autoFixAliasNaming": "Auto-fix alias naming",
- "main.autoLayoutCanvas": "Auto layout canvas",
- "main.toggleDataPreview": "Toggle data preview",
- "main.language": "Language",
- "main.restore.prompt": "Previous session found — restore the last canvas?",
- "main.restore.button": "Restore session",
- "main.cteEditor.editingPrefix": "Editing CTE: ",
- "main.cteEditor.backToCanvas": "Back to Canvas",
- "main.cteEditor.exitA11y": "Exit CTE editor",
- "main.viewEditor.editingPrefix": "DDL > View: ",
- "main.viewEditor.backToCanvas": "Back to DDL",
- "main.viewEditor.exitA11y": "Exit view editor",
- "connection.title": "Connection Manager",
- "connection.subtitle": "Configure, test, and activate connections without leaving your flow",
- "connection.none": "No connection",
- "connection.active": "ACTIVE",
- "connection.health.online": "Online",
- "connection.health.degraded": "Degraded",
- "connection.health.offline": "Offline",
- "connection.tooltip.none": "No active connection — click to manage",
- "connection.ping": "Ping",
- "connection.saved": "SAVED CONNECTIONS",
- "connection.new": "New Connection",
- "connection.selectOrCreate": "Select a connection or create a new one",
- "connection.name": "Connection Name",
- "connection.provider": "Provider",
- "connection.host": "Host",
- "connection.port": "Port",
- "connection.database": "Database",
- "connection.sqlitePath": "SQLite Path",
- "connection.sqliteBrowse": "Browse",
- "connection.sqliteCreate": "Create",
- "connection.username": "Username",
- "connection.password": "Password",
- "connection.timeout": "Timeout (seconds)",
- "connection.test": "Test",
- "connection.save": "Save",
- "connection.connect": "Connect",
- "connection.action.testConnection": "Test connection",
- "connection.action.saveConnection": "Save connection",
- "connection.action.connectConnection": "Connect connection",
- "connection.status.connecting": "Connecting...",
- "connection.status.connected": "Connected",
- "connection.status.testing": "Testing...",
- "connection.status.failedPrefix": "Connection failed",
- "connection.status.metadataUnavailable": "Connection failed: metadata not available.",
- "connection.status.highLatency": "high latency",
- "connection.watermark.name": "My Production DB",
- "connection.watermark.host": "localhost",
- "connection.watermark.port": "5432",
- "connection.watermark.database": "database_name",
- "connection.watermark.username": "user",
- "connection.watermark.password": "••••••••",
- "connection.watermark.timeout": "30",
- "main.connectingDb": "Connecting to database...",
- "main.emptyHint": "Press ⇧A to add your first node, or drag a table from the sidebar",
- "status.nodesSeparator": " nodes · ",
- "status.connectionsSuffix": " connections",
- "status.undo": "Undo: ",
- "status.shortcuts": "⇧A Nodes · F3 Preview · Ctrl+Z Undo · Del Remove · Alt+Drag Pan",
- "connection.disconnect": "Disconnect",
- "connection.action.disconnectConnection": "Disconnect connection",
- "connectionTab.active": "ACTIVE CONNECTION",
- "connectionTab.none": "No active connection",
- "connectionTab.saved": "SAVED CONNECTIONS",
- "connectionTab.new": "+ New Connection",
- "schema.database": "DATABASE",
- "schema.search": "Search tables, columns...",
- "schema.loading": "Searching tables, columns...",
- "schema.noConnection": "No Connection",
- "schema.noConnectionHint": "Connect to a database to see tables, columns, and relationships",
- "schema.emptyNoTables": "No tables found",
- "fileHistory.title": "Save/Load Version History",
- "fileHistory.reload": "Reload",
- "fileHistory.restoreSelected": "Restore selected",
- "fileHistory.empty": "No local versions yet",
- "fileHistory.emptyHint": "Save this file to generate version history.",
- "preview.title": "Data Preview",
- "preview.subtitle": "Review data and diagnostics before continuing",
- "preview.run": "Run",
- "preview.cancel": "Cancel",
- "preview.tab.preview": "Preview",
- "preview.tab.sql": "SQL",
- "preview.close": "Close preview",
- "preview.running": "Running preview query… ",
- "preview.clickCancel": "Click Cancel to stop",
- "preview.cancelled": "Query cancelled",
- "preview.runAgain": "Press Run to execute again",
- "preview.failed": "Preview execution failed",
- "preview.technical": "TECHNICAL DETAILS",
- "preview.noData": "No data yet",
- "preview.f3Hint": "Press F3 or Space to run the current query",
- "sqlImporter.title": "Import SQL to Graph",
- "sqlImporter.subtitle": "Paste a SELECT statement — nodes are created automatically",
- "sqlImporter.sqlStatement": "SQL STATEMENT",
- "sqlImporter.supported": "Supported: ",
- "sqlImporter.import": "Import",
- "sqlImporter.report": "CONVERSION REPORT",
- "sqlEditor.mutation.dialogTitle": "Mutation confirmation",
- "sqlEditor.mutation.dialogSubtitle": "Review impact before confirming execution",
- "search.empty": "No nodes found",
- "search.emptyHint": "Try searching for UPPER, JSON, CAST, AND…",
- "search.shortcut": "⇧A",
- "search.spawn": "Spawn",
- "commandPalette.empty": "No commands match your search",
- "commandPalette.search": "Command search",
- "commandPalette.shortcut": "CTRL+SHIFT+P",
- "commandPalette.execute": "Execute",
- "context.editCte": "Edit Selected CTE",
- "context.editViewSubcanvas": "Edit View Subcanvas",
- "explain.title": "Explain Plan",
- "explain.sql": "SQL",
- "explain.option.analyze": "Analyze",
- "explain.option.buffers": "Buffers",
- "explain.badge.simulated": "SIMULATED",
- "explain.timing.planning": "Planning:",
- "explain.timing.execution": "Execution:",
- "explain.section.snapshotComparison": "Snapshot comparison",
- "explain.section.indexRecommendations": "Index recommendations",
- "explain.section.history": "History",
- "explain.detail.estimated": "Estimated",
- "explain.detail.actual": "Actual",
- "explain.detail.error": "Error",
- "explain.detail.time": "Time",
- "explain.detail.loops": "Loops",
- "explain.rerun": "Re-run",
- "explain.alertSuffix": " expensive operation(s) detected — consider adding indexes",
- "explain.running": "Running EXPLAIN…",
- "explain.failed": "⚠ EXPLAIN failed",
- "explain.noPlan": "No plan yet",
- "explain.rerunHint": "Press Re-run to execute EXPLAIN",
- "explain.header.operation": "OPERATION",
- "explain.header.cost": "COST",
- "explain.header.rows": "ROWS",
- "explain.header.err": "ERR",
- "explain.header.alert": "ALERT",
- "explain.snapshot.labelA": "A",
- "explain.snapshot.labelB": "B",
- "explain.mode.list": "List",
- "explain.mode.tree": "Tree",
- "explain.action.snapshot": "Save snapshot",
- "explain.action.copyJson": "Copy JSON",
- "explain.action.copyText": "Copy text",
- "explain.action.saveJson": "Save .json",
- "explain.action.openDalibo": "Open in Dalibo",
- "explain.legend.seqscan": "SEQ SCAN — full table read, no index",
- "explain.legend.sort": "SORT — in-memory sort",
- "explain.legend.hash": "HASH — hash join",
- "explain.escClose": "Esc to close",
- "flowVersion.title": "Flow Version History",
- "flowVersion.subtitle": "Create checkpoints, compare versions and restore",
- "flowVersion.watermark": "Checkpoint label (optional)…",
- "flowVersion.saveCheckpoint": "Save Checkpoint",
- "flowVersion.compareMode": "Compare Mode",
- "flowVersion.selectBase": "Select BASE version (from):",
- "flowVersion.clickAny": "Then click any version in the list below to compare.",
- "flowVersion.noCheckpoints": "No checkpoints yet",
- "flowVersion.noCheckpointsHint": "Save a checkpoint above to begin tracking versions.",
- "flowVersion.restore": "Restore",
- "flowVersion.diffResults": "Diff Results",
- "benchmark.title": "Query Benchmark",
- "benchmark.subtitle": "Measures avg / median / p95 latency over N iterations",
- "benchmark.sql": "SQL being benchmarked",
- "benchmark.runLabel": "Run label",
- "benchmark.runLabelWatermark": "Run 1",
- "benchmark.iterations": "Iterations (1–100)",
- "benchmark.warmup": "Warm-up passes (0–10)",
- "benchmark.interval": "Interval between runs (ms)",
- "benchmark.run": "Run Benchmark",
- "benchmark.cancel": "Cancel",
- "benchmark.clearHistory": "Clear History",
- "benchmark.latest": "LATEST RESULT",
- "benchmark.avg": "AVG",
- "benchmark.median": "MEDIAN",
- "benchmark.min": "MIN",
- "benchmark.max": "MAX",
- "benchmark.iterationsAt": " iterations · run at ",
- "benchmark.history": "HISTORY",
- "benchmark.header.label": "Label",
- "benchmark.header.avg": "Avg",
- "benchmark.header.median": "Median",
- "benchmark.header.min": "Min",
- "benchmark.header.max": "Max",
- "benchmark.itersSuffix": " iters",
- "diagnostics.title": "App Diagnostics",
- "diagnostics.run": "Run",
- "diagnostics.running": "Running checks…",
- "diagnostics.ok": "OK",
- "diagnostics.warning": "Warning",
- "diagnostics.error": "Error",
- "diagnostics.tooltip.rerun": "Re-run all checks",
- "diagnostics.tooltip.copy": "Copy diagnostic report to clipboard",
- "diagnostics.tooltip.close": "Close (Esc)",
- "autoJoin.title": "Auto-Join Suggestions",
- "autoJoin.titleForTable": "Auto-Join suggestions for {0}",
- "autoJoin.acceptAll": "Accept All",
- "autoJoin.accept": "Accept",
- "autoJoin.skip": "Skip",
- "autoJoin.allHandled": "All suggestions handled",
- "autoJoin.joinKeyword": "JOIN",
- "autoJoin.confidence.fkConstraint": "FK Constraint",
- "autoJoin.confidence.fkReverse": "FK (Reverse)",
- "autoJoin.confidence.namingMatch": "Naming Match",
- "autoJoin.confidence.weakMatch": "Weak Match",
- "autoJoin.runSelected": "Auto-Join Selected",
- "autoJoin.noSimilarityTitle": "No automatic join found",
- "autoJoin.noSimilarityDetails": "Choose the columns manually to create a simple join.",
- "autoJoin.appliedTitle": "Auto-join applied",
- "autoJoin.manual.title": "Create Manual Join",
- "autoJoin.manual.subtitle": "No reliable similarity was found. Select one column from each table.",
- "autoJoin.manual.leftColumn": "Left column",
- "autoJoin.manual.rightColumn": "Right column",
- "autoJoin.manual.joinType": "Join type",
- "autoJoin.manual.operator": "Operator",
- "autoJoin.manual.confirm": "Create join",
- "autoJoin.manual.noCompatible": "No compatible columns for the selected left pin type.",
- "autoJoin.manualJoinCreatedTitle": "Manual join created",
- "autoJoin.manualJoinFailedTitle": "Manual join could not be created",
- "autoJoin.manualJoinFailedDetails": "Check selected columns and existing joins, then try again.",
- "autoJoin.multipleCandidatesTitle": "Multiple join candidates found",
- "autoJoin.multipleCandidatesDetails": "{0} possible combinations were found. Confirm which columns should be used.",
- "autoJoin.suggestionsFoundTitle": "Auto-join suggestions available",
- "autoJoin.suggestionsFoundDetails": "{0} suggestion(s) found. Select two tables and run Auto-Join Selected.",
- "property.outputAlias": "OUTPUT ALIAS",
- "property.sourceAlias": "SOURCE ALIAS",
- "property.aliasWatermark": "e.g. MyColumn (optional)",
- "property.parameters": "PARAMETERS",
- "property.enabled": "Enabled",
- "property.datetimeWatermark": "YYYY-MM-DDTHH:mm:ss or leave empty",
- "property.dateWatermark": "YYYY-MM-DD or leave empty",
- "property.apply": "Apply",
- "property.inputPins": "INPUT PINS",
- "property.outputPins": "OUTPUT PINS",
- "property.sqlTrace": "SQL TRACE",
- "property.live": "live",
- "node.numericValue": "Numeric Value",
- "node.stringValue": "String Value",
- "node.enterText": "Enter text",
- "node.datetimeValue": "DateTime Value",
- "node.valueLabel": "Value:",
- "node.noInputs": "No inputs",
- "node.loadingSample": "Loading sample…",
- "node.previewFailed": "⚠ Preview failed",
- "node.sampleRowsHint": "5 sample rows · demo data",
- "sidebar.tab.nodes": "Nodes",
- "sidebar.tab.connection": "Connection",
- "sidebar.tab.schema": "Schema",
- "sidebar.tab.diagnostics": "Diagnostics",
- "sidebar.addNode": "+ Add Node (⇧A)",
- "sidebar.previewF3": "Preview (F3)",
- "nodesList.search": "Search nodes...",
- "search.watermark": "Search nodes… (Esc to close)",
- "search.snippets": "★ SNIPPETS",
- "commandPalette.watermark": "Run a command… (Esc to close)",
- "tooltip.newCanvas": "New canvas (Ctrl+N)",
- "tooltip.openCanvas": "Open canvas (Ctrl+O)",
- "tooltip.saveCanvas": "Save canvas (Ctrl+S)",
- "tooltip.fileHistory": "Local save/load history (Ctrl+Alt+H)",
- "tooltip.zoomOut": "Zoom out (Ctrl+-)",
- "tooltip.zoomIn": "Zoom in (Ctrl++)",
- "tooltip.fitToScreen": "Fit to screen (Ctrl+0)",
- "tooltip.autoLayout": "Auto Layout — arrange nodes into logical columns (Ctrl+L, Ctrl+Z to undo)",
- "tooltip.snapToGrid": "Toggle snap to grid (Ctrl+G)",
- "tooltip.dataPreview": "Data preview (F3)",
- "tooltip.toggleLanguage": "Toggle language (pt-BR / en-US)",
- "tooltip.appDiagnostics": "App Diagnostics (self-check)",
- "tooltip.keyboardShortcuts": "Keyboard shortcuts (F1)",
- "tooltip.cancelRunningQuery": "Cancel the running query",
- "tooltip.closeEsc": "Close (Esc)",
- "tooltip.recheckConnectionHealth": "Re-check connection health",
- "tooltip.deleteConnection": "Delete connection",
- "tooltip.testConnection": "Test connection",
- "tooltip.saveConnection": "Save connection",
- "tooltip.activateConnection": "Activate this connection",
- "tooltip.toggleDataSamplePreview": "Toggle data sample preview",
- "tooltip.liveSqlMutatingBlocked": "This SQL contains a data-mutating command and cannot be run in Safe Preview Mode",
- "tooltip.copySql": "Copy SQL to clipboard",
- "tooltip.formatSql": "Format SQL",
- "tooltip.openBenchmark": "Open Query Benchmark (measure avg / median / p95 latency)",
- "tooltip.openExplainPlan": "Open Explain Plan inspector — visualise the query execution plan",
- "tooltip.switchToQueryMode": "Switch to Query canvas",
- "tooltip.switchToDdlMode": "Switch to DDL canvas",
- "tooltip.switchToSqlMode": "Switch to SQL editor",
- "tooltip.autoJoinSelected": "Try auto-join between the two selected tables",
- "tooltip.pins.inputs": "Inputs",
- "tooltip.pins.outputs": "Outputs",
- "tooltip.pins.none": "None",
- "tooltip.tableColumns": "Columns",
- "tooltip.tableColumns.none": "No detailed columns",
- "window.minimize": "Minimize window",
- "window.maximizeRestore": "Maximize/restore window",
- "window.close": "Close window",
- "menu.newDiagram": "New diagram",
- "menu.openFile": "Open file",
- "menu.save": "Save",
- "menu.fileHistory": "File history",
- "menu.shortcuts": "Keyboard shortcuts",
- "menu.settings": "Settings",
- "menu.group.project": "PROJECT",
- "menu.group.currentMode": "CURRENT MODE",
- "menu.group.tools": "TOOLS",
- "menu.reason.ddlOnly": "Available only in DDL mode.",
- "menu.importSqlQuery": "Import SQL to Query",
- "menu.importDdlSchema": "Import DDL schema",
- "menu.viewDdlSql": "View DDL SQL",
- "menu.executeDdl": "Execute DDL",
- "menu.backToStart": "Back to start",
- "toast.ddlExecuteFailed": "Failed to execute DDL.",
- "toast.ddlOpenFailed": "Failed to open DDL SQL.",
- "toast.ddlImportFailed": "Failed to import schema into DDL.",
- "toast.ddlConnectToImportSchema": "Connect to a database to import schema into the DDL canvas.",
- "toast.ddlNoTablesFound": "No tables found to import in DDL mode.",
- "toast.ddlSchemaImported": "Schema imported into the DDL canvas.",
- "toast.ddlImportSummary": "{0} table(s), {1} column(s), {2} FK(s), {3} unique index(es).",
- "toast.ddlConnectToImportTable": "Connect to a database to import tables into the DDL canvas.",
- "toast.ddlTableAlreadyExists": "Table '{0}' already exists in the DDL canvas.",
- "toast.ddlTableImported": "Table imported into the DDL canvas.",
- "toast.ddlTableImportSummary": "Nodes: +{0}, connections: +{1}, FKs: +{2}.",
- "toast.ddlNoActiveConnection": "No active connection to execute DDL.",
- "toast.ddlExecutedSuccess": "DDL executed successfully.",
- "toast.ddlExecutedWithIssues": "DDL executed with issues.",
- "toast.switchToDdl": "Switch to DDL mode to generate SQL.",
- "toast.ddlInvalid": "Invalid DDL. Fix errors before continuing.",
- "toast.ddlNoStatements": "No DDL statements were generated in the canvas.",
- "toast.previewOpenFailed": "Failed to open preview.",
- "tab.switchFailed": "Failed to switch tab: {0}",
- "settings.status.darkApplied": "Dark theme applied.",
- "settings.status.lightApplied": "Light theme applied.",
- "settings.status.snapUpdated": "Snap updated: {0}.",
- "settings.status.languageToggled": "Language toggled.",
- "settings.status.languageSelected": "Language selected: {0}.",
- "settings.status.themeEditorReady": "Theme editor ready. Apply to save and use this theme.",
- "settings.section.appearance.title": "Themes",
- "settings.section.languageRegion.title": "Language & Region",
- "settings.section.dateTime.title": "Date & Time",
- "settings.section.keyboard.title": "Keyboard Shortcuts",
- "settings.section.privacy.title": "Privacy",
- "settings.section.notification.title": "Notification",
- "settings.section.accessibility.title": "Accessibility",
- "settings.section.default.title": "Settings",
- "settings.section.appearance.subtitle": "Choose your style or customize your theme",
- "settings.section.languageRegion.subtitle": "Manage language and regional formatting",
- "settings.section.keyboard.subtitle": "Customize keyboard shortcuts used by command palette and canvas execution.",
- "settings.section.wip.subtitle": "Work in progress.",
- "settings.section.default.subtitle": "Application settings",
- "settings.general": "General",
- "settings.nav.appearance": "Appearance",
- "settings.theme.light": "Light Mode",
- "settings.theme.dark": "Dark Mode",
- "settings.theme.system": "System Preferences",
- "settings.gridSnap.title": "Grid Snap",
- "settings.gridSnap.subtitle": "Controls node snapping on the canvas.",
- "settings.language.subtitle": "Toggle between PT-BR and EN-US.",
- "settings.language.toggle": "Toggle language",
- "settings.language.option.ptBR": "Portuguese (Brazil)",
- "settings.language.option.enUS": "English (United States)",
- "settings.language.option.esES": "Spanish (Spain)",
- "settings.language.option.ruRU": "Russian",
- "settings.language.option.jaJP": "Japanese",
- "settings.language.option.zhTW": "Traditional Chinese",
- "settings.themeJson.title": "Theme JSON",
- "settings.themeJson.subtitle": "Paste your theme JSON, apply and persist instantly.",
- "settings.themeJson.apply": "Apply JSON",
- "settings.themeJson.restoreDefault": "Restore default theme",
- "mode.query": "Query",
- "mode.ddl": "DDL",
- "mode.sql": "SQL",
- "sidebar.left.close": "Close left sidebar",
- "sidebar.left.open": "Reopen left sidebar",
- "sidebar.right.close": "Close right sidebar",
- "sidebar.right.open": "Reopen right sidebar",
- "connection.completedTitle": "Connection completed",
- "connection.clearCanvasPrompt": "Do you want to clear the current canvas to start with the new connection?",
- "connection.close": "Close connection manager",
- "connection.refreshHealth": "Refresh connection health",
- "common.details": "Details",
- "common.cancel": "Cancel",
- "common.keep": "Keep",
- "common.clear": "Clear",
- "zoom.out": "Zoom out",
- "zoom.in": "Zoom in",
- "zoom.fit": "Fit zoom to screen",
- "zoom.level": "Zoom level",
- "settings.theme.mode": "Theme mode",
- "diagnostics.category.canvas": "Canvas Integrity",
- "diagnostics.category.output": "Output & Execution",
- "diagnostics.category.session": "Session & Safety",
- "diagnostics.category.notice": "Runtime Notices",
- "diagnostics.summary.ok": "All systems OK",
- "diagnostics.summary.warningCount": "{0} warning(s) detected",
- "diagnostics.summary.errorCount": "{0} error(s) detected",
- "diagnostics.canvasMigration": "Canvas Migration",
- "diagnostics.recommendation.resaveFile": "Re-save the file to update it to the latest schema version.",
- "diagnostics.canvasState.name": "Canvas State",
- "diagnostics.canvasState.recommendation": "Add at least one {0} and one {1}",
- "diagnostics.canvasState.empty": "Canvas is empty - no nodes present",
- "diagnostics.canvasState.counts": "{0} node(s), {1} connection(s)",
- "diagnostics.validation.name": "Validation Errors",
- "diagnostics.validation.recommendation": "Fix highlighted nodes before running output preview",
- "diagnostics.validation.errorWithWarnings": "{0} error(s) and {1} warning(s) in the graph",
- "diagnostics.validation.warningOnly": "{0} warning(s) in the graph",
- "diagnostics.validation.none": "No validation issues",
- "diagnostics.orphan.name": "Orphan Nodes",
- "diagnostics.orphan.recommendation": "Use the orphan cleanup action to remove unused nodes",
- "diagnostics.orphan.count": "{0} node(s) not connected to any output",
- "diagnostics.orphan.none": "No orphan nodes detected",
- "diagnostics.naming.name": "Naming Conventions",
- "diagnostics.naming.recommendation": "Use auto-fix alias naming when conformance is below 100%",
- "diagnostics.naming.conformance": "Naming conformance: {0}%",
- "diagnostics.naming.ok": "All aliases follow naming conventions (100%)",
- "diagnostics.queryCompilation.name": "Live SQL Compilation",
- "diagnostics.queryCompilation.recommendation": "Review SQL diagnostics in output when errors/warnings are reported.",
- "diagnostics.queryCompilation.errorFallback": "Live SQL compilation reported errors.",
- "diagnostics.queryCompilation.warningCounts": "{0} diagnostic item(s), {1} guardrail warning(s).",
- "diagnostics.queryCompilation.ok": "Live SQL compiled without diagnostics.",
- "diagnostics.previewSafety.name": "Preview Safety",
- "diagnostics.previewSafety.recommendation": "Preview executes read-only statements only.",
- "diagnostics.previewSafety.blocked": "Current SQL is mutating and blocked by Safe Preview mode.",
- "diagnostics.previewSafety.ok": "Preview safety checks passed.",
- "diagnostics.previewExecution.name": "Preview Execution",
- "diagnostics.previewExecution.recommendation": "Run preview and inspect diagnostics for execution/runtime errors.",
- "diagnostics.previewExecution.failed": "Preview execution failed.",
- "diagnostics.previewExecution.cancelled": "Preview execution was cancelled.",
- "diagnostics.previewExecution.done": "{0} row(s) in {1}ms.",
- "diagnostics.previewExecution.none": "No preview execution issues detected.",
- "diagnostics.ddlCompilation.name": "DDL Compilation",
- "diagnostics.ddlCompilation.recommendation": "Fix DDL compile diagnostics before execution.",
- "diagnostics.ddlCompilation.failed": "DDL compilation failed.",
- "diagnostics.ddlCompilation.warningCount": "{0} warning(s) reported by DDL compiler.",
- "diagnostics.ddlCompilation.ok": "DDL compilation succeeded.",
- "diagnostics.ddlOutput.name": "DDL Output",
- "diagnostics.ddlOutput.recommendation": "Add/complete DDL nodes until at least one statement is generated.",
- "diagnostics.ddlOutput.none": "No DDL statements generated yet.",
- "diagnostics.ddlOutput.lines": "{0} line(s) of DDL generated.",
- "diagnostics.undo.name": "Undo History",
- "diagnostics.undo.recommendation": "History is in-memory only; save your canvas regularly.",
- "diagnostics.undo.saved": "Canvas is saved (no unsaved changes).",
- "diagnostics.undo.unsavedDeep": "Unsaved changes with {0} undo steps.",
- "diagnostics.undo.unsaved": "Unsaved changes - {0} undo step(s) available.",
- "diagnostics.report.title": "DBWeaver - Diagnostic Report",
- "diagnostics.report.generated": "Generated",
- "diagnostics.report.overall": "Overall",
- "diagnostics.report.details": "Details",
- "diagnostics.report.recommendation": "Recommendation",
- "diagnostics.report.lastCheck": "Last Check",
- "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
- "node.datetimeFormat": "YYYY-MM-DDTHH:mm:ss",
- "preview.providerLabel": "Provider",
- "preview.ddlDiagnosticsHint": "Error/warning details are available in Diagnostics.",
- "preview.schemaAnalysis.run": "Run Analysis",
- "preview.schemaAnalysis.cancel": "Cancel",
- "preview.schemaAnalysis.issues": "Issues",
- "preview.schemaAnalysis.clearFilters": "Clear Filters",
- "preview.schemaAnalysis.clearBlacklist": "Clear Blacklist",
- "preview.schemaAnalysis.severity": "Severity",
- "preview.schemaAnalysis.severity.info": "Info",
- "preview.schemaAnalysis.severity.warning": "Warning",
- "preview.schemaAnalysis.severity.critical": "Critical",
- "preview.schemaAnalysis.rule": "Rule",
- "preview.schemaAnalysis.rule.fkCatalogInconsistent": "FK catalog inconsistent",
- "preview.schemaAnalysis.rule.missingFk": "Missing FK",
- "preview.schemaAnalysis.rule.namingConventionViolation": "Naming convention violation",
- "preview.schemaAnalysis.rule.lowSemanticName": "Low semantic name",
- "preview.schemaAnalysis.rule.missingRequiredComment": "Missing required comment",
- "preview.schemaAnalysis.rule.nf1HintMultiValued": "1NF hint: multi-valued",
- "preview.schemaAnalysis.rule.nf2HintPartialDependency": "2NF hint: partial dependency",
- "preview.schemaAnalysis.rule.nf3HintTransitiveDependency": "3NF hint: transitive dependency",
- "preview.schemaAnalysis.minConfidence": "Min Confidence",
- "preview.schemaAnalysis.tableFilter": "Table Filter",
- "preview.schemaAnalysis.tableFilterWatermark": "schema.table",
- "preview.schemaAnalysis.ignore": "Execution Filters",
- "preview.schemaAnalysis.ignoreViews": "Ignore views and materialized views",
- "preview.schemaAnalysis.blacklist": "Table blacklist",
- "preview.schemaAnalysis.blacklistAdd": "Add",
- "preview.schemaAnalysis.blacklistRemove": "Remove selected",
- "preview.schemaAnalysis.ignoreTable.placeholder": "schema.table",
- "preview.schemaAnalysis.details": "Details",
- "preview.schemaAnalysis.evidence": "Evidence",
- "preview.schemaAnalysis.suggestions": "Suggestions",
- "preview.schemaAnalysis.ruleDiagnostics": "Rule Diagnostics",
- "preview.schemaAnalysis.sqlCandidates": "SQL Candidates",
- "preview.schemaAnalysis.copySql": "Copy SQL",
- "preview.schemaAnalysis.applyToCanvas": "Apply to Canvas",
- "preview.schemaAnalysis.summary.issues": "Issues:",
- "preview.schemaAnalysis.summary.rawPrefix": "(raw:",
- "preview.schemaAnalysis.summary.critical": "| Critical:",
- "preview.schemaAnalysis.summary.warning": "| Warning:",
- "preview.schemaAnalysis.summary.info": "| Info:",
- "preview.schemaAnalysis.state.metadataUnavailable": "Metadata unavailable for structural analysis.",
- "preview.schemaAnalysis.state.cancelled": "Analysis cancelled by the user.",
- "preview.schemaAnalysis.state.partialTimeout": "Analysis finished partially due to timeout.",
- "preview.schemaAnalysis.state.failed": "Structural analysis failed.",
- "preview.schemaAnalysis.state.empty": "No inferable structural issue was detected.",
- "preview.schemaAnalysis.state.noFilterMatch": "No issue matches the selected filters.",
- "preview.schemaAnalysis.state.noIssueSelected": "No issue selected.",
- "preview.schemaAnalysis.state.noSqlCandidate": "No SQL candidate available.",
- "preview.schemaAnalysis.actionBlockedTooltip": "Action unavailable for the current risk level or capability.",
- "common.navigate": "Navigate",
- "common.close": "Close",
- "common.esc": "Esc",
- "common.ms": "ms",
- "common.zero": "0",
- "diagnostics.tip": "Tip: check Diagnostics whenever preview/output reports warnings or errors.",
- "nodesList.empty": "No nodes found",
- "nodesList.emptyHint": "Adjust the search term to explore available types",
- "schema.emptyFiltered": "No objects found for the current filter",
- "start.lastSnapshot": "Last snapshot",
- "app.brandBadge": "VS",
- "property.tab.properties": "Properties",
- "property.tab.projectSettings": "Project Settings",
- "property.nodeType": "NODE TYPE",
- "property.selectNodeHint": "Select a node to edit its properties.",
- "property.namingConventions": "Naming Conventions",
- "property.aliasConvention": "Alias convention",
- "property.enforceAliasNaming": "Enforce alias naming",
- "property.warnReservedSql": "Warn on reserved SQL keywords",
- "property.maxAliasLength": "Max alias length",
- "property.maxAliasLengthDefault": "64",
- "property.namingSettingsHint": "These settings are project-scoped and are used by naming and validation helpers.",
- "start.tips": "Tips",
- "start.tips.quick": "Quick tips",
- "start.tips.item1": "1. Click New Diagram to start from scratch.",
- "start.tips.item2": "2. Use templates to speed up prototyping.",
- "start.tips.item3": "3. Open saved connections to load real tables.",
- "start.tips.shortcut": "Shortcut: CTRL+SHIFT+P opens the command palette.",
- "start.workspace": "WORKSPACE",
- "start.resumeTitle": "Continue where you left off",
- "start.resumeSubtitle": "Quickly resume a recent project or start a new diagram.",
- "start.chip.quickFlow": "Quick flow",
- "start.chip.templates": "Templates",
- "start.chip.connections": "Connections",
- "start.savedConnectionsTitle": "Saved Connections",
- "start.savedConnectionsSubtitle": "Connect quickly to a database to load schema and tables.",
- "start.noConnectionsTitle": "No connections configured yet",
- "start.noConnectionsSubtitle": "Create a connection to explore real tables in the editor.",
- "start.newConnection": "+ New Connection",
- "start.recentProjectsTitle": "Recent Projects",
- "start.searchRecent": "Search recent project...",
- "start.quickActions": "Quick actions",
- "start.quickActionsSubtitle": "Open an existing file or start a new diagram.",
- "start.noRecentTitle": "No recent projects yet",
- "start.noRecentSubtitle": "Use the quick actions card above to get started.",
- "start.exploreTemplates": "Explore templates",
- "start.templatesFavoritesHint": "Favorites on top",
- "start.favoriteTemplate": "Favorite template",
- "node.columnSetPreview": "ColumnSet preview",
- "node.view": "VIEW",
- "node.tableDefinition": "Table Definition",
- "node.join": "JOIN",
- "node.window.addPartition": "Add PARTITION BY slot",
- "node.window.removePartition": "Remove PARTITION BY slot",
- "node.window.addOrder": "Add ORDER BY slot",
- "node.window.removeOrder": "Remove ORDER BY slot",
- "sql.keyword.select": "SELECT",
- "sql.keyword.from": "FROM",
- "sql.keyword.join": "JOIN",
- "sql.keyword.where": "WHERE",
- "sql.keyword.limit": "LIMIT",
- "sqlImporter.close": "Close SQL importer",
- "sqlImporter.report.imported": "Imported",
- "sqlImporter.report.partial": "Partial",
- "sqlImporter.report.skipped": "Skipped",
- "sqlImporter.confirmClearCanvas": "SQL import will clear the current canvas. Do you want to continue?",
- "sqlImporter.confirmProceed": "Continue import",
- "benchmark.close": "Close benchmark",
- "benchmark.p95": "P95",
- "benchmark.n": "N",
- "liveSql.safePreview": "SAFE PREVIEW MODE",
- "liveSql.title": "LIVE SQL",
- "liveSql.blocked": "BLOCKED",
- "liveSql.copy": "Copy",
- "liveSql.format": "Format",
- "liveSql.benchmark": "Benchmark",
- "liveSql.explain": "Explain",
- "liveSql.actionsHint": "Performance tools",
- "ddl.dialog.title": "Execute DDL",
- "ddl.dialog.execute": "Execute",
- "ddl.dialog.cancel": "Cancel",
- "ddl.dialog.close": "Close",
- "ddl.dialog.stopOnError": "Stop on first failure",
- "ddl.dialog.confirmDestructive": "I confirm execution of destructive statements (DROP TABLE)",
- "ddl.dialog.reviewBeforeRun": "Review the DDL script before confirming.",
- "ddl.dialog.confirmQuestion": "Confirm DDL execution on the connected database?",
- "ddl.dialog.irreversibleWarning": "This action can change the schema irreversibly.",
- "ddl.dialog.mustConfirmDestructive": "Confirm destructive execution to continue.",
- "ddl.dialog.executing": "Executing...",
- "ddl.execute.result.summary": "Statements: {0} | Success: {1} | Failures: {2} | Time: {3:0}ms",
- "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
- "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
- "ddl.execute.result.failed": "Failed to execute DDL.",
- "ddl.execute.result.cancelled": "Execution cancelled by the user.",
- "ddl.execute.result.cancelledDetails": "DDL execution was interrupted before completion.",
- "context.deleteSingle": "Delete {0}",
- "context.deleteMultiple": "Delete {0} nodes",
- "context.bringForward": "Bring Forward (Ctrl+PgUp)",
- "context.sendBackward": "Send Backward (Ctrl+PgDown)",
- "context.bringToFront": "Bring to Front (Ctrl+Shift+PgUp)",
- "context.sendToBack": "Send to Back (Ctrl+Shift+PgDown)",
- "context.normalizeLayers": "Normalize Layers",
- "context.deleteWire": "Delete wire",
- "context.addNode": "Add Node (Shift+A)",
- "context.undoWithDescription": "Undo {0}",
- "context.redo": "Redo",
- "shortcuts.windowTitle": "Keyboard Shortcuts",
- "shortcuts.headerTitle": "DBWeaver - Shortcuts",
- "shortcuts.headerHint": "Tip: use CTRL+SHIFT+P to open the Command Palette and search commands.",
- "shortcuts.filterWatermark": "Filter shortcuts by key or action...",
- "shortcuts.resultCount": "{0} shortcuts",
- "shortcuts.resultFilter": "{0} result(s) for \"{1}\"",
- "shortcuts.noneFound": "No shortcuts found.",
- "shortcuts.section.fileGeneral": "File and General",
- "shortcuts.section.editing": "Editing",
- "shortcuts.section.canvasNavigation": "Canvas and Navigation",
- "shortcuts.section.zoomPanPrecision": "Zoom, pan and precision",
- "shortcuts.section.previewInspection": "Preview and Inspection",
- "shortcuts.key.deleteOrBackspace": "Del or Backspace",
- "shortcuts.key.middleDrag": "Middle mouse + drag",
- "shortcuts.key.rightDrag": "Right mouse + drag",
- "shortcuts.key.spaceDrag": "Space + drag",
- "shortcuts.key.altLeftDrag": "Alt + left drag",
- "shortcuts.key.arrows": "Arrows",
- "shortcuts.key.shiftArrows": "Shift + Arrows",
- "shortcuts.action.openShortcutScreen": "Open this shortcuts screen",
- "shortcuts.action.newCanvas": "New canvas",
- "shortcuts.action.openFile": "Open file",
- "shortcuts.action.save": "Save",
- "shortcuts.action.saveAs": "Save as",
- "shortcuts.action.commandPalette": "Command Palette",
- "shortcuts.action.undo": "Undo",
- "shortcuts.action.redo": "Redo",
- "shortcuts.action.selectAll": "Select all",
- "shortcuts.action.deleteSelection": "Delete selection",
- "shortcuts.action.closeOverlayCancel": "Close overlays / cancel actions",
- "shortcuts.action.openNodeSearch": "Open node search",
- "shortcuts.action.resetViewport": "Reset viewport",
- "shortcuts.action.centerSelection": "Center selection",
- "shortcuts.action.fitSelection": "Fit selection",
- "shortcuts.action.autoLayout": "Auto Layout",
- "shortcuts.action.toggleSnapToGrid": "Toggle Snap to Grid",
- "shortcuts.action.bringForward": "Bring Forward",
- "shortcuts.action.sendBackward": "Send Backward",
- "shortcuts.action.bringToFront": "Bring to Front",
- "shortcuts.action.sendToBack": "Send to Back",
- "shortcuts.action.zoomInOut": "Zoom in / out",
- "shortcuts.action.pan": "Pan",
- "shortcuts.action.temporaryPan": "Temporary pan",
- "shortcuts.action.alternatePan": "Alternate pan",
- "shortcuts.action.fineNudge": "Fine nudge selection",
- "shortcuts.action.fastNudge": "Fast nudge",
- "shortcuts.action.togglePreview": "Toggle data preview",
- "shortcuts.action.explainPlan": "Explain plan",
- "shortcuts.action.runPreview": "Run preview",
- "shortcuts.action.connectionManager": "Connection manager",
- "shortcuts.action.flowVersionHistory": "Flow version history",
- "shortcuts.resetAll": "Reset all",
- "shortcuts.customized": "Customized",
- "shortcuts.default": "Default",
- "shortcuts.apply": "Apply",
- "shortcuts.reset": "Reset",
- "shortcuts.status.resetAllSuccess": "All shortcuts reset to defaults.",
- "shortcuts.status.updated": "Shortcut updated.",
- "shortcuts.status.reset": "Shortcut reset to default.",
- "shortcuts.status.updateFailed": "Unable to update shortcut.",
- "toast.severity.success": "Success",
- "toast.severity.warning": "Warning",
- "toast.severity.error": "Error",
- "toast.details.success": "Success Details",
- "toast.details.warning": "Warning Details",
- "toast.details.error": "Error Details",
- "diagnostics.area.cteEditor": "CTE Editor",
- "diagnostics.area.viewEditor": "View Editor",
- "diagnostics.area.subEditor": "Sub-editor",
- "diagnostics.cteEditor.restoreParentFailed": "Failed to restore the parent canvas. CTE edits were discarded.",
- "diagnostics.recommendation.reloadFileIfNeeded": "Reload the file if needed.",
- "diagnostics.viewEditor.exitFailed": "Could not exit: {0}",
- "diagnostics.viewEditor.canvasIncomplete": "the canvas is incomplete.",
- "diagnostics.viewEditor.exitRecommendation": "Connect a valid ResultOutput or use the discard command.",
- "diagnostics.viewEditor.restoreParentFailed": "Failed to restore the parent canvas. The subgraph was discarded.",
- "diagnostics.subEditor.executeFailed": "Failed to execute editor action: {0}",
- "diagnostics.subEditor.executeRecommendation": "Try again. If it persists, reload the canvas.",
- "diagnostics.canvasMigration.openWarning": "Open: {0}",
- "diagnostics.canvasMigration.sessionRestoreWarning": "Session restore: {0}",
- "diagnostics.canvasMigration.versionRestoreWarning": "Version restore: {0}",
- "diagnostics.recommendation.resaveLatestSchema": "Review diagnostics and re-save the canvas to persist the latest schema.",
- "diagnostics.recommendation.saveMigratedSchema": "Review diagnostics and save the canvas to persist the migrated schema.",
- "file.saveDialog.title": "Save Canvas",
- "file.saveDialog.suggestedName": "Query1",
- "file.save.success": "Canvas saved successfully.",
- "file.save.failedWithReason": "Save failed: {0}",
- "file.openDialog.title": "Open Canvas",
- "file.openDialog.canvasType": "SQL Architect Canvas",
- "file.open.failedWithReason": "Open failed: {0}",
- "file.open.success": "Canvas opened successfully.",
- "file.open.successWithWarnings": "Canvas opened with warnings.",
- "session.restore.failedWithReason": "Restore failed: {0}",
- "session.restore.successWithWarnings": "Session restored with warnings.",
- "session.restore.success": "Session restored successfully.",
- "export.documentation.dialogTitle": "Export Flow Documentation",
- "export.documentation.success": "Documentation exported successfully.",
- "export.documentation.failed": "Documentation export failed.",
- "export.failed.pathPermissionsHint": "Check file path and permissions.",
- "export.nodeNotFound": "No {0} Export node found on the canvas. Add one via the node search menu.",
- "export.dialogTitleByExtension": "Export as {0}",
- "export.success": "Export completed successfully.",
- "export.failed": "Export failed.",
- "fileHistory.currentFile.none": "No file selected",
- "fileHistory.status.saveFirst": "Save the canvas first to enable local history.",
- "fileHistory.status.noneFound": "No local versions found yet. Save this file to create history entries.",
- "fileHistory.status.countAvailable": "{0} local version(s) available.",
- "fileHistory.restore.failedWithReason": "Restore failed: {0}",
- "fileHistory.restore.successFrom": "Restored version from {0}.",
- "preview.status.cancelled": "Cancelled",
- "preview.status.error": "Error",
- "preview.status.ready": "Ready",
- "preview.runningWithMs": "Running... {0}ms",
- "preview.runningWithTimeout": "Running... {0}ms (timeout: {1}s)",
- "preview.runningSlowWithTimeout": "Running... {0}ms (timeout: {1}s) · Slow query, timeout in {2}s",
- "explain.errorWithReason": "Explain plan error: {0}",
- "explain.noSql": "No SQL to explain. Build a query on the canvas first.",
- "ddl.compilationFailed": "Compilation failed",
- "ddl.compileErrorWithReason": "DDL compile error: {0}",
- "command.undo.name": "Undo",
- "command.undo.description": "Undo last action",
- "command.redo.name": "Redo",
- "command.redo.description": "Redo last undone action",
- "command.addNode.name": "Add Node",
- "command.addNode.description": "Open node search menu to add a node",
- "command.bringForward.name": "Bring Forward",
- "command.bringForward.description": "Move selected nodes one layer forward",
- "command.sendBackward.name": "Send Backward",
- "command.sendBackward.description": "Move selected nodes one layer backward",
- "command.bringToFront.name": "Bring to Front",
- "command.bringToFront.description": "Move selected nodes to top layer",
- "command.sendToBack.name": "Send to Back",
- "command.sendToBack.description": "Move selected nodes to bottom layer",
- "command.normalizeLayers.name": "Normalize Layers",
- "command.normalizeLayers.description": "Compact node layer indices to a clean 0..N order",
- "tooltip.cleanupOrphans": "Remove orphan nodes not connected to the output (Ctrl+Z to undo)",
- "main.orphanSuffix": "Orphan(s)",
- "tooltip.autoFixAliasNaming": "Fix alias naming to snake_case (Ctrl+Z to undo)",
- "main.namingPrefix": "Naming",
- "fileHistory.compressedLabel": "Compressed:",
- "schema.itemsSuffix": "item(s)",
- "property.panel.title": "Properties",
- "property.panel.multiSelected": "{0} nodes selected",
- "sqlImporter.status.pasteSelect": "Paste a SELECT statement above, then click Import.",
- "sqlImporter.status.inputTooLarge": "SQL input is too large ({0:N0} chars). Limit is {1:N0}. Split the query or increase the import limit.",
- "sqlImporter.status.parsing": "Parsing SQL...",
- "sqlImporter.status.done": "Done - {0} imported, {1} partial, {2} skipped.",
- "sqlImporter.status.cancelledByUser": "Import cancelled by user.",
- "sqlImporter.status.timeout": "Import timed out after {0:0.#}s. Try a smaller query or increase timeout.",
- "sqlImporter.status.parseError": "Parse error: {0}",
- "sqlImporter.status.clearConfirmationRequired": "SQL import will clear the current canvas. Confirm to continue.",
- "sqlImporter.status.clearConfirmationCancelled": "Import cancelled. The current canvas was kept.",
- "diagnostics.area.undoRedoTransaction": "Undo/Redo Transaction",
- "undoRedo.rollbackExecuted": "Rollback executed for '{0}' ({1} operation(s) reverted).",
- "undoRedo.rollbackRecommendation": "Review the canvas state and retry the action if needed.",
- "node.preview.noCatalog": "No catalog available",
- "connection.error.searchMenuNotInitialized": "search menu not initialized",
- "connection.error.timeoutReachability": "Connection timed out - check that the server is reachable and increase the timeout if needed.",
- "connection.error.authenticationFailedForProvider": "Authentication failed - verify username and password for {0}.",
- "connection.error.databaseNotFoundForProvider": "Database not found - confirm the database name exists on {0}.",
- "connection.error.hostNotFound": "Host not found - check the server address and DNS resolution.",
- "connection.error.portRefused": "Port connection refused - check the port number and that the server is running / firewall rules allow access.",
- "connection.error.sslTls": "SSL/TLS error - check the server's SSL configuration or disable SSL for local connections.",
- "connection.error.timeoutOverloaded": "Connection timed out - the server may be overloaded or unreachable. Try increasing the timeout.",
- "connection.error.insufficientPrivileges": "Insufficient privileges - the user may lack permission to connect to this database.",
- "diagnostics.area.connection": "Connection",
- "connection.warning.canvasMayContainOldTables": "The canvas may still contain tables from a previous connection.",
- "connection.warning.canvasMayContainOldTablesRecommendation": "Clear the canvas manually or reconnect and choose keep/clear again.",
- "undoRedo.transaction.unnamed": "unnamed transaction",
- "benchmark.runLabelDefault": "Run 1",
- "benchmark.runLabelPattern": "Run {0}",
- "benchmark.status.failedWithReason": "Benchmark failed: {0}",
- "benchmark.status.noSql": "No SQL to benchmark - build a query first.",
- "benchmark.status.warmupProgress": "Warm-up {0}/{1}...",
- "benchmark.status.iterationProgress": "Iteration {0}/{1}...",
- "benchmark.status.done": "Done - {0}",
- "benchmark.status.cancelled": "Benchmark cancelled.",
- "app.windowTitle": "DBWeaver",
- "preview.error.safePreviewBlocked": "Safe Preview Mode: data-mutating commands (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) cannot be executed in preview.",
- "preview.error.noActiveConnection": "No active database connection. Please connect to a database first.",
- "sqlImporter.error.selectFromNotFound": "Could not find SELECT ... FROM in the query.",
- "sqlImporter.error.fromClauseParseFailed": "Could not parse FROM clause.",
- "sqlImporter.error.syntaxUnterminatedString": "Syntax error at line {0}, column {1}: unterminated string literal.",
- "sqlImporter.error.missingClosingParenthesis": "missing closing ')'",
- "sqlImporter.error.unexpectedClosingParenthesis": "unexpected ')'",
- "sqlImporter.error.syntaxAtLineColumn": "Syntax error at line {0}, column {1}: {2}.",
- "errorDiagnostics.safePreview.label": "Blocked by Safe Preview Mode",
- "errorDiagnostics.safePreview.friendly": "This SQL contains a data-mutating command and cannot be executed in preview.",
- "errorDiagnostics.safePreview.suggestion": "Remove or replace the mutating command (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) before running preview.",
- "errorDiagnostics.connection.label": "Connection failed",
- "errorDiagnostics.connection.friendly": "Could not reach the database server. The host may be down, unreachable, or blocking connections.",
- "errorDiagnostics.connection.suggestion": "Verify the server address and port, ensure the database is running, and check firewall rules.",
- "errorDiagnostics.authorization.label": "Authorization error",
- "errorDiagnostics.authorization.friendly": "The current credentials do not have permission to perform this operation.",
- "errorDiagnostics.authorization.suggestion": "Confirm the database user has SELECT privileges on the target table/schema, or contact your DBA.",
- "errorDiagnostics.timeout.label": "Query timeout",
- "errorDiagnostics.timeout.friendly": "The query took too long to complete and was cancelled by the server or client.",
- "errorDiagnostics.timeout.suggestion": "Add a WHERE clause or LIMIT to reduce the result set, or increase the query timeout in connection settings.",
- "errorDiagnostics.schema.label": "Schema error",
- "errorDiagnostics.schema.friendly": "A referenced table, column, or object could not be found in the database.",
- "errorDiagnostics.schema.suggestion": "Check that all table/column names are spelled correctly and that the schema matches the active connection.",
- "errorDiagnostics.syntax.label": "SQL syntax error",
- "errorDiagnostics.syntax.friendly": "The query contains a syntax error and could not be parsed by the database engine.",
- "errorDiagnostics.syntax.suggestion": "Review the highlighted SQL for typos, mismatched parentheses, or unsupported clauses for the active provider.",
- "errorDiagnostics.compatibility.label": "Compatibility error",
- "errorDiagnostics.compatibility.friendly": "A function, operator, or syntax construct is not supported by the active database provider.",
- "errorDiagnostics.compatibility.suggestion": "Switch to the correct provider in the SQL bar, or replace the unsupported construct with an equivalent.",
- "errorDiagnostics.unknown.label": "Unexpected error",
- "errorDiagnostics.unknown.friendly": "An error occurred while running the preview query.",
- "errorDiagnostics.unknown.suggestion": "Check the technical details below and verify that your canvas is configured correctly.",
- "error.mainWindow.invalidDataContext": "MainWindow DataContext must be a ShellViewModel.",
- "error.mainWindow.canvasNotInitialized": "CanvasViewModel was not initialized.",
- "error.mainWindow.ddlPreviewUnavailable": "DDL preview is unavailable for the current canvas.",
- "themeJson.editor.template": "{\n \"meta\": { \"name\": \"Custom Theme\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
- "themeJson.error.pasteBeforeApply": "Paste a theme JSON before applying.",
- "themeJson.error.invalidJson": "Invalid JSON: {0}",
- "themeJson.error.emptyPayload": "Invalid JSON: empty payload.",
- "themeJson.error.invalidTheme": "Invalid theme: {0}",
- "themeJson.error.appliedButSaveFailed": "Theme applied, but failed to persist: {0}",
- "themeJson.success.appliedAndSaved": "JSON theme applied and saved.",
- "themeJson.success.customRemoved": "Custom theme removed. Restart the app to fully return to the default theme.",
- "themeJson.error.restoreDefaultFailed": "Failed to restore default theme: {0}",
- "themeValidator.error.configNull": "Theme config is null.",
- "themeValidator.warning.noSections": "Theme has no colors or typography sections; nothing to apply.",
- "themeValidator.warning.invalidColor": "{0} has invalid color '{1}'. This key will be ignored.",
- "themeValidator.warning.sizeOutOfRange": "{0}={1} is out of range (8..48). This key will be ignored.",
- "queryExecutor.error.openConnectionMethodNotFound": "Cannot find OpenConnectionAsync method on orchestrator",
- "queryExecutor.error.openConnectionInvokeFailed": "Failed to invoke OpenConnectionAsync",
- "ddlImporter.warning.viewSelectNotReconstructable": "View '{0}': view SELECT cannot be reconstructed visually - edit it manually in the subcanvas.",
- "ddlImporter.error.tableNotFoundInMetadata": "Table '{0}' was not found in current metadata.",
- "main.window.untitled": "Untitled",
- "main.subEditor.noSeedProvided": "No {0} sub-editor seed was provided.",
- "main.layerOrder.bringToFront": "Bring to front",
- "main.layerOrder.sendToBack": "Send to back",
- "main.layerOrder.bringForward": "Bring forward",
- "main.layerOrder.sendBackward": "Send backward",
- "main.layerOrder.normalizeLayers": "Normalize layers",
- "export.fileType.html": "HTML Files",
- "export.fileType.json": "JSON Files",
- "export.fileType.csv": "CSV Files",
- "export.fileType.excel": "Excel Files",
- "commandPalette.templatePrefix": "Template: {0}",
- "themeLoader.status.notFoundWithPath": "Theme file not found: {0}",
- "themeLoader.status.deserializedNull": "Theme JSON deserialized to null.",
- "themeLoader.status.loaded": "Theme JSON loaded successfully.",
- "credential.error.ciphertextTooShort": "Ciphertext blob is too short.",
- "credential.error.dpapiWindowsOnly": "DPAPI is only available on Windows.",
- "credential.warning.loadVaultFailed": "Failed to load credential vault '{0}': {1}",
- "credential.warning.persistVaultFailed": "Failed to persist credential vault '{0}': {1}",
- "snippetStore.warning.loadFailed": "Failed to load snippets from '{0}': {1}",
- "snippetStore.warning.saveFailed": "Failed to save snippets: {0}",
- "flowVersionStore.warning.loadFailed": "Failed to load flow versions from '{0}': {1}",
- "flowVersionStore.warning.saveFailed": "Failed to save flow versions: {0}",
- "queryExecutor.error.queryEmpty": "Query cannot be empty",
- "queryExecutor.error.providerNotSupported": "Provider {0} is not supported",
- "queryExecutor.error.singleStatementOnly": "Preview accepts a single SQL statement only.",
- "queryExecutor.error.queryEmptyWithPeriod": "Query cannot be empty.",
- "queryExecutor.error.readOnlyOnly": "Preview mode only supports read-only SQL statements.",
- "queryExecutor.error.namedParametersNotSupported": "Preview mode does not support bound parameters in execution SQL. Inline safe literals or run the query outside preview.",
- "queryExecutor.error.positionalParametersNotSupported": "Preview mode does not support positional parameter placeholders ('?' or '$1').",
- "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "Align selected nodes to the bottom edge",
- "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "Align selected nodes to the leftmost edge",
- "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "Align selected nodes to the rightmost edge",
- "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "Align selected nodes to the topmost edge",
- "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "Apply CTE sub-canvas edits and return to the parent canvas",
- "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "Arrange nodes into logical columns automatically",
- "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "Centre selected nodes on a horizontal axis",
- "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "Centre selected nodes on a vertical axis",
- "commandPalette.description.clear_canvas_and_start_fresh": "Clear canvas and start fresh",
- "commandPalette.description.clear_node_selection": "Clear node selection",
- "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "Convert aliases to the convention configured in project settings",
- "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "Create checkpoints, compare versions side-by-side and restore a previous canvas state",
- "commandPalette.description.delete_the_selected_nodes": "Delete the selected nodes",
- "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "Discard current sub-editor edits and return to the parent canvas",
- "commandPalette.description.execute_the_current_query_in_preview": "Execute the current query in preview",
- "commandPalette.description.fit_all_nodes_into_the_visible_area": "Fit all nodes into the visible area",
- "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "Generate CSV file from the first CSV Export node",
- "commandPalette.description.generate_html_file_from_the_first_html_export_node": "Generate HTML file from the first HTML Export node",
- "commandPalette.description.generate_json_file_from_the_first_json_export_node": "Generate JSON file from the first JSON Export node",
- "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "Generate XLSX workbook from the first Excel Export node",
- "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "Inspect the query execution plan — see scan types, join strategies, and cost estimates",
- "commandPalette.description.load_a_vsaq_canvas_file": "Load a .vsaq canvas file",
- "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "Measure avg / median / p95 latency of the current SQL over N iterations",
- "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "Open isolated sub-canvas editor for the selected CTE Definition node",
- "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "Open local file version history created on each save and restore previous saved snapshots",
- "commandPalette.description.open_output_preview_modal_for_the_active_mode": "Open output preview modal for the active mode",
- "commandPalette.description.open_shortcut_reference_screen": "Open shortcut reference screen",
- "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "Open the connection manager to add, edit or switch database connections",
- "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "Paste a SELECT statement and generate nodes automatically — FROM, JOIN, WHERE, LIMIT are supported",
- "commandPalette.description.remove_all_nodes_not_connected_to_output": "Remove all nodes not connected to output",
- "commandPalette.description.reset_zoom_and_pan_to_default": "Reset zoom and pan to default",
- "commandPalette.description.save_canvas_to_a_new_file": "Save canvas to a new file",
- "commandPalette.description.save_current_canvas": "Save current canvas",
- "commandPalette.description.save_markdown_documentation_of_the_current_flow": "Save Markdown documentation of the current flow",
- "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "Save the selected nodes as a reusable snippet — insert it later via the node search menu (⇧A)",
- "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "Scan all table-source nodes on the canvas for possible join relationships based on FK conventions and naming patterns",
- "commandPalette.description.select_all_nodes_on_canvas": "Select all nodes on canvas",
- "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "Snap node positions to 16px grid (Ctrl+G)",
- "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "Spread selected nodes with equal horizontal spacing",
- "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "Spread selected nodes with equal vertical spacing",
- "commandPalette.description.zoom_into_the_canvas": "Zoom into the canvas",
- "commandPalette.description.zoom_out_of_the_canvas": "Zoom out of the canvas",
- "commandPalette.name.align_bottom": "Align Bottom",
- "commandPalette.name.align_left": "Align Left",
- "commandPalette.name.align_right": "Align Right",
- "commandPalette.name.align_top": "Align Top",
- "commandPalette.name.analyze_all_joins": "Analyze All Joins",
- "commandPalette.name.auto_fix_naming": "Auto-Fix Naming",
- "commandPalette.name.auto_layout": "Auto Layout",
- "commandPalette.name.center_horizontally": "Center Horizontally",
- "commandPalette.name.center_vertically": "Center Vertically",
- "commandPalette.name.cleanup_orphans": "Cleanup Orphans",
- "commandPalette.name.delete_selected": "Delete Selected",
- "commandPalette.name.deselect_all": "Deselect All",
- "commandPalette.name.discard_and_exit_editor": "Discard and Exit Editor",
- "commandPalette.name.distribute_horizontally": "Distribute Horizontally",
- "commandPalette.name.distribute_vertically": "Distribute Vertically",
- "commandPalette.name.edit_selected_cte": "Edit Selected CTE",
- "commandPalette.name.exit_cte_editor": "Exit CTE Editor",
- "commandPalette.name.explain_plan": "Explain Plan",
- "commandPalette.name.export_csv": "Export CSV",
- "commandPalette.name.export_documentation": "Export Documentation",
- "commandPalette.name.export_excel": "Export Excel",
- "commandPalette.name.export_html": "Export HTML",
- "commandPalette.name.export_json": "Export JSON",
- "commandPalette.name.file_save_load_history": "File Save/Load History",
- "commandPalette.name.fit_to_screen": "Fit to Screen",
- "commandPalette.name.flow_version_history": "Flow Version History",
- "commandPalette.name.import_sql_to_graph": "Import SQL to Graph",
- "commandPalette.name.keyboard_shortcuts": "Keyboard Shortcuts",
- "commandPalette.name.manage_connections": "Manage Connections",
- "commandPalette.name.new_canvas": "New Canvas",
- "commandPalette.name.open_file": "Open File",
- "commandPalette.name.reset_viewport": "Reset Viewport",
- "commandPalette.name.run_preview": "Run Preview",
- "commandPalette.name.run_query_benchmark": "Run Query Benchmark",
- "commandPalette.name.save": "Save",
- "commandPalette.name.save_as": "Save As",
- "commandPalette.name.save_selection_as_snippet": "Save Selection as Snippet",
- "commandPalette.name.select_all": "Select All",
- "commandPalette.name.toggle_preview": "Toggle Preview",
- "commandPalette.name.toggle_snap_to_grid": "Toggle Snap to Grid",
- "commandPalette.name.zoom_in": "Zoom In",
- "commandPalette.name.zoom_out": "Zoom Out",
- "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 percent restore zoom pan viewport",
- "commandPalette.tags.align_bottom_edge_selection_nodes": "align bottom edge selection nodes",
- "commandPalette.tags.align_center_middle_horizontal_nodes": "align center middle horizontal nodes",
- "commandPalette.tags.align_center_middle_vertical_nodes": "align center middle vertical nodes",
- "commandPalette.tags.align_left_edge_selection_nodes": "align left edge selection nodes",
- "commandPalette.tags.align_right_edge_selection_nodes": "align right edge selection nodes",
- "commandPalette.tags.align_top_edge_selection_nodes": "align top edge selection nodes",
- "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout view reset zoom",
- "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark performance latency timing profile measure speed",
- "commandPalette.tags.clear_selection": "clear selection",
- "commandPalette.tags.connection_database_server_host_provider_switch": "connection database server host provider switch",
- "commandPalette.tags.create_insert_search_transform": "create insert search transform",
- "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas exit apply back",
- "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte view subcanvas discard exit force",
- "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursive editor subgraph subcanvas isolate",
- "commandPalette.tags.data_results_table_panel": "data results table panel",
- "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribute space equal horizontal nodes",
- "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribute space equal vertical nodes",
- "commandPalette.tags.execute_run_sql_query_results": "execute run sql query results",
- "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan execution cost scan index join performance",
- "commandPalette.tags.export_csv_file_tabular_output_save": "export csv file tabular output save",
- "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "export excel xlsx file tabular output spreadsheet save",
- "commandPalette.tags.export_html_file_output_report_save": "export html file output report save",
- "commandPalette.tags.export_json_file_output_save": "export json file output save",
- "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "export markdown doc documentation flow save md",
- "commandPalette.tags.export_persist_copy": "export persist copy",
- "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "file history save load backup versions restore local",
- "commandPalette.tags.forward_history": "forward history",
- "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "help shortcuts hotkeys keyboard reference",
- "commandPalette.tags.highlight_mark_all_nodes": "highlight mark all nodes",
- "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "import sql paste convert graph reverse engineer query",
- "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analyze suggest detect foreign key relationships heuristic",
- "commandPalette.tags.layer_z_order_back_selected_nodes": "layer z-order back selected nodes",
- "commandPalette.tags.layer_z_order_backward_selected_nodes": "layer z-order backward selected nodes",
- "commandPalette.tags.layer_z_order_forward_selected_nodes": "layer z-order forward selected nodes",
- "commandPalette.tags.layer_z_order_front_selected_nodes": "layer z-order front selected nodes",
- "commandPalette.tags.layer_z_order_normalize_compact": "layer z-order normalize compact",
- "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout arrange columns auto organize readability",
- "commandPalette.tags.load_import_vsaq": "load import vsaq",
- "commandPalette.tags.magnify_enlarge": "magnify enlarge",
- "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "orphan unused disconnected clean delete nodes",
- "commandPalette.tags.persist_write_disk": "persist write disk",
- "commandPalette.tags.remove_erase_nodes": "remove erase nodes",
- "commandPalette.tags.rename_alias_fix_naming_convention": "rename alias fix naming convention",
- "commandPalette.tags.reset_clear_blank": "reset clear blank",
- "commandPalette.tags.revert_back_history": "revert back history",
- "commandPalette.tags.shrink_reduce": "shrink reduce",
- "commandPalette.tags.snap_grid_align_precision_position": "snap grid align precision position",
- "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet save selection reuse template favorite bookmark",
- "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "version history checkpoint diff restore snapshot compare undo flow",
- "sqlEditor.diffPreview.title": "Transactional Diff Preview",
- "sqlEditor.mutation.confirmExecute": "Confirm Execute",
- "sqlEditor.tab.closeAnyway": "Close Anyway",
- "sqlEditor.tab.keepTab": "Keep Tab",
- "sqlEditor.status.ready": "Ready.",
- "sqlEditor.telemetry.none": "No execution telemetry yet.",
- "sqlEditor.telemetry.summary": "Statements: {0} Success: {1} Failed: {2} Total: {3} ms",
- "sqlEditor.telemetry.errors.none": "No aggregated errors.",
- "sqlEditor.diff.none": "No transactional diff preview available.",
- "sqlEditor.mutation.estimate.none": "No mutation estimate available.",
- "sqlEditor.mutation.estimate.value": "Estimated affected rows: {0}",
- "sqlEditor.mutation.estimate.unavailable": "Could not estimate affected rows automatically.",
- "sqlEditor.tab.closePending": "Unsaved changes detected. Confirm tab close.",
- "sqlEditor.tab.noPendingClose": "No tab close pending.",
- "sqlEditor.tab.manyWarning": "High tab count: {0} open tabs.",
- "sqlEditor.mutation.pending.none": "No pending mutation confirmation.",
- "sqlEditor.mutation.pending.required": "Mutation requires confirmation before execution.",
- "sqlEditor.message.empty": "Execute a statement to see messages.",
- "sqlEditor.message.success": "Execution completed successfully.",
- "sqlEditor.result.summary.empty": "Rows: - Time: -",
- "sqlEditor.result.summary": "Rows: {0} Time: {1} ms",
- "sqlEditor.file.save.canceled": "Save canceled.",
- "sqlEditor.file.save.noPath": "No target path selected.",
- "sqlEditor.file.save.success": "SQL file saved.",
- "sqlEditor.file.save.failed": "Save failed.",
- "sqlEditor.file.open.failed": "Open failed.",
- "sqlEditor.file.open.notFound": "Selected SQL file was not found.",
- "sqlEditor.file.open.success": "SQL file opened.",
- "sqlEditor.status.executing": "Executing SQL...",
- "sqlEditor.status.executingScript": "Executing SQL script...",
- "sqlEditor.status.executingStep": "Executing {0}/{1}...",
- "sqlEditor.status.canceling": "Canceling execution...",
- "sqlEditor.status.executingConfirmedMutation": "Executing confirmed mutation...",
- "sqlEditor.status.mutationCanceled": "Mutation execution canceled.",
- "sqlEditor.detail.statementNotExecuted": "Statement was not executed.",
- "sqlEditor.status.success": "Execution succeeded.",
- "sqlEditor.detail.rowsAndTime": "{0} row(s) in {1} ms.",
- "sqlEditor.status.canceled": "Execution canceled.",
- "sqlEditor.status.failed": "Execution failed.",
- "sqlEditor.status.confirmationRequired": "Confirmation required before execution.",
- "sqlEditor.error.mutationConfirmationRequired": "Mutation confirmation required.",
- "sqlEditor.result.tabTitle": "Result {0}",
- "sqlEditor.tab.closeRequiresConfirmation": "Tab close requires confirmation.",
- "sqlEditor.tab.unsavedDetail": "This tab has unsaved changes.",
- "sqlEditor.tab.closed": "Tab closed.",
- "sqlEditor.tab.closeCanceled": "Tab close canceled.",
- "sqlEditor.tab.closeCanceledDetail": "Unsaved tab kept open.",
- "sqlEditor.error.noStatementSelected": "No SQL statement selected for execution.",
- "sqlEditor.error.noConnection": "No active database connection for SQL execution.",
- "sqlEditor.error.executionCanceled": "SQL execution was canceled.",
- "sqlEditor.tab.scriptTitle": "Script {0}",
- "sqlEditor.guard.delete.noWhere.message": "DELETE without WHERE can remove all rows.",
- "sqlEditor.guard.delete.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
- "sqlEditor.guard.delete.trivialWhere.message": "DELETE has a trivially true WHERE clause.",
- "sqlEditor.guard.delete.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
- "sqlEditor.guard.update.noWhere.message": "UPDATE without WHERE can affect all rows.",
- "sqlEditor.guard.update.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
- "sqlEditor.guard.update.trivialWhere.message": "UPDATE has a trivially true WHERE clause.",
- "sqlEditor.guard.update.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
- "sqlEditor.guard.insert.noColumnList.message": "INSERT without explicit column list is fragile against schema changes.",
- "sqlEditor.guard.insert.noColumnList.recommendation": "Prefer INSERT INTO table(col1, col2, ...) VALUES (...).",
- "sqlEditor.guard.ddl.message": "DDL statement may cause structural changes in the database.",
- "sqlEditor.guard.ddl.recommendation": "Confirm execution only when schema changes are intended.",
- "sqlEditor.diff.unavailable.noPreview": "No transactional diff preview available for this statement.",
- "sqlEditor.diff.unavailable.parseError": "Could not parse mutation target for transactional diff preview.",
- "sqlEditor.diff.unavailable.connection": "Transactional diff preview unavailable due to connection or query limitations.",
- "sqlEditor.diff.deleteSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, affected {2}, total rows after {3}.",
- "sqlEditor.diff.updateSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, candidate rows affected {2}, total rows after {3}.",
- "sqlEditor.diff.unavailable.unsupportedStatement": "Transactional diff preview currently supports UPDATE and DELETE only.",
- "sqlEditor.results.title": "Results",
- "sqlEditor.results.filterWatermark": "Filter results",
- "sqlEditor.results.rows.countZero": "0 rows",
- "sqlEditor.results.rows.countSingle": "{0} rows",
- "sqlEditor.results.rows.countFiltered": "{0} of {1} rows",
- "sqlEditor.results.context.copyCell": "Copy Cell",
- "sqlEditor.results.context.copyRow": "Copy Row",
- "sqlEditor.results.context.hideColumn": "Hide Column",
- "sqlEditor.results.context.showAllColumns": "Show All Columns",
- "sqlEditor.sidebar.messages": "MESSAGES",
- "sqlEditor.sidebar.history": "HISTORY",
- "sqlEditor.sidebar.connection.none": "No connection",
- "sqlEditor.sidebar.connection.connectHint": "Connect to load metadata and execute queries.",
- "sqlEditor.sidebar.connection.connect": "Connect",
- "sqlEditor.sidebar.schema.searchWatermark": "Search table or column",
- "sqlEditor.sidebar.schema.reloadTooltip": "Reload metadata",
- "sqlEditor.sidebar.schema.connectHint": "Connect to view the full schema.",
- "sqlEditor.history.searchWatermark": "Search history",
- "sqlEditor.history.navigationHint": "Arrow keys navigate history, Enter runs selected, Esc clears the search.",
- "sqlEditor.history.noSearchResults": "No items found for this search.",
- "sqlEditor.history.use": "Use",
- "sqlEditor.history.copy": "Copy",
- "sqlEditor.history.run": "Run",
- "sqlEditor.history.copiedFromHistory": "SQL copied from history.",
- "sqlEditor.toast.scriptSuccessTitle": "Script executed.",
- "sqlEditor.toast.scriptSuccessDetail": "{0} statement(s) executed successfully.",
- "sqlEditor.toast.scriptWarningTitle": "Script executed with failures.",
- "sqlEditor.toast.scriptWarningDetail": "{0} of {1} statement(s) failed.",
- "sqlEditor.toast.resultErrorTitle": "Failed to execute statement.",
- "sqlEditor.toast.resultSuccessTitle": "Execution completed successfully.",
- "sqlEditor.export.action": "Export Report",
- "sqlEditor.openSql.pickerTitle": "Open SQL File",
- "sqlEditor.saveSql.fileType": "SQL Files",
- "sqlEditor.saveSql.pickerTitle": "Save SQL File",
- "sqlEditor.export.pickerTitle": "Export SQL Data",
- "sqlEditor.export.status.noResultTitle": "No execution result available for export.",
- "sqlEditor.export.status.noResultDetail": "Execute a query first.",
- "sqlEditor.export.status.successTitle": "Report exported.",
- "sqlEditor.export.status.failedTitle": "Failed to export report.",
- "sqlEditor.export.fileType.html": "HTML File",
- "sqlEditor.export.fileType.json": "JSON File",
- "sqlEditor.export.fileType.csv": "CSV File",
- "sqlEditor.export.fileType.xlsx": "Excel Workbook",
- "sqlEditor.export.defaultFileBase": "report",
- "sqlEditor.export.defaultTitle": "SQL Report",
- "sqlEditor.export.error.typeRequired": "A report type must be selected before export.",
- "sqlEditor.export.type.html.title": "HTML full-feature report",
- "sqlEditor.export.type.html.description": "Standalone, SQL-first HTML artifact for offline audit.",
- "sqlEditor.export.type.json.title": "JSON execution contract",
- "sqlEditor.export.type.json.description": "Machine-readable payload with SQL, metadata and execution result.",
- "sqlEditor.export.type.csv.title": "CSV data export",
- "sqlEditor.export.type.csv.description": "Tabular result data only, suitable for spreadsheet tools.",
- "sqlEditor.export.type.xlsx.title": "Excel workbook export",
- "sqlEditor.export.type.xlsx.description": "Spreadsheet workbook with query result data only.",
- "sqlEditor.export.dialog.windowTitle": "Export SQL Data",
- "sqlEditor.export.dialog.title": "Export SQL Data",
- "sqlEditor.export.dialog.subtitle": "Choose the artifact format and metadata before exporting.",
- "sqlEditor.export.dialog.confirm": "Export",
- "sqlEditor.export.dialog.fileNameWatermark": "report.html",
- "sqlEditor.export.dialog.titleWatermark": "SQL Report",
- "sqlEditor.export.dialog.descriptionWatermark": "Additional context for auditors and teammates.",
- "sqlEditor.export.dialog.section.reportType": "REPORT TYPE",
- "sqlEditor.export.dialog.section.fileName": "FILE NAME",
- "sqlEditor.export.dialog.section.reportTitle": "TITLE",
- "sqlEditor.export.dialog.section.description": "DESCRIPTION",
- "sqlEditor.export.dialog.section.options": "OPTIONS",
- "sqlEditor.export.option.includeSchema": "Include output schema",
- "sqlEditor.export.option.includeNodeDetails": "Include node/connection placeholders in JSON",
- "sqlEditor.export.option.includeMetadata": "Include optional metadata",
- "sqlEditor.export.option.useDashForEmpty": "Use '-' for empty fields",
- "sqlEditor.export.badge.offline": "OFFLINE READY",
- "sqlEditor.export.badge.structured": "STRUCTURED PAYLOAD",
- "sqlEditor.export.badge.dataOnly": "DATA ONLY"
-}
+{
+ "main.brand": "AkkornStudio",
+ "main.tab.query1": "Query 1",
+ "main.new": "New",
+ "main.open": "Open",
+ "main.save": "Save",
+ "main.history": "History",
+ "main.layout": "Layout",
+ "main.preview": "Preview",
+ "main.undo": "Undo",
+ "main.redo": "Redo",
+ "main.cleanupOrphans": "Cleanup orphan nodes",
+ "main.autoFixAliasNaming": "Auto-fix alias naming",
+ "main.autoLayoutCanvas": "Auto layout canvas",
+ "main.toggleDataPreview": "Toggle data preview",
+ "main.language": "Language",
+ "main.restore.prompt": "Previous session found — restore the last canvas?",
+ "main.restore.button": "Restore session",
+ "main.cteEditor.editingPrefix": "Editing CTE: ",
+ "main.cteEditor.backToCanvas": "Back to Canvas",
+ "main.cteEditor.exitA11y": "Exit CTE editor",
+ "main.viewEditor.editingPrefix": "DDL > View: ",
+ "main.viewEditor.backToCanvas": "Back to DDL",
+ "main.viewEditor.exitA11y": "Exit view editor",
+ "connection.title": "Connection Manager",
+ "connection.subtitle": "Configure, test, and activate connections without leaving your flow",
+ "connection.none": "No connection",
+ "connection.active": "ACTIVE",
+ "connection.health.online": "Online",
+ "connection.health.degraded": "Degraded",
+ "connection.health.offline": "Offline",
+ "connection.tooltip.none": "No active connection — click to manage",
+ "connection.ping": "Ping",
+ "connection.saved": "SAVED CONNECTIONS",
+ "connection.new": "New Connection",
+ "connection.selectOrCreate": "Select a connection or create a new one",
+ "connection.name": "Connection Name",
+ "connection.provider": "Provider",
+ "connection.host": "Host",
+ "connection.port": "Port",
+ "connection.database": "Database",
+ "connection.sqlitePath": "SQLite Path",
+ "connection.sqliteBrowse": "Browse",
+ "connection.sqliteCreate": "Create",
+ "connection.username": "Username",
+ "connection.password": "Password",
+ "connection.timeout": "Timeout (seconds)",
+ "connection.test": "Test",
+ "connection.save": "Save",
+ "connection.connect": "Connect",
+ "connection.action.testConnection": "Test connection",
+ "connection.action.saveConnection": "Save connection",
+ "connection.action.connectConnection": "Connect connection",
+ "connection.status.connecting": "Connecting...",
+ "connection.status.connected": "Connected",
+ "connection.status.testing": "Testing...",
+ "connection.status.failedPrefix": "Connection failed",
+ "connection.status.metadataUnavailable": "Connection failed: metadata not available.",
+ "connection.status.highLatency": "high latency",
+ "connection.watermark.name": "My Production DB",
+ "connection.watermark.host": "localhost",
+ "connection.watermark.port": "5432",
+ "connection.watermark.database": "database_name",
+ "connection.watermark.username": "user",
+ "connection.watermark.password": "••••••••",
+ "connection.watermark.timeout": "30",
+ "main.connectingDb": "Connecting to database...",
+ "main.emptyHint": "Press ⇧A to add your first node, or drag a table from the sidebar",
+ "status.nodesSeparator": " nodes · ",
+ "status.connectionsSuffix": " connections",
+ "status.undo": "Undo: ",
+ "status.shortcuts": "⇧A Nodes · F3 Preview · Ctrl+Z Undo · Del Remove · Alt+Drag Pan",
+ "connection.disconnect": "Disconnect",
+ "connection.action.disconnectConnection": "Disconnect connection",
+ "connectionTab.active": "ACTIVE CONNECTION",
+ "connectionTab.none": "No active connection",
+ "connectionTab.saved": "SAVED CONNECTIONS",
+ "connectionTab.new": "+ New Connection",
+ "schema.database": "DATABASE",
+ "schema.search": "Search tables, columns...",
+ "schema.loading": "Searching tables, columns...",
+ "schema.noConnection": "No Connection",
+ "schema.noConnectionHint": "Connect to a database to see tables, columns, and relationships",
+ "schema.emptyNoTables": "No tables found",
+ "fileHistory.title": "Save/Load Version History",
+ "fileHistory.reload": "Reload",
+ "fileHistory.restoreSelected": "Restore selected",
+ "fileHistory.empty": "No local versions yet",
+ "fileHistory.emptyHint": "Save this file to generate version history.",
+ "preview.title": "Data Preview",
+ "preview.subtitle": "Review data and diagnostics before continuing",
+ "preview.run": "Run",
+ "preview.cancel": "Cancel",
+ "preview.tab.preview": "Preview",
+ "preview.tab.sql": "SQL",
+ "preview.close": "Close preview",
+ "preview.running": "Running preview query… ",
+ "preview.clickCancel": "Click Cancel to stop",
+ "preview.cancelled": "Query cancelled",
+ "preview.runAgain": "Press Run to execute again",
+ "preview.failed": "Preview execution failed",
+ "preview.technical": "TECHNICAL DETAILS",
+ "preview.noData": "No data yet",
+ "preview.f3Hint": "Press F3 or Space to run the current query",
+ "sqlImporter.title": "Import SQL to Graph",
+ "sqlImporter.subtitle": "Paste a SELECT statement — nodes are created automatically",
+ "sqlImporter.sqlStatement": "SQL STATEMENT",
+ "sqlImporter.supported": "Supported: ",
+ "sqlImporter.import": "Import",
+ "sqlImporter.report": "CONVERSION REPORT",
+ "sqlEditor.mutation.dialogTitle": "Mutation confirmation",
+ "sqlEditor.mutation.dialogSubtitle": "Review impact before confirming execution",
+ "search.empty": "No nodes found",
+ "search.emptyHint": "Try searching for UPPER, JSON, CAST, AND…",
+ "search.shortcut": "⇧A",
+ "search.spawn": "Spawn",
+ "commandPalette.empty": "No commands match your search",
+ "commandPalette.search": "Command search",
+ "commandPalette.shortcut": "CTRL+SHIFT+P",
+ "commandPalette.execute": "Execute",
+ "context.editCte": "Edit Selected CTE",
+ "context.editViewSubcanvas": "Edit View Subcanvas",
+ "explain.title": "Explain Plan",
+ "explain.sql": "SQL",
+ "explain.option.analyze": "Analyze",
+ "explain.option.buffers": "Buffers",
+ "explain.badge.simulated": "SIMULATED",
+ "explain.timing.planning": "Planning:",
+ "explain.timing.execution": "Execution:",
+ "explain.section.snapshotComparison": "Snapshot comparison",
+ "explain.section.indexRecommendations": "Index recommendations",
+ "explain.section.history": "History",
+ "explain.detail.estimated": "Estimated",
+ "explain.detail.actual": "Actual",
+ "explain.detail.error": "Error",
+ "explain.detail.time": "Time",
+ "explain.detail.loops": "Loops",
+ "explain.rerun": "Re-run",
+ "explain.alertSuffix": " expensive operation(s) detected — consider adding indexes",
+ "explain.running": "Running EXPLAIN…",
+ "explain.failed": "⚠ EXPLAIN failed",
+ "explain.noPlan": "No plan yet",
+ "explain.rerunHint": "Press Re-run to execute EXPLAIN",
+ "explain.header.operation": "OPERATION",
+ "explain.header.cost": "COST",
+ "explain.header.rows": "ROWS",
+ "explain.header.err": "ERR",
+ "explain.header.alert": "ALERT",
+ "explain.snapshot.labelA": "A",
+ "explain.snapshot.labelB": "B",
+ "explain.mode.list": "List",
+ "explain.mode.tree": "Tree",
+ "explain.action.snapshot": "Save snapshot",
+ "explain.action.copyJson": "Copy JSON",
+ "explain.action.copyText": "Copy text",
+ "explain.action.saveJson": "Save .json",
+ "explain.action.openDalibo": "Open in Dalibo",
+ "explain.legend.seqscan": "SEQ SCAN — full table read, no index",
+ "explain.legend.sort": "SORT — in-memory sort",
+ "explain.legend.hash": "HASH — hash join",
+ "explain.escClose": "Esc to close",
+ "flowVersion.title": "Flow Version History",
+ "flowVersion.subtitle": "Create checkpoints, compare versions and restore",
+ "flowVersion.watermark": "Checkpoint label (optional)…",
+ "flowVersion.saveCheckpoint": "Save Checkpoint",
+ "flowVersion.compareMode": "Compare Mode",
+ "flowVersion.selectBase": "Select BASE version (from):",
+ "flowVersion.clickAny": "Then click any version in the list below to compare.",
+ "flowVersion.noCheckpoints": "No checkpoints yet",
+ "flowVersion.noCheckpointsHint": "Save a checkpoint above to begin tracking versions.",
+ "flowVersion.restore": "Restore",
+ "flowVersion.diffResults": "Diff Results",
+ "benchmark.title": "Query Benchmark",
+ "benchmark.subtitle": "Measures avg / median / p95 latency over N iterations",
+ "benchmark.sql": "SQL being benchmarked",
+ "benchmark.runLabel": "Run label",
+ "benchmark.runLabelWatermark": "Run 1",
+ "benchmark.iterations": "Iterations (1–100)",
+ "benchmark.warmup": "Warm-up passes (0–10)",
+ "benchmark.interval": "Interval between runs (ms)",
+ "benchmark.run": "Run Benchmark",
+ "benchmark.cancel": "Cancel",
+ "benchmark.clearHistory": "Clear History",
+ "benchmark.latest": "LATEST RESULT",
+ "benchmark.avg": "AVG",
+ "benchmark.median": "MEDIAN",
+ "benchmark.min": "MIN",
+ "benchmark.max": "MAX",
+ "benchmark.iterationsAt": " iterations · run at ",
+ "benchmark.history": "HISTORY",
+ "benchmark.header.label": "Label",
+ "benchmark.header.avg": "Avg",
+ "benchmark.header.median": "Median",
+ "benchmark.header.min": "Min",
+ "benchmark.header.max": "Max",
+ "benchmark.itersSuffix": " iters",
+ "diagnostics.title": "App Diagnostics",
+ "diagnostics.run": "Run",
+ "diagnostics.running": "Running checks…",
+ "diagnostics.ok": "OK",
+ "diagnostics.warning": "Warning",
+ "diagnostics.error": "Error",
+ "diagnostics.tooltip.rerun": "Re-run all checks",
+ "diagnostics.tooltip.copy": "Copy diagnostic report to clipboard",
+ "diagnostics.tooltip.close": "Close (Esc)",
+ "autoJoin.title": "Auto-Join Suggestions",
+ "autoJoin.titleForTable": "Auto-Join suggestions for {0}",
+ "autoJoin.acceptAll": "Accept All",
+ "autoJoin.accept": "Accept",
+ "autoJoin.skip": "Skip",
+ "autoJoin.allHandled": "All suggestions handled",
+ "autoJoin.joinKeyword": "JOIN",
+ "autoJoin.confidence.fkConstraint": "FK Constraint",
+ "autoJoin.confidence.fkReverse": "FK (Reverse)",
+ "autoJoin.confidence.namingMatch": "Naming Match",
+ "autoJoin.confidence.weakMatch": "Weak Match",
+ "autoJoin.runSelected": "Auto-Join Selected",
+ "autoJoin.noSimilarityTitle": "No automatic join found",
+ "autoJoin.noSimilarityDetails": "Choose the columns manually to create a simple join.",
+ "autoJoin.appliedTitle": "Auto-join applied",
+ "autoJoin.manual.title": "Create Manual Join",
+ "autoJoin.manual.subtitle": "No reliable similarity was found. Select one column from each table.",
+ "autoJoin.manual.leftColumn": "Left column",
+ "autoJoin.manual.rightColumn": "Right column",
+ "autoJoin.manual.joinType": "Join type",
+ "autoJoin.manual.operator": "Operator",
+ "autoJoin.manual.confirm": "Create join",
+ "autoJoin.manual.noCompatible": "No compatible columns for the selected left pin type.",
+ "autoJoin.manualJoinCreatedTitle": "Manual join created",
+ "autoJoin.manualJoinFailedTitle": "Manual join could not be created",
+ "autoJoin.manualJoinFailedDetails": "Check selected columns and existing joins, then try again.",
+ "autoJoin.multipleCandidatesTitle": "Multiple join candidates found",
+ "autoJoin.multipleCandidatesDetails": "{0} possible combinations were found. Confirm which columns should be used.",
+ "autoJoin.suggestionsFoundTitle": "Auto-join suggestions available",
+ "autoJoin.suggestionsFoundDetails": "{0} suggestion(s) found. Select two tables and run Auto-Join Selected.",
+ "property.outputAlias": "OUTPUT ALIAS",
+ "property.sourceAlias": "SOURCE ALIAS",
+ "property.aliasWatermark": "e.g. MyColumn (optional)",
+ "property.parameters": "PARAMETERS",
+ "property.enabled": "Enabled",
+ "property.datetimeWatermark": "YYYY-MM-DDTHH:mm:ss or leave empty",
+ "property.dateWatermark": "YYYY-MM-DD or leave empty",
+ "property.apply": "Apply",
+ "property.inputPins": "INPUT PINS",
+ "property.outputPins": "OUTPUT PINS",
+ "property.sqlTrace": "SQL TRACE",
+ "property.live": "live",
+ "node.numericValue": "Numeric Value",
+ "node.stringValue": "String Value",
+ "node.enterText": "Enter text",
+ "node.datetimeValue": "DateTime Value",
+ "node.valueLabel": "Value:",
+ "node.noInputs": "No inputs",
+ "node.loadingSample": "Loading sample…",
+ "node.previewFailed": "⚠ Preview failed",
+ "node.sampleRowsHint": "5 sample rows · demo data",
+ "sidebar.tab.nodes": "Nodes",
+ "sidebar.tab.connection": "Connection",
+ "sidebar.tab.schema": "Schema",
+ "sidebar.tab.diagnostics": "Diagnostics",
+ "sidebar.addNode": "+ Add Node (⇧A)",
+ "sidebar.previewF3": "Preview (F3)",
+ "nodesList.search": "Search nodes...",
+ "search.watermark": "Search nodes… (Esc to close)",
+ "search.snippets": "★ SNIPPETS",
+ "commandPalette.watermark": "Run a command… (Esc to close)",
+ "tooltip.newCanvas": "New canvas (Ctrl+N)",
+ "tooltip.openCanvas": "Open canvas (Ctrl+O)",
+ "tooltip.saveCanvas": "Save canvas (Ctrl+S)",
+ "tooltip.fileHistory": "Local save/load history (Ctrl+Alt+H)",
+ "tooltip.zoomOut": "Zoom out (Ctrl+-)",
+ "tooltip.zoomIn": "Zoom in (Ctrl++)",
+ "tooltip.fitToScreen": "Fit to screen (Ctrl+0)",
+ "tooltip.autoLayout": "Auto Layout — arrange nodes into logical columns (Ctrl+L, Ctrl+Z to undo)",
+ "tooltip.snapToGrid": "Toggle snap to grid (Ctrl+G)",
+ "tooltip.dataPreview": "Data preview (F3)",
+ "tooltip.toggleLanguage": "Toggle language (pt-BR / en-US)",
+ "tooltip.appDiagnostics": "App Diagnostics (self-check)",
+ "tooltip.keyboardShortcuts": "Keyboard shortcuts (F1)",
+ "tooltip.cancelRunningQuery": "Cancel the running query",
+ "tooltip.closeEsc": "Close (Esc)",
+ "tooltip.recheckConnectionHealth": "Re-check connection health",
+ "tooltip.deleteConnection": "Delete connection",
+ "tooltip.testConnection": "Test connection",
+ "tooltip.saveConnection": "Save connection",
+ "tooltip.activateConnection": "Activate this connection",
+ "tooltip.toggleDataSamplePreview": "Toggle data sample preview",
+ "tooltip.liveSqlMutatingBlocked": "This SQL contains a data-mutating command and cannot be run in Safe Preview Mode",
+ "tooltip.copySql": "Copy SQL to clipboard",
+ "tooltip.formatSql": "Format SQL",
+ "tooltip.openBenchmark": "Open Query Benchmark (measure avg / median / p95 latency)",
+ "tooltip.openExplainPlan": "Open Explain Plan inspector — visualise the query execution plan",
+ "tooltip.switchToQueryMode": "Switch to Query canvas",
+ "tooltip.switchToDdlMode": "Switch to DDL canvas",
+ "tooltip.switchToSqlMode": "Switch to SQL editor",
+ "tooltip.autoJoinSelected": "Try auto-join between the two selected tables",
+ "tooltip.pins.inputs": "Inputs",
+ "tooltip.pins.outputs": "Outputs",
+ "tooltip.pins.none": "None",
+ "tooltip.tableColumns": "Columns",
+ "tooltip.tableColumns.none": "No detailed columns",
+ "window.minimize": "Minimize window",
+ "window.maximizeRestore": "Maximize/restore window",
+ "window.close": "Close window",
+ "menu.newDiagram": "New diagram",
+ "menu.openFile": "Open file",
+ "menu.save": "Save",
+ "menu.fileHistory": "File history",
+ "menu.shortcuts": "Keyboard shortcuts",
+ "menu.settings": "Settings",
+ "menu.group.project": "PROJECT",
+ "menu.group.currentMode": "CURRENT MODE",
+ "menu.group.tools": "TOOLS",
+ "menu.reason.ddlOnly": "Available only in DDL mode.",
+ "menu.importSqlQuery": "Import SQL to Query",
+ "menu.importDdlSchema": "Import DDL schema",
+ "menu.viewDdlSql": "View DDL SQL",
+ "menu.executeDdl": "Execute DDL",
+ "menu.backToStart": "Back to start",
+ "toast.ddlExecuteFailed": "Failed to execute DDL.",
+ "toast.ddlOpenFailed": "Failed to open DDL SQL.",
+ "toast.ddlImportFailed": "Failed to import schema into DDL.",
+ "toast.ddlConnectToImportSchema": "Connect to a database to import schema into the DDL canvas.",
+ "toast.ddlNoTablesFound": "No tables found to import in DDL mode.",
+ "toast.ddlSchemaImported": "Schema imported into the DDL canvas.",
+ "toast.ddlImportSummary": "{0} table(s), {1} column(s), {2} FK(s), {3} unique index(es).",
+ "toast.ddlConnectToImportTable": "Connect to a database to import tables into the DDL canvas.",
+ "toast.ddlTableAlreadyExists": "Table '{0}' already exists in the DDL canvas.",
+ "toast.ddlTableImported": "Table imported into the DDL canvas.",
+ "toast.ddlTableImportSummary": "Nodes: +{0}, connections: +{1}, FKs: +{2}.",
+ "toast.ddlNoActiveConnection": "No active connection to execute DDL.",
+ "toast.ddlExecutedSuccess": "DDL executed successfully.",
+ "toast.ddlExecutedWithIssues": "DDL executed with issues.",
+ "toast.switchToDdl": "Switch to DDL mode to generate SQL.",
+ "toast.ddlInvalid": "Invalid DDL. Fix errors before continuing.",
+ "toast.ddlNoStatements": "No DDL statements were generated in the canvas.",
+ "toast.previewOpenFailed": "Failed to open preview.",
+ "tab.switchFailed": "Failed to switch tab: {0}",
+ "settings.status.darkApplied": "Dark theme applied.",
+ "settings.status.lightApplied": "Light theme applied.",
+ "settings.status.snapUpdated": "Snap updated: {0}.",
+ "settings.status.languageToggled": "Language toggled.",
+ "settings.status.languageSelected": "Language selected: {0}.",
+ "settings.status.themeEditorReady": "Theme editor ready. Apply to save and use this theme.",
+ "settings.section.appearance.title": "Themes",
+ "settings.section.languageRegion.title": "Language & Region",
+ "settings.section.dateTime.title": "Date & Time",
+ "settings.section.keyboard.title": "Keyboard Shortcuts",
+ "settings.section.privacy.title": "Privacy",
+ "settings.section.notification.title": "Notification",
+ "settings.section.accessibility.title": "Accessibility",
+ "settings.section.default.title": "Settings",
+ "settings.section.appearance.subtitle": "Choose your style or customize your theme",
+ "settings.section.languageRegion.subtitle": "Manage language and regional formatting",
+ "settings.section.keyboard.subtitle": "Customize keyboard shortcuts used by command palette and canvas execution.",
+ "settings.section.wip.subtitle": "Work in progress.",
+ "settings.section.default.subtitle": "Application settings",
+ "settings.general": "General",
+ "settings.nav.appearance": "Appearance",
+ "settings.theme.light": "Light Mode",
+ "settings.theme.dark": "Dark Mode",
+ "settings.theme.system": "System Preferences",
+ "settings.gridSnap.title": "Grid Snap",
+ "settings.gridSnap.subtitle": "Controls node snapping on the canvas.",
+ "settings.language.subtitle": "Toggle between PT-BR and EN-US.",
+ "settings.language.toggle": "Toggle language",
+ "settings.language.option.ptBR": "Portuguese (Brazil)",
+ "settings.language.option.enUS": "English (United States)",
+ "settings.language.option.esES": "Spanish (Spain)",
+ "settings.language.option.ruRU": "Russian",
+ "settings.language.option.jaJP": "Japanese",
+ "settings.language.option.zhTW": "Traditional Chinese",
+ "settings.themeJson.title": "Theme JSON",
+ "settings.themeJson.subtitle": "Paste your theme JSON, apply and persist instantly.",
+ "settings.themeJson.apply": "Apply JSON",
+ "settings.themeJson.restoreDefault": "Restore default theme",
+ "mode.query": "Query",
+ "mode.ddl": "DDL",
+ "mode.sql": "SQL",
+ "sidebar.left.close": "Close left sidebar",
+ "sidebar.left.open": "Reopen left sidebar",
+ "sidebar.right.close": "Close right sidebar",
+ "sidebar.right.open": "Reopen right sidebar",
+ "connection.completedTitle": "Connection completed",
+ "connection.clearCanvasPrompt": "Do you want to clear the current canvas to start with the new connection?",
+ "connection.close": "Close connection manager",
+ "connection.refreshHealth": "Refresh connection health",
+ "common.details": "Details",
+ "common.cancel": "Cancel",
+ "common.keep": "Keep",
+ "common.clear": "Clear",
+ "zoom.out": "Zoom out",
+ "zoom.in": "Zoom in",
+ "zoom.fit": "Fit zoom to screen",
+ "zoom.level": "Zoom level",
+ "settings.theme.mode": "Theme mode",
+ "diagnostics.category.canvas": "Canvas Integrity",
+ "diagnostics.category.output": "Output & Execution",
+ "diagnostics.category.session": "Session & Safety",
+ "diagnostics.category.notice": "Runtime Notices",
+ "diagnostics.summary.ok": "All systems OK",
+ "diagnostics.summary.warningCount": "{0} warning(s) detected",
+ "diagnostics.summary.errorCount": "{0} error(s) detected",
+ "diagnostics.canvasMigration": "Canvas Migration",
+ "diagnostics.recommendation.resaveFile": "Re-save the file to update it to the latest schema version.",
+ "diagnostics.canvasState.name": "Canvas State",
+ "diagnostics.canvasState.recommendation": "Add at least one {0} and one {1}",
+ "diagnostics.canvasState.empty": "Canvas is empty - no nodes present",
+ "diagnostics.canvasState.counts": "{0} node(s), {1} connection(s)",
+ "diagnostics.validation.name": "Validation Errors",
+ "diagnostics.validation.recommendation": "Fix highlighted nodes before running output preview",
+ "diagnostics.validation.errorWithWarnings": "{0} error(s) and {1} warning(s) in the graph",
+ "diagnostics.validation.warningOnly": "{0} warning(s) in the graph",
+ "diagnostics.validation.none": "No validation issues",
+ "diagnostics.orphan.name": "Orphan Nodes",
+ "diagnostics.orphan.recommendation": "Use the orphan cleanup action to remove unused nodes",
+ "diagnostics.orphan.count": "{0} node(s) not connected to any output",
+ "diagnostics.orphan.none": "No orphan nodes detected",
+ "diagnostics.naming.name": "Naming Conventions",
+ "diagnostics.naming.recommendation": "Use auto-fix alias naming when conformance is below 100%",
+ "diagnostics.naming.conformance": "Naming conformance: {0}%",
+ "diagnostics.naming.ok": "All aliases follow naming conventions (100%)",
+ "diagnostics.queryCompilation.name": "Live SQL Compilation",
+ "diagnostics.queryCompilation.recommendation": "Review SQL diagnostics in output when errors/warnings are reported.",
+ "diagnostics.queryCompilation.errorFallback": "Live SQL compilation reported errors.",
+ "diagnostics.queryCompilation.warningCounts": "{0} diagnostic item(s), {1} guardrail warning(s).",
+ "diagnostics.queryCompilation.ok": "Live SQL compiled without diagnostics.",
+ "diagnostics.previewSafety.name": "Preview Safety",
+ "diagnostics.previewSafety.recommendation": "Preview executes read-only statements only.",
+ "diagnostics.previewSafety.blocked": "Current SQL is mutating and blocked by Safe Preview mode.",
+ "diagnostics.previewSafety.ok": "Preview safety checks passed.",
+ "diagnostics.previewExecution.name": "Preview Execution",
+ "diagnostics.previewExecution.recommendation": "Run preview and inspect diagnostics for execution/runtime errors.",
+ "diagnostics.previewExecution.failed": "Preview execution failed.",
+ "diagnostics.previewExecution.cancelled": "Preview execution was cancelled.",
+ "diagnostics.previewExecution.done": "{0} row(s) in {1}ms.",
+ "diagnostics.previewExecution.none": "No preview execution issues detected.",
+ "diagnostics.ddlCompilation.name": "DDL Compilation",
+ "diagnostics.ddlCompilation.recommendation": "Fix DDL compile diagnostics before execution.",
+ "diagnostics.ddlCompilation.failed": "DDL compilation failed.",
+ "diagnostics.ddlCompilation.warningCount": "{0} warning(s) reported by DDL compiler.",
+ "diagnostics.ddlCompilation.ok": "DDL compilation succeeded.",
+ "diagnostics.ddlOutput.name": "DDL Output",
+ "diagnostics.ddlOutput.recommendation": "Add/complete DDL nodes until at least one statement is generated.",
+ "diagnostics.ddlOutput.none": "No DDL statements generated yet.",
+ "diagnostics.ddlOutput.lines": "{0} line(s) of DDL generated.",
+ "diagnostics.undo.name": "Undo History",
+ "diagnostics.undo.recommendation": "History is in-memory only; save your canvas regularly.",
+ "diagnostics.undo.saved": "Canvas is saved (no unsaved changes).",
+ "diagnostics.undo.unsavedDeep": "Unsaved changes with {0} undo steps.",
+ "diagnostics.undo.unsaved": "Unsaved changes - {0} undo step(s) available.",
+ "diagnostics.report.title": "AkkornStudio - Diagnostic Report",
+ "diagnostics.report.generated": "Generated",
+ "diagnostics.report.overall": "Overall",
+ "diagnostics.report.details": "Details",
+ "diagnostics.report.recommendation": "Recommendation",
+ "diagnostics.report.lastCheck": "Last Check",
+ "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
+ "node.datetimeFormat": "YYYY-MM-DDTHH:mm:ss",
+ "preview.providerLabel": "Provider",
+ "preview.ddlDiagnosticsHint": "Error/warning details are available in Diagnostics.",
+ "preview.schemaAnalysis.run": "Run Analysis",
+ "preview.schemaAnalysis.cancel": "Cancel",
+ "preview.schemaAnalysis.issues": "Issues",
+ "preview.schemaAnalysis.clearFilters": "Clear Filters",
+ "preview.schemaAnalysis.clearBlacklist": "Clear Blacklist",
+ "preview.schemaAnalysis.severity": "Severity",
+ "preview.schemaAnalysis.severity.info": "Info",
+ "preview.schemaAnalysis.severity.warning": "Warning",
+ "preview.schemaAnalysis.severity.critical": "Critical",
+ "preview.schemaAnalysis.rule": "Rule",
+ "preview.schemaAnalysis.rule.fkCatalogInconsistent": "FK catalog inconsistent",
+ "preview.schemaAnalysis.rule.missingFk": "Missing FK",
+ "preview.schemaAnalysis.rule.namingConventionViolation": "Naming convention violation",
+ "preview.schemaAnalysis.rule.lowSemanticName": "Low semantic name",
+ "preview.schemaAnalysis.rule.missingRequiredComment": "Missing required comment",
+ "preview.schemaAnalysis.rule.nf1HintMultiValued": "1NF hint: multi-valued",
+ "preview.schemaAnalysis.rule.nf2HintPartialDependency": "2NF hint: partial dependency",
+ "preview.schemaAnalysis.rule.nf3HintTransitiveDependency": "3NF hint: transitive dependency",
+ "preview.schemaAnalysis.minConfidence": "Min Confidence",
+ "preview.schemaAnalysis.tableFilter": "Table Filter",
+ "preview.schemaAnalysis.tableFilterWatermark": "schema.table",
+ "preview.schemaAnalysis.ignore": "Execution Filters",
+ "preview.schemaAnalysis.ignoreViews": "Ignore views and materialized views",
+ "preview.schemaAnalysis.blacklist": "Table blacklist",
+ "preview.schemaAnalysis.blacklistAdd": "Add",
+ "preview.schemaAnalysis.blacklistRemove": "Remove selected",
+ "preview.schemaAnalysis.ignoreTable.placeholder": "schema.table",
+ "preview.schemaAnalysis.details": "Details",
+ "preview.schemaAnalysis.evidence": "Evidence",
+ "preview.schemaAnalysis.suggestions": "Suggestions",
+ "preview.schemaAnalysis.ruleDiagnostics": "Rule Diagnostics",
+ "preview.schemaAnalysis.sqlCandidates": "SQL Candidates",
+ "preview.schemaAnalysis.copySql": "Copy SQL",
+ "preview.schemaAnalysis.applyToCanvas": "Apply to Canvas",
+ "preview.schemaAnalysis.summary.issues": "Issues:",
+ "preview.schemaAnalysis.summary.rawPrefix": "(raw:",
+ "preview.schemaAnalysis.summary.critical": "| Critical:",
+ "preview.schemaAnalysis.summary.warning": "| Warning:",
+ "preview.schemaAnalysis.summary.info": "| Info:",
+ "preview.schemaAnalysis.state.metadataUnavailable": "Metadata unavailable for structural analysis.",
+ "preview.schemaAnalysis.state.cancelled": "Analysis cancelled by the user.",
+ "preview.schemaAnalysis.state.partialTimeout": "Analysis finished partially due to timeout.",
+ "preview.schemaAnalysis.state.failed": "Structural analysis failed.",
+ "preview.schemaAnalysis.state.empty": "No inferable structural issue was detected.",
+ "preview.schemaAnalysis.state.noFilterMatch": "No issue matches the selected filters.",
+ "preview.schemaAnalysis.state.noIssueSelected": "No issue selected.",
+ "preview.schemaAnalysis.state.noSqlCandidate": "No SQL candidate available.",
+ "preview.schemaAnalysis.actionBlockedTooltip": "Action unavailable for the current risk level or capability.",
+ "common.navigate": "Navigate",
+ "common.close": "Close",
+ "common.esc": "Esc",
+ "common.ms": "ms",
+ "common.zero": "0",
+ "diagnostics.tip": "Tip: check Diagnostics whenever preview/output reports warnings or errors.",
+ "nodesList.empty": "No nodes found",
+ "nodesList.emptyHint": "Adjust the search term to explore available types",
+ "schema.emptyFiltered": "No objects found for the current filter",
+ "start.lastSnapshot": "Last snapshot",
+ "app.brandBadge": "VS",
+ "property.tab.properties": "Properties",
+ "property.tab.projectSettings": "Project Settings",
+ "property.nodeType": "NODE TYPE",
+ "property.selectNodeHint": "Select a node to edit its properties.",
+ "property.namingConventions": "Naming Conventions",
+ "property.aliasConvention": "Alias convention",
+ "property.enforceAliasNaming": "Enforce alias naming",
+ "property.warnReservedSql": "Warn on reserved SQL keywords",
+ "property.maxAliasLength": "Max alias length",
+ "property.maxAliasLengthDefault": "64",
+ "property.namingSettingsHint": "These settings are project-scoped and are used by naming and validation helpers.",
+ "start.tips": "Tips",
+ "start.tips.quick": "Quick tips",
+ "start.tips.item1": "1. Click New Diagram to start from scratch.",
+ "start.tips.item2": "2. Use templates to speed up prototyping.",
+ "start.tips.item3": "3. Open saved connections to load real tables.",
+ "start.tips.shortcut": "Shortcut: CTRL+SHIFT+P opens the command palette.",
+ "start.workspace": "WORKSPACE",
+ "start.resumeTitle": "Continue where you left off",
+ "start.resumeSubtitle": "Quickly resume a recent project or start a new diagram.",
+ "start.chip.quickFlow": "Quick flow",
+ "start.chip.templates": "Templates",
+ "start.chip.connections": "Connections",
+ "start.savedConnectionsTitle": "Saved Connections",
+ "start.savedConnectionsSubtitle": "Connect quickly to a database to load schema and tables.",
+ "start.noConnectionsTitle": "No connections configured yet",
+ "start.noConnectionsSubtitle": "Create a connection to explore real tables in the editor.",
+ "start.newConnection": "+ New Connection",
+ "start.recentProjectsTitle": "Recent Projects",
+ "start.searchRecent": "Search recent project...",
+ "start.quickActions": "Quick actions",
+ "start.quickActionsSubtitle": "Open an existing file or start a new diagram.",
+ "start.noRecentTitle": "No recent projects yet",
+ "start.noRecentSubtitle": "Use the quick actions card above to get started.",
+ "start.exploreTemplates": "Explore templates",
+ "start.templatesFavoritesHint": "Favorites on top",
+ "start.favoriteTemplate": "Favorite template",
+ "node.columnSetPreview": "ColumnSet preview",
+ "node.view": "VIEW",
+ "node.tableDefinition": "Table Definition",
+ "node.join": "JOIN",
+ "node.window.addPartition": "Add PARTITION BY slot",
+ "node.window.removePartition": "Remove PARTITION BY slot",
+ "node.window.addOrder": "Add ORDER BY slot",
+ "node.window.removeOrder": "Remove ORDER BY slot",
+ "sql.keyword.select": "SELECT",
+ "sql.keyword.from": "FROM",
+ "sql.keyword.join": "JOIN",
+ "sql.keyword.where": "WHERE",
+ "sql.keyword.limit": "LIMIT",
+ "sqlImporter.close": "Close SQL importer",
+ "sqlImporter.report.imported": "Imported",
+ "sqlImporter.report.partial": "Partial",
+ "sqlImporter.report.skipped": "Skipped",
+ "sqlImporter.confirmClearCanvas": "SQL import will clear the current canvas. Do you want to continue?",
+ "sqlImporter.confirmProceed": "Continue import",
+ "benchmark.close": "Close benchmark",
+ "benchmark.p95": "P95",
+ "benchmark.n": "N",
+ "liveSql.safePreview": "SAFE PREVIEW MODE",
+ "liveSql.title": "LIVE SQL",
+ "liveSql.blocked": "BLOCKED",
+ "liveSql.copy": "Copy",
+ "liveSql.format": "Format",
+ "liveSql.benchmark": "Benchmark",
+ "liveSql.explain": "Explain",
+ "liveSql.actionsHint": "Performance tools",
+ "ddl.dialog.title": "Execute DDL",
+ "ddl.dialog.execute": "Execute",
+ "ddl.dialog.cancel": "Cancel",
+ "ddl.dialog.close": "Close",
+ "ddl.dialog.stopOnError": "Stop on first failure",
+ "ddl.dialog.confirmDestructive": "I confirm execution of destructive statements (DROP TABLE)",
+ "ddl.dialog.reviewBeforeRun": "Review the DDL script before confirming.",
+ "ddl.dialog.confirmQuestion": "Confirm DDL execution on the connected database?",
+ "ddl.dialog.irreversibleWarning": "This action can change the schema irreversibly.",
+ "ddl.dialog.mustConfirmDestructive": "Confirm destructive execution to continue.",
+ "ddl.dialog.executing": "Executing...",
+ "ddl.execute.result.summary": "Statements: {0} | Success: {1} | Failures: {2} | Time: {3:0}ms",
+ "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
+ "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
+ "ddl.execute.result.failed": "Failed to execute DDL.",
+ "ddl.execute.result.cancelled": "Execution cancelled by the user.",
+ "ddl.execute.result.cancelledDetails": "DDL execution was interrupted before completion.",
+ "context.deleteSingle": "Delete {0}",
+ "context.deleteMultiple": "Delete {0} nodes",
+ "context.bringForward": "Bring Forward (Ctrl+PgUp)",
+ "context.sendBackward": "Send Backward (Ctrl+PgDown)",
+ "context.bringToFront": "Bring to Front (Ctrl+Shift+PgUp)",
+ "context.sendToBack": "Send to Back (Ctrl+Shift+PgDown)",
+ "context.normalizeLayers": "Normalize Layers",
+ "context.deleteWire": "Delete wire",
+ "context.addNode": "Add Node (Shift+A)",
+ "context.undoWithDescription": "Undo {0}",
+ "context.redo": "Redo",
+ "shortcuts.windowTitle": "Keyboard Shortcuts",
+ "shortcuts.headerTitle": "AkkornStudio - Shortcuts",
+ "shortcuts.headerHint": "Tip: use CTRL+SHIFT+P to open the Command Palette and search commands.",
+ "shortcuts.filterWatermark": "Filter shortcuts by key or action...",
+ "shortcuts.resultCount": "{0} shortcuts",
+ "shortcuts.resultFilter": "{0} result(s) for \"{1}\"",
+ "shortcuts.noneFound": "No shortcuts found.",
+ "shortcuts.section.fileGeneral": "File and General",
+ "shortcuts.section.editing": "Editing",
+ "shortcuts.section.canvasNavigation": "Canvas and Navigation",
+ "shortcuts.section.zoomPanPrecision": "Zoom, pan and precision",
+ "shortcuts.section.previewInspection": "Preview and Inspection",
+ "shortcuts.key.deleteOrBackspace": "Del or Backspace",
+ "shortcuts.key.middleDrag": "Middle mouse + drag",
+ "shortcuts.key.rightDrag": "Right mouse + drag",
+ "shortcuts.key.spaceDrag": "Space + drag",
+ "shortcuts.key.altLeftDrag": "Alt + left drag",
+ "shortcuts.key.arrows": "Arrows",
+ "shortcuts.key.shiftArrows": "Shift + Arrows",
+ "shortcuts.action.openShortcutScreen": "Open this shortcuts screen",
+ "shortcuts.action.newCanvas": "New canvas",
+ "shortcuts.action.openFile": "Open file",
+ "shortcuts.action.save": "Save",
+ "shortcuts.action.saveAs": "Save as",
+ "shortcuts.action.commandPalette": "Command Palette",
+ "shortcuts.action.undo": "Undo",
+ "shortcuts.action.redo": "Redo",
+ "shortcuts.action.selectAll": "Select all",
+ "shortcuts.action.deleteSelection": "Delete selection",
+ "shortcuts.action.closeOverlayCancel": "Close overlays / cancel actions",
+ "shortcuts.action.openNodeSearch": "Open node search",
+ "shortcuts.action.resetViewport": "Reset viewport",
+ "shortcuts.action.centerSelection": "Center selection",
+ "shortcuts.action.fitSelection": "Fit selection",
+ "shortcuts.action.autoLayout": "Auto Layout",
+ "shortcuts.action.toggleSnapToGrid": "Toggle Snap to Grid",
+ "shortcuts.action.bringForward": "Bring Forward",
+ "shortcuts.action.sendBackward": "Send Backward",
+ "shortcuts.action.bringToFront": "Bring to Front",
+ "shortcuts.action.sendToBack": "Send to Back",
+ "shortcuts.action.zoomInOut": "Zoom in / out",
+ "shortcuts.action.pan": "Pan",
+ "shortcuts.action.temporaryPan": "Temporary pan",
+ "shortcuts.action.alternatePan": "Alternate pan",
+ "shortcuts.action.fineNudge": "Fine nudge selection",
+ "shortcuts.action.fastNudge": "Fast nudge",
+ "shortcuts.action.togglePreview": "Toggle data preview",
+ "shortcuts.action.explainPlan": "Explain plan",
+ "shortcuts.action.runPreview": "Run preview",
+ "shortcuts.action.connectionManager": "Connection manager",
+ "shortcuts.action.flowVersionHistory": "Flow version history",
+ "shortcuts.resetAll": "Reset all",
+ "shortcuts.customized": "Customized",
+ "shortcuts.default": "Default",
+ "shortcuts.apply": "Apply",
+ "shortcuts.reset": "Reset",
+ "shortcuts.status.resetAllSuccess": "All shortcuts reset to defaults.",
+ "shortcuts.status.updated": "Shortcut updated.",
+ "shortcuts.status.reset": "Shortcut reset to default.",
+ "shortcuts.status.updateFailed": "Unable to update shortcut.",
+ "toast.severity.success": "Success",
+ "toast.severity.warning": "Warning",
+ "toast.severity.error": "Error",
+ "toast.details.success": "Success Details",
+ "toast.details.warning": "Warning Details",
+ "toast.details.error": "Error Details",
+ "diagnostics.area.cteEditor": "CTE Editor",
+ "diagnostics.area.viewEditor": "View Editor",
+ "diagnostics.area.subEditor": "Sub-editor",
+ "diagnostics.cteEditor.restoreParentFailed": "Failed to restore the parent canvas. CTE edits were discarded.",
+ "diagnostics.recommendation.reloadFileIfNeeded": "Reload the file if needed.",
+ "diagnostics.viewEditor.exitFailed": "Could not exit: {0}",
+ "diagnostics.viewEditor.canvasIncomplete": "the canvas is incomplete.",
+ "diagnostics.viewEditor.exitRecommendation": "Connect a valid ResultOutput or use the discard command.",
+ "diagnostics.viewEditor.restoreParentFailed": "Failed to restore the parent canvas. The subgraph was discarded.",
+ "diagnostics.subEditor.executeFailed": "Failed to execute editor action: {0}",
+ "diagnostics.subEditor.executeRecommendation": "Try again. If it persists, reload the canvas.",
+ "diagnostics.canvasMigration.openWarning": "Open: {0}",
+ "diagnostics.canvasMigration.sessionRestoreWarning": "Session restore: {0}",
+ "diagnostics.canvasMigration.versionRestoreWarning": "Version restore: {0}",
+ "diagnostics.recommendation.resaveLatestSchema": "Review diagnostics and re-save the canvas to persist the latest schema.",
+ "diagnostics.recommendation.saveMigratedSchema": "Review diagnostics and save the canvas to persist the migrated schema.",
+ "file.saveDialog.title": "Save Canvas",
+ "file.saveDialog.suggestedName": "Query1",
+ "file.save.success": "Canvas saved successfully.",
+ "file.save.failedWithReason": "Save failed: {0}",
+ "file.openDialog.title": "Open Canvas",
+ "file.openDialog.canvasType": "SQL Architect Canvas",
+ "file.open.failedWithReason": "Open failed: {0}",
+ "file.open.success": "Canvas opened successfully.",
+ "file.open.successWithWarnings": "Canvas opened with warnings.",
+ "session.restore.failedWithReason": "Restore failed: {0}",
+ "session.restore.successWithWarnings": "Session restored with warnings.",
+ "session.restore.success": "Session restored successfully.",
+ "export.documentation.dialogTitle": "Export Flow Documentation",
+ "export.documentation.success": "Documentation exported successfully.",
+ "export.documentation.failed": "Documentation export failed.",
+ "export.failed.pathPermissionsHint": "Check file path and permissions.",
+ "export.nodeNotFound": "No {0} Export node found on the canvas. Add one via the node search menu.",
+ "export.dialogTitleByExtension": "Export as {0}",
+ "export.success": "Export completed successfully.",
+ "export.failed": "Export failed.",
+ "fileHistory.currentFile.none": "No file selected",
+ "fileHistory.status.saveFirst": "Save the canvas first to enable local history.",
+ "fileHistory.status.noneFound": "No local versions found yet. Save this file to create history entries.",
+ "fileHistory.status.countAvailable": "{0} local version(s) available.",
+ "fileHistory.restore.failedWithReason": "Restore failed: {0}",
+ "fileHistory.restore.successFrom": "Restored version from {0}.",
+ "preview.status.cancelled": "Cancelled",
+ "preview.status.error": "Error",
+ "preview.status.ready": "Ready",
+ "preview.runningWithMs": "Running... {0}ms",
+ "preview.runningWithTimeout": "Running... {0}ms (timeout: {1}s)",
+ "preview.runningSlowWithTimeout": "Running... {0}ms (timeout: {1}s) · Slow query, timeout in {2}s",
+ "explain.errorWithReason": "Explain plan error: {0}",
+ "explain.noSql": "No SQL to explain. Build a query on the canvas first.",
+ "ddl.compilationFailed": "Compilation failed",
+ "ddl.compileErrorWithReason": "DDL compile error: {0}",
+ "command.undo.name": "Undo",
+ "command.undo.description": "Undo last action",
+ "command.redo.name": "Redo",
+ "command.redo.description": "Redo last undone action",
+ "command.addNode.name": "Add Node",
+ "command.addNode.description": "Open node search menu to add a node",
+ "command.bringForward.name": "Bring Forward",
+ "command.bringForward.description": "Move selected nodes one layer forward",
+ "command.sendBackward.name": "Send Backward",
+ "command.sendBackward.description": "Move selected nodes one layer backward",
+ "command.bringToFront.name": "Bring to Front",
+ "command.bringToFront.description": "Move selected nodes to top layer",
+ "command.sendToBack.name": "Send to Back",
+ "command.sendToBack.description": "Move selected nodes to bottom layer",
+ "command.normalizeLayers.name": "Normalize Layers",
+ "command.normalizeLayers.description": "Compact node layer indices to a clean 0..N order",
+ "tooltip.cleanupOrphans": "Remove orphan nodes not connected to the output (Ctrl+Z to undo)",
+ "main.orphanSuffix": "Orphan(s)",
+ "tooltip.autoFixAliasNaming": "Fix alias naming to snake_case (Ctrl+Z to undo)",
+ "main.namingPrefix": "Naming",
+ "fileHistory.compressedLabel": "Compressed:",
+ "schema.itemsSuffix": "item(s)",
+ "property.panel.title": "Properties",
+ "property.panel.multiSelected": "{0} nodes selected",
+ "sqlImporter.status.pasteSelect": "Paste a SELECT statement above, then click Import.",
+ "sqlImporter.status.inputTooLarge": "SQL input is too large ({0:N0} chars). Limit is {1:N0}. Split the query or increase the import limit.",
+ "sqlImporter.status.parsing": "Parsing SQL...",
+ "sqlImporter.status.done": "Done - {0} imported, {1} partial, {2} skipped.",
+ "sqlImporter.status.cancelledByUser": "Import cancelled by user.",
+ "sqlImporter.status.timeout": "Import timed out after {0:0.#}s. Try a smaller query or increase timeout.",
+ "sqlImporter.status.parseError": "Parse error: {0}",
+ "sqlImporter.status.clearConfirmationRequired": "SQL import will clear the current canvas. Confirm to continue.",
+ "sqlImporter.status.clearConfirmationCancelled": "Import cancelled. The current canvas was kept.",
+ "diagnostics.area.undoRedoTransaction": "Undo/Redo Transaction",
+ "undoRedo.rollbackExecuted": "Rollback executed for '{0}' ({1} operation(s) reverted).",
+ "undoRedo.rollbackRecommendation": "Review the canvas state and retry the action if needed.",
+ "node.preview.noCatalog": "No catalog available",
+ "connection.error.searchMenuNotInitialized": "search menu not initialized",
+ "connection.error.timeoutReachability": "Connection timed out - check that the server is reachable and increase the timeout if needed.",
+ "connection.error.authenticationFailedForProvider": "Authentication failed - verify username and password for {0}.",
+ "connection.error.databaseNotFoundForProvider": "Database not found - confirm the database name exists on {0}.",
+ "connection.error.hostNotFound": "Host not found - check the server address and DNS resolution.",
+ "connection.error.portRefused": "Port connection refused - check the port number and that the server is running / firewall rules allow access.",
+ "connection.error.sslTls": "SSL/TLS error - check the server's SSL configuration or disable SSL for local connections.",
+ "connection.error.timeoutOverloaded": "Connection timed out - the server may be overloaded or unreachable. Try increasing the timeout.",
+ "connection.error.insufficientPrivileges": "Insufficient privileges - the user may lack permission to connect to this database.",
+ "diagnostics.area.connection": "Connection",
+ "connection.warning.canvasMayContainOldTables": "The canvas may still contain tables from a previous connection.",
+ "connection.warning.canvasMayContainOldTablesRecommendation": "Clear the canvas manually or reconnect and choose keep/clear again.",
+ "undoRedo.transaction.unnamed": "unnamed transaction",
+ "benchmark.runLabelDefault": "Run 1",
+ "benchmark.runLabelPattern": "Run {0}",
+ "benchmark.status.failedWithReason": "Benchmark failed: {0}",
+ "benchmark.status.noSql": "No SQL to benchmark - build a query first.",
+ "benchmark.status.warmupProgress": "Warm-up {0}/{1}...",
+ "benchmark.status.iterationProgress": "Iteration {0}/{1}...",
+ "benchmark.status.done": "Done - {0}",
+ "benchmark.status.cancelled": "Benchmark cancelled.",
+ "app.windowTitle": "AkkornStudio",
+ "preview.error.safePreviewBlocked": "Safe Preview Mode: data-mutating commands (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) cannot be executed in preview.",
+ "preview.error.noActiveConnection": "No active database connection. Please connect to a database first.",
+ "sqlImporter.error.selectFromNotFound": "Could not find SELECT ... FROM in the query.",
+ "sqlImporter.error.fromClauseParseFailed": "Could not parse FROM clause.",
+ "sqlImporter.error.syntaxUnterminatedString": "Syntax error at line {0}, column {1}: unterminated string literal.",
+ "sqlImporter.error.missingClosingParenthesis": "missing closing ')'",
+ "sqlImporter.error.unexpectedClosingParenthesis": "unexpected ')'",
+ "sqlImporter.error.syntaxAtLineColumn": "Syntax error at line {0}, column {1}: {2}.",
+ "errorDiagnostics.safePreview.label": "Blocked by Safe Preview Mode",
+ "errorDiagnostics.safePreview.friendly": "This SQL contains a data-mutating command and cannot be executed in preview.",
+ "errorDiagnostics.safePreview.suggestion": "Remove or replace the mutating command (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) before running preview.",
+ "errorDiagnostics.connection.label": "Connection failed",
+ "errorDiagnostics.connection.friendly": "Could not reach the database server. The host may be down, unreachable, or blocking connections.",
+ "errorDiagnostics.connection.suggestion": "Verify the server address and port, ensure the database is running, and check firewall rules.",
+ "errorDiagnostics.authorization.label": "Authorization error",
+ "errorDiagnostics.authorization.friendly": "The current credentials do not have permission to perform this operation.",
+ "errorDiagnostics.authorization.suggestion": "Confirm the database user has SELECT privileges on the target table/schema, or contact your DBA.",
+ "errorDiagnostics.timeout.label": "Query timeout",
+ "errorDiagnostics.timeout.friendly": "The query took too long to complete and was cancelled by the server or client.",
+ "errorDiagnostics.timeout.suggestion": "Add a WHERE clause or LIMIT to reduce the result set, or increase the query timeout in connection settings.",
+ "errorDiagnostics.schema.label": "Schema error",
+ "errorDiagnostics.schema.friendly": "A referenced table, column, or object could not be found in the database.",
+ "errorDiagnostics.schema.suggestion": "Check that all table/column names are spelled correctly and that the schema matches the active connection.",
+ "errorDiagnostics.syntax.label": "SQL syntax error",
+ "errorDiagnostics.syntax.friendly": "The query contains a syntax error and could not be parsed by the database engine.",
+ "errorDiagnostics.syntax.suggestion": "Review the highlighted SQL for typos, mismatched parentheses, or unsupported clauses for the active provider.",
+ "errorDiagnostics.compatibility.label": "Compatibility error",
+ "errorDiagnostics.compatibility.friendly": "A function, operator, or syntax construct is not supported by the active database provider.",
+ "errorDiagnostics.compatibility.suggestion": "Switch to the correct provider in the SQL bar, or replace the unsupported construct with an equivalent.",
+ "errorDiagnostics.unknown.label": "Unexpected error",
+ "errorDiagnostics.unknown.friendly": "An error occurred while running the preview query.",
+ "errorDiagnostics.unknown.suggestion": "Check the technical details below and verify that your canvas is configured correctly.",
+ "error.mainWindow.invalidDataContext": "MainWindow DataContext must be a ShellViewModel.",
+ "error.mainWindow.canvasNotInitialized": "CanvasViewModel was not initialized.",
+ "error.mainWindow.ddlPreviewUnavailable": "DDL preview is unavailable for the current canvas.",
+ "themeJson.editor.template": "{\n \"meta\": { \"name\": \"Custom Theme\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
+ "themeJson.error.pasteBeforeApply": "Paste a theme JSON before applying.",
+ "themeJson.error.invalidJson": "Invalid JSON: {0}",
+ "themeJson.error.emptyPayload": "Invalid JSON: empty payload.",
+ "themeJson.error.invalidTheme": "Invalid theme: {0}",
+ "themeJson.error.appliedButSaveFailed": "Theme applied, but failed to persist: {0}",
+ "themeJson.success.appliedAndSaved": "JSON theme applied and saved.",
+ "themeJson.success.customRemoved": "Custom theme removed. Restart the app to fully return to the default theme.",
+ "themeJson.error.restoreDefaultFailed": "Failed to restore default theme: {0}",
+ "themeValidator.error.configNull": "Theme config is null.",
+ "themeValidator.warning.noSections": "Theme has no colors or typography sections; nothing to apply.",
+ "themeValidator.warning.invalidColor": "{0} has invalid color '{1}'. This key will be ignored.",
+ "themeValidator.warning.sizeOutOfRange": "{0}={1} is out of range (8..48). This key will be ignored.",
+ "queryExecutor.error.openConnectionMethodNotFound": "Cannot find OpenConnectionAsync method on orchestrator",
+ "queryExecutor.error.openConnectionInvokeFailed": "Failed to invoke OpenConnectionAsync",
+ "ddlImporter.warning.viewSelectNotReconstructable": "View '{0}': view SELECT cannot be reconstructed visually - edit it manually in the subcanvas.",
+ "ddlImporter.error.tableNotFoundInMetadata": "Table '{0}' was not found in current metadata.",
+ "main.window.untitled": "Untitled",
+ "main.subEditor.noSeedProvided": "No {0} sub-editor seed was provided.",
+ "main.layerOrder.bringToFront": "Bring to front",
+ "main.layerOrder.sendToBack": "Send to back",
+ "main.layerOrder.bringForward": "Bring forward",
+ "main.layerOrder.sendBackward": "Send backward",
+ "main.layerOrder.normalizeLayers": "Normalize layers",
+ "export.fileType.html": "HTML Files",
+ "export.fileType.json": "JSON Files",
+ "export.fileType.csv": "CSV Files",
+ "export.fileType.excel": "Excel Files",
+ "commandPalette.templatePrefix": "Template: {0}",
+ "themeLoader.status.notFoundWithPath": "Theme file not found: {0}",
+ "themeLoader.status.deserializedNull": "Theme JSON deserialized to null.",
+ "themeLoader.status.loaded": "Theme JSON loaded successfully.",
+ "credential.error.ciphertextTooShort": "Ciphertext blob is too short.",
+ "credential.error.dpapiWindowsOnly": "DPAPI is only available on Windows.",
+ "credential.warning.loadVaultFailed": "Failed to load credential vault '{0}': {1}",
+ "credential.warning.persistVaultFailed": "Failed to persist credential vault '{0}': {1}",
+ "snippetStore.warning.loadFailed": "Failed to load snippets from '{0}': {1}",
+ "snippetStore.warning.saveFailed": "Failed to save snippets: {0}",
+ "flowVersionStore.warning.loadFailed": "Failed to load flow versions from '{0}': {1}",
+ "flowVersionStore.warning.saveFailed": "Failed to save flow versions: {0}",
+ "queryExecutor.error.queryEmpty": "Query cannot be empty",
+ "queryExecutor.error.providerNotSupported": "Provider {0} is not supported",
+ "queryExecutor.error.singleStatementOnly": "Preview accepts a single SQL statement only.",
+ "queryExecutor.error.queryEmptyWithPeriod": "Query cannot be empty.",
+ "queryExecutor.error.readOnlyOnly": "Preview mode only supports read-only SQL statements.",
+ "queryExecutor.error.namedParametersNotSupported": "Preview mode does not support bound parameters in execution SQL. Inline safe literals or run the query outside preview.",
+ "queryExecutor.error.positionalParametersNotSupported": "Preview mode does not support positional parameter placeholders ('?' or '$1').",
+ "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "Align selected nodes to the bottom edge",
+ "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "Align selected nodes to the leftmost edge",
+ "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "Align selected nodes to the rightmost edge",
+ "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "Align selected nodes to the topmost edge",
+ "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "Apply CTE sub-canvas edits and return to the parent canvas",
+ "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "Arrange nodes into logical columns automatically",
+ "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "Centre selected nodes on a horizontal axis",
+ "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "Centre selected nodes on a vertical axis",
+ "commandPalette.description.clear_canvas_and_start_fresh": "Clear canvas and start fresh",
+ "commandPalette.description.clear_node_selection": "Clear node selection",
+ "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "Convert aliases to the convention configured in project settings",
+ "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "Create checkpoints, compare versions side-by-side and restore a previous canvas state",
+ "commandPalette.description.delete_the_selected_nodes": "Delete the selected nodes",
+ "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "Discard current sub-editor edits and return to the parent canvas",
+ "commandPalette.description.execute_the_current_query_in_preview": "Execute the current query in preview",
+ "commandPalette.description.fit_all_nodes_into_the_visible_area": "Fit all nodes into the visible area",
+ "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "Generate CSV file from the first CSV Export node",
+ "commandPalette.description.generate_html_file_from_the_first_html_export_node": "Generate HTML file from the first HTML Export node",
+ "commandPalette.description.generate_json_file_from_the_first_json_export_node": "Generate JSON file from the first JSON Export node",
+ "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "Generate XLSX workbook from the first Excel Export node",
+ "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "Inspect the query execution plan — see scan types, join strategies, and cost estimates",
+ "commandPalette.description.load_a_vsaq_canvas_file": "Load a .vsaq canvas file",
+ "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "Measure avg / median / p95 latency of the current SQL over N iterations",
+ "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "Open isolated sub-canvas editor for the selected CTE Definition node",
+ "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "Open local file version history created on each save and restore previous saved snapshots",
+ "commandPalette.description.open_output_preview_modal_for_the_active_mode": "Open output preview modal for the active mode",
+ "commandPalette.description.open_shortcut_reference_screen": "Open shortcut reference screen",
+ "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "Open the connection manager to add, edit or switch database connections",
+ "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "Paste a SELECT statement and generate nodes automatically — FROM, JOIN, WHERE, LIMIT are supported",
+ "commandPalette.description.remove_all_nodes_not_connected_to_output": "Remove all nodes not connected to output",
+ "commandPalette.description.reset_zoom_and_pan_to_default": "Reset zoom and pan to default",
+ "commandPalette.description.save_canvas_to_a_new_file": "Save canvas to a new file",
+ "commandPalette.description.save_current_canvas": "Save current canvas",
+ "commandPalette.description.save_markdown_documentation_of_the_current_flow": "Save Markdown documentation of the current flow",
+ "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "Save the selected nodes as a reusable snippet — insert it later via the node search menu (⇧A)",
+ "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "Scan all table-source nodes on the canvas for possible join relationships based on FK conventions and naming patterns",
+ "commandPalette.description.select_all_nodes_on_canvas": "Select all nodes on canvas",
+ "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "Snap node positions to 16px grid (Ctrl+G)",
+ "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "Spread selected nodes with equal horizontal spacing",
+ "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "Spread selected nodes with equal vertical spacing",
+ "commandPalette.description.zoom_into_the_canvas": "Zoom into the canvas",
+ "commandPalette.description.zoom_out_of_the_canvas": "Zoom out of the canvas",
+ "commandPalette.name.align_bottom": "Align Bottom",
+ "commandPalette.name.align_left": "Align Left",
+ "commandPalette.name.align_right": "Align Right",
+ "commandPalette.name.align_top": "Align Top",
+ "commandPalette.name.analyze_all_joins": "Analyze All Joins",
+ "commandPalette.name.auto_fix_naming": "Auto-Fix Naming",
+ "commandPalette.name.auto_layout": "Auto Layout",
+ "commandPalette.name.center_horizontally": "Center Horizontally",
+ "commandPalette.name.center_vertically": "Center Vertically",
+ "commandPalette.name.cleanup_orphans": "Cleanup Orphans",
+ "commandPalette.name.delete_selected": "Delete Selected",
+ "commandPalette.name.deselect_all": "Deselect All",
+ "commandPalette.name.discard_and_exit_editor": "Discard and Exit Editor",
+ "commandPalette.name.distribute_horizontally": "Distribute Horizontally",
+ "commandPalette.name.distribute_vertically": "Distribute Vertically",
+ "commandPalette.name.edit_selected_cte": "Edit Selected CTE",
+ "commandPalette.name.exit_cte_editor": "Exit CTE Editor",
+ "commandPalette.name.explain_plan": "Explain Plan",
+ "commandPalette.name.export_csv": "Export CSV",
+ "commandPalette.name.export_documentation": "Export Documentation",
+ "commandPalette.name.export_excel": "Export Excel",
+ "commandPalette.name.export_html": "Export HTML",
+ "commandPalette.name.export_json": "Export JSON",
+ "commandPalette.name.file_save_load_history": "File Save/Load History",
+ "commandPalette.name.fit_to_screen": "Fit to Screen",
+ "commandPalette.name.flow_version_history": "Flow Version History",
+ "commandPalette.name.import_sql_to_graph": "Import SQL to Graph",
+ "commandPalette.name.keyboard_shortcuts": "Keyboard Shortcuts",
+ "commandPalette.name.manage_connections": "Manage Connections",
+ "commandPalette.name.new_canvas": "New Canvas",
+ "commandPalette.name.open_file": "Open File",
+ "commandPalette.name.reset_viewport": "Reset Viewport",
+ "commandPalette.name.run_preview": "Run Preview",
+ "commandPalette.name.run_query_benchmark": "Run Query Benchmark",
+ "commandPalette.name.save": "Save",
+ "commandPalette.name.save_as": "Save As",
+ "commandPalette.name.save_selection_as_snippet": "Save Selection as Snippet",
+ "commandPalette.name.select_all": "Select All",
+ "commandPalette.name.toggle_preview": "Toggle Preview",
+ "commandPalette.name.toggle_snap_to_grid": "Toggle Snap to Grid",
+ "commandPalette.name.zoom_in": "Zoom In",
+ "commandPalette.name.zoom_out": "Zoom Out",
+ "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 percent restore zoom pan viewport",
+ "commandPalette.tags.align_bottom_edge_selection_nodes": "align bottom edge selection nodes",
+ "commandPalette.tags.align_center_middle_horizontal_nodes": "align center middle horizontal nodes",
+ "commandPalette.tags.align_center_middle_vertical_nodes": "align center middle vertical nodes",
+ "commandPalette.tags.align_left_edge_selection_nodes": "align left edge selection nodes",
+ "commandPalette.tags.align_right_edge_selection_nodes": "align right edge selection nodes",
+ "commandPalette.tags.align_top_edge_selection_nodes": "align top edge selection nodes",
+ "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout view reset zoom",
+ "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark performance latency timing profile measure speed",
+ "commandPalette.tags.clear_selection": "clear selection",
+ "commandPalette.tags.connection_database_server_host_provider_switch": "connection database server host provider switch",
+ "commandPalette.tags.create_insert_search_transform": "create insert search transform",
+ "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas exit apply back",
+ "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte view subcanvas discard exit force",
+ "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursive editor subgraph subcanvas isolate",
+ "commandPalette.tags.data_results_table_panel": "data results table panel",
+ "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribute space equal horizontal nodes",
+ "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribute space equal vertical nodes",
+ "commandPalette.tags.execute_run_sql_query_results": "execute run sql query results",
+ "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan execution cost scan index join performance",
+ "commandPalette.tags.export_csv_file_tabular_output_save": "export csv file tabular output save",
+ "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "export excel xlsx file tabular output spreadsheet save",
+ "commandPalette.tags.export_html_file_output_report_save": "export html file output report save",
+ "commandPalette.tags.export_json_file_output_save": "export json file output save",
+ "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "export markdown doc documentation flow save md",
+ "commandPalette.tags.export_persist_copy": "export persist copy",
+ "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "file history save load backup versions restore local",
+ "commandPalette.tags.forward_history": "forward history",
+ "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "help shortcuts hotkeys keyboard reference",
+ "commandPalette.tags.highlight_mark_all_nodes": "highlight mark all nodes",
+ "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "import sql paste convert graph reverse engineer query",
+ "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analyze suggest detect foreign key relationships heuristic",
+ "commandPalette.tags.layer_z_order_back_selected_nodes": "layer z-order back selected nodes",
+ "commandPalette.tags.layer_z_order_backward_selected_nodes": "layer z-order backward selected nodes",
+ "commandPalette.tags.layer_z_order_forward_selected_nodes": "layer z-order forward selected nodes",
+ "commandPalette.tags.layer_z_order_front_selected_nodes": "layer z-order front selected nodes",
+ "commandPalette.tags.layer_z_order_normalize_compact": "layer z-order normalize compact",
+ "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout arrange columns auto organize readability",
+ "commandPalette.tags.load_import_vsaq": "load import vsaq",
+ "commandPalette.tags.magnify_enlarge": "magnify enlarge",
+ "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "orphan unused disconnected clean delete nodes",
+ "commandPalette.tags.persist_write_disk": "persist write disk",
+ "commandPalette.tags.remove_erase_nodes": "remove erase nodes",
+ "commandPalette.tags.rename_alias_fix_naming_convention": "rename alias fix naming convention",
+ "commandPalette.tags.reset_clear_blank": "reset clear blank",
+ "commandPalette.tags.revert_back_history": "revert back history",
+ "commandPalette.tags.shrink_reduce": "shrink reduce",
+ "commandPalette.tags.snap_grid_align_precision_position": "snap grid align precision position",
+ "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet save selection reuse template favorite bookmark",
+ "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "version history checkpoint diff restore snapshot compare undo flow",
+ "sqlEditor.diffPreview.title": "Transactional Diff Preview",
+ "sqlEditor.mutation.confirmExecute": "Confirm Execute",
+ "sqlEditor.tab.closeAnyway": "Close Anyway",
+ "sqlEditor.tab.keepTab": "Keep Tab",
+ "sqlEditor.status.ready": "Ready.",
+ "sqlEditor.telemetry.none": "No execution telemetry yet.",
+ "sqlEditor.telemetry.summary": "Statements: {0} Success: {1} Failed: {2} Total: {3} ms",
+ "sqlEditor.telemetry.errors.none": "No aggregated errors.",
+ "sqlEditor.diff.none": "No transactional diff preview available.",
+ "sqlEditor.mutation.estimate.none": "No mutation estimate available.",
+ "sqlEditor.mutation.estimate.value": "Estimated affected rows: {0}",
+ "sqlEditor.mutation.estimate.unavailable": "Could not estimate affected rows automatically.",
+ "sqlEditor.tab.closePending": "Unsaved changes detected. Confirm tab close.",
+ "sqlEditor.tab.noPendingClose": "No tab close pending.",
+ "sqlEditor.tab.manyWarning": "High tab count: {0} open tabs.",
+ "sqlEditor.mutation.pending.none": "No pending mutation confirmation.",
+ "sqlEditor.mutation.pending.required": "Mutation requires confirmation before execution.",
+ "sqlEditor.message.empty": "Execute a statement to see messages.",
+ "sqlEditor.message.success": "Execution completed successfully.",
+ "sqlEditor.result.summary.empty": "Rows: - Time: -",
+ "sqlEditor.result.summary": "Rows: {0} Time: {1} ms",
+ "sqlEditor.file.save.canceled": "Save canceled.",
+ "sqlEditor.file.save.noPath": "No target path selected.",
+ "sqlEditor.file.save.success": "SQL file saved.",
+ "sqlEditor.file.save.failed": "Save failed.",
+ "sqlEditor.file.open.failed": "Open failed.",
+ "sqlEditor.file.open.notFound": "Selected SQL file was not found.",
+ "sqlEditor.file.open.success": "SQL file opened.",
+ "sqlEditor.status.executing": "Executing SQL...",
+ "sqlEditor.status.executingScript": "Executing SQL script...",
+ "sqlEditor.status.executingStep": "Executing {0}/{1}...",
+ "sqlEditor.status.canceling": "Canceling execution...",
+ "sqlEditor.status.executingConfirmedMutation": "Executing confirmed mutation...",
+ "sqlEditor.status.mutationCanceled": "Mutation execution canceled.",
+ "sqlEditor.detail.statementNotExecuted": "Statement was not executed.",
+ "sqlEditor.status.success": "Execution succeeded.",
+ "sqlEditor.detail.rowsAndTime": "{0} row(s) in {1} ms.",
+ "sqlEditor.status.canceled": "Execution canceled.",
+ "sqlEditor.status.failed": "Execution failed.",
+ "sqlEditor.status.confirmationRequired": "Confirmation required before execution.",
+ "sqlEditor.error.mutationConfirmationRequired": "Mutation confirmation required.",
+ "sqlEditor.result.tabTitle": "Result {0}",
+ "sqlEditor.tab.closeRequiresConfirmation": "Tab close requires confirmation.",
+ "sqlEditor.tab.unsavedDetail": "This tab has unsaved changes.",
+ "sqlEditor.tab.closed": "Tab closed.",
+ "sqlEditor.tab.closeCanceled": "Tab close canceled.",
+ "sqlEditor.tab.closeCanceledDetail": "Unsaved tab kept open.",
+ "sqlEditor.error.noStatementSelected": "No SQL statement selected for execution.",
+ "sqlEditor.error.noConnection": "No active database connection for SQL execution.",
+ "sqlEditor.error.executionCanceled": "SQL execution was canceled.",
+ "sqlEditor.tab.scriptTitle": "Script {0}",
+ "sqlEditor.guard.delete.noWhere.message": "DELETE without WHERE can remove all rows.",
+ "sqlEditor.guard.delete.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
+ "sqlEditor.guard.delete.trivialWhere.message": "DELETE has a trivially true WHERE clause.",
+ "sqlEditor.guard.delete.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
+ "sqlEditor.guard.update.noWhere.message": "UPDATE without WHERE can affect all rows.",
+ "sqlEditor.guard.update.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
+ "sqlEditor.guard.update.trivialWhere.message": "UPDATE has a trivially true WHERE clause.",
+ "sqlEditor.guard.update.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
+ "sqlEditor.guard.insert.noColumnList.message": "INSERT without explicit column list is fragile against schema changes.",
+ "sqlEditor.guard.insert.noColumnList.recommendation": "Prefer INSERT INTO table(col1, col2, ...) VALUES (...).",
+ "sqlEditor.guard.ddl.message": "DDL statement may cause structural changes in the database.",
+ "sqlEditor.guard.ddl.recommendation": "Confirm execution only when schema changes are intended.",
+ "sqlEditor.diff.unavailable.noPreview": "No transactional diff preview available for this statement.",
+ "sqlEditor.diff.unavailable.parseError": "Could not parse mutation target for transactional diff preview.",
+ "sqlEditor.diff.unavailable.connection": "Transactional diff preview unavailable due to connection or query limitations.",
+ "sqlEditor.diff.deleteSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, affected {2}, total rows after {3}.",
+ "sqlEditor.diff.updateSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, candidate rows affected {2}, total rows after {3}.",
+ "sqlEditor.diff.unavailable.unsupportedStatement": "Transactional diff preview currently supports UPDATE and DELETE only.",
+ "sqlEditor.results.title": "Results",
+ "sqlEditor.results.filterWatermark": "Filter results",
+ "sqlEditor.results.rows.countZero": "0 rows",
+ "sqlEditor.results.rows.countSingle": "{0} rows",
+ "sqlEditor.results.rows.countFiltered": "{0} of {1} rows",
+ "sqlEditor.results.context.copyCell": "Copy Cell",
+ "sqlEditor.results.context.copyRow": "Copy Row",
+ "sqlEditor.results.context.hideColumn": "Hide Column",
+ "sqlEditor.results.context.showAllColumns": "Show All Columns",
+ "sqlEditor.sidebar.messages": "MESSAGES",
+ "sqlEditor.sidebar.history": "HISTORY",
+ "sqlEditor.sidebar.connection.none": "No connection",
+ "sqlEditor.sidebar.connection.connectHint": "Connect to load metadata and execute queries.",
+ "sqlEditor.sidebar.connection.connect": "Connect",
+ "sqlEditor.sidebar.schema.searchWatermark": "Search table or column",
+ "sqlEditor.sidebar.schema.reloadTooltip": "Reload metadata",
+ "sqlEditor.sidebar.schema.connectHint": "Connect to view the full schema.",
+ "sqlEditor.history.searchWatermark": "Search history",
+ "sqlEditor.history.navigationHint": "Arrow keys navigate history, Enter runs selected, Esc clears the search.",
+ "sqlEditor.history.noSearchResults": "No items found for this search.",
+ "sqlEditor.history.use": "Use",
+ "sqlEditor.history.copy": "Copy",
+ "sqlEditor.history.run": "Run",
+ "sqlEditor.history.copiedFromHistory": "SQL copied from history.",
+ "sqlEditor.toast.scriptSuccessTitle": "Script executed.",
+ "sqlEditor.toast.scriptSuccessDetail": "{0} statement(s) executed successfully.",
+ "sqlEditor.toast.scriptWarningTitle": "Script executed with failures.",
+ "sqlEditor.toast.scriptWarningDetail": "{0} of {1} statement(s) failed.",
+ "sqlEditor.toast.resultErrorTitle": "Failed to execute statement.",
+ "sqlEditor.toast.resultSuccessTitle": "Execution completed successfully.",
+ "sqlEditor.export.action": "Export Report",
+ "sqlEditor.openSql.pickerTitle": "Open SQL File",
+ "sqlEditor.saveSql.fileType": "SQL Files",
+ "sqlEditor.saveSql.pickerTitle": "Save SQL File",
+ "sqlEditor.export.pickerTitle": "Export SQL Data",
+ "sqlEditor.export.status.noResultTitle": "No execution result available for export.",
+ "sqlEditor.export.status.noResultDetail": "Execute a query first.",
+ "sqlEditor.export.status.successTitle": "Report exported.",
+ "sqlEditor.export.status.failedTitle": "Failed to export report.",
+ "sqlEditor.export.fileType.html": "HTML File",
+ "sqlEditor.export.fileType.json": "JSON File",
+ "sqlEditor.export.fileType.csv": "CSV File",
+ "sqlEditor.export.fileType.xlsx": "Excel Workbook",
+ "sqlEditor.export.defaultFileBase": "report",
+ "sqlEditor.export.defaultTitle": "SQL Report",
+ "sqlEditor.export.error.typeRequired": "A report type must be selected before export.",
+ "sqlEditor.export.type.html.title": "HTML full-feature report",
+ "sqlEditor.export.type.html.description": "Standalone, SQL-first HTML artifact for offline audit.",
+ "sqlEditor.export.type.json.title": "JSON execution contract",
+ "sqlEditor.export.type.json.description": "Machine-readable payload with SQL, metadata and execution result.",
+ "sqlEditor.export.type.csv.title": "CSV data export",
+ "sqlEditor.export.type.csv.description": "Tabular result data only, suitable for spreadsheet tools.",
+ "sqlEditor.export.type.xlsx.title": "Excel workbook export",
+ "sqlEditor.export.type.xlsx.description": "Spreadsheet workbook with query result data only.",
+ "sqlEditor.export.dialog.windowTitle": "Export SQL Data",
+ "sqlEditor.export.dialog.title": "Export SQL Data",
+ "sqlEditor.export.dialog.subtitle": "Choose the artifact format and metadata before exporting.",
+ "sqlEditor.export.dialog.confirm": "Export",
+ "sqlEditor.export.dialog.fileNameWatermark": "report.html",
+ "sqlEditor.export.dialog.titleWatermark": "SQL Report",
+ "sqlEditor.export.dialog.descriptionWatermark": "Additional context for auditors and teammates.",
+ "sqlEditor.export.dialog.section.reportType": "REPORT TYPE",
+ "sqlEditor.export.dialog.section.fileName": "FILE NAME",
+ "sqlEditor.export.dialog.section.reportTitle": "TITLE",
+ "sqlEditor.export.dialog.section.description": "DESCRIPTION",
+ "sqlEditor.export.dialog.section.options": "OPTIONS",
+ "sqlEditor.export.option.includeSchema": "Include output schema",
+ "sqlEditor.export.option.includeNodeDetails": "Include node/connection placeholders in JSON",
+ "sqlEditor.export.option.includeMetadata": "Include optional metadata",
+ "sqlEditor.export.option.useDashForEmpty": "Use '-' for empty fields",
+ "sqlEditor.export.badge.offline": "OFFLINE READY",
+ "sqlEditor.export.badge.structured": "STRUCTURED PAYLOAD",
+ "sqlEditor.export.badge.dataOnly": "DATA ONLY"
+}
diff --git a/src/DBWeaver.UI/Assets/Localization/es-ES.json b/src/AkkornStudio.UI/Assets/Localization/es-ES.json
similarity index 98%
rename from src/DBWeaver.UI/Assets/Localization/es-ES.json
rename to src/AkkornStudio.UI/Assets/Localization/es-ES.json
index ec12deee..420e29ee 100644
--- a/src/DBWeaver.UI/Assets/Localization/es-ES.json
+++ b/src/AkkornStudio.UI/Assets/Localization/es-ES.json
@@ -1,1105 +1,1105 @@
-{
- "main.brand": "DBWeaver",
- "main.tab.query1": "Query 1",
- "main.new": "New",
- "main.open": "Open",
- "main.save": "Save",
- "main.history": "History",
- "main.layout": "Layout",
- "main.preview": "Preview",
- "main.undo": "Undo",
- "main.redo": "Redo",
- "main.cleanupOrphans": "Cleanup orphan nodes",
- "main.autoFixAliasNaming": "Auto-fix alias naming",
- "main.autoLayoutCanvas": "Auto layout canvas",
- "main.toggleDataPreview": "Toggle data preview",
- "main.language": "Language",
- "main.restore.prompt": "Previous session found — restore the last canvas?",
- "main.restore.button": "Restore session",
- "main.cteEditor.editingPrefix": "Editing CTE: ",
- "main.cteEditor.backToCanvas": "Back to Canvas",
- "main.cteEditor.exitA11y": "Exit CTE editor",
- "main.viewEditor.editingPrefix": "DDL > View: ",
- "main.viewEditor.backToCanvas": "Back to DDL",
- "main.viewEditor.exitA11y": "Exit view editor",
- "connection.title": "Connection Manager",
- "connection.subtitle": "Configure, pruebe y active conexiones sin salir del flujo",
- "connection.none": "No connection",
- "connection.active": "ACTIVE",
- "connection.health.online": "Online",
- "connection.health.degraded": "Degraded",
- "connection.health.offline": "Offline",
- "connection.tooltip.none": "No active connection — click to manage",
- "connection.ping": "Ping",
- "connection.saved": "SAVED CONNECTIONS",
- "connection.new": "New Connection",
- "connection.selectOrCreate": "Select a connection or create a new one",
- "connection.name": "Connection Name",
- "connection.provider": "Provider",
- "connection.host": "Host",
- "connection.port": "Port",
- "connection.database": "Database",
- "connection.sqlitePath": "SQLite Path",
- "connection.sqliteBrowse": "Browse",
- "connection.sqliteCreate": "Create",
- "connection.username": "Username",
- "connection.password": "Password",
- "connection.timeout": "Timeout (seconds)",
- "connection.test": "Test",
- "connection.save": "Save",
- "connection.connect": "Connect",
- "connection.action.testConnection": "Test connection",
- "connection.action.saveConnection": "Save connection",
- "connection.action.connectConnection": "Connect connection",
- "connection.status.connecting": "Conectando...",
- "connection.status.connected": "Conectado",
- "connection.status.testing": "Probando...",
- "connection.status.failedPrefix": "Falló la conexión",
- "connection.status.metadataUnavailable": "Falló la conexión: metadatos no disponibles.",
- "connection.status.highLatency": "alta latencia",
- "connection.watermark.name": "Mi BD de Producción",
- "connection.watermark.host": "localhost",
- "connection.watermark.port": "5432",
- "connection.watermark.database": "database_name",
- "connection.watermark.username": "user",
- "connection.watermark.password": "••••••••",
- "connection.watermark.timeout": "30",
- "main.connectingDb": "Connecting to database...",
- "main.emptyHint": "Press ⇧A to add your first node, or drag a table from the sidebar",
- "status.nodesSeparator": " nodes · ",
- "status.connectionsSuffix": " connections",
- "status.undo": "Undo: ",
- "status.shortcuts": "⇧A Nodes · F3 Preview · Ctrl+Z Undo · Del Remove · Alt+Drag Pan",
- "connection.disconnect": "Disconnect",
- "connection.action.disconnectConnection": "Disconnect connection",
- "connectionTab.active": "ACTIVE CONNECTION",
- "connectionTab.none": "No active connection",
- "connectionTab.saved": "SAVED CONNECTIONS",
- "connectionTab.new": "+ New Connection",
- "schema.database": "DATABASE",
- "schema.search": "Search tables, columns...",
- "schema.loading": "Searching tables, columns...",
- "schema.noConnection": "No Connection",
- "schema.noConnectionHint": "Connect to a database to see tables, columns, and relationships",
- "schema.emptyNoTables": "No tables found",
- "fileHistory.title": "Save/Load Version History",
- "fileHistory.reload": "Reload",
- "fileHistory.restoreSelected": "Restore selected",
- "fileHistory.empty": "No local versions yet",
- "fileHistory.emptyHint": "Save this file to generate version history.",
- "preview.title": "Data Preview",
- "preview.subtitle": "Review data and diagnostics before continuing",
- "preview.run": "Run",
- "preview.cancel": "Cancel",
- "preview.tab.preview": "Preview",
- "preview.tab.sql": "SQL",
- "preview.close": "Close preview",
- "preview.running": "Running preview query… ",
- "preview.clickCancel": "Click Cancel to stop",
- "preview.cancelled": "Query cancelled",
- "preview.runAgain": "Press Run to execute again",
- "preview.failed": "Preview execution failed",
- "preview.technical": "TECHNICAL DETAILS",
- "preview.noData": "No data yet",
- "preview.f3Hint": "Press F3 or Space to run the current query",
- "sqlImporter.title": "Import SQL to Graph",
- "sqlImporter.subtitle": "Paste a SELECT statement — nodes are created automatically",
- "sqlImporter.sqlStatement": "SQL STATEMENT",
- "sqlImporter.supported": "Supported: ",
- "sqlImporter.import": "Import",
- "sqlImporter.report": "CONVERSION REPORT",
- "sqlEditor.mutation.dialogTitle": "Confirmacion de cambio",
- "sqlEditor.mutation.dialogSubtitle": "Revisa el impacto antes de confirmar la ejecucion",
- "search.empty": "No nodes found",
- "search.emptyHint": "Try searching for UPPER, JSON, CAST, AND…",
- "search.shortcut": "⇧A",
- "search.spawn": "Spawn",
- "commandPalette.empty": "Ningún comando coincide con tu búsqueda",
- "commandPalette.search": "Buscar comando",
- "commandPalette.shortcut": "CTRL+SHIFT+P",
- "commandPalette.execute": "Ejecutar",
- "context.editCte": "Edit Selected CTE",
- "context.editViewSubcanvas": "Edit View Subcanvas",
- "explain.title": "Explain Plan",
- "explain.sql": "SQL",
- "explain.option.analyze": "Analizar",
- "explain.option.buffers": "Buffers",
- "explain.badge.simulated": "SIMULADO",
- "explain.timing.planning": "Planificacion:",
- "explain.timing.execution": "Ejecucion:",
- "explain.section.snapshotComparison": "Comparacion de instantaneas",
- "explain.section.indexRecommendations": "Recomendaciones de indices",
- "explain.section.history": "Historial",
- "explain.detail.estimated": "Estimadas",
- "explain.detail.actual": "Actuales",
- "explain.detail.error": "Error",
- "explain.detail.time": "Tiempo",
- "explain.detail.loops": "Bucles",
- "explain.rerun": "Re-run",
- "explain.alertSuffix": " expensive operation(s) detected — consider adding indexes",
- "explain.running": "Running EXPLAIN…",
- "explain.failed": "⚠ EXPLAIN failed",
- "explain.noPlan": "No plan yet",
- "explain.rerunHint": "Press Re-run to execute EXPLAIN",
- "explain.header.operation": "OPERACIÓN",
- "explain.header.cost": "COSTO",
- "explain.header.rows": "FILAS",
- "explain.header.alert": "ALERTA",
- "explain.mode.list": "Lista",
- "explain.mode.tree": "Arbol",
- "explain.action.snapshot": "Guardar snapshot",
- "explain.action.copyJson": "Copiar JSON",
- "explain.action.copyText": "Copiar texto",
- "explain.action.saveJson": "Guardar .json",
- "explain.action.openDalibo": "Abrir en Dalibo",
- "explain.legend.seqscan": "SEQ SCAN — full table read, no index",
- "explain.legend.sort": "SORT — in-memory sort",
- "explain.legend.hash": "HASH — hash join",
- "explain.escClose": "Esc to close",
- "flowVersion.title": "Flow Version History",
- "flowVersion.subtitle": "Create checkpoints, compare versions and restore",
- "flowVersion.watermark": "Checkpoint label (optional)…",
- "flowVersion.saveCheckpoint": "Save Checkpoint",
- "flowVersion.compareMode": "Compare Mode",
- "flowVersion.selectBase": "Select BASE version (from):",
- "flowVersion.clickAny": "Then click any version in the list below to compare.",
- "flowVersion.noCheckpoints": "No checkpoints yet",
- "flowVersion.noCheckpointsHint": "Save a checkpoint above to begin tracking versions.",
- "flowVersion.restore": "Restore",
- "flowVersion.diffResults": "Diff Results",
- "benchmark.title": "Query Benchmark",
- "benchmark.subtitle": "Measures avg / median / p95 latency over N iterations",
- "benchmark.sql": "SQL being benchmarked",
- "benchmark.runLabel": "Run label",
- "benchmark.runLabelWatermark": "Run 1",
- "benchmark.iterations": "Iterations (1–100)",
- "benchmark.warmup": "Warm-up passes (0–10)",
- "benchmark.interval": "Interval between runs (ms)",
- "benchmark.run": "Run Benchmark",
- "benchmark.cancel": "Cancel",
- "benchmark.clearHistory": "Clear History",
- "benchmark.latest": "LATEST RESULT",
- "benchmark.avg": "AVG",
- "benchmark.median": "MEDIAN",
- "benchmark.min": "MIN",
- "benchmark.max": "MAX",
- "benchmark.iterationsAt": " iterations · run at ",
- "benchmark.history": "HISTORY",
- "benchmark.header.label": "Etiqueta",
- "benchmark.header.avg": "Prom",
- "benchmark.header.median": "Mediana",
- "benchmark.header.min": "Mín",
- "benchmark.header.max": "Máx",
- "benchmark.itersSuffix": " iters",
- "diagnostics.title": "App Diagnostics",
- "diagnostics.run": "Run",
- "diagnostics.running": "Running checks…",
- "diagnostics.ok": "OK",
- "diagnostics.warning": "Warning",
- "diagnostics.error": "Error",
- "diagnostics.tooltip.rerun": "Re-run all checks",
- "diagnostics.tooltip.copy": "Copy diagnostic report to clipboard",
- "diagnostics.tooltip.close": "Close (Esc)",
- "autoJoin.title": "Auto-Join Suggestions",
- "autoJoin.titleForTable": "Auto-Join suggestions for {0}",
- "autoJoin.acceptAll": "Accept All",
- "autoJoin.accept": "Accept",
- "autoJoin.skip": "Skip",
- "autoJoin.allHandled": "All suggestions handled",
- "autoJoin.joinKeyword": "JOIN",
- "autoJoin.confidence.fkConstraint": "FK Constraint",
- "autoJoin.confidence.fkReverse": "FK (Reverse)",
- "autoJoin.confidence.namingMatch": "Naming Match",
- "autoJoin.confidence.weakMatch": "Weak Match",
- "autoJoin.runSelected": "Auto-Join Selected",
- "autoJoin.noSimilarityTitle": "No automatic join found",
- "autoJoin.noSimilarityDetails": "Choose the columns manually to create a simple join.",
- "autoJoin.appliedTitle": "Auto-join applied",
- "autoJoin.manual.title": "Create Manual Join",
- "autoJoin.manual.subtitle": "No reliable similarity was found. Select one column from each table.",
- "autoJoin.manual.leftColumn": "Left column",
- "autoJoin.manual.rightColumn": "Right column",
- "autoJoin.manual.joinType": "Join type",
- "autoJoin.manual.operator": "Operator",
- "autoJoin.manual.confirm": "Create join",
- "autoJoin.manual.noCompatible": "No compatible columns for the selected left pin type.",
- "autoJoin.manualJoinCreatedTitle": "Manual join created",
- "autoJoin.manualJoinFailedTitle": "Manual join could not be created",
- "autoJoin.manualJoinFailedDetails": "Check selected columns and existing joins, then try again.",
- "autoJoin.multipleCandidatesTitle": "Multiple join candidates found",
- "autoJoin.multipleCandidatesDetails": "{0} possible combinations were found. Confirm which columns should be used.",
- "autoJoin.suggestionsFoundTitle": "Auto-join suggestions available",
- "autoJoin.suggestionsFoundDetails": "{0} suggestion(s) found. Select two tables and run Auto-Join Selected.",
- "property.outputAlias": "OUTPUT ALIAS",
- "property.sourceAlias": "SOURCE ALIAS",
- "property.aliasWatermark": "e.g. MyColumn (optional)",
- "property.parameters": "PARAMETERS",
- "property.enabled": "Enabled",
- "property.datetimeWatermark": "YYYY-MM-DDTHH:mm:ss or leave empty",
- "property.dateWatermark": "YYYY-MM-DD or leave empty",
- "property.apply": "Apply",
- "property.inputPins": "INPUT PINS",
- "property.outputPins": "OUTPUT PINS",
- "property.sqlTrace": "SQL TRACE",
- "property.live": "live",
- "node.numericValue": "Numeric Value",
- "node.stringValue": "String Value",
- "node.enterText": "Enter text",
- "node.datetimeValue": "DateTime Value",
- "node.valueLabel": "Value:",
- "node.noInputs": "No inputs",
- "node.loadingSample": "Loading sample…",
- "node.previewFailed": "⚠ Preview failed",
- "node.sampleRowsHint": "5 sample rows · demo data",
- "sidebar.tab.nodes": "Nodos",
- "sidebar.tab.connection": "Conexión",
- "sidebar.tab.schema": "Esquema",
- "sidebar.tab.diagnostics": "Diagnóstico",
- "sidebar.addNode": "+ Add Node (⇧A)",
- "sidebar.previewF3": "Preview (F3)",
- "nodesList.search": "Search nodes...",
- "search.watermark": "Search nodes… (Esc to close)",
- "search.snippets": "★ SNIPPETS",
- "commandPalette.watermark": "Ejecuta un comando… (Esc para cerrar)",
- "tooltip.newCanvas": "New canvas (Ctrl+N)",
- "tooltip.openCanvas": "Open canvas (Ctrl+O)",
- "tooltip.saveCanvas": "Save canvas (Ctrl+S)",
- "tooltip.fileHistory": "Local save/load history (Ctrl+Alt+H)",
- "tooltip.zoomOut": "Zoom out (Ctrl+-)",
- "tooltip.zoomIn": "Zoom in (Ctrl++)",
- "tooltip.fitToScreen": "Fit to screen (Ctrl+0)",
- "tooltip.autoLayout": "Auto Layout — arrange nodes into logical columns (Ctrl+L, Ctrl+Z to undo)",
- "tooltip.snapToGrid": "Toggle snap to grid (Ctrl+G)",
- "tooltip.dataPreview": "Data preview (F3)",
- "tooltip.toggleLanguage": "Toggle language (pt-BR / en-US)",
- "tooltip.appDiagnostics": "App Diagnostics (self-check)",
- "tooltip.keyboardShortcuts": "Keyboard shortcuts (F1)",
- "tooltip.cancelRunningQuery": "Cancel the running query",
- "tooltip.closeEsc": "Close (Esc)",
- "tooltip.recheckConnectionHealth": "Re-check connection health",
- "tooltip.deleteConnection": "Delete connection",
- "tooltip.testConnection": "Test connection",
- "tooltip.saveConnection": "Save connection",
- "tooltip.activateConnection": "Activate this connection",
- "tooltip.toggleDataSamplePreview": "Toggle data sample preview",
- "tooltip.liveSqlMutatingBlocked": "This SQL contains a data-mutating command and cannot be run in Safe Preview Mode",
- "tooltip.copySql": "Copy SQL to clipboard",
- "tooltip.formatSql": "Format SQL",
- "tooltip.openBenchmark": "Open Query Benchmark (measure avg / median / p95 latency)",
- "tooltip.openExplainPlan": "Open Explain Plan inspector — visualise the query execution plan",
- "tooltip.switchToQueryMode": "Switch to Query canvas",
- "tooltip.switchToDdlMode": "Switch to DDL canvas",
- "tooltip.autoJoinSelected": "Try auto-join between the two selected tables",
- "tooltip.pins.inputs": "Inputs",
- "tooltip.pins.outputs": "Outputs",
- "tooltip.pins.none": "None",
- "tooltip.tableColumns": "Columns",
- "tooltip.tableColumns.none": "No detailed columns",
- "window.minimize": "Minimize window",
- "window.maximizeRestore": "Maximize/restore window",
- "window.close": "Close window",
- "menu.newDiagram": "New diagram",
- "menu.openFile": "Open file",
- "menu.save": "Save",
- "menu.fileHistory": "File history",
- "menu.shortcuts": "Keyboard shortcuts",
- "menu.settings": "Settings",
- "menu.importDdlSchema": "Import DDL schema",
- "menu.viewDdlSql": "View DDL SQL",
- "menu.executeDdl": "Execute DDL",
- "menu.backToStart": "Back to start",
- "toast.ddlExecuteFailed": "Failed to execute DDL.",
- "toast.ddlOpenFailed": "Failed to open DDL SQL.",
- "toast.ddlImportFailed": "Failed to import schema into DDL.",
- "toast.ddlConnectToImportSchema": "Connect to a database to import schema into the DDL canvas.",
- "toast.ddlNoTablesFound": "No tables found to import in DDL mode.",
- "toast.ddlSchemaImported": "Schema imported into the DDL canvas.",
- "toast.ddlImportSummary": "{0} table(s), {1} column(s), {2} FK(s), {3} unique index(es).",
- "toast.ddlConnectToImportTable": "Connect to a database to import tables into the DDL canvas.",
- "toast.ddlTableAlreadyExists": "Table '{0}' already exists in the DDL canvas.",
- "toast.ddlTableImported": "Table imported into the DDL canvas.",
- "toast.ddlTableImportSummary": "Nodes: +{0}, connections: +{1}, FKs: +{2}.",
- "toast.ddlNoActiveConnection": "No active connection to execute DDL.",
- "toast.ddlExecutedSuccess": "DDL executed successfully.",
- "toast.ddlExecutedWithIssues": "DDL executed with issues.",
- "toast.switchToDdl": "Switch to DDL mode to generate SQL.",
- "toast.ddlInvalid": "Invalid DDL. Fix errors before continuing.",
- "toast.ddlNoStatements": "No DDL statements were generated in the canvas.",
- "toast.previewOpenFailed": "Failed to open preview.",
- "tab.switchFailed": "Failed to switch tab: {0}",
- "settings.status.darkApplied": "Dark theme applied.",
- "settings.status.lightApplied": "Light theme applied.",
- "settings.status.snapUpdated": "Snap updated: {0}.",
- "settings.status.languageToggled": "Language toggled.",
- "settings.status.languageSelected": "Language selected: {0}.",
- "settings.status.themeEditorReady": "Theme editor ready. Apply to save and use this theme.",
- "settings.section.appearance.title": "Themes",
- "settings.section.languageRegion.title": "Idioma y región",
- "settings.section.dateTime.title": "Fecha y hora",
- "settings.section.keyboard.title": "Atajos de teclado",
- "settings.section.privacy.title": "Privacidad",
- "settings.section.notification.title": "Notificaciones",
- "settings.section.accessibility.title": "Accesibilidad",
- "settings.section.default.title": "Configuración",
- "settings.section.appearance.subtitle": "Elige tu estilo o personaliza tu tema",
- "settings.section.languageRegion.subtitle": "Administra idioma y formato regional",
- "settings.section.keyboard.subtitle": "Personaliza los atajos de teclado usados por la command palette y la ejecución del canvas.",
- "settings.section.wip.subtitle": "En progreso.",
- "settings.section.default.subtitle": "Configuración de la aplicación",
- "settings.general": "General",
- "settings.nav.appearance": "Appearance",
- "settings.theme.light": "Modo claro",
- "settings.theme.dark": "Modo oscuro",
- "settings.theme.system": "Preferencias del sistema",
- "settings.gridSnap.title": "Grid Snap",
- "settings.gridSnap.subtitle": "Controls node snapping on the canvas.",
- "settings.language.subtitle": "Seleccione el idioma de la aplicación.",
- "settings.language.toggle": "Cambiar idioma",
- "settings.language.option.ptBR": "Portugués (Brasil)",
- "settings.language.option.enUS": "Inglés (Estados Unidos)",
- "settings.language.option.esES": "Español (España)",
- "settings.language.option.ruRU": "Ruso",
- "settings.language.option.jaJP": "Japonés",
- "settings.language.option.zhTW": "Chino tradicional",
- "settings.themeJson.title": "JSON del tema",
- "settings.themeJson.subtitle": "Pega tu JSON de tema, aplícalo y persístelo al instante.",
- "settings.themeJson.apply": "Aplicar JSON",
- "settings.themeJson.restoreDefault": "Restaurar tema predeterminado",
- "mode.query": "Query",
- "mode.ddl": "DDL",
- "sidebar.left.close": "Close left sidebar",
- "sidebar.left.open": "Reopen left sidebar",
- "sidebar.right.close": "Close right sidebar",
- "sidebar.right.open": "Reopen right sidebar",
- "connection.completedTitle": "Connection completed",
- "connection.clearCanvasPrompt": "Do you want to clear the current canvas to start with the new connection?",
- "connection.close": "Close connection manager",
- "connection.refreshHealth": "Refresh connection health",
- "common.details": "Details",
- "common.cancel": "Cancel",
- "common.keep": "Keep",
- "common.clear": "Clear",
- "zoom.out": "Zoom out",
- "zoom.in": "Zoom in",
- "zoom.fit": "Fit zoom to screen",
- "zoom.level": "Zoom level",
- "settings.theme.mode": "Modo de tema",
- "diagnostics.category.canvas": "Canvas Integrity",
- "diagnostics.category.output": "Output & Execution",
- "diagnostics.category.session": "Session & Safety",
- "diagnostics.category.notice": "Runtime Notices",
- "diagnostics.summary.ok": "All systems OK",
- "diagnostics.summary.warningCount": "{0} warning(s) detected",
- "diagnostics.summary.errorCount": "{0} error(s) detected",
- "diagnostics.canvasMigration": "Canvas Migration",
- "diagnostics.recommendation.resaveFile": "Vuelve a guardar el archivo para actualizarlo a la última versión del esquema.",
- "diagnostics.canvasState.name": "Canvas State",
- "diagnostics.canvasState.recommendation": "Add at least one {0} and one {1}",
- "diagnostics.canvasState.empty": "Canvas is empty - no nodes present",
- "diagnostics.canvasState.counts": "{0} node(s), {1} connection(s)",
- "diagnostics.validation.name": "Errores de validación",
- "diagnostics.validation.recommendation": "Corrige los nodos resaltados antes de ejecutar la vista previa de salida",
- "diagnostics.validation.errorWithWarnings": "{0} error(es) y {1} advertencia(s) en el grafo",
- "diagnostics.validation.warningOnly": "{0} advertencia(s) en el grafo",
- "diagnostics.validation.none": "Sin problemas de validación",
- "diagnostics.orphan.name": "Nodos huérfanos",
- "diagnostics.orphan.recommendation": "Usa la acción de limpieza de huérfanos para remover nodos no usados",
- "diagnostics.orphan.count": "{0} nodo(s) no conectado(s) a ninguna salida",
- "diagnostics.orphan.none": "No se detectaron nodos huérfanos",
- "diagnostics.naming.name": "Convenciones de nombres",
- "diagnostics.naming.recommendation": "Usa autocorrección de alias cuando la conformidad sea menor a 100%",
- "diagnostics.naming.conformance": "Conformidad de nombres: {0}%",
- "diagnostics.naming.ok": "Todos los alias siguen las convenciones de nombres (100%)",
- "diagnostics.queryCompilation.name": "Compilación SQL en vivo",
- "diagnostics.queryCompilation.recommendation": "Revisa el diagnóstico SQL en la salida cuando se reporten errores/advertencias.",
- "diagnostics.queryCompilation.errorFallback": "La compilación SQL en vivo reportó errores.",
- "diagnostics.queryCompilation.warningCounts": "{0} elemento(s) de diagnóstico, {1} advertencia(s) de guardrail.",
- "diagnostics.queryCompilation.ok": "SQL en vivo compilado sin diagnósticos.",
- "diagnostics.previewSafety.name": "Seguridad de vista previa",
- "diagnostics.previewSafety.recommendation": "La vista previa solo ejecuta sentencias de solo lectura.",
- "diagnostics.previewSafety.blocked": "El SQL actual modifica datos y está bloqueado por el modo de vista previa segura.",
- "diagnostics.previewSafety.ok": "Las verificaciones de seguridad de vista previa pasaron.",
- "diagnostics.previewExecution.name": "Ejecución de vista previa",
- "diagnostics.previewExecution.recommendation": "Ejecuta la vista previa e inspecciona diagnósticos por errores de ejecución/runtime.",
- "diagnostics.previewExecution.failed": "La ejecución de vista previa falló.",
- "diagnostics.previewExecution.cancelled": "La ejecución de vista previa fue cancelada.",
- "diagnostics.previewExecution.done": "{0} fila(s) en {1}ms.",
- "diagnostics.previewExecution.none": "No se detectaron problemas en la ejecución de vista previa.",
- "diagnostics.ddlCompilation.name": "Compilación DDL",
- "diagnostics.ddlCompilation.recommendation": "Corrige los diagnósticos de compilación DDL antes de ejecutar.",
- "diagnostics.ddlCompilation.failed": "La compilación DDL falló.",
- "diagnostics.ddlCompilation.warningCount": "{0} advertencia(s) reportada(s) por el compilador DDL.",
- "diagnostics.ddlCompilation.ok": "Compilación DDL exitosa.",
- "diagnostics.ddlOutput.name": "DDL Output",
- "diagnostics.ddlOutput.recommendation": "Add/complete DDL nodes until at least one statement is generated.",
- "diagnostics.ddlOutput.none": "No DDL statements generated yet.",
- "diagnostics.ddlOutput.lines": "{0} line(s) of DDL generated.",
- "diagnostics.undo.name": "Historial de deshacer",
- "diagnostics.undo.recommendation": "El historial solo está en memoria; guarda tu canvas regularmente.",
- "diagnostics.undo.saved": "Canvas guardado (sin cambios sin guardar).",
- "diagnostics.undo.unsavedDeep": "Cambios sin guardar con {0} pasos de deshacer.",
- "diagnostics.undo.unsaved": "Cambios sin guardar - {0} paso(s) de deshacer disponibles.",
- "diagnostics.report.title": "DBWeaver - Informe de diagnóstico",
- "diagnostics.report.generated": "Generado",
- "diagnostics.report.overall": "General",
- "diagnostics.report.details": "Detalles",
- "diagnostics.report.recommendation": "Recomendación",
- "diagnostics.report.lastCheck": "Última verificación",
- "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
- "node.datetimeFormat": "YYYY-MM-DDTHH:mm:ss",
- "preview.providerLabel": "Provider",
- "preview.ddlDiagnosticsHint": "Error/warning details are available in Diagnostics.",
- "preview.schemaAnalysis.run": "Run Analysis",
- "preview.schemaAnalysis.cancel": "Cancel",
- "preview.schemaAnalysis.issues": "Issues",
- "preview.schemaAnalysis.clearFilters": "Clear Filters",
- "preview.schemaAnalysis.clearBlacklist": "Clear Blacklist",
- "preview.schemaAnalysis.severity": "Severity",
- "preview.schemaAnalysis.severity.info": "Info",
- "preview.schemaAnalysis.severity.warning": "Warning",
- "preview.schemaAnalysis.severity.critical": "Critical",
- "preview.schemaAnalysis.rule": "Rule",
- "preview.schemaAnalysis.rule.fkCatalogInconsistent": "FK catalog inconsistent",
- "preview.schemaAnalysis.rule.missingFk": "Missing FK",
- "preview.schemaAnalysis.rule.namingConventionViolation": "Naming convention violation",
- "preview.schemaAnalysis.rule.lowSemanticName": "Low semantic name",
- "preview.schemaAnalysis.rule.missingRequiredComment": "Missing required comment",
- "preview.schemaAnalysis.rule.nf1HintMultiValued": "1NF hint: multi-valued",
- "preview.schemaAnalysis.rule.nf2HintPartialDependency": "2NF hint: partial dependency",
- "preview.schemaAnalysis.rule.nf3HintTransitiveDependency": "3NF hint: transitive dependency",
- "preview.schemaAnalysis.minConfidence": "Min Confidence",
- "preview.schemaAnalysis.tableFilter": "Table Filter",
- "preview.schemaAnalysis.tableFilterWatermark": "schema.table",
- "preview.schemaAnalysis.ignore": "Execution Filters",
- "preview.schemaAnalysis.ignoreViews": "Ignore views and materialized views",
- "preview.schemaAnalysis.blacklist": "Table blacklist",
- "preview.schemaAnalysis.blacklistAdd": "Add",
- "preview.schemaAnalysis.blacklistRemove": "Remove selected",
- "preview.schemaAnalysis.ignoreTable.placeholder": "schema.table",
- "preview.schemaAnalysis.details": "Details",
- "preview.schemaAnalysis.evidence": "Evidence",
- "preview.schemaAnalysis.suggestions": "Suggestions",
- "preview.schemaAnalysis.ruleDiagnostics": "Rule Diagnostics",
- "preview.schemaAnalysis.sqlCandidates": "SQL Candidates",
- "preview.schemaAnalysis.copySql": "Copy SQL",
- "preview.schemaAnalysis.applyToCanvas": "Apply to Canvas",
- "preview.schemaAnalysis.summary.issues": "Issues:",
- "preview.schemaAnalysis.summary.rawPrefix": "(raw:",
- "preview.schemaAnalysis.summary.critical": "| Critical:",
- "preview.schemaAnalysis.summary.warning": "| Warning:",
- "preview.schemaAnalysis.summary.info": "| Info:",
- "preview.schemaAnalysis.state.metadataUnavailable": "Metadata unavailable for structural analysis.",
- "preview.schemaAnalysis.state.cancelled": "Analysis cancelled by the user.",
- "preview.schemaAnalysis.state.partialTimeout": "Analysis finished partially due to timeout.",
- "preview.schemaAnalysis.state.failed": "Structural analysis failed.",
- "preview.schemaAnalysis.state.empty": "No inferable structural issue was detected.",
- "preview.schemaAnalysis.state.noFilterMatch": "No issue matches the selected filters.",
- "preview.schemaAnalysis.state.noIssueSelected": "No issue selected.",
- "preview.schemaAnalysis.state.noSqlCandidate": "No SQL candidate available.",
- "preview.schemaAnalysis.actionBlockedTooltip": "Action unavailable for the current risk level or capability.",
- "common.navigate": "Navigate",
- "common.close": "Close",
- "common.esc": "Esc",
- "common.ms": "ms",
- "common.zero": "0",
- "diagnostics.tip": "Tip: check Diagnostics whenever preview/output reports warnings or errors.",
- "nodesList.empty": "No nodes found",
- "nodesList.emptyHint": "Adjust the search term to explore available types",
- "schema.emptyFiltered": "No objects found for the current filter",
- "start.lastSnapshot": "Last snapshot",
- "app.brandBadge": "VS",
- "property.tab.properties": "Properties",
- "property.tab.projectSettings": "Project Settings",
- "property.nodeType": "NODE TYPE",
- "property.selectNodeHint": "Select a node to edit its properties.",
- "property.namingConventions": "Naming Conventions",
- "property.aliasConvention": "Alias convention",
- "property.enforceAliasNaming": "Enforce alias naming",
- "property.warnReservedSql": "Warn on reserved SQL keywords",
- "property.maxAliasLength": "Max alias length",
- "property.maxAliasLengthDefault": "64",
- "property.namingSettingsHint": "These settings are project-scoped and are used by naming and validation helpers.",
- "start.tips": "Tips",
- "start.tips.quick": "Consejos rápidos",
- "start.tips.item1": "1. Haz clic en Nuevo diagrama para empezar desde cero.",
- "start.tips.item2": "2. Usa plantillas para acelerar el prototipado.",
- "start.tips.item3": "3. Abre conexiones guardadas para cargar tablas reales.",
- "start.tips.shortcut": "Atajo: CTRL+SHIFT+P abre la paleta de comandos.",
- "start.workspace": "WORKSPACE",
- "start.resumeTitle": "Continue where you left off",
- "start.resumeSubtitle": "Quickly resume a recent project or start a new diagram.",
- "start.chip.quickFlow": "Quick flow",
- "start.chip.templates": "Templates",
- "start.chip.connections": "Connections",
- "start.savedConnectionsTitle": "Saved Connections",
- "start.savedConnectionsSubtitle": "Connect quickly to a database to load schema and tables.",
- "start.noConnectionsTitle": "No connections configured yet",
- "start.noConnectionsSubtitle": "Create a connection to explore real tables in the editor.",
- "start.newConnection": "+ New Connection",
- "start.recentProjectsTitle": "Recent Projects",
- "start.searchRecent": "Search recent project...",
- "start.quickActions": "Quick actions",
- "start.quickActionsSubtitle": "Open an existing file or start a new diagram.",
- "start.noRecentTitle": "No recent projects yet",
- "start.noRecentSubtitle": "Use the quick actions card above to get started.",
- "start.exploreTemplates": "Explore templates",
- "start.templatesFavoritesHint": "Favorites on top",
- "start.favoriteTemplate": "Favorite template",
- "node.columnSetPreview": "ColumnSet preview",
- "node.view": "VIEW",
- "node.tableDefinition": "Table Definition",
- "node.join": "JOIN",
- "node.window.addPartition": "Agregar ranura PARTITION BY",
- "node.window.removePartition": "Remover ranura PARTITION BY",
- "node.window.addOrder": "Agregar ranura ORDER BY",
- "node.window.removeOrder": "Remover ranura ORDER BY",
- "sql.keyword.select": "SELECT",
- "sql.keyword.from": "FROM",
- "sql.keyword.join": "JOIN",
- "sql.keyword.where": "WHERE",
- "sql.keyword.limit": "LIMIT",
- "sqlImporter.close": "Close SQL importer",
- "sqlImporter.report.imported": "Importado",
- "sqlImporter.report.partial": "Parcial",
- "sqlImporter.report.skipped": "Omitido",
- "benchmark.close": "Close benchmark",
- "benchmark.p95": "P95",
- "benchmark.n": "N",
- "liveSql.safePreview": "SAFE PREVIEW MODE",
- "liveSql.title": "LIVE SQL",
- "liveSql.blocked": "BLOCKED",
- "liveSql.copy": "Copy",
- "liveSql.format": "Format",
- "liveSql.benchmark": "Benchmark",
- "liveSql.explain": "Explain",
- "liveSql.actionsHint": "Performance tools",
- "ddl.dialog.title": "Ejecutar DDL",
- "ddl.dialog.execute": "Ejecutar",
- "ddl.dialog.cancel": "Cancelar",
- "ddl.dialog.close": "Cerrar",
- "ddl.dialog.stopOnError": "Detener en el primer fallo",
- "ddl.dialog.confirmDestructive": "Confirmo la ejecución de sentencias destructivas (DROP TABLE)",
- "ddl.dialog.reviewBeforeRun": "Revisa el script DDL antes de confirmar.",
- "ddl.dialog.confirmQuestion": "¿Confirmar ejecución DDL en la base conectada?",
- "ddl.dialog.irreversibleWarning": "Esta acción puede cambiar el esquema de forma irreversible.",
- "ddl.dialog.mustConfirmDestructive": "Confirma la ejecución destructiva para continuar.",
- "ddl.dialog.executing": "Ejecutando...",
- "ddl.execute.result.summary": "Statements: {0} | Success: {1} | Failures: {2} | Time: {3:0}ms",
- "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
- "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
- "ddl.execute.result.failed": "Failed to execute DDL.",
- "ddl.execute.result.cancelled": "Execution cancelled by the user.",
- "ddl.execute.result.cancelledDetails": "DDL execution was interrupted before completion.",
- "context.deleteSingle": "Delete {0}",
- "context.deleteMultiple": "Delete {0} nodes",
- "context.bringForward": "Bring Forward (Ctrl+PgUp)",
- "context.sendBackward": "Send Backward (Ctrl+PgDown)",
- "context.bringToFront": "Bring to Front (Ctrl+Shift+PgUp)",
- "context.sendToBack": "Send to Back (Ctrl+Shift+PgDown)",
- "context.normalizeLayers": "Normalize Layers",
- "context.deleteWire": "Delete wire",
- "context.addNode": "Add Node (Shift+A)",
- "context.undoWithDescription": "Undo {0}",
- "context.redo": "Redo",
- "shortcuts.windowTitle": "Keyboard Shortcuts",
- "shortcuts.headerTitle": "DBWeaver - Shortcuts",
- "shortcuts.headerHint": "Tip: use CTRL+SHIFT+P to open the Command Palette and search commands.",
- "shortcuts.filterWatermark": "Filter shortcuts by key or action...",
- "shortcuts.resultCount": "{0} shortcuts",
- "shortcuts.resultFilter": "{0} result(s) for \"{1}\"",
- "shortcuts.noneFound": "No shortcuts found.",
- "shortcuts.section.fileGeneral": "Archivo y general",
- "shortcuts.section.editing": "Edición",
- "shortcuts.section.canvasNavigation": "Canvas y navegación",
- "shortcuts.section.zoomPanPrecision": "Zoom, paneo y precisión",
- "shortcuts.section.previewInspection": "Vista previa e inspección",
- "shortcuts.key.deleteOrBackspace": "Del o Backspace",
- "shortcuts.key.middleDrag": "Botón medio + arrastrar",
- "shortcuts.key.rightDrag": "Botón derecho + arrastrar",
- "shortcuts.key.spaceDrag": "Espacio + arrastrar",
- "shortcuts.key.altLeftDrag": "Alt + arrastre izquierdo",
- "shortcuts.key.arrows": "Flechas",
- "shortcuts.key.shiftArrows": "Shift + Flechas",
- "shortcuts.action.openShortcutScreen": "Abrir esta pantalla de atajos",
- "shortcuts.action.newCanvas": "Nuevo canvas",
- "shortcuts.action.openFile": "Abrir archivo",
- "shortcuts.action.save": "Guardar",
- "shortcuts.action.saveAs": "Guardar como",
- "shortcuts.action.commandPalette": "Paleta de comandos",
- "shortcuts.action.undo": "Deshacer",
- "shortcuts.action.redo": "Rehacer",
- "shortcuts.action.selectAll": "Seleccionar todo",
- "shortcuts.action.deleteSelection": "Eliminar selección",
- "shortcuts.action.closeOverlayCancel": "Cerrar overlays / cancelar acciones",
- "shortcuts.action.openNodeSearch": "Abrir búsqueda de nodos",
- "shortcuts.action.resetViewport": "Restablecer viewport",
- "shortcuts.action.centerSelection": "Centrar selección",
- "shortcuts.action.fitSelection": "Ajustar selección",
- "shortcuts.action.autoLayout": "Diseño automático",
- "shortcuts.action.toggleSnapToGrid": "Alternar ajuste a cuadrícula",
- "shortcuts.action.bringForward": "Traer adelante",
- "shortcuts.action.sendBackward": "Enviar atrás",
- "shortcuts.action.bringToFront": "Traer al frente",
- "shortcuts.action.sendToBack": "Enviar al fondo",
- "shortcuts.action.zoomInOut": "Acercar / alejar",
- "shortcuts.action.pan": "Panear",
- "shortcuts.action.temporaryPan": "Paneo temporal",
- "shortcuts.action.alternatePan": "Paneo alternativo",
- "shortcuts.action.fineNudge": "Movimiento fino de selección",
- "shortcuts.action.fastNudge": "Movimiento rápido",
- "shortcuts.action.togglePreview": "Alternar vista previa de datos",
- "shortcuts.action.explainPlan": "Plan de ejecución",
- "shortcuts.action.runPreview": "Ejecutar vista previa",
- "shortcuts.action.connectionManager": "Administrador de conexiones",
- "shortcuts.action.flowVersionHistory": "Historial de versiones del flujo",
- "shortcuts.resetAll": "Restablecer todo",
- "shortcuts.customized": "Personalizado",
- "shortcuts.default": "Predeterminado",
- "shortcuts.apply": "Aplicar",
- "shortcuts.reset": "Restablecer",
- "shortcuts.status.resetAllSuccess": "Todos los atajos se restablecieron a los valores predeterminados.",
- "shortcuts.status.updated": "Atajo actualizado.",
- "shortcuts.status.reset": "Atajo restablecido al valor predeterminado.",
- "shortcuts.status.updateFailed": "No se pudo actualizar el atajo.",
- "toast.severity.success": "Success",
- "toast.severity.warning": "Warning",
- "toast.severity.error": "Error",
- "toast.details.success": "Success Details",
- "toast.details.warning": "Warning Details",
- "toast.details.error": "Error Details",
- "diagnostics.area.cteEditor": "Editor CTE",
- "diagnostics.area.viewEditor": "Editor de vista",
- "diagnostics.area.subEditor": "Subeditor",
- "diagnostics.cteEditor.restoreParentFailed": "Failed to restore the parent canvas. CTE edits were discarded.",
- "diagnostics.recommendation.reloadFileIfNeeded": "Recarga el archivo si es necesario.",
- "diagnostics.viewEditor.exitFailed": "No se pudo salir: {0}",
- "diagnostics.viewEditor.canvasIncomplete": "el canvas está incompleto.",
- "diagnostics.viewEditor.exitRecommendation": "Conecta un ResultOutput válido o usa el comando descartar.",
- "diagnostics.viewEditor.restoreParentFailed": "Falló la restauración del canvas padre. El subgrafo fue descartado.",
- "diagnostics.subEditor.executeFailed": "Failed to execute editor action: {0}",
- "diagnostics.subEditor.executeRecommendation": "Try again. If it persists, reload the canvas.",
- "diagnostics.canvasMigration.openWarning": "Open: {0}",
- "diagnostics.canvasMigration.sessionRestoreWarning": "Session restore: {0}",
- "diagnostics.canvasMigration.versionRestoreWarning": "Version restore: {0}",
- "diagnostics.recommendation.resaveLatestSchema": "Revisa diagnósticos y vuelve a guardar el canvas para persistir el esquema más reciente.",
- "diagnostics.recommendation.saveMigratedSchema": "Revisa diagnósticos y guarda el canvas para persistir el esquema migrado.",
- "file.saveDialog.title": "Save Canvas",
- "file.saveDialog.suggestedName": "Query1",
- "file.save.success": "Canvas saved successfully.",
- "file.save.failedWithReason": "Save failed: {0}",
- "file.openDialog.title": "Open Canvas",
- "file.open.failedWithReason": "Open failed: {0}",
- "file.open.success": "Canvas opened successfully.",
- "file.open.successWithWarnings": "Canvas opened with warnings.",
- "session.restore.failedWithReason": "Restore failed: {0}",
- "session.restore.successWithWarnings": "Session restored with warnings.",
- "session.restore.success": "Session restored successfully.",
- "export.documentation.dialogTitle": "Export Flow Documentation",
- "export.documentation.success": "Documentation exported successfully.",
- "export.documentation.failed": "Documentation export failed.",
- "export.failed.pathPermissionsHint": "Check file path and permissions.",
- "export.nodeNotFound": "No {0} Export node found on the canvas. Add one via the node search menu.",
- "export.dialogTitleByExtension": "Export as {0}",
- "export.success": "Export completed successfully.",
- "export.failed": "Export failed.",
- "fileHistory.currentFile.none": "No file selected",
- "fileHistory.status.saveFirst": "Save the canvas first to enable local history.",
- "fileHistory.status.noneFound": "No local versions found yet. Save this file to create history entries.",
- "fileHistory.status.countAvailable": "{0} local version(s) available.",
- "fileHistory.restore.failedWithReason": "Restore failed: {0}",
- "fileHistory.restore.successFrom": "Restored version from {0}.",
- "preview.status.cancelled": "Cancelled",
- "preview.status.error": "Error",
- "preview.status.ready": "Ready",
- "preview.runningWithMs": "Running... {0}ms",
- "preview.runningWithTimeout": "Running... {0}ms (timeout: {1}s)",
- "preview.runningSlowWithTimeout": "Running... {0}ms (timeout: {1}s) · Slow query, timeout in {2}s",
- "explain.errorWithReason": "Explain plan error: {0}",
- "explain.noSql": "No SQL to explain. Build a query on the canvas first.",
- "ddl.compilationFailed": "Compilation failed",
- "ddl.compileErrorWithReason": "DDL compile error: {0}",
- "command.undo.name": "Undo",
- "command.undo.description": "Undo last action",
- "command.redo.name": "Redo",
- "command.redo.description": "Redo last undone action",
- "command.addNode.name": "Add Node",
- "command.addNode.description": "Open node search menu to add a node",
- "command.bringForward.name": "Bring Forward",
- "command.bringForward.description": "Move selected nodes one layer forward",
- "command.sendBackward.name": "Send Backward",
- "command.sendBackward.description": "Move selected nodes one layer backward",
- "command.bringToFront.name": "Bring to Front",
- "command.bringToFront.description": "Move selected nodes to top layer",
- "command.sendToBack.name": "Send to Back",
- "command.sendToBack.description": "Move selected nodes to bottom layer",
- "command.normalizeLayers.name": "Normalize Layers",
- "command.normalizeLayers.description": "Compact node layer indices to a clean 0..N order",
- "tooltip.cleanupOrphans": "Remove orphan nodes not connected to the output (Ctrl+Z to undo)",
- "main.orphanSuffix": "Orphan(s)",
- "tooltip.autoFixAliasNaming": "Fix alias naming to snake_case (Ctrl+Z to undo)",
- "main.namingPrefix": "Naming",
- "fileHistory.compressedLabel": "Compressed:",
- "schema.itemsSuffix": "item(s)",
- "property.panel.title": "Properties",
- "property.panel.multiSelected": "{0} nodes selected",
- "sqlImporter.status.pasteSelect": "Pega una sentencia SELECT arriba y luego haz clic en Importar.",
- "sqlImporter.status.inputTooLarge": "La entrada SQL es demasiado grande ({0:N0} caracteres). El límite es {1:N0}. Divide la consulta o aumenta el límite de importación.",
- "sqlImporter.status.parsing": "Analizando SQL...",
- "sqlImporter.status.done": "Listo - {0} importado(s), {1} parcial(es), {2} omitido(s).",
- "sqlImporter.status.cancelledByUser": "Importación cancelada por el usuario.",
- "sqlImporter.status.timeout": "La importación agotó el tiempo tras {0:0.#}s. Prueba una consulta más pequeña o aumenta el timeout.",
- "sqlImporter.status.parseError": "Error de parseo: {0}",
- "diagnostics.area.undoRedoTransaction": "Transacción Deshacer/Rehacer",
- "undoRedo.rollbackExecuted": "Rollback executed for '{0}' ({1} operation(s) reverted).",
- "undoRedo.rollbackRecommendation": "Review the canvas state and retry the action if needed.",
- "node.preview.noCatalog": "No catalog available",
- "connection.error.searchMenuNotInitialized": "el menú de búsqueda no está inicializado",
- "connection.error.timeoutReachability": "Tiempo de conexión agotado - verifica que el servidor sea accesible y aumenta el timeout si es necesario.",
- "connection.error.authenticationFailedForProvider": "Falló la autenticación - verifica usuario y contraseña para {0}.",
- "connection.error.databaseNotFoundForProvider": "Base de datos no encontrada - confirma que el nombre exista en {0}.",
- "connection.error.hostNotFound": "Host no encontrado - verifica dirección del servidor y resolución DNS.",
- "connection.error.portRefused": "Conexión al puerto rechazada - verifica el puerto y que el servidor/firewall permitan acceso.",
- "connection.error.sslTls": "Error SSL/TLS - verifica configuración SSL del servidor o desactiva SSL para conexiones locales.",
- "connection.error.timeoutOverloaded": "Tiempo de conexión agotado - el servidor puede estar sobrecargado o inaccesible. Intenta aumentar el timeout.",
- "connection.error.insufficientPrivileges": "Privilegios insuficientes - el usuario puede no tener permiso para conectarse a esta base.",
- "diagnostics.area.connection": "Conexión",
- "connection.warning.canvasMayContainOldTables": "The canvas may still contain tables from a previous connection.",
- "connection.warning.canvasMayContainOldTablesRecommendation": "Clear the canvas manually or reconnect and choose keep/clear again.",
- "undoRedo.transaction.unnamed": "unnamed transaction",
- "benchmark.runLabelDefault": "Run 1",
- "benchmark.runLabelPattern": "Run {0}",
- "benchmark.status.failedWithReason": "Benchmark falló: {0}",
- "benchmark.status.noSql": "No hay SQL para benchmark - construye una consulta primero.",
- "benchmark.status.warmupProgress": "Calentamiento {0}/{1}...",
- "benchmark.status.iterationProgress": "Iteración {0}/{1}...",
- "benchmark.status.done": "Listo - {0}",
- "benchmark.status.cancelled": "Benchmark cancelado.",
- "app.windowTitle": "DBWeaver",
- "preview.error.safePreviewBlocked": "Safe Preview Mode: data-mutating commands (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) cannot be executed in preview.",
- "preview.error.noActiveConnection": "No active database connection. Please connect to a database first.",
- "sqlImporter.error.selectFromNotFound": "No se pudo encontrar SELECT ... FROM en la consulta.",
- "sqlImporter.error.fromClauseParseFailed": "No se pudo parsear la cláusula FROM.",
- "sqlImporter.error.syntaxUnterminatedString": "Error de sintaxis en línea {0}, columna {1}: literal de cadena sin cerrar.",
- "sqlImporter.error.missingClosingParenthesis": "falta ')' de cierre",
- "sqlImporter.error.unexpectedClosingParenthesis": "')' inesperado",
- "sqlImporter.error.syntaxAtLineColumn": "Error de sintaxis en línea {0}, columna {1}: {2}.",
- "errorDiagnostics.safePreview.label": "Blocked by Safe Preview Mode",
- "errorDiagnostics.safePreview.friendly": "This SQL contains a data-mutating command and cannot be executed in preview.",
- "errorDiagnostics.safePreview.suggestion": "Remove or replace the mutating command (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) before running preview.",
- "errorDiagnostics.connection.label": "Connection failed",
- "errorDiagnostics.connection.friendly": "Could not reach the database server. The host may be down, unreachable, or blocking connections.",
- "errorDiagnostics.connection.suggestion": "Verify the server address and port, ensure the database is running, and check firewall rules.",
- "errorDiagnostics.authorization.label": "Authorization error",
- "errorDiagnostics.authorization.friendly": "The current credentials do not have permission to perform this operation.",
- "errorDiagnostics.authorization.suggestion": "Confirm the database user has SELECT privileges on the target table/schema, or contact your DBA.",
- "errorDiagnostics.timeout.label": "Query timeout",
- "errorDiagnostics.timeout.friendly": "The query took too long to complete and was cancelled by the server or client.",
- "errorDiagnostics.timeout.suggestion": "Add a WHERE clause or LIMIT to reduce the result set, or increase the query timeout in connection settings.",
- "errorDiagnostics.schema.label": "Schema error",
- "errorDiagnostics.schema.friendly": "A referenced table, column, or object could not be found in the database.",
- "errorDiagnostics.schema.suggestion": "Check that all table/column names are spelled correctly and that the schema matches the active connection.",
- "errorDiagnostics.syntax.label": "SQL syntax error",
- "errorDiagnostics.syntax.friendly": "The query contains a syntax error and could not be parsed by the database engine.",
- "errorDiagnostics.syntax.suggestion": "Review the highlighted SQL for typos, mismatched parentheses, or unsupported clauses for the active provider.",
- "errorDiagnostics.compatibility.label": "Compatibility error",
- "errorDiagnostics.compatibility.friendly": "A function, operator, or syntax construct is not supported by the active database provider.",
- "errorDiagnostics.compatibility.suggestion": "Switch to the correct provider in the SQL bar, or replace the unsupported construct with an equivalent.",
- "errorDiagnostics.unknown.label": "Unexpected error",
- "errorDiagnostics.unknown.friendly": "An error occurred while running the preview query.",
- "errorDiagnostics.unknown.suggestion": "Check the technical details below and verify that your canvas is configured correctly.",
- "error.mainWindow.invalidDataContext": "El DataContext de MainWindow debe ser un ShellViewModel.",
- "error.mainWindow.canvasNotInitialized": "CanvasViewModel no fue inicializado.",
- "error.mainWindow.ddlPreviewUnavailable": "La vista previa DDL no está disponible para el canvas actual.",
- "themeJson.editor.template": "{\n \"meta\": { \"name\": \"Tema personalizado\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
- "themeJson.error.pasteBeforeApply": "Pega un JSON de tema antes de aplicar.",
- "themeJson.error.invalidJson": "JSON inválido: {0}",
- "themeJson.error.emptyPayload": "JSON inválido: payload vacío.",
- "themeJson.error.invalidTheme": "Tema inválido: {0}",
- "themeJson.error.appliedButSaveFailed": "Tema aplicado, pero no se pudo guardar: {0}",
- "themeJson.success.appliedAndSaved": "Tema JSON aplicado y guardado.",
- "themeJson.success.customRemoved": "Tema personalizado eliminado. Reinicia la app para volver completamente al tema predeterminado.",
- "themeJson.error.restoreDefaultFailed": "Error al restaurar el tema predeterminado: {0}",
- "themeValidator.error.configNull": "La configuración del tema es nula.",
- "themeValidator.warning.noSections": "El tema no tiene secciones de colores o tipografía; no hay nada para aplicar.",
- "themeValidator.warning.invalidColor": "{0} tiene un color inválido '{1}'. Esta clave será ignorada.",
- "themeValidator.warning.sizeOutOfRange": "{0}={1} está fuera del rango (8..48). Esta clave será ignorada.",
- "queryExecutor.error.openConnectionMethodNotFound": "No se puede encontrar el método OpenConnectionAsync en el orquestador",
- "queryExecutor.error.openConnectionInvokeFailed": "Error al invocar OpenConnectionAsync",
- "ddlImporter.warning.viewSelectNotReconstructable": "Vista '{0}': el SELECT de la vista no puede reconstruirse visualmente; edítalo manualmente en el subcanvas.",
- "ddlImporter.error.tableNotFoundInMetadata": "La tabla '{0}' no se encontró en los metadatos actuales.",
- "main.window.untitled": "Sin título",
- "main.subEditor.noSeedProvided": "No se proporcionó seed de subeditor para {0}.",
- "main.layerOrder.bringToFront": "Traer al frente",
- "main.layerOrder.sendToBack": "Enviar atrás",
- "main.layerOrder.bringForward": "Adelantar capa",
- "main.layerOrder.sendBackward": "Retroceder capa",
- "main.layerOrder.normalizeLayers": "Normalizar capas",
- "export.fileType.html": "Archivos HTML",
- "export.fileType.json": "Archivos JSON",
- "export.fileType.csv": "Archivos CSV",
- "export.fileType.excel": "Archivos Excel",
- "commandPalette.templatePrefix": "Plantilla: {0}",
- "themeLoader.status.notFoundWithPath": "Archivo de tema no encontrado: {0}",
- "themeLoader.status.deserializedNull": "El JSON del tema se deserializó como null.",
- "themeLoader.status.loaded": "JSON del tema cargado correctamente.",
- "credential.error.ciphertextTooShort": "El bloque de texto cifrado es demasiado corto.",
- "credential.error.dpapiWindowsOnly": "DPAPI solo está disponible en Windows.",
- "credential.warning.loadVaultFailed": "No se pudo cargar el almacén de credenciales {0}: {1}",
- "credential.warning.persistVaultFailed": "No se pudo guardar el almacén de credenciales {0}: {1}",
- "snippetStore.warning.loadFailed": "No se pudieron cargar snippets desde {0}: {1}",
- "snippetStore.warning.saveFailed": "No se pudieron guardar snippets: {0}",
- "flowVersionStore.warning.loadFailed": "No se pudieron cargar versiones de flujo desde {0}: {1}",
- "flowVersionStore.warning.saveFailed": "No se pudieron guardar versiones de flujo: {0}",
- "queryExecutor.error.queryEmpty": "La consulta no puede estar vacía",
- "queryExecutor.error.providerNotSupported": "El proveedor {0} no es compatible",
- "queryExecutor.error.singleStatementOnly": "La vista previa solo acepta una única sentencia SQL.",
- "queryExecutor.error.queryEmptyWithPeriod": "La consulta no puede estar vacía.",
- "queryExecutor.error.readOnlyOnly": "El modo de vista previa solo admite sentencias SQL de solo lectura.",
- "queryExecutor.error.namedParametersNotSupported": "El modo de vista previa no admite parámetros vinculados en SQL de ejecución. Usa literales seguros inline o ejecuta la consulta fuera de la vista previa.",
- "queryExecutor.error.positionalParametersNotSupported": "El modo de vista previa no admite placeholders posicionales (? o ).",
- "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "Alinear nodos seleccionados al borde inferior",
- "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "Alinear nodos seleccionados al borde izquierdo",
- "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "Alinear nodos seleccionados al borde derecho",
- "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "Alinear nodos seleccionados al borde superior",
- "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "Aplicar cambios del subcanvas CTE y volver al canvas padre",
- "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "Organizar nodos automáticamente en columnas lógicas",
- "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "Centrar nodos seleccionados en el eje horizontal",
- "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "Centrar nodos seleccionados en el eje vertical",
- "commandPalette.description.clear_canvas_and_start_fresh": "Limpiar canvas y comenzar desde cero",
- "commandPalette.description.clear_node_selection": "Limpiar selección de nodos",
- "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "Convertir alias a la convención configurada en ajustes del proyecto",
- "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "Crear checkpoints, comparar versiones lado a lado y restaurar un estado anterior del canvas",
- "commandPalette.description.delete_the_selected_nodes": "Eliminar nodos seleccionados",
- "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "Descartar cambios del subeditor actual y volver al canvas padre",
- "commandPalette.description.execute_the_current_query_in_preview": "Ejecutar la consulta actual en vista previa",
- "commandPalette.description.fit_all_nodes_into_the_visible_area": "Ajustar todos los nodos al área visible",
- "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "Generar archivo CSV desde el primer nodo de exportación CSV",
- "commandPalette.description.generate_html_file_from_the_first_html_export_node": "Generar archivo HTML desde el primer nodo de exportación HTML",
- "commandPalette.description.generate_json_file_from_the_first_json_export_node": "Generar archivo JSON desde el primer nodo de exportación JSON",
- "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "Generar libro XLSX desde el primer nodo de exportación Excel",
- "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "Inspeccionar plan de ejecución: tipos de scan, estrategias de join y estimaciones de costo",
- "commandPalette.description.load_a_vsaq_canvas_file": "Cargar archivo de canvas .vsaq",
- "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "Medir latencia promedio/mediana/p95 del SQL actual en N iteraciones",
- "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "Abrir editor de subcanvas aislado para el nodo de definición CTE seleccionado",
- "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "Abrir historial local de versiones creado en cada guardado y restaurar snapshots anteriores",
- "commandPalette.description.open_output_preview_modal_for_the_active_mode": "Abrir modal de vista previa de salida para el modo activo",
- "commandPalette.description.open_shortcut_reference_screen": "Abrir pantalla de referencia de atajos",
- "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "Abrir administrador de conexiones para agregar, editar o cambiar conexiones de base de datos",
- "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "Pegar SELECT y generar nodos automáticamente: FROM, JOIN, WHERE y LIMIT soportados",
- "commandPalette.description.remove_all_nodes_not_connected_to_output": "Eliminar todos los nodos no conectados a la salida",
- "commandPalette.description.reset_zoom_and_pan_to_default": "Restablecer zoom y desplazamiento a valores predeterminados",
- "commandPalette.description.save_canvas_to_a_new_file": "Guardar canvas en un archivo nuevo",
- "commandPalette.description.save_current_canvas": "Guardar canvas actual",
- "commandPalette.description.save_markdown_documentation_of_the_current_flow": "Guardar documentación Markdown del flujo actual",
- "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "Guardar nodos seleccionados como snippet reutilizable e insertarlo luego desde el buscador de nodos (⇧A)",
- "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "Escanear todos los nodos de tabla del canvas para posibles joins según convenciones FK y patrones de nombres",
- "commandPalette.description.select_all_nodes_on_canvas": "Seleccionar todos los nodos del canvas",
- "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "Ajustar posiciones de nodos a cuadrícula de 16px (Ctrl+G)",
- "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "Distribuir nodos seleccionados con espaciado horizontal igual",
- "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "Distribuir nodos seleccionados con espaciado vertical igual",
- "commandPalette.description.zoom_into_the_canvas": "Acercar en el canvas",
- "commandPalette.description.zoom_out_of_the_canvas": "Alejar en el canvas",
- "commandPalette.name.align_bottom": "Alinear Abajo",
- "commandPalette.name.align_left": "Alinear Izquierda",
- "commandPalette.name.align_right": "Alinear Derecha",
- "commandPalette.name.align_top": "Alinear Arriba",
- "commandPalette.name.analyze_all_joins": "Analizar Todos los Joins",
- "commandPalette.name.auto_fix_naming": "Auto-Corregir Nombres",
- "commandPalette.name.auto_layout": "Diseño automático",
- "commandPalette.name.center_horizontally": "Centrar Horizontalmente",
- "commandPalette.name.center_vertically": "Centrar Verticalmente",
- "commandPalette.name.cleanup_orphans": "Limpiar Huérfanos",
- "commandPalette.name.delete_selected": "Eliminar Seleccionados",
- "commandPalette.name.deselect_all": "Deseleccionar Todo",
- "commandPalette.name.discard_and_exit_editor": "Descartar y Salir del Editor",
- "commandPalette.name.distribute_horizontally": "Distribuir Horizontalmente",
- "commandPalette.name.distribute_vertically": "Distribuir Verticalmente",
- "commandPalette.name.edit_selected_cte": "Editar CTE Seleccionado",
- "commandPalette.name.exit_cte_editor": "Salir del Editor CTE",
- "commandPalette.name.explain_plan": "Plan de Ejecución",
- "commandPalette.name.export_csv": "Exportar CSV",
- "commandPalette.name.export_documentation": "Exportar Documentación",
- "commandPalette.name.export_excel": "Exportar Excel",
- "commandPalette.name.export_html": "Exportar HTML",
- "commandPalette.name.export_json": "Exportar JSON",
- "commandPalette.name.file_save_load_history": "Historial de Guardado/Carga",
- "commandPalette.name.fit_to_screen": "Ajustar a Pantalla",
- "commandPalette.name.flow_version_history": "Historial de Versiones del Flujo",
- "commandPalette.name.import_sql_to_graph": "Importar SQL a Grafo",
- "commandPalette.name.keyboard_shortcuts": "Atajos de Teclado",
- "commandPalette.name.manage_connections": "Administrar Conexiones",
- "commandPalette.name.new_canvas": "Nuevo Canvas",
- "commandPalette.name.open_file": "Abrir Archivo",
- "commandPalette.name.reset_viewport": "Restablecer Vista",
- "commandPalette.name.run_preview": "Ejecutar Vista Previa",
- "commandPalette.name.run_query_benchmark": "Ejecutar Benchmark de Consulta",
- "commandPalette.name.save": "Guardar",
- "commandPalette.name.save_as": "Guardar Como",
- "commandPalette.name.save_selection_as_snippet": "Guardar Selección como Snippet",
- "commandPalette.name.select_all": "Seleccionar Todo",
- "commandPalette.name.toggle_preview": "Alternar Vista Previa",
- "commandPalette.name.toggle_snap_to_grid": "Alternar Ajuste a Cuadrícula",
- "commandPalette.name.zoom_in": "Acercar",
- "commandPalette.name.zoom_out": "Alejar",
- "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 por ciento restaurar zoom paneo viewport",
- "commandPalette.tags.align_bottom_edge_selection_nodes": "alinear borde inferior selección nodos",
- "commandPalette.tags.align_center_middle_horizontal_nodes": "alinear centro medio horizontal nodos",
- "commandPalette.tags.align_center_middle_vertical_nodes": "alinear centro medio vertical nodos",
- "commandPalette.tags.align_left_edge_selection_nodes": "alinear borde izquierdo selección nodos",
- "commandPalette.tags.align_right_edge_selection_nodes": "alinear borde derecho selección nodos",
- "commandPalette.tags.align_top_edge_selection_nodes": "alinear borde superior selección nodos",
- "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout vista restablecer zoom",
- "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark rendimiento latencia tiempos perfil medir velocidad",
- "commandPalette.tags.clear_selection": "limpiar selección",
- "commandPalette.tags.connection_database_server_host_provider_switch": "conexión base datos servidor host proveedor cambiar",
- "commandPalette.tags.create_insert_search_transform": "crear insertar buscar transformar",
- "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas salir aplicar volver",
- "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte vista subcanvas descartar salir forzar",
- "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursivo editor subgrafo subcanvas aislar",
- "commandPalette.tags.data_results_table_panel": "datos resultados tabla panel",
- "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribuir espacio igual horizontal nodos",
- "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribuir espacio igual vertical nodos",
- "commandPalette.tags.execute_run_sql_query_results": "ejecutar correr sql consulta resultados",
- "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan ejecución costo scan índice join rendimiento",
- "commandPalette.tags.export_csv_file_tabular_output_save": "exportar csv archivo salida tabular guardar",
- "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "exportar excel xlsx archivo salida tabular hoja cálculo guardar",
- "commandPalette.tags.export_html_file_output_report_save": "exportar html archivo salida informe guardar",
- "commandPalette.tags.export_json_file_output_save": "exportar json archivo salida guardar",
- "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "exportar markdown doc documentación flujo guardar md",
- "commandPalette.tags.export_persist_copy": "exportar persistir copia",
- "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "archivo historial guardar cargar backup versiones restaurar local",
- "commandPalette.tags.forward_history": "adelante historial",
- "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "ayuda atajos hotkeys teclado referencia",
- "commandPalette.tags.highlight_mark_all_nodes": "resaltar marcar todos nodos",
- "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "importar sql pegar convertir grafo ingeniería inversa consulta",
- "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analizar sugerir detectar foreign key relaciones heurística",
- "commandPalette.tags.layer_z_order_back_selected_nodes": "capa orden z atrás nodos seleccionados",
- "commandPalette.tags.layer_z_order_backward_selected_nodes": "capa orden z enviar atrás nodos seleccionados",
- "commandPalette.tags.layer_z_order_forward_selected_nodes": "capa orden z traer adelante nodos seleccionados",
- "commandPalette.tags.layer_z_order_front_selected_nodes": "capa orden z al frente nodos seleccionados",
- "commandPalette.tags.layer_z_order_normalize_compact": "capa orden z normalizar compactar",
- "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout organizar columnas auto legibilidad",
- "commandPalette.tags.load_import_vsaq": "cargar importar vsaq",
- "commandPalette.tags.magnify_enlarge": "aumentar ampliar",
- "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "huérfano no usado desconectado limpiar eliminar nodos",
- "commandPalette.tags.persist_write_disk": "persistir escribir disco",
- "commandPalette.tags.remove_erase_nodes": "remover borrar nodos",
- "commandPalette.tags.rename_alias_fix_naming_convention": "renombrar alias corregir convención nombres",
- "commandPalette.tags.reset_clear_blank": "restablecer limpiar en blanco",
- "commandPalette.tags.revert_back_history": "revertir volver historial",
- "commandPalette.tags.shrink_reduce": "encoger reducir",
- "commandPalette.tags.snap_grid_align_precision_position": "snap cuadrícula alinear precisión posición",
- "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet guardar selección reutilizar plantilla favorito marcador",
- "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "versión historial checkpoint diff restaurar snapshot comparar deshacer flujo",
- "sqlEditor.diffPreview.title": "Transactional Diff Preview",
- "sqlEditor.mutation.confirmExecute": "Confirm Execute",
- "sqlEditor.tab.closeAnyway": "Close Anyway",
- "sqlEditor.tab.keepTab": "Keep Tab",
- "sqlEditor.status.ready": "Ready.",
- "sqlEditor.telemetry.none": "No execution telemetry yet.",
- "sqlEditor.telemetry.summary": "Statements: {0} Success: {1} Failed: {2} Total: {3} ms",
- "sqlEditor.telemetry.errors.none": "No aggregated errors.",
- "sqlEditor.diff.none": "No transactional diff preview available.",
- "sqlEditor.mutation.estimate.none": "No mutation estimate available.",
- "sqlEditor.mutation.estimate.value": "Estimated affected rows: {0}",
- "sqlEditor.mutation.estimate.unavailable": "Could not estimate affected rows automatically.",
- "sqlEditor.tab.closePending": "Unsaved changes detected. Confirm tab close.",
- "sqlEditor.tab.noPendingClose": "No tab close pending.",
- "sqlEditor.tab.manyWarning": "High tab count: {0} open tabs.",
- "sqlEditor.mutation.pending.none": "No pending mutation confirmation.",
- "sqlEditor.mutation.pending.required": "Mutation requires confirmation before execution.",
- "sqlEditor.message.empty": "Execute a statement to see messages.",
- "sqlEditor.message.success": "Execution completed successfully.",
- "sqlEditor.result.summary.empty": "Rows: - Time: -",
- "sqlEditor.result.summary": "Rows: {0} Time: {1} ms",
- "sqlEditor.file.save.canceled": "Save canceled.",
- "sqlEditor.file.save.noPath": "No target path selected.",
- "sqlEditor.file.save.success": "SQL file saved.",
- "sqlEditor.file.save.failed": "Save failed.",
- "sqlEditor.file.open.failed": "Open failed.",
- "sqlEditor.file.open.notFound": "Selected SQL file was not found.",
- "sqlEditor.file.open.success": "SQL file opened.",
- "sqlEditor.status.executing": "Executing SQL...",
- "sqlEditor.status.executingScript": "Executing SQL script...",
- "sqlEditor.status.executingStep": "Executing {0}/{1}...",
- "sqlEditor.status.canceling": "Canceling execution...",
- "sqlEditor.status.executingConfirmedMutation": "Executing confirmed mutation...",
- "sqlEditor.status.mutationCanceled": "Mutation execution canceled.",
- "sqlEditor.detail.statementNotExecuted": "Statement was not executed.",
- "sqlEditor.status.success": "Execution succeeded.",
- "sqlEditor.detail.rowsAndTime": "{0} row(s) in {1} ms.",
- "sqlEditor.status.canceled": "Execution canceled.",
- "sqlEditor.status.failed": "Execution failed.",
- "sqlEditor.status.confirmationRequired": "Confirmation required before execution.",
- "sqlEditor.error.mutationConfirmationRequired": "Mutation confirmation required.",
- "sqlEditor.result.tabTitle": "Result {0}",
- "sqlEditor.tab.closeRequiresConfirmation": "Tab close requires confirmation.",
- "sqlEditor.tab.unsavedDetail": "This tab has unsaved changes.",
- "sqlEditor.tab.closed": "Tab closed.",
- "sqlEditor.tab.closeCanceled": "Tab close canceled.",
- "sqlEditor.tab.closeCanceledDetail": "Unsaved tab kept open.",
- "sqlEditor.error.noStatementSelected": "No SQL statement selected for execution.",
- "sqlEditor.error.noConnection": "No active database connection for SQL execution.",
- "sqlEditor.error.executionCanceled": "SQL execution was canceled.",
- "sqlEditor.tab.scriptTitle": "Script {0}",
- "sqlEditor.guard.delete.noWhere.message": "DELETE without WHERE can remove all rows.",
- "sqlEditor.guard.delete.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
- "sqlEditor.guard.delete.trivialWhere.message": "DELETE has a trivially true WHERE clause.",
- "sqlEditor.guard.delete.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
- "sqlEditor.guard.update.noWhere.message": "UPDATE without WHERE can affect all rows.",
- "sqlEditor.guard.update.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
- "sqlEditor.guard.update.trivialWhere.message": "UPDATE has a trivially true WHERE clause.",
- "sqlEditor.guard.update.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
- "sqlEditor.guard.insert.noColumnList.message": "INSERT without explicit column list is fragile against schema changes.",
- "sqlEditor.guard.insert.noColumnList.recommendation": "Prefer INSERT INTO table(col1, col2, ...) VALUES (...).",
- "sqlEditor.guard.ddl.message": "DDL statement may cause structural changes in the database.",
- "sqlEditor.guard.ddl.recommendation": "Confirm execution only when schema changes are intended.",
- "sqlEditor.diff.unavailable.noPreview": "No transactional diff preview available for this statement.",
- "sqlEditor.diff.unavailable.parseError": "Could not parse mutation target for transactional diff preview.",
- "sqlEditor.diff.unavailable.connection": "Transactional diff preview unavailable due to connection or query limitations.",
- "sqlEditor.diff.deleteSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, affected {2}, total rows after {3}.",
- "sqlEditor.diff.updateSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, candidate rows affected {2}, total rows after {3}.",
- "sqlEditor.diff.unavailable.unsupportedStatement": "Transactional diff preview currently supports UPDATE and DELETE only.",
- "sqlEditor.results.title": "Results",
- "sqlEditor.saveSql.fileType": "SQL Files",
- "sqlEditor.saveSql.pickerTitle": "Save SQL File",
- "sqlEditor.export.pickerTitle": "Export SQL Data",
- "sqlEditor.export.status.noResultTitle": "No execution result available for export.",
- "sqlEditor.export.status.noResultDetail": "Execute a query first.",
- "sqlEditor.export.status.successTitle": "Report exported.",
- "sqlEditor.export.status.failedTitle": "Failed to export report.",
- "sqlEditor.export.fileType.html": "HTML File",
- "sqlEditor.export.fileType.json": "JSON File",
- "sqlEditor.export.fileType.csv": "CSV File",
- "sqlEditor.export.fileType.xlsx": "Excel Workbook",
- "sqlEditor.export.defaultFileBase": "report",
- "sqlEditor.export.defaultTitle": "SQL Report",
- "sqlEditor.export.error.typeRequired": "A report type must be selected before export.",
- "sqlEditor.export.type.html.title": "HTML full-feature report",
- "sqlEditor.export.type.html.description": "Standalone, SQL-first HTML artifact for offline audit.",
- "sqlEditor.export.type.json.title": "JSON execution contract",
- "sqlEditor.export.type.json.description": "Machine-readable payload with SQL, metadata and execution result.",
- "sqlEditor.export.type.csv.title": "CSV data export",
- "sqlEditor.export.type.csv.description": "Tabular result data only, suitable for spreadsheet tools.",
- "sqlEditor.export.type.xlsx.title": "Excel workbook export",
- "sqlEditor.export.type.xlsx.description": "Spreadsheet workbook with query result data only.",
- "sqlEditor.export.dialog.windowTitle": "Export SQL Data",
- "sqlEditor.export.dialog.title": "Export SQL Data",
- "sqlEditor.export.dialog.subtitle": "Choose the artifact format and metadata before exporting.",
- "sqlEditor.export.dialog.confirm": "Export",
- "sqlEditor.export.dialog.fileNameWatermark": "report.html",
- "sqlEditor.export.dialog.titleWatermark": "SQL Report",
- "sqlEditor.export.dialog.descriptionWatermark": "Additional context for auditors and teammates.",
- "sqlEditor.export.dialog.section.reportType": "REPORT TYPE",
- "sqlEditor.export.dialog.section.fileName": "FILE NAME",
- "sqlEditor.export.dialog.section.reportTitle": "TITLE",
- "sqlEditor.export.dialog.section.description": "DESCRIPTION",
- "sqlEditor.export.dialog.section.options": "OPTIONS",
- "sqlEditor.export.option.includeSchema": "Include output schema",
- "sqlEditor.export.option.includeNodeDetails": "Include node/connection placeholders in JSON",
- "sqlEditor.export.option.includeMetadata": "Include optional metadata",
- "sqlEditor.export.option.useDashForEmpty": "Use '-' for empty fields",
- "sqlEditor.export.badge.offline": "OFFLINE READY",
- "sqlEditor.export.badge.structured": "STRUCTURED PAYLOAD",
- "sqlEditor.export.badge.dataOnly": "DATA ONLY"
-}
+{
+ "main.brand": "AkkornStudio",
+ "main.tab.query1": "Query 1",
+ "main.new": "New",
+ "main.open": "Open",
+ "main.save": "Save",
+ "main.history": "History",
+ "main.layout": "Layout",
+ "main.preview": "Preview",
+ "main.undo": "Undo",
+ "main.redo": "Redo",
+ "main.cleanupOrphans": "Cleanup orphan nodes",
+ "main.autoFixAliasNaming": "Auto-fix alias naming",
+ "main.autoLayoutCanvas": "Auto layout canvas",
+ "main.toggleDataPreview": "Toggle data preview",
+ "main.language": "Language",
+ "main.restore.prompt": "Previous session found — restore the last canvas?",
+ "main.restore.button": "Restore session",
+ "main.cteEditor.editingPrefix": "Editing CTE: ",
+ "main.cteEditor.backToCanvas": "Back to Canvas",
+ "main.cteEditor.exitA11y": "Exit CTE editor",
+ "main.viewEditor.editingPrefix": "DDL > View: ",
+ "main.viewEditor.backToCanvas": "Back to DDL",
+ "main.viewEditor.exitA11y": "Exit view editor",
+ "connection.title": "Connection Manager",
+ "connection.subtitle": "Configure, pruebe y active conexiones sin salir del flujo",
+ "connection.none": "No connection",
+ "connection.active": "ACTIVE",
+ "connection.health.online": "Online",
+ "connection.health.degraded": "Degraded",
+ "connection.health.offline": "Offline",
+ "connection.tooltip.none": "No active connection — click to manage",
+ "connection.ping": "Ping",
+ "connection.saved": "SAVED CONNECTIONS",
+ "connection.new": "New Connection",
+ "connection.selectOrCreate": "Select a connection or create a new one",
+ "connection.name": "Connection Name",
+ "connection.provider": "Provider",
+ "connection.host": "Host",
+ "connection.port": "Port",
+ "connection.database": "Database",
+ "connection.sqlitePath": "SQLite Path",
+ "connection.sqliteBrowse": "Browse",
+ "connection.sqliteCreate": "Create",
+ "connection.username": "Username",
+ "connection.password": "Password",
+ "connection.timeout": "Timeout (seconds)",
+ "connection.test": "Test",
+ "connection.save": "Save",
+ "connection.connect": "Connect",
+ "connection.action.testConnection": "Test connection",
+ "connection.action.saveConnection": "Save connection",
+ "connection.action.connectConnection": "Connect connection",
+ "connection.status.connecting": "Conectando...",
+ "connection.status.connected": "Conectado",
+ "connection.status.testing": "Probando...",
+ "connection.status.failedPrefix": "Falló la conexión",
+ "connection.status.metadataUnavailable": "Falló la conexión: metadatos no disponibles.",
+ "connection.status.highLatency": "alta latencia",
+ "connection.watermark.name": "Mi BD de Producción",
+ "connection.watermark.host": "localhost",
+ "connection.watermark.port": "5432",
+ "connection.watermark.database": "database_name",
+ "connection.watermark.username": "user",
+ "connection.watermark.password": "••••••••",
+ "connection.watermark.timeout": "30",
+ "main.connectingDb": "Connecting to database...",
+ "main.emptyHint": "Press ⇧A to add your first node, or drag a table from the sidebar",
+ "status.nodesSeparator": " nodes · ",
+ "status.connectionsSuffix": " connections",
+ "status.undo": "Undo: ",
+ "status.shortcuts": "⇧A Nodes · F3 Preview · Ctrl+Z Undo · Del Remove · Alt+Drag Pan",
+ "connection.disconnect": "Disconnect",
+ "connection.action.disconnectConnection": "Disconnect connection",
+ "connectionTab.active": "ACTIVE CONNECTION",
+ "connectionTab.none": "No active connection",
+ "connectionTab.saved": "SAVED CONNECTIONS",
+ "connectionTab.new": "+ New Connection",
+ "schema.database": "DATABASE",
+ "schema.search": "Search tables, columns...",
+ "schema.loading": "Searching tables, columns...",
+ "schema.noConnection": "No Connection",
+ "schema.noConnectionHint": "Connect to a database to see tables, columns, and relationships",
+ "schema.emptyNoTables": "No tables found",
+ "fileHistory.title": "Save/Load Version History",
+ "fileHistory.reload": "Reload",
+ "fileHistory.restoreSelected": "Restore selected",
+ "fileHistory.empty": "No local versions yet",
+ "fileHistory.emptyHint": "Save this file to generate version history.",
+ "preview.title": "Data Preview",
+ "preview.subtitle": "Review data and diagnostics before continuing",
+ "preview.run": "Run",
+ "preview.cancel": "Cancel",
+ "preview.tab.preview": "Preview",
+ "preview.tab.sql": "SQL",
+ "preview.close": "Close preview",
+ "preview.running": "Running preview query… ",
+ "preview.clickCancel": "Click Cancel to stop",
+ "preview.cancelled": "Query cancelled",
+ "preview.runAgain": "Press Run to execute again",
+ "preview.failed": "Preview execution failed",
+ "preview.technical": "TECHNICAL DETAILS",
+ "preview.noData": "No data yet",
+ "preview.f3Hint": "Press F3 or Space to run the current query",
+ "sqlImporter.title": "Import SQL to Graph",
+ "sqlImporter.subtitle": "Paste a SELECT statement — nodes are created automatically",
+ "sqlImporter.sqlStatement": "SQL STATEMENT",
+ "sqlImporter.supported": "Supported: ",
+ "sqlImporter.import": "Import",
+ "sqlImporter.report": "CONVERSION REPORT",
+ "sqlEditor.mutation.dialogTitle": "Confirmacion de cambio",
+ "sqlEditor.mutation.dialogSubtitle": "Revisa el impacto antes de confirmar la ejecucion",
+ "search.empty": "No nodes found",
+ "search.emptyHint": "Try searching for UPPER, JSON, CAST, AND…",
+ "search.shortcut": "⇧A",
+ "search.spawn": "Spawn",
+ "commandPalette.empty": "Ningún comando coincide con tu búsqueda",
+ "commandPalette.search": "Buscar comando",
+ "commandPalette.shortcut": "CTRL+SHIFT+P",
+ "commandPalette.execute": "Ejecutar",
+ "context.editCte": "Edit Selected CTE",
+ "context.editViewSubcanvas": "Edit View Subcanvas",
+ "explain.title": "Explain Plan",
+ "explain.sql": "SQL",
+ "explain.option.analyze": "Analizar",
+ "explain.option.buffers": "Buffers",
+ "explain.badge.simulated": "SIMULADO",
+ "explain.timing.planning": "Planificacion:",
+ "explain.timing.execution": "Ejecucion:",
+ "explain.section.snapshotComparison": "Comparacion de instantaneas",
+ "explain.section.indexRecommendations": "Recomendaciones de indices",
+ "explain.section.history": "Historial",
+ "explain.detail.estimated": "Estimadas",
+ "explain.detail.actual": "Actuales",
+ "explain.detail.error": "Error",
+ "explain.detail.time": "Tiempo",
+ "explain.detail.loops": "Bucles",
+ "explain.rerun": "Re-run",
+ "explain.alertSuffix": " expensive operation(s) detected — consider adding indexes",
+ "explain.running": "Running EXPLAIN…",
+ "explain.failed": "⚠ EXPLAIN failed",
+ "explain.noPlan": "No plan yet",
+ "explain.rerunHint": "Press Re-run to execute EXPLAIN",
+ "explain.header.operation": "OPERACIÓN",
+ "explain.header.cost": "COSTO",
+ "explain.header.rows": "FILAS",
+ "explain.header.alert": "ALERTA",
+ "explain.mode.list": "Lista",
+ "explain.mode.tree": "Arbol",
+ "explain.action.snapshot": "Guardar snapshot",
+ "explain.action.copyJson": "Copiar JSON",
+ "explain.action.copyText": "Copiar texto",
+ "explain.action.saveJson": "Guardar .json",
+ "explain.action.openDalibo": "Abrir en Dalibo",
+ "explain.legend.seqscan": "SEQ SCAN — full table read, no index",
+ "explain.legend.sort": "SORT — in-memory sort",
+ "explain.legend.hash": "HASH — hash join",
+ "explain.escClose": "Esc to close",
+ "flowVersion.title": "Flow Version History",
+ "flowVersion.subtitle": "Create checkpoints, compare versions and restore",
+ "flowVersion.watermark": "Checkpoint label (optional)…",
+ "flowVersion.saveCheckpoint": "Save Checkpoint",
+ "flowVersion.compareMode": "Compare Mode",
+ "flowVersion.selectBase": "Select BASE version (from):",
+ "flowVersion.clickAny": "Then click any version in the list below to compare.",
+ "flowVersion.noCheckpoints": "No checkpoints yet",
+ "flowVersion.noCheckpointsHint": "Save a checkpoint above to begin tracking versions.",
+ "flowVersion.restore": "Restore",
+ "flowVersion.diffResults": "Diff Results",
+ "benchmark.title": "Query Benchmark",
+ "benchmark.subtitle": "Measures avg / median / p95 latency over N iterations",
+ "benchmark.sql": "SQL being benchmarked",
+ "benchmark.runLabel": "Run label",
+ "benchmark.runLabelWatermark": "Run 1",
+ "benchmark.iterations": "Iterations (1–100)",
+ "benchmark.warmup": "Warm-up passes (0–10)",
+ "benchmark.interval": "Interval between runs (ms)",
+ "benchmark.run": "Run Benchmark",
+ "benchmark.cancel": "Cancel",
+ "benchmark.clearHistory": "Clear History",
+ "benchmark.latest": "LATEST RESULT",
+ "benchmark.avg": "AVG",
+ "benchmark.median": "MEDIAN",
+ "benchmark.min": "MIN",
+ "benchmark.max": "MAX",
+ "benchmark.iterationsAt": " iterations · run at ",
+ "benchmark.history": "HISTORY",
+ "benchmark.header.label": "Etiqueta",
+ "benchmark.header.avg": "Prom",
+ "benchmark.header.median": "Mediana",
+ "benchmark.header.min": "Mín",
+ "benchmark.header.max": "Máx",
+ "benchmark.itersSuffix": " iters",
+ "diagnostics.title": "App Diagnostics",
+ "diagnostics.run": "Run",
+ "diagnostics.running": "Running checks…",
+ "diagnostics.ok": "OK",
+ "diagnostics.warning": "Warning",
+ "diagnostics.error": "Error",
+ "diagnostics.tooltip.rerun": "Re-run all checks",
+ "diagnostics.tooltip.copy": "Copy diagnostic report to clipboard",
+ "diagnostics.tooltip.close": "Close (Esc)",
+ "autoJoin.title": "Auto-Join Suggestions",
+ "autoJoin.titleForTable": "Auto-Join suggestions for {0}",
+ "autoJoin.acceptAll": "Accept All",
+ "autoJoin.accept": "Accept",
+ "autoJoin.skip": "Skip",
+ "autoJoin.allHandled": "All suggestions handled",
+ "autoJoin.joinKeyword": "JOIN",
+ "autoJoin.confidence.fkConstraint": "FK Constraint",
+ "autoJoin.confidence.fkReverse": "FK (Reverse)",
+ "autoJoin.confidence.namingMatch": "Naming Match",
+ "autoJoin.confidence.weakMatch": "Weak Match",
+ "autoJoin.runSelected": "Auto-Join Selected",
+ "autoJoin.noSimilarityTitle": "No automatic join found",
+ "autoJoin.noSimilarityDetails": "Choose the columns manually to create a simple join.",
+ "autoJoin.appliedTitle": "Auto-join applied",
+ "autoJoin.manual.title": "Create Manual Join",
+ "autoJoin.manual.subtitle": "No reliable similarity was found. Select one column from each table.",
+ "autoJoin.manual.leftColumn": "Left column",
+ "autoJoin.manual.rightColumn": "Right column",
+ "autoJoin.manual.joinType": "Join type",
+ "autoJoin.manual.operator": "Operator",
+ "autoJoin.manual.confirm": "Create join",
+ "autoJoin.manual.noCompatible": "No compatible columns for the selected left pin type.",
+ "autoJoin.manualJoinCreatedTitle": "Manual join created",
+ "autoJoin.manualJoinFailedTitle": "Manual join could not be created",
+ "autoJoin.manualJoinFailedDetails": "Check selected columns and existing joins, then try again.",
+ "autoJoin.multipleCandidatesTitle": "Multiple join candidates found",
+ "autoJoin.multipleCandidatesDetails": "{0} possible combinations were found. Confirm which columns should be used.",
+ "autoJoin.suggestionsFoundTitle": "Auto-join suggestions available",
+ "autoJoin.suggestionsFoundDetails": "{0} suggestion(s) found. Select two tables and run Auto-Join Selected.",
+ "property.outputAlias": "OUTPUT ALIAS",
+ "property.sourceAlias": "SOURCE ALIAS",
+ "property.aliasWatermark": "e.g. MyColumn (optional)",
+ "property.parameters": "PARAMETERS",
+ "property.enabled": "Enabled",
+ "property.datetimeWatermark": "YYYY-MM-DDTHH:mm:ss or leave empty",
+ "property.dateWatermark": "YYYY-MM-DD or leave empty",
+ "property.apply": "Apply",
+ "property.inputPins": "INPUT PINS",
+ "property.outputPins": "OUTPUT PINS",
+ "property.sqlTrace": "SQL TRACE",
+ "property.live": "live",
+ "node.numericValue": "Numeric Value",
+ "node.stringValue": "String Value",
+ "node.enterText": "Enter text",
+ "node.datetimeValue": "DateTime Value",
+ "node.valueLabel": "Value:",
+ "node.noInputs": "No inputs",
+ "node.loadingSample": "Loading sample…",
+ "node.previewFailed": "⚠ Preview failed",
+ "node.sampleRowsHint": "5 sample rows · demo data",
+ "sidebar.tab.nodes": "Nodos",
+ "sidebar.tab.connection": "Conexión",
+ "sidebar.tab.schema": "Esquema",
+ "sidebar.tab.diagnostics": "Diagnóstico",
+ "sidebar.addNode": "+ Add Node (⇧A)",
+ "sidebar.previewF3": "Preview (F3)",
+ "nodesList.search": "Search nodes...",
+ "search.watermark": "Search nodes… (Esc to close)",
+ "search.snippets": "★ SNIPPETS",
+ "commandPalette.watermark": "Ejecuta un comando… (Esc para cerrar)",
+ "tooltip.newCanvas": "New canvas (Ctrl+N)",
+ "tooltip.openCanvas": "Open canvas (Ctrl+O)",
+ "tooltip.saveCanvas": "Save canvas (Ctrl+S)",
+ "tooltip.fileHistory": "Local save/load history (Ctrl+Alt+H)",
+ "tooltip.zoomOut": "Zoom out (Ctrl+-)",
+ "tooltip.zoomIn": "Zoom in (Ctrl++)",
+ "tooltip.fitToScreen": "Fit to screen (Ctrl+0)",
+ "tooltip.autoLayout": "Auto Layout — arrange nodes into logical columns (Ctrl+L, Ctrl+Z to undo)",
+ "tooltip.snapToGrid": "Toggle snap to grid (Ctrl+G)",
+ "tooltip.dataPreview": "Data preview (F3)",
+ "tooltip.toggleLanguage": "Toggle language (pt-BR / en-US)",
+ "tooltip.appDiagnostics": "App Diagnostics (self-check)",
+ "tooltip.keyboardShortcuts": "Keyboard shortcuts (F1)",
+ "tooltip.cancelRunningQuery": "Cancel the running query",
+ "tooltip.closeEsc": "Close (Esc)",
+ "tooltip.recheckConnectionHealth": "Re-check connection health",
+ "tooltip.deleteConnection": "Delete connection",
+ "tooltip.testConnection": "Test connection",
+ "tooltip.saveConnection": "Save connection",
+ "tooltip.activateConnection": "Activate this connection",
+ "tooltip.toggleDataSamplePreview": "Toggle data sample preview",
+ "tooltip.liveSqlMutatingBlocked": "This SQL contains a data-mutating command and cannot be run in Safe Preview Mode",
+ "tooltip.copySql": "Copy SQL to clipboard",
+ "tooltip.formatSql": "Format SQL",
+ "tooltip.openBenchmark": "Open Query Benchmark (measure avg / median / p95 latency)",
+ "tooltip.openExplainPlan": "Open Explain Plan inspector — visualise the query execution plan",
+ "tooltip.switchToQueryMode": "Switch to Query canvas",
+ "tooltip.switchToDdlMode": "Switch to DDL canvas",
+ "tooltip.autoJoinSelected": "Try auto-join between the two selected tables",
+ "tooltip.pins.inputs": "Inputs",
+ "tooltip.pins.outputs": "Outputs",
+ "tooltip.pins.none": "None",
+ "tooltip.tableColumns": "Columns",
+ "tooltip.tableColumns.none": "No detailed columns",
+ "window.minimize": "Minimize window",
+ "window.maximizeRestore": "Maximize/restore window",
+ "window.close": "Close window",
+ "menu.newDiagram": "New diagram",
+ "menu.openFile": "Open file",
+ "menu.save": "Save",
+ "menu.fileHistory": "File history",
+ "menu.shortcuts": "Keyboard shortcuts",
+ "menu.settings": "Settings",
+ "menu.importDdlSchema": "Import DDL schema",
+ "menu.viewDdlSql": "View DDL SQL",
+ "menu.executeDdl": "Execute DDL",
+ "menu.backToStart": "Back to start",
+ "toast.ddlExecuteFailed": "Failed to execute DDL.",
+ "toast.ddlOpenFailed": "Failed to open DDL SQL.",
+ "toast.ddlImportFailed": "Failed to import schema into DDL.",
+ "toast.ddlConnectToImportSchema": "Connect to a database to import schema into the DDL canvas.",
+ "toast.ddlNoTablesFound": "No tables found to import in DDL mode.",
+ "toast.ddlSchemaImported": "Schema imported into the DDL canvas.",
+ "toast.ddlImportSummary": "{0} table(s), {1} column(s), {2} FK(s), {3} unique index(es).",
+ "toast.ddlConnectToImportTable": "Connect to a database to import tables into the DDL canvas.",
+ "toast.ddlTableAlreadyExists": "Table '{0}' already exists in the DDL canvas.",
+ "toast.ddlTableImported": "Table imported into the DDL canvas.",
+ "toast.ddlTableImportSummary": "Nodes: +{0}, connections: +{1}, FKs: +{2}.",
+ "toast.ddlNoActiveConnection": "No active connection to execute DDL.",
+ "toast.ddlExecutedSuccess": "DDL executed successfully.",
+ "toast.ddlExecutedWithIssues": "DDL executed with issues.",
+ "toast.switchToDdl": "Switch to DDL mode to generate SQL.",
+ "toast.ddlInvalid": "Invalid DDL. Fix errors before continuing.",
+ "toast.ddlNoStatements": "No DDL statements were generated in the canvas.",
+ "toast.previewOpenFailed": "Failed to open preview.",
+ "tab.switchFailed": "Failed to switch tab: {0}",
+ "settings.status.darkApplied": "Dark theme applied.",
+ "settings.status.lightApplied": "Light theme applied.",
+ "settings.status.snapUpdated": "Snap updated: {0}.",
+ "settings.status.languageToggled": "Language toggled.",
+ "settings.status.languageSelected": "Language selected: {0}.",
+ "settings.status.themeEditorReady": "Theme editor ready. Apply to save and use this theme.",
+ "settings.section.appearance.title": "Themes",
+ "settings.section.languageRegion.title": "Idioma y región",
+ "settings.section.dateTime.title": "Fecha y hora",
+ "settings.section.keyboard.title": "Atajos de teclado",
+ "settings.section.privacy.title": "Privacidad",
+ "settings.section.notification.title": "Notificaciones",
+ "settings.section.accessibility.title": "Accesibilidad",
+ "settings.section.default.title": "Configuración",
+ "settings.section.appearance.subtitle": "Elige tu estilo o personaliza tu tema",
+ "settings.section.languageRegion.subtitle": "Administra idioma y formato regional",
+ "settings.section.keyboard.subtitle": "Personaliza los atajos de teclado usados por la command palette y la ejecución del canvas.",
+ "settings.section.wip.subtitle": "En progreso.",
+ "settings.section.default.subtitle": "Configuración de la aplicación",
+ "settings.general": "General",
+ "settings.nav.appearance": "Appearance",
+ "settings.theme.light": "Modo claro",
+ "settings.theme.dark": "Modo oscuro",
+ "settings.theme.system": "Preferencias del sistema",
+ "settings.gridSnap.title": "Grid Snap",
+ "settings.gridSnap.subtitle": "Controls node snapping on the canvas.",
+ "settings.language.subtitle": "Seleccione el idioma de la aplicación.",
+ "settings.language.toggle": "Cambiar idioma",
+ "settings.language.option.ptBR": "Portugués (Brasil)",
+ "settings.language.option.enUS": "Inglés (Estados Unidos)",
+ "settings.language.option.esES": "Español (España)",
+ "settings.language.option.ruRU": "Ruso",
+ "settings.language.option.jaJP": "Japonés",
+ "settings.language.option.zhTW": "Chino tradicional",
+ "settings.themeJson.title": "JSON del tema",
+ "settings.themeJson.subtitle": "Pega tu JSON de tema, aplícalo y persístelo al instante.",
+ "settings.themeJson.apply": "Aplicar JSON",
+ "settings.themeJson.restoreDefault": "Restaurar tema predeterminado",
+ "mode.query": "Query",
+ "mode.ddl": "DDL",
+ "sidebar.left.close": "Close left sidebar",
+ "sidebar.left.open": "Reopen left sidebar",
+ "sidebar.right.close": "Close right sidebar",
+ "sidebar.right.open": "Reopen right sidebar",
+ "connection.completedTitle": "Connection completed",
+ "connection.clearCanvasPrompt": "Do you want to clear the current canvas to start with the new connection?",
+ "connection.close": "Close connection manager",
+ "connection.refreshHealth": "Refresh connection health",
+ "common.details": "Details",
+ "common.cancel": "Cancel",
+ "common.keep": "Keep",
+ "common.clear": "Clear",
+ "zoom.out": "Zoom out",
+ "zoom.in": "Zoom in",
+ "zoom.fit": "Fit zoom to screen",
+ "zoom.level": "Zoom level",
+ "settings.theme.mode": "Modo de tema",
+ "diagnostics.category.canvas": "Canvas Integrity",
+ "diagnostics.category.output": "Output & Execution",
+ "diagnostics.category.session": "Session & Safety",
+ "diagnostics.category.notice": "Runtime Notices",
+ "diagnostics.summary.ok": "All systems OK",
+ "diagnostics.summary.warningCount": "{0} warning(s) detected",
+ "diagnostics.summary.errorCount": "{0} error(s) detected",
+ "diagnostics.canvasMigration": "Canvas Migration",
+ "diagnostics.recommendation.resaveFile": "Vuelve a guardar el archivo para actualizarlo a la última versión del esquema.",
+ "diagnostics.canvasState.name": "Canvas State",
+ "diagnostics.canvasState.recommendation": "Add at least one {0} and one {1}",
+ "diagnostics.canvasState.empty": "Canvas is empty - no nodes present",
+ "diagnostics.canvasState.counts": "{0} node(s), {1} connection(s)",
+ "diagnostics.validation.name": "Errores de validación",
+ "diagnostics.validation.recommendation": "Corrige los nodos resaltados antes de ejecutar la vista previa de salida",
+ "diagnostics.validation.errorWithWarnings": "{0} error(es) y {1} advertencia(s) en el grafo",
+ "diagnostics.validation.warningOnly": "{0} advertencia(s) en el grafo",
+ "diagnostics.validation.none": "Sin problemas de validación",
+ "diagnostics.orphan.name": "Nodos huérfanos",
+ "diagnostics.orphan.recommendation": "Usa la acción de limpieza de huérfanos para remover nodos no usados",
+ "diagnostics.orphan.count": "{0} nodo(s) no conectado(s) a ninguna salida",
+ "diagnostics.orphan.none": "No se detectaron nodos huérfanos",
+ "diagnostics.naming.name": "Convenciones de nombres",
+ "diagnostics.naming.recommendation": "Usa autocorrección de alias cuando la conformidad sea menor a 100%",
+ "diagnostics.naming.conformance": "Conformidad de nombres: {0}%",
+ "diagnostics.naming.ok": "Todos los alias siguen las convenciones de nombres (100%)",
+ "diagnostics.queryCompilation.name": "Compilación SQL en vivo",
+ "diagnostics.queryCompilation.recommendation": "Revisa el diagnóstico SQL en la salida cuando se reporten errores/advertencias.",
+ "diagnostics.queryCompilation.errorFallback": "La compilación SQL en vivo reportó errores.",
+ "diagnostics.queryCompilation.warningCounts": "{0} elemento(s) de diagnóstico, {1} advertencia(s) de guardrail.",
+ "diagnostics.queryCompilation.ok": "SQL en vivo compilado sin diagnósticos.",
+ "diagnostics.previewSafety.name": "Seguridad de vista previa",
+ "diagnostics.previewSafety.recommendation": "La vista previa solo ejecuta sentencias de solo lectura.",
+ "diagnostics.previewSafety.blocked": "El SQL actual modifica datos y está bloqueado por el modo de vista previa segura.",
+ "diagnostics.previewSafety.ok": "Las verificaciones de seguridad de vista previa pasaron.",
+ "diagnostics.previewExecution.name": "Ejecución de vista previa",
+ "diagnostics.previewExecution.recommendation": "Ejecuta la vista previa e inspecciona diagnósticos por errores de ejecución/runtime.",
+ "diagnostics.previewExecution.failed": "La ejecución de vista previa falló.",
+ "diagnostics.previewExecution.cancelled": "La ejecución de vista previa fue cancelada.",
+ "diagnostics.previewExecution.done": "{0} fila(s) en {1}ms.",
+ "diagnostics.previewExecution.none": "No se detectaron problemas en la ejecución de vista previa.",
+ "diagnostics.ddlCompilation.name": "Compilación DDL",
+ "diagnostics.ddlCompilation.recommendation": "Corrige los diagnósticos de compilación DDL antes de ejecutar.",
+ "diagnostics.ddlCompilation.failed": "La compilación DDL falló.",
+ "diagnostics.ddlCompilation.warningCount": "{0} advertencia(s) reportada(s) por el compilador DDL.",
+ "diagnostics.ddlCompilation.ok": "Compilación DDL exitosa.",
+ "diagnostics.ddlOutput.name": "DDL Output",
+ "diagnostics.ddlOutput.recommendation": "Add/complete DDL nodes until at least one statement is generated.",
+ "diagnostics.ddlOutput.none": "No DDL statements generated yet.",
+ "diagnostics.ddlOutput.lines": "{0} line(s) of DDL generated.",
+ "diagnostics.undo.name": "Historial de deshacer",
+ "diagnostics.undo.recommendation": "El historial solo está en memoria; guarda tu canvas regularmente.",
+ "diagnostics.undo.saved": "Canvas guardado (sin cambios sin guardar).",
+ "diagnostics.undo.unsavedDeep": "Cambios sin guardar con {0} pasos de deshacer.",
+ "diagnostics.undo.unsaved": "Cambios sin guardar - {0} paso(s) de deshacer disponibles.",
+ "diagnostics.report.title": "AkkornStudio - Informe de diagnóstico",
+ "diagnostics.report.generated": "Generado",
+ "diagnostics.report.overall": "General",
+ "diagnostics.report.details": "Detalles",
+ "diagnostics.report.recommendation": "Recomendación",
+ "diagnostics.report.lastCheck": "Última verificación",
+ "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
+ "node.datetimeFormat": "YYYY-MM-DDTHH:mm:ss",
+ "preview.providerLabel": "Provider",
+ "preview.ddlDiagnosticsHint": "Error/warning details are available in Diagnostics.",
+ "preview.schemaAnalysis.run": "Run Analysis",
+ "preview.schemaAnalysis.cancel": "Cancel",
+ "preview.schemaAnalysis.issues": "Issues",
+ "preview.schemaAnalysis.clearFilters": "Clear Filters",
+ "preview.schemaAnalysis.clearBlacklist": "Clear Blacklist",
+ "preview.schemaAnalysis.severity": "Severity",
+ "preview.schemaAnalysis.severity.info": "Info",
+ "preview.schemaAnalysis.severity.warning": "Warning",
+ "preview.schemaAnalysis.severity.critical": "Critical",
+ "preview.schemaAnalysis.rule": "Rule",
+ "preview.schemaAnalysis.rule.fkCatalogInconsistent": "FK catalog inconsistent",
+ "preview.schemaAnalysis.rule.missingFk": "Missing FK",
+ "preview.schemaAnalysis.rule.namingConventionViolation": "Naming convention violation",
+ "preview.schemaAnalysis.rule.lowSemanticName": "Low semantic name",
+ "preview.schemaAnalysis.rule.missingRequiredComment": "Missing required comment",
+ "preview.schemaAnalysis.rule.nf1HintMultiValued": "1NF hint: multi-valued",
+ "preview.schemaAnalysis.rule.nf2HintPartialDependency": "2NF hint: partial dependency",
+ "preview.schemaAnalysis.rule.nf3HintTransitiveDependency": "3NF hint: transitive dependency",
+ "preview.schemaAnalysis.minConfidence": "Min Confidence",
+ "preview.schemaAnalysis.tableFilter": "Table Filter",
+ "preview.schemaAnalysis.tableFilterWatermark": "schema.table",
+ "preview.schemaAnalysis.ignore": "Execution Filters",
+ "preview.schemaAnalysis.ignoreViews": "Ignore views and materialized views",
+ "preview.schemaAnalysis.blacklist": "Table blacklist",
+ "preview.schemaAnalysis.blacklistAdd": "Add",
+ "preview.schemaAnalysis.blacklistRemove": "Remove selected",
+ "preview.schemaAnalysis.ignoreTable.placeholder": "schema.table",
+ "preview.schemaAnalysis.details": "Details",
+ "preview.schemaAnalysis.evidence": "Evidence",
+ "preview.schemaAnalysis.suggestions": "Suggestions",
+ "preview.schemaAnalysis.ruleDiagnostics": "Rule Diagnostics",
+ "preview.schemaAnalysis.sqlCandidates": "SQL Candidates",
+ "preview.schemaAnalysis.copySql": "Copy SQL",
+ "preview.schemaAnalysis.applyToCanvas": "Apply to Canvas",
+ "preview.schemaAnalysis.summary.issues": "Issues:",
+ "preview.schemaAnalysis.summary.rawPrefix": "(raw:",
+ "preview.schemaAnalysis.summary.critical": "| Critical:",
+ "preview.schemaAnalysis.summary.warning": "| Warning:",
+ "preview.schemaAnalysis.summary.info": "| Info:",
+ "preview.schemaAnalysis.state.metadataUnavailable": "Metadata unavailable for structural analysis.",
+ "preview.schemaAnalysis.state.cancelled": "Analysis cancelled by the user.",
+ "preview.schemaAnalysis.state.partialTimeout": "Analysis finished partially due to timeout.",
+ "preview.schemaAnalysis.state.failed": "Structural analysis failed.",
+ "preview.schemaAnalysis.state.empty": "No inferable structural issue was detected.",
+ "preview.schemaAnalysis.state.noFilterMatch": "No issue matches the selected filters.",
+ "preview.schemaAnalysis.state.noIssueSelected": "No issue selected.",
+ "preview.schemaAnalysis.state.noSqlCandidate": "No SQL candidate available.",
+ "preview.schemaAnalysis.actionBlockedTooltip": "Action unavailable for the current risk level or capability.",
+ "common.navigate": "Navigate",
+ "common.close": "Close",
+ "common.esc": "Esc",
+ "common.ms": "ms",
+ "common.zero": "0",
+ "diagnostics.tip": "Tip: check Diagnostics whenever preview/output reports warnings or errors.",
+ "nodesList.empty": "No nodes found",
+ "nodesList.emptyHint": "Adjust the search term to explore available types",
+ "schema.emptyFiltered": "No objects found for the current filter",
+ "start.lastSnapshot": "Last snapshot",
+ "app.brandBadge": "VS",
+ "property.tab.properties": "Properties",
+ "property.tab.projectSettings": "Project Settings",
+ "property.nodeType": "NODE TYPE",
+ "property.selectNodeHint": "Select a node to edit its properties.",
+ "property.namingConventions": "Naming Conventions",
+ "property.aliasConvention": "Alias convention",
+ "property.enforceAliasNaming": "Enforce alias naming",
+ "property.warnReservedSql": "Warn on reserved SQL keywords",
+ "property.maxAliasLength": "Max alias length",
+ "property.maxAliasLengthDefault": "64",
+ "property.namingSettingsHint": "These settings are project-scoped and are used by naming and validation helpers.",
+ "start.tips": "Tips",
+ "start.tips.quick": "Consejos rápidos",
+ "start.tips.item1": "1. Haz clic en Nuevo diagrama para empezar desde cero.",
+ "start.tips.item2": "2. Usa plantillas para acelerar el prototipado.",
+ "start.tips.item3": "3. Abre conexiones guardadas para cargar tablas reales.",
+ "start.tips.shortcut": "Atajo: CTRL+SHIFT+P abre la paleta de comandos.",
+ "start.workspace": "WORKSPACE",
+ "start.resumeTitle": "Continue where you left off",
+ "start.resumeSubtitle": "Quickly resume a recent project or start a new diagram.",
+ "start.chip.quickFlow": "Quick flow",
+ "start.chip.templates": "Templates",
+ "start.chip.connections": "Connections",
+ "start.savedConnectionsTitle": "Saved Connections",
+ "start.savedConnectionsSubtitle": "Connect quickly to a database to load schema and tables.",
+ "start.noConnectionsTitle": "No connections configured yet",
+ "start.noConnectionsSubtitle": "Create a connection to explore real tables in the editor.",
+ "start.newConnection": "+ New Connection",
+ "start.recentProjectsTitle": "Recent Projects",
+ "start.searchRecent": "Search recent project...",
+ "start.quickActions": "Quick actions",
+ "start.quickActionsSubtitle": "Open an existing file or start a new diagram.",
+ "start.noRecentTitle": "No recent projects yet",
+ "start.noRecentSubtitle": "Use the quick actions card above to get started.",
+ "start.exploreTemplates": "Explore templates",
+ "start.templatesFavoritesHint": "Favorites on top",
+ "start.favoriteTemplate": "Favorite template",
+ "node.columnSetPreview": "ColumnSet preview",
+ "node.view": "VIEW",
+ "node.tableDefinition": "Table Definition",
+ "node.join": "JOIN",
+ "node.window.addPartition": "Agregar ranura PARTITION BY",
+ "node.window.removePartition": "Remover ranura PARTITION BY",
+ "node.window.addOrder": "Agregar ranura ORDER BY",
+ "node.window.removeOrder": "Remover ranura ORDER BY",
+ "sql.keyword.select": "SELECT",
+ "sql.keyword.from": "FROM",
+ "sql.keyword.join": "JOIN",
+ "sql.keyword.where": "WHERE",
+ "sql.keyword.limit": "LIMIT",
+ "sqlImporter.close": "Close SQL importer",
+ "sqlImporter.report.imported": "Importado",
+ "sqlImporter.report.partial": "Parcial",
+ "sqlImporter.report.skipped": "Omitido",
+ "benchmark.close": "Close benchmark",
+ "benchmark.p95": "P95",
+ "benchmark.n": "N",
+ "liveSql.safePreview": "SAFE PREVIEW MODE",
+ "liveSql.title": "LIVE SQL",
+ "liveSql.blocked": "BLOCKED",
+ "liveSql.copy": "Copy",
+ "liveSql.format": "Format",
+ "liveSql.benchmark": "Benchmark",
+ "liveSql.explain": "Explain",
+ "liveSql.actionsHint": "Performance tools",
+ "ddl.dialog.title": "Ejecutar DDL",
+ "ddl.dialog.execute": "Ejecutar",
+ "ddl.dialog.cancel": "Cancelar",
+ "ddl.dialog.close": "Cerrar",
+ "ddl.dialog.stopOnError": "Detener en el primer fallo",
+ "ddl.dialog.confirmDestructive": "Confirmo la ejecución de sentencias destructivas (DROP TABLE)",
+ "ddl.dialog.reviewBeforeRun": "Revisa el script DDL antes de confirmar.",
+ "ddl.dialog.confirmQuestion": "¿Confirmar ejecución DDL en la base conectada?",
+ "ddl.dialog.irreversibleWarning": "Esta acción puede cambiar el esquema de forma irreversible.",
+ "ddl.dialog.mustConfirmDestructive": "Confirma la ejecución destructiva para continuar.",
+ "ddl.dialog.executing": "Ejecutando...",
+ "ddl.execute.result.summary": "Statements: {0} | Success: {1} | Failures: {2} | Time: {3:0}ms",
+ "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
+ "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
+ "ddl.execute.result.failed": "Failed to execute DDL.",
+ "ddl.execute.result.cancelled": "Execution cancelled by the user.",
+ "ddl.execute.result.cancelledDetails": "DDL execution was interrupted before completion.",
+ "context.deleteSingle": "Delete {0}",
+ "context.deleteMultiple": "Delete {0} nodes",
+ "context.bringForward": "Bring Forward (Ctrl+PgUp)",
+ "context.sendBackward": "Send Backward (Ctrl+PgDown)",
+ "context.bringToFront": "Bring to Front (Ctrl+Shift+PgUp)",
+ "context.sendToBack": "Send to Back (Ctrl+Shift+PgDown)",
+ "context.normalizeLayers": "Normalize Layers",
+ "context.deleteWire": "Delete wire",
+ "context.addNode": "Add Node (Shift+A)",
+ "context.undoWithDescription": "Undo {0}",
+ "context.redo": "Redo",
+ "shortcuts.windowTitle": "Keyboard Shortcuts",
+ "shortcuts.headerTitle": "AkkornStudio - Shortcuts",
+ "shortcuts.headerHint": "Tip: use CTRL+SHIFT+P to open the Command Palette and search commands.",
+ "shortcuts.filterWatermark": "Filter shortcuts by key or action...",
+ "shortcuts.resultCount": "{0} shortcuts",
+ "shortcuts.resultFilter": "{0} result(s) for \"{1}\"",
+ "shortcuts.noneFound": "No shortcuts found.",
+ "shortcuts.section.fileGeneral": "Archivo y general",
+ "shortcuts.section.editing": "Edición",
+ "shortcuts.section.canvasNavigation": "Canvas y navegación",
+ "shortcuts.section.zoomPanPrecision": "Zoom, paneo y precisión",
+ "shortcuts.section.previewInspection": "Vista previa e inspección",
+ "shortcuts.key.deleteOrBackspace": "Del o Backspace",
+ "shortcuts.key.middleDrag": "Botón medio + arrastrar",
+ "shortcuts.key.rightDrag": "Botón derecho + arrastrar",
+ "shortcuts.key.spaceDrag": "Espacio + arrastrar",
+ "shortcuts.key.altLeftDrag": "Alt + arrastre izquierdo",
+ "shortcuts.key.arrows": "Flechas",
+ "shortcuts.key.shiftArrows": "Shift + Flechas",
+ "shortcuts.action.openShortcutScreen": "Abrir esta pantalla de atajos",
+ "shortcuts.action.newCanvas": "Nuevo canvas",
+ "shortcuts.action.openFile": "Abrir archivo",
+ "shortcuts.action.save": "Guardar",
+ "shortcuts.action.saveAs": "Guardar como",
+ "shortcuts.action.commandPalette": "Paleta de comandos",
+ "shortcuts.action.undo": "Deshacer",
+ "shortcuts.action.redo": "Rehacer",
+ "shortcuts.action.selectAll": "Seleccionar todo",
+ "shortcuts.action.deleteSelection": "Eliminar selección",
+ "shortcuts.action.closeOverlayCancel": "Cerrar overlays / cancelar acciones",
+ "shortcuts.action.openNodeSearch": "Abrir búsqueda de nodos",
+ "shortcuts.action.resetViewport": "Restablecer viewport",
+ "shortcuts.action.centerSelection": "Centrar selección",
+ "shortcuts.action.fitSelection": "Ajustar selección",
+ "shortcuts.action.autoLayout": "Diseño automático",
+ "shortcuts.action.toggleSnapToGrid": "Alternar ajuste a cuadrícula",
+ "shortcuts.action.bringForward": "Traer adelante",
+ "shortcuts.action.sendBackward": "Enviar atrás",
+ "shortcuts.action.bringToFront": "Traer al frente",
+ "shortcuts.action.sendToBack": "Enviar al fondo",
+ "shortcuts.action.zoomInOut": "Acercar / alejar",
+ "shortcuts.action.pan": "Panear",
+ "shortcuts.action.temporaryPan": "Paneo temporal",
+ "shortcuts.action.alternatePan": "Paneo alternativo",
+ "shortcuts.action.fineNudge": "Movimiento fino de selección",
+ "shortcuts.action.fastNudge": "Movimiento rápido",
+ "shortcuts.action.togglePreview": "Alternar vista previa de datos",
+ "shortcuts.action.explainPlan": "Plan de ejecución",
+ "shortcuts.action.runPreview": "Ejecutar vista previa",
+ "shortcuts.action.connectionManager": "Administrador de conexiones",
+ "shortcuts.action.flowVersionHistory": "Historial de versiones del flujo",
+ "shortcuts.resetAll": "Restablecer todo",
+ "shortcuts.customized": "Personalizado",
+ "shortcuts.default": "Predeterminado",
+ "shortcuts.apply": "Aplicar",
+ "shortcuts.reset": "Restablecer",
+ "shortcuts.status.resetAllSuccess": "Todos los atajos se restablecieron a los valores predeterminados.",
+ "shortcuts.status.updated": "Atajo actualizado.",
+ "shortcuts.status.reset": "Atajo restablecido al valor predeterminado.",
+ "shortcuts.status.updateFailed": "No se pudo actualizar el atajo.",
+ "toast.severity.success": "Success",
+ "toast.severity.warning": "Warning",
+ "toast.severity.error": "Error",
+ "toast.details.success": "Success Details",
+ "toast.details.warning": "Warning Details",
+ "toast.details.error": "Error Details",
+ "diagnostics.area.cteEditor": "Editor CTE",
+ "diagnostics.area.viewEditor": "Editor de vista",
+ "diagnostics.area.subEditor": "Subeditor",
+ "diagnostics.cteEditor.restoreParentFailed": "Failed to restore the parent canvas. CTE edits were discarded.",
+ "diagnostics.recommendation.reloadFileIfNeeded": "Recarga el archivo si es necesario.",
+ "diagnostics.viewEditor.exitFailed": "No se pudo salir: {0}",
+ "diagnostics.viewEditor.canvasIncomplete": "el canvas está incompleto.",
+ "diagnostics.viewEditor.exitRecommendation": "Conecta un ResultOutput válido o usa el comando descartar.",
+ "diagnostics.viewEditor.restoreParentFailed": "Falló la restauración del canvas padre. El subgrafo fue descartado.",
+ "diagnostics.subEditor.executeFailed": "Failed to execute editor action: {0}",
+ "diagnostics.subEditor.executeRecommendation": "Try again. If it persists, reload the canvas.",
+ "diagnostics.canvasMigration.openWarning": "Open: {0}",
+ "diagnostics.canvasMigration.sessionRestoreWarning": "Session restore: {0}",
+ "diagnostics.canvasMigration.versionRestoreWarning": "Version restore: {0}",
+ "diagnostics.recommendation.resaveLatestSchema": "Revisa diagnósticos y vuelve a guardar el canvas para persistir el esquema más reciente.",
+ "diagnostics.recommendation.saveMigratedSchema": "Revisa diagnósticos y guarda el canvas para persistir el esquema migrado.",
+ "file.saveDialog.title": "Save Canvas",
+ "file.saveDialog.suggestedName": "Query1",
+ "file.save.success": "Canvas saved successfully.",
+ "file.save.failedWithReason": "Save failed: {0}",
+ "file.openDialog.title": "Open Canvas",
+ "file.open.failedWithReason": "Open failed: {0}",
+ "file.open.success": "Canvas opened successfully.",
+ "file.open.successWithWarnings": "Canvas opened with warnings.",
+ "session.restore.failedWithReason": "Restore failed: {0}",
+ "session.restore.successWithWarnings": "Session restored with warnings.",
+ "session.restore.success": "Session restored successfully.",
+ "export.documentation.dialogTitle": "Export Flow Documentation",
+ "export.documentation.success": "Documentation exported successfully.",
+ "export.documentation.failed": "Documentation export failed.",
+ "export.failed.pathPermissionsHint": "Check file path and permissions.",
+ "export.nodeNotFound": "No {0} Export node found on the canvas. Add one via the node search menu.",
+ "export.dialogTitleByExtension": "Export as {0}",
+ "export.success": "Export completed successfully.",
+ "export.failed": "Export failed.",
+ "fileHistory.currentFile.none": "No file selected",
+ "fileHistory.status.saveFirst": "Save the canvas first to enable local history.",
+ "fileHistory.status.noneFound": "No local versions found yet. Save this file to create history entries.",
+ "fileHistory.status.countAvailable": "{0} local version(s) available.",
+ "fileHistory.restore.failedWithReason": "Restore failed: {0}",
+ "fileHistory.restore.successFrom": "Restored version from {0}.",
+ "preview.status.cancelled": "Cancelled",
+ "preview.status.error": "Error",
+ "preview.status.ready": "Ready",
+ "preview.runningWithMs": "Running... {0}ms",
+ "preview.runningWithTimeout": "Running... {0}ms (timeout: {1}s)",
+ "preview.runningSlowWithTimeout": "Running... {0}ms (timeout: {1}s) · Slow query, timeout in {2}s",
+ "explain.errorWithReason": "Explain plan error: {0}",
+ "explain.noSql": "No SQL to explain. Build a query on the canvas first.",
+ "ddl.compilationFailed": "Compilation failed",
+ "ddl.compileErrorWithReason": "DDL compile error: {0}",
+ "command.undo.name": "Undo",
+ "command.undo.description": "Undo last action",
+ "command.redo.name": "Redo",
+ "command.redo.description": "Redo last undone action",
+ "command.addNode.name": "Add Node",
+ "command.addNode.description": "Open node search menu to add a node",
+ "command.bringForward.name": "Bring Forward",
+ "command.bringForward.description": "Move selected nodes one layer forward",
+ "command.sendBackward.name": "Send Backward",
+ "command.sendBackward.description": "Move selected nodes one layer backward",
+ "command.bringToFront.name": "Bring to Front",
+ "command.bringToFront.description": "Move selected nodes to top layer",
+ "command.sendToBack.name": "Send to Back",
+ "command.sendToBack.description": "Move selected nodes to bottom layer",
+ "command.normalizeLayers.name": "Normalize Layers",
+ "command.normalizeLayers.description": "Compact node layer indices to a clean 0..N order",
+ "tooltip.cleanupOrphans": "Remove orphan nodes not connected to the output (Ctrl+Z to undo)",
+ "main.orphanSuffix": "Orphan(s)",
+ "tooltip.autoFixAliasNaming": "Fix alias naming to snake_case (Ctrl+Z to undo)",
+ "main.namingPrefix": "Naming",
+ "fileHistory.compressedLabel": "Compressed:",
+ "schema.itemsSuffix": "item(s)",
+ "property.panel.title": "Properties",
+ "property.panel.multiSelected": "{0} nodes selected",
+ "sqlImporter.status.pasteSelect": "Pega una sentencia SELECT arriba y luego haz clic en Importar.",
+ "sqlImporter.status.inputTooLarge": "La entrada SQL es demasiado grande ({0:N0} caracteres). El límite es {1:N0}. Divide la consulta o aumenta el límite de importación.",
+ "sqlImporter.status.parsing": "Analizando SQL...",
+ "sqlImporter.status.done": "Listo - {0} importado(s), {1} parcial(es), {2} omitido(s).",
+ "sqlImporter.status.cancelledByUser": "Importación cancelada por el usuario.",
+ "sqlImporter.status.timeout": "La importación agotó el tiempo tras {0:0.#}s. Prueba una consulta más pequeña o aumenta el timeout.",
+ "sqlImporter.status.parseError": "Error de parseo: {0}",
+ "diagnostics.area.undoRedoTransaction": "Transacción Deshacer/Rehacer",
+ "undoRedo.rollbackExecuted": "Rollback executed for '{0}' ({1} operation(s) reverted).",
+ "undoRedo.rollbackRecommendation": "Review the canvas state and retry the action if needed.",
+ "node.preview.noCatalog": "No catalog available",
+ "connection.error.searchMenuNotInitialized": "el menú de búsqueda no está inicializado",
+ "connection.error.timeoutReachability": "Tiempo de conexión agotado - verifica que el servidor sea accesible y aumenta el timeout si es necesario.",
+ "connection.error.authenticationFailedForProvider": "Falló la autenticación - verifica usuario y contraseña para {0}.",
+ "connection.error.databaseNotFoundForProvider": "Base de datos no encontrada - confirma que el nombre exista en {0}.",
+ "connection.error.hostNotFound": "Host no encontrado - verifica dirección del servidor y resolución DNS.",
+ "connection.error.portRefused": "Conexión al puerto rechazada - verifica el puerto y que el servidor/firewall permitan acceso.",
+ "connection.error.sslTls": "Error SSL/TLS - verifica configuración SSL del servidor o desactiva SSL para conexiones locales.",
+ "connection.error.timeoutOverloaded": "Tiempo de conexión agotado - el servidor puede estar sobrecargado o inaccesible. Intenta aumentar el timeout.",
+ "connection.error.insufficientPrivileges": "Privilegios insuficientes - el usuario puede no tener permiso para conectarse a esta base.",
+ "diagnostics.area.connection": "Conexión",
+ "connection.warning.canvasMayContainOldTables": "The canvas may still contain tables from a previous connection.",
+ "connection.warning.canvasMayContainOldTablesRecommendation": "Clear the canvas manually or reconnect and choose keep/clear again.",
+ "undoRedo.transaction.unnamed": "unnamed transaction",
+ "benchmark.runLabelDefault": "Run 1",
+ "benchmark.runLabelPattern": "Run {0}",
+ "benchmark.status.failedWithReason": "Benchmark falló: {0}",
+ "benchmark.status.noSql": "No hay SQL para benchmark - construye una consulta primero.",
+ "benchmark.status.warmupProgress": "Calentamiento {0}/{1}...",
+ "benchmark.status.iterationProgress": "Iteración {0}/{1}...",
+ "benchmark.status.done": "Listo - {0}",
+ "benchmark.status.cancelled": "Benchmark cancelado.",
+ "app.windowTitle": "AkkornStudio",
+ "preview.error.safePreviewBlocked": "Safe Preview Mode: data-mutating commands (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) cannot be executed in preview.",
+ "preview.error.noActiveConnection": "No active database connection. Please connect to a database first.",
+ "sqlImporter.error.selectFromNotFound": "No se pudo encontrar SELECT ... FROM en la consulta.",
+ "sqlImporter.error.fromClauseParseFailed": "No se pudo parsear la cláusula FROM.",
+ "sqlImporter.error.syntaxUnterminatedString": "Error de sintaxis en línea {0}, columna {1}: literal de cadena sin cerrar.",
+ "sqlImporter.error.missingClosingParenthesis": "falta ')' de cierre",
+ "sqlImporter.error.unexpectedClosingParenthesis": "')' inesperado",
+ "sqlImporter.error.syntaxAtLineColumn": "Error de sintaxis en línea {0}, columna {1}: {2}.",
+ "errorDiagnostics.safePreview.label": "Blocked by Safe Preview Mode",
+ "errorDiagnostics.safePreview.friendly": "This SQL contains a data-mutating command and cannot be executed in preview.",
+ "errorDiagnostics.safePreview.suggestion": "Remove or replace the mutating command (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) before running preview.",
+ "errorDiagnostics.connection.label": "Connection failed",
+ "errorDiagnostics.connection.friendly": "Could not reach the database server. The host may be down, unreachable, or blocking connections.",
+ "errorDiagnostics.connection.suggestion": "Verify the server address and port, ensure the database is running, and check firewall rules.",
+ "errorDiagnostics.authorization.label": "Authorization error",
+ "errorDiagnostics.authorization.friendly": "The current credentials do not have permission to perform this operation.",
+ "errorDiagnostics.authorization.suggestion": "Confirm the database user has SELECT privileges on the target table/schema, or contact your DBA.",
+ "errorDiagnostics.timeout.label": "Query timeout",
+ "errorDiagnostics.timeout.friendly": "The query took too long to complete and was cancelled by the server or client.",
+ "errorDiagnostics.timeout.suggestion": "Add a WHERE clause or LIMIT to reduce the result set, or increase the query timeout in connection settings.",
+ "errorDiagnostics.schema.label": "Schema error",
+ "errorDiagnostics.schema.friendly": "A referenced table, column, or object could not be found in the database.",
+ "errorDiagnostics.schema.suggestion": "Check that all table/column names are spelled correctly and that the schema matches the active connection.",
+ "errorDiagnostics.syntax.label": "SQL syntax error",
+ "errorDiagnostics.syntax.friendly": "The query contains a syntax error and could not be parsed by the database engine.",
+ "errorDiagnostics.syntax.suggestion": "Review the highlighted SQL for typos, mismatched parentheses, or unsupported clauses for the active provider.",
+ "errorDiagnostics.compatibility.label": "Compatibility error",
+ "errorDiagnostics.compatibility.friendly": "A function, operator, or syntax construct is not supported by the active database provider.",
+ "errorDiagnostics.compatibility.suggestion": "Switch to the correct provider in the SQL bar, or replace the unsupported construct with an equivalent.",
+ "errorDiagnostics.unknown.label": "Unexpected error",
+ "errorDiagnostics.unknown.friendly": "An error occurred while running the preview query.",
+ "errorDiagnostics.unknown.suggestion": "Check the technical details below and verify that your canvas is configured correctly.",
+ "error.mainWindow.invalidDataContext": "El DataContext de MainWindow debe ser un ShellViewModel.",
+ "error.mainWindow.canvasNotInitialized": "CanvasViewModel no fue inicializado.",
+ "error.mainWindow.ddlPreviewUnavailable": "La vista previa DDL no está disponible para el canvas actual.",
+ "themeJson.editor.template": "{\n \"meta\": { \"name\": \"Tema personalizado\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
+ "themeJson.error.pasteBeforeApply": "Pega un JSON de tema antes de aplicar.",
+ "themeJson.error.invalidJson": "JSON inválido: {0}",
+ "themeJson.error.emptyPayload": "JSON inválido: payload vacío.",
+ "themeJson.error.invalidTheme": "Tema inválido: {0}",
+ "themeJson.error.appliedButSaveFailed": "Tema aplicado, pero no se pudo guardar: {0}",
+ "themeJson.success.appliedAndSaved": "Tema JSON aplicado y guardado.",
+ "themeJson.success.customRemoved": "Tema personalizado eliminado. Reinicia la app para volver completamente al tema predeterminado.",
+ "themeJson.error.restoreDefaultFailed": "Error al restaurar el tema predeterminado: {0}",
+ "themeValidator.error.configNull": "La configuración del tema es nula.",
+ "themeValidator.warning.noSections": "El tema no tiene secciones de colores o tipografía; no hay nada para aplicar.",
+ "themeValidator.warning.invalidColor": "{0} tiene un color inválido '{1}'. Esta clave será ignorada.",
+ "themeValidator.warning.sizeOutOfRange": "{0}={1} está fuera del rango (8..48). Esta clave será ignorada.",
+ "queryExecutor.error.openConnectionMethodNotFound": "No se puede encontrar el método OpenConnectionAsync en el orquestador",
+ "queryExecutor.error.openConnectionInvokeFailed": "Error al invocar OpenConnectionAsync",
+ "ddlImporter.warning.viewSelectNotReconstructable": "Vista '{0}': el SELECT de la vista no puede reconstruirse visualmente; edítalo manualmente en el subcanvas.",
+ "ddlImporter.error.tableNotFoundInMetadata": "La tabla '{0}' no se encontró en los metadatos actuales.",
+ "main.window.untitled": "Sin título",
+ "main.subEditor.noSeedProvided": "No se proporcionó seed de subeditor para {0}.",
+ "main.layerOrder.bringToFront": "Traer al frente",
+ "main.layerOrder.sendToBack": "Enviar atrás",
+ "main.layerOrder.bringForward": "Adelantar capa",
+ "main.layerOrder.sendBackward": "Retroceder capa",
+ "main.layerOrder.normalizeLayers": "Normalizar capas",
+ "export.fileType.html": "Archivos HTML",
+ "export.fileType.json": "Archivos JSON",
+ "export.fileType.csv": "Archivos CSV",
+ "export.fileType.excel": "Archivos Excel",
+ "commandPalette.templatePrefix": "Plantilla: {0}",
+ "themeLoader.status.notFoundWithPath": "Archivo de tema no encontrado: {0}",
+ "themeLoader.status.deserializedNull": "El JSON del tema se deserializó como null.",
+ "themeLoader.status.loaded": "JSON del tema cargado correctamente.",
+ "credential.error.ciphertextTooShort": "El bloque de texto cifrado es demasiado corto.",
+ "credential.error.dpapiWindowsOnly": "DPAPI solo está disponible en Windows.",
+ "credential.warning.loadVaultFailed": "No se pudo cargar el almacén de credenciales {0}: {1}",
+ "credential.warning.persistVaultFailed": "No se pudo guardar el almacén de credenciales {0}: {1}",
+ "snippetStore.warning.loadFailed": "No se pudieron cargar snippets desde {0}: {1}",
+ "snippetStore.warning.saveFailed": "No se pudieron guardar snippets: {0}",
+ "flowVersionStore.warning.loadFailed": "No se pudieron cargar versiones de flujo desde {0}: {1}",
+ "flowVersionStore.warning.saveFailed": "No se pudieron guardar versiones de flujo: {0}",
+ "queryExecutor.error.queryEmpty": "La consulta no puede estar vacía",
+ "queryExecutor.error.providerNotSupported": "El proveedor {0} no es compatible",
+ "queryExecutor.error.singleStatementOnly": "La vista previa solo acepta una única sentencia SQL.",
+ "queryExecutor.error.queryEmptyWithPeriod": "La consulta no puede estar vacía.",
+ "queryExecutor.error.readOnlyOnly": "El modo de vista previa solo admite sentencias SQL de solo lectura.",
+ "queryExecutor.error.namedParametersNotSupported": "El modo de vista previa no admite parámetros vinculados en SQL de ejecución. Usa literales seguros inline o ejecuta la consulta fuera de la vista previa.",
+ "queryExecutor.error.positionalParametersNotSupported": "El modo de vista previa no admite placeholders posicionales (? o ).",
+ "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "Alinear nodos seleccionados al borde inferior",
+ "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "Alinear nodos seleccionados al borde izquierdo",
+ "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "Alinear nodos seleccionados al borde derecho",
+ "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "Alinear nodos seleccionados al borde superior",
+ "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "Aplicar cambios del subcanvas CTE y volver al canvas padre",
+ "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "Organizar nodos automáticamente en columnas lógicas",
+ "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "Centrar nodos seleccionados en el eje horizontal",
+ "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "Centrar nodos seleccionados en el eje vertical",
+ "commandPalette.description.clear_canvas_and_start_fresh": "Limpiar canvas y comenzar desde cero",
+ "commandPalette.description.clear_node_selection": "Limpiar selección de nodos",
+ "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "Convertir alias a la convención configurada en ajustes del proyecto",
+ "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "Crear checkpoints, comparar versiones lado a lado y restaurar un estado anterior del canvas",
+ "commandPalette.description.delete_the_selected_nodes": "Eliminar nodos seleccionados",
+ "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "Descartar cambios del subeditor actual y volver al canvas padre",
+ "commandPalette.description.execute_the_current_query_in_preview": "Ejecutar la consulta actual en vista previa",
+ "commandPalette.description.fit_all_nodes_into_the_visible_area": "Ajustar todos los nodos al área visible",
+ "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "Generar archivo CSV desde el primer nodo de exportación CSV",
+ "commandPalette.description.generate_html_file_from_the_first_html_export_node": "Generar archivo HTML desde el primer nodo de exportación HTML",
+ "commandPalette.description.generate_json_file_from_the_first_json_export_node": "Generar archivo JSON desde el primer nodo de exportación JSON",
+ "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "Generar libro XLSX desde el primer nodo de exportación Excel",
+ "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "Inspeccionar plan de ejecución: tipos de scan, estrategias de join y estimaciones de costo",
+ "commandPalette.description.load_a_vsaq_canvas_file": "Cargar archivo de canvas .vsaq",
+ "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "Medir latencia promedio/mediana/p95 del SQL actual en N iteraciones",
+ "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "Abrir editor de subcanvas aislado para el nodo de definición CTE seleccionado",
+ "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "Abrir historial local de versiones creado en cada guardado y restaurar snapshots anteriores",
+ "commandPalette.description.open_output_preview_modal_for_the_active_mode": "Abrir modal de vista previa de salida para el modo activo",
+ "commandPalette.description.open_shortcut_reference_screen": "Abrir pantalla de referencia de atajos",
+ "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "Abrir administrador de conexiones para agregar, editar o cambiar conexiones de base de datos",
+ "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "Pegar SELECT y generar nodos automáticamente: FROM, JOIN, WHERE y LIMIT soportados",
+ "commandPalette.description.remove_all_nodes_not_connected_to_output": "Eliminar todos los nodos no conectados a la salida",
+ "commandPalette.description.reset_zoom_and_pan_to_default": "Restablecer zoom y desplazamiento a valores predeterminados",
+ "commandPalette.description.save_canvas_to_a_new_file": "Guardar canvas en un archivo nuevo",
+ "commandPalette.description.save_current_canvas": "Guardar canvas actual",
+ "commandPalette.description.save_markdown_documentation_of_the_current_flow": "Guardar documentación Markdown del flujo actual",
+ "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "Guardar nodos seleccionados como snippet reutilizable e insertarlo luego desde el buscador de nodos (⇧A)",
+ "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "Escanear todos los nodos de tabla del canvas para posibles joins según convenciones FK y patrones de nombres",
+ "commandPalette.description.select_all_nodes_on_canvas": "Seleccionar todos los nodos del canvas",
+ "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "Ajustar posiciones de nodos a cuadrícula de 16px (Ctrl+G)",
+ "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "Distribuir nodos seleccionados con espaciado horizontal igual",
+ "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "Distribuir nodos seleccionados con espaciado vertical igual",
+ "commandPalette.description.zoom_into_the_canvas": "Acercar en el canvas",
+ "commandPalette.description.zoom_out_of_the_canvas": "Alejar en el canvas",
+ "commandPalette.name.align_bottom": "Alinear Abajo",
+ "commandPalette.name.align_left": "Alinear Izquierda",
+ "commandPalette.name.align_right": "Alinear Derecha",
+ "commandPalette.name.align_top": "Alinear Arriba",
+ "commandPalette.name.analyze_all_joins": "Analizar Todos los Joins",
+ "commandPalette.name.auto_fix_naming": "Auto-Corregir Nombres",
+ "commandPalette.name.auto_layout": "Diseño automático",
+ "commandPalette.name.center_horizontally": "Centrar Horizontalmente",
+ "commandPalette.name.center_vertically": "Centrar Verticalmente",
+ "commandPalette.name.cleanup_orphans": "Limpiar Huérfanos",
+ "commandPalette.name.delete_selected": "Eliminar Seleccionados",
+ "commandPalette.name.deselect_all": "Deseleccionar Todo",
+ "commandPalette.name.discard_and_exit_editor": "Descartar y Salir del Editor",
+ "commandPalette.name.distribute_horizontally": "Distribuir Horizontalmente",
+ "commandPalette.name.distribute_vertically": "Distribuir Verticalmente",
+ "commandPalette.name.edit_selected_cte": "Editar CTE Seleccionado",
+ "commandPalette.name.exit_cte_editor": "Salir del Editor CTE",
+ "commandPalette.name.explain_plan": "Plan de Ejecución",
+ "commandPalette.name.export_csv": "Exportar CSV",
+ "commandPalette.name.export_documentation": "Exportar Documentación",
+ "commandPalette.name.export_excel": "Exportar Excel",
+ "commandPalette.name.export_html": "Exportar HTML",
+ "commandPalette.name.export_json": "Exportar JSON",
+ "commandPalette.name.file_save_load_history": "Historial de Guardado/Carga",
+ "commandPalette.name.fit_to_screen": "Ajustar a Pantalla",
+ "commandPalette.name.flow_version_history": "Historial de Versiones del Flujo",
+ "commandPalette.name.import_sql_to_graph": "Importar SQL a Grafo",
+ "commandPalette.name.keyboard_shortcuts": "Atajos de Teclado",
+ "commandPalette.name.manage_connections": "Administrar Conexiones",
+ "commandPalette.name.new_canvas": "Nuevo Canvas",
+ "commandPalette.name.open_file": "Abrir Archivo",
+ "commandPalette.name.reset_viewport": "Restablecer Vista",
+ "commandPalette.name.run_preview": "Ejecutar Vista Previa",
+ "commandPalette.name.run_query_benchmark": "Ejecutar Benchmark de Consulta",
+ "commandPalette.name.save": "Guardar",
+ "commandPalette.name.save_as": "Guardar Como",
+ "commandPalette.name.save_selection_as_snippet": "Guardar Selección como Snippet",
+ "commandPalette.name.select_all": "Seleccionar Todo",
+ "commandPalette.name.toggle_preview": "Alternar Vista Previa",
+ "commandPalette.name.toggle_snap_to_grid": "Alternar Ajuste a Cuadrícula",
+ "commandPalette.name.zoom_in": "Acercar",
+ "commandPalette.name.zoom_out": "Alejar",
+ "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 por ciento restaurar zoom paneo viewport",
+ "commandPalette.tags.align_bottom_edge_selection_nodes": "alinear borde inferior selección nodos",
+ "commandPalette.tags.align_center_middle_horizontal_nodes": "alinear centro medio horizontal nodos",
+ "commandPalette.tags.align_center_middle_vertical_nodes": "alinear centro medio vertical nodos",
+ "commandPalette.tags.align_left_edge_selection_nodes": "alinear borde izquierdo selección nodos",
+ "commandPalette.tags.align_right_edge_selection_nodes": "alinear borde derecho selección nodos",
+ "commandPalette.tags.align_top_edge_selection_nodes": "alinear borde superior selección nodos",
+ "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout vista restablecer zoom",
+ "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark rendimiento latencia tiempos perfil medir velocidad",
+ "commandPalette.tags.clear_selection": "limpiar selección",
+ "commandPalette.tags.connection_database_server_host_provider_switch": "conexión base datos servidor host proveedor cambiar",
+ "commandPalette.tags.create_insert_search_transform": "crear insertar buscar transformar",
+ "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas salir aplicar volver",
+ "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte vista subcanvas descartar salir forzar",
+ "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursivo editor subgrafo subcanvas aislar",
+ "commandPalette.tags.data_results_table_panel": "datos resultados tabla panel",
+ "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribuir espacio igual horizontal nodos",
+ "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribuir espacio igual vertical nodos",
+ "commandPalette.tags.execute_run_sql_query_results": "ejecutar correr sql consulta resultados",
+ "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan ejecución costo scan índice join rendimiento",
+ "commandPalette.tags.export_csv_file_tabular_output_save": "exportar csv archivo salida tabular guardar",
+ "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "exportar excel xlsx archivo salida tabular hoja cálculo guardar",
+ "commandPalette.tags.export_html_file_output_report_save": "exportar html archivo salida informe guardar",
+ "commandPalette.tags.export_json_file_output_save": "exportar json archivo salida guardar",
+ "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "exportar markdown doc documentación flujo guardar md",
+ "commandPalette.tags.export_persist_copy": "exportar persistir copia",
+ "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "archivo historial guardar cargar backup versiones restaurar local",
+ "commandPalette.tags.forward_history": "adelante historial",
+ "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "ayuda atajos hotkeys teclado referencia",
+ "commandPalette.tags.highlight_mark_all_nodes": "resaltar marcar todos nodos",
+ "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "importar sql pegar convertir grafo ingeniería inversa consulta",
+ "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analizar sugerir detectar foreign key relaciones heurística",
+ "commandPalette.tags.layer_z_order_back_selected_nodes": "capa orden z atrás nodos seleccionados",
+ "commandPalette.tags.layer_z_order_backward_selected_nodes": "capa orden z enviar atrás nodos seleccionados",
+ "commandPalette.tags.layer_z_order_forward_selected_nodes": "capa orden z traer adelante nodos seleccionados",
+ "commandPalette.tags.layer_z_order_front_selected_nodes": "capa orden z al frente nodos seleccionados",
+ "commandPalette.tags.layer_z_order_normalize_compact": "capa orden z normalizar compactar",
+ "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout organizar columnas auto legibilidad",
+ "commandPalette.tags.load_import_vsaq": "cargar importar vsaq",
+ "commandPalette.tags.magnify_enlarge": "aumentar ampliar",
+ "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "huérfano no usado desconectado limpiar eliminar nodos",
+ "commandPalette.tags.persist_write_disk": "persistir escribir disco",
+ "commandPalette.tags.remove_erase_nodes": "remover borrar nodos",
+ "commandPalette.tags.rename_alias_fix_naming_convention": "renombrar alias corregir convención nombres",
+ "commandPalette.tags.reset_clear_blank": "restablecer limpiar en blanco",
+ "commandPalette.tags.revert_back_history": "revertir volver historial",
+ "commandPalette.tags.shrink_reduce": "encoger reducir",
+ "commandPalette.tags.snap_grid_align_precision_position": "snap cuadrícula alinear precisión posición",
+ "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet guardar selección reutilizar plantilla favorito marcador",
+ "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "versión historial checkpoint diff restaurar snapshot comparar deshacer flujo",
+ "sqlEditor.diffPreview.title": "Transactional Diff Preview",
+ "sqlEditor.mutation.confirmExecute": "Confirm Execute",
+ "sqlEditor.tab.closeAnyway": "Close Anyway",
+ "sqlEditor.tab.keepTab": "Keep Tab",
+ "sqlEditor.status.ready": "Ready.",
+ "sqlEditor.telemetry.none": "No execution telemetry yet.",
+ "sqlEditor.telemetry.summary": "Statements: {0} Success: {1} Failed: {2} Total: {3} ms",
+ "sqlEditor.telemetry.errors.none": "No aggregated errors.",
+ "sqlEditor.diff.none": "No transactional diff preview available.",
+ "sqlEditor.mutation.estimate.none": "No mutation estimate available.",
+ "sqlEditor.mutation.estimate.value": "Estimated affected rows: {0}",
+ "sqlEditor.mutation.estimate.unavailable": "Could not estimate affected rows automatically.",
+ "sqlEditor.tab.closePending": "Unsaved changes detected. Confirm tab close.",
+ "sqlEditor.tab.noPendingClose": "No tab close pending.",
+ "sqlEditor.tab.manyWarning": "High tab count: {0} open tabs.",
+ "sqlEditor.mutation.pending.none": "No pending mutation confirmation.",
+ "sqlEditor.mutation.pending.required": "Mutation requires confirmation before execution.",
+ "sqlEditor.message.empty": "Execute a statement to see messages.",
+ "sqlEditor.message.success": "Execution completed successfully.",
+ "sqlEditor.result.summary.empty": "Rows: - Time: -",
+ "sqlEditor.result.summary": "Rows: {0} Time: {1} ms",
+ "sqlEditor.file.save.canceled": "Save canceled.",
+ "sqlEditor.file.save.noPath": "No target path selected.",
+ "sqlEditor.file.save.success": "SQL file saved.",
+ "sqlEditor.file.save.failed": "Save failed.",
+ "sqlEditor.file.open.failed": "Open failed.",
+ "sqlEditor.file.open.notFound": "Selected SQL file was not found.",
+ "sqlEditor.file.open.success": "SQL file opened.",
+ "sqlEditor.status.executing": "Executing SQL...",
+ "sqlEditor.status.executingScript": "Executing SQL script...",
+ "sqlEditor.status.executingStep": "Executing {0}/{1}...",
+ "sqlEditor.status.canceling": "Canceling execution...",
+ "sqlEditor.status.executingConfirmedMutation": "Executing confirmed mutation...",
+ "sqlEditor.status.mutationCanceled": "Mutation execution canceled.",
+ "sqlEditor.detail.statementNotExecuted": "Statement was not executed.",
+ "sqlEditor.status.success": "Execution succeeded.",
+ "sqlEditor.detail.rowsAndTime": "{0} row(s) in {1} ms.",
+ "sqlEditor.status.canceled": "Execution canceled.",
+ "sqlEditor.status.failed": "Execution failed.",
+ "sqlEditor.status.confirmationRequired": "Confirmation required before execution.",
+ "sqlEditor.error.mutationConfirmationRequired": "Mutation confirmation required.",
+ "sqlEditor.result.tabTitle": "Result {0}",
+ "sqlEditor.tab.closeRequiresConfirmation": "Tab close requires confirmation.",
+ "sqlEditor.tab.unsavedDetail": "This tab has unsaved changes.",
+ "sqlEditor.tab.closed": "Tab closed.",
+ "sqlEditor.tab.closeCanceled": "Tab close canceled.",
+ "sqlEditor.tab.closeCanceledDetail": "Unsaved tab kept open.",
+ "sqlEditor.error.noStatementSelected": "No SQL statement selected for execution.",
+ "sqlEditor.error.noConnection": "No active database connection for SQL execution.",
+ "sqlEditor.error.executionCanceled": "SQL execution was canceled.",
+ "sqlEditor.tab.scriptTitle": "Script {0}",
+ "sqlEditor.guard.delete.noWhere.message": "DELETE without WHERE can remove all rows.",
+ "sqlEditor.guard.delete.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
+ "sqlEditor.guard.delete.trivialWhere.message": "DELETE has a trivially true WHERE clause.",
+ "sqlEditor.guard.delete.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
+ "sqlEditor.guard.update.noWhere.message": "UPDATE without WHERE can affect all rows.",
+ "sqlEditor.guard.update.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
+ "sqlEditor.guard.update.trivialWhere.message": "UPDATE has a trivially true WHERE clause.",
+ "sqlEditor.guard.update.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
+ "sqlEditor.guard.insert.noColumnList.message": "INSERT without explicit column list is fragile against schema changes.",
+ "sqlEditor.guard.insert.noColumnList.recommendation": "Prefer INSERT INTO table(col1, col2, ...) VALUES (...).",
+ "sqlEditor.guard.ddl.message": "DDL statement may cause structural changes in the database.",
+ "sqlEditor.guard.ddl.recommendation": "Confirm execution only when schema changes are intended.",
+ "sqlEditor.diff.unavailable.noPreview": "No transactional diff preview available for this statement.",
+ "sqlEditor.diff.unavailable.parseError": "Could not parse mutation target for transactional diff preview.",
+ "sqlEditor.diff.unavailable.connection": "Transactional diff preview unavailable due to connection or query limitations.",
+ "sqlEditor.diff.deleteSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, affected {2}, total rows after {3}.",
+ "sqlEditor.diff.updateSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, candidate rows affected {2}, total rows after {3}.",
+ "sqlEditor.diff.unavailable.unsupportedStatement": "Transactional diff preview currently supports UPDATE and DELETE only.",
+ "sqlEditor.results.title": "Results",
+ "sqlEditor.saveSql.fileType": "SQL Files",
+ "sqlEditor.saveSql.pickerTitle": "Save SQL File",
+ "sqlEditor.export.pickerTitle": "Export SQL Data",
+ "sqlEditor.export.status.noResultTitle": "No execution result available for export.",
+ "sqlEditor.export.status.noResultDetail": "Execute a query first.",
+ "sqlEditor.export.status.successTitle": "Report exported.",
+ "sqlEditor.export.status.failedTitle": "Failed to export report.",
+ "sqlEditor.export.fileType.html": "HTML File",
+ "sqlEditor.export.fileType.json": "JSON File",
+ "sqlEditor.export.fileType.csv": "CSV File",
+ "sqlEditor.export.fileType.xlsx": "Excel Workbook",
+ "sqlEditor.export.defaultFileBase": "report",
+ "sqlEditor.export.defaultTitle": "SQL Report",
+ "sqlEditor.export.error.typeRequired": "A report type must be selected before export.",
+ "sqlEditor.export.type.html.title": "HTML full-feature report",
+ "sqlEditor.export.type.html.description": "Standalone, SQL-first HTML artifact for offline audit.",
+ "sqlEditor.export.type.json.title": "JSON execution contract",
+ "sqlEditor.export.type.json.description": "Machine-readable payload with SQL, metadata and execution result.",
+ "sqlEditor.export.type.csv.title": "CSV data export",
+ "sqlEditor.export.type.csv.description": "Tabular result data only, suitable for spreadsheet tools.",
+ "sqlEditor.export.type.xlsx.title": "Excel workbook export",
+ "sqlEditor.export.type.xlsx.description": "Spreadsheet workbook with query result data only.",
+ "sqlEditor.export.dialog.windowTitle": "Export SQL Data",
+ "sqlEditor.export.dialog.title": "Export SQL Data",
+ "sqlEditor.export.dialog.subtitle": "Choose the artifact format and metadata before exporting.",
+ "sqlEditor.export.dialog.confirm": "Export",
+ "sqlEditor.export.dialog.fileNameWatermark": "report.html",
+ "sqlEditor.export.dialog.titleWatermark": "SQL Report",
+ "sqlEditor.export.dialog.descriptionWatermark": "Additional context for auditors and teammates.",
+ "sqlEditor.export.dialog.section.reportType": "REPORT TYPE",
+ "sqlEditor.export.dialog.section.fileName": "FILE NAME",
+ "sqlEditor.export.dialog.section.reportTitle": "TITLE",
+ "sqlEditor.export.dialog.section.description": "DESCRIPTION",
+ "sqlEditor.export.dialog.section.options": "OPTIONS",
+ "sqlEditor.export.option.includeSchema": "Include output schema",
+ "sqlEditor.export.option.includeNodeDetails": "Include node/connection placeholders in JSON",
+ "sqlEditor.export.option.includeMetadata": "Include optional metadata",
+ "sqlEditor.export.option.useDashForEmpty": "Use '-' for empty fields",
+ "sqlEditor.export.badge.offline": "OFFLINE READY",
+ "sqlEditor.export.badge.structured": "STRUCTURED PAYLOAD",
+ "sqlEditor.export.badge.dataOnly": "DATA ONLY"
+}
diff --git a/src/DBWeaver.UI/Assets/Localization/ja-JP.json b/src/AkkornStudio.UI/Assets/Localization/ja-JP.json
similarity index 98%
rename from src/DBWeaver.UI/Assets/Localization/ja-JP.json
rename to src/AkkornStudio.UI/Assets/Localization/ja-JP.json
index 6bad2726..6e03f23d 100644
--- a/src/DBWeaver.UI/Assets/Localization/ja-JP.json
+++ b/src/AkkornStudio.UI/Assets/Localization/ja-JP.json
@@ -1,1105 +1,1105 @@
-{
- "main.brand": "DBWeaver",
- "main.tab.query1": "Query 1",
- "main.new": "New",
- "main.open": "Open",
- "main.save": "Save",
- "main.history": "History",
- "main.layout": "Layout",
- "main.preview": "Preview",
- "main.undo": "Undo",
- "main.redo": "Redo",
- "main.cleanupOrphans": "Cleanup orphan nodes",
- "main.autoFixAliasNaming": "Auto-fix alias naming",
- "main.autoLayoutCanvas": "Auto layout canvas",
- "main.toggleDataPreview": "Toggle data preview",
- "main.language": "Language",
- "main.restore.prompt": "Previous session found — restore the last canvas?",
- "main.restore.button": "Restore session",
- "main.cteEditor.editingPrefix": "Editing CTE: ",
- "main.cteEditor.backToCanvas": "Back to Canvas",
- "main.cteEditor.exitA11y": "Exit CTE editor",
- "main.viewEditor.editingPrefix": "DDL > View: ",
- "main.viewEditor.backToCanvas": "Back to DDL",
- "main.viewEditor.exitA11y": "Exit view editor",
- "connection.title": "Connection Manager",
- "connection.subtitle": "作業フローを中断せずに接続の設定・テスト・有効化を行います",
- "connection.none": "No connection",
- "connection.active": "ACTIVE",
- "connection.health.online": "Online",
- "connection.health.degraded": "Degraded",
- "connection.health.offline": "Offline",
- "connection.tooltip.none": "No active connection — click to manage",
- "connection.ping": "Ping",
- "connection.saved": "SAVED CONNECTIONS",
- "connection.new": "New Connection",
- "connection.selectOrCreate": "Select a connection or create a new one",
- "connection.name": "Connection Name",
- "connection.provider": "Provider",
- "connection.host": "Host",
- "connection.port": "Port",
- "connection.database": "Database",
- "connection.sqlitePath": "SQLite Path",
- "connection.sqliteBrowse": "Browse",
- "connection.sqliteCreate": "Create",
- "connection.username": "Username",
- "connection.password": "Password",
- "connection.timeout": "Timeout (seconds)",
- "connection.test": "Test",
- "connection.save": "Save",
- "connection.connect": "Connect",
- "connection.action.testConnection": "Test connection",
- "connection.action.saveConnection": "Save connection",
- "connection.action.connectConnection": "Connect connection",
- "connection.status.connecting": "接続中...",
- "connection.status.connected": "接続済み",
- "connection.status.testing": "テスト中...",
- "connection.status.failedPrefix": "接続に失敗しました",
- "connection.status.metadataUnavailable": "接続に失敗しました: メタデータが利用できません。",
- "connection.status.highLatency": "高遅延",
- "connection.watermark.name": "本番DB",
- "connection.watermark.host": "localhost",
- "connection.watermark.port": "5432",
- "connection.watermark.database": "database_name",
- "connection.watermark.username": "user",
- "connection.watermark.password": "••••••••",
- "connection.watermark.timeout": "30",
- "main.connectingDb": "Connecting to database...",
- "main.emptyHint": "Press ⇧A to add your first node, or drag a table from the sidebar",
- "status.nodesSeparator": " nodes · ",
- "status.connectionsSuffix": " connections",
- "status.undo": "Undo: ",
- "status.shortcuts": "⇧A Nodes · F3 Preview · Ctrl+Z Undo · Del Remove · Alt+Drag Pan",
- "connection.disconnect": "Disconnect",
- "connection.action.disconnectConnection": "Disconnect connection",
- "connectionTab.active": "ACTIVE CONNECTION",
- "connectionTab.none": "No active connection",
- "connectionTab.saved": "SAVED CONNECTIONS",
- "connectionTab.new": "+ New Connection",
- "schema.database": "DATABASE",
- "schema.search": "Search tables, columns...",
- "schema.loading": "Searching tables, columns...",
- "schema.noConnection": "No Connection",
- "schema.noConnectionHint": "Connect to a database to see tables, columns, and relationships",
- "schema.emptyNoTables": "No tables found",
- "fileHistory.title": "Save/Load Version History",
- "fileHistory.reload": "Reload",
- "fileHistory.restoreSelected": "Restore selected",
- "fileHistory.empty": "No local versions yet",
- "fileHistory.emptyHint": "Save this file to generate version history.",
- "preview.title": "Data Preview",
- "preview.subtitle": "Review data and diagnostics before continuing",
- "preview.run": "Run",
- "preview.cancel": "Cancel",
- "preview.tab.preview": "Preview",
- "preview.tab.sql": "SQL",
- "preview.close": "Close preview",
- "preview.running": "Running preview query… ",
- "preview.clickCancel": "Click Cancel to stop",
- "preview.cancelled": "Query cancelled",
- "preview.runAgain": "Press Run to execute again",
- "preview.failed": "Preview execution failed",
- "preview.technical": "TECHNICAL DETAILS",
- "preview.noData": "No data yet",
- "preview.f3Hint": "Press F3 or Space to run the current query",
- "sqlImporter.title": "Import SQL to Graph",
- "sqlImporter.subtitle": "Paste a SELECT statement — nodes are created automatically",
- "sqlImporter.sqlStatement": "SQL STATEMENT",
- "sqlImporter.supported": "Supported: ",
- "sqlImporter.import": "Import",
- "sqlImporter.report": "CONVERSION REPORT",
- "sqlEditor.mutation.dialogTitle": "変更の確認",
- "sqlEditor.mutation.dialogSubtitle": "実行を確定する前に影響を確認してください",
- "search.empty": "No nodes found",
- "search.emptyHint": "Try searching for UPPER, JSON, CAST, AND…",
- "search.shortcut": "⇧A",
- "search.spawn": "Spawn",
- "commandPalette.empty": "検索に一致するコマンドがありません",
- "commandPalette.search": "コマンド検索",
- "commandPalette.shortcut": "CTRL+SHIFT+P",
- "commandPalette.execute": "実行",
- "context.editCte": "Edit Selected CTE",
- "context.editViewSubcanvas": "Edit View Subcanvas",
- "explain.title": "Explain Plan",
- "explain.sql": "SQL",
- "explain.option.analyze": "解析",
- "explain.option.buffers": "バッファ",
- "explain.badge.simulated": "シミュレーション",
- "explain.timing.planning": "計画:",
- "explain.timing.execution": "実行:",
- "explain.section.snapshotComparison": "スナップショット比較",
- "explain.section.indexRecommendations": "インデックスの推奨",
- "explain.section.history": "履歴",
- "explain.detail.estimated": "推定",
- "explain.detail.actual": "実測",
- "explain.detail.error": "誤差",
- "explain.detail.time": "時間",
- "explain.detail.loops": "ループ",
- "explain.rerun": "Re-run",
- "explain.alertSuffix": " expensive operation(s) detected — consider adding indexes",
- "explain.running": "Running EXPLAIN…",
- "explain.failed": "⚠ EXPLAIN failed",
- "explain.noPlan": "No plan yet",
- "explain.rerunHint": "Press Re-run to execute EXPLAIN",
- "explain.header.operation": "操作",
- "explain.header.cost": "コスト",
- "explain.header.rows": "行数",
- "explain.header.alert": "警告",
- "explain.mode.list": "リスト",
- "explain.mode.tree": "ツリー",
- "explain.action.snapshot": "スナップショットを保存",
- "explain.action.copyJson": "JSONをコピー",
- "explain.action.copyText": "テキストをコピー",
- "explain.action.saveJson": ".json を保存",
- "explain.action.openDalibo": "Daliboで開く",
- "explain.legend.seqscan": "SEQ SCAN — full table read, no index",
- "explain.legend.sort": "SORT — in-memory sort",
- "explain.legend.hash": "HASH — hash join",
- "explain.escClose": "Esc to close",
- "flowVersion.title": "Flow Version History",
- "flowVersion.subtitle": "Create checkpoints, compare versions and restore",
- "flowVersion.watermark": "Checkpoint label (optional)…",
- "flowVersion.saveCheckpoint": "Save Checkpoint",
- "flowVersion.compareMode": "Compare Mode",
- "flowVersion.selectBase": "Select BASE version (from):",
- "flowVersion.clickAny": "Then click any version in the list below to compare.",
- "flowVersion.noCheckpoints": "No checkpoints yet",
- "flowVersion.noCheckpointsHint": "Save a checkpoint above to begin tracking versions.",
- "flowVersion.restore": "Restore",
- "flowVersion.diffResults": "Diff Results",
- "benchmark.title": "Query Benchmark",
- "benchmark.subtitle": "Measures avg / median / p95 latency over N iterations",
- "benchmark.sql": "SQL being benchmarked",
- "benchmark.runLabel": "Run label",
- "benchmark.runLabelWatermark": "Run 1",
- "benchmark.iterations": "Iterations (1–100)",
- "benchmark.warmup": "Warm-up passes (0–10)",
- "benchmark.interval": "Interval between runs (ms)",
- "benchmark.run": "Run Benchmark",
- "benchmark.cancel": "Cancel",
- "benchmark.clearHistory": "Clear History",
- "benchmark.latest": "LATEST RESULT",
- "benchmark.avg": "AVG",
- "benchmark.median": "MEDIAN",
- "benchmark.min": "MIN",
- "benchmark.max": "MAX",
- "benchmark.iterationsAt": " iterations · run at ",
- "benchmark.history": "HISTORY",
- "benchmark.header.label": "ラベル",
- "benchmark.header.avg": "平均",
- "benchmark.header.median": "中央値",
- "benchmark.header.min": "最小",
- "benchmark.header.max": "最大",
- "benchmark.itersSuffix": " iters",
- "diagnostics.title": "App Diagnostics",
- "diagnostics.run": "Run",
- "diagnostics.running": "Running checks…",
- "diagnostics.ok": "OK",
- "diagnostics.warning": "Warning",
- "diagnostics.error": "Error",
- "diagnostics.tooltip.rerun": "Re-run all checks",
- "diagnostics.tooltip.copy": "Copy diagnostic report to clipboard",
- "diagnostics.tooltip.close": "Close (Esc)",
- "autoJoin.title": "Auto-Join Suggestions",
- "autoJoin.titleForTable": "Auto-Join suggestions for {0}",
- "autoJoin.acceptAll": "Accept All",
- "autoJoin.accept": "Accept",
- "autoJoin.skip": "Skip",
- "autoJoin.allHandled": "All suggestions handled",
- "autoJoin.joinKeyword": "JOIN",
- "autoJoin.confidence.fkConstraint": "FK Constraint",
- "autoJoin.confidence.fkReverse": "FK (Reverse)",
- "autoJoin.confidence.namingMatch": "Naming Match",
- "autoJoin.confidence.weakMatch": "Weak Match",
- "autoJoin.runSelected": "Auto-Join Selected",
- "autoJoin.noSimilarityTitle": "No automatic join found",
- "autoJoin.noSimilarityDetails": "Choose the columns manually to create a simple join.",
- "autoJoin.appliedTitle": "Auto-join applied",
- "autoJoin.manual.title": "Create Manual Join",
- "autoJoin.manual.subtitle": "No reliable similarity was found. Select one column from each table.",
- "autoJoin.manual.leftColumn": "Left column",
- "autoJoin.manual.rightColumn": "Right column",
- "autoJoin.manual.joinType": "Join type",
- "autoJoin.manual.operator": "Operator",
- "autoJoin.manual.confirm": "Create join",
- "autoJoin.manual.noCompatible": "No compatible columns for the selected left pin type.",
- "autoJoin.manualJoinCreatedTitle": "Manual join created",
- "autoJoin.manualJoinFailedTitle": "Manual join could not be created",
- "autoJoin.manualJoinFailedDetails": "Check selected columns and existing joins, then try again.",
- "autoJoin.multipleCandidatesTitle": "Multiple join candidates found",
- "autoJoin.multipleCandidatesDetails": "{0} possible combinations were found. Confirm which columns should be used.",
- "autoJoin.suggestionsFoundTitle": "Auto-join suggestions available",
- "autoJoin.suggestionsFoundDetails": "{0} suggestion(s) found. Select two tables and run Auto-Join Selected.",
- "property.outputAlias": "OUTPUT ALIAS",
- "property.sourceAlias": "SOURCE ALIAS",
- "property.aliasWatermark": "e.g. MyColumn (optional)",
- "property.parameters": "PARAMETERS",
- "property.enabled": "Enabled",
- "property.datetimeWatermark": "YYYY-MM-DDTHH:mm:ss or leave empty",
- "property.dateWatermark": "YYYY-MM-DD or leave empty",
- "property.apply": "Apply",
- "property.inputPins": "INPUT PINS",
- "property.outputPins": "OUTPUT PINS",
- "property.sqlTrace": "SQL TRACE",
- "property.live": "live",
- "node.numericValue": "Numeric Value",
- "node.stringValue": "String Value",
- "node.enterText": "Enter text",
- "node.datetimeValue": "DateTime Value",
- "node.valueLabel": "Value:",
- "node.noInputs": "No inputs",
- "node.loadingSample": "Loading sample…",
- "node.previewFailed": "⚠ Preview failed",
- "node.sampleRowsHint": "5 sample rows · demo data",
- "sidebar.tab.nodes": "ノード",
- "sidebar.tab.connection": "接続",
- "sidebar.tab.schema": "スキーマ",
- "sidebar.tab.diagnostics": "診断",
- "sidebar.addNode": "+ Add Node (⇧A)",
- "sidebar.previewF3": "Preview (F3)",
- "nodesList.search": "Search nodes...",
- "search.watermark": "Search nodes… (Esc to close)",
- "search.snippets": "★ SNIPPETS",
- "commandPalette.watermark": "コマンドを実行…(Esc で閉じる)",
- "tooltip.newCanvas": "New canvas (Ctrl+N)",
- "tooltip.openCanvas": "Open canvas (Ctrl+O)",
- "tooltip.saveCanvas": "Save canvas (Ctrl+S)",
- "tooltip.fileHistory": "Local save/load history (Ctrl+Alt+H)",
- "tooltip.zoomOut": "Zoom out (Ctrl+-)",
- "tooltip.zoomIn": "Zoom in (Ctrl++)",
- "tooltip.fitToScreen": "Fit to screen (Ctrl+0)",
- "tooltip.autoLayout": "Auto Layout — arrange nodes into logical columns (Ctrl+L, Ctrl+Z to undo)",
- "tooltip.snapToGrid": "Toggle snap to grid (Ctrl+G)",
- "tooltip.dataPreview": "Data preview (F3)",
- "tooltip.toggleLanguage": "Toggle language (pt-BR / en-US)",
- "tooltip.appDiagnostics": "App Diagnostics (self-check)",
- "tooltip.keyboardShortcuts": "Keyboard shortcuts (F1)",
- "tooltip.cancelRunningQuery": "Cancel the running query",
- "tooltip.closeEsc": "Close (Esc)",
- "tooltip.recheckConnectionHealth": "Re-check connection health",
- "tooltip.deleteConnection": "Delete connection",
- "tooltip.testConnection": "Test connection",
- "tooltip.saveConnection": "Save connection",
- "tooltip.activateConnection": "Activate this connection",
- "tooltip.toggleDataSamplePreview": "Toggle data sample preview",
- "tooltip.liveSqlMutatingBlocked": "This SQL contains a data-mutating command and cannot be run in Safe Preview Mode",
- "tooltip.copySql": "Copy SQL to clipboard",
- "tooltip.formatSql": "Format SQL",
- "tooltip.openBenchmark": "Open Query Benchmark (measure avg / median / p95 latency)",
- "tooltip.openExplainPlan": "Open Explain Plan inspector — visualise the query execution plan",
- "tooltip.switchToQueryMode": "Switch to Query canvas",
- "tooltip.switchToDdlMode": "Switch to DDL canvas",
- "tooltip.autoJoinSelected": "Try auto-join between the two selected tables",
- "tooltip.pins.inputs": "Inputs",
- "tooltip.pins.outputs": "Outputs",
- "tooltip.pins.none": "None",
- "tooltip.tableColumns": "Columns",
- "tooltip.tableColumns.none": "No detailed columns",
- "window.minimize": "Minimize window",
- "window.maximizeRestore": "Maximize/restore window",
- "window.close": "Close window",
- "menu.newDiagram": "New diagram",
- "menu.openFile": "Open file",
- "menu.save": "Save",
- "menu.fileHistory": "File history",
- "menu.shortcuts": "Keyboard shortcuts",
- "menu.settings": "Settings",
- "menu.importDdlSchema": "Import DDL schema",
- "menu.viewDdlSql": "View DDL SQL",
- "menu.executeDdl": "Execute DDL",
- "menu.backToStart": "Back to start",
- "toast.ddlExecuteFailed": "Failed to execute DDL.",
- "toast.ddlOpenFailed": "Failed to open DDL SQL.",
- "toast.ddlImportFailed": "Failed to import schema into DDL.",
- "toast.ddlConnectToImportSchema": "Connect to a database to import schema into the DDL canvas.",
- "toast.ddlNoTablesFound": "No tables found to import in DDL mode.",
- "toast.ddlSchemaImported": "Schema imported into the DDL canvas.",
- "toast.ddlImportSummary": "{0} table(s), {1} column(s), {2} FK(s), {3} unique index(es).",
- "toast.ddlConnectToImportTable": "Connect to a database to import tables into the DDL canvas.",
- "toast.ddlTableAlreadyExists": "Table '{0}' already exists in the DDL canvas.",
- "toast.ddlTableImported": "Table imported into the DDL canvas.",
- "toast.ddlTableImportSummary": "Nodes: +{0}, connections: +{1}, FKs: +{2}.",
- "toast.ddlNoActiveConnection": "No active connection to execute DDL.",
- "toast.ddlExecutedSuccess": "DDL executed successfully.",
- "toast.ddlExecutedWithIssues": "DDL executed with issues.",
- "toast.switchToDdl": "Switch to DDL mode to generate SQL.",
- "toast.ddlInvalid": "Invalid DDL. Fix errors before continuing.",
- "toast.ddlNoStatements": "No DDL statements were generated in the canvas.",
- "toast.previewOpenFailed": "Failed to open preview.",
- "tab.switchFailed": "Failed to switch tab: {0}",
- "settings.status.darkApplied": "Dark theme applied.",
- "settings.status.lightApplied": "Light theme applied.",
- "settings.status.snapUpdated": "Snap updated: {0}.",
- "settings.status.languageToggled": "Language toggled.",
- "settings.status.languageSelected": "Language selected: {0}.",
- "settings.status.themeEditorReady": "Theme editor ready. Apply to save and use this theme.",
- "settings.section.appearance.title": "Themes",
- "settings.section.languageRegion.title": "言語と地域",
- "settings.section.dateTime.title": "日付と時刻",
- "settings.section.keyboard.title": "キーボードショートカット",
- "settings.section.privacy.title": "プライバシー",
- "settings.section.notification.title": "通知",
- "settings.section.accessibility.title": "アクセシビリティ",
- "settings.section.default.title": "設定",
- "settings.section.appearance.subtitle": "スタイルを選択するか、テーマをカスタマイズします",
- "settings.section.languageRegion.subtitle": "言語と地域フォーマットを管理します",
- "settings.section.keyboard.subtitle": "コマンドパレットとキャンバス実行で使うキーボードショートカットをカスタマイズします。",
- "settings.section.wip.subtitle": "作業中です。",
- "settings.section.default.subtitle": "アプリケーション設定",
- "settings.general": "General",
- "settings.nav.appearance": "Appearance",
- "settings.theme.light": "ライトモード",
- "settings.theme.dark": "ダークモード",
- "settings.theme.system": "システム設定",
- "settings.gridSnap.title": "Grid Snap",
- "settings.gridSnap.subtitle": "Controls node snapping on the canvas.",
- "settings.language.subtitle": "アプリの言語を選択してください。",
- "settings.language.toggle": "言語を切り替える",
- "settings.language.option.ptBR": "ポルトガル語(ブラジル)",
- "settings.language.option.enUS": "英語(米国)",
- "settings.language.option.esES": "スペイン語(スペイン)",
- "settings.language.option.ruRU": "ロシア語",
- "settings.language.option.jaJP": "日本語",
- "settings.language.option.zhTW": "繁体字中国語",
- "settings.themeJson.title": "テーマ JSON",
- "settings.themeJson.subtitle": "テーマ JSON を貼り付けて、即時に適用・保存します。",
- "settings.themeJson.apply": "JSON を適用",
- "settings.themeJson.restoreDefault": "既定テーマに戻す",
- "mode.query": "Query",
- "mode.ddl": "DDL",
- "sidebar.left.close": "Close left sidebar",
- "sidebar.left.open": "Reopen left sidebar",
- "sidebar.right.close": "Close right sidebar",
- "sidebar.right.open": "Reopen right sidebar",
- "connection.completedTitle": "Connection completed",
- "connection.clearCanvasPrompt": "Do you want to clear the current canvas to start with the new connection?",
- "connection.close": "Close connection manager",
- "connection.refreshHealth": "Refresh connection health",
- "common.details": "Details",
- "common.cancel": "Cancel",
- "common.keep": "Keep",
- "common.clear": "Clear",
- "zoom.out": "Zoom out",
- "zoom.in": "Zoom in",
- "zoom.fit": "Fit zoom to screen",
- "zoom.level": "Zoom level",
- "settings.theme.mode": "テーマモード",
- "diagnostics.category.canvas": "Canvas Integrity",
- "diagnostics.category.output": "Output & Execution",
- "diagnostics.category.session": "Session & Safety",
- "diagnostics.category.notice": "Runtime Notices",
- "diagnostics.summary.ok": "All systems OK",
- "diagnostics.summary.warningCount": "{0} warning(s) detected",
- "diagnostics.summary.errorCount": "{0} error(s) detected",
- "diagnostics.canvasMigration": "Canvas Migration",
- "diagnostics.recommendation.resaveFile": "Re-save the file to update it to the latest schema version.",
- "diagnostics.canvasState.name": "Canvas State",
- "diagnostics.canvasState.recommendation": "Add at least one {0} and one {1}",
- "diagnostics.canvasState.empty": "Canvas is empty - no nodes present",
- "diagnostics.canvasState.counts": "{0} node(s), {1} connection(s)",
- "diagnostics.validation.name": "Validation Errors",
- "diagnostics.validation.recommendation": "Fix highlighted nodes before running output preview",
- "diagnostics.validation.errorWithWarnings": "{0} error(s) and {1} warning(s) in the graph",
- "diagnostics.validation.warningOnly": "{0} warning(s) in the graph",
- "diagnostics.validation.none": "No validation issues",
- "diagnostics.orphan.name": "Orphan Nodes",
- "diagnostics.orphan.recommendation": "Use the orphan cleanup action to remove unused nodes",
- "diagnostics.orphan.count": "{0} node(s) not connected to any output",
- "diagnostics.orphan.none": "No orphan nodes detected",
- "diagnostics.naming.name": "Naming Conventions",
- "diagnostics.naming.recommendation": "Use auto-fix alias naming when conformance is below 100%",
- "diagnostics.naming.conformance": "Naming conformance: {0}%",
- "diagnostics.naming.ok": "All aliases follow naming conventions (100%)",
- "diagnostics.queryCompilation.name": "Live SQL Compilation",
- "diagnostics.queryCompilation.recommendation": "Review SQL diagnostics in output when errors/warnings are reported.",
- "diagnostics.queryCompilation.errorFallback": "Live SQL compilation reported errors.",
- "diagnostics.queryCompilation.warningCounts": "{0} diagnostic item(s), {1} guardrail warning(s).",
- "diagnostics.queryCompilation.ok": "Live SQL compiled without diagnostics.",
- "diagnostics.previewSafety.name": "Preview Safety",
- "diagnostics.previewSafety.recommendation": "Preview executes read-only statements only.",
- "diagnostics.previewSafety.blocked": "Current SQL is mutating and blocked by Safe Preview mode.",
- "diagnostics.previewSafety.ok": "Preview safety checks passed.",
- "diagnostics.previewExecution.name": "Preview Execution",
- "diagnostics.previewExecution.recommendation": "Run preview and inspect diagnostics for execution/runtime errors.",
- "diagnostics.previewExecution.failed": "Preview execution failed.",
- "diagnostics.previewExecution.cancelled": "Preview execution was cancelled.",
- "diagnostics.previewExecution.done": "{0} row(s) in {1}ms.",
- "diagnostics.previewExecution.none": "No preview execution issues detected.",
- "diagnostics.ddlCompilation.name": "DDL Compilation",
- "diagnostics.ddlCompilation.recommendation": "Fix DDL compile diagnostics before execution.",
- "diagnostics.ddlCompilation.failed": "DDL compilation failed.",
- "diagnostics.ddlCompilation.warningCount": "{0} warning(s) reported by DDL compiler.",
- "diagnostics.ddlCompilation.ok": "DDL compilation succeeded.",
- "diagnostics.ddlOutput.name": "DDL Output",
- "diagnostics.ddlOutput.recommendation": "Add/complete DDL nodes until at least one statement is generated.",
- "diagnostics.ddlOutput.none": "No DDL statements generated yet.",
- "diagnostics.ddlOutput.lines": "{0} line(s) of DDL generated.",
- "diagnostics.undo.name": "Undo History",
- "diagnostics.undo.recommendation": "History is in-memory only; save your canvas regularly.",
- "diagnostics.undo.saved": "Canvas is saved (no unsaved changes).",
- "diagnostics.undo.unsavedDeep": "Unsaved changes with {0} undo steps.",
- "diagnostics.undo.unsaved": "Unsaved changes - {0} undo step(s) available.",
- "diagnostics.report.title": "DBWeaver - Diagnostic Report",
- "diagnostics.report.generated": "Generated",
- "diagnostics.report.overall": "Overall",
- "diagnostics.report.details": "Details",
- "diagnostics.report.recommendation": "Recommendation",
- "diagnostics.report.lastCheck": "Last Check",
- "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
- "node.datetimeFormat": "YYYY-MM-DDTHH:mm:ss",
- "preview.providerLabel": "Provider",
- "preview.ddlDiagnosticsHint": "Error/warning details are available in Diagnostics.",
- "preview.schemaAnalysis.run": "Run Analysis",
- "preview.schemaAnalysis.cancel": "Cancel",
- "preview.schemaAnalysis.issues": "Issues",
- "preview.schemaAnalysis.clearFilters": "Clear Filters",
- "preview.schemaAnalysis.clearBlacklist": "Clear Blacklist",
- "preview.schemaAnalysis.severity": "Severity",
- "preview.schemaAnalysis.severity.info": "Info",
- "preview.schemaAnalysis.severity.warning": "Warning",
- "preview.schemaAnalysis.severity.critical": "Critical",
- "preview.schemaAnalysis.rule": "Rule",
- "preview.schemaAnalysis.rule.fkCatalogInconsistent": "FK catalog inconsistent",
- "preview.schemaAnalysis.rule.missingFk": "Missing FK",
- "preview.schemaAnalysis.rule.namingConventionViolation": "Naming convention violation",
- "preview.schemaAnalysis.rule.lowSemanticName": "Low semantic name",
- "preview.schemaAnalysis.rule.missingRequiredComment": "Missing required comment",
- "preview.schemaAnalysis.rule.nf1HintMultiValued": "1NF hint: multi-valued",
- "preview.schemaAnalysis.rule.nf2HintPartialDependency": "2NF hint: partial dependency",
- "preview.schemaAnalysis.rule.nf3HintTransitiveDependency": "3NF hint: transitive dependency",
- "preview.schemaAnalysis.minConfidence": "Min Confidence",
- "preview.schemaAnalysis.tableFilter": "Table Filter",
- "preview.schemaAnalysis.tableFilterWatermark": "schema.table",
- "preview.schemaAnalysis.ignore": "Execution Filters",
- "preview.schemaAnalysis.ignoreViews": "Ignore views and materialized views",
- "preview.schemaAnalysis.blacklist": "Table blacklist",
- "preview.schemaAnalysis.blacklistAdd": "Add",
- "preview.schemaAnalysis.blacklistRemove": "Remove selected",
- "preview.schemaAnalysis.ignoreTable.placeholder": "schema.table",
- "preview.schemaAnalysis.details": "Details",
- "preview.schemaAnalysis.evidence": "Evidence",
- "preview.schemaAnalysis.suggestions": "Suggestions",
- "preview.schemaAnalysis.ruleDiagnostics": "Rule Diagnostics",
- "preview.schemaAnalysis.sqlCandidates": "SQL Candidates",
- "preview.schemaAnalysis.copySql": "Copy SQL",
- "preview.schemaAnalysis.applyToCanvas": "Apply to Canvas",
- "preview.schemaAnalysis.summary.issues": "Issues:",
- "preview.schemaAnalysis.summary.rawPrefix": "(raw:",
- "preview.schemaAnalysis.summary.critical": "| Critical:",
- "preview.schemaAnalysis.summary.warning": "| Warning:",
- "preview.schemaAnalysis.summary.info": "| Info:",
- "preview.schemaAnalysis.state.metadataUnavailable": "Metadata unavailable for structural analysis.",
- "preview.schemaAnalysis.state.cancelled": "Analysis cancelled by the user.",
- "preview.schemaAnalysis.state.partialTimeout": "Analysis finished partially due to timeout.",
- "preview.schemaAnalysis.state.failed": "Structural analysis failed.",
- "preview.schemaAnalysis.state.empty": "No inferable structural issue was detected.",
- "preview.schemaAnalysis.state.noFilterMatch": "No issue matches the selected filters.",
- "preview.schemaAnalysis.state.noIssueSelected": "No issue selected.",
- "preview.schemaAnalysis.state.noSqlCandidate": "No SQL candidate available.",
- "preview.schemaAnalysis.actionBlockedTooltip": "Action unavailable for the current risk level or capability.",
- "common.navigate": "Navigate",
- "common.close": "Close",
- "common.esc": "Esc",
- "common.ms": "ms",
- "common.zero": "0",
- "diagnostics.tip": "Tip: check Diagnostics whenever preview/output reports warnings or errors.",
- "nodesList.empty": "No nodes found",
- "nodesList.emptyHint": "Adjust the search term to explore available types",
- "schema.emptyFiltered": "No objects found for the current filter",
- "start.lastSnapshot": "Last snapshot",
- "app.brandBadge": "VS",
- "property.tab.properties": "Properties",
- "property.tab.projectSettings": "Project Settings",
- "property.nodeType": "NODE TYPE",
- "property.selectNodeHint": "Select a node to edit its properties.",
- "property.namingConventions": "Naming Conventions",
- "property.aliasConvention": "Alias convention",
- "property.enforceAliasNaming": "Enforce alias naming",
- "property.warnReservedSql": "Warn on reserved SQL keywords",
- "property.maxAliasLength": "Max alias length",
- "property.maxAliasLengthDefault": "64",
- "property.namingSettingsHint": "These settings are project-scoped and are used by naming and validation helpers.",
- "start.tips": "Tips",
- "start.tips.quick": "Quick tips",
- "start.tips.item1": "1. Click New Diagram to start from scratch.",
- "start.tips.item2": "2. Use templates to speed up prototyping.",
- "start.tips.item3": "3. Open saved connections to load real tables.",
- "start.tips.shortcut": "Shortcut: CTRL+SHIFT+P opens the command palette.",
- "start.workspace": "WORKSPACE",
- "start.resumeTitle": "Continue where you left off",
- "start.resumeSubtitle": "Quickly resume a recent project or start a new diagram.",
- "start.chip.quickFlow": "Quick flow",
- "start.chip.templates": "Templates",
- "start.chip.connections": "Connections",
- "start.savedConnectionsTitle": "Saved Connections",
- "start.savedConnectionsSubtitle": "Connect quickly to a database to load schema and tables.",
- "start.noConnectionsTitle": "No connections configured yet",
- "start.noConnectionsSubtitle": "Create a connection to explore real tables in the editor.",
- "start.newConnection": "+ New Connection",
- "start.recentProjectsTitle": "Recent Projects",
- "start.searchRecent": "Search recent project...",
- "start.quickActions": "Quick actions",
- "start.quickActionsSubtitle": "Open an existing file or start a new diagram.",
- "start.noRecentTitle": "No recent projects yet",
- "start.noRecentSubtitle": "Use the quick actions card above to get started.",
- "start.exploreTemplates": "Explore templates",
- "start.templatesFavoritesHint": "Favorites on top",
- "start.favoriteTemplate": "Favorite template",
- "node.columnSetPreview": "ColumnSet preview",
- "node.view": "VIEW",
- "node.tableDefinition": "Table Definition",
- "node.join": "JOIN",
- "node.window.addPartition": "Add PARTITION BY slot",
- "node.window.removePartition": "Remove PARTITION BY slot",
- "node.window.addOrder": "Add ORDER BY slot",
- "node.window.removeOrder": "Remove ORDER BY slot",
- "sql.keyword.select": "SELECT",
- "sql.keyword.from": "FROM",
- "sql.keyword.join": "JOIN",
- "sql.keyword.where": "WHERE",
- "sql.keyword.limit": "LIMIT",
- "sqlImporter.close": "Close SQL importer",
- "sqlImporter.report.imported": "Imported",
- "sqlImporter.report.partial": "Partial",
- "sqlImporter.report.skipped": "Skipped",
- "benchmark.close": "Close benchmark",
- "benchmark.p95": "P95",
- "benchmark.n": "N",
- "liveSql.safePreview": "SAFE PREVIEW MODE",
- "liveSql.title": "LIVE SQL",
- "liveSql.blocked": "BLOCKED",
- "liveSql.copy": "Copy",
- "liveSql.format": "Format",
- "liveSql.benchmark": "Benchmark",
- "liveSql.explain": "Explain",
- "liveSql.actionsHint": "Performance tools",
- "ddl.dialog.title": "Execute DDL",
- "ddl.dialog.execute": "Execute",
- "ddl.dialog.cancel": "Cancel",
- "ddl.dialog.close": "Close",
- "ddl.dialog.stopOnError": "Stop on first failure",
- "ddl.dialog.confirmDestructive": "I confirm execution of destructive statements (DROP TABLE)",
- "ddl.dialog.reviewBeforeRun": "Review the DDL script before confirming.",
- "ddl.dialog.confirmQuestion": "Confirm DDL execution on the connected database?",
- "ddl.dialog.irreversibleWarning": "This action can change the schema irreversibly.",
- "ddl.dialog.mustConfirmDestructive": "Confirm destructive execution to continue.",
- "ddl.dialog.executing": "Executing...",
- "ddl.execute.result.summary": "Statements: {0} | Success: {1} | Failures: {2} | Time: {3:0}ms",
- "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
- "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
- "ddl.execute.result.failed": "Failed to execute DDL.",
- "ddl.execute.result.cancelled": "Execution cancelled by the user.",
- "ddl.execute.result.cancelledDetails": "DDL execution was interrupted before completion.",
- "context.deleteSingle": "Delete {0}",
- "context.deleteMultiple": "Delete {0} nodes",
- "context.bringForward": "Bring Forward (Ctrl+PgUp)",
- "context.sendBackward": "Send Backward (Ctrl+PgDown)",
- "context.bringToFront": "Bring to Front (Ctrl+Shift+PgUp)",
- "context.sendToBack": "Send to Back (Ctrl+Shift+PgDown)",
- "context.normalizeLayers": "Normalize Layers",
- "context.deleteWire": "Delete wire",
- "context.addNode": "Add Node (Shift+A)",
- "context.undoWithDescription": "Undo {0}",
- "context.redo": "Redo",
- "shortcuts.windowTitle": "Keyboard Shortcuts",
- "shortcuts.headerTitle": "DBWeaver - Shortcuts",
- "shortcuts.headerHint": "Tip: use CTRL+SHIFT+P to open the Command Palette and search commands.",
- "shortcuts.filterWatermark": "Filter shortcuts by key or action...",
- "shortcuts.resultCount": "{0} shortcuts",
- "shortcuts.resultFilter": "{0} result(s) for \"{1}\"",
- "shortcuts.noneFound": "No shortcuts found.",
- "shortcuts.section.fileGeneral": "ファイルと一般",
- "shortcuts.section.editing": "編集",
- "shortcuts.section.canvasNavigation": "キャンバスとナビゲーション",
- "shortcuts.section.zoomPanPrecision": "ズーム、パン、精密操作",
- "shortcuts.section.previewInspection": "プレビューと検査",
- "shortcuts.key.deleteOrBackspace": "Del または Backspace",
- "shortcuts.key.middleDrag": "中ボタン + ドラッグ",
- "shortcuts.key.rightDrag": "右ボタン + ドラッグ",
- "shortcuts.key.spaceDrag": "Space + ドラッグ",
- "shortcuts.key.altLeftDrag": "Alt + 左ドラッグ",
- "shortcuts.key.arrows": "矢印キー",
- "shortcuts.key.shiftArrows": "Shift + 矢印キー",
- "shortcuts.action.openShortcutScreen": "このショートカット画面を開く",
- "shortcuts.action.newCanvas": "新しいキャンバス",
- "shortcuts.action.openFile": "ファイルを開く",
- "shortcuts.action.save": "保存",
- "shortcuts.action.saveAs": "名前を付けて保存",
- "shortcuts.action.commandPalette": "コマンドパレット",
- "shortcuts.action.undo": "元に戻す",
- "shortcuts.action.redo": "やり直し",
- "shortcuts.action.selectAll": "すべて選択",
- "shortcuts.action.deleteSelection": "選択を削除",
- "shortcuts.action.closeOverlayCancel": "オーバーレイを閉じる / 操作をキャンセル",
- "shortcuts.action.openNodeSearch": "ノード検索を開く",
- "shortcuts.action.resetViewport": "ビューポートをリセット",
- "shortcuts.action.centerSelection": "選択を中央に配置",
- "shortcuts.action.fitSelection": "選択にフィット",
- "shortcuts.action.autoLayout": "自動レイアウト",
- "shortcuts.action.toggleSnapToGrid": "グリッドスナップ切替",
- "shortcuts.action.bringForward": "前面へ",
- "shortcuts.action.sendBackward": "背面へ",
- "shortcuts.action.bringToFront": "最前面へ",
- "shortcuts.action.sendToBack": "最背面へ",
- "shortcuts.action.zoomInOut": "ズームイン / アウト",
- "shortcuts.action.pan": "パン",
- "shortcuts.action.temporaryPan": "一時パン",
- "shortcuts.action.alternatePan": "代替パン",
- "shortcuts.action.fineNudge": "選択を微調整移動",
- "shortcuts.action.fastNudge": "高速移動",
- "shortcuts.action.togglePreview": "データプレビュー切替",
- "shortcuts.action.explainPlan": "実行計画",
- "shortcuts.action.runPreview": "プレビュー実行",
- "shortcuts.action.connectionManager": "接続マネージャー",
- "shortcuts.action.flowVersionHistory": "フローバージョン履歴",
- "shortcuts.resetAll": "すべてリセット",
- "shortcuts.customized": "カスタム",
- "shortcuts.default": "デフォルト",
- "shortcuts.apply": "適用",
- "shortcuts.reset": "リセット",
- "shortcuts.status.resetAllSuccess": "すべてのショートカットをデフォルトに戻しました。",
- "shortcuts.status.updated": "ショートカットを更新しました。",
- "shortcuts.status.reset": "ショートカットをデフォルトに戻しました。",
- "shortcuts.status.updateFailed": "ショートカットを更新できませんでした。",
- "toast.severity.success": "Success",
- "toast.severity.warning": "Warning",
- "toast.severity.error": "Error",
- "toast.details.success": "Success Details",
- "toast.details.warning": "Warning Details",
- "toast.details.error": "Error Details",
- "diagnostics.area.cteEditor": "CTE Editor",
- "diagnostics.area.viewEditor": "View Editor",
- "diagnostics.area.subEditor": "Sub-editor",
- "diagnostics.cteEditor.restoreParentFailed": "Failed to restore the parent canvas. CTE edits were discarded.",
- "diagnostics.recommendation.reloadFileIfNeeded": "Reload the file if needed.",
- "diagnostics.viewEditor.exitFailed": "Could not exit: {0}",
- "diagnostics.viewEditor.canvasIncomplete": "the canvas is incomplete.",
- "diagnostics.viewEditor.exitRecommendation": "Connect a valid ResultOutput or use the discard command.",
- "diagnostics.viewEditor.restoreParentFailed": "Failed to restore the parent canvas. The subgraph was discarded.",
- "diagnostics.subEditor.executeFailed": "Failed to execute editor action: {0}",
- "diagnostics.subEditor.executeRecommendation": "Try again. If it persists, reload the canvas.",
- "diagnostics.canvasMigration.openWarning": "Open: {0}",
- "diagnostics.canvasMigration.sessionRestoreWarning": "Session restore: {0}",
- "diagnostics.canvasMigration.versionRestoreWarning": "Version restore: {0}",
- "diagnostics.recommendation.resaveLatestSchema": "Review diagnostics and re-save the canvas to persist the latest schema.",
- "diagnostics.recommendation.saveMigratedSchema": "Review diagnostics and save the canvas to persist the migrated schema.",
- "file.saveDialog.title": "Save Canvas",
- "file.saveDialog.suggestedName": "Query1",
- "file.save.success": "Canvas saved successfully.",
- "file.save.failedWithReason": "Save failed: {0}",
- "file.openDialog.title": "Open Canvas",
- "file.open.failedWithReason": "Open failed: {0}",
- "file.open.success": "Canvas opened successfully.",
- "file.open.successWithWarnings": "Canvas opened with warnings.",
- "session.restore.failedWithReason": "Restore failed: {0}",
- "session.restore.successWithWarnings": "Session restored with warnings.",
- "session.restore.success": "Session restored successfully.",
- "export.documentation.dialogTitle": "Export Flow Documentation",
- "export.documentation.success": "Documentation exported successfully.",
- "export.documentation.failed": "Documentation export failed.",
- "export.failed.pathPermissionsHint": "Check file path and permissions.",
- "export.nodeNotFound": "No {0} Export node found on the canvas. Add one via the node search menu.",
- "export.dialogTitleByExtension": "Export as {0}",
- "export.success": "Export completed successfully.",
- "export.failed": "Export failed.",
- "fileHistory.currentFile.none": "No file selected",
- "fileHistory.status.saveFirst": "Save the canvas first to enable local history.",
- "fileHistory.status.noneFound": "No local versions found yet. Save this file to create history entries.",
- "fileHistory.status.countAvailable": "{0} local version(s) available.",
- "fileHistory.restore.failedWithReason": "Restore failed: {0}",
- "fileHistory.restore.successFrom": "Restored version from {0}.",
- "preview.status.cancelled": "Cancelled",
- "preview.status.error": "Error",
- "preview.status.ready": "Ready",
- "preview.runningWithMs": "Running... {0}ms",
- "preview.runningWithTimeout": "Running... {0}ms (timeout: {1}s)",
- "preview.runningSlowWithTimeout": "Running... {0}ms (timeout: {1}s) · Slow query, timeout in {2}s",
- "explain.errorWithReason": "Explain plan error: {0}",
- "explain.noSql": "No SQL to explain. Build a query on the canvas first.",
- "ddl.compilationFailed": "Compilation failed",
- "ddl.compileErrorWithReason": "DDL compile error: {0}",
- "command.undo.name": "Undo",
- "command.undo.description": "Undo last action",
- "command.redo.name": "Redo",
- "command.redo.description": "Redo last undone action",
- "command.addNode.name": "Add Node",
- "command.addNode.description": "Open node search menu to add a node",
- "command.bringForward.name": "Bring Forward",
- "command.bringForward.description": "Move selected nodes one layer forward",
- "command.sendBackward.name": "Send Backward",
- "command.sendBackward.description": "Move selected nodes one layer backward",
- "command.bringToFront.name": "Bring to Front",
- "command.bringToFront.description": "Move selected nodes to top layer",
- "command.sendToBack.name": "Send to Back",
- "command.sendToBack.description": "Move selected nodes to bottom layer",
- "command.normalizeLayers.name": "Normalize Layers",
- "command.normalizeLayers.description": "Compact node layer indices to a clean 0..N order",
- "tooltip.cleanupOrphans": "Remove orphan nodes not connected to the output (Ctrl+Z to undo)",
- "main.orphanSuffix": "Orphan(s)",
- "tooltip.autoFixAliasNaming": "Fix alias naming to snake_case (Ctrl+Z to undo)",
- "main.namingPrefix": "Naming",
- "fileHistory.compressedLabel": "Compressed:",
- "schema.itemsSuffix": "item(s)",
- "property.panel.title": "Properties",
- "property.panel.multiSelected": "{0} nodes selected",
- "sqlImporter.status.pasteSelect": "Paste a SELECT statement above, then click Import.",
- "sqlImporter.status.inputTooLarge": "SQL input is too large ({0:N0} chars). Limit is {1:N0}. Split the query or increase the import limit.",
- "sqlImporter.status.parsing": "Parsing SQL...",
- "sqlImporter.status.done": "Done - {0} imported, {1} partial, {2} skipped.",
- "sqlImporter.status.cancelledByUser": "Import cancelled by user.",
- "sqlImporter.status.timeout": "Import timed out after {0:0.#}s. Try a smaller query or increase timeout.",
- "sqlImporter.status.parseError": "Parse error: {0}",
- "diagnostics.area.undoRedoTransaction": "Undo/Redo Transaction",
- "undoRedo.rollbackExecuted": "Rollback executed for '{0}' ({1} operation(s) reverted).",
- "undoRedo.rollbackRecommendation": "Review the canvas state and retry the action if needed.",
- "node.preview.noCatalog": "No catalog available",
- "connection.error.searchMenuNotInitialized": "search menu not initialized",
- "connection.error.timeoutReachability": "Connection timed out - check that the server is reachable and increase the timeout if needed.",
- "connection.error.authenticationFailedForProvider": "Authentication failed - verify username and password for {0}.",
- "connection.error.databaseNotFoundForProvider": "Database not found - confirm the database name exists on {0}.",
- "connection.error.hostNotFound": "Host not found - check the server address and DNS resolution.",
- "connection.error.portRefused": "Port connection refused - check the port number and that the server is running / firewall rules allow access.",
- "connection.error.sslTls": "SSL/TLS error - check the server's SSL configuration or disable SSL for local connections.",
- "connection.error.timeoutOverloaded": "Connection timed out - the server may be overloaded or unreachable. Try increasing the timeout.",
- "connection.error.insufficientPrivileges": "Insufficient privileges - the user may lack permission to connect to this database.",
- "diagnostics.area.connection": "Connection",
- "connection.warning.canvasMayContainOldTables": "The canvas may still contain tables from a previous connection.",
- "connection.warning.canvasMayContainOldTablesRecommendation": "Clear the canvas manually or reconnect and choose keep/clear again.",
- "undoRedo.transaction.unnamed": "unnamed transaction",
- "benchmark.runLabelDefault": "Run 1",
- "benchmark.runLabelPattern": "Run {0}",
- "benchmark.status.failedWithReason": "Benchmark failed: {0}",
- "benchmark.status.noSql": "No SQL to benchmark - build a query first.",
- "benchmark.status.warmupProgress": "Warm-up {0}/{1}...",
- "benchmark.status.iterationProgress": "Iteration {0}/{1}...",
- "benchmark.status.done": "Done - {0}",
- "benchmark.status.cancelled": "Benchmark cancelled.",
- "app.windowTitle": "DBWeaver",
- "preview.error.safePreviewBlocked": "Safe Preview Mode: data-mutating commands (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) cannot be executed in preview.",
- "preview.error.noActiveConnection": "No active database connection. Please connect to a database first.",
- "sqlImporter.error.selectFromNotFound": "Could not find SELECT ... FROM in the query.",
- "sqlImporter.error.fromClauseParseFailed": "Could not parse FROM clause.",
- "sqlImporter.error.syntaxUnterminatedString": "Syntax error at line {0}, column {1}: unterminated string literal.",
- "sqlImporter.error.missingClosingParenthesis": "missing closing ')'",
- "sqlImporter.error.unexpectedClosingParenthesis": "unexpected ')'",
- "sqlImporter.error.syntaxAtLineColumn": "Syntax error at line {0}, column {1}: {2}.",
- "errorDiagnostics.safePreview.label": "Blocked by Safe Preview Mode",
- "errorDiagnostics.safePreview.friendly": "This SQL contains a data-mutating command and cannot be executed in preview.",
- "errorDiagnostics.safePreview.suggestion": "Remove or replace the mutating command (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) before running preview.",
- "errorDiagnostics.connection.label": "Connection failed",
- "errorDiagnostics.connection.friendly": "Could not reach the database server. The host may be down, unreachable, or blocking connections.",
- "errorDiagnostics.connection.suggestion": "Verify the server address and port, ensure the database is running, and check firewall rules.",
- "errorDiagnostics.authorization.label": "Authorization error",
- "errorDiagnostics.authorization.friendly": "The current credentials do not have permission to perform this operation.",
- "errorDiagnostics.authorization.suggestion": "Confirm the database user has SELECT privileges on the target table/schema, or contact your DBA.",
- "errorDiagnostics.timeout.label": "Query timeout",
- "errorDiagnostics.timeout.friendly": "The query took too long to complete and was cancelled by the server or client.",
- "errorDiagnostics.timeout.suggestion": "Add a WHERE clause or LIMIT to reduce the result set, or increase the query timeout in connection settings.",
- "errorDiagnostics.schema.label": "Schema error",
- "errorDiagnostics.schema.friendly": "A referenced table, column, or object could not be found in the database.",
- "errorDiagnostics.schema.suggestion": "Check that all table/column names are spelled correctly and that the schema matches the active connection.",
- "errorDiagnostics.syntax.label": "SQL syntax error",
- "errorDiagnostics.syntax.friendly": "The query contains a syntax error and could not be parsed by the database engine.",
- "errorDiagnostics.syntax.suggestion": "Review the highlighted SQL for typos, mismatched parentheses, or unsupported clauses for the active provider.",
- "errorDiagnostics.compatibility.label": "Compatibility error",
- "errorDiagnostics.compatibility.friendly": "A function, operator, or syntax construct is not supported by the active database provider.",
- "errorDiagnostics.compatibility.suggestion": "Switch to the correct provider in the SQL bar, or replace the unsupported construct with an equivalent.",
- "errorDiagnostics.unknown.label": "Unexpected error",
- "errorDiagnostics.unknown.friendly": "An error occurred while running the preview query.",
- "errorDiagnostics.unknown.suggestion": "Check the technical details below and verify that your canvas is configured correctly.",
- "error.mainWindow.invalidDataContext": "MainWindow の DataContext は ShellViewModel である必要があります。",
- "error.mainWindow.canvasNotInitialized": "CanvasViewModel が初期化されていません。",
- "error.mainWindow.ddlPreviewUnavailable": "現在のキャンバスではDDLプレビューを利用できません。",
- "themeJson.editor.template": "{\n \"meta\": { \"name\": \"カスタムテーマ\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
- "themeJson.error.pasteBeforeApply": "適用する前にテーマJSONを貼り付けてください。",
- "themeJson.error.invalidJson": "無効なJSON: {0}",
- "themeJson.error.emptyPayload": "無効なJSON: payloadが空です。",
- "themeJson.error.invalidTheme": "無効なテーマ: {0}",
- "themeJson.error.appliedButSaveFailed": "テーマは適用されましたが保存に失敗しました: {0}",
- "themeJson.success.appliedAndSaved": "JSONテーマを適用して保存しました。",
- "themeJson.success.customRemoved": "カスタムテーマを削除しました。既定テーマへ完全に戻すにはアプリを再起動してください。",
- "themeJson.error.restoreDefaultFailed": "既定テーマの復元に失敗しました: {0}",
- "themeValidator.error.configNull": "テーマ設定がnullです。",
- "themeValidator.warning.noSections": "テーマに色またはタイポグラフィのセクションがありません。適用する内容がありません。",
- "themeValidator.warning.invalidColor": "{0} の色 '{1}' は無効です。このキーは無視されます。",
- "themeValidator.warning.sizeOutOfRange": "{0}={1} は範囲外です (8..48)。このキーは無視されます。",
- "queryExecutor.error.openConnectionMethodNotFound": "orchestratorにOpenConnectionAsyncメソッドが見つかりません",
- "queryExecutor.error.openConnectionInvokeFailed": "OpenConnectionAsyncの呼び出しに失敗しました",
- "ddlImporter.warning.viewSelectNotReconstructable": "View '{0}': ビューのSELECTは視覚的に再構築できません。subcanvasで手動編集してください。",
- "ddlImporter.error.tableNotFoundInMetadata": "テーブル '{0}' は現在のメタデータに見つかりませんでした。",
- "main.window.untitled": "無題",
- "main.subEditor.noSeedProvided": "{0} のサブエディターseedが提供されませんでした。",
- "main.layerOrder.bringToFront": "最前面へ",
- "main.layerOrder.sendToBack": "最背面へ",
- "main.layerOrder.bringForward": "前面へ移動",
- "main.layerOrder.sendBackward": "背面へ移動",
- "main.layerOrder.normalizeLayers": "レイヤーを正規化",
- "export.fileType.html": "HTMLファイル",
- "export.fileType.json": "JSONファイル",
- "export.fileType.csv": "CSVファイル",
- "export.fileType.excel": "Excelファイル",
- "commandPalette.templatePrefix": "テンプレート: {0}",
- "themeLoader.status.notFoundWithPath": "テーマファイルが見つかりません: {0}",
- "themeLoader.status.deserializedNull": "テーマJSONのデシリアライズ結果が null でした。",
- "themeLoader.status.loaded": "テーマJSONを正常に読み込みました。",
- "credential.error.ciphertextTooShort": "暗号文ブロブが短すぎます。",
- "credential.error.dpapiWindowsOnly": "DPAPI は Windows でのみ利用できます。",
- "credential.warning.loadVaultFailed": "資格情報ボルト {0} の読み込みに失敗しました: {1}",
- "credential.warning.persistVaultFailed": "資格情報ボルト {0} の保存に失敗しました: {1}",
- "snippetStore.warning.loadFailed": "{0} からスニペットの読み込みに失敗しました: {1}",
- "snippetStore.warning.saveFailed": "スニペットの保存に失敗しました: {0}",
- "flowVersionStore.warning.loadFailed": "{0} からフローバージョンの読み込みに失敗しました: {1}",
- "flowVersionStore.warning.saveFailed": "フローバージョンの保存に失敗しました: {0}",
- "queryExecutor.error.queryEmpty": "クエリは空にできません",
- "queryExecutor.error.providerNotSupported": "プロバイダー {0} はサポートされていません",
- "queryExecutor.error.singleStatementOnly": "プレビューは単一のSQL文のみ受け付けます。",
- "queryExecutor.error.queryEmptyWithPeriod": "クエリは空にできません。",
- "queryExecutor.error.readOnlyOnly": "プレビューモードは読み取り専用SQLのみサポートします。",
- "queryExecutor.error.namedParametersNotSupported": "プレビューモードは実行SQLのバインドパラメータをサポートしません。安全なリテラルをインラインで指定するか、プレビュー外で実行してください。",
- "queryExecutor.error.positionalParametersNotSupported": "プレビューモードは位置パラメータプレースホルダー(? または )をサポートしません。",
- "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "選択したノードを下端に揃えます",
- "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "選択したノードを左端に揃えます",
- "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "選択したノードを右端に揃えます",
- "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "選択したノードを上端に揃えます",
- "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "CTEサブキャンバスの編集を適用して親キャンバスに戻ります",
- "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "ノードを論理的な列に自動配置します",
- "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "選択したノードを水平軸で中央揃えします",
- "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "選択したノードを垂直軸で中央揃えします",
- "commandPalette.description.clear_canvas_and_start_fresh": "キャンバスをクリアして最初から開始します",
- "commandPalette.description.clear_node_selection": "ノードの選択を解除します",
- "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "エイリアスをプロジェクト設定の命名規則に変換します",
- "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "チェックポイントを作成し、バージョン比較と以前の状態への復元を行います",
- "commandPalette.description.delete_the_selected_nodes": "選択したノードを削除します",
- "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "現在のサブエディタの編集を破棄して親キャンバスに戻ります",
- "commandPalette.description.execute_the_current_query_in_preview": "プレビューで現在のクエリを実行します",
- "commandPalette.description.fit_all_nodes_into_the_visible_area": "すべてのノードを表示領域に収めます",
- "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "最初のCSVエクスポートノードからCSVファイルを生成します",
- "commandPalette.description.generate_html_file_from_the_first_html_export_node": "最初のHTMLエクスポートノードからHTMLファイルを生成します",
- "commandPalette.description.generate_json_file_from_the_first_json_export_node": "最初のJSONエクスポートノードからJSONファイルを生成します",
- "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "最初のExcelエクスポートノードからXLSXブックを生成します",
- "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "クエリ実行計画を確認し、スキャン種別・結合戦略・コスト見積りを確認します",
- "commandPalette.description.load_a_vsaq_canvas_file": ".vsaq キャンバスファイルを読み込みます",
- "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "現在のSQLをN回実行して平均/中央値/p95レイテンシを測定します",
- "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "選択したCTE定義ノードの分離サブキャンバスエディタを開きます",
- "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "保存ごとに作成されるローカル履歴を開き、過去スナップショットを復元します",
- "commandPalette.description.open_output_preview_modal_for_the_active_mode": "アクティブモードの出力プレビューモーダルを開きます",
- "commandPalette.description.open_shortcut_reference_screen": "ショートカット一覧画面を開きます",
- "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "接続マネージャーを開いてDB接続の追加・編集・切替を行います",
- "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "SELECT文を貼り付けてノードを自動生成します(FROM/JOIN/WHERE/LIMIT対応)",
- "commandPalette.description.remove_all_nodes_not_connected_to_output": "出力に接続されていないノードをすべて削除します",
- "commandPalette.description.reset_zoom_and_pan_to_default": "ズームとパンを初期値に戻します",
- "commandPalette.description.save_canvas_to_a_new_file": "キャンバスを新しいファイルに保存します",
- "commandPalette.description.save_current_canvas": "現在のキャンバスを保存します",
- "commandPalette.description.save_markdown_documentation_of_the_current_flow": "現在のフローのMarkdownドキュメントを保存します",
- "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "選択ノードを再利用可能なスニペットとして保存し、後でノード検索メニュー(⇧A)から挿入します",
- "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "FK規約と命名パターンに基づいてテーブルソースノード間のJOIN候補を検出します",
- "commandPalette.description.select_all_nodes_on_canvas": "キャンバス上のすべてのノードを選択します",
- "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "ノード位置を16pxグリッドにスナップします(Ctrl+G)",
- "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "選択ノードを水平方向に等間隔で配置します",
- "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "選択ノードを垂直方向に等間隔で配置します",
- "commandPalette.description.zoom_into_the_canvas": "キャンバスを拡大します",
- "commandPalette.description.zoom_out_of_the_canvas": "キャンバスを縮小します",
- "commandPalette.name.align_bottom": "下揃え",
- "commandPalette.name.align_left": "左揃え",
- "commandPalette.name.align_right": "右揃え",
- "commandPalette.name.align_top": "上揃え",
- "commandPalette.name.analyze_all_joins": "すべてのJOINを解析",
- "commandPalette.name.auto_fix_naming": "命名を自動修正",
- "commandPalette.name.auto_layout": "自動レイアウト",
- "commandPalette.name.center_horizontally": "水平中央揃え",
- "commandPalette.name.center_vertically": "垂直中央揃え",
- "commandPalette.name.cleanup_orphans": "孤立ノードをクリーンアップ",
- "commandPalette.name.delete_selected": "選択を削除",
- "commandPalette.name.deselect_all": "すべて選択解除",
- "commandPalette.name.discard_and_exit_editor": "破棄してエディタを終了",
- "commandPalette.name.distribute_horizontally": "水平方向に均等配置",
- "commandPalette.name.distribute_vertically": "垂直方向に均等配置",
- "commandPalette.name.edit_selected_cte": "選択したCTEを編集",
- "commandPalette.name.exit_cte_editor": "CTEエディタを終了",
- "commandPalette.name.explain_plan": "実行計画",
- "commandPalette.name.export_csv": "CSVをエクスポート",
- "commandPalette.name.export_documentation": "ドキュメントをエクスポート",
- "commandPalette.name.export_excel": "Excelをエクスポート",
- "commandPalette.name.export_html": "HTMLをエクスポート",
- "commandPalette.name.export_json": "JSONをエクスポート",
- "commandPalette.name.file_save_load_history": "保存/読み込み履歴",
- "commandPalette.name.fit_to_screen": "画面にフィット",
- "commandPalette.name.flow_version_history": "フローバージョン履歴",
- "commandPalette.name.import_sql_to_graph": "SQLをグラフにインポート",
- "commandPalette.name.keyboard_shortcuts": "キーボードショートカット",
- "commandPalette.name.manage_connections": "接続を管理",
- "commandPalette.name.new_canvas": "新しいキャンバス",
- "commandPalette.name.open_file": "ファイルを開く",
- "commandPalette.name.reset_viewport": "ビューポートをリセット",
- "commandPalette.name.run_preview": "プレビューを実行",
- "commandPalette.name.run_query_benchmark": "クエリベンチマークを実行",
- "commandPalette.name.save": "保存",
- "commandPalette.name.save_as": "名前を付けて保存",
- "commandPalette.name.save_selection_as_snippet": "選択をスニペットとして保存",
- "commandPalette.name.select_all": "すべて選択",
- "commandPalette.name.toggle_preview": "プレビューを切り替え",
- "commandPalette.name.toggle_snap_to_grid": "グリッドスナップを切り替え",
- "commandPalette.name.zoom_in": "ズームイン",
- "commandPalette.name.zoom_out": "ズームアウト",
- "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 percent restore zoom pan viewport",
- "commandPalette.tags.align_bottom_edge_selection_nodes": "align bottom edge selection nodes",
- "commandPalette.tags.align_center_middle_horizontal_nodes": "align center middle horizontal nodes",
- "commandPalette.tags.align_center_middle_vertical_nodes": "align center middle vertical nodes",
- "commandPalette.tags.align_left_edge_selection_nodes": "align left edge selection nodes",
- "commandPalette.tags.align_right_edge_selection_nodes": "align right edge selection nodes",
- "commandPalette.tags.align_top_edge_selection_nodes": "align top edge selection nodes",
- "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout view reset zoom",
- "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark performance latency timing profile measure speed",
- "commandPalette.tags.clear_selection": "clear selection",
- "commandPalette.tags.connection_database_server_host_provider_switch": "connection database server host provider switch",
- "commandPalette.tags.create_insert_search_transform": "create insert search transform",
- "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas exit apply back",
- "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte view subcanvas discard exit force",
- "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursive editor subgraph subcanvas isolate",
- "commandPalette.tags.data_results_table_panel": "data results table panel",
- "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribute space equal horizontal nodes",
- "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribute space equal vertical nodes",
- "commandPalette.tags.execute_run_sql_query_results": "execute run sql query results",
- "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan execution cost scan index join performance",
- "commandPalette.tags.export_csv_file_tabular_output_save": "export csv file tabular output save",
- "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "export excel xlsx file tabular output spreadsheet save",
- "commandPalette.tags.export_html_file_output_report_save": "export html file output report save",
- "commandPalette.tags.export_json_file_output_save": "export json file output save",
- "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "export markdown doc documentation flow save md",
- "commandPalette.tags.export_persist_copy": "export persist copy",
- "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "file history save load backup versions restore local",
- "commandPalette.tags.forward_history": "forward history",
- "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "help shortcuts hotkeys keyboard reference",
- "commandPalette.tags.highlight_mark_all_nodes": "highlight mark all nodes",
- "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "import sql paste convert graph reverse engineer query",
- "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analyze suggest detect foreign key relationships heuristic",
- "commandPalette.tags.layer_z_order_back_selected_nodes": "layer z-order back selected nodes",
- "commandPalette.tags.layer_z_order_backward_selected_nodes": "layer z-order backward selected nodes",
- "commandPalette.tags.layer_z_order_forward_selected_nodes": "layer z-order forward selected nodes",
- "commandPalette.tags.layer_z_order_front_selected_nodes": "layer z-order front selected nodes",
- "commandPalette.tags.layer_z_order_normalize_compact": "layer z-order normalize compact",
- "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout arrange columns auto organize readability",
- "commandPalette.tags.load_import_vsaq": "load import vsaq",
- "commandPalette.tags.magnify_enlarge": "magnify enlarge",
- "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "orphan unused disconnected clean delete nodes",
- "commandPalette.tags.persist_write_disk": "persist write disk",
- "commandPalette.tags.remove_erase_nodes": "remove erase nodes",
- "commandPalette.tags.rename_alias_fix_naming_convention": "rename alias fix naming convention",
- "commandPalette.tags.reset_clear_blank": "reset clear blank",
- "commandPalette.tags.revert_back_history": "revert back history",
- "commandPalette.tags.shrink_reduce": "shrink reduce",
- "commandPalette.tags.snap_grid_align_precision_position": "snap grid align precision position",
- "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet save selection reuse template favorite bookmark",
- "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "version history checkpoint diff restore snapshot compare undo flow",
- "sqlEditor.diffPreview.title": "Transactional Diff Preview",
- "sqlEditor.mutation.confirmExecute": "Confirm Execute",
- "sqlEditor.tab.closeAnyway": "Close Anyway",
- "sqlEditor.tab.keepTab": "Keep Tab",
- "sqlEditor.status.ready": "Ready.",
- "sqlEditor.telemetry.none": "No execution telemetry yet.",
- "sqlEditor.telemetry.summary": "Statements: {0} Success: {1} Failed: {2} Total: {3} ms",
- "sqlEditor.telemetry.errors.none": "No aggregated errors.",
- "sqlEditor.diff.none": "No transactional diff preview available.",
- "sqlEditor.mutation.estimate.none": "No mutation estimate available.",
- "sqlEditor.mutation.estimate.value": "Estimated affected rows: {0}",
- "sqlEditor.mutation.estimate.unavailable": "Could not estimate affected rows automatically.",
- "sqlEditor.tab.closePending": "Unsaved changes detected. Confirm tab close.",
- "sqlEditor.tab.noPendingClose": "No tab close pending.",
- "sqlEditor.tab.manyWarning": "High tab count: {0} open tabs.",
- "sqlEditor.mutation.pending.none": "No pending mutation confirmation.",
- "sqlEditor.mutation.pending.required": "Mutation requires confirmation before execution.",
- "sqlEditor.message.empty": "Execute a statement to see messages.",
- "sqlEditor.message.success": "Execution completed successfully.",
- "sqlEditor.result.summary.empty": "Rows: - Time: -",
- "sqlEditor.result.summary": "Rows: {0} Time: {1} ms",
- "sqlEditor.file.save.canceled": "Save canceled.",
- "sqlEditor.file.save.noPath": "No target path selected.",
- "sqlEditor.file.save.success": "SQL file saved.",
- "sqlEditor.file.save.failed": "Save failed.",
- "sqlEditor.file.open.failed": "Open failed.",
- "sqlEditor.file.open.notFound": "Selected SQL file was not found.",
- "sqlEditor.file.open.success": "SQL file opened.",
- "sqlEditor.status.executing": "Executing SQL...",
- "sqlEditor.status.executingScript": "Executing SQL script...",
- "sqlEditor.status.executingStep": "Executing {0}/{1}...",
- "sqlEditor.status.canceling": "Canceling execution...",
- "sqlEditor.status.executingConfirmedMutation": "Executing confirmed mutation...",
- "sqlEditor.status.mutationCanceled": "Mutation execution canceled.",
- "sqlEditor.detail.statementNotExecuted": "Statement was not executed.",
- "sqlEditor.status.success": "Execution succeeded.",
- "sqlEditor.detail.rowsAndTime": "{0} row(s) in {1} ms.",
- "sqlEditor.status.canceled": "Execution canceled.",
- "sqlEditor.status.failed": "Execution failed.",
- "sqlEditor.status.confirmationRequired": "Confirmation required before execution.",
- "sqlEditor.error.mutationConfirmationRequired": "Mutation confirmation required.",
- "sqlEditor.result.tabTitle": "Result {0}",
- "sqlEditor.tab.closeRequiresConfirmation": "Tab close requires confirmation.",
- "sqlEditor.tab.unsavedDetail": "This tab has unsaved changes.",
- "sqlEditor.tab.closed": "Tab closed.",
- "sqlEditor.tab.closeCanceled": "Tab close canceled.",
- "sqlEditor.tab.closeCanceledDetail": "Unsaved tab kept open.",
- "sqlEditor.error.noStatementSelected": "No SQL statement selected for execution.",
- "sqlEditor.error.noConnection": "No active database connection for SQL execution.",
- "sqlEditor.error.executionCanceled": "SQL execution was canceled.",
- "sqlEditor.tab.scriptTitle": "Script {0}",
- "sqlEditor.guard.delete.noWhere.message": "DELETE without WHERE can remove all rows.",
- "sqlEditor.guard.delete.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
- "sqlEditor.guard.delete.trivialWhere.message": "DELETE has a trivially true WHERE clause.",
- "sqlEditor.guard.delete.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
- "sqlEditor.guard.update.noWhere.message": "UPDATE without WHERE can affect all rows.",
- "sqlEditor.guard.update.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
- "sqlEditor.guard.update.trivialWhere.message": "UPDATE has a trivially true WHERE clause.",
- "sqlEditor.guard.update.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
- "sqlEditor.guard.insert.noColumnList.message": "INSERT without explicit column list is fragile against schema changes.",
- "sqlEditor.guard.insert.noColumnList.recommendation": "Prefer INSERT INTO table(col1, col2, ...) VALUES (...).",
- "sqlEditor.guard.ddl.message": "DDL statement may cause structural changes in the database.",
- "sqlEditor.guard.ddl.recommendation": "Confirm execution only when schema changes are intended.",
- "sqlEditor.diff.unavailable.noPreview": "No transactional diff preview available for this statement.",
- "sqlEditor.diff.unavailable.parseError": "Could not parse mutation target for transactional diff preview.",
- "sqlEditor.diff.unavailable.connection": "Transactional diff preview unavailable due to connection or query limitations.",
- "sqlEditor.diff.deleteSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, affected {2}, total rows after {3}.",
- "sqlEditor.diff.updateSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, candidate rows affected {2}, total rows after {3}.",
- "sqlEditor.diff.unavailable.unsupportedStatement": "Transactional diff preview currently supports UPDATE and DELETE only.",
- "sqlEditor.results.title": "Results",
- "sqlEditor.saveSql.fileType": "SQL Files",
- "sqlEditor.saveSql.pickerTitle": "Save SQL File",
- "sqlEditor.export.pickerTitle": "Export SQL Data",
- "sqlEditor.export.status.noResultTitle": "No execution result available for export.",
- "sqlEditor.export.status.noResultDetail": "Execute a query first.",
- "sqlEditor.export.status.successTitle": "Report exported.",
- "sqlEditor.export.status.failedTitle": "Failed to export report.",
- "sqlEditor.export.fileType.html": "HTML File",
- "sqlEditor.export.fileType.json": "JSON File",
- "sqlEditor.export.fileType.csv": "CSV File",
- "sqlEditor.export.fileType.xlsx": "Excel Workbook",
- "sqlEditor.export.defaultFileBase": "report",
- "sqlEditor.export.defaultTitle": "SQL Report",
- "sqlEditor.export.error.typeRequired": "A report type must be selected before export.",
- "sqlEditor.export.type.html.title": "HTML full-feature report",
- "sqlEditor.export.type.html.description": "Standalone, SQL-first HTML artifact for offline audit.",
- "sqlEditor.export.type.json.title": "JSON execution contract",
- "sqlEditor.export.type.json.description": "Machine-readable payload with SQL, metadata and execution result.",
- "sqlEditor.export.type.csv.title": "CSV data export",
- "sqlEditor.export.type.csv.description": "Tabular result data only, suitable for spreadsheet tools.",
- "sqlEditor.export.type.xlsx.title": "Excel workbook export",
- "sqlEditor.export.type.xlsx.description": "Spreadsheet workbook with query result data only.",
- "sqlEditor.export.dialog.windowTitle": "Export SQL Data",
- "sqlEditor.export.dialog.title": "Export SQL Data",
- "sqlEditor.export.dialog.subtitle": "Choose the artifact format and metadata before exporting.",
- "sqlEditor.export.dialog.confirm": "Export",
- "sqlEditor.export.dialog.fileNameWatermark": "report.html",
- "sqlEditor.export.dialog.titleWatermark": "SQL Report",
- "sqlEditor.export.dialog.descriptionWatermark": "Additional context for auditors and teammates.",
- "sqlEditor.export.dialog.section.reportType": "REPORT TYPE",
- "sqlEditor.export.dialog.section.fileName": "FILE NAME",
- "sqlEditor.export.dialog.section.reportTitle": "TITLE",
- "sqlEditor.export.dialog.section.description": "DESCRIPTION",
- "sqlEditor.export.dialog.section.options": "OPTIONS",
- "sqlEditor.export.option.includeSchema": "Include output schema",
- "sqlEditor.export.option.includeNodeDetails": "Include node/connection placeholders in JSON",
- "sqlEditor.export.option.includeMetadata": "Include optional metadata",
- "sqlEditor.export.option.useDashForEmpty": "Use '-' for empty fields",
- "sqlEditor.export.badge.offline": "OFFLINE READY",
- "sqlEditor.export.badge.structured": "STRUCTURED PAYLOAD",
- "sqlEditor.export.badge.dataOnly": "DATA ONLY"
-}
+{
+ "main.brand": "AkkornStudio",
+ "main.tab.query1": "Query 1",
+ "main.new": "New",
+ "main.open": "Open",
+ "main.save": "Save",
+ "main.history": "History",
+ "main.layout": "Layout",
+ "main.preview": "Preview",
+ "main.undo": "Undo",
+ "main.redo": "Redo",
+ "main.cleanupOrphans": "Cleanup orphan nodes",
+ "main.autoFixAliasNaming": "Auto-fix alias naming",
+ "main.autoLayoutCanvas": "Auto layout canvas",
+ "main.toggleDataPreview": "Toggle data preview",
+ "main.language": "Language",
+ "main.restore.prompt": "Previous session found — restore the last canvas?",
+ "main.restore.button": "Restore session",
+ "main.cteEditor.editingPrefix": "Editing CTE: ",
+ "main.cteEditor.backToCanvas": "Back to Canvas",
+ "main.cteEditor.exitA11y": "Exit CTE editor",
+ "main.viewEditor.editingPrefix": "DDL > View: ",
+ "main.viewEditor.backToCanvas": "Back to DDL",
+ "main.viewEditor.exitA11y": "Exit view editor",
+ "connection.title": "Connection Manager",
+ "connection.subtitle": "作業フローを中断せずに接続の設定・テスト・有効化を行います",
+ "connection.none": "No connection",
+ "connection.active": "ACTIVE",
+ "connection.health.online": "Online",
+ "connection.health.degraded": "Degraded",
+ "connection.health.offline": "Offline",
+ "connection.tooltip.none": "No active connection — click to manage",
+ "connection.ping": "Ping",
+ "connection.saved": "SAVED CONNECTIONS",
+ "connection.new": "New Connection",
+ "connection.selectOrCreate": "Select a connection or create a new one",
+ "connection.name": "Connection Name",
+ "connection.provider": "Provider",
+ "connection.host": "Host",
+ "connection.port": "Port",
+ "connection.database": "Database",
+ "connection.sqlitePath": "SQLite Path",
+ "connection.sqliteBrowse": "Browse",
+ "connection.sqliteCreate": "Create",
+ "connection.username": "Username",
+ "connection.password": "Password",
+ "connection.timeout": "Timeout (seconds)",
+ "connection.test": "Test",
+ "connection.save": "Save",
+ "connection.connect": "Connect",
+ "connection.action.testConnection": "Test connection",
+ "connection.action.saveConnection": "Save connection",
+ "connection.action.connectConnection": "Connect connection",
+ "connection.status.connecting": "接続中...",
+ "connection.status.connected": "接続済み",
+ "connection.status.testing": "テスト中...",
+ "connection.status.failedPrefix": "接続に失敗しました",
+ "connection.status.metadataUnavailable": "接続に失敗しました: メタデータが利用できません。",
+ "connection.status.highLatency": "高遅延",
+ "connection.watermark.name": "本番DB",
+ "connection.watermark.host": "localhost",
+ "connection.watermark.port": "5432",
+ "connection.watermark.database": "database_name",
+ "connection.watermark.username": "user",
+ "connection.watermark.password": "••••••••",
+ "connection.watermark.timeout": "30",
+ "main.connectingDb": "Connecting to database...",
+ "main.emptyHint": "Press ⇧A to add your first node, or drag a table from the sidebar",
+ "status.nodesSeparator": " nodes · ",
+ "status.connectionsSuffix": " connections",
+ "status.undo": "Undo: ",
+ "status.shortcuts": "⇧A Nodes · F3 Preview · Ctrl+Z Undo · Del Remove · Alt+Drag Pan",
+ "connection.disconnect": "Disconnect",
+ "connection.action.disconnectConnection": "Disconnect connection",
+ "connectionTab.active": "ACTIVE CONNECTION",
+ "connectionTab.none": "No active connection",
+ "connectionTab.saved": "SAVED CONNECTIONS",
+ "connectionTab.new": "+ New Connection",
+ "schema.database": "DATABASE",
+ "schema.search": "Search tables, columns...",
+ "schema.loading": "Searching tables, columns...",
+ "schema.noConnection": "No Connection",
+ "schema.noConnectionHint": "Connect to a database to see tables, columns, and relationships",
+ "schema.emptyNoTables": "No tables found",
+ "fileHistory.title": "Save/Load Version History",
+ "fileHistory.reload": "Reload",
+ "fileHistory.restoreSelected": "Restore selected",
+ "fileHistory.empty": "No local versions yet",
+ "fileHistory.emptyHint": "Save this file to generate version history.",
+ "preview.title": "Data Preview",
+ "preview.subtitle": "Review data and diagnostics before continuing",
+ "preview.run": "Run",
+ "preview.cancel": "Cancel",
+ "preview.tab.preview": "Preview",
+ "preview.tab.sql": "SQL",
+ "preview.close": "Close preview",
+ "preview.running": "Running preview query… ",
+ "preview.clickCancel": "Click Cancel to stop",
+ "preview.cancelled": "Query cancelled",
+ "preview.runAgain": "Press Run to execute again",
+ "preview.failed": "Preview execution failed",
+ "preview.technical": "TECHNICAL DETAILS",
+ "preview.noData": "No data yet",
+ "preview.f3Hint": "Press F3 or Space to run the current query",
+ "sqlImporter.title": "Import SQL to Graph",
+ "sqlImporter.subtitle": "Paste a SELECT statement — nodes are created automatically",
+ "sqlImporter.sqlStatement": "SQL STATEMENT",
+ "sqlImporter.supported": "Supported: ",
+ "sqlImporter.import": "Import",
+ "sqlImporter.report": "CONVERSION REPORT",
+ "sqlEditor.mutation.dialogTitle": "変更の確認",
+ "sqlEditor.mutation.dialogSubtitle": "実行を確定する前に影響を確認してください",
+ "search.empty": "No nodes found",
+ "search.emptyHint": "Try searching for UPPER, JSON, CAST, AND…",
+ "search.shortcut": "⇧A",
+ "search.spawn": "Spawn",
+ "commandPalette.empty": "検索に一致するコマンドがありません",
+ "commandPalette.search": "コマンド検索",
+ "commandPalette.shortcut": "CTRL+SHIFT+P",
+ "commandPalette.execute": "実行",
+ "context.editCte": "Edit Selected CTE",
+ "context.editViewSubcanvas": "Edit View Subcanvas",
+ "explain.title": "Explain Plan",
+ "explain.sql": "SQL",
+ "explain.option.analyze": "解析",
+ "explain.option.buffers": "バッファ",
+ "explain.badge.simulated": "シミュレーション",
+ "explain.timing.planning": "計画:",
+ "explain.timing.execution": "実行:",
+ "explain.section.snapshotComparison": "スナップショット比較",
+ "explain.section.indexRecommendations": "インデックスの推奨",
+ "explain.section.history": "履歴",
+ "explain.detail.estimated": "推定",
+ "explain.detail.actual": "実測",
+ "explain.detail.error": "誤差",
+ "explain.detail.time": "時間",
+ "explain.detail.loops": "ループ",
+ "explain.rerun": "Re-run",
+ "explain.alertSuffix": " expensive operation(s) detected — consider adding indexes",
+ "explain.running": "Running EXPLAIN…",
+ "explain.failed": "⚠ EXPLAIN failed",
+ "explain.noPlan": "No plan yet",
+ "explain.rerunHint": "Press Re-run to execute EXPLAIN",
+ "explain.header.operation": "操作",
+ "explain.header.cost": "コスト",
+ "explain.header.rows": "行数",
+ "explain.header.alert": "警告",
+ "explain.mode.list": "リスト",
+ "explain.mode.tree": "ツリー",
+ "explain.action.snapshot": "スナップショットを保存",
+ "explain.action.copyJson": "JSONをコピー",
+ "explain.action.copyText": "テキストをコピー",
+ "explain.action.saveJson": ".json を保存",
+ "explain.action.openDalibo": "Daliboで開く",
+ "explain.legend.seqscan": "SEQ SCAN — full table read, no index",
+ "explain.legend.sort": "SORT — in-memory sort",
+ "explain.legend.hash": "HASH — hash join",
+ "explain.escClose": "Esc to close",
+ "flowVersion.title": "Flow Version History",
+ "flowVersion.subtitle": "Create checkpoints, compare versions and restore",
+ "flowVersion.watermark": "Checkpoint label (optional)…",
+ "flowVersion.saveCheckpoint": "Save Checkpoint",
+ "flowVersion.compareMode": "Compare Mode",
+ "flowVersion.selectBase": "Select BASE version (from):",
+ "flowVersion.clickAny": "Then click any version in the list below to compare.",
+ "flowVersion.noCheckpoints": "No checkpoints yet",
+ "flowVersion.noCheckpointsHint": "Save a checkpoint above to begin tracking versions.",
+ "flowVersion.restore": "Restore",
+ "flowVersion.diffResults": "Diff Results",
+ "benchmark.title": "Query Benchmark",
+ "benchmark.subtitle": "Measures avg / median / p95 latency over N iterations",
+ "benchmark.sql": "SQL being benchmarked",
+ "benchmark.runLabel": "Run label",
+ "benchmark.runLabelWatermark": "Run 1",
+ "benchmark.iterations": "Iterations (1–100)",
+ "benchmark.warmup": "Warm-up passes (0–10)",
+ "benchmark.interval": "Interval between runs (ms)",
+ "benchmark.run": "Run Benchmark",
+ "benchmark.cancel": "Cancel",
+ "benchmark.clearHistory": "Clear History",
+ "benchmark.latest": "LATEST RESULT",
+ "benchmark.avg": "AVG",
+ "benchmark.median": "MEDIAN",
+ "benchmark.min": "MIN",
+ "benchmark.max": "MAX",
+ "benchmark.iterationsAt": " iterations · run at ",
+ "benchmark.history": "HISTORY",
+ "benchmark.header.label": "ラベル",
+ "benchmark.header.avg": "平均",
+ "benchmark.header.median": "中央値",
+ "benchmark.header.min": "最小",
+ "benchmark.header.max": "最大",
+ "benchmark.itersSuffix": " iters",
+ "diagnostics.title": "App Diagnostics",
+ "diagnostics.run": "Run",
+ "diagnostics.running": "Running checks…",
+ "diagnostics.ok": "OK",
+ "diagnostics.warning": "Warning",
+ "diagnostics.error": "Error",
+ "diagnostics.tooltip.rerun": "Re-run all checks",
+ "diagnostics.tooltip.copy": "Copy diagnostic report to clipboard",
+ "diagnostics.tooltip.close": "Close (Esc)",
+ "autoJoin.title": "Auto-Join Suggestions",
+ "autoJoin.titleForTable": "Auto-Join suggestions for {0}",
+ "autoJoin.acceptAll": "Accept All",
+ "autoJoin.accept": "Accept",
+ "autoJoin.skip": "Skip",
+ "autoJoin.allHandled": "All suggestions handled",
+ "autoJoin.joinKeyword": "JOIN",
+ "autoJoin.confidence.fkConstraint": "FK Constraint",
+ "autoJoin.confidence.fkReverse": "FK (Reverse)",
+ "autoJoin.confidence.namingMatch": "Naming Match",
+ "autoJoin.confidence.weakMatch": "Weak Match",
+ "autoJoin.runSelected": "Auto-Join Selected",
+ "autoJoin.noSimilarityTitle": "No automatic join found",
+ "autoJoin.noSimilarityDetails": "Choose the columns manually to create a simple join.",
+ "autoJoin.appliedTitle": "Auto-join applied",
+ "autoJoin.manual.title": "Create Manual Join",
+ "autoJoin.manual.subtitle": "No reliable similarity was found. Select one column from each table.",
+ "autoJoin.manual.leftColumn": "Left column",
+ "autoJoin.manual.rightColumn": "Right column",
+ "autoJoin.manual.joinType": "Join type",
+ "autoJoin.manual.operator": "Operator",
+ "autoJoin.manual.confirm": "Create join",
+ "autoJoin.manual.noCompatible": "No compatible columns for the selected left pin type.",
+ "autoJoin.manualJoinCreatedTitle": "Manual join created",
+ "autoJoin.manualJoinFailedTitle": "Manual join could not be created",
+ "autoJoin.manualJoinFailedDetails": "Check selected columns and existing joins, then try again.",
+ "autoJoin.multipleCandidatesTitle": "Multiple join candidates found",
+ "autoJoin.multipleCandidatesDetails": "{0} possible combinations were found. Confirm which columns should be used.",
+ "autoJoin.suggestionsFoundTitle": "Auto-join suggestions available",
+ "autoJoin.suggestionsFoundDetails": "{0} suggestion(s) found. Select two tables and run Auto-Join Selected.",
+ "property.outputAlias": "OUTPUT ALIAS",
+ "property.sourceAlias": "SOURCE ALIAS",
+ "property.aliasWatermark": "e.g. MyColumn (optional)",
+ "property.parameters": "PARAMETERS",
+ "property.enabled": "Enabled",
+ "property.datetimeWatermark": "YYYY-MM-DDTHH:mm:ss or leave empty",
+ "property.dateWatermark": "YYYY-MM-DD or leave empty",
+ "property.apply": "Apply",
+ "property.inputPins": "INPUT PINS",
+ "property.outputPins": "OUTPUT PINS",
+ "property.sqlTrace": "SQL TRACE",
+ "property.live": "live",
+ "node.numericValue": "Numeric Value",
+ "node.stringValue": "String Value",
+ "node.enterText": "Enter text",
+ "node.datetimeValue": "DateTime Value",
+ "node.valueLabel": "Value:",
+ "node.noInputs": "No inputs",
+ "node.loadingSample": "Loading sample…",
+ "node.previewFailed": "⚠ Preview failed",
+ "node.sampleRowsHint": "5 sample rows · demo data",
+ "sidebar.tab.nodes": "ノード",
+ "sidebar.tab.connection": "接続",
+ "sidebar.tab.schema": "スキーマ",
+ "sidebar.tab.diagnostics": "診断",
+ "sidebar.addNode": "+ Add Node (⇧A)",
+ "sidebar.previewF3": "Preview (F3)",
+ "nodesList.search": "Search nodes...",
+ "search.watermark": "Search nodes… (Esc to close)",
+ "search.snippets": "★ SNIPPETS",
+ "commandPalette.watermark": "コマンドを実行…(Esc で閉じる)",
+ "tooltip.newCanvas": "New canvas (Ctrl+N)",
+ "tooltip.openCanvas": "Open canvas (Ctrl+O)",
+ "tooltip.saveCanvas": "Save canvas (Ctrl+S)",
+ "tooltip.fileHistory": "Local save/load history (Ctrl+Alt+H)",
+ "tooltip.zoomOut": "Zoom out (Ctrl+-)",
+ "tooltip.zoomIn": "Zoom in (Ctrl++)",
+ "tooltip.fitToScreen": "Fit to screen (Ctrl+0)",
+ "tooltip.autoLayout": "Auto Layout — arrange nodes into logical columns (Ctrl+L, Ctrl+Z to undo)",
+ "tooltip.snapToGrid": "Toggle snap to grid (Ctrl+G)",
+ "tooltip.dataPreview": "Data preview (F3)",
+ "tooltip.toggleLanguage": "Toggle language (pt-BR / en-US)",
+ "tooltip.appDiagnostics": "App Diagnostics (self-check)",
+ "tooltip.keyboardShortcuts": "Keyboard shortcuts (F1)",
+ "tooltip.cancelRunningQuery": "Cancel the running query",
+ "tooltip.closeEsc": "Close (Esc)",
+ "tooltip.recheckConnectionHealth": "Re-check connection health",
+ "tooltip.deleteConnection": "Delete connection",
+ "tooltip.testConnection": "Test connection",
+ "tooltip.saveConnection": "Save connection",
+ "tooltip.activateConnection": "Activate this connection",
+ "tooltip.toggleDataSamplePreview": "Toggle data sample preview",
+ "tooltip.liveSqlMutatingBlocked": "This SQL contains a data-mutating command and cannot be run in Safe Preview Mode",
+ "tooltip.copySql": "Copy SQL to clipboard",
+ "tooltip.formatSql": "Format SQL",
+ "tooltip.openBenchmark": "Open Query Benchmark (measure avg / median / p95 latency)",
+ "tooltip.openExplainPlan": "Open Explain Plan inspector — visualise the query execution plan",
+ "tooltip.switchToQueryMode": "Switch to Query canvas",
+ "tooltip.switchToDdlMode": "Switch to DDL canvas",
+ "tooltip.autoJoinSelected": "Try auto-join between the two selected tables",
+ "tooltip.pins.inputs": "Inputs",
+ "tooltip.pins.outputs": "Outputs",
+ "tooltip.pins.none": "None",
+ "tooltip.tableColumns": "Columns",
+ "tooltip.tableColumns.none": "No detailed columns",
+ "window.minimize": "Minimize window",
+ "window.maximizeRestore": "Maximize/restore window",
+ "window.close": "Close window",
+ "menu.newDiagram": "New diagram",
+ "menu.openFile": "Open file",
+ "menu.save": "Save",
+ "menu.fileHistory": "File history",
+ "menu.shortcuts": "Keyboard shortcuts",
+ "menu.settings": "Settings",
+ "menu.importDdlSchema": "Import DDL schema",
+ "menu.viewDdlSql": "View DDL SQL",
+ "menu.executeDdl": "Execute DDL",
+ "menu.backToStart": "Back to start",
+ "toast.ddlExecuteFailed": "Failed to execute DDL.",
+ "toast.ddlOpenFailed": "Failed to open DDL SQL.",
+ "toast.ddlImportFailed": "Failed to import schema into DDL.",
+ "toast.ddlConnectToImportSchema": "Connect to a database to import schema into the DDL canvas.",
+ "toast.ddlNoTablesFound": "No tables found to import in DDL mode.",
+ "toast.ddlSchemaImported": "Schema imported into the DDL canvas.",
+ "toast.ddlImportSummary": "{0} table(s), {1} column(s), {2} FK(s), {3} unique index(es).",
+ "toast.ddlConnectToImportTable": "Connect to a database to import tables into the DDL canvas.",
+ "toast.ddlTableAlreadyExists": "Table '{0}' already exists in the DDL canvas.",
+ "toast.ddlTableImported": "Table imported into the DDL canvas.",
+ "toast.ddlTableImportSummary": "Nodes: +{0}, connections: +{1}, FKs: +{2}.",
+ "toast.ddlNoActiveConnection": "No active connection to execute DDL.",
+ "toast.ddlExecutedSuccess": "DDL executed successfully.",
+ "toast.ddlExecutedWithIssues": "DDL executed with issues.",
+ "toast.switchToDdl": "Switch to DDL mode to generate SQL.",
+ "toast.ddlInvalid": "Invalid DDL. Fix errors before continuing.",
+ "toast.ddlNoStatements": "No DDL statements were generated in the canvas.",
+ "toast.previewOpenFailed": "Failed to open preview.",
+ "tab.switchFailed": "Failed to switch tab: {0}",
+ "settings.status.darkApplied": "Dark theme applied.",
+ "settings.status.lightApplied": "Light theme applied.",
+ "settings.status.snapUpdated": "Snap updated: {0}.",
+ "settings.status.languageToggled": "Language toggled.",
+ "settings.status.languageSelected": "Language selected: {0}.",
+ "settings.status.themeEditorReady": "Theme editor ready. Apply to save and use this theme.",
+ "settings.section.appearance.title": "Themes",
+ "settings.section.languageRegion.title": "言語と地域",
+ "settings.section.dateTime.title": "日付と時刻",
+ "settings.section.keyboard.title": "キーボードショートカット",
+ "settings.section.privacy.title": "プライバシー",
+ "settings.section.notification.title": "通知",
+ "settings.section.accessibility.title": "アクセシビリティ",
+ "settings.section.default.title": "設定",
+ "settings.section.appearance.subtitle": "スタイルを選択するか、テーマをカスタマイズします",
+ "settings.section.languageRegion.subtitle": "言語と地域フォーマットを管理します",
+ "settings.section.keyboard.subtitle": "コマンドパレットとキャンバス実行で使うキーボードショートカットをカスタマイズします。",
+ "settings.section.wip.subtitle": "作業中です。",
+ "settings.section.default.subtitle": "アプリケーション設定",
+ "settings.general": "General",
+ "settings.nav.appearance": "Appearance",
+ "settings.theme.light": "ライトモード",
+ "settings.theme.dark": "ダークモード",
+ "settings.theme.system": "システム設定",
+ "settings.gridSnap.title": "Grid Snap",
+ "settings.gridSnap.subtitle": "Controls node snapping on the canvas.",
+ "settings.language.subtitle": "アプリの言語を選択してください。",
+ "settings.language.toggle": "言語を切り替える",
+ "settings.language.option.ptBR": "ポルトガル語(ブラジル)",
+ "settings.language.option.enUS": "英語(米国)",
+ "settings.language.option.esES": "スペイン語(スペイン)",
+ "settings.language.option.ruRU": "ロシア語",
+ "settings.language.option.jaJP": "日本語",
+ "settings.language.option.zhTW": "繁体字中国語",
+ "settings.themeJson.title": "テーマ JSON",
+ "settings.themeJson.subtitle": "テーマ JSON を貼り付けて、即時に適用・保存します。",
+ "settings.themeJson.apply": "JSON を適用",
+ "settings.themeJson.restoreDefault": "既定テーマに戻す",
+ "mode.query": "Query",
+ "mode.ddl": "DDL",
+ "sidebar.left.close": "Close left sidebar",
+ "sidebar.left.open": "Reopen left sidebar",
+ "sidebar.right.close": "Close right sidebar",
+ "sidebar.right.open": "Reopen right sidebar",
+ "connection.completedTitle": "Connection completed",
+ "connection.clearCanvasPrompt": "Do you want to clear the current canvas to start with the new connection?",
+ "connection.close": "Close connection manager",
+ "connection.refreshHealth": "Refresh connection health",
+ "common.details": "Details",
+ "common.cancel": "Cancel",
+ "common.keep": "Keep",
+ "common.clear": "Clear",
+ "zoom.out": "Zoom out",
+ "zoom.in": "Zoom in",
+ "zoom.fit": "Fit zoom to screen",
+ "zoom.level": "Zoom level",
+ "settings.theme.mode": "テーマモード",
+ "diagnostics.category.canvas": "Canvas Integrity",
+ "diagnostics.category.output": "Output & Execution",
+ "diagnostics.category.session": "Session & Safety",
+ "diagnostics.category.notice": "Runtime Notices",
+ "diagnostics.summary.ok": "All systems OK",
+ "diagnostics.summary.warningCount": "{0} warning(s) detected",
+ "diagnostics.summary.errorCount": "{0} error(s) detected",
+ "diagnostics.canvasMigration": "Canvas Migration",
+ "diagnostics.recommendation.resaveFile": "Re-save the file to update it to the latest schema version.",
+ "diagnostics.canvasState.name": "Canvas State",
+ "diagnostics.canvasState.recommendation": "Add at least one {0} and one {1}",
+ "diagnostics.canvasState.empty": "Canvas is empty - no nodes present",
+ "diagnostics.canvasState.counts": "{0} node(s), {1} connection(s)",
+ "diagnostics.validation.name": "Validation Errors",
+ "diagnostics.validation.recommendation": "Fix highlighted nodes before running output preview",
+ "diagnostics.validation.errorWithWarnings": "{0} error(s) and {1} warning(s) in the graph",
+ "diagnostics.validation.warningOnly": "{0} warning(s) in the graph",
+ "diagnostics.validation.none": "No validation issues",
+ "diagnostics.orphan.name": "Orphan Nodes",
+ "diagnostics.orphan.recommendation": "Use the orphan cleanup action to remove unused nodes",
+ "diagnostics.orphan.count": "{0} node(s) not connected to any output",
+ "diagnostics.orphan.none": "No orphan nodes detected",
+ "diagnostics.naming.name": "Naming Conventions",
+ "diagnostics.naming.recommendation": "Use auto-fix alias naming when conformance is below 100%",
+ "diagnostics.naming.conformance": "Naming conformance: {0}%",
+ "diagnostics.naming.ok": "All aliases follow naming conventions (100%)",
+ "diagnostics.queryCompilation.name": "Live SQL Compilation",
+ "diagnostics.queryCompilation.recommendation": "Review SQL diagnostics in output when errors/warnings are reported.",
+ "diagnostics.queryCompilation.errorFallback": "Live SQL compilation reported errors.",
+ "diagnostics.queryCompilation.warningCounts": "{0} diagnostic item(s), {1} guardrail warning(s).",
+ "diagnostics.queryCompilation.ok": "Live SQL compiled without diagnostics.",
+ "diagnostics.previewSafety.name": "Preview Safety",
+ "diagnostics.previewSafety.recommendation": "Preview executes read-only statements only.",
+ "diagnostics.previewSafety.blocked": "Current SQL is mutating and blocked by Safe Preview mode.",
+ "diagnostics.previewSafety.ok": "Preview safety checks passed.",
+ "diagnostics.previewExecution.name": "Preview Execution",
+ "diagnostics.previewExecution.recommendation": "Run preview and inspect diagnostics for execution/runtime errors.",
+ "diagnostics.previewExecution.failed": "Preview execution failed.",
+ "diagnostics.previewExecution.cancelled": "Preview execution was cancelled.",
+ "diagnostics.previewExecution.done": "{0} row(s) in {1}ms.",
+ "diagnostics.previewExecution.none": "No preview execution issues detected.",
+ "diagnostics.ddlCompilation.name": "DDL Compilation",
+ "diagnostics.ddlCompilation.recommendation": "Fix DDL compile diagnostics before execution.",
+ "diagnostics.ddlCompilation.failed": "DDL compilation failed.",
+ "diagnostics.ddlCompilation.warningCount": "{0} warning(s) reported by DDL compiler.",
+ "diagnostics.ddlCompilation.ok": "DDL compilation succeeded.",
+ "diagnostics.ddlOutput.name": "DDL Output",
+ "diagnostics.ddlOutput.recommendation": "Add/complete DDL nodes until at least one statement is generated.",
+ "diagnostics.ddlOutput.none": "No DDL statements generated yet.",
+ "diagnostics.ddlOutput.lines": "{0} line(s) of DDL generated.",
+ "diagnostics.undo.name": "Undo History",
+ "diagnostics.undo.recommendation": "History is in-memory only; save your canvas regularly.",
+ "diagnostics.undo.saved": "Canvas is saved (no unsaved changes).",
+ "diagnostics.undo.unsavedDeep": "Unsaved changes with {0} undo steps.",
+ "diagnostics.undo.unsaved": "Unsaved changes - {0} undo step(s) available.",
+ "diagnostics.report.title": "AkkornStudio - Diagnostic Report",
+ "diagnostics.report.generated": "Generated",
+ "diagnostics.report.overall": "Overall",
+ "diagnostics.report.details": "Details",
+ "diagnostics.report.recommendation": "Recommendation",
+ "diagnostics.report.lastCheck": "Last Check",
+ "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
+ "node.datetimeFormat": "YYYY-MM-DDTHH:mm:ss",
+ "preview.providerLabel": "Provider",
+ "preview.ddlDiagnosticsHint": "Error/warning details are available in Diagnostics.",
+ "preview.schemaAnalysis.run": "Run Analysis",
+ "preview.schemaAnalysis.cancel": "Cancel",
+ "preview.schemaAnalysis.issues": "Issues",
+ "preview.schemaAnalysis.clearFilters": "Clear Filters",
+ "preview.schemaAnalysis.clearBlacklist": "Clear Blacklist",
+ "preview.schemaAnalysis.severity": "Severity",
+ "preview.schemaAnalysis.severity.info": "Info",
+ "preview.schemaAnalysis.severity.warning": "Warning",
+ "preview.schemaAnalysis.severity.critical": "Critical",
+ "preview.schemaAnalysis.rule": "Rule",
+ "preview.schemaAnalysis.rule.fkCatalogInconsistent": "FK catalog inconsistent",
+ "preview.schemaAnalysis.rule.missingFk": "Missing FK",
+ "preview.schemaAnalysis.rule.namingConventionViolation": "Naming convention violation",
+ "preview.schemaAnalysis.rule.lowSemanticName": "Low semantic name",
+ "preview.schemaAnalysis.rule.missingRequiredComment": "Missing required comment",
+ "preview.schemaAnalysis.rule.nf1HintMultiValued": "1NF hint: multi-valued",
+ "preview.schemaAnalysis.rule.nf2HintPartialDependency": "2NF hint: partial dependency",
+ "preview.schemaAnalysis.rule.nf3HintTransitiveDependency": "3NF hint: transitive dependency",
+ "preview.schemaAnalysis.minConfidence": "Min Confidence",
+ "preview.schemaAnalysis.tableFilter": "Table Filter",
+ "preview.schemaAnalysis.tableFilterWatermark": "schema.table",
+ "preview.schemaAnalysis.ignore": "Execution Filters",
+ "preview.schemaAnalysis.ignoreViews": "Ignore views and materialized views",
+ "preview.schemaAnalysis.blacklist": "Table blacklist",
+ "preview.schemaAnalysis.blacklistAdd": "Add",
+ "preview.schemaAnalysis.blacklistRemove": "Remove selected",
+ "preview.schemaAnalysis.ignoreTable.placeholder": "schema.table",
+ "preview.schemaAnalysis.details": "Details",
+ "preview.schemaAnalysis.evidence": "Evidence",
+ "preview.schemaAnalysis.suggestions": "Suggestions",
+ "preview.schemaAnalysis.ruleDiagnostics": "Rule Diagnostics",
+ "preview.schemaAnalysis.sqlCandidates": "SQL Candidates",
+ "preview.schemaAnalysis.copySql": "Copy SQL",
+ "preview.schemaAnalysis.applyToCanvas": "Apply to Canvas",
+ "preview.schemaAnalysis.summary.issues": "Issues:",
+ "preview.schemaAnalysis.summary.rawPrefix": "(raw:",
+ "preview.schemaAnalysis.summary.critical": "| Critical:",
+ "preview.schemaAnalysis.summary.warning": "| Warning:",
+ "preview.schemaAnalysis.summary.info": "| Info:",
+ "preview.schemaAnalysis.state.metadataUnavailable": "Metadata unavailable for structural analysis.",
+ "preview.schemaAnalysis.state.cancelled": "Analysis cancelled by the user.",
+ "preview.schemaAnalysis.state.partialTimeout": "Analysis finished partially due to timeout.",
+ "preview.schemaAnalysis.state.failed": "Structural analysis failed.",
+ "preview.schemaAnalysis.state.empty": "No inferable structural issue was detected.",
+ "preview.schemaAnalysis.state.noFilterMatch": "No issue matches the selected filters.",
+ "preview.schemaAnalysis.state.noIssueSelected": "No issue selected.",
+ "preview.schemaAnalysis.state.noSqlCandidate": "No SQL candidate available.",
+ "preview.schemaAnalysis.actionBlockedTooltip": "Action unavailable for the current risk level or capability.",
+ "common.navigate": "Navigate",
+ "common.close": "Close",
+ "common.esc": "Esc",
+ "common.ms": "ms",
+ "common.zero": "0",
+ "diagnostics.tip": "Tip: check Diagnostics whenever preview/output reports warnings or errors.",
+ "nodesList.empty": "No nodes found",
+ "nodesList.emptyHint": "Adjust the search term to explore available types",
+ "schema.emptyFiltered": "No objects found for the current filter",
+ "start.lastSnapshot": "Last snapshot",
+ "app.brandBadge": "VS",
+ "property.tab.properties": "Properties",
+ "property.tab.projectSettings": "Project Settings",
+ "property.nodeType": "NODE TYPE",
+ "property.selectNodeHint": "Select a node to edit its properties.",
+ "property.namingConventions": "Naming Conventions",
+ "property.aliasConvention": "Alias convention",
+ "property.enforceAliasNaming": "Enforce alias naming",
+ "property.warnReservedSql": "Warn on reserved SQL keywords",
+ "property.maxAliasLength": "Max alias length",
+ "property.maxAliasLengthDefault": "64",
+ "property.namingSettingsHint": "These settings are project-scoped and are used by naming and validation helpers.",
+ "start.tips": "Tips",
+ "start.tips.quick": "Quick tips",
+ "start.tips.item1": "1. Click New Diagram to start from scratch.",
+ "start.tips.item2": "2. Use templates to speed up prototyping.",
+ "start.tips.item3": "3. Open saved connections to load real tables.",
+ "start.tips.shortcut": "Shortcut: CTRL+SHIFT+P opens the command palette.",
+ "start.workspace": "WORKSPACE",
+ "start.resumeTitle": "Continue where you left off",
+ "start.resumeSubtitle": "Quickly resume a recent project or start a new diagram.",
+ "start.chip.quickFlow": "Quick flow",
+ "start.chip.templates": "Templates",
+ "start.chip.connections": "Connections",
+ "start.savedConnectionsTitle": "Saved Connections",
+ "start.savedConnectionsSubtitle": "Connect quickly to a database to load schema and tables.",
+ "start.noConnectionsTitle": "No connections configured yet",
+ "start.noConnectionsSubtitle": "Create a connection to explore real tables in the editor.",
+ "start.newConnection": "+ New Connection",
+ "start.recentProjectsTitle": "Recent Projects",
+ "start.searchRecent": "Search recent project...",
+ "start.quickActions": "Quick actions",
+ "start.quickActionsSubtitle": "Open an existing file or start a new diagram.",
+ "start.noRecentTitle": "No recent projects yet",
+ "start.noRecentSubtitle": "Use the quick actions card above to get started.",
+ "start.exploreTemplates": "Explore templates",
+ "start.templatesFavoritesHint": "Favorites on top",
+ "start.favoriteTemplate": "Favorite template",
+ "node.columnSetPreview": "ColumnSet preview",
+ "node.view": "VIEW",
+ "node.tableDefinition": "Table Definition",
+ "node.join": "JOIN",
+ "node.window.addPartition": "Add PARTITION BY slot",
+ "node.window.removePartition": "Remove PARTITION BY slot",
+ "node.window.addOrder": "Add ORDER BY slot",
+ "node.window.removeOrder": "Remove ORDER BY slot",
+ "sql.keyword.select": "SELECT",
+ "sql.keyword.from": "FROM",
+ "sql.keyword.join": "JOIN",
+ "sql.keyword.where": "WHERE",
+ "sql.keyword.limit": "LIMIT",
+ "sqlImporter.close": "Close SQL importer",
+ "sqlImporter.report.imported": "Imported",
+ "sqlImporter.report.partial": "Partial",
+ "sqlImporter.report.skipped": "Skipped",
+ "benchmark.close": "Close benchmark",
+ "benchmark.p95": "P95",
+ "benchmark.n": "N",
+ "liveSql.safePreview": "SAFE PREVIEW MODE",
+ "liveSql.title": "LIVE SQL",
+ "liveSql.blocked": "BLOCKED",
+ "liveSql.copy": "Copy",
+ "liveSql.format": "Format",
+ "liveSql.benchmark": "Benchmark",
+ "liveSql.explain": "Explain",
+ "liveSql.actionsHint": "Performance tools",
+ "ddl.dialog.title": "Execute DDL",
+ "ddl.dialog.execute": "Execute",
+ "ddl.dialog.cancel": "Cancel",
+ "ddl.dialog.close": "Close",
+ "ddl.dialog.stopOnError": "Stop on first failure",
+ "ddl.dialog.confirmDestructive": "I confirm execution of destructive statements (DROP TABLE)",
+ "ddl.dialog.reviewBeforeRun": "Review the DDL script before confirming.",
+ "ddl.dialog.confirmQuestion": "Confirm DDL execution on the connected database?",
+ "ddl.dialog.irreversibleWarning": "This action can change the schema irreversibly.",
+ "ddl.dialog.mustConfirmDestructive": "Confirm destructive execution to continue.",
+ "ddl.dialog.executing": "Executing...",
+ "ddl.execute.result.summary": "Statements: {0} | Success: {1} | Failures: {2} | Time: {3:0}ms",
+ "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
+ "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
+ "ddl.execute.result.failed": "Failed to execute DDL.",
+ "ddl.execute.result.cancelled": "Execution cancelled by the user.",
+ "ddl.execute.result.cancelledDetails": "DDL execution was interrupted before completion.",
+ "context.deleteSingle": "Delete {0}",
+ "context.deleteMultiple": "Delete {0} nodes",
+ "context.bringForward": "Bring Forward (Ctrl+PgUp)",
+ "context.sendBackward": "Send Backward (Ctrl+PgDown)",
+ "context.bringToFront": "Bring to Front (Ctrl+Shift+PgUp)",
+ "context.sendToBack": "Send to Back (Ctrl+Shift+PgDown)",
+ "context.normalizeLayers": "Normalize Layers",
+ "context.deleteWire": "Delete wire",
+ "context.addNode": "Add Node (Shift+A)",
+ "context.undoWithDescription": "Undo {0}",
+ "context.redo": "Redo",
+ "shortcuts.windowTitle": "Keyboard Shortcuts",
+ "shortcuts.headerTitle": "AkkornStudio - Shortcuts",
+ "shortcuts.headerHint": "Tip: use CTRL+SHIFT+P to open the Command Palette and search commands.",
+ "shortcuts.filterWatermark": "Filter shortcuts by key or action...",
+ "shortcuts.resultCount": "{0} shortcuts",
+ "shortcuts.resultFilter": "{0} result(s) for \"{1}\"",
+ "shortcuts.noneFound": "No shortcuts found.",
+ "shortcuts.section.fileGeneral": "ファイルと一般",
+ "shortcuts.section.editing": "編集",
+ "shortcuts.section.canvasNavigation": "キャンバスとナビゲーション",
+ "shortcuts.section.zoomPanPrecision": "ズーム、パン、精密操作",
+ "shortcuts.section.previewInspection": "プレビューと検査",
+ "shortcuts.key.deleteOrBackspace": "Del または Backspace",
+ "shortcuts.key.middleDrag": "中ボタン + ドラッグ",
+ "shortcuts.key.rightDrag": "右ボタン + ドラッグ",
+ "shortcuts.key.spaceDrag": "Space + ドラッグ",
+ "shortcuts.key.altLeftDrag": "Alt + 左ドラッグ",
+ "shortcuts.key.arrows": "矢印キー",
+ "shortcuts.key.shiftArrows": "Shift + 矢印キー",
+ "shortcuts.action.openShortcutScreen": "このショートカット画面を開く",
+ "shortcuts.action.newCanvas": "新しいキャンバス",
+ "shortcuts.action.openFile": "ファイルを開く",
+ "shortcuts.action.save": "保存",
+ "shortcuts.action.saveAs": "名前を付けて保存",
+ "shortcuts.action.commandPalette": "コマンドパレット",
+ "shortcuts.action.undo": "元に戻す",
+ "shortcuts.action.redo": "やり直し",
+ "shortcuts.action.selectAll": "すべて選択",
+ "shortcuts.action.deleteSelection": "選択を削除",
+ "shortcuts.action.closeOverlayCancel": "オーバーレイを閉じる / 操作をキャンセル",
+ "shortcuts.action.openNodeSearch": "ノード検索を開く",
+ "shortcuts.action.resetViewport": "ビューポートをリセット",
+ "shortcuts.action.centerSelection": "選択を中央に配置",
+ "shortcuts.action.fitSelection": "選択にフィット",
+ "shortcuts.action.autoLayout": "自動レイアウト",
+ "shortcuts.action.toggleSnapToGrid": "グリッドスナップ切替",
+ "shortcuts.action.bringForward": "前面へ",
+ "shortcuts.action.sendBackward": "背面へ",
+ "shortcuts.action.bringToFront": "最前面へ",
+ "shortcuts.action.sendToBack": "最背面へ",
+ "shortcuts.action.zoomInOut": "ズームイン / アウト",
+ "shortcuts.action.pan": "パン",
+ "shortcuts.action.temporaryPan": "一時パン",
+ "shortcuts.action.alternatePan": "代替パン",
+ "shortcuts.action.fineNudge": "選択を微調整移動",
+ "shortcuts.action.fastNudge": "高速移動",
+ "shortcuts.action.togglePreview": "データプレビュー切替",
+ "shortcuts.action.explainPlan": "実行計画",
+ "shortcuts.action.runPreview": "プレビュー実行",
+ "shortcuts.action.connectionManager": "接続マネージャー",
+ "shortcuts.action.flowVersionHistory": "フローバージョン履歴",
+ "shortcuts.resetAll": "すべてリセット",
+ "shortcuts.customized": "カスタム",
+ "shortcuts.default": "デフォルト",
+ "shortcuts.apply": "適用",
+ "shortcuts.reset": "リセット",
+ "shortcuts.status.resetAllSuccess": "すべてのショートカットをデフォルトに戻しました。",
+ "shortcuts.status.updated": "ショートカットを更新しました。",
+ "shortcuts.status.reset": "ショートカットをデフォルトに戻しました。",
+ "shortcuts.status.updateFailed": "ショートカットを更新できませんでした。",
+ "toast.severity.success": "Success",
+ "toast.severity.warning": "Warning",
+ "toast.severity.error": "Error",
+ "toast.details.success": "Success Details",
+ "toast.details.warning": "Warning Details",
+ "toast.details.error": "Error Details",
+ "diagnostics.area.cteEditor": "CTE Editor",
+ "diagnostics.area.viewEditor": "View Editor",
+ "diagnostics.area.subEditor": "Sub-editor",
+ "diagnostics.cteEditor.restoreParentFailed": "Failed to restore the parent canvas. CTE edits were discarded.",
+ "diagnostics.recommendation.reloadFileIfNeeded": "Reload the file if needed.",
+ "diagnostics.viewEditor.exitFailed": "Could not exit: {0}",
+ "diagnostics.viewEditor.canvasIncomplete": "the canvas is incomplete.",
+ "diagnostics.viewEditor.exitRecommendation": "Connect a valid ResultOutput or use the discard command.",
+ "diagnostics.viewEditor.restoreParentFailed": "Failed to restore the parent canvas. The subgraph was discarded.",
+ "diagnostics.subEditor.executeFailed": "Failed to execute editor action: {0}",
+ "diagnostics.subEditor.executeRecommendation": "Try again. If it persists, reload the canvas.",
+ "diagnostics.canvasMigration.openWarning": "Open: {0}",
+ "diagnostics.canvasMigration.sessionRestoreWarning": "Session restore: {0}",
+ "diagnostics.canvasMigration.versionRestoreWarning": "Version restore: {0}",
+ "diagnostics.recommendation.resaveLatestSchema": "Review diagnostics and re-save the canvas to persist the latest schema.",
+ "diagnostics.recommendation.saveMigratedSchema": "Review diagnostics and save the canvas to persist the migrated schema.",
+ "file.saveDialog.title": "Save Canvas",
+ "file.saveDialog.suggestedName": "Query1",
+ "file.save.success": "Canvas saved successfully.",
+ "file.save.failedWithReason": "Save failed: {0}",
+ "file.openDialog.title": "Open Canvas",
+ "file.open.failedWithReason": "Open failed: {0}",
+ "file.open.success": "Canvas opened successfully.",
+ "file.open.successWithWarnings": "Canvas opened with warnings.",
+ "session.restore.failedWithReason": "Restore failed: {0}",
+ "session.restore.successWithWarnings": "Session restored with warnings.",
+ "session.restore.success": "Session restored successfully.",
+ "export.documentation.dialogTitle": "Export Flow Documentation",
+ "export.documentation.success": "Documentation exported successfully.",
+ "export.documentation.failed": "Documentation export failed.",
+ "export.failed.pathPermissionsHint": "Check file path and permissions.",
+ "export.nodeNotFound": "No {0} Export node found on the canvas. Add one via the node search menu.",
+ "export.dialogTitleByExtension": "Export as {0}",
+ "export.success": "Export completed successfully.",
+ "export.failed": "Export failed.",
+ "fileHistory.currentFile.none": "No file selected",
+ "fileHistory.status.saveFirst": "Save the canvas first to enable local history.",
+ "fileHistory.status.noneFound": "No local versions found yet. Save this file to create history entries.",
+ "fileHistory.status.countAvailable": "{0} local version(s) available.",
+ "fileHistory.restore.failedWithReason": "Restore failed: {0}",
+ "fileHistory.restore.successFrom": "Restored version from {0}.",
+ "preview.status.cancelled": "Cancelled",
+ "preview.status.error": "Error",
+ "preview.status.ready": "Ready",
+ "preview.runningWithMs": "Running... {0}ms",
+ "preview.runningWithTimeout": "Running... {0}ms (timeout: {1}s)",
+ "preview.runningSlowWithTimeout": "Running... {0}ms (timeout: {1}s) · Slow query, timeout in {2}s",
+ "explain.errorWithReason": "Explain plan error: {0}",
+ "explain.noSql": "No SQL to explain. Build a query on the canvas first.",
+ "ddl.compilationFailed": "Compilation failed",
+ "ddl.compileErrorWithReason": "DDL compile error: {0}",
+ "command.undo.name": "Undo",
+ "command.undo.description": "Undo last action",
+ "command.redo.name": "Redo",
+ "command.redo.description": "Redo last undone action",
+ "command.addNode.name": "Add Node",
+ "command.addNode.description": "Open node search menu to add a node",
+ "command.bringForward.name": "Bring Forward",
+ "command.bringForward.description": "Move selected nodes one layer forward",
+ "command.sendBackward.name": "Send Backward",
+ "command.sendBackward.description": "Move selected nodes one layer backward",
+ "command.bringToFront.name": "Bring to Front",
+ "command.bringToFront.description": "Move selected nodes to top layer",
+ "command.sendToBack.name": "Send to Back",
+ "command.sendToBack.description": "Move selected nodes to bottom layer",
+ "command.normalizeLayers.name": "Normalize Layers",
+ "command.normalizeLayers.description": "Compact node layer indices to a clean 0..N order",
+ "tooltip.cleanupOrphans": "Remove orphan nodes not connected to the output (Ctrl+Z to undo)",
+ "main.orphanSuffix": "Orphan(s)",
+ "tooltip.autoFixAliasNaming": "Fix alias naming to snake_case (Ctrl+Z to undo)",
+ "main.namingPrefix": "Naming",
+ "fileHistory.compressedLabel": "Compressed:",
+ "schema.itemsSuffix": "item(s)",
+ "property.panel.title": "Properties",
+ "property.panel.multiSelected": "{0} nodes selected",
+ "sqlImporter.status.pasteSelect": "Paste a SELECT statement above, then click Import.",
+ "sqlImporter.status.inputTooLarge": "SQL input is too large ({0:N0} chars). Limit is {1:N0}. Split the query or increase the import limit.",
+ "sqlImporter.status.parsing": "Parsing SQL...",
+ "sqlImporter.status.done": "Done - {0} imported, {1} partial, {2} skipped.",
+ "sqlImporter.status.cancelledByUser": "Import cancelled by user.",
+ "sqlImporter.status.timeout": "Import timed out after {0:0.#}s. Try a smaller query or increase timeout.",
+ "sqlImporter.status.parseError": "Parse error: {0}",
+ "diagnostics.area.undoRedoTransaction": "Undo/Redo Transaction",
+ "undoRedo.rollbackExecuted": "Rollback executed for '{0}' ({1} operation(s) reverted).",
+ "undoRedo.rollbackRecommendation": "Review the canvas state and retry the action if needed.",
+ "node.preview.noCatalog": "No catalog available",
+ "connection.error.searchMenuNotInitialized": "search menu not initialized",
+ "connection.error.timeoutReachability": "Connection timed out - check that the server is reachable and increase the timeout if needed.",
+ "connection.error.authenticationFailedForProvider": "Authentication failed - verify username and password for {0}.",
+ "connection.error.databaseNotFoundForProvider": "Database not found - confirm the database name exists on {0}.",
+ "connection.error.hostNotFound": "Host not found - check the server address and DNS resolution.",
+ "connection.error.portRefused": "Port connection refused - check the port number and that the server is running / firewall rules allow access.",
+ "connection.error.sslTls": "SSL/TLS error - check the server's SSL configuration or disable SSL for local connections.",
+ "connection.error.timeoutOverloaded": "Connection timed out - the server may be overloaded or unreachable. Try increasing the timeout.",
+ "connection.error.insufficientPrivileges": "Insufficient privileges - the user may lack permission to connect to this database.",
+ "diagnostics.area.connection": "Connection",
+ "connection.warning.canvasMayContainOldTables": "The canvas may still contain tables from a previous connection.",
+ "connection.warning.canvasMayContainOldTablesRecommendation": "Clear the canvas manually or reconnect and choose keep/clear again.",
+ "undoRedo.transaction.unnamed": "unnamed transaction",
+ "benchmark.runLabelDefault": "Run 1",
+ "benchmark.runLabelPattern": "Run {0}",
+ "benchmark.status.failedWithReason": "Benchmark failed: {0}",
+ "benchmark.status.noSql": "No SQL to benchmark - build a query first.",
+ "benchmark.status.warmupProgress": "Warm-up {0}/{1}...",
+ "benchmark.status.iterationProgress": "Iteration {0}/{1}...",
+ "benchmark.status.done": "Done - {0}",
+ "benchmark.status.cancelled": "Benchmark cancelled.",
+ "app.windowTitle": "AkkornStudio",
+ "preview.error.safePreviewBlocked": "Safe Preview Mode: data-mutating commands (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) cannot be executed in preview.",
+ "preview.error.noActiveConnection": "No active database connection. Please connect to a database first.",
+ "sqlImporter.error.selectFromNotFound": "Could not find SELECT ... FROM in the query.",
+ "sqlImporter.error.fromClauseParseFailed": "Could not parse FROM clause.",
+ "sqlImporter.error.syntaxUnterminatedString": "Syntax error at line {0}, column {1}: unterminated string literal.",
+ "sqlImporter.error.missingClosingParenthesis": "missing closing ')'",
+ "sqlImporter.error.unexpectedClosingParenthesis": "unexpected ')'",
+ "sqlImporter.error.syntaxAtLineColumn": "Syntax error at line {0}, column {1}: {2}.",
+ "errorDiagnostics.safePreview.label": "Blocked by Safe Preview Mode",
+ "errorDiagnostics.safePreview.friendly": "This SQL contains a data-mutating command and cannot be executed in preview.",
+ "errorDiagnostics.safePreview.suggestion": "Remove or replace the mutating command (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) before running preview.",
+ "errorDiagnostics.connection.label": "Connection failed",
+ "errorDiagnostics.connection.friendly": "Could not reach the database server. The host may be down, unreachable, or blocking connections.",
+ "errorDiagnostics.connection.suggestion": "Verify the server address and port, ensure the database is running, and check firewall rules.",
+ "errorDiagnostics.authorization.label": "Authorization error",
+ "errorDiagnostics.authorization.friendly": "The current credentials do not have permission to perform this operation.",
+ "errorDiagnostics.authorization.suggestion": "Confirm the database user has SELECT privileges on the target table/schema, or contact your DBA.",
+ "errorDiagnostics.timeout.label": "Query timeout",
+ "errorDiagnostics.timeout.friendly": "The query took too long to complete and was cancelled by the server or client.",
+ "errorDiagnostics.timeout.suggestion": "Add a WHERE clause or LIMIT to reduce the result set, or increase the query timeout in connection settings.",
+ "errorDiagnostics.schema.label": "Schema error",
+ "errorDiagnostics.schema.friendly": "A referenced table, column, or object could not be found in the database.",
+ "errorDiagnostics.schema.suggestion": "Check that all table/column names are spelled correctly and that the schema matches the active connection.",
+ "errorDiagnostics.syntax.label": "SQL syntax error",
+ "errorDiagnostics.syntax.friendly": "The query contains a syntax error and could not be parsed by the database engine.",
+ "errorDiagnostics.syntax.suggestion": "Review the highlighted SQL for typos, mismatched parentheses, or unsupported clauses for the active provider.",
+ "errorDiagnostics.compatibility.label": "Compatibility error",
+ "errorDiagnostics.compatibility.friendly": "A function, operator, or syntax construct is not supported by the active database provider.",
+ "errorDiagnostics.compatibility.suggestion": "Switch to the correct provider in the SQL bar, or replace the unsupported construct with an equivalent.",
+ "errorDiagnostics.unknown.label": "Unexpected error",
+ "errorDiagnostics.unknown.friendly": "An error occurred while running the preview query.",
+ "errorDiagnostics.unknown.suggestion": "Check the technical details below and verify that your canvas is configured correctly.",
+ "error.mainWindow.invalidDataContext": "MainWindow の DataContext は ShellViewModel である必要があります。",
+ "error.mainWindow.canvasNotInitialized": "CanvasViewModel が初期化されていません。",
+ "error.mainWindow.ddlPreviewUnavailable": "現在のキャンバスではDDLプレビューを利用できません。",
+ "themeJson.editor.template": "{\n \"meta\": { \"name\": \"カスタムテーマ\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
+ "themeJson.error.pasteBeforeApply": "適用する前にテーマJSONを貼り付けてください。",
+ "themeJson.error.invalidJson": "無効なJSON: {0}",
+ "themeJson.error.emptyPayload": "無効なJSON: payloadが空です。",
+ "themeJson.error.invalidTheme": "無効なテーマ: {0}",
+ "themeJson.error.appliedButSaveFailed": "テーマは適用されましたが保存に失敗しました: {0}",
+ "themeJson.success.appliedAndSaved": "JSONテーマを適用して保存しました。",
+ "themeJson.success.customRemoved": "カスタムテーマを削除しました。既定テーマへ完全に戻すにはアプリを再起動してください。",
+ "themeJson.error.restoreDefaultFailed": "既定テーマの復元に失敗しました: {0}",
+ "themeValidator.error.configNull": "テーマ設定がnullです。",
+ "themeValidator.warning.noSections": "テーマに色またはタイポグラフィのセクションがありません。適用する内容がありません。",
+ "themeValidator.warning.invalidColor": "{0} の色 '{1}' は無効です。このキーは無視されます。",
+ "themeValidator.warning.sizeOutOfRange": "{0}={1} は範囲外です (8..48)。このキーは無視されます。",
+ "queryExecutor.error.openConnectionMethodNotFound": "orchestratorにOpenConnectionAsyncメソッドが見つかりません",
+ "queryExecutor.error.openConnectionInvokeFailed": "OpenConnectionAsyncの呼び出しに失敗しました",
+ "ddlImporter.warning.viewSelectNotReconstructable": "View '{0}': ビューのSELECTは視覚的に再構築できません。subcanvasで手動編集してください。",
+ "ddlImporter.error.tableNotFoundInMetadata": "テーブル '{0}' は現在のメタデータに見つかりませんでした。",
+ "main.window.untitled": "無題",
+ "main.subEditor.noSeedProvided": "{0} のサブエディターseedが提供されませんでした。",
+ "main.layerOrder.bringToFront": "最前面へ",
+ "main.layerOrder.sendToBack": "最背面へ",
+ "main.layerOrder.bringForward": "前面へ移動",
+ "main.layerOrder.sendBackward": "背面へ移動",
+ "main.layerOrder.normalizeLayers": "レイヤーを正規化",
+ "export.fileType.html": "HTMLファイル",
+ "export.fileType.json": "JSONファイル",
+ "export.fileType.csv": "CSVファイル",
+ "export.fileType.excel": "Excelファイル",
+ "commandPalette.templatePrefix": "テンプレート: {0}",
+ "themeLoader.status.notFoundWithPath": "テーマファイルが見つかりません: {0}",
+ "themeLoader.status.deserializedNull": "テーマJSONのデシリアライズ結果が null でした。",
+ "themeLoader.status.loaded": "テーマJSONを正常に読み込みました。",
+ "credential.error.ciphertextTooShort": "暗号文ブロブが短すぎます。",
+ "credential.error.dpapiWindowsOnly": "DPAPI は Windows でのみ利用できます。",
+ "credential.warning.loadVaultFailed": "資格情報ボルト {0} の読み込みに失敗しました: {1}",
+ "credential.warning.persistVaultFailed": "資格情報ボルト {0} の保存に失敗しました: {1}",
+ "snippetStore.warning.loadFailed": "{0} からスニペットの読み込みに失敗しました: {1}",
+ "snippetStore.warning.saveFailed": "スニペットの保存に失敗しました: {0}",
+ "flowVersionStore.warning.loadFailed": "{0} からフローバージョンの読み込みに失敗しました: {1}",
+ "flowVersionStore.warning.saveFailed": "フローバージョンの保存に失敗しました: {0}",
+ "queryExecutor.error.queryEmpty": "クエリは空にできません",
+ "queryExecutor.error.providerNotSupported": "プロバイダー {0} はサポートされていません",
+ "queryExecutor.error.singleStatementOnly": "プレビューは単一のSQL文のみ受け付けます。",
+ "queryExecutor.error.queryEmptyWithPeriod": "クエリは空にできません。",
+ "queryExecutor.error.readOnlyOnly": "プレビューモードは読み取り専用SQLのみサポートします。",
+ "queryExecutor.error.namedParametersNotSupported": "プレビューモードは実行SQLのバインドパラメータをサポートしません。安全なリテラルをインラインで指定するか、プレビュー外で実行してください。",
+ "queryExecutor.error.positionalParametersNotSupported": "プレビューモードは位置パラメータプレースホルダー(? または )をサポートしません。",
+ "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "選択したノードを下端に揃えます",
+ "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "選択したノードを左端に揃えます",
+ "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "選択したノードを右端に揃えます",
+ "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "選択したノードを上端に揃えます",
+ "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "CTEサブキャンバスの編集を適用して親キャンバスに戻ります",
+ "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "ノードを論理的な列に自動配置します",
+ "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "選択したノードを水平軸で中央揃えします",
+ "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "選択したノードを垂直軸で中央揃えします",
+ "commandPalette.description.clear_canvas_and_start_fresh": "キャンバスをクリアして最初から開始します",
+ "commandPalette.description.clear_node_selection": "ノードの選択を解除します",
+ "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "エイリアスをプロジェクト設定の命名規則に変換します",
+ "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "チェックポイントを作成し、バージョン比較と以前の状態への復元を行います",
+ "commandPalette.description.delete_the_selected_nodes": "選択したノードを削除します",
+ "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "現在のサブエディタの編集を破棄して親キャンバスに戻ります",
+ "commandPalette.description.execute_the_current_query_in_preview": "プレビューで現在のクエリを実行します",
+ "commandPalette.description.fit_all_nodes_into_the_visible_area": "すべてのノードを表示領域に収めます",
+ "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "最初のCSVエクスポートノードからCSVファイルを生成します",
+ "commandPalette.description.generate_html_file_from_the_first_html_export_node": "最初のHTMLエクスポートノードからHTMLファイルを生成します",
+ "commandPalette.description.generate_json_file_from_the_first_json_export_node": "最初のJSONエクスポートノードからJSONファイルを生成します",
+ "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "最初のExcelエクスポートノードからXLSXブックを生成します",
+ "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "クエリ実行計画を確認し、スキャン種別・結合戦略・コスト見積りを確認します",
+ "commandPalette.description.load_a_vsaq_canvas_file": ".vsaq キャンバスファイルを読み込みます",
+ "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "現在のSQLをN回実行して平均/中央値/p95レイテンシを測定します",
+ "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "選択したCTE定義ノードの分離サブキャンバスエディタを開きます",
+ "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "保存ごとに作成されるローカル履歴を開き、過去スナップショットを復元します",
+ "commandPalette.description.open_output_preview_modal_for_the_active_mode": "アクティブモードの出力プレビューモーダルを開きます",
+ "commandPalette.description.open_shortcut_reference_screen": "ショートカット一覧画面を開きます",
+ "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "接続マネージャーを開いてDB接続の追加・編集・切替を行います",
+ "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "SELECT文を貼り付けてノードを自動生成します(FROM/JOIN/WHERE/LIMIT対応)",
+ "commandPalette.description.remove_all_nodes_not_connected_to_output": "出力に接続されていないノードをすべて削除します",
+ "commandPalette.description.reset_zoom_and_pan_to_default": "ズームとパンを初期値に戻します",
+ "commandPalette.description.save_canvas_to_a_new_file": "キャンバスを新しいファイルに保存します",
+ "commandPalette.description.save_current_canvas": "現在のキャンバスを保存します",
+ "commandPalette.description.save_markdown_documentation_of_the_current_flow": "現在のフローのMarkdownドキュメントを保存します",
+ "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "選択ノードを再利用可能なスニペットとして保存し、後でノード検索メニュー(⇧A)から挿入します",
+ "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "FK規約と命名パターンに基づいてテーブルソースノード間のJOIN候補を検出します",
+ "commandPalette.description.select_all_nodes_on_canvas": "キャンバス上のすべてのノードを選択します",
+ "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "ノード位置を16pxグリッドにスナップします(Ctrl+G)",
+ "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "選択ノードを水平方向に等間隔で配置します",
+ "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "選択ノードを垂直方向に等間隔で配置します",
+ "commandPalette.description.zoom_into_the_canvas": "キャンバスを拡大します",
+ "commandPalette.description.zoom_out_of_the_canvas": "キャンバスを縮小します",
+ "commandPalette.name.align_bottom": "下揃え",
+ "commandPalette.name.align_left": "左揃え",
+ "commandPalette.name.align_right": "右揃え",
+ "commandPalette.name.align_top": "上揃え",
+ "commandPalette.name.analyze_all_joins": "すべてのJOINを解析",
+ "commandPalette.name.auto_fix_naming": "命名を自動修正",
+ "commandPalette.name.auto_layout": "自動レイアウト",
+ "commandPalette.name.center_horizontally": "水平中央揃え",
+ "commandPalette.name.center_vertically": "垂直中央揃え",
+ "commandPalette.name.cleanup_orphans": "孤立ノードをクリーンアップ",
+ "commandPalette.name.delete_selected": "選択を削除",
+ "commandPalette.name.deselect_all": "すべて選択解除",
+ "commandPalette.name.discard_and_exit_editor": "破棄してエディタを終了",
+ "commandPalette.name.distribute_horizontally": "水平方向に均等配置",
+ "commandPalette.name.distribute_vertically": "垂直方向に均等配置",
+ "commandPalette.name.edit_selected_cte": "選択したCTEを編集",
+ "commandPalette.name.exit_cte_editor": "CTEエディタを終了",
+ "commandPalette.name.explain_plan": "実行計画",
+ "commandPalette.name.export_csv": "CSVをエクスポート",
+ "commandPalette.name.export_documentation": "ドキュメントをエクスポート",
+ "commandPalette.name.export_excel": "Excelをエクスポート",
+ "commandPalette.name.export_html": "HTMLをエクスポート",
+ "commandPalette.name.export_json": "JSONをエクスポート",
+ "commandPalette.name.file_save_load_history": "保存/読み込み履歴",
+ "commandPalette.name.fit_to_screen": "画面にフィット",
+ "commandPalette.name.flow_version_history": "フローバージョン履歴",
+ "commandPalette.name.import_sql_to_graph": "SQLをグラフにインポート",
+ "commandPalette.name.keyboard_shortcuts": "キーボードショートカット",
+ "commandPalette.name.manage_connections": "接続を管理",
+ "commandPalette.name.new_canvas": "新しいキャンバス",
+ "commandPalette.name.open_file": "ファイルを開く",
+ "commandPalette.name.reset_viewport": "ビューポートをリセット",
+ "commandPalette.name.run_preview": "プレビューを実行",
+ "commandPalette.name.run_query_benchmark": "クエリベンチマークを実行",
+ "commandPalette.name.save": "保存",
+ "commandPalette.name.save_as": "名前を付けて保存",
+ "commandPalette.name.save_selection_as_snippet": "選択をスニペットとして保存",
+ "commandPalette.name.select_all": "すべて選択",
+ "commandPalette.name.toggle_preview": "プレビューを切り替え",
+ "commandPalette.name.toggle_snap_to_grid": "グリッドスナップを切り替え",
+ "commandPalette.name.zoom_in": "ズームイン",
+ "commandPalette.name.zoom_out": "ズームアウト",
+ "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 percent restore zoom pan viewport",
+ "commandPalette.tags.align_bottom_edge_selection_nodes": "align bottom edge selection nodes",
+ "commandPalette.tags.align_center_middle_horizontal_nodes": "align center middle horizontal nodes",
+ "commandPalette.tags.align_center_middle_vertical_nodes": "align center middle vertical nodes",
+ "commandPalette.tags.align_left_edge_selection_nodes": "align left edge selection nodes",
+ "commandPalette.tags.align_right_edge_selection_nodes": "align right edge selection nodes",
+ "commandPalette.tags.align_top_edge_selection_nodes": "align top edge selection nodes",
+ "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout view reset zoom",
+ "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark performance latency timing profile measure speed",
+ "commandPalette.tags.clear_selection": "clear selection",
+ "commandPalette.tags.connection_database_server_host_provider_switch": "connection database server host provider switch",
+ "commandPalette.tags.create_insert_search_transform": "create insert search transform",
+ "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas exit apply back",
+ "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte view subcanvas discard exit force",
+ "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursive editor subgraph subcanvas isolate",
+ "commandPalette.tags.data_results_table_panel": "data results table panel",
+ "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribute space equal horizontal nodes",
+ "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribute space equal vertical nodes",
+ "commandPalette.tags.execute_run_sql_query_results": "execute run sql query results",
+ "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan execution cost scan index join performance",
+ "commandPalette.tags.export_csv_file_tabular_output_save": "export csv file tabular output save",
+ "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "export excel xlsx file tabular output spreadsheet save",
+ "commandPalette.tags.export_html_file_output_report_save": "export html file output report save",
+ "commandPalette.tags.export_json_file_output_save": "export json file output save",
+ "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "export markdown doc documentation flow save md",
+ "commandPalette.tags.export_persist_copy": "export persist copy",
+ "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "file history save load backup versions restore local",
+ "commandPalette.tags.forward_history": "forward history",
+ "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "help shortcuts hotkeys keyboard reference",
+ "commandPalette.tags.highlight_mark_all_nodes": "highlight mark all nodes",
+ "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "import sql paste convert graph reverse engineer query",
+ "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analyze suggest detect foreign key relationships heuristic",
+ "commandPalette.tags.layer_z_order_back_selected_nodes": "layer z-order back selected nodes",
+ "commandPalette.tags.layer_z_order_backward_selected_nodes": "layer z-order backward selected nodes",
+ "commandPalette.tags.layer_z_order_forward_selected_nodes": "layer z-order forward selected nodes",
+ "commandPalette.tags.layer_z_order_front_selected_nodes": "layer z-order front selected nodes",
+ "commandPalette.tags.layer_z_order_normalize_compact": "layer z-order normalize compact",
+ "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout arrange columns auto organize readability",
+ "commandPalette.tags.load_import_vsaq": "load import vsaq",
+ "commandPalette.tags.magnify_enlarge": "magnify enlarge",
+ "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "orphan unused disconnected clean delete nodes",
+ "commandPalette.tags.persist_write_disk": "persist write disk",
+ "commandPalette.tags.remove_erase_nodes": "remove erase nodes",
+ "commandPalette.tags.rename_alias_fix_naming_convention": "rename alias fix naming convention",
+ "commandPalette.tags.reset_clear_blank": "reset clear blank",
+ "commandPalette.tags.revert_back_history": "revert back history",
+ "commandPalette.tags.shrink_reduce": "shrink reduce",
+ "commandPalette.tags.snap_grid_align_precision_position": "snap grid align precision position",
+ "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet save selection reuse template favorite bookmark",
+ "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "version history checkpoint diff restore snapshot compare undo flow",
+ "sqlEditor.diffPreview.title": "Transactional Diff Preview",
+ "sqlEditor.mutation.confirmExecute": "Confirm Execute",
+ "sqlEditor.tab.closeAnyway": "Close Anyway",
+ "sqlEditor.tab.keepTab": "Keep Tab",
+ "sqlEditor.status.ready": "Ready.",
+ "sqlEditor.telemetry.none": "No execution telemetry yet.",
+ "sqlEditor.telemetry.summary": "Statements: {0} Success: {1} Failed: {2} Total: {3} ms",
+ "sqlEditor.telemetry.errors.none": "No aggregated errors.",
+ "sqlEditor.diff.none": "No transactional diff preview available.",
+ "sqlEditor.mutation.estimate.none": "No mutation estimate available.",
+ "sqlEditor.mutation.estimate.value": "Estimated affected rows: {0}",
+ "sqlEditor.mutation.estimate.unavailable": "Could not estimate affected rows automatically.",
+ "sqlEditor.tab.closePending": "Unsaved changes detected. Confirm tab close.",
+ "sqlEditor.tab.noPendingClose": "No tab close pending.",
+ "sqlEditor.tab.manyWarning": "High tab count: {0} open tabs.",
+ "sqlEditor.mutation.pending.none": "No pending mutation confirmation.",
+ "sqlEditor.mutation.pending.required": "Mutation requires confirmation before execution.",
+ "sqlEditor.message.empty": "Execute a statement to see messages.",
+ "sqlEditor.message.success": "Execution completed successfully.",
+ "sqlEditor.result.summary.empty": "Rows: - Time: -",
+ "sqlEditor.result.summary": "Rows: {0} Time: {1} ms",
+ "sqlEditor.file.save.canceled": "Save canceled.",
+ "sqlEditor.file.save.noPath": "No target path selected.",
+ "sqlEditor.file.save.success": "SQL file saved.",
+ "sqlEditor.file.save.failed": "Save failed.",
+ "sqlEditor.file.open.failed": "Open failed.",
+ "sqlEditor.file.open.notFound": "Selected SQL file was not found.",
+ "sqlEditor.file.open.success": "SQL file opened.",
+ "sqlEditor.status.executing": "Executing SQL...",
+ "sqlEditor.status.executingScript": "Executing SQL script...",
+ "sqlEditor.status.executingStep": "Executing {0}/{1}...",
+ "sqlEditor.status.canceling": "Canceling execution...",
+ "sqlEditor.status.executingConfirmedMutation": "Executing confirmed mutation...",
+ "sqlEditor.status.mutationCanceled": "Mutation execution canceled.",
+ "sqlEditor.detail.statementNotExecuted": "Statement was not executed.",
+ "sqlEditor.status.success": "Execution succeeded.",
+ "sqlEditor.detail.rowsAndTime": "{0} row(s) in {1} ms.",
+ "sqlEditor.status.canceled": "Execution canceled.",
+ "sqlEditor.status.failed": "Execution failed.",
+ "sqlEditor.status.confirmationRequired": "Confirmation required before execution.",
+ "sqlEditor.error.mutationConfirmationRequired": "Mutation confirmation required.",
+ "sqlEditor.result.tabTitle": "Result {0}",
+ "sqlEditor.tab.closeRequiresConfirmation": "Tab close requires confirmation.",
+ "sqlEditor.tab.unsavedDetail": "This tab has unsaved changes.",
+ "sqlEditor.tab.closed": "Tab closed.",
+ "sqlEditor.tab.closeCanceled": "Tab close canceled.",
+ "sqlEditor.tab.closeCanceledDetail": "Unsaved tab kept open.",
+ "sqlEditor.error.noStatementSelected": "No SQL statement selected for execution.",
+ "sqlEditor.error.noConnection": "No active database connection for SQL execution.",
+ "sqlEditor.error.executionCanceled": "SQL execution was canceled.",
+ "sqlEditor.tab.scriptTitle": "Script {0}",
+ "sqlEditor.guard.delete.noWhere.message": "DELETE without WHERE can remove all rows.",
+ "sqlEditor.guard.delete.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
+ "sqlEditor.guard.delete.trivialWhere.message": "DELETE has a trivially true WHERE clause.",
+ "sqlEditor.guard.delete.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
+ "sqlEditor.guard.update.noWhere.message": "UPDATE without WHERE can affect all rows.",
+ "sqlEditor.guard.update.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
+ "sqlEditor.guard.update.trivialWhere.message": "UPDATE has a trivially true WHERE clause.",
+ "sqlEditor.guard.update.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
+ "sqlEditor.guard.insert.noColumnList.message": "INSERT without explicit column list is fragile against schema changes.",
+ "sqlEditor.guard.insert.noColumnList.recommendation": "Prefer INSERT INTO table(col1, col2, ...) VALUES (...).",
+ "sqlEditor.guard.ddl.message": "DDL statement may cause structural changes in the database.",
+ "sqlEditor.guard.ddl.recommendation": "Confirm execution only when schema changes are intended.",
+ "sqlEditor.diff.unavailable.noPreview": "No transactional diff preview available for this statement.",
+ "sqlEditor.diff.unavailable.parseError": "Could not parse mutation target for transactional diff preview.",
+ "sqlEditor.diff.unavailable.connection": "Transactional diff preview unavailable due to connection or query limitations.",
+ "sqlEditor.diff.deleteSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, affected {2}, total rows after {3}.",
+ "sqlEditor.diff.updateSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, candidate rows affected {2}, total rows after {3}.",
+ "sqlEditor.diff.unavailable.unsupportedStatement": "Transactional diff preview currently supports UPDATE and DELETE only.",
+ "sqlEditor.results.title": "Results",
+ "sqlEditor.saveSql.fileType": "SQL Files",
+ "sqlEditor.saveSql.pickerTitle": "Save SQL File",
+ "sqlEditor.export.pickerTitle": "Export SQL Data",
+ "sqlEditor.export.status.noResultTitle": "No execution result available for export.",
+ "sqlEditor.export.status.noResultDetail": "Execute a query first.",
+ "sqlEditor.export.status.successTitle": "Report exported.",
+ "sqlEditor.export.status.failedTitle": "Failed to export report.",
+ "sqlEditor.export.fileType.html": "HTML File",
+ "sqlEditor.export.fileType.json": "JSON File",
+ "sqlEditor.export.fileType.csv": "CSV File",
+ "sqlEditor.export.fileType.xlsx": "Excel Workbook",
+ "sqlEditor.export.defaultFileBase": "report",
+ "sqlEditor.export.defaultTitle": "SQL Report",
+ "sqlEditor.export.error.typeRequired": "A report type must be selected before export.",
+ "sqlEditor.export.type.html.title": "HTML full-feature report",
+ "sqlEditor.export.type.html.description": "Standalone, SQL-first HTML artifact for offline audit.",
+ "sqlEditor.export.type.json.title": "JSON execution contract",
+ "sqlEditor.export.type.json.description": "Machine-readable payload with SQL, metadata and execution result.",
+ "sqlEditor.export.type.csv.title": "CSV data export",
+ "sqlEditor.export.type.csv.description": "Tabular result data only, suitable for spreadsheet tools.",
+ "sqlEditor.export.type.xlsx.title": "Excel workbook export",
+ "sqlEditor.export.type.xlsx.description": "Spreadsheet workbook with query result data only.",
+ "sqlEditor.export.dialog.windowTitle": "Export SQL Data",
+ "sqlEditor.export.dialog.title": "Export SQL Data",
+ "sqlEditor.export.dialog.subtitle": "Choose the artifact format and metadata before exporting.",
+ "sqlEditor.export.dialog.confirm": "Export",
+ "sqlEditor.export.dialog.fileNameWatermark": "report.html",
+ "sqlEditor.export.dialog.titleWatermark": "SQL Report",
+ "sqlEditor.export.dialog.descriptionWatermark": "Additional context for auditors and teammates.",
+ "sqlEditor.export.dialog.section.reportType": "REPORT TYPE",
+ "sqlEditor.export.dialog.section.fileName": "FILE NAME",
+ "sqlEditor.export.dialog.section.reportTitle": "TITLE",
+ "sqlEditor.export.dialog.section.description": "DESCRIPTION",
+ "sqlEditor.export.dialog.section.options": "OPTIONS",
+ "sqlEditor.export.option.includeSchema": "Include output schema",
+ "sqlEditor.export.option.includeNodeDetails": "Include node/connection placeholders in JSON",
+ "sqlEditor.export.option.includeMetadata": "Include optional metadata",
+ "sqlEditor.export.option.useDashForEmpty": "Use '-' for empty fields",
+ "sqlEditor.export.badge.offline": "OFFLINE READY",
+ "sqlEditor.export.badge.structured": "STRUCTURED PAYLOAD",
+ "sqlEditor.export.badge.dataOnly": "DATA ONLY"
+}
diff --git a/src/DBWeaver.UI/Assets/Localization/pt-BR.json b/src/AkkornStudio.UI/Assets/Localization/pt-BR.json
similarity index 98%
rename from src/DBWeaver.UI/Assets/Localization/pt-BR.json
rename to src/AkkornStudio.UI/Assets/Localization/pt-BR.json
index 70f89f36..f0431953 100644
--- a/src/DBWeaver.UI/Assets/Localization/pt-BR.json
+++ b/src/AkkornStudio.UI/Assets/Localization/pt-BR.json
@@ -1,1151 +1,1151 @@
-{
- "main.brand": "DBWeaver",
- "main.tab.query1": "Consulta 1",
- "main.new": "Novo",
- "main.open": "Abrir",
- "main.save": "Salvar",
- "main.history": "Histórico",
- "main.layout": "Layout",
- "main.preview": "Prévia",
- "main.undo": "Desfazer",
- "main.redo": "Refazer",
- "main.cleanupOrphans": "Limpar nós órfãos",
- "main.autoFixAliasNaming": "Autoajustar nomenclatura de aliases",
- "main.autoLayoutCanvas": "Layout automático do canvas",
- "main.toggleDataPreview": "Alternar prévia de dados",
- "main.language": "Idioma",
- "main.restore.prompt": "Sessão anterior encontrada — deseja restaurar o último canvas?",
- "main.restore.button": "Restaurar sessão",
- "main.cteEditor.editingPrefix": "Editando CTE: ",
- "main.cteEditor.backToCanvas": "Voltar ao Canvas",
- "main.cteEditor.exitA11y": "Sair do editor de CTE",
- "main.viewEditor.editingPrefix": "DDL > View: ",
- "main.viewEditor.backToCanvas": "Voltar ao DDL",
- "main.viewEditor.exitA11y": "Sair do editor de view",
- "connection.title": "Gerenciador de Conexões",
- "connection.subtitle": "Configure, teste e ative conexões sem sair do fluxo",
- "connection.none": "Sem conexão",
- "connection.active": "ATIVA",
- "connection.health.online": "Online",
- "connection.health.degraded": "Degradada",
- "connection.health.offline": "Offline",
- "connection.tooltip.none": "Nenhuma conexão ativa — clique para gerenciar",
- "connection.ping": "Ping",
- "connection.saved": "CONEXÕES SALVAS",
- "connection.new": "Nova Conexão",
- "connection.selectOrCreate": "Selecione uma conexão ou crie uma nova",
- "connection.name": "Nome da Conexão",
- "connection.provider": "Provedor",
- "connection.host": "Host",
- "connection.port": "Porta",
- "connection.database": "Banco de Dados",
- "connection.sqlitePath": "Caminho SQLite",
- "connection.sqliteBrowse": "Procurar",
- "connection.sqliteCreate": "Criar",
- "connection.username": "Usuário",
- "connection.password": "Senha",
- "connection.timeout": "Timeout (segundos)",
- "connection.test": "Testar",
- "connection.save": "Salvar",
- "connection.connect": "Conectar",
- "connection.action.testConnection": "Testar conexão",
- "connection.action.saveConnection": "Salvar conexão",
- "connection.action.connectConnection": "Conectar conexão",
- "connection.status.connecting": "Conectando...",
- "connection.status.connected": "Conectado",
- "connection.status.testing": "Testando...",
- "connection.status.failedPrefix": "Falha na conexão",
- "connection.status.metadataUnavailable": "Falha na conexão: metadados indisponíveis.",
- "connection.status.highLatency": "latência alta",
- "connection.watermark.name": "Meu Banco de Produção",
- "connection.watermark.host": "localhost",
- "connection.watermark.port": "5432",
- "connection.watermark.database": "nome_do_banco",
- "connection.watermark.username": "usuario",
- "connection.watermark.password": "••••••••",
- "connection.watermark.timeout": "30",
- "main.connectingDb": "Conectando ao banco de dados...",
- "main.emptyHint": "Pressione ⇧A para adicionar seu primeiro nó, ou arraste uma tabela da barra lateral",
- "status.nodesSeparator": " nós · ",
- "status.connectionsSuffix": " conexões",
- "status.undo": "Desfazer: ",
- "status.shortcuts": "⇧A Nós · F3 Prévia · Ctrl+Z Desfazer · Del Remover · Alt+Arrastar Pan",
- "connection.disconnect": "Desconectar",
- "connection.action.disconnectConnection": "Desconectar conexão",
- "connectionTab.active": "CONEXÃO ATIVA",
- "connectionTab.none": "Nenhuma conexão ativa",
- "connectionTab.saved": "CONEXÕES SALVAS",
- "connectionTab.new": "+ Nova Conexão",
- "schema.database": "BANCO DE DADOS",
- "schema.search": "Buscar tabelas, colunas...",
- "schema.loading": "Buscando tabelas, colunas...",
- "schema.noConnection": "Sem conexão",
- "schema.noConnectionHint": "Conecte-se a um banco para ver tabelas, colunas e relacionamentos",
- "schema.emptyNoTables": "Nenhuma tabela encontrada",
- "fileHistory.title": "Histórico de Versões (Salvar/Carregar)",
- "fileHistory.reload": "Recarregar",
- "fileHistory.restoreSelected": "Restaurar selecionada",
- "fileHistory.empty": "Nenhuma versão local ainda",
- "fileHistory.emptyHint": "Salve este arquivo para gerar histórico de versões.",
- "preview.title": "Prévia de Dados",
- "preview.subtitle": "Revise dados e diagnósticos antes de continuar",
- "preview.run": "Executar",
- "preview.cancel": "Cancelar",
- "preview.tab.preview": "Prévia",
- "preview.tab.sql": "SQL",
- "preview.close": "Fechar prévia",
- "preview.running": "Executando consulta de prévia… ",
- "preview.clickCancel": "Clique em Cancelar para interromper",
- "preview.cancelled": "Consulta cancelada",
- "preview.runAgain": "Pressione Executar para tentar novamente",
- "preview.failed": "Falha na execução da prévia",
- "preview.technical": "DETALHES TÉCNICOS",
- "preview.noData": "Sem dados ainda",
- "preview.f3Hint": "Pressione F3 ou Espaço para executar a consulta atual",
- "sqlImporter.title": "Importar SQL para Grafo",
- "sqlImporter.subtitle": "Cole uma instrução SELECT — os nós são criados automaticamente",
- "sqlImporter.sqlStatement": "INSTRUÇÃO SQL",
- "sqlImporter.supported": "Suportado: ",
- "sqlImporter.import": "Importar",
- "sqlImporter.report": "RELATÓRIO DE CONVERSÃO",
- "sqlEditor.mutation.dialogTitle": "Confirmacao de mutacao",
- "sqlEditor.mutation.dialogSubtitle": "Revise o impacto antes de confirmar a execucao",
- "search.empty": "Nenhum nó encontrado",
- "search.emptyHint": "Tente buscar por UPPER, JSON, CAST, AND…",
- "search.shortcut": "⇧A",
- "search.spawn": "Criar",
- "commandPalette.empty": "Nenhum comando corresponde à sua busca",
- "commandPalette.search": "Busca de comandos",
- "commandPalette.shortcut": "CTRL+SHIFT+P",
- "commandPalette.execute": "Executar",
- "context.editCte": "Editar CTE Selecionada",
- "context.editViewSubcanvas": "Editar Subcanvas da View",
- "explain.title": "Plano de Execução",
- "explain.sql": "SQL",
- "explain.option.analyze": "Analisar",
- "explain.option.buffers": "Buffers",
- "explain.badge.simulated": "SIMULADO",
- "explain.timing.planning": "Planejamento:",
- "explain.timing.execution": "Execucao:",
- "explain.section.snapshotComparison": "Comparacao de snapshots",
- "explain.section.indexRecommendations": "Recomendacoes de indice",
- "explain.section.history": "Historico",
- "explain.detail.estimated": "Estimadas",
- "explain.detail.actual": "Atuais",
- "explain.detail.error": "Erro",
- "explain.detail.time": "Tempo",
- "explain.detail.loops": "Loops",
- "explain.rerun": "Reexecutar",
- "explain.alertSuffix": " operação(ões) cara(s) detectada(s) — considere adicionar índices",
- "explain.running": "Executando EXPLAIN…",
- "explain.failed": "⚠ EXPLAIN falhou",
- "explain.noPlan": "Nenhum plano ainda",
- "explain.rerunHint": "Pressione Reexecutar para executar EXPLAIN",
- "explain.header.operation": "OPERAÇÃO",
- "explain.header.cost": "CUSTO",
- "explain.header.rows": "LINHAS",
- "explain.header.err": "ERR",
- "explain.header.alert": "ALERTA",
- "explain.snapshot.labelA": "A",
- "explain.snapshot.labelB": "B",
- "explain.mode.list": "Lista",
- "explain.mode.tree": "Arvore",
- "explain.action.snapshot": "Salvar snapshot",
- "explain.action.copyJson": "Copiar JSON",
- "explain.action.copyText": "Copiar texto",
- "explain.action.saveJson": "Salvar .json",
- "explain.action.openDalibo": "Abrir no Dalibo",
- "explain.legend.seqscan": "SEQ SCAN — leitura completa da tabela, sem índice",
- "explain.legend.sort": "SORT — ordenação em memória",
- "explain.legend.hash": "HASH — junção por hash",
- "explain.escClose": "Esc para fechar",
- "flowVersion.title": "Histórico de Versões do Fluxo",
- "flowVersion.subtitle": "Crie checkpoints, compare versões e restaure",
- "flowVersion.watermark": "Rótulo do checkpoint (opcional)…",
- "flowVersion.saveCheckpoint": "Salvar Checkpoint",
- "flowVersion.compareMode": "Modo de Comparação",
- "flowVersion.selectBase": "Selecione a versão BASE (de):",
- "flowVersion.clickAny": "Depois clique em qualquer versão da lista abaixo para comparar.",
- "flowVersion.noCheckpoints": "Nenhum checkpoint ainda",
- "flowVersion.noCheckpointsHint": "Salve um checkpoint acima para começar a rastrear versões.",
- "flowVersion.restore": "Restaurar",
- "flowVersion.diffResults": "Resultados da Diferença",
- "benchmark.title": "Benchmark de Consulta",
- "benchmark.subtitle": "Mede latência média / mediana / p95 em N iterações",
- "benchmark.sql": "SQL sendo avaliado",
- "benchmark.runLabel": "Rótulo da execução",
- "benchmark.runLabelWatermark": "Execução 1",
- "benchmark.iterations": "Iterações (1–100)",
- "benchmark.warmup": "Passes de aquecimento (0–10)",
- "benchmark.interval": "Intervalo entre execuções (ms)",
- "benchmark.run": "Executar Benchmark",
- "benchmark.cancel": "Cancelar",
- "benchmark.clearHistory": "Limpar Histórico",
- "benchmark.latest": "ÚLTIMO RESULTADO",
- "benchmark.avg": "MÉDIA",
- "benchmark.median": "MEDIANA",
- "benchmark.min": "MÍN",
- "benchmark.max": "MÁX",
- "benchmark.iterationsAt": " iterações · executado às ",
- "benchmark.history": "HISTÓRICO",
- "benchmark.header.label": "Rótulo",
- "benchmark.header.avg": "Média",
- "benchmark.header.median": "Mediana",
- "benchmark.header.min": "Mín",
- "benchmark.header.max": "Máx",
- "benchmark.itersSuffix": " iterações",
- "diagnostics.title": "Diagnóstico do Aplicativo",
- "diagnostics.run": "Executar",
- "diagnostics.running": "Executando verificações…",
- "diagnostics.ok": "OK",
- "diagnostics.warning": "Aviso",
- "diagnostics.error": "Erro",
- "diagnostics.tooltip.rerun": "Executar novamente todas as verificações",
- "diagnostics.tooltip.copy": "Copiar relatório de diagnóstico para a área de transferência",
- "diagnostics.tooltip.close": "Fechar (Esc)",
- "autoJoin.title": "Sugestões de Auto-Join",
- "autoJoin.titleForTable": "Sugestões de Auto-Join para {0}",
- "autoJoin.acceptAll": "Aceitar Todas",
- "autoJoin.accept": "Aceitar",
- "autoJoin.skip": "Pular",
- "autoJoin.allHandled": "Todas as sugestões foram tratadas",
- "autoJoin.joinKeyword": "JOIN",
- "autoJoin.confidence.fkConstraint": "Restrição FK",
- "autoJoin.confidence.fkReverse": "FK (Reversa)",
- "autoJoin.confidence.namingMatch": "Correspondência por nome",
- "autoJoin.confidence.weakMatch": "Correspondência fraca",
- "autoJoin.runSelected": "Auto-Join Selecionado",
- "autoJoin.noSimilarityTitle": "Nenhum auto join encontrado",
- "autoJoin.noSimilarityDetails": "Escolha manualmente as colunas para criar um join simples.",
- "autoJoin.appliedTitle": "Auto-join aplicado",
- "autoJoin.manual.title": "Criar Join Manual",
- "autoJoin.manual.subtitle": "Nenhuma similaridade confiável foi encontrada. Selecione uma coluna de cada tabela.",
- "autoJoin.manual.leftColumn": "Coluna da esquerda",
- "autoJoin.manual.rightColumn": "Coluna da direita",
- "autoJoin.manual.joinType": "Tipo de join",
- "autoJoin.manual.operator": "Operador",
- "autoJoin.manual.confirm": "Criar join",
- "autoJoin.manual.noCompatible": "Nao ha colunas compativeis para o tipo de pin selecionado na esquerda.",
- "autoJoin.manualJoinCreatedTitle": "Join manual criado",
- "autoJoin.manualJoinFailedTitle": "Não foi possível criar o join manual",
- "autoJoin.manualJoinFailedDetails": "Verifique as colunas selecionadas e joins existentes, depois tente novamente.",
- "autoJoin.multipleCandidatesTitle": "Múltiplas opções de join encontradas",
- "autoJoin.multipleCandidatesDetails": "{0} combinações possíveis foram encontradas. Confirme quais colunas devem ser usadas.",
- "autoJoin.suggestionsFoundTitle": "Sugestões de auto-join disponíveis",
- "autoJoin.suggestionsFoundDetails": "{0} sugestão(ões) encontrada(s). Selecione duas tabelas e execute Auto-Join Selecionado.",
- "property.outputAlias": "ALIAS DE SAÍDA",
- "property.sourceAlias": "ALIAS DE FONTE",
- "property.aliasWatermark": "ex.: MinhaColuna (opcional)",
- "property.parameters": "PARÂMETROS",
- "property.enabled": "Habilitado",
- "property.datetimeWatermark": "AAAA-MM-DDTHH:mm:ss ou deixe vazio",
- "property.dateWatermark": "AAAA-MM-DD ou deixe vazio",
- "property.apply": "Aplicar",
- "property.inputPins": "PINS DE ENTRADA",
- "property.outputPins": "PINS DE SAÍDA",
- "property.sqlTrace": "RASTREIO SQL",
- "property.live": "ao vivo",
- "node.numericValue": "Valor Numérico",
- "node.stringValue": "Valor de Texto",
- "node.enterText": "Digite o texto",
- "node.datetimeValue": "Valor de Data/Hora",
- "node.valueLabel": "Valor:",
- "node.noInputs": "Sem entradas",
- "node.loadingSample": "Carregando amostra…",
- "node.previewFailed": "⚠ Falha na prévia",
- "node.sampleRowsHint": "5 linhas de amostra · dados de demonstração",
- "sidebar.tab.nodes": "Nós",
- "sidebar.tab.connection": "Conexão",
- "sidebar.tab.schema": "Esquema",
- "sidebar.tab.diagnostics": "Diagnósticos",
- "sidebar.addNode": "+ Adicionar Nó (⇧A)",
- "sidebar.previewF3": "Prévia (F3)",
- "nodesList.search": "Buscar nós...",
- "search.watermark": "Buscar nós… (Esc para fechar)",
- "search.snippets": "★ SNIPPETS",
- "commandPalette.watermark": "Executar um comando… (Esc para fechar)",
- "tooltip.newCanvas": "Novo canvas (Ctrl+N)",
- "tooltip.openCanvas": "Abrir canvas (Ctrl+O)",
- "tooltip.saveCanvas": "Salvar canvas (Ctrl+S)",
- "tooltip.fileHistory": "Histórico local de salvar/carregar (Ctrl+Alt+H)",
- "tooltip.zoomOut": "Diminuir zoom (Ctrl+-)",
- "tooltip.zoomIn": "Aumentar zoom (Ctrl++)",
- "tooltip.fitToScreen": "Ajustar à tela (Ctrl+0)",
- "tooltip.autoLayout": "Layout automático — organiza os nós em colunas lógicas (Ctrl+L, Ctrl+Z para desfazer)",
- "tooltip.snapToGrid": "Alternar snap na grade (Ctrl+G)",
- "tooltip.dataPreview": "Prévia de dados (F3)",
- "tooltip.toggleLanguage": "Alternar idioma (pt-BR / en-US)",
- "tooltip.appDiagnostics": "Diagnóstico do app (autoavaliação)",
- "tooltip.keyboardShortcuts": "Atalhos do teclado (F1)",
- "tooltip.cancelRunningQuery": "Cancelar a consulta em execução",
- "tooltip.closeEsc": "Fechar (Esc)",
- "tooltip.recheckConnectionHealth": "Verificar novamente a saúde da conexão",
- "tooltip.deleteConnection": "Excluir conexão",
- "tooltip.testConnection": "Testar conexão",
- "tooltip.saveConnection": "Salvar conexão",
- "tooltip.activateConnection": "Ativar esta conexão",
- "tooltip.toggleDataSamplePreview": "Alternar prévia de dados de amostra",
- "tooltip.liveSqlMutatingBlocked": "Este SQL contém um comando que altera dados e não pode ser executado no Modo de Prévia Segura",
- "tooltip.copySql": "Copiar SQL para a área de transferência",
- "tooltip.formatSql": "Formatar SQL",
- "tooltip.openBenchmark": "Abrir Benchmark de Consulta (medir média / mediana / p95 de latência)",
- "tooltip.openExplainPlan": "Abrir inspetor de Explain Plan — visualizar o plano de execução da consulta",
- "tooltip.switchToQueryMode": "Alternar para o canvas de Query",
- "tooltip.switchToDdlMode": "Alternar para o canvas de DDL",
- "tooltip.switchToSqlMode": "Alternar para o editor SQL",
- "tooltip.autoJoinSelected": "Tentar auto-join entre as duas tabelas selecionadas",
- "tooltip.pins.inputs": "Entradas",
- "tooltip.pins.outputs": "Saídas",
- "tooltip.pins.none": "Nenhum",
- "tooltip.tableColumns": "Colunas",
- "tooltip.tableColumns.none": "Sem colunas detalhadas",
- "window.minimize": "Minimizar janela",
- "window.maximizeRestore": "Maximizar/restaurar janela",
- "window.close": "Fechar janela",
- "menu.newDiagram": "Novo diagrama",
- "menu.openFile": "Abrir arquivo",
- "menu.save": "Salvar",
- "menu.fileHistory": "Histórico de arquivos",
- "menu.shortcuts": "Atalhos de teclado",
- "menu.settings": "Configurações",
- "menu.group.project": "PROJETO",
- "menu.group.currentMode": "MODO ATUAL",
- "menu.group.tools": "FERRAMENTAS",
- "menu.reason.ddlOnly": "Disponível apenas no modo DDL.",
- "menu.importSqlQuery": "Importar SQL para Query",
- "menu.importDdlSchema": "Importar Schema DDL",
- "menu.viewDdlSql": "Ver SQL DDL",
- "menu.executeDdl": "Executar DDL",
- "menu.backToStart": "Voltar para início",
- "toast.ddlExecuteFailed": "Falha ao executar DDL.",
- "toast.ddlOpenFailed": "Falha ao abrir SQL DDL.",
- "toast.ddlImportFailed": "Falha ao importar schema para DDL.",
- "toast.ddlConnectToImportSchema": "Conecte-se a um banco para importar schema no canvas DDL.",
- "toast.ddlNoTablesFound": "Nenhuma tabela encontrada para importar no modo DDL.",
- "toast.ddlSchemaImported": "Schema importado para o canvas DDL.",
- "toast.ddlImportSummary": "{0} tabela(s), {1} coluna(s), {2} FK(s), {3} indice(s) unicos.",
- "toast.ddlConnectToImportTable": "Conecte-se a um banco para importar tabelas no canvas DDL.",
- "toast.ddlTableAlreadyExists": "A tabela '{0}' ja existe no canvas DDL.",
- "toast.ddlTableImported": "Tabela importada para o canvas DDL.",
- "toast.ddlTableImportSummary": "Nos: +{0}, conexoes: +{1}, FKs: +{2}.",
- "toast.ddlNoActiveConnection": "Nenhuma conexão ativa para executar DDL.",
- "toast.ddlExecutedSuccess": "DDL executado com sucesso.",
- "toast.ddlExecutedWithIssues": "DDL executado com falhas.",
- "toast.switchToDdl": "Alterne para o modo DDL para gerar SQL.",
- "toast.ddlInvalid": "DDL inválido. Corrija os erros antes de continuar.",
- "toast.ddlNoStatements": "Nenhum statement DDL foi gerado no canvas.",
- "toast.previewOpenFailed": "Falha ao abrir preview.",
- "tab.switchFailed": "Falha ao alternar aba: {0}",
- "settings.status.darkApplied": "Tema escuro aplicado.",
- "settings.status.lightApplied": "Tema claro aplicado.",
- "settings.status.snapUpdated": "Snap atualizado: {0}.",
- "settings.status.languageToggled": "Idioma alternado.",
- "settings.status.languageSelected": "Idioma selecionado: {0}.",
- "settings.status.themeEditorReady": "Editor de tema pronto. Aplique para salvar e usar o tema.",
- "settings.section.appearance.title": "Temas",
- "settings.section.languageRegion.title": "Idioma e Região",
- "settings.section.dateTime.title": "Data e Hora",
- "settings.section.keyboard.title": "Atalhos de Teclado",
- "settings.section.privacy.title": "Privacidade",
- "settings.section.notification.title": "Notificações",
- "settings.section.accessibility.title": "Acessibilidade",
- "settings.section.default.title": "Configurações",
- "settings.section.appearance.subtitle": "Escolha o estilo ou personalize seu tema",
- "settings.section.languageRegion.subtitle": "Gerencie idioma e formatação regional",
- "settings.section.keyboard.subtitle": "Personalize os atalhos de teclado usados pela command palette e execução do canvas.",
- "settings.section.wip.subtitle": "Trabalho em progresso.",
- "settings.section.default.subtitle": "Configurações da aplicação",
- "settings.general": "Geral",
- "settings.nav.appearance": "Aparência",
- "settings.theme.light": "Modo Claro",
- "settings.theme.dark": "Modo Escuro",
- "settings.theme.system": "Preferências do Sistema",
- "settings.gridSnap.title": "Snap na Grade",
- "settings.gridSnap.subtitle": "Controla o snap dos nós no canvas.",
- "settings.language.subtitle": "Alterna entre PT-BR e EN-US.",
- "settings.language.toggle": "Alternar idioma",
- "settings.language.option.ptBR": "Português (Brasil)",
- "settings.language.option.enUS": "Inglês (Estados Unidos)",
- "settings.language.option.esES": "Espanhol (Espanha)",
- "settings.language.option.ruRU": "Russo",
- "settings.language.option.jaJP": "Japonês",
- "settings.language.option.zhTW": "Chinês Tradicional",
- "settings.themeJson.title": "Theme JSON",
- "settings.themeJson.subtitle": "Cole o JSON do tema, aplique e persista instantaneamente.",
- "settings.themeJson.apply": "Aplicar JSON",
- "settings.themeJson.restoreDefault": "Restaurar tema padrão",
- "mode.query": "Query",
- "mode.ddl": "DDL",
- "mode.sql": "SQL",
- "sidebar.left.close": "Fechar barra lateral esquerda",
- "sidebar.left.open": "Reabrir barra lateral esquerda",
- "sidebar.right.close": "Fechar barra lateral direita",
- "sidebar.right.open": "Reabrir barra lateral direita",
- "connection.completedTitle": "Conexão concluída",
- "connection.clearCanvasPrompt": "Deseja limpar o canvas atual para começar com a nova conexão?",
- "connection.close": "Fechar gerenciador de conexões",
- "connection.refreshHealth": "Atualizar saúde da conexão",
- "common.details": "Detalhes",
- "common.cancel": "Cancelar",
- "common.keep": "Manter",
- "common.clear": "Limpar",
- "zoom.out": "Diminuir zoom",
- "zoom.in": "Aumentar zoom",
- "zoom.fit": "Ajustar zoom à tela",
- "zoom.level": "Nível de zoom",
- "settings.theme.mode": "Modo de tema",
- "diagnostics.category.canvas": "Integridade do Canvas",
- "diagnostics.category.output": "Saída e Execução",
- "diagnostics.category.session": "Sessão e Segurança",
- "diagnostics.category.notice": "Avisos em Tempo de Execução",
- "diagnostics.summary.ok": "Sistema sem problemas",
- "diagnostics.summary.warningCount": "{0} aviso(s) detectado(s)",
- "diagnostics.summary.errorCount": "{0} erro(s) detectado(s)",
- "diagnostics.canvasMigration": "Migração de Canvas",
- "diagnostics.recommendation.resaveFile": "Salve novamente o arquivo para atualizar para a versão mais recente do schema.",
- "diagnostics.canvasState.name": "Estado do Canvas",
- "diagnostics.canvasState.recommendation": "Adicione pelo menos um {0} e um {1}",
- "diagnostics.canvasState.empty": "Canvas vazio - nenhum nó presente",
- "diagnostics.canvasState.counts": "{0} nó(s), {1} conexão(ões)",
- "diagnostics.validation.name": "Erros de Validação",
- "diagnostics.validation.recommendation": "Corrija os nós destacados antes de abrir a prévia de saída",
- "diagnostics.validation.errorWithWarnings": "{0} erro(s) e {1} aviso(s) no grafo",
- "diagnostics.validation.warningOnly": "{0} aviso(s) no grafo",
- "diagnostics.validation.none": "Sem problemas de validação",
- "diagnostics.orphan.name": "Nós Órfãos",
- "diagnostics.orphan.recommendation": "Use a limpeza de órfãos para remover nós sem uso",
- "diagnostics.orphan.count": "{0} nó(s) não conectado(s) a nenhuma saída",
- "diagnostics.orphan.none": "Nenhum nó órfão detectado",
- "diagnostics.naming.name": "Convenções de Nome",
- "diagnostics.naming.recommendation": "Use correção automática quando a conformidade estiver abaixo de 100%",
- "diagnostics.naming.conformance": "Conformidade de nomes: {0}%",
- "diagnostics.naming.ok": "Todos os aliases seguem as convenções (100%)",
- "diagnostics.queryCompilation.name": "Compilação SQL ao Vivo",
- "diagnostics.queryCompilation.recommendation": "Revise os diagnósticos SQL quando houver erros/avisos",
- "diagnostics.queryCompilation.errorFallback": "A compilação SQL ao vivo reportou erros.",
- "diagnostics.queryCompilation.warningCounts": "{0} item(ns) de diagnóstico, {1} aviso(s) de guardrail.",
- "diagnostics.queryCompilation.ok": "SQL ao vivo compilado sem diagnósticos.",
- "diagnostics.previewSafety.name": "Segurança da Prévia",
- "diagnostics.previewSafety.recommendation": "A prévia executa apenas comandos de leitura.",
- "diagnostics.previewSafety.blocked": "O SQL atual altera dados e foi bloqueado pelo modo seguro.",
- "diagnostics.previewSafety.ok": "Verificações de segurança da prévia concluídas.",
- "diagnostics.previewExecution.name": "Execução da Prévia",
- "diagnostics.previewExecution.recommendation": "Execute a prévia e revise diagnósticos de execução",
- "diagnostics.previewExecution.failed": "Falha na execução da prévia.",
- "diagnostics.previewExecution.cancelled": "Execução da prévia cancelada.",
- "diagnostics.previewExecution.done": "{0} linha(s) em {1}ms.",
- "diagnostics.previewExecution.none": "Nenhum problema de execução de prévia detectado.",
- "diagnostics.ddlCompilation.name": "Compilação DDL",
- "diagnostics.ddlCompilation.recommendation": "Corrija diagnósticos de compilação DDL antes de executar",
- "diagnostics.ddlCompilation.failed": "Falha na compilação DDL.",
- "diagnostics.ddlCompilation.warningCount": "{0} aviso(s) reportado(s) pelo compilador DDL.",
- "diagnostics.ddlCompilation.ok": "Compilação DDL concluída com sucesso.",
- "diagnostics.ddlOutput.name": "Saída DDL",
- "diagnostics.ddlOutput.recommendation": "Complete os nós DDL até gerar ao menos um statement",
- "diagnostics.ddlOutput.none": "Nenhum statement DDL gerado ainda.",
- "diagnostics.ddlOutput.lines": "{0} linha(s) de DDL gerada(s).",
- "diagnostics.undo.name": "Histórico de Desfazer",
- "diagnostics.undo.recommendation": "O histórico fica apenas em memória; salve o canvas regularmente.",
- "diagnostics.undo.saved": "Canvas salvo (sem mudanças pendentes).",
- "diagnostics.undo.unsavedDeep": "Mudanças não salvas com {0} passos de desfazer.",
- "diagnostics.undo.unsaved": "Mudanças não salvas - {0} passo(s) de desfazer disponível(is).",
- "diagnostics.report.title": "DBWeaver - Relatório de Diagnóstico",
- "diagnostics.report.generated": "Gerado",
- "diagnostics.report.overall": "Resumo",
- "diagnostics.report.details": "Detalhes",
- "diagnostics.report.recommendation": "Recomendação",
- "diagnostics.report.lastCheck": "Última verificação",
- "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
- "node.datetimeFormat": "AAAA-MM-DDTHH:mm:ss",
- "preview.providerLabel": "Provedor",
- "preview.ddlDiagnosticsHint": "Detalhes de erros/avisos disponíveis em Diagnósticos.",
- "preview.schemaAnalysis.run": "Executar análise",
- "preview.schemaAnalysis.cancel": "Cancelar",
- "preview.schemaAnalysis.issues": "Issues",
- "preview.schemaAnalysis.clearFilters": "Limpar filtros",
- "preview.schemaAnalysis.clearBlacklist": "Limpar blacklist",
- "preview.schemaAnalysis.severity": "Severidade",
- "preview.schemaAnalysis.severity.info": "Info",
- "preview.schemaAnalysis.severity.warning": "Aviso",
- "preview.schemaAnalysis.severity.critical": "Crítico",
- "preview.schemaAnalysis.rule": "Regra",
- "preview.schemaAnalysis.rule.fkCatalogInconsistent": "Catálogo de FK inconsistente",
- "preview.schemaAnalysis.rule.missingFk": "FK ausente",
- "preview.schemaAnalysis.rule.namingConventionViolation": "Violação de convenção de nomes",
- "preview.schemaAnalysis.rule.lowSemanticName": "Nome com baixa semântica",
- "preview.schemaAnalysis.rule.missingRequiredComment": "Comentário obrigatório ausente",
- "preview.schemaAnalysis.rule.nf1HintMultiValued": "Indício 1FN: multi-valorado",
- "preview.schemaAnalysis.rule.nf2HintPartialDependency": "Indício 2FN: dependência parcial",
- "preview.schemaAnalysis.rule.nf3HintTransitiveDependency": "Indício 3FN: dependência transitiva",
- "preview.schemaAnalysis.minConfidence": "Confiança mínima",
- "preview.schemaAnalysis.tableFilter": "Filtro de tabela",
- "preview.schemaAnalysis.tableFilterWatermark": "schema.tabela",
- "preview.schemaAnalysis.ignore": "Filtros de execução",
- "preview.schemaAnalysis.ignoreViews": "Ignorar views e materialized views",
- "preview.schemaAnalysis.blacklist": "Blacklist de tabelas",
- "preview.schemaAnalysis.blacklistAdd": "Adicionar",
- "preview.schemaAnalysis.blacklistRemove": "Remover selecionada",
- "preview.schemaAnalysis.ignoreTable.placeholder": "schema.tabela",
- "preview.schemaAnalysis.details": "Detalhes",
- "preview.schemaAnalysis.evidence": "Evidências",
- "preview.schemaAnalysis.suggestions": "Sugestões",
- "preview.schemaAnalysis.ruleDiagnostics": "Diagnósticos da regra",
- "preview.schemaAnalysis.sqlCandidates": "SQL Candidates",
- "preview.schemaAnalysis.copySql": "Copiar SQL",
- "preview.schemaAnalysis.applyToCanvas": "Aplicar no canvas",
- "preview.schemaAnalysis.summary.issues": "Issues:",
- "preview.schemaAnalysis.summary.rawPrefix": "(bruto:",
- "preview.schemaAnalysis.summary.critical": "| Crítico:",
- "preview.schemaAnalysis.summary.warning": "| Aviso:",
- "preview.schemaAnalysis.summary.info": "| Info:",
- "preview.schemaAnalysis.state.metadataUnavailable": "Metadata indisponível para análise estrutural.",
- "preview.schemaAnalysis.state.cancelled": "Análise cancelada pelo usuário.",
- "preview.schemaAnalysis.state.partialTimeout": "Análise finalizada parcialmente por timeout.",
- "preview.schemaAnalysis.state.failed": "Falha na análise estrutural.",
- "preview.schemaAnalysis.state.empty": "Nenhum problema estrutural inferível foi detectado.",
- "preview.schemaAnalysis.state.noFilterMatch": "Nenhuma issue corresponde aos filtros selecionados.",
- "preview.schemaAnalysis.state.noIssueSelected": "Nenhuma issue selecionada.",
- "preview.schemaAnalysis.state.noSqlCandidate": "Nenhum SQL candidate disponível.",
- "preview.schemaAnalysis.actionBlockedTooltip": "Ação indisponível para o nível de risco ou capacidade atual.",
- "common.navigate": "Navegar",
- "common.close": "Fechar",
- "common.esc": "Esc",
- "common.ms": "ms",
- "common.zero": "0",
- "diagnostics.tip": "Dica: verifique Diagnósticos sempre que preview/saída reportar avisos ou erros.",
- "nodesList.empty": "Nenhum nó encontrado",
- "nodesList.emptyHint": "Ajuste o termo de busca para explorar os tipos disponíveis",
- "schema.emptyFiltered": "Nenhum objeto encontrado para o filtro atual",
- "start.lastSnapshot": "Último snapshot",
- "app.brandBadge": "VS",
- "property.tab.properties": "Propriedades",
- "property.tab.projectSettings": "Configurações do Projeto",
- "property.nodeType": "TIPO DE NÓ",
- "property.selectNodeHint": "Selecione um nó para editar suas propriedades.",
- "property.namingConventions": "Convenções de Nomenclatura",
- "property.aliasConvention": "Convenção de alias",
- "property.enforceAliasNaming": "Forçar nomenclatura de alias",
- "property.warnReservedSql": "Alertar sobre palavras reservadas SQL",
- "property.maxAliasLength": "Tamanho máximo do alias",
- "property.maxAliasLengthDefault": "64",
- "property.namingSettingsHint": "Essas configurações são por projeto e são usadas por validação e helpers de nomenclatura.",
- "start.tips": "Dicas",
- "start.tips.quick": "Dicas rápidas",
- "start.tips.item1": "1. Clique em Novo Diagrama para iniciar do zero.",
- "start.tips.item2": "2. Use templates para acelerar protótipos.",
- "start.tips.item3": "3. Abra conexões salvas para carregar tabelas reais.",
- "start.tips.shortcut": "Atalho: CTRL+SHIFT+P abre a paleta de comandos.",
- "start.workspace": "WORKSPACE",
- "start.resumeTitle": "Continuar de onde parou",
- "start.resumeSubtitle": "Retome rapidamente um projeto recente ou comece um novo diagrama.",
- "start.chip.quickFlow": "Fluxo rápido",
- "start.chip.templates": "Templates",
- "start.chip.connections": "Conexões",
- "start.savedConnectionsTitle": "Conexões salvas",
- "start.savedConnectionsSubtitle": "Conecte-se rapidamente a um banco para carregar schema e tabelas.",
- "start.noConnectionsTitle": "Nenhuma conexão configurada ainda",
- "start.noConnectionsSubtitle": "Crie uma conexão para explorar tabelas reais no editor.",
- "start.newConnection": "+ Nova Conexão",
- "start.recentProjectsTitle": "Projetos Recentes",
- "start.searchRecent": "Buscar projeto recente...",
- "start.quickActions": "Ações rápidas",
- "start.quickActionsSubtitle": "Abra um arquivo existente ou inicie um novo diagrama.",
- "start.noRecentTitle": "Nenhum projeto recente ainda",
- "start.noRecentSubtitle": "Use o card de ações rápidas acima para começar.",
- "start.exploreTemplates": "Explorar templates",
- "start.templatesFavoritesHint": "Favoritos no topo",
- "start.favoriteTemplate": "Favoritar template",
- "node.columnSetPreview": "Prévia de ColumnSet",
- "node.view": "VIEW",
- "node.tableDefinition": "Definição da Tabela",
- "node.join": "JOIN",
- "node.window.addPartition": "Adicionar slot PARTITION BY",
- "node.window.removePartition": "Remover slot PARTITION BY",
- "node.window.addOrder": "Adicionar slot ORDER BY",
- "node.window.removeOrder": "Remover slot ORDER BY",
- "sql.keyword.select": "SELECT",
- "sql.keyword.from": "FROM",
- "sql.keyword.join": "JOIN",
- "sql.keyword.where": "WHERE",
- "sql.keyword.limit": "LIMIT",
- "sqlImporter.close": "Fechar importador SQL",
- "sqlImporter.report.imported": "Importados",
- "sqlImporter.report.partial": "Parciais",
- "sqlImporter.report.skipped": "Ignorados",
- "sqlImporter.confirmClearCanvas": "A importação SQL irá limpar o canvas atual. Deseja continuar?",
- "sqlImporter.confirmProceed": "Continuar importação",
- "benchmark.close": "Fechar benchmark",
- "benchmark.p95": "P95",
- "benchmark.n": "N",
- "liveSql.safePreview": "MODO DE PRÉVIA SEGURA",
- "liveSql.title": "SQL AO VIVO",
- "liveSql.blocked": "BLOQUEADO",
- "liveSql.copy": "Copiar",
- "liveSql.format": "Formatar",
- "liveSql.benchmark": "Benchmark",
- "liveSql.explain": "Explain",
- "liveSql.actionsHint": "Ferramentas de desempenho",
- "ddl.dialog.title": "Executar DDL",
- "ddl.dialog.execute": "Executar",
- "ddl.dialog.cancel": "Cancelar",
- "ddl.dialog.close": "Fechar",
- "ddl.dialog.stopOnError": "Parar na primeira falha",
- "ddl.dialog.confirmDestructive": "Confirmo execução de statements destrutivos (DROP TABLE)",
- "ddl.dialog.reviewBeforeRun": "Revise o script DDL antes de confirmar.",
- "ddl.dialog.confirmQuestion": "Confirma a execução do DDL no banco conectado?",
- "ddl.dialog.irreversibleWarning": "Esta ação pode alterar o schema de forma irreversível.",
- "ddl.dialog.mustConfirmDestructive": "Confirme a execução destrutiva para continuar.",
- "ddl.dialog.executing": "Executando...",
- "ddl.execute.result.summary": "Statements: {0} | Sucesso: {1} | Falhas: {2} | Tempo: {3:0}ms",
- "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
- "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
- "ddl.execute.result.failed": "Falha ao executar DDL.",
- "ddl.execute.result.cancelled": "Execução cancelada pelo usuário.",
- "ddl.execute.result.cancelledDetails": "A execução DDL foi interrompida antes da conclusão.",
- "context.deleteSingle": "Excluir {0}",
- "context.deleteMultiple": "Excluir {0} nós",
- "context.bringForward": "Trazer para frente (Ctrl+PgUp)",
- "context.sendBackward": "Enviar para trás (Ctrl+PgDown)",
- "context.bringToFront": "Trazer para o topo (Ctrl+Shift+PgUp)",
- "context.sendToBack": "Enviar para o fundo (Ctrl+Shift+PgDown)",
- "context.normalizeLayers": "Normalizar camadas",
- "context.deleteWire": "Excluir conexão",
- "context.addNode": "Adicionar nó (Shift+A)",
- "context.undoWithDescription": "Desfazer {0}",
- "context.redo": "Refazer",
- "shortcuts.windowTitle": "Atalhos de Teclado",
- "shortcuts.headerTitle": "DBWeaver - Atalhos",
- "shortcuts.headerHint": "Dica: use CTRL+SHIFT+P para abrir a Command Palette e pesquisar comandos.",
- "shortcuts.filterWatermark": "Filtrar atalhos por tecla ou ação...",
- "shortcuts.resultCount": "{0} atalhos",
- "shortcuts.resultFilter": "{0} resultado(s) para \"{1}\"",
- "shortcuts.noneFound": "Nenhum atalho encontrado.",
- "shortcuts.section.fileGeneral": "Arquivo e geral",
- "shortcuts.section.editing": "Edição",
- "shortcuts.section.canvasNavigation": "Canvas e navegação",
- "shortcuts.section.zoomPanPrecision": "Zoom, pan e precisão",
- "shortcuts.section.previewInspection": "Preview e inspeção",
- "shortcuts.key.deleteOrBackspace": "Del ou Backspace",
- "shortcuts.key.middleDrag": "Botão do meio + arrastar",
- "shortcuts.key.rightDrag": "Botão direito + arrastar",
- "shortcuts.key.spaceDrag": "Space + arrastar",
- "shortcuts.key.altLeftDrag": "Alt + arrastar esquerdo",
- "shortcuts.key.arrows": "Setas",
- "shortcuts.key.shiftArrows": "Shift + Setas",
- "shortcuts.action.openShortcutScreen": "Abrir esta tela de atalhos",
- "shortcuts.action.newCanvas": "Novo canvas",
- "shortcuts.action.openFile": "Abrir arquivo",
- "shortcuts.action.save": "Salvar",
- "shortcuts.action.saveAs": "Salvar como",
- "shortcuts.action.commandPalette": "Command Palette",
- "shortcuts.action.undo": "Desfazer",
- "shortcuts.action.redo": "Refazer",
- "shortcuts.action.selectAll": "Selecionar todos",
- "shortcuts.action.deleteSelection": "Excluir seleção",
- "shortcuts.action.closeOverlayCancel": "Fechar overlays / cancelar ações",
- "shortcuts.action.openNodeSearch": "Abrir busca de nodes",
- "shortcuts.action.resetViewport": "Reset de viewport",
- "shortcuts.action.centerSelection": "Centralizar seleção",
- "shortcuts.action.fitSelection": "Enquadrar seleção",
- "shortcuts.action.autoLayout": "Auto Layout",
- "shortcuts.action.toggleSnapToGrid": "Toggle Snap to Grid",
- "shortcuts.action.bringForward": "Trazer para frente",
- "shortcuts.action.sendBackward": "Enviar para trás",
- "shortcuts.action.bringToFront": "Trazer para o topo",
- "shortcuts.action.sendToBack": "Enviar para o fundo",
- "shortcuts.action.zoomInOut": "Zoom in / out",
- "shortcuts.action.pan": "Pan",
- "shortcuts.action.temporaryPan": "Pan temporário",
- "shortcuts.action.alternatePan": "Pan alternativo",
- "shortcuts.action.fineNudge": "Nudge fino da seleção",
- "shortcuts.action.fastNudge": "Nudge acelerado",
- "shortcuts.action.togglePreview": "Toggle data preview",
- "shortcuts.action.explainPlan": "Explain plan",
- "shortcuts.action.runPreview": "Run preview",
- "shortcuts.action.connectionManager": "Connection manager",
- "shortcuts.action.flowVersionHistory": "Flow version history",
- "shortcuts.resetAll": "Resetar tudo",
- "shortcuts.customized": "Customizado",
- "shortcuts.default": "Padrão",
- "shortcuts.apply": "Aplicar",
- "shortcuts.reset": "Resetar",
- "shortcuts.status.resetAllSuccess": "Todos os atalhos foram resetados para o padrão.",
- "shortcuts.status.updated": "Atalho atualizado.",
- "shortcuts.status.reset": "Atalho resetado para o padrão.",
- "shortcuts.status.updateFailed": "Não foi possível atualizar o atalho.",
- "toast.severity.success": "Sucesso",
- "toast.severity.warning": "Aviso",
- "toast.severity.error": "Erro",
- "toast.details.success": "Detalhes de Sucesso",
- "toast.details.warning": "Detalhes de Aviso",
- "toast.details.error": "Detalhes de Erro",
- "diagnostics.area.cteEditor": "Editor de CTE",
- "diagnostics.area.viewEditor": "Editor de View",
- "diagnostics.area.subEditor": "Sub-editor",
- "diagnostics.cteEditor.restoreParentFailed": "Falha ao restaurar o canvas pai. As edições do CTE foram descartadas.",
- "diagnostics.recommendation.reloadFileIfNeeded": "Recarregue o arquivo se necessário.",
- "diagnostics.viewEditor.exitFailed": "Não foi possível sair: {0}",
- "diagnostics.viewEditor.canvasIncomplete": "o canvas está incompleto.",
- "diagnostics.viewEditor.exitRecommendation": "Conecte um ResultOutput válido ou use o comando de descarte.",
- "diagnostics.viewEditor.restoreParentFailed": "Falha ao restaurar o canvas pai. O subgrafo foi descartado.",
- "diagnostics.subEditor.executeFailed": "Falha ao executar ação do editor: {0}",
- "diagnostics.subEditor.executeRecommendation": "Tente novamente. Se persistir, recarregue o canvas.",
- "diagnostics.canvasMigration.openWarning": "Abertura: {0}",
- "diagnostics.canvasMigration.sessionRestoreWarning": "Restauração de sessão: {0}",
- "diagnostics.canvasMigration.versionRestoreWarning": "Restauração de versão: {0}",
- "diagnostics.recommendation.resaveLatestSchema": "Revise os diagnósticos e salve novamente o canvas para persistir o schema mais recente.",
- "diagnostics.recommendation.saveMigratedSchema": "Revise os diagnósticos e salve o canvas para persistir o schema migrado.",
- "file.saveDialog.title": "Salvar Canvas",
- "file.saveDialog.suggestedName": "Query1",
- "file.save.success": "Canvas salvo com sucesso.",
- "file.save.failedWithReason": "Falha ao salvar: {0}",
- "file.openDialog.title": "Abrir Canvas",
- "file.openDialog.canvasType": "Canvas SQL Architect",
- "file.open.failedWithReason": "Falha ao abrir: {0}",
- "file.open.success": "Canvas aberto com sucesso.",
- "file.open.successWithWarnings": "Canvas aberto com avisos.",
- "session.restore.failedWithReason": "Falha ao restaurar: {0}",
- "session.restore.successWithWarnings": "Sessão restaurada com avisos.",
- "session.restore.success": "Sessão restaurada com sucesso.",
- "export.documentation.dialogTitle": "Exportar Documentação do Fluxo",
- "export.documentation.success": "Documentação exportada com sucesso.",
- "export.documentation.failed": "Falha ao exportar documentação.",
- "export.failed.pathPermissionsHint": "Verifique o caminho do arquivo e as permissões.",
- "export.nodeNotFound": "Nenhum nó de Exportação {0} foi encontrado no canvas. Adicione um pelo menu de busca de nós.",
- "export.dialogTitleByExtension": "Exportar como {0}",
- "export.success": "Exportação concluída com sucesso.",
- "export.failed": "Falha na exportação.",
- "fileHistory.currentFile.none": "Nenhum arquivo selecionado",
- "fileHistory.status.saveFirst": "Salve o canvas primeiro para habilitar o histórico local.",
- "fileHistory.status.noneFound": "Nenhuma versão local encontrada ainda. Salve este arquivo para criar entradas no histórico.",
- "fileHistory.status.countAvailable": "{0} versão(ões) local(is) disponível(is).",
- "fileHistory.restore.failedWithReason": "Falha ao restaurar: {0}",
- "fileHistory.restore.successFrom": "Versão restaurada de {0}.",
- "preview.status.cancelled": "Cancelado",
- "preview.status.error": "Erro",
- "preview.status.ready": "Pronto",
- "preview.runningWithMs": "Executando... {0}ms",
- "preview.runningWithTimeout": "Executando... {0}ms (timeout: {1}s)",
- "preview.runningSlowWithTimeout": "Executando... {0}ms (timeout: {1}s) · Consulta lenta, timeout em {2}s",
- "explain.errorWithReason": "Erro no explain plan: {0}",
- "explain.noSql": "Nenhum SQL para explicar. Monte uma consulta no canvas primeiro.",
- "ddl.compilationFailed": "Falha na compilação",
- "ddl.compileErrorWithReason": "Erro de compilação DDL: {0}",
- "command.undo.name": "Desfazer",
- "command.undo.description": "Desfazer última ação",
- "command.redo.name": "Refazer",
- "command.redo.description": "Refazer última ação desfeita",
- "command.addNode.name": "Adicionar nó",
- "command.addNode.description": "Abrir menu de busca para adicionar um nó",
- "command.bringForward.name": "Trazer para frente",
- "command.bringForward.description": "Mover nós selecionados uma camada para frente",
- "command.sendBackward.name": "Enviar para trás",
- "command.sendBackward.description": "Mover nós selecionados uma camada para trás",
- "command.bringToFront.name": "Trazer para o topo",
- "command.bringToFront.description": "Mover nós selecionados para a camada superior",
- "command.sendToBack.name": "Enviar para o fundo",
- "command.sendToBack.description": "Mover nós selecionados para a camada inferior",
- "command.normalizeLayers.name": "Normalizar camadas",
- "command.normalizeLayers.description": "Compactar índices de camada para uma ordem limpa de 0..N",
- "tooltip.cleanupOrphans": "Remover nós órfãos não conectados ao output (Ctrl+Z para desfazer)",
- "main.orphanSuffix": "Órfão(s)",
- "tooltip.autoFixAliasNaming": "Corrigir aliases para snake_case (Ctrl+Z para desfazer)",
- "main.namingPrefix": "Nomenclatura",
- "fileHistory.compressedLabel": "Comprimido:",
- "schema.itemsSuffix": "item(ns)",
- "property.panel.title": "Propriedades",
- "property.panel.multiSelected": "{0} nós selecionados",
- "sqlImporter.status.pasteSelect": "Cole um SELECT acima e clique em Importar.",
- "sqlImporter.status.inputTooLarge": "A entrada SQL é muito grande ({0:N0} caracteres). O limite é {1:N0}. Divida a consulta ou aumente o limite de importação.",
- "sqlImporter.status.parsing": "Analisando SQL...",
- "sqlImporter.status.done": "Concluído - {0} importado(s), {1} parcial(is), {2} ignorado(s).",
- "sqlImporter.status.cancelledByUser": "Importação cancelada pelo usuário.",
- "sqlImporter.status.timeout": "A importação excedeu o tempo após {0:0.#}s. Tente uma consulta menor ou aumente o timeout.",
- "sqlImporter.status.parseError": "Erro de parsing: {0}",
- "sqlImporter.status.clearConfirmationRequired": "A importação SQL vai limpar o canvas atual. Confirme para continuar.",
- "sqlImporter.status.clearConfirmationCancelled": "Importação cancelada. O canvas atual foi mantido.",
- "diagnostics.area.undoRedoTransaction": "Transação Desfazer/Refazer",
- "undoRedo.rollbackExecuted": "Rollback executado para '{0}' ({1} operação(ões) revertida(s)).",
- "undoRedo.rollbackRecommendation": "Revise o estado do canvas e tente novamente a ação, se necessário.",
- "node.preview.noCatalog": "Catálogo indisponível",
- "connection.error.searchMenuNotInitialized": "menu de busca não inicializado",
- "connection.error.timeoutReachability": "Connection timed out - check that the server is reachable and increase the timeout if needed.",
- "connection.error.authenticationFailedForProvider": "Authentication failed - verify username and password for {0}.",
- "connection.error.databaseNotFoundForProvider": "Database not found - confirm the database name exists on {0}.",
- "connection.error.hostNotFound": "Host not found - check the server address and DNS resolution.",
- "connection.error.portRefused": "Port connection refused - check the port number and that the server is running / firewall rules allow access.",
- "connection.error.sslTls": "SSL/TLS error - check the server's SSL configuration or disable SSL for local connections.",
- "connection.error.timeoutOverloaded": "Connection timed out - the server may be overloaded or unreachable. Try increasing the timeout.",
- "connection.error.insufficientPrivileges": "Insufficient privileges - the user may lack permission to connect to this database.",
- "diagnostics.area.connection": "Conexão",
- "connection.warning.canvasMayContainOldTables": "O canvas ainda pode conter tabelas de uma conexão anterior.",
- "connection.warning.canvasMayContainOldTablesRecommendation": "Limpe o canvas manualmente ou reconecte e escolha manter/limpar novamente.",
- "undoRedo.transaction.unnamed": "transação sem nome",
- "benchmark.runLabelDefault": "Execução 1",
- "benchmark.runLabelPattern": "Execução {0}",
- "benchmark.status.failedWithReason": "Falha no benchmark: {0}",
- "benchmark.status.noSql": "Nenhum SQL para benchmark - monte uma consulta primeiro.",
- "benchmark.status.warmupProgress": "Aquecimento {0}/{1}...",
- "benchmark.status.iterationProgress": "Iteração {0}/{1}...",
- "benchmark.status.done": "Concluído - {0}",
- "benchmark.status.cancelled": "Benchmark cancelado.",
- "app.windowTitle": "DBWeaver",
- "preview.error.safePreviewBlocked": "Modo Preview Seguro: comandos que alteram dados (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) não podem ser executados no preview.",
- "preview.error.noActiveConnection": "Nenhuma conexão de banco ativa. Conecte-se a um banco primeiro.",
- "sqlImporter.error.selectFromNotFound": "Não foi possível encontrar SELECT ... FROM na consulta.",
- "sqlImporter.error.fromClauseParseFailed": "Não foi possível interpretar a cláusula FROM.",
- "sqlImporter.error.syntaxUnterminatedString": "Erro de sintaxe na linha {0}, coluna {1}: literal de string não terminada.",
- "sqlImporter.error.missingClosingParenthesis": "faltando ')' de fechamento",
- "sqlImporter.error.unexpectedClosingParenthesis": "')' inesperado",
- "sqlImporter.error.syntaxAtLineColumn": "Erro de sintaxe na linha {0}, coluna {1}: {2}.",
- "errorDiagnostics.safePreview.label": "Bloqueado pelo Modo Preview Seguro",
- "errorDiagnostics.safePreview.friendly": "Este SQL contém um comando de mutação de dados e não pode ser executado no preview.",
- "errorDiagnostics.safePreview.suggestion": "Remova ou substitua o comando de mutação (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) antes de executar o preview.",
- "errorDiagnostics.connection.label": "Falha de conexão",
- "errorDiagnostics.connection.friendly": "Não foi possível alcançar o servidor de banco. O host pode estar indisponível, inacessível ou bloqueando conexões.",
- "errorDiagnostics.connection.suggestion": "Verifique endereço e porta do servidor, confirme que o banco está em execução e confira as regras de firewall.",
- "errorDiagnostics.authorization.label": "Erro de autorização",
- "errorDiagnostics.authorization.friendly": "As credenciais atuais não têm permissão para executar esta operação.",
- "errorDiagnostics.authorization.suggestion": "Confirme que o usuário do banco tem privilégios de SELECT no schema/tabela de destino, ou contate o DBA.",
- "errorDiagnostics.timeout.label": "Timeout de consulta",
- "errorDiagnostics.timeout.friendly": "A consulta demorou demais para concluir e foi cancelada pelo servidor ou cliente.",
- "errorDiagnostics.timeout.suggestion": "Adicione WHERE ou LIMIT para reduzir o volume de dados, ou aumente o timeout da consulta nas configurações de conexão.",
- "errorDiagnostics.schema.label": "Erro de schema",
- "errorDiagnostics.schema.friendly": "Uma tabela, coluna ou objeto referenciado não foi encontrado no banco.",
- "errorDiagnostics.schema.suggestion": "Verifique nomes de tabela/coluna e confirme que o schema corresponde à conexão ativa.",
- "errorDiagnostics.syntax.label": "Erro de sintaxe SQL",
- "errorDiagnostics.syntax.friendly": "A consulta contém erro de sintaxe e não pôde ser interpretada pelo mecanismo do banco.",
- "errorDiagnostics.syntax.suggestion": "Revise o SQL destacado procurando typos, parênteses desalinhados ou cláusulas não suportadas pelo provider ativo.",
- "errorDiagnostics.compatibility.label": "Erro de compatibilidade",
- "errorDiagnostics.compatibility.friendly": "Uma função, operador ou construção de sintaxe não é suportada pelo provider de banco ativo.",
- "errorDiagnostics.compatibility.suggestion": "Troque para o provider correto na barra SQL, ou substitua a construção não suportada por equivalente.",
- "errorDiagnostics.unknown.label": "Erro inesperado",
- "errorDiagnostics.unknown.friendly": "Ocorreu um erro ao executar a consulta de preview.",
- "errorDiagnostics.unknown.suggestion": "Verifique os detalhes técnicos abaixo e confirme que o canvas está configurado corretamente.",
- "error.mainWindow.invalidDataContext": "O DataContext da MainWindow deve ser um ShellViewModel.",
- "error.mainWindow.canvasNotInitialized": "CanvasViewModel não foi inicializado.",
- "error.mainWindow.ddlPreviewUnavailable": "Preview DDL indisponível para o canvas atual.",
- "themeJson.editor.template": "{\n \"meta\": { \"name\": \"Tema Personalizado\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
- "themeJson.error.pasteBeforeApply": "Cole um JSON de tema antes de aplicar.",
- "themeJson.error.invalidJson": "JSON inválido: {0}",
- "themeJson.error.emptyPayload": "JSON inválido: payload vazio.",
- "themeJson.error.invalidTheme": "Tema inválido: {0}",
- "themeJson.error.appliedButSaveFailed": "Tema aplicado, mas falhou ao salvar: {0}",
- "themeJson.success.appliedAndSaved": "Tema JSON aplicado e salvo.",
- "themeJson.success.customRemoved": "Tema personalizado removido. Reinicie o app para voltar totalmente ao tema padrão.",
- "themeJson.error.restoreDefaultFailed": "Falha ao restaurar tema padrão: {0}",
- "themeValidator.error.configNull": "A configuração de tema está nula.",
- "themeValidator.warning.noSections": "O tema não possui seções de cores ou tipografia; nada para aplicar.",
- "themeValidator.warning.invalidColor": "{0} possui cor inválida '{1}'. Esta chave será ignorada.",
- "themeValidator.warning.sizeOutOfRange": "{0}={1} está fora do intervalo (8..48). Esta chave será ignorada.",
- "queryExecutor.error.openConnectionMethodNotFound": "Não foi possível encontrar o método OpenConnectionAsync no orquestrador",
- "queryExecutor.error.openConnectionInvokeFailed": "Falha ao invocar OpenConnectionAsync",
- "ddlImporter.warning.viewSelectNotReconstructable": "View '{0}': o SELECT da view não pode ser reconstruído visualmente - edite manualmente no subcanvas.",
- "ddlImporter.error.tableNotFoundInMetadata": "A tabela '{0}' não foi encontrada nos metadados atuais.",
- "main.window.untitled": "Sem título",
- "main.subEditor.noSeedProvided": "Nenhum seed de subeditor foi fornecido para {0}.",
- "main.layerOrder.bringToFront": "Trazer para frente",
- "main.layerOrder.sendToBack": "Enviar para trás",
- "main.layerOrder.bringForward": "Avançar camada",
- "main.layerOrder.sendBackward": "Recuar camada",
- "main.layerOrder.normalizeLayers": "Normalizar camadas",
- "export.fileType.html": "Arquivos HTML",
- "export.fileType.json": "Arquivos JSON",
- "export.fileType.csv": "Arquivos CSV",
- "export.fileType.excel": "Arquivos Excel",
- "commandPalette.templatePrefix": "Template: {0}",
- "themeLoader.status.notFoundWithPath": "Arquivo de tema não encontrado: {0}",
- "themeLoader.status.deserializedNull": "O JSON de tema foi desserializado para null.",
- "themeLoader.status.loaded": "JSON de tema carregado com sucesso.",
- "credential.error.ciphertextTooShort": "O blob de texto cifrado está muito curto.",
- "credential.error.dpapiWindowsOnly": "DPAPI está disponível apenas no Windows.",
- "credential.warning.loadVaultFailed": "Falha ao carregar o cofre de credenciais '{0}': {1}",
- "credential.warning.persistVaultFailed": "Falha ao persistir o cofre de credenciais '{0}': {1}",
- "snippetStore.warning.loadFailed": "Falha ao carregar snippets de '{0}': {1}",
- "snippetStore.warning.saveFailed": "Falha ao salvar snippets: {0}",
- "flowVersionStore.warning.loadFailed": "Falha ao carregar versões de fluxo de '{0}': {1}",
- "flowVersionStore.warning.saveFailed": "Falha ao salvar versões de fluxo: {0}",
- "queryExecutor.error.queryEmpty": "A consulta não pode estar vazia",
- "queryExecutor.error.providerNotSupported": "O provider {0} não é suportado",
- "queryExecutor.error.singleStatementOnly": "O preview aceita apenas uma única instrução SQL.",
- "queryExecutor.error.queryEmptyWithPeriod": "A consulta não pode estar vazia.",
- "queryExecutor.error.readOnlyOnly": "O modo preview suporta apenas instruções SQL somente leitura.",
- "queryExecutor.error.namedParametersNotSupported": "O modo preview não suporta parâmetros nomeados na execução SQL. Use literais seguros inline ou execute a consulta fora do preview.",
- "queryExecutor.error.positionalParametersNotSupported": "O modo preview não suporta placeholders posicionais ('?' ou '$1').",
- "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "Align selected nodes to the bottom edge",
- "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "Align selected nodes to the leftmost edge",
- "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "Align selected nodes to the rightmost edge",
- "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "Align selected nodes to the topmost edge",
- "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "Apply CTE sub-canvas edits and return to the parent canvas",
- "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "Arrange nodes into logical columns automatically",
- "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "Centre selected nodes on a horizontal axis",
- "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "Centre selected nodes on a vertical axis",
- "commandPalette.description.clear_canvas_and_start_fresh": "Clear canvas and start fresh",
- "commandPalette.description.clear_node_selection": "Clear node selection",
- "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "Convert aliases to the convention configured in project settings",
- "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "Create checkpoints, compare versions side-by-side and restore a previous canvas state",
- "commandPalette.description.delete_the_selected_nodes": "Delete the selected nodes",
- "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "Discard current sub-editor edits and return to the parent canvas",
- "commandPalette.description.execute_the_current_query_in_preview": "Execute the current query in preview",
- "commandPalette.description.fit_all_nodes_into_the_visible_area": "Fit all nodes into the visible area",
- "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "Generate CSV file from the first CSV Export node",
- "commandPalette.description.generate_html_file_from_the_first_html_export_node": "Generate HTML file from the first HTML Export node",
- "commandPalette.description.generate_json_file_from_the_first_json_export_node": "Generate JSON file from the first JSON Export node",
- "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "Generate XLSX workbook from the first Excel Export node",
- "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "Inspect the query execution plan — see scan types, join strategies, and cost estimates",
- "commandPalette.description.load_a_vsaq_canvas_file": "Load a .vsaq canvas file",
- "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "Measure avg / median / p95 latency of the current SQL over N iterations",
- "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "Open isolated sub-canvas editor for the selected CTE Definition node",
- "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "Open local file version history created on each save and restore previous saved snapshots",
- "commandPalette.description.open_output_preview_modal_for_the_active_mode": "Open output preview modal for the active mode",
- "commandPalette.description.open_shortcut_reference_screen": "Open shortcut reference screen",
- "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "Open the connection manager to add, edit or switch database connections",
- "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "Paste a SELECT statement and generate nodes automatically — FROM, JOIN, WHERE, LIMIT are supported",
- "commandPalette.description.remove_all_nodes_not_connected_to_output": "Remove all nodes not connected to output",
- "commandPalette.description.reset_zoom_and_pan_to_default": "Reset zoom and pan to default",
- "commandPalette.description.save_canvas_to_a_new_file": "Save canvas to a new file",
- "commandPalette.description.save_current_canvas": "Save current canvas",
- "commandPalette.description.save_markdown_documentation_of_the_current_flow": "Save Markdown documentation of the current flow",
- "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "Save the selected nodes as a reusable snippet — insert it later via the node search menu (⇧A)",
- "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "Scan all table-source nodes on the canvas for possible join relationships based on FK conventions and naming patterns",
- "commandPalette.description.select_all_nodes_on_canvas": "Select all nodes on canvas",
- "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "Snap node positions to 16px grid (Ctrl+G)",
- "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "Spread selected nodes with equal horizontal spacing",
- "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "Spread selected nodes with equal vertical spacing",
- "commandPalette.description.zoom_into_the_canvas": "Zoom into the canvas",
- "commandPalette.description.zoom_out_of_the_canvas": "Zoom out of the canvas",
- "commandPalette.name.align_bottom": "Align Bottom",
- "commandPalette.name.align_left": "Align Left",
- "commandPalette.name.align_right": "Align Right",
- "commandPalette.name.align_top": "Align Top",
- "commandPalette.name.analyze_all_joins": "Analyze All Joins",
- "commandPalette.name.auto_fix_naming": "Auto-Fix Naming",
- "commandPalette.name.auto_layout": "Auto Layout",
- "commandPalette.name.center_horizontally": "Center Horizontally",
- "commandPalette.name.center_vertically": "Center Vertically",
- "commandPalette.name.cleanup_orphans": "Cleanup Orphans",
- "commandPalette.name.delete_selected": "Delete Selected",
- "commandPalette.name.deselect_all": "Deselect All",
- "commandPalette.name.discard_and_exit_editor": "Discard and Exit Editor",
- "commandPalette.name.distribute_horizontally": "Distribute Horizontally",
- "commandPalette.name.distribute_vertically": "Distribute Vertically",
- "commandPalette.name.edit_selected_cte": "Edit Selected CTE",
- "commandPalette.name.exit_cte_editor": "Exit CTE Editor",
- "commandPalette.name.explain_plan": "Explain Plan",
- "commandPalette.name.export_csv": "Export CSV",
- "commandPalette.name.export_documentation": "Export Documentation",
- "commandPalette.name.export_excel": "Export Excel",
- "commandPalette.name.export_html": "Export HTML",
- "commandPalette.name.export_json": "Export JSON",
- "commandPalette.name.file_save_load_history": "File Save/Load History",
- "commandPalette.name.fit_to_screen": "Fit to Screen",
- "commandPalette.name.flow_version_history": "Flow Version History",
- "commandPalette.name.import_sql_to_graph": "Import SQL to Graph",
- "commandPalette.name.keyboard_shortcuts": "Keyboard Shortcuts",
- "commandPalette.name.manage_connections": "Manage Connections",
- "commandPalette.name.new_canvas": "New Canvas",
- "commandPalette.name.open_file": "Open File",
- "commandPalette.name.reset_viewport": "Reset Viewport",
- "commandPalette.name.run_preview": "Run Preview",
- "commandPalette.name.run_query_benchmark": "Run Query Benchmark",
- "commandPalette.name.save": "Save",
- "commandPalette.name.save_as": "Save As",
- "commandPalette.name.save_selection_as_snippet": "Save Selection as Snippet",
- "commandPalette.name.select_all": "Select All",
- "commandPalette.name.toggle_preview": "Toggle Preview",
- "commandPalette.name.toggle_snap_to_grid": "Toggle Snap to Grid",
- "commandPalette.name.zoom_in": "Zoom In",
- "commandPalette.name.zoom_out": "Zoom Out",
- "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 percent restore zoom pan viewport",
- "commandPalette.tags.align_bottom_edge_selection_nodes": "align bottom edge selection nodes",
- "commandPalette.tags.align_center_middle_horizontal_nodes": "align center middle horizontal nodes",
- "commandPalette.tags.align_center_middle_vertical_nodes": "align center middle vertical nodes",
- "commandPalette.tags.align_left_edge_selection_nodes": "align left edge selection nodes",
- "commandPalette.tags.align_right_edge_selection_nodes": "align right edge selection nodes",
- "commandPalette.tags.align_top_edge_selection_nodes": "align top edge selection nodes",
- "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout view reset zoom",
- "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark performance latency timing profile measure speed",
- "commandPalette.tags.clear_selection": "clear selection",
- "commandPalette.tags.connection_database_server_host_provider_switch": "connection database server host provider switch",
- "commandPalette.tags.create_insert_search_transform": "create insert search transform",
- "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas exit apply back",
- "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte view subcanvas discard exit force",
- "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursive editor subgraph subcanvas isolate",
- "commandPalette.tags.data_results_table_panel": "data results table panel",
- "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribute space equal horizontal nodes",
- "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribute space equal vertical nodes",
- "commandPalette.tags.execute_run_sql_query_results": "execute run sql query results",
- "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan execution cost scan index join performance",
- "commandPalette.tags.export_csv_file_tabular_output_save": "export csv file tabular output save",
- "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "export excel xlsx file tabular output spreadsheet save",
- "commandPalette.tags.export_html_file_output_report_save": "export html file output report save",
- "commandPalette.tags.export_json_file_output_save": "export json file output save",
- "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "export markdown doc documentation flow save md",
- "commandPalette.tags.export_persist_copy": "export persist copy",
- "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "file history save load backup versions restore local",
- "commandPalette.tags.forward_history": "forward history",
- "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "help shortcuts hotkeys keyboard reference",
- "commandPalette.tags.highlight_mark_all_nodes": "highlight mark all nodes",
- "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "import sql paste convert graph reverse engineer query",
- "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analyze suggest detect foreign key relationships heuristic",
- "commandPalette.tags.layer_z_order_back_selected_nodes": "layer z-order back selected nodes",
- "commandPalette.tags.layer_z_order_backward_selected_nodes": "layer z-order backward selected nodes",
- "commandPalette.tags.layer_z_order_forward_selected_nodes": "layer z-order forward selected nodes",
- "commandPalette.tags.layer_z_order_front_selected_nodes": "layer z-order front selected nodes",
- "commandPalette.tags.layer_z_order_normalize_compact": "layer z-order normalize compact",
- "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout arrange columns auto organize readability",
- "commandPalette.tags.load_import_vsaq": "load import vsaq",
- "commandPalette.tags.magnify_enlarge": "magnify enlarge",
- "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "orphan unused disconnected clean delete nodes",
- "commandPalette.tags.persist_write_disk": "persist write disk",
- "commandPalette.tags.remove_erase_nodes": "remove erase nodes",
- "commandPalette.tags.rename_alias_fix_naming_convention": "rename alias fix naming convention",
- "commandPalette.tags.reset_clear_blank": "reset clear blank",
- "commandPalette.tags.revert_back_history": "revert back history",
- "commandPalette.tags.shrink_reduce": "shrink reduce",
- "commandPalette.tags.snap_grid_align_precision_position": "snap grid align precision position",
- "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet save selection reuse template favorite bookmark",
- "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "version history checkpoint diff restore snapshot compare undo flow",
- "sqlEditor.diffPreview.title": "Previa de diff transacional",
- "sqlEditor.mutation.confirmExecute": "Confirmar execucao",
- "sqlEditor.tab.closeAnyway": "Fechar mesmo assim",
- "sqlEditor.tab.keepTab": "Manter aba",
- "sqlEditor.status.ready": "Pronto.",
- "sqlEditor.telemetry.none": "Sem telemetria de execucao ainda.",
- "sqlEditor.telemetry.summary": "Instrucoes: {0} Sucesso: {1} Falhas: {2} Total: {3} ms",
- "sqlEditor.telemetry.errors.none": "Sem erros agregados.",
- "sqlEditor.diff.none": "Sem diff transacional disponivel.",
- "sqlEditor.mutation.estimate.none": "Sem estimativa de mutacao disponivel.",
- "sqlEditor.mutation.estimate.value": "Linhas afetadas estimadas: {0}",
- "sqlEditor.mutation.estimate.unavailable": "Nao foi possivel estimar as linhas afetadas automaticamente.",
- "sqlEditor.tab.closePending": "Alteracoes nao salvas detectadas. Confirme o fechamento da aba.",
- "sqlEditor.tab.noPendingClose": "Nao ha fechamento de aba pendente.",
- "sqlEditor.tab.manyWarning": "Quantidade alta de abas: {0} abas abertas.",
- "sqlEditor.mutation.pending.none": "Sem confirmacao de mutacao pendente.",
- "sqlEditor.mutation.pending.required": "A mutacao exige confirmacao antes da execucao.",
- "sqlEditor.message.empty": "Execute uma instrucao para ver mensagens.",
- "sqlEditor.message.success": "Execucao concluida com sucesso.",
- "sqlEditor.result.summary.empty": "Linhas: - Tempo: -",
- "sqlEditor.result.summary": "Linhas: {0} Tempo: {1} ms",
- "sqlEditor.file.save.canceled": "Salvamento cancelado.",
- "sqlEditor.file.save.noPath": "Nenhum caminho de destino selecionado.",
- "sqlEditor.file.save.success": "Arquivo SQL salvo.",
- "sqlEditor.file.save.failed": "Falha ao salvar arquivo SQL.",
- "sqlEditor.file.open.failed": "Falha ao abrir arquivo SQL.",
- "sqlEditor.file.open.notFound": "O arquivo SQL selecionado nao foi encontrado.",
- "sqlEditor.file.open.success": "Arquivo SQL aberto.",
- "sqlEditor.status.executing": "Executando SQL...",
- "sqlEditor.status.executingScript": "Executando script SQL...",
- "sqlEditor.status.executingStep": "Executando {0}/{1}...",
- "sqlEditor.status.canceling": "Cancelando execucao...",
- "sqlEditor.status.executingConfirmedMutation": "Executando mutacao confirmada...",
- "sqlEditor.status.mutationCanceled": "Execucao da mutacao cancelada.",
- "sqlEditor.detail.statementNotExecuted": "A instrucao nao foi executada.",
- "sqlEditor.status.success": "Execucao concluida com sucesso.",
- "sqlEditor.detail.rowsAndTime": "{0} linha(s) em {1} ms.",
- "sqlEditor.status.canceled": "Execucao cancelada.",
- "sqlEditor.status.failed": "Falha na execucao.",
- "sqlEditor.status.confirmationRequired": "Confirmacao necessaria antes da execucao.",
- "sqlEditor.error.mutationConfirmationRequired": "Confirmacao de mutacao necessaria.",
- "sqlEditor.result.tabTitle": "Resultado {0}",
- "sqlEditor.tab.closeRequiresConfirmation": "O fechamento da aba exige confirmacao.",
- "sqlEditor.tab.unsavedDetail": "Esta aba possui alteracoes nao salvas.",
- "sqlEditor.tab.closed": "Aba fechada.",
- "sqlEditor.tab.closeCanceled": "Fechamento da aba cancelado.",
- "sqlEditor.tab.closeCanceledDetail": "Aba com alteracoes nao salvas mantida aberta.",
- "sqlEditor.error.noStatementSelected": "Nenhuma instrucao SQL selecionada para execucao.",
- "sqlEditor.error.noConnection": "Nenhuma conexao ativa para execucao SQL.",
- "sqlEditor.error.executionCanceled": "A execucao SQL foi cancelada.",
- "sqlEditor.tab.scriptTitle": "Script {0}",
- "sqlEditor.guard.delete.noWhere.message": "DELETE sem WHERE pode remover todas as linhas.",
- "sqlEditor.guard.delete.noWhere.recommendation": "Adicione uma clausula WHERE restritiva antes de executar.",
- "sqlEditor.guard.delete.trivialWhere.message": "DELETE possui uma clausula WHERE trivialmente verdadeira.",
- "sqlEditor.guard.delete.trivialWhere.recommendation": "Use um filtro seletivo para atingir apenas as linhas desejadas.",
- "sqlEditor.guard.update.noWhere.message": "UPDATE sem WHERE pode afetar todas as linhas.",
- "sqlEditor.guard.update.noWhere.recommendation": "Adicione uma clausula WHERE restritiva antes de executar.",
- "sqlEditor.guard.update.trivialWhere.message": "UPDATE possui uma clausula WHERE trivialmente verdadeira.",
- "sqlEditor.guard.update.trivialWhere.recommendation": "Use um filtro seletivo para atingir apenas as linhas desejadas.",
- "sqlEditor.guard.insert.noColumnList.message": "INSERT sem lista explicita de colunas e fragil diante de mudancas de schema.",
- "sqlEditor.guard.insert.noColumnList.recommendation": "Prefira INSERT INTO tabela(col1, col2, ...) VALUES (...).",
- "sqlEditor.guard.ddl.message": "Uma instrucao DDL pode causar mudancas estruturais no banco de dados.",
- "sqlEditor.guard.ddl.recommendation": "Confirme a execucao apenas quando as mudancas de schema forem intencionais.",
- "sqlEditor.diff.unavailable.noPreview": "Sem previa de diff transacional disponivel para esta instrucao.",
- "sqlEditor.diff.unavailable.parseError": "Nao foi possivel identificar o alvo da mutacao para gerar a previa de diff transacional.",
- "sqlEditor.diff.unavailable.connection": "Previa de diff transacional indisponivel por limitacoes de conexao ou consulta.",
- "sqlEditor.diff.deleteSummary": "Previa de diff transacional (ROLLBACK garantido): tabela {0}, total de linhas antes {1}, afetadas {2}, total de linhas depois {3}.",
- "sqlEditor.diff.updateSummary": "Previa de diff transacional (ROLLBACK garantido): tabela {0}, total de linhas antes {1}, linhas candidatas afetadas {2}, total de linhas depois {3}.",
- "sqlEditor.diff.unavailable.unsupportedStatement": "A previa de diff transacional atualmente suporta apenas UPDATE e DELETE.",
- "sqlEditor.results.title": "Resultados",
- "sqlEditor.results.filterWatermark": "Filtrar resultados",
- "sqlEditor.results.rows.countZero": "0 linhas",
- "sqlEditor.results.rows.countSingle": "{0} linhas",
- "sqlEditor.results.rows.countFiltered": "{0} de {1} linhas",
- "sqlEditor.results.context.copyCell": "Copiar célula",
- "sqlEditor.results.context.copyRow": "Copiar linha",
- "sqlEditor.results.context.hideColumn": "Ocultar coluna",
- "sqlEditor.results.context.showAllColumns": "Mostrar todas as colunas",
- "sqlEditor.sidebar.messages": "MENSAGENS",
- "sqlEditor.sidebar.history": "HISTÓRICO",
- "sqlEditor.sidebar.connection.none": "Sem conexão",
- "sqlEditor.sidebar.connection.connectHint": "Conecte-se para carregar metadados e executar consultas.",
- "sqlEditor.sidebar.connection.connect": "Conectar",
- "sqlEditor.sidebar.schema.searchWatermark": "Buscar tabela ou coluna",
- "sqlEditor.sidebar.schema.reloadTooltip": "Recarregar metadados",
- "sqlEditor.sidebar.schema.connectHint": "Conecte-se para visualizar o schema completo.",
- "sqlEditor.history.searchWatermark": "Buscar no histórico",
- "sqlEditor.history.navigationHint": "Setas percorrem o histórico, Enter executa selecionado e Esc limpa a busca.",
- "sqlEditor.history.noSearchResults": "Nenhum item encontrado para a busca.",
- "sqlEditor.history.use": "Usar",
- "sqlEditor.history.copy": "Copiar",
- "sqlEditor.history.run": "Executar",
- "sqlEditor.history.copiedFromHistory": "SQL copiado do histórico.",
- "sqlEditor.toast.scriptSuccessTitle": "Script executado.",
- "sqlEditor.toast.scriptSuccessDetail": "{0} instrução(ões) executada(s) com sucesso.",
- "sqlEditor.toast.scriptWarningTitle": "Script executado com falhas.",
- "sqlEditor.toast.scriptWarningDetail": "{0} de {1} instrução(ões) falharam.",
- "sqlEditor.toast.resultErrorTitle": "Falha ao executar instrução.",
- "sqlEditor.toast.resultSuccessTitle": "Execução concluída com sucesso.",
- "sqlEditor.export.action": "Exportar relatório",
- "sqlEditor.openSql.pickerTitle": "Abrir Arquivo SQL",
- "sqlEditor.saveSql.fileType": "Arquivos SQL",
- "sqlEditor.saveSql.pickerTitle": "Salvar Arquivo SQL",
- "sqlEditor.export.pickerTitle": "Exportar Dados SQL",
- "sqlEditor.export.status.noResultTitle": "Nenhum resultado de execucao disponivel para exportacao.",
- "sqlEditor.export.status.noResultDetail": "Execute uma consulta primeiro.",
- "sqlEditor.export.status.successTitle": "Relatorio exportado.",
- "sqlEditor.export.status.failedTitle": "Falha ao exportar relatorio.",
- "sqlEditor.export.fileType.html": "Arquivo HTML",
- "sqlEditor.export.fileType.json": "Arquivo JSON",
- "sqlEditor.export.fileType.csv": "Arquivo CSV",
- "sqlEditor.export.fileType.xlsx": "Pasta de Trabalho Excel",
- "sqlEditor.export.defaultFileBase": "relatorio",
- "sqlEditor.export.defaultTitle": "Relatorio SQL",
- "sqlEditor.export.error.typeRequired": "Um tipo de relatorio deve ser selecionado antes da exportacao.",
- "sqlEditor.export.type.html.title": "Relatorio HTML completo",
- "sqlEditor.export.type.html.description": "Artefato HTML autonomo e orientado a SQL para auditoria offline.",
- "sqlEditor.export.type.json.title": "Contrato de execucao JSON",
- "sqlEditor.export.type.json.description": "Payload legivel por maquina com SQL, metadados e resultado da execucao.",
- "sqlEditor.export.type.csv.title": "Exportacao de dados CSV",
- "sqlEditor.export.type.csv.description": "Apenas dados tabulares do resultado, ideal para planilhas.",
- "sqlEditor.export.type.xlsx.title": "Exportacao de pasta Excel",
- "sqlEditor.export.type.xlsx.description": "Pasta de trabalho com os dados tabulares do resultado.",
- "sqlEditor.export.dialog.windowTitle": "Exportar Dados SQL",
- "sqlEditor.export.dialog.title": "Exportar Dados SQL",
- "sqlEditor.export.dialog.subtitle": "Escolha o formato e os metadados do artefato antes de exportar.",
- "sqlEditor.export.dialog.confirm": "Exportar",
- "sqlEditor.export.dialog.fileNameWatermark": "relatorio.html",
- "sqlEditor.export.dialog.titleWatermark": "Relatorio SQL",
- "sqlEditor.export.dialog.descriptionWatermark": "Contexto adicional para auditoria e compartilhamento.",
- "sqlEditor.export.dialog.section.reportType": "TIPO DE RELATORIO",
- "sqlEditor.export.dialog.section.fileName": "NOME DO ARQUIVO",
- "sqlEditor.export.dialog.section.reportTitle": "TITULO",
- "sqlEditor.export.dialog.section.description": "DESCRICAO",
- "sqlEditor.export.dialog.section.options": "OPCOES",
- "sqlEditor.export.option.includeSchema": "Incluir schema de saida",
- "sqlEditor.export.option.includeNodeDetails": "Incluir placeholders de no/conexao no JSON",
- "sqlEditor.export.option.includeMetadata": "Incluir metadados opcionais",
- "sqlEditor.export.option.useDashForEmpty": "Usar '-' para campos vazios",
- "sqlEditor.export.badge.offline": "PRONTO PARA OFFLINE",
- "sqlEditor.export.badge.structured": "PAYLOAD ESTRUTURADO",
- "sqlEditor.export.badge.dataOnly": "SOMENTE DADOS"
-}
+{
+ "main.brand": "AkkornStudio",
+ "main.tab.query1": "Consulta 1",
+ "main.new": "Novo",
+ "main.open": "Abrir",
+ "main.save": "Salvar",
+ "main.history": "Histórico",
+ "main.layout": "Layout",
+ "main.preview": "Prévia",
+ "main.undo": "Desfazer",
+ "main.redo": "Refazer",
+ "main.cleanupOrphans": "Limpar nós órfãos",
+ "main.autoFixAliasNaming": "Autoajustar nomenclatura de aliases",
+ "main.autoLayoutCanvas": "Layout automático do canvas",
+ "main.toggleDataPreview": "Alternar prévia de dados",
+ "main.language": "Idioma",
+ "main.restore.prompt": "Sessão anterior encontrada — deseja restaurar o último canvas?",
+ "main.restore.button": "Restaurar sessão",
+ "main.cteEditor.editingPrefix": "Editando CTE: ",
+ "main.cteEditor.backToCanvas": "Voltar ao Canvas",
+ "main.cteEditor.exitA11y": "Sair do editor de CTE",
+ "main.viewEditor.editingPrefix": "DDL > View: ",
+ "main.viewEditor.backToCanvas": "Voltar ao DDL",
+ "main.viewEditor.exitA11y": "Sair do editor de view",
+ "connection.title": "Gerenciador de Conexões",
+ "connection.subtitle": "Configure, teste e ative conexões sem sair do fluxo",
+ "connection.none": "Sem conexão",
+ "connection.active": "ATIVA",
+ "connection.health.online": "Online",
+ "connection.health.degraded": "Degradada",
+ "connection.health.offline": "Offline",
+ "connection.tooltip.none": "Nenhuma conexão ativa — clique para gerenciar",
+ "connection.ping": "Ping",
+ "connection.saved": "CONEXÕES SALVAS",
+ "connection.new": "Nova Conexão",
+ "connection.selectOrCreate": "Selecione uma conexão ou crie uma nova",
+ "connection.name": "Nome da Conexão",
+ "connection.provider": "Provedor",
+ "connection.host": "Host",
+ "connection.port": "Porta",
+ "connection.database": "Banco de Dados",
+ "connection.sqlitePath": "Caminho SQLite",
+ "connection.sqliteBrowse": "Procurar",
+ "connection.sqliteCreate": "Criar",
+ "connection.username": "Usuário",
+ "connection.password": "Senha",
+ "connection.timeout": "Timeout (segundos)",
+ "connection.test": "Testar",
+ "connection.save": "Salvar",
+ "connection.connect": "Conectar",
+ "connection.action.testConnection": "Testar conexão",
+ "connection.action.saveConnection": "Salvar conexão",
+ "connection.action.connectConnection": "Conectar conexão",
+ "connection.status.connecting": "Conectando...",
+ "connection.status.connected": "Conectado",
+ "connection.status.testing": "Testando...",
+ "connection.status.failedPrefix": "Falha na conexão",
+ "connection.status.metadataUnavailable": "Falha na conexão: metadados indisponíveis.",
+ "connection.status.highLatency": "latência alta",
+ "connection.watermark.name": "Meu Banco de Produção",
+ "connection.watermark.host": "localhost",
+ "connection.watermark.port": "5432",
+ "connection.watermark.database": "nome_do_banco",
+ "connection.watermark.username": "usuario",
+ "connection.watermark.password": "••••••••",
+ "connection.watermark.timeout": "30",
+ "main.connectingDb": "Conectando ao banco de dados...",
+ "main.emptyHint": "Pressione ⇧A para adicionar seu primeiro nó, ou arraste uma tabela da barra lateral",
+ "status.nodesSeparator": " nós · ",
+ "status.connectionsSuffix": " conexões",
+ "status.undo": "Desfazer: ",
+ "status.shortcuts": "⇧A Nós · F3 Prévia · Ctrl+Z Desfazer · Del Remover · Alt+Arrastar Pan",
+ "connection.disconnect": "Desconectar",
+ "connection.action.disconnectConnection": "Desconectar conexão",
+ "connectionTab.active": "CONEXÃO ATIVA",
+ "connectionTab.none": "Nenhuma conexão ativa",
+ "connectionTab.saved": "CONEXÕES SALVAS",
+ "connectionTab.new": "+ Nova Conexão",
+ "schema.database": "BANCO DE DADOS",
+ "schema.search": "Buscar tabelas, colunas...",
+ "schema.loading": "Buscando tabelas, colunas...",
+ "schema.noConnection": "Sem conexão",
+ "schema.noConnectionHint": "Conecte-se a um banco para ver tabelas, colunas e relacionamentos",
+ "schema.emptyNoTables": "Nenhuma tabela encontrada",
+ "fileHistory.title": "Histórico de Versões (Salvar/Carregar)",
+ "fileHistory.reload": "Recarregar",
+ "fileHistory.restoreSelected": "Restaurar selecionada",
+ "fileHistory.empty": "Nenhuma versão local ainda",
+ "fileHistory.emptyHint": "Salve este arquivo para gerar histórico de versões.",
+ "preview.title": "Prévia de Dados",
+ "preview.subtitle": "Revise dados e diagnósticos antes de continuar",
+ "preview.run": "Executar",
+ "preview.cancel": "Cancelar",
+ "preview.tab.preview": "Prévia",
+ "preview.tab.sql": "SQL",
+ "preview.close": "Fechar prévia",
+ "preview.running": "Executando consulta de prévia… ",
+ "preview.clickCancel": "Clique em Cancelar para interromper",
+ "preview.cancelled": "Consulta cancelada",
+ "preview.runAgain": "Pressione Executar para tentar novamente",
+ "preview.failed": "Falha na execução da prévia",
+ "preview.technical": "DETALHES TÉCNICOS",
+ "preview.noData": "Sem dados ainda",
+ "preview.f3Hint": "Pressione F3 ou Espaço para executar a consulta atual",
+ "sqlImporter.title": "Importar SQL para Grafo",
+ "sqlImporter.subtitle": "Cole uma instrução SELECT — os nós são criados automaticamente",
+ "sqlImporter.sqlStatement": "INSTRUÇÃO SQL",
+ "sqlImporter.supported": "Suportado: ",
+ "sqlImporter.import": "Importar",
+ "sqlImporter.report": "RELATÓRIO DE CONVERSÃO",
+ "sqlEditor.mutation.dialogTitle": "Confirmacao de mutacao",
+ "sqlEditor.mutation.dialogSubtitle": "Revise o impacto antes de confirmar a execucao",
+ "search.empty": "Nenhum nó encontrado",
+ "search.emptyHint": "Tente buscar por UPPER, JSON, CAST, AND…",
+ "search.shortcut": "⇧A",
+ "search.spawn": "Criar",
+ "commandPalette.empty": "Nenhum comando corresponde à sua busca",
+ "commandPalette.search": "Busca de comandos",
+ "commandPalette.shortcut": "CTRL+SHIFT+P",
+ "commandPalette.execute": "Executar",
+ "context.editCte": "Editar CTE Selecionada",
+ "context.editViewSubcanvas": "Editar Subcanvas da View",
+ "explain.title": "Plano de Execução",
+ "explain.sql": "SQL",
+ "explain.option.analyze": "Analisar",
+ "explain.option.buffers": "Buffers",
+ "explain.badge.simulated": "SIMULADO",
+ "explain.timing.planning": "Planejamento:",
+ "explain.timing.execution": "Execucao:",
+ "explain.section.snapshotComparison": "Comparacao de snapshots",
+ "explain.section.indexRecommendations": "Recomendacoes de indice",
+ "explain.section.history": "Historico",
+ "explain.detail.estimated": "Estimadas",
+ "explain.detail.actual": "Atuais",
+ "explain.detail.error": "Erro",
+ "explain.detail.time": "Tempo",
+ "explain.detail.loops": "Loops",
+ "explain.rerun": "Reexecutar",
+ "explain.alertSuffix": " operação(ões) cara(s) detectada(s) — considere adicionar índices",
+ "explain.running": "Executando EXPLAIN…",
+ "explain.failed": "⚠ EXPLAIN falhou",
+ "explain.noPlan": "Nenhum plano ainda",
+ "explain.rerunHint": "Pressione Reexecutar para executar EXPLAIN",
+ "explain.header.operation": "OPERAÇÃO",
+ "explain.header.cost": "CUSTO",
+ "explain.header.rows": "LINHAS",
+ "explain.header.err": "ERR",
+ "explain.header.alert": "ALERTA",
+ "explain.snapshot.labelA": "A",
+ "explain.snapshot.labelB": "B",
+ "explain.mode.list": "Lista",
+ "explain.mode.tree": "Arvore",
+ "explain.action.snapshot": "Salvar snapshot",
+ "explain.action.copyJson": "Copiar JSON",
+ "explain.action.copyText": "Copiar texto",
+ "explain.action.saveJson": "Salvar .json",
+ "explain.action.openDalibo": "Abrir no Dalibo",
+ "explain.legend.seqscan": "SEQ SCAN — leitura completa da tabela, sem índice",
+ "explain.legend.sort": "SORT — ordenação em memória",
+ "explain.legend.hash": "HASH — junção por hash",
+ "explain.escClose": "Esc para fechar",
+ "flowVersion.title": "Histórico de Versões do Fluxo",
+ "flowVersion.subtitle": "Crie checkpoints, compare versões e restaure",
+ "flowVersion.watermark": "Rótulo do checkpoint (opcional)…",
+ "flowVersion.saveCheckpoint": "Salvar Checkpoint",
+ "flowVersion.compareMode": "Modo de Comparação",
+ "flowVersion.selectBase": "Selecione a versão BASE (de):",
+ "flowVersion.clickAny": "Depois clique em qualquer versão da lista abaixo para comparar.",
+ "flowVersion.noCheckpoints": "Nenhum checkpoint ainda",
+ "flowVersion.noCheckpointsHint": "Salve um checkpoint acima para começar a rastrear versões.",
+ "flowVersion.restore": "Restaurar",
+ "flowVersion.diffResults": "Resultados da Diferença",
+ "benchmark.title": "Benchmark de Consulta",
+ "benchmark.subtitle": "Mede latência média / mediana / p95 em N iterações",
+ "benchmark.sql": "SQL sendo avaliado",
+ "benchmark.runLabel": "Rótulo da execução",
+ "benchmark.runLabelWatermark": "Execução 1",
+ "benchmark.iterations": "Iterações (1–100)",
+ "benchmark.warmup": "Passes de aquecimento (0–10)",
+ "benchmark.interval": "Intervalo entre execuções (ms)",
+ "benchmark.run": "Executar Benchmark",
+ "benchmark.cancel": "Cancelar",
+ "benchmark.clearHistory": "Limpar Histórico",
+ "benchmark.latest": "ÚLTIMO RESULTADO",
+ "benchmark.avg": "MÉDIA",
+ "benchmark.median": "MEDIANA",
+ "benchmark.min": "MÍN",
+ "benchmark.max": "MÁX",
+ "benchmark.iterationsAt": " iterações · executado às ",
+ "benchmark.history": "HISTÓRICO",
+ "benchmark.header.label": "Rótulo",
+ "benchmark.header.avg": "Média",
+ "benchmark.header.median": "Mediana",
+ "benchmark.header.min": "Mín",
+ "benchmark.header.max": "Máx",
+ "benchmark.itersSuffix": " iterações",
+ "diagnostics.title": "Diagnóstico do Aplicativo",
+ "diagnostics.run": "Executar",
+ "diagnostics.running": "Executando verificações…",
+ "diagnostics.ok": "OK",
+ "diagnostics.warning": "Aviso",
+ "diagnostics.error": "Erro",
+ "diagnostics.tooltip.rerun": "Executar novamente todas as verificações",
+ "diagnostics.tooltip.copy": "Copiar relatório de diagnóstico para a área de transferência",
+ "diagnostics.tooltip.close": "Fechar (Esc)",
+ "autoJoin.title": "Sugestões de Auto-Join",
+ "autoJoin.titleForTable": "Sugestões de Auto-Join para {0}",
+ "autoJoin.acceptAll": "Aceitar Todas",
+ "autoJoin.accept": "Aceitar",
+ "autoJoin.skip": "Pular",
+ "autoJoin.allHandled": "Todas as sugestões foram tratadas",
+ "autoJoin.joinKeyword": "JOIN",
+ "autoJoin.confidence.fkConstraint": "Restrição FK",
+ "autoJoin.confidence.fkReverse": "FK (Reversa)",
+ "autoJoin.confidence.namingMatch": "Correspondência por nome",
+ "autoJoin.confidence.weakMatch": "Correspondência fraca",
+ "autoJoin.runSelected": "Auto-Join Selecionado",
+ "autoJoin.noSimilarityTitle": "Nenhum auto join encontrado",
+ "autoJoin.noSimilarityDetails": "Escolha manualmente as colunas para criar um join simples.",
+ "autoJoin.appliedTitle": "Auto-join aplicado",
+ "autoJoin.manual.title": "Criar Join Manual",
+ "autoJoin.manual.subtitle": "Nenhuma similaridade confiável foi encontrada. Selecione uma coluna de cada tabela.",
+ "autoJoin.manual.leftColumn": "Coluna da esquerda",
+ "autoJoin.manual.rightColumn": "Coluna da direita",
+ "autoJoin.manual.joinType": "Tipo de join",
+ "autoJoin.manual.operator": "Operador",
+ "autoJoin.manual.confirm": "Criar join",
+ "autoJoin.manual.noCompatible": "Nao ha colunas compativeis para o tipo de pin selecionado na esquerda.",
+ "autoJoin.manualJoinCreatedTitle": "Join manual criado",
+ "autoJoin.manualJoinFailedTitle": "Não foi possível criar o join manual",
+ "autoJoin.manualJoinFailedDetails": "Verifique as colunas selecionadas e joins existentes, depois tente novamente.",
+ "autoJoin.multipleCandidatesTitle": "Múltiplas opções de join encontradas",
+ "autoJoin.multipleCandidatesDetails": "{0} combinações possíveis foram encontradas. Confirme quais colunas devem ser usadas.",
+ "autoJoin.suggestionsFoundTitle": "Sugestões de auto-join disponíveis",
+ "autoJoin.suggestionsFoundDetails": "{0} sugestão(ões) encontrada(s). Selecione duas tabelas e execute Auto-Join Selecionado.",
+ "property.outputAlias": "ALIAS DE SAÍDA",
+ "property.sourceAlias": "ALIAS DE FONTE",
+ "property.aliasWatermark": "ex.: MinhaColuna (opcional)",
+ "property.parameters": "PARÂMETROS",
+ "property.enabled": "Habilitado",
+ "property.datetimeWatermark": "AAAA-MM-DDTHH:mm:ss ou deixe vazio",
+ "property.dateWatermark": "AAAA-MM-DD ou deixe vazio",
+ "property.apply": "Aplicar",
+ "property.inputPins": "PINS DE ENTRADA",
+ "property.outputPins": "PINS DE SAÍDA",
+ "property.sqlTrace": "RASTREIO SQL",
+ "property.live": "ao vivo",
+ "node.numericValue": "Valor Numérico",
+ "node.stringValue": "Valor de Texto",
+ "node.enterText": "Digite o texto",
+ "node.datetimeValue": "Valor de Data/Hora",
+ "node.valueLabel": "Valor:",
+ "node.noInputs": "Sem entradas",
+ "node.loadingSample": "Carregando amostra…",
+ "node.previewFailed": "⚠ Falha na prévia",
+ "node.sampleRowsHint": "5 linhas de amostra · dados de demonstração",
+ "sidebar.tab.nodes": "Nós",
+ "sidebar.tab.connection": "Conexão",
+ "sidebar.tab.schema": "Esquema",
+ "sidebar.tab.diagnostics": "Diagnósticos",
+ "sidebar.addNode": "+ Adicionar Nó (⇧A)",
+ "sidebar.previewF3": "Prévia (F3)",
+ "nodesList.search": "Buscar nós...",
+ "search.watermark": "Buscar nós… (Esc para fechar)",
+ "search.snippets": "★ SNIPPETS",
+ "commandPalette.watermark": "Executar um comando… (Esc para fechar)",
+ "tooltip.newCanvas": "Novo canvas (Ctrl+N)",
+ "tooltip.openCanvas": "Abrir canvas (Ctrl+O)",
+ "tooltip.saveCanvas": "Salvar canvas (Ctrl+S)",
+ "tooltip.fileHistory": "Histórico local de salvar/carregar (Ctrl+Alt+H)",
+ "tooltip.zoomOut": "Diminuir zoom (Ctrl+-)",
+ "tooltip.zoomIn": "Aumentar zoom (Ctrl++)",
+ "tooltip.fitToScreen": "Ajustar à tela (Ctrl+0)",
+ "tooltip.autoLayout": "Layout automático — organiza os nós em colunas lógicas (Ctrl+L, Ctrl+Z para desfazer)",
+ "tooltip.snapToGrid": "Alternar snap na grade (Ctrl+G)",
+ "tooltip.dataPreview": "Prévia de dados (F3)",
+ "tooltip.toggleLanguage": "Alternar idioma (pt-BR / en-US)",
+ "tooltip.appDiagnostics": "Diagnóstico do app (autoavaliação)",
+ "tooltip.keyboardShortcuts": "Atalhos do teclado (F1)",
+ "tooltip.cancelRunningQuery": "Cancelar a consulta em execução",
+ "tooltip.closeEsc": "Fechar (Esc)",
+ "tooltip.recheckConnectionHealth": "Verificar novamente a saúde da conexão",
+ "tooltip.deleteConnection": "Excluir conexão",
+ "tooltip.testConnection": "Testar conexão",
+ "tooltip.saveConnection": "Salvar conexão",
+ "tooltip.activateConnection": "Ativar esta conexão",
+ "tooltip.toggleDataSamplePreview": "Alternar prévia de dados de amostra",
+ "tooltip.liveSqlMutatingBlocked": "Este SQL contém um comando que altera dados e não pode ser executado no Modo de Prévia Segura",
+ "tooltip.copySql": "Copiar SQL para a área de transferência",
+ "tooltip.formatSql": "Formatar SQL",
+ "tooltip.openBenchmark": "Abrir Benchmark de Consulta (medir média / mediana / p95 de latência)",
+ "tooltip.openExplainPlan": "Abrir inspetor de Explain Plan — visualizar o plano de execução da consulta",
+ "tooltip.switchToQueryMode": "Alternar para o canvas de Query",
+ "tooltip.switchToDdlMode": "Alternar para o canvas de DDL",
+ "tooltip.switchToSqlMode": "Alternar para o editor SQL",
+ "tooltip.autoJoinSelected": "Tentar auto-join entre as duas tabelas selecionadas",
+ "tooltip.pins.inputs": "Entradas",
+ "tooltip.pins.outputs": "Saídas",
+ "tooltip.pins.none": "Nenhum",
+ "tooltip.tableColumns": "Colunas",
+ "tooltip.tableColumns.none": "Sem colunas detalhadas",
+ "window.minimize": "Minimizar janela",
+ "window.maximizeRestore": "Maximizar/restaurar janela",
+ "window.close": "Fechar janela",
+ "menu.newDiagram": "Novo diagrama",
+ "menu.openFile": "Abrir arquivo",
+ "menu.save": "Salvar",
+ "menu.fileHistory": "Histórico de arquivos",
+ "menu.shortcuts": "Atalhos de teclado",
+ "menu.settings": "Configurações",
+ "menu.group.project": "PROJETO",
+ "menu.group.currentMode": "MODO ATUAL",
+ "menu.group.tools": "FERRAMENTAS",
+ "menu.reason.ddlOnly": "Disponível apenas no modo DDL.",
+ "menu.importSqlQuery": "Importar SQL para Query",
+ "menu.importDdlSchema": "Importar Schema DDL",
+ "menu.viewDdlSql": "Ver SQL DDL",
+ "menu.executeDdl": "Executar DDL",
+ "menu.backToStart": "Voltar para início",
+ "toast.ddlExecuteFailed": "Falha ao executar DDL.",
+ "toast.ddlOpenFailed": "Falha ao abrir SQL DDL.",
+ "toast.ddlImportFailed": "Falha ao importar schema para DDL.",
+ "toast.ddlConnectToImportSchema": "Conecte-se a um banco para importar schema no canvas DDL.",
+ "toast.ddlNoTablesFound": "Nenhuma tabela encontrada para importar no modo DDL.",
+ "toast.ddlSchemaImported": "Schema importado para o canvas DDL.",
+ "toast.ddlImportSummary": "{0} tabela(s), {1} coluna(s), {2} FK(s), {3} indice(s) unicos.",
+ "toast.ddlConnectToImportTable": "Conecte-se a um banco para importar tabelas no canvas DDL.",
+ "toast.ddlTableAlreadyExists": "A tabela '{0}' ja existe no canvas DDL.",
+ "toast.ddlTableImported": "Tabela importada para o canvas DDL.",
+ "toast.ddlTableImportSummary": "Nos: +{0}, conexoes: +{1}, FKs: +{2}.",
+ "toast.ddlNoActiveConnection": "Nenhuma conexão ativa para executar DDL.",
+ "toast.ddlExecutedSuccess": "DDL executado com sucesso.",
+ "toast.ddlExecutedWithIssues": "DDL executado com falhas.",
+ "toast.switchToDdl": "Alterne para o modo DDL para gerar SQL.",
+ "toast.ddlInvalid": "DDL inválido. Corrija os erros antes de continuar.",
+ "toast.ddlNoStatements": "Nenhum statement DDL foi gerado no canvas.",
+ "toast.previewOpenFailed": "Falha ao abrir preview.",
+ "tab.switchFailed": "Falha ao alternar aba: {0}",
+ "settings.status.darkApplied": "Tema escuro aplicado.",
+ "settings.status.lightApplied": "Tema claro aplicado.",
+ "settings.status.snapUpdated": "Snap atualizado: {0}.",
+ "settings.status.languageToggled": "Idioma alternado.",
+ "settings.status.languageSelected": "Idioma selecionado: {0}.",
+ "settings.status.themeEditorReady": "Editor de tema pronto. Aplique para salvar e usar o tema.",
+ "settings.section.appearance.title": "Temas",
+ "settings.section.languageRegion.title": "Idioma e Região",
+ "settings.section.dateTime.title": "Data e Hora",
+ "settings.section.keyboard.title": "Atalhos de Teclado",
+ "settings.section.privacy.title": "Privacidade",
+ "settings.section.notification.title": "Notificações",
+ "settings.section.accessibility.title": "Acessibilidade",
+ "settings.section.default.title": "Configurações",
+ "settings.section.appearance.subtitle": "Escolha o estilo ou personalize seu tema",
+ "settings.section.languageRegion.subtitle": "Gerencie idioma e formatação regional",
+ "settings.section.keyboard.subtitle": "Personalize os atalhos de teclado usados pela command palette e execução do canvas.",
+ "settings.section.wip.subtitle": "Trabalho em progresso.",
+ "settings.section.default.subtitle": "Configurações da aplicação",
+ "settings.general": "Geral",
+ "settings.nav.appearance": "Aparência",
+ "settings.theme.light": "Modo Claro",
+ "settings.theme.dark": "Modo Escuro",
+ "settings.theme.system": "Preferências do Sistema",
+ "settings.gridSnap.title": "Snap na Grade",
+ "settings.gridSnap.subtitle": "Controla o snap dos nós no canvas.",
+ "settings.language.subtitle": "Alterna entre PT-BR e EN-US.",
+ "settings.language.toggle": "Alternar idioma",
+ "settings.language.option.ptBR": "Português (Brasil)",
+ "settings.language.option.enUS": "Inglês (Estados Unidos)",
+ "settings.language.option.esES": "Espanhol (Espanha)",
+ "settings.language.option.ruRU": "Russo",
+ "settings.language.option.jaJP": "Japonês",
+ "settings.language.option.zhTW": "Chinês Tradicional",
+ "settings.themeJson.title": "Theme JSON",
+ "settings.themeJson.subtitle": "Cole o JSON do tema, aplique e persista instantaneamente.",
+ "settings.themeJson.apply": "Aplicar JSON",
+ "settings.themeJson.restoreDefault": "Restaurar tema padrão",
+ "mode.query": "Query",
+ "mode.ddl": "DDL",
+ "mode.sql": "SQL",
+ "sidebar.left.close": "Fechar barra lateral esquerda",
+ "sidebar.left.open": "Reabrir barra lateral esquerda",
+ "sidebar.right.close": "Fechar barra lateral direita",
+ "sidebar.right.open": "Reabrir barra lateral direita",
+ "connection.completedTitle": "Conexão concluída",
+ "connection.clearCanvasPrompt": "Deseja limpar o canvas atual para começar com a nova conexão?",
+ "connection.close": "Fechar gerenciador de conexões",
+ "connection.refreshHealth": "Atualizar saúde da conexão",
+ "common.details": "Detalhes",
+ "common.cancel": "Cancelar",
+ "common.keep": "Manter",
+ "common.clear": "Limpar",
+ "zoom.out": "Diminuir zoom",
+ "zoom.in": "Aumentar zoom",
+ "zoom.fit": "Ajustar zoom à tela",
+ "zoom.level": "Nível de zoom",
+ "settings.theme.mode": "Modo de tema",
+ "diagnostics.category.canvas": "Integridade do Canvas",
+ "diagnostics.category.output": "Saída e Execução",
+ "diagnostics.category.session": "Sessão e Segurança",
+ "diagnostics.category.notice": "Avisos em Tempo de Execução",
+ "diagnostics.summary.ok": "Sistema sem problemas",
+ "diagnostics.summary.warningCount": "{0} aviso(s) detectado(s)",
+ "diagnostics.summary.errorCount": "{0} erro(s) detectado(s)",
+ "diagnostics.canvasMigration": "Migração de Canvas",
+ "diagnostics.recommendation.resaveFile": "Salve novamente o arquivo para atualizar para a versão mais recente do schema.",
+ "diagnostics.canvasState.name": "Estado do Canvas",
+ "diagnostics.canvasState.recommendation": "Adicione pelo menos um {0} e um {1}",
+ "diagnostics.canvasState.empty": "Canvas vazio - nenhum nó presente",
+ "diagnostics.canvasState.counts": "{0} nó(s), {1} conexão(ões)",
+ "diagnostics.validation.name": "Erros de Validação",
+ "diagnostics.validation.recommendation": "Corrija os nós destacados antes de abrir a prévia de saída",
+ "diagnostics.validation.errorWithWarnings": "{0} erro(s) e {1} aviso(s) no grafo",
+ "diagnostics.validation.warningOnly": "{0} aviso(s) no grafo",
+ "diagnostics.validation.none": "Sem problemas de validação",
+ "diagnostics.orphan.name": "Nós Órfãos",
+ "diagnostics.orphan.recommendation": "Use a limpeza de órfãos para remover nós sem uso",
+ "diagnostics.orphan.count": "{0} nó(s) não conectado(s) a nenhuma saída",
+ "diagnostics.orphan.none": "Nenhum nó órfão detectado",
+ "diagnostics.naming.name": "Convenções de Nome",
+ "diagnostics.naming.recommendation": "Use correção automática quando a conformidade estiver abaixo de 100%",
+ "diagnostics.naming.conformance": "Conformidade de nomes: {0}%",
+ "diagnostics.naming.ok": "Todos os aliases seguem as convenções (100%)",
+ "diagnostics.queryCompilation.name": "Compilação SQL ao Vivo",
+ "diagnostics.queryCompilation.recommendation": "Revise os diagnósticos SQL quando houver erros/avisos",
+ "diagnostics.queryCompilation.errorFallback": "A compilação SQL ao vivo reportou erros.",
+ "diagnostics.queryCompilation.warningCounts": "{0} item(ns) de diagnóstico, {1} aviso(s) de guardrail.",
+ "diagnostics.queryCompilation.ok": "SQL ao vivo compilado sem diagnósticos.",
+ "diagnostics.previewSafety.name": "Segurança da Prévia",
+ "diagnostics.previewSafety.recommendation": "A prévia executa apenas comandos de leitura.",
+ "diagnostics.previewSafety.blocked": "O SQL atual altera dados e foi bloqueado pelo modo seguro.",
+ "diagnostics.previewSafety.ok": "Verificações de segurança da prévia concluídas.",
+ "diagnostics.previewExecution.name": "Execução da Prévia",
+ "diagnostics.previewExecution.recommendation": "Execute a prévia e revise diagnósticos de execução",
+ "diagnostics.previewExecution.failed": "Falha na execução da prévia.",
+ "diagnostics.previewExecution.cancelled": "Execução da prévia cancelada.",
+ "diagnostics.previewExecution.done": "{0} linha(s) em {1}ms.",
+ "diagnostics.previewExecution.none": "Nenhum problema de execução de prévia detectado.",
+ "diagnostics.ddlCompilation.name": "Compilação DDL",
+ "diagnostics.ddlCompilation.recommendation": "Corrija diagnósticos de compilação DDL antes de executar",
+ "diagnostics.ddlCompilation.failed": "Falha na compilação DDL.",
+ "diagnostics.ddlCompilation.warningCount": "{0} aviso(s) reportado(s) pelo compilador DDL.",
+ "diagnostics.ddlCompilation.ok": "Compilação DDL concluída com sucesso.",
+ "diagnostics.ddlOutput.name": "Saída DDL",
+ "diagnostics.ddlOutput.recommendation": "Complete os nós DDL até gerar ao menos um statement",
+ "diagnostics.ddlOutput.none": "Nenhum statement DDL gerado ainda.",
+ "diagnostics.ddlOutput.lines": "{0} linha(s) de DDL gerada(s).",
+ "diagnostics.undo.name": "Histórico de Desfazer",
+ "diagnostics.undo.recommendation": "O histórico fica apenas em memória; salve o canvas regularmente.",
+ "diagnostics.undo.saved": "Canvas salvo (sem mudanças pendentes).",
+ "diagnostics.undo.unsavedDeep": "Mudanças não salvas com {0} passos de desfazer.",
+ "diagnostics.undo.unsaved": "Mudanças não salvas - {0} passo(s) de desfazer disponível(is).",
+ "diagnostics.report.title": "AkkornStudio - Relatório de Diagnóstico",
+ "diagnostics.report.generated": "Gerado",
+ "diagnostics.report.overall": "Resumo",
+ "diagnostics.report.details": "Detalhes",
+ "diagnostics.report.recommendation": "Recomendação",
+ "diagnostics.report.lastCheck": "Última verificação",
+ "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
+ "node.datetimeFormat": "AAAA-MM-DDTHH:mm:ss",
+ "preview.providerLabel": "Provedor",
+ "preview.ddlDiagnosticsHint": "Detalhes de erros/avisos disponíveis em Diagnósticos.",
+ "preview.schemaAnalysis.run": "Executar análise",
+ "preview.schemaAnalysis.cancel": "Cancelar",
+ "preview.schemaAnalysis.issues": "Issues",
+ "preview.schemaAnalysis.clearFilters": "Limpar filtros",
+ "preview.schemaAnalysis.clearBlacklist": "Limpar blacklist",
+ "preview.schemaAnalysis.severity": "Severidade",
+ "preview.schemaAnalysis.severity.info": "Info",
+ "preview.schemaAnalysis.severity.warning": "Aviso",
+ "preview.schemaAnalysis.severity.critical": "Crítico",
+ "preview.schemaAnalysis.rule": "Regra",
+ "preview.schemaAnalysis.rule.fkCatalogInconsistent": "Catálogo de FK inconsistente",
+ "preview.schemaAnalysis.rule.missingFk": "FK ausente",
+ "preview.schemaAnalysis.rule.namingConventionViolation": "Violação de convenção de nomes",
+ "preview.schemaAnalysis.rule.lowSemanticName": "Nome com baixa semântica",
+ "preview.schemaAnalysis.rule.missingRequiredComment": "Comentário obrigatório ausente",
+ "preview.schemaAnalysis.rule.nf1HintMultiValued": "Indício 1FN: multi-valorado",
+ "preview.schemaAnalysis.rule.nf2HintPartialDependency": "Indício 2FN: dependência parcial",
+ "preview.schemaAnalysis.rule.nf3HintTransitiveDependency": "Indício 3FN: dependência transitiva",
+ "preview.schemaAnalysis.minConfidence": "Confiança mínima",
+ "preview.schemaAnalysis.tableFilter": "Filtro de tabela",
+ "preview.schemaAnalysis.tableFilterWatermark": "schema.tabela",
+ "preview.schemaAnalysis.ignore": "Filtros de execução",
+ "preview.schemaAnalysis.ignoreViews": "Ignorar views e materialized views",
+ "preview.schemaAnalysis.blacklist": "Blacklist de tabelas",
+ "preview.schemaAnalysis.blacklistAdd": "Adicionar",
+ "preview.schemaAnalysis.blacklistRemove": "Remover selecionada",
+ "preview.schemaAnalysis.ignoreTable.placeholder": "schema.tabela",
+ "preview.schemaAnalysis.details": "Detalhes",
+ "preview.schemaAnalysis.evidence": "Evidências",
+ "preview.schemaAnalysis.suggestions": "Sugestões",
+ "preview.schemaAnalysis.ruleDiagnostics": "Diagnósticos da regra",
+ "preview.schemaAnalysis.sqlCandidates": "SQL Candidates",
+ "preview.schemaAnalysis.copySql": "Copiar SQL",
+ "preview.schemaAnalysis.applyToCanvas": "Aplicar no canvas",
+ "preview.schemaAnalysis.summary.issues": "Issues:",
+ "preview.schemaAnalysis.summary.rawPrefix": "(bruto:",
+ "preview.schemaAnalysis.summary.critical": "| Crítico:",
+ "preview.schemaAnalysis.summary.warning": "| Aviso:",
+ "preview.schemaAnalysis.summary.info": "| Info:",
+ "preview.schemaAnalysis.state.metadataUnavailable": "Metadata indisponível para análise estrutural.",
+ "preview.schemaAnalysis.state.cancelled": "Análise cancelada pelo usuário.",
+ "preview.schemaAnalysis.state.partialTimeout": "Análise finalizada parcialmente por timeout.",
+ "preview.schemaAnalysis.state.failed": "Falha na análise estrutural.",
+ "preview.schemaAnalysis.state.empty": "Nenhum problema estrutural inferível foi detectado.",
+ "preview.schemaAnalysis.state.noFilterMatch": "Nenhuma issue corresponde aos filtros selecionados.",
+ "preview.schemaAnalysis.state.noIssueSelected": "Nenhuma issue selecionada.",
+ "preview.schemaAnalysis.state.noSqlCandidate": "Nenhum SQL candidate disponível.",
+ "preview.schemaAnalysis.actionBlockedTooltip": "Ação indisponível para o nível de risco ou capacidade atual.",
+ "common.navigate": "Navegar",
+ "common.close": "Fechar",
+ "common.esc": "Esc",
+ "common.ms": "ms",
+ "common.zero": "0",
+ "diagnostics.tip": "Dica: verifique Diagnósticos sempre que preview/saída reportar avisos ou erros.",
+ "nodesList.empty": "Nenhum nó encontrado",
+ "nodesList.emptyHint": "Ajuste o termo de busca para explorar os tipos disponíveis",
+ "schema.emptyFiltered": "Nenhum objeto encontrado para o filtro atual",
+ "start.lastSnapshot": "Último snapshot",
+ "app.brandBadge": "VS",
+ "property.tab.properties": "Propriedades",
+ "property.tab.projectSettings": "Configurações do Projeto",
+ "property.nodeType": "TIPO DE NÓ",
+ "property.selectNodeHint": "Selecione um nó para editar suas propriedades.",
+ "property.namingConventions": "Convenções de Nomenclatura",
+ "property.aliasConvention": "Convenção de alias",
+ "property.enforceAliasNaming": "Forçar nomenclatura de alias",
+ "property.warnReservedSql": "Alertar sobre palavras reservadas SQL",
+ "property.maxAliasLength": "Tamanho máximo do alias",
+ "property.maxAliasLengthDefault": "64",
+ "property.namingSettingsHint": "Essas configurações são por projeto e são usadas por validação e helpers de nomenclatura.",
+ "start.tips": "Dicas",
+ "start.tips.quick": "Dicas rápidas",
+ "start.tips.item1": "1. Clique em Novo Diagrama para iniciar do zero.",
+ "start.tips.item2": "2. Use templates para acelerar protótipos.",
+ "start.tips.item3": "3. Abra conexões salvas para carregar tabelas reais.",
+ "start.tips.shortcut": "Atalho: CTRL+SHIFT+P abre a paleta de comandos.",
+ "start.workspace": "WORKSPACE",
+ "start.resumeTitle": "Continuar de onde parou",
+ "start.resumeSubtitle": "Retome rapidamente um projeto recente ou comece um novo diagrama.",
+ "start.chip.quickFlow": "Fluxo rápido",
+ "start.chip.templates": "Templates",
+ "start.chip.connections": "Conexões",
+ "start.savedConnectionsTitle": "Conexões salvas",
+ "start.savedConnectionsSubtitle": "Conecte-se rapidamente a um banco para carregar schema e tabelas.",
+ "start.noConnectionsTitle": "Nenhuma conexão configurada ainda",
+ "start.noConnectionsSubtitle": "Crie uma conexão para explorar tabelas reais no editor.",
+ "start.newConnection": "+ Nova Conexão",
+ "start.recentProjectsTitle": "Projetos Recentes",
+ "start.searchRecent": "Buscar projeto recente...",
+ "start.quickActions": "Ações rápidas",
+ "start.quickActionsSubtitle": "Abra um arquivo existente ou inicie um novo diagrama.",
+ "start.noRecentTitle": "Nenhum projeto recente ainda",
+ "start.noRecentSubtitle": "Use o card de ações rápidas acima para começar.",
+ "start.exploreTemplates": "Explorar templates",
+ "start.templatesFavoritesHint": "Favoritos no topo",
+ "start.favoriteTemplate": "Favoritar template",
+ "node.columnSetPreview": "Prévia de ColumnSet",
+ "node.view": "VIEW",
+ "node.tableDefinition": "Definição da Tabela",
+ "node.join": "JOIN",
+ "node.window.addPartition": "Adicionar slot PARTITION BY",
+ "node.window.removePartition": "Remover slot PARTITION BY",
+ "node.window.addOrder": "Adicionar slot ORDER BY",
+ "node.window.removeOrder": "Remover slot ORDER BY",
+ "sql.keyword.select": "SELECT",
+ "sql.keyword.from": "FROM",
+ "sql.keyword.join": "JOIN",
+ "sql.keyword.where": "WHERE",
+ "sql.keyword.limit": "LIMIT",
+ "sqlImporter.close": "Fechar importador SQL",
+ "sqlImporter.report.imported": "Importados",
+ "sqlImporter.report.partial": "Parciais",
+ "sqlImporter.report.skipped": "Ignorados",
+ "sqlImporter.confirmClearCanvas": "A importação SQL irá limpar o canvas atual. Deseja continuar?",
+ "sqlImporter.confirmProceed": "Continuar importação",
+ "benchmark.close": "Fechar benchmark",
+ "benchmark.p95": "P95",
+ "benchmark.n": "N",
+ "liveSql.safePreview": "MODO DE PRÉVIA SEGURA",
+ "liveSql.title": "SQL AO VIVO",
+ "liveSql.blocked": "BLOQUEADO",
+ "liveSql.copy": "Copiar",
+ "liveSql.format": "Formatar",
+ "liveSql.benchmark": "Benchmark",
+ "liveSql.explain": "Explain",
+ "liveSql.actionsHint": "Ferramentas de desempenho",
+ "ddl.dialog.title": "Executar DDL",
+ "ddl.dialog.execute": "Executar",
+ "ddl.dialog.cancel": "Cancelar",
+ "ddl.dialog.close": "Fechar",
+ "ddl.dialog.stopOnError": "Parar na primeira falha",
+ "ddl.dialog.confirmDestructive": "Confirmo execução de statements destrutivos (DROP TABLE)",
+ "ddl.dialog.reviewBeforeRun": "Revise o script DDL antes de confirmar.",
+ "ddl.dialog.confirmQuestion": "Confirma a execução do DDL no banco conectado?",
+ "ddl.dialog.irreversibleWarning": "Esta ação pode alterar o schema de forma irreversível.",
+ "ddl.dialog.mustConfirmDestructive": "Confirme a execução destrutiva para continuar.",
+ "ddl.dialog.executing": "Executando...",
+ "ddl.execute.result.summary": "Statements: {0} | Sucesso: {1} | Falhas: {2} | Tempo: {3:0}ms",
+ "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
+ "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
+ "ddl.execute.result.failed": "Falha ao executar DDL.",
+ "ddl.execute.result.cancelled": "Execução cancelada pelo usuário.",
+ "ddl.execute.result.cancelledDetails": "A execução DDL foi interrompida antes da conclusão.",
+ "context.deleteSingle": "Excluir {0}",
+ "context.deleteMultiple": "Excluir {0} nós",
+ "context.bringForward": "Trazer para frente (Ctrl+PgUp)",
+ "context.sendBackward": "Enviar para trás (Ctrl+PgDown)",
+ "context.bringToFront": "Trazer para o topo (Ctrl+Shift+PgUp)",
+ "context.sendToBack": "Enviar para o fundo (Ctrl+Shift+PgDown)",
+ "context.normalizeLayers": "Normalizar camadas",
+ "context.deleteWire": "Excluir conexão",
+ "context.addNode": "Adicionar nó (Shift+A)",
+ "context.undoWithDescription": "Desfazer {0}",
+ "context.redo": "Refazer",
+ "shortcuts.windowTitle": "Atalhos de Teclado",
+ "shortcuts.headerTitle": "AkkornStudio - Atalhos",
+ "shortcuts.headerHint": "Dica: use CTRL+SHIFT+P para abrir a Command Palette e pesquisar comandos.",
+ "shortcuts.filterWatermark": "Filtrar atalhos por tecla ou ação...",
+ "shortcuts.resultCount": "{0} atalhos",
+ "shortcuts.resultFilter": "{0} resultado(s) para \"{1}\"",
+ "shortcuts.noneFound": "Nenhum atalho encontrado.",
+ "shortcuts.section.fileGeneral": "Arquivo e geral",
+ "shortcuts.section.editing": "Edição",
+ "shortcuts.section.canvasNavigation": "Canvas e navegação",
+ "shortcuts.section.zoomPanPrecision": "Zoom, pan e precisão",
+ "shortcuts.section.previewInspection": "Preview e inspeção",
+ "shortcuts.key.deleteOrBackspace": "Del ou Backspace",
+ "shortcuts.key.middleDrag": "Botão do meio + arrastar",
+ "shortcuts.key.rightDrag": "Botão direito + arrastar",
+ "shortcuts.key.spaceDrag": "Space + arrastar",
+ "shortcuts.key.altLeftDrag": "Alt + arrastar esquerdo",
+ "shortcuts.key.arrows": "Setas",
+ "shortcuts.key.shiftArrows": "Shift + Setas",
+ "shortcuts.action.openShortcutScreen": "Abrir esta tela de atalhos",
+ "shortcuts.action.newCanvas": "Novo canvas",
+ "shortcuts.action.openFile": "Abrir arquivo",
+ "shortcuts.action.save": "Salvar",
+ "shortcuts.action.saveAs": "Salvar como",
+ "shortcuts.action.commandPalette": "Command Palette",
+ "shortcuts.action.undo": "Desfazer",
+ "shortcuts.action.redo": "Refazer",
+ "shortcuts.action.selectAll": "Selecionar todos",
+ "shortcuts.action.deleteSelection": "Excluir seleção",
+ "shortcuts.action.closeOverlayCancel": "Fechar overlays / cancelar ações",
+ "shortcuts.action.openNodeSearch": "Abrir busca de nodes",
+ "shortcuts.action.resetViewport": "Reset de viewport",
+ "shortcuts.action.centerSelection": "Centralizar seleção",
+ "shortcuts.action.fitSelection": "Enquadrar seleção",
+ "shortcuts.action.autoLayout": "Auto Layout",
+ "shortcuts.action.toggleSnapToGrid": "Toggle Snap to Grid",
+ "shortcuts.action.bringForward": "Trazer para frente",
+ "shortcuts.action.sendBackward": "Enviar para trás",
+ "shortcuts.action.bringToFront": "Trazer para o topo",
+ "shortcuts.action.sendToBack": "Enviar para o fundo",
+ "shortcuts.action.zoomInOut": "Zoom in / out",
+ "shortcuts.action.pan": "Pan",
+ "shortcuts.action.temporaryPan": "Pan temporário",
+ "shortcuts.action.alternatePan": "Pan alternativo",
+ "shortcuts.action.fineNudge": "Nudge fino da seleção",
+ "shortcuts.action.fastNudge": "Nudge acelerado",
+ "shortcuts.action.togglePreview": "Toggle data preview",
+ "shortcuts.action.explainPlan": "Explain plan",
+ "shortcuts.action.runPreview": "Run preview",
+ "shortcuts.action.connectionManager": "Connection manager",
+ "shortcuts.action.flowVersionHistory": "Flow version history",
+ "shortcuts.resetAll": "Resetar tudo",
+ "shortcuts.customized": "Customizado",
+ "shortcuts.default": "Padrão",
+ "shortcuts.apply": "Aplicar",
+ "shortcuts.reset": "Resetar",
+ "shortcuts.status.resetAllSuccess": "Todos os atalhos foram resetados para o padrão.",
+ "shortcuts.status.updated": "Atalho atualizado.",
+ "shortcuts.status.reset": "Atalho resetado para o padrão.",
+ "shortcuts.status.updateFailed": "Não foi possível atualizar o atalho.",
+ "toast.severity.success": "Sucesso",
+ "toast.severity.warning": "Aviso",
+ "toast.severity.error": "Erro",
+ "toast.details.success": "Detalhes de Sucesso",
+ "toast.details.warning": "Detalhes de Aviso",
+ "toast.details.error": "Detalhes de Erro",
+ "diagnostics.area.cteEditor": "Editor de CTE",
+ "diagnostics.area.viewEditor": "Editor de View",
+ "diagnostics.area.subEditor": "Sub-editor",
+ "diagnostics.cteEditor.restoreParentFailed": "Falha ao restaurar o canvas pai. As edições do CTE foram descartadas.",
+ "diagnostics.recommendation.reloadFileIfNeeded": "Recarregue o arquivo se necessário.",
+ "diagnostics.viewEditor.exitFailed": "Não foi possível sair: {0}",
+ "diagnostics.viewEditor.canvasIncomplete": "o canvas está incompleto.",
+ "diagnostics.viewEditor.exitRecommendation": "Conecte um ResultOutput válido ou use o comando de descarte.",
+ "diagnostics.viewEditor.restoreParentFailed": "Falha ao restaurar o canvas pai. O subgrafo foi descartado.",
+ "diagnostics.subEditor.executeFailed": "Falha ao executar ação do editor: {0}",
+ "diagnostics.subEditor.executeRecommendation": "Tente novamente. Se persistir, recarregue o canvas.",
+ "diagnostics.canvasMigration.openWarning": "Abertura: {0}",
+ "diagnostics.canvasMigration.sessionRestoreWarning": "Restauração de sessão: {0}",
+ "diagnostics.canvasMigration.versionRestoreWarning": "Restauração de versão: {0}",
+ "diagnostics.recommendation.resaveLatestSchema": "Revise os diagnósticos e salve novamente o canvas para persistir o schema mais recente.",
+ "diagnostics.recommendation.saveMigratedSchema": "Revise os diagnósticos e salve o canvas para persistir o schema migrado.",
+ "file.saveDialog.title": "Salvar Canvas",
+ "file.saveDialog.suggestedName": "Query1",
+ "file.save.success": "Canvas salvo com sucesso.",
+ "file.save.failedWithReason": "Falha ao salvar: {0}",
+ "file.openDialog.title": "Abrir Canvas",
+ "file.openDialog.canvasType": "Canvas SQL Architect",
+ "file.open.failedWithReason": "Falha ao abrir: {0}",
+ "file.open.success": "Canvas aberto com sucesso.",
+ "file.open.successWithWarnings": "Canvas aberto com avisos.",
+ "session.restore.failedWithReason": "Falha ao restaurar: {0}",
+ "session.restore.successWithWarnings": "Sessão restaurada com avisos.",
+ "session.restore.success": "Sessão restaurada com sucesso.",
+ "export.documentation.dialogTitle": "Exportar Documentação do Fluxo",
+ "export.documentation.success": "Documentação exportada com sucesso.",
+ "export.documentation.failed": "Falha ao exportar documentação.",
+ "export.failed.pathPermissionsHint": "Verifique o caminho do arquivo e as permissões.",
+ "export.nodeNotFound": "Nenhum nó de Exportação {0} foi encontrado no canvas. Adicione um pelo menu de busca de nós.",
+ "export.dialogTitleByExtension": "Exportar como {0}",
+ "export.success": "Exportação concluída com sucesso.",
+ "export.failed": "Falha na exportação.",
+ "fileHistory.currentFile.none": "Nenhum arquivo selecionado",
+ "fileHistory.status.saveFirst": "Salve o canvas primeiro para habilitar o histórico local.",
+ "fileHistory.status.noneFound": "Nenhuma versão local encontrada ainda. Salve este arquivo para criar entradas no histórico.",
+ "fileHistory.status.countAvailable": "{0} versão(ões) local(is) disponível(is).",
+ "fileHistory.restore.failedWithReason": "Falha ao restaurar: {0}",
+ "fileHistory.restore.successFrom": "Versão restaurada de {0}.",
+ "preview.status.cancelled": "Cancelado",
+ "preview.status.error": "Erro",
+ "preview.status.ready": "Pronto",
+ "preview.runningWithMs": "Executando... {0}ms",
+ "preview.runningWithTimeout": "Executando... {0}ms (timeout: {1}s)",
+ "preview.runningSlowWithTimeout": "Executando... {0}ms (timeout: {1}s) · Consulta lenta, timeout em {2}s",
+ "explain.errorWithReason": "Erro no explain plan: {0}",
+ "explain.noSql": "Nenhum SQL para explicar. Monte uma consulta no canvas primeiro.",
+ "ddl.compilationFailed": "Falha na compilação",
+ "ddl.compileErrorWithReason": "Erro de compilação DDL: {0}",
+ "command.undo.name": "Desfazer",
+ "command.undo.description": "Desfazer última ação",
+ "command.redo.name": "Refazer",
+ "command.redo.description": "Refazer última ação desfeita",
+ "command.addNode.name": "Adicionar nó",
+ "command.addNode.description": "Abrir menu de busca para adicionar um nó",
+ "command.bringForward.name": "Trazer para frente",
+ "command.bringForward.description": "Mover nós selecionados uma camada para frente",
+ "command.sendBackward.name": "Enviar para trás",
+ "command.sendBackward.description": "Mover nós selecionados uma camada para trás",
+ "command.bringToFront.name": "Trazer para o topo",
+ "command.bringToFront.description": "Mover nós selecionados para a camada superior",
+ "command.sendToBack.name": "Enviar para o fundo",
+ "command.sendToBack.description": "Mover nós selecionados para a camada inferior",
+ "command.normalizeLayers.name": "Normalizar camadas",
+ "command.normalizeLayers.description": "Compactar índices de camada para uma ordem limpa de 0..N",
+ "tooltip.cleanupOrphans": "Remover nós órfãos não conectados ao output (Ctrl+Z para desfazer)",
+ "main.orphanSuffix": "Órfão(s)",
+ "tooltip.autoFixAliasNaming": "Corrigir aliases para snake_case (Ctrl+Z para desfazer)",
+ "main.namingPrefix": "Nomenclatura",
+ "fileHistory.compressedLabel": "Comprimido:",
+ "schema.itemsSuffix": "item(ns)",
+ "property.panel.title": "Propriedades",
+ "property.panel.multiSelected": "{0} nós selecionados",
+ "sqlImporter.status.pasteSelect": "Cole um SELECT acima e clique em Importar.",
+ "sqlImporter.status.inputTooLarge": "A entrada SQL é muito grande ({0:N0} caracteres). O limite é {1:N0}. Divida a consulta ou aumente o limite de importação.",
+ "sqlImporter.status.parsing": "Analisando SQL...",
+ "sqlImporter.status.done": "Concluído - {0} importado(s), {1} parcial(is), {2} ignorado(s).",
+ "sqlImporter.status.cancelledByUser": "Importação cancelada pelo usuário.",
+ "sqlImporter.status.timeout": "A importação excedeu o tempo após {0:0.#}s. Tente uma consulta menor ou aumente o timeout.",
+ "sqlImporter.status.parseError": "Erro de parsing: {0}",
+ "sqlImporter.status.clearConfirmationRequired": "A importação SQL vai limpar o canvas atual. Confirme para continuar.",
+ "sqlImporter.status.clearConfirmationCancelled": "Importação cancelada. O canvas atual foi mantido.",
+ "diagnostics.area.undoRedoTransaction": "Transação Desfazer/Refazer",
+ "undoRedo.rollbackExecuted": "Rollback executado para '{0}' ({1} operação(ões) revertida(s)).",
+ "undoRedo.rollbackRecommendation": "Revise o estado do canvas e tente novamente a ação, se necessário.",
+ "node.preview.noCatalog": "Catálogo indisponível",
+ "connection.error.searchMenuNotInitialized": "menu de busca não inicializado",
+ "connection.error.timeoutReachability": "Connection timed out - check that the server is reachable and increase the timeout if needed.",
+ "connection.error.authenticationFailedForProvider": "Authentication failed - verify username and password for {0}.",
+ "connection.error.databaseNotFoundForProvider": "Database not found - confirm the database name exists on {0}.",
+ "connection.error.hostNotFound": "Host not found - check the server address and DNS resolution.",
+ "connection.error.portRefused": "Port connection refused - check the port number and that the server is running / firewall rules allow access.",
+ "connection.error.sslTls": "SSL/TLS error - check the server's SSL configuration or disable SSL for local connections.",
+ "connection.error.timeoutOverloaded": "Connection timed out - the server may be overloaded or unreachable. Try increasing the timeout.",
+ "connection.error.insufficientPrivileges": "Insufficient privileges - the user may lack permission to connect to this database.",
+ "diagnostics.area.connection": "Conexão",
+ "connection.warning.canvasMayContainOldTables": "O canvas ainda pode conter tabelas de uma conexão anterior.",
+ "connection.warning.canvasMayContainOldTablesRecommendation": "Limpe o canvas manualmente ou reconecte e escolha manter/limpar novamente.",
+ "undoRedo.transaction.unnamed": "transação sem nome",
+ "benchmark.runLabelDefault": "Execução 1",
+ "benchmark.runLabelPattern": "Execução {0}",
+ "benchmark.status.failedWithReason": "Falha no benchmark: {0}",
+ "benchmark.status.noSql": "Nenhum SQL para benchmark - monte uma consulta primeiro.",
+ "benchmark.status.warmupProgress": "Aquecimento {0}/{1}...",
+ "benchmark.status.iterationProgress": "Iteração {0}/{1}...",
+ "benchmark.status.done": "Concluído - {0}",
+ "benchmark.status.cancelled": "Benchmark cancelado.",
+ "app.windowTitle": "AkkornStudio",
+ "preview.error.safePreviewBlocked": "Modo Preview Seguro: comandos que alteram dados (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) não podem ser executados no preview.",
+ "preview.error.noActiveConnection": "Nenhuma conexão de banco ativa. Conecte-se a um banco primeiro.",
+ "sqlImporter.error.selectFromNotFound": "Não foi possível encontrar SELECT ... FROM na consulta.",
+ "sqlImporter.error.fromClauseParseFailed": "Não foi possível interpretar a cláusula FROM.",
+ "sqlImporter.error.syntaxUnterminatedString": "Erro de sintaxe na linha {0}, coluna {1}: literal de string não terminada.",
+ "sqlImporter.error.missingClosingParenthesis": "faltando ')' de fechamento",
+ "sqlImporter.error.unexpectedClosingParenthesis": "')' inesperado",
+ "sqlImporter.error.syntaxAtLineColumn": "Erro de sintaxe na linha {0}, coluna {1}: {2}.",
+ "errorDiagnostics.safePreview.label": "Bloqueado pelo Modo Preview Seguro",
+ "errorDiagnostics.safePreview.friendly": "Este SQL contém um comando de mutação de dados e não pode ser executado no preview.",
+ "errorDiagnostics.safePreview.suggestion": "Remova ou substitua o comando de mutação (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) antes de executar o preview.",
+ "errorDiagnostics.connection.label": "Falha de conexão",
+ "errorDiagnostics.connection.friendly": "Não foi possível alcançar o servidor de banco. O host pode estar indisponível, inacessível ou bloqueando conexões.",
+ "errorDiagnostics.connection.suggestion": "Verifique endereço e porta do servidor, confirme que o banco está em execução e confira as regras de firewall.",
+ "errorDiagnostics.authorization.label": "Erro de autorização",
+ "errorDiagnostics.authorization.friendly": "As credenciais atuais não têm permissão para executar esta operação.",
+ "errorDiagnostics.authorization.suggestion": "Confirme que o usuário do banco tem privilégios de SELECT no schema/tabela de destino, ou contate o DBA.",
+ "errorDiagnostics.timeout.label": "Timeout de consulta",
+ "errorDiagnostics.timeout.friendly": "A consulta demorou demais para concluir e foi cancelada pelo servidor ou cliente.",
+ "errorDiagnostics.timeout.suggestion": "Adicione WHERE ou LIMIT para reduzir o volume de dados, ou aumente o timeout da consulta nas configurações de conexão.",
+ "errorDiagnostics.schema.label": "Erro de schema",
+ "errorDiagnostics.schema.friendly": "Uma tabela, coluna ou objeto referenciado não foi encontrado no banco.",
+ "errorDiagnostics.schema.suggestion": "Verifique nomes de tabela/coluna e confirme que o schema corresponde à conexão ativa.",
+ "errorDiagnostics.syntax.label": "Erro de sintaxe SQL",
+ "errorDiagnostics.syntax.friendly": "A consulta contém erro de sintaxe e não pôde ser interpretada pelo mecanismo do banco.",
+ "errorDiagnostics.syntax.suggestion": "Revise o SQL destacado procurando typos, parênteses desalinhados ou cláusulas não suportadas pelo provider ativo.",
+ "errorDiagnostics.compatibility.label": "Erro de compatibilidade",
+ "errorDiagnostics.compatibility.friendly": "Uma função, operador ou construção de sintaxe não é suportada pelo provider de banco ativo.",
+ "errorDiagnostics.compatibility.suggestion": "Troque para o provider correto na barra SQL, ou substitua a construção não suportada por equivalente.",
+ "errorDiagnostics.unknown.label": "Erro inesperado",
+ "errorDiagnostics.unknown.friendly": "Ocorreu um erro ao executar a consulta de preview.",
+ "errorDiagnostics.unknown.suggestion": "Verifique os detalhes técnicos abaixo e confirme que o canvas está configurado corretamente.",
+ "error.mainWindow.invalidDataContext": "O DataContext da MainWindow deve ser um ShellViewModel.",
+ "error.mainWindow.canvasNotInitialized": "CanvasViewModel não foi inicializado.",
+ "error.mainWindow.ddlPreviewUnavailable": "Preview DDL indisponível para o canvas atual.",
+ "themeJson.editor.template": "{\n \"meta\": { \"name\": \"Tema Personalizado\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
+ "themeJson.error.pasteBeforeApply": "Cole um JSON de tema antes de aplicar.",
+ "themeJson.error.invalidJson": "JSON inválido: {0}",
+ "themeJson.error.emptyPayload": "JSON inválido: payload vazio.",
+ "themeJson.error.invalidTheme": "Tema inválido: {0}",
+ "themeJson.error.appliedButSaveFailed": "Tema aplicado, mas falhou ao salvar: {0}",
+ "themeJson.success.appliedAndSaved": "Tema JSON aplicado e salvo.",
+ "themeJson.success.customRemoved": "Tema personalizado removido. Reinicie o app para voltar totalmente ao tema padrão.",
+ "themeJson.error.restoreDefaultFailed": "Falha ao restaurar tema padrão: {0}",
+ "themeValidator.error.configNull": "A configuração de tema está nula.",
+ "themeValidator.warning.noSections": "O tema não possui seções de cores ou tipografia; nada para aplicar.",
+ "themeValidator.warning.invalidColor": "{0} possui cor inválida '{1}'. Esta chave será ignorada.",
+ "themeValidator.warning.sizeOutOfRange": "{0}={1} está fora do intervalo (8..48). Esta chave será ignorada.",
+ "queryExecutor.error.openConnectionMethodNotFound": "Não foi possível encontrar o método OpenConnectionAsync no orquestrador",
+ "queryExecutor.error.openConnectionInvokeFailed": "Falha ao invocar OpenConnectionAsync",
+ "ddlImporter.warning.viewSelectNotReconstructable": "View '{0}': o SELECT da view não pode ser reconstruído visualmente - edite manualmente no subcanvas.",
+ "ddlImporter.error.tableNotFoundInMetadata": "A tabela '{0}' não foi encontrada nos metadados atuais.",
+ "main.window.untitled": "Sem título",
+ "main.subEditor.noSeedProvided": "Nenhum seed de subeditor foi fornecido para {0}.",
+ "main.layerOrder.bringToFront": "Trazer para frente",
+ "main.layerOrder.sendToBack": "Enviar para trás",
+ "main.layerOrder.bringForward": "Avançar camada",
+ "main.layerOrder.sendBackward": "Recuar camada",
+ "main.layerOrder.normalizeLayers": "Normalizar camadas",
+ "export.fileType.html": "Arquivos HTML",
+ "export.fileType.json": "Arquivos JSON",
+ "export.fileType.csv": "Arquivos CSV",
+ "export.fileType.excel": "Arquivos Excel",
+ "commandPalette.templatePrefix": "Template: {0}",
+ "themeLoader.status.notFoundWithPath": "Arquivo de tema não encontrado: {0}",
+ "themeLoader.status.deserializedNull": "O JSON de tema foi desserializado para null.",
+ "themeLoader.status.loaded": "JSON de tema carregado com sucesso.",
+ "credential.error.ciphertextTooShort": "O blob de texto cifrado está muito curto.",
+ "credential.error.dpapiWindowsOnly": "DPAPI está disponível apenas no Windows.",
+ "credential.warning.loadVaultFailed": "Falha ao carregar o cofre de credenciais '{0}': {1}",
+ "credential.warning.persistVaultFailed": "Falha ao persistir o cofre de credenciais '{0}': {1}",
+ "snippetStore.warning.loadFailed": "Falha ao carregar snippets de '{0}': {1}",
+ "snippetStore.warning.saveFailed": "Falha ao salvar snippets: {0}",
+ "flowVersionStore.warning.loadFailed": "Falha ao carregar versões de fluxo de '{0}': {1}",
+ "flowVersionStore.warning.saveFailed": "Falha ao salvar versões de fluxo: {0}",
+ "queryExecutor.error.queryEmpty": "A consulta não pode estar vazia",
+ "queryExecutor.error.providerNotSupported": "O provider {0} não é suportado",
+ "queryExecutor.error.singleStatementOnly": "O preview aceita apenas uma única instrução SQL.",
+ "queryExecutor.error.queryEmptyWithPeriod": "A consulta não pode estar vazia.",
+ "queryExecutor.error.readOnlyOnly": "O modo preview suporta apenas instruções SQL somente leitura.",
+ "queryExecutor.error.namedParametersNotSupported": "O modo preview não suporta parâmetros nomeados na execução SQL. Use literais seguros inline ou execute a consulta fora do preview.",
+ "queryExecutor.error.positionalParametersNotSupported": "O modo preview não suporta placeholders posicionais ('?' ou '$1').",
+ "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "Align selected nodes to the bottom edge",
+ "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "Align selected nodes to the leftmost edge",
+ "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "Align selected nodes to the rightmost edge",
+ "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "Align selected nodes to the topmost edge",
+ "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "Apply CTE sub-canvas edits and return to the parent canvas",
+ "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "Arrange nodes into logical columns automatically",
+ "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "Centre selected nodes on a horizontal axis",
+ "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "Centre selected nodes on a vertical axis",
+ "commandPalette.description.clear_canvas_and_start_fresh": "Clear canvas and start fresh",
+ "commandPalette.description.clear_node_selection": "Clear node selection",
+ "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "Convert aliases to the convention configured in project settings",
+ "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "Create checkpoints, compare versions side-by-side and restore a previous canvas state",
+ "commandPalette.description.delete_the_selected_nodes": "Delete the selected nodes",
+ "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "Discard current sub-editor edits and return to the parent canvas",
+ "commandPalette.description.execute_the_current_query_in_preview": "Execute the current query in preview",
+ "commandPalette.description.fit_all_nodes_into_the_visible_area": "Fit all nodes into the visible area",
+ "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "Generate CSV file from the first CSV Export node",
+ "commandPalette.description.generate_html_file_from_the_first_html_export_node": "Generate HTML file from the first HTML Export node",
+ "commandPalette.description.generate_json_file_from_the_first_json_export_node": "Generate JSON file from the first JSON Export node",
+ "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "Generate XLSX workbook from the first Excel Export node",
+ "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "Inspect the query execution plan — see scan types, join strategies, and cost estimates",
+ "commandPalette.description.load_a_vsaq_canvas_file": "Load a .vsaq canvas file",
+ "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "Measure avg / median / p95 latency of the current SQL over N iterations",
+ "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "Open isolated sub-canvas editor for the selected CTE Definition node",
+ "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "Open local file version history created on each save and restore previous saved snapshots",
+ "commandPalette.description.open_output_preview_modal_for_the_active_mode": "Open output preview modal for the active mode",
+ "commandPalette.description.open_shortcut_reference_screen": "Open shortcut reference screen",
+ "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "Open the connection manager to add, edit or switch database connections",
+ "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "Paste a SELECT statement and generate nodes automatically — FROM, JOIN, WHERE, LIMIT are supported",
+ "commandPalette.description.remove_all_nodes_not_connected_to_output": "Remove all nodes not connected to output",
+ "commandPalette.description.reset_zoom_and_pan_to_default": "Reset zoom and pan to default",
+ "commandPalette.description.save_canvas_to_a_new_file": "Save canvas to a new file",
+ "commandPalette.description.save_current_canvas": "Save current canvas",
+ "commandPalette.description.save_markdown_documentation_of_the_current_flow": "Save Markdown documentation of the current flow",
+ "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "Save the selected nodes as a reusable snippet — insert it later via the node search menu (⇧A)",
+ "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "Scan all table-source nodes on the canvas for possible join relationships based on FK conventions and naming patterns",
+ "commandPalette.description.select_all_nodes_on_canvas": "Select all nodes on canvas",
+ "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "Snap node positions to 16px grid (Ctrl+G)",
+ "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "Spread selected nodes with equal horizontal spacing",
+ "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "Spread selected nodes with equal vertical spacing",
+ "commandPalette.description.zoom_into_the_canvas": "Zoom into the canvas",
+ "commandPalette.description.zoom_out_of_the_canvas": "Zoom out of the canvas",
+ "commandPalette.name.align_bottom": "Align Bottom",
+ "commandPalette.name.align_left": "Align Left",
+ "commandPalette.name.align_right": "Align Right",
+ "commandPalette.name.align_top": "Align Top",
+ "commandPalette.name.analyze_all_joins": "Analyze All Joins",
+ "commandPalette.name.auto_fix_naming": "Auto-Fix Naming",
+ "commandPalette.name.auto_layout": "Auto Layout",
+ "commandPalette.name.center_horizontally": "Center Horizontally",
+ "commandPalette.name.center_vertically": "Center Vertically",
+ "commandPalette.name.cleanup_orphans": "Cleanup Orphans",
+ "commandPalette.name.delete_selected": "Delete Selected",
+ "commandPalette.name.deselect_all": "Deselect All",
+ "commandPalette.name.discard_and_exit_editor": "Discard and Exit Editor",
+ "commandPalette.name.distribute_horizontally": "Distribute Horizontally",
+ "commandPalette.name.distribute_vertically": "Distribute Vertically",
+ "commandPalette.name.edit_selected_cte": "Edit Selected CTE",
+ "commandPalette.name.exit_cte_editor": "Exit CTE Editor",
+ "commandPalette.name.explain_plan": "Explain Plan",
+ "commandPalette.name.export_csv": "Export CSV",
+ "commandPalette.name.export_documentation": "Export Documentation",
+ "commandPalette.name.export_excel": "Export Excel",
+ "commandPalette.name.export_html": "Export HTML",
+ "commandPalette.name.export_json": "Export JSON",
+ "commandPalette.name.file_save_load_history": "File Save/Load History",
+ "commandPalette.name.fit_to_screen": "Fit to Screen",
+ "commandPalette.name.flow_version_history": "Flow Version History",
+ "commandPalette.name.import_sql_to_graph": "Import SQL to Graph",
+ "commandPalette.name.keyboard_shortcuts": "Keyboard Shortcuts",
+ "commandPalette.name.manage_connections": "Manage Connections",
+ "commandPalette.name.new_canvas": "New Canvas",
+ "commandPalette.name.open_file": "Open File",
+ "commandPalette.name.reset_viewport": "Reset Viewport",
+ "commandPalette.name.run_preview": "Run Preview",
+ "commandPalette.name.run_query_benchmark": "Run Query Benchmark",
+ "commandPalette.name.save": "Save",
+ "commandPalette.name.save_as": "Save As",
+ "commandPalette.name.save_selection_as_snippet": "Save Selection as Snippet",
+ "commandPalette.name.select_all": "Select All",
+ "commandPalette.name.toggle_preview": "Toggle Preview",
+ "commandPalette.name.toggle_snap_to_grid": "Toggle Snap to Grid",
+ "commandPalette.name.zoom_in": "Zoom In",
+ "commandPalette.name.zoom_out": "Zoom Out",
+ "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 percent restore zoom pan viewport",
+ "commandPalette.tags.align_bottom_edge_selection_nodes": "align bottom edge selection nodes",
+ "commandPalette.tags.align_center_middle_horizontal_nodes": "align center middle horizontal nodes",
+ "commandPalette.tags.align_center_middle_vertical_nodes": "align center middle vertical nodes",
+ "commandPalette.tags.align_left_edge_selection_nodes": "align left edge selection nodes",
+ "commandPalette.tags.align_right_edge_selection_nodes": "align right edge selection nodes",
+ "commandPalette.tags.align_top_edge_selection_nodes": "align top edge selection nodes",
+ "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout view reset zoom",
+ "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark performance latency timing profile measure speed",
+ "commandPalette.tags.clear_selection": "clear selection",
+ "commandPalette.tags.connection_database_server_host_provider_switch": "connection database server host provider switch",
+ "commandPalette.tags.create_insert_search_transform": "create insert search transform",
+ "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas exit apply back",
+ "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte view subcanvas discard exit force",
+ "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursive editor subgraph subcanvas isolate",
+ "commandPalette.tags.data_results_table_panel": "data results table panel",
+ "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribute space equal horizontal nodes",
+ "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribute space equal vertical nodes",
+ "commandPalette.tags.execute_run_sql_query_results": "execute run sql query results",
+ "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan execution cost scan index join performance",
+ "commandPalette.tags.export_csv_file_tabular_output_save": "export csv file tabular output save",
+ "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "export excel xlsx file tabular output spreadsheet save",
+ "commandPalette.tags.export_html_file_output_report_save": "export html file output report save",
+ "commandPalette.tags.export_json_file_output_save": "export json file output save",
+ "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "export markdown doc documentation flow save md",
+ "commandPalette.tags.export_persist_copy": "export persist copy",
+ "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "file history save load backup versions restore local",
+ "commandPalette.tags.forward_history": "forward history",
+ "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "help shortcuts hotkeys keyboard reference",
+ "commandPalette.tags.highlight_mark_all_nodes": "highlight mark all nodes",
+ "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "import sql paste convert graph reverse engineer query",
+ "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analyze suggest detect foreign key relationships heuristic",
+ "commandPalette.tags.layer_z_order_back_selected_nodes": "layer z-order back selected nodes",
+ "commandPalette.tags.layer_z_order_backward_selected_nodes": "layer z-order backward selected nodes",
+ "commandPalette.tags.layer_z_order_forward_selected_nodes": "layer z-order forward selected nodes",
+ "commandPalette.tags.layer_z_order_front_selected_nodes": "layer z-order front selected nodes",
+ "commandPalette.tags.layer_z_order_normalize_compact": "layer z-order normalize compact",
+ "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout arrange columns auto organize readability",
+ "commandPalette.tags.load_import_vsaq": "load import vsaq",
+ "commandPalette.tags.magnify_enlarge": "magnify enlarge",
+ "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "orphan unused disconnected clean delete nodes",
+ "commandPalette.tags.persist_write_disk": "persist write disk",
+ "commandPalette.tags.remove_erase_nodes": "remove erase nodes",
+ "commandPalette.tags.rename_alias_fix_naming_convention": "rename alias fix naming convention",
+ "commandPalette.tags.reset_clear_blank": "reset clear blank",
+ "commandPalette.tags.revert_back_history": "revert back history",
+ "commandPalette.tags.shrink_reduce": "shrink reduce",
+ "commandPalette.tags.snap_grid_align_precision_position": "snap grid align precision position",
+ "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet save selection reuse template favorite bookmark",
+ "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "version history checkpoint diff restore snapshot compare undo flow",
+ "sqlEditor.diffPreview.title": "Previa de diff transacional",
+ "sqlEditor.mutation.confirmExecute": "Confirmar execucao",
+ "sqlEditor.tab.closeAnyway": "Fechar mesmo assim",
+ "sqlEditor.tab.keepTab": "Manter aba",
+ "sqlEditor.status.ready": "Pronto.",
+ "sqlEditor.telemetry.none": "Sem telemetria de execucao ainda.",
+ "sqlEditor.telemetry.summary": "Instrucoes: {0} Sucesso: {1} Falhas: {2} Total: {3} ms",
+ "sqlEditor.telemetry.errors.none": "Sem erros agregados.",
+ "sqlEditor.diff.none": "Sem diff transacional disponivel.",
+ "sqlEditor.mutation.estimate.none": "Sem estimativa de mutacao disponivel.",
+ "sqlEditor.mutation.estimate.value": "Linhas afetadas estimadas: {0}",
+ "sqlEditor.mutation.estimate.unavailable": "Nao foi possivel estimar as linhas afetadas automaticamente.",
+ "sqlEditor.tab.closePending": "Alteracoes nao salvas detectadas. Confirme o fechamento da aba.",
+ "sqlEditor.tab.noPendingClose": "Nao ha fechamento de aba pendente.",
+ "sqlEditor.tab.manyWarning": "Quantidade alta de abas: {0} abas abertas.",
+ "sqlEditor.mutation.pending.none": "Sem confirmacao de mutacao pendente.",
+ "sqlEditor.mutation.pending.required": "A mutacao exige confirmacao antes da execucao.",
+ "sqlEditor.message.empty": "Execute uma instrucao para ver mensagens.",
+ "sqlEditor.message.success": "Execucao concluida com sucesso.",
+ "sqlEditor.result.summary.empty": "Linhas: - Tempo: -",
+ "sqlEditor.result.summary": "Linhas: {0} Tempo: {1} ms",
+ "sqlEditor.file.save.canceled": "Salvamento cancelado.",
+ "sqlEditor.file.save.noPath": "Nenhum caminho de destino selecionado.",
+ "sqlEditor.file.save.success": "Arquivo SQL salvo.",
+ "sqlEditor.file.save.failed": "Falha ao salvar arquivo SQL.",
+ "sqlEditor.file.open.failed": "Falha ao abrir arquivo SQL.",
+ "sqlEditor.file.open.notFound": "O arquivo SQL selecionado nao foi encontrado.",
+ "sqlEditor.file.open.success": "Arquivo SQL aberto.",
+ "sqlEditor.status.executing": "Executando SQL...",
+ "sqlEditor.status.executingScript": "Executando script SQL...",
+ "sqlEditor.status.executingStep": "Executando {0}/{1}...",
+ "sqlEditor.status.canceling": "Cancelando execucao...",
+ "sqlEditor.status.executingConfirmedMutation": "Executando mutacao confirmada...",
+ "sqlEditor.status.mutationCanceled": "Execucao da mutacao cancelada.",
+ "sqlEditor.detail.statementNotExecuted": "A instrucao nao foi executada.",
+ "sqlEditor.status.success": "Execucao concluida com sucesso.",
+ "sqlEditor.detail.rowsAndTime": "{0} linha(s) em {1} ms.",
+ "sqlEditor.status.canceled": "Execucao cancelada.",
+ "sqlEditor.status.failed": "Falha na execucao.",
+ "sqlEditor.status.confirmationRequired": "Confirmacao necessaria antes da execucao.",
+ "sqlEditor.error.mutationConfirmationRequired": "Confirmacao de mutacao necessaria.",
+ "sqlEditor.result.tabTitle": "Resultado {0}",
+ "sqlEditor.tab.closeRequiresConfirmation": "O fechamento da aba exige confirmacao.",
+ "sqlEditor.tab.unsavedDetail": "Esta aba possui alteracoes nao salvas.",
+ "sqlEditor.tab.closed": "Aba fechada.",
+ "sqlEditor.tab.closeCanceled": "Fechamento da aba cancelado.",
+ "sqlEditor.tab.closeCanceledDetail": "Aba com alteracoes nao salvas mantida aberta.",
+ "sqlEditor.error.noStatementSelected": "Nenhuma instrucao SQL selecionada para execucao.",
+ "sqlEditor.error.noConnection": "Nenhuma conexao ativa para execucao SQL.",
+ "sqlEditor.error.executionCanceled": "A execucao SQL foi cancelada.",
+ "sqlEditor.tab.scriptTitle": "Script {0}",
+ "sqlEditor.guard.delete.noWhere.message": "DELETE sem WHERE pode remover todas as linhas.",
+ "sqlEditor.guard.delete.noWhere.recommendation": "Adicione uma clausula WHERE restritiva antes de executar.",
+ "sqlEditor.guard.delete.trivialWhere.message": "DELETE possui uma clausula WHERE trivialmente verdadeira.",
+ "sqlEditor.guard.delete.trivialWhere.recommendation": "Use um filtro seletivo para atingir apenas as linhas desejadas.",
+ "sqlEditor.guard.update.noWhere.message": "UPDATE sem WHERE pode afetar todas as linhas.",
+ "sqlEditor.guard.update.noWhere.recommendation": "Adicione uma clausula WHERE restritiva antes de executar.",
+ "sqlEditor.guard.update.trivialWhere.message": "UPDATE possui uma clausula WHERE trivialmente verdadeira.",
+ "sqlEditor.guard.update.trivialWhere.recommendation": "Use um filtro seletivo para atingir apenas as linhas desejadas.",
+ "sqlEditor.guard.insert.noColumnList.message": "INSERT sem lista explicita de colunas e fragil diante de mudancas de schema.",
+ "sqlEditor.guard.insert.noColumnList.recommendation": "Prefira INSERT INTO tabela(col1, col2, ...) VALUES (...).",
+ "sqlEditor.guard.ddl.message": "Uma instrucao DDL pode causar mudancas estruturais no banco de dados.",
+ "sqlEditor.guard.ddl.recommendation": "Confirme a execucao apenas quando as mudancas de schema forem intencionais.",
+ "sqlEditor.diff.unavailable.noPreview": "Sem previa de diff transacional disponivel para esta instrucao.",
+ "sqlEditor.diff.unavailable.parseError": "Nao foi possivel identificar o alvo da mutacao para gerar a previa de diff transacional.",
+ "sqlEditor.diff.unavailable.connection": "Previa de diff transacional indisponivel por limitacoes de conexao ou consulta.",
+ "sqlEditor.diff.deleteSummary": "Previa de diff transacional (ROLLBACK garantido): tabela {0}, total de linhas antes {1}, afetadas {2}, total de linhas depois {3}.",
+ "sqlEditor.diff.updateSummary": "Previa de diff transacional (ROLLBACK garantido): tabela {0}, total de linhas antes {1}, linhas candidatas afetadas {2}, total de linhas depois {3}.",
+ "sqlEditor.diff.unavailable.unsupportedStatement": "A previa de diff transacional atualmente suporta apenas UPDATE e DELETE.",
+ "sqlEditor.results.title": "Resultados",
+ "sqlEditor.results.filterWatermark": "Filtrar resultados",
+ "sqlEditor.results.rows.countZero": "0 linhas",
+ "sqlEditor.results.rows.countSingle": "{0} linhas",
+ "sqlEditor.results.rows.countFiltered": "{0} de {1} linhas",
+ "sqlEditor.results.context.copyCell": "Copiar célula",
+ "sqlEditor.results.context.copyRow": "Copiar linha",
+ "sqlEditor.results.context.hideColumn": "Ocultar coluna",
+ "sqlEditor.results.context.showAllColumns": "Mostrar todas as colunas",
+ "sqlEditor.sidebar.messages": "MENSAGENS",
+ "sqlEditor.sidebar.history": "HISTÓRICO",
+ "sqlEditor.sidebar.connection.none": "Sem conexão",
+ "sqlEditor.sidebar.connection.connectHint": "Conecte-se para carregar metadados e executar consultas.",
+ "sqlEditor.sidebar.connection.connect": "Conectar",
+ "sqlEditor.sidebar.schema.searchWatermark": "Buscar tabela ou coluna",
+ "sqlEditor.sidebar.schema.reloadTooltip": "Recarregar metadados",
+ "sqlEditor.sidebar.schema.connectHint": "Conecte-se para visualizar o schema completo.",
+ "sqlEditor.history.searchWatermark": "Buscar no histórico",
+ "sqlEditor.history.navigationHint": "Setas percorrem o histórico, Enter executa selecionado e Esc limpa a busca.",
+ "sqlEditor.history.noSearchResults": "Nenhum item encontrado para a busca.",
+ "sqlEditor.history.use": "Usar",
+ "sqlEditor.history.copy": "Copiar",
+ "sqlEditor.history.run": "Executar",
+ "sqlEditor.history.copiedFromHistory": "SQL copiado do histórico.",
+ "sqlEditor.toast.scriptSuccessTitle": "Script executado.",
+ "sqlEditor.toast.scriptSuccessDetail": "{0} instrução(ões) executada(s) com sucesso.",
+ "sqlEditor.toast.scriptWarningTitle": "Script executado com falhas.",
+ "sqlEditor.toast.scriptWarningDetail": "{0} de {1} instrução(ões) falharam.",
+ "sqlEditor.toast.resultErrorTitle": "Falha ao executar instrução.",
+ "sqlEditor.toast.resultSuccessTitle": "Execução concluída com sucesso.",
+ "sqlEditor.export.action": "Exportar relatório",
+ "sqlEditor.openSql.pickerTitle": "Abrir Arquivo SQL",
+ "sqlEditor.saveSql.fileType": "Arquivos SQL",
+ "sqlEditor.saveSql.pickerTitle": "Salvar Arquivo SQL",
+ "sqlEditor.export.pickerTitle": "Exportar Dados SQL",
+ "sqlEditor.export.status.noResultTitle": "Nenhum resultado de execucao disponivel para exportacao.",
+ "sqlEditor.export.status.noResultDetail": "Execute uma consulta primeiro.",
+ "sqlEditor.export.status.successTitle": "Relatorio exportado.",
+ "sqlEditor.export.status.failedTitle": "Falha ao exportar relatorio.",
+ "sqlEditor.export.fileType.html": "Arquivo HTML",
+ "sqlEditor.export.fileType.json": "Arquivo JSON",
+ "sqlEditor.export.fileType.csv": "Arquivo CSV",
+ "sqlEditor.export.fileType.xlsx": "Pasta de Trabalho Excel",
+ "sqlEditor.export.defaultFileBase": "relatorio",
+ "sqlEditor.export.defaultTitle": "Relatorio SQL",
+ "sqlEditor.export.error.typeRequired": "Um tipo de relatorio deve ser selecionado antes da exportacao.",
+ "sqlEditor.export.type.html.title": "Relatorio HTML completo",
+ "sqlEditor.export.type.html.description": "Artefato HTML autonomo e orientado a SQL para auditoria offline.",
+ "sqlEditor.export.type.json.title": "Contrato de execucao JSON",
+ "sqlEditor.export.type.json.description": "Payload legivel por maquina com SQL, metadados e resultado da execucao.",
+ "sqlEditor.export.type.csv.title": "Exportacao de dados CSV",
+ "sqlEditor.export.type.csv.description": "Apenas dados tabulares do resultado, ideal para planilhas.",
+ "sqlEditor.export.type.xlsx.title": "Exportacao de pasta Excel",
+ "sqlEditor.export.type.xlsx.description": "Pasta de trabalho com os dados tabulares do resultado.",
+ "sqlEditor.export.dialog.windowTitle": "Exportar Dados SQL",
+ "sqlEditor.export.dialog.title": "Exportar Dados SQL",
+ "sqlEditor.export.dialog.subtitle": "Escolha o formato e os metadados do artefato antes de exportar.",
+ "sqlEditor.export.dialog.confirm": "Exportar",
+ "sqlEditor.export.dialog.fileNameWatermark": "relatorio.html",
+ "sqlEditor.export.dialog.titleWatermark": "Relatorio SQL",
+ "sqlEditor.export.dialog.descriptionWatermark": "Contexto adicional para auditoria e compartilhamento.",
+ "sqlEditor.export.dialog.section.reportType": "TIPO DE RELATORIO",
+ "sqlEditor.export.dialog.section.fileName": "NOME DO ARQUIVO",
+ "sqlEditor.export.dialog.section.reportTitle": "TITULO",
+ "sqlEditor.export.dialog.section.description": "DESCRICAO",
+ "sqlEditor.export.dialog.section.options": "OPCOES",
+ "sqlEditor.export.option.includeSchema": "Incluir schema de saida",
+ "sqlEditor.export.option.includeNodeDetails": "Incluir placeholders de no/conexao no JSON",
+ "sqlEditor.export.option.includeMetadata": "Incluir metadados opcionais",
+ "sqlEditor.export.option.useDashForEmpty": "Usar '-' para campos vazios",
+ "sqlEditor.export.badge.offline": "PRONTO PARA OFFLINE",
+ "sqlEditor.export.badge.structured": "PAYLOAD ESTRUTURADO",
+ "sqlEditor.export.badge.dataOnly": "SOMENTE DADOS"
+}
diff --git a/src/DBWeaver.UI/Assets/Localization/ru-RU.json b/src/AkkornStudio.UI/Assets/Localization/ru-RU.json
similarity index 98%
rename from src/DBWeaver.UI/Assets/Localization/ru-RU.json
rename to src/AkkornStudio.UI/Assets/Localization/ru-RU.json
index 790c6894..1dda0c27 100644
--- a/src/DBWeaver.UI/Assets/Localization/ru-RU.json
+++ b/src/AkkornStudio.UI/Assets/Localization/ru-RU.json
@@ -1,1087 +1,1087 @@
-{
- "main.brand": "DBWeaver",
- "main.tab.query1": "Query 1",
- "main.new": "New",
- "main.open": "Open",
- "main.save": "Save",
- "main.history": "History",
- "main.layout": "Layout",
- "main.preview": "Preview",
- "main.undo": "Undo",
- "main.redo": "Redo",
- "main.cleanupOrphans": "Cleanup orphan nodes",
- "main.autoFixAliasNaming": "Auto-fix alias naming",
- "main.autoLayoutCanvas": "Auto layout canvas",
- "main.toggleDataPreview": "Toggle data preview",
- "main.language": "Language",
- "main.restore.prompt": "Previous session found — restore the last canvas?",
- "main.restore.button": "Restore session",
- "main.cteEditor.editingPrefix": "Editing CTE: ",
- "main.cteEditor.backToCanvas": "Back to Canvas",
- "main.cteEditor.exitA11y": "Exit CTE editor",
- "main.viewEditor.editingPrefix": "DDL > View: ",
- "main.viewEditor.backToCanvas": "Back to DDL",
- "main.viewEditor.exitA11y": "Exit view editor",
- "connection.title": "Connection Manager",
- "connection.subtitle": "Настраивайте, проверяйте и активируйте подключения, не прерывая поток",
- "connection.none": "No connection",
- "connection.active": "ACTIVE",
- "connection.health.online": "Online",
- "connection.health.degraded": "Degraded",
- "connection.health.offline": "Offline",
- "connection.tooltip.none": "No active connection — click to manage",
- "connection.ping": "Ping",
- "connection.saved": "SAVED CONNECTIONS",
- "connection.new": "New Connection",
- "connection.selectOrCreate": "Select a connection or create a new one",
- "connection.name": "Connection Name",
- "connection.provider": "Provider",
- "connection.host": "Host",
- "connection.port": "Port",
- "connection.database": "Database",
- "connection.sqlitePath": "SQLite Path",
- "connection.sqliteBrowse": "Browse",
- "connection.sqliteCreate": "Create",
- "connection.username": "Username",
- "connection.password": "Password",
- "connection.timeout": "Timeout (seconds)",
- "connection.test": "Test",
- "connection.save": "Save",
- "connection.connect": "Connect",
- "connection.action.testConnection": "Test connection",
- "connection.action.saveConnection": "Save connection",
- "connection.action.connectConnection": "Connect connection",
- "connection.status.connecting": "Подключение...",
- "connection.status.connected": "Подключено",
- "connection.status.testing": "Проверка...",
- "connection.status.failedPrefix": "Сбой подключения",
- "connection.status.metadataUnavailable": "Сбой подключения: метаданные недоступны.",
- "connection.status.highLatency": "высокая задержка",
- "connection.watermark.name": "Моя Prod БД",
- "connection.watermark.host": "localhost",
- "connection.watermark.port": "5432",
- "connection.watermark.database": "database_name",
- "connection.watermark.username": "user",
- "connection.watermark.password": "••••••••",
- "connection.watermark.timeout": "30",
- "main.connectingDb": "Connecting to database...",
- "main.emptyHint": "Press ⇧A to add your first node, or drag a table from the sidebar",
- "status.nodesSeparator": " nodes · ",
- "status.connectionsSuffix": " connections",
- "status.undo": "Undo: ",
- "status.shortcuts": "⇧A Nodes · F3 Preview · Ctrl+Z Undo · Del Remove · Alt+Drag Pan",
- "connection.disconnect": "Disconnect",
- "connection.action.disconnectConnection": "Disconnect connection",
- "connectionTab.active": "ACTIVE CONNECTION",
- "connectionTab.none": "No active connection",
- "connectionTab.saved": "SAVED CONNECTIONS",
- "connectionTab.new": "+ New Connection",
- "schema.database": "DATABASE",
- "schema.search": "Search tables, columns...",
- "schema.loading": "Searching tables, columns...",
- "schema.noConnection": "No Connection",
- "schema.noConnectionHint": "Connect to a database to see tables, columns, and relationships",
- "schema.emptyNoTables": "No tables found",
- "fileHistory.title": "Save/Load Version History",
- "fileHistory.reload": "Reload",
- "fileHistory.restoreSelected": "Restore selected",
- "fileHistory.empty": "No local versions yet",
- "fileHistory.emptyHint": "Save this file to generate version history.",
- "preview.title": "Data Preview",
- "preview.subtitle": "Review data and diagnostics before continuing",
- "preview.run": "Run",
- "preview.cancel": "Cancel",
- "preview.tab.preview": "Preview",
- "preview.tab.sql": "SQL",
- "preview.close": "Close preview",
- "preview.running": "Running preview query… ",
- "preview.clickCancel": "Click Cancel to stop",
- "preview.cancelled": "Query cancelled",
- "preview.runAgain": "Press Run to execute again",
- "preview.failed": "Preview execution failed",
- "preview.technical": "TECHNICAL DETAILS",
- "preview.noData": "No data yet",
- "preview.f3Hint": "Press F3 or Space to run the current query",
- "sqlImporter.title": "Import SQL to Graph",
- "sqlImporter.subtitle": "Paste a SELECT statement — nodes are created automatically",
- "sqlImporter.sqlStatement": "SQL STATEMENT",
- "sqlImporter.supported": "Supported: ",
- "sqlImporter.import": "Import",
- "sqlImporter.report": "CONVERSION REPORT",
- "sqlEditor.mutation.dialogTitle": "Подтверждение изменения",
- "sqlEditor.mutation.dialogSubtitle": "Проверьте влияние перед подтверждением выполнения",
- "search.empty": "No nodes found",
- "search.emptyHint": "Try searching for UPPER, JSON, CAST, AND…",
- "search.shortcut": "⇧A",
- "search.spawn": "Spawn",
- "commandPalette.empty": "Нет команд, соответствующих поиску",
- "commandPalette.search": "Поиск команд",
- "commandPalette.shortcut": "CTRL+SHIFT+P",
- "commandPalette.execute": "Выполнить",
- "context.editCte": "Edit Selected CTE",
- "context.editViewSubcanvas": "Edit View Subcanvas",
- "explain.title": "Explain Plan",
- "explain.sql": "SQL",
- "explain.option.analyze": "Анализ",
- "explain.option.buffers": "Буферы",
- "explain.badge.simulated": "СИМУЛИРОВАНО",
- "explain.timing.planning": "Планирование:",
- "explain.timing.execution": "Выполнение:",
- "explain.section.snapshotComparison": "Сравнение снимков",
- "explain.section.indexRecommendations": "Рекомендации по индексам",
- "explain.section.history": "История",
- "explain.detail.estimated": "Оценочные",
- "explain.detail.actual": "Фактические",
- "explain.detail.error": "Ошибка",
- "explain.detail.time": "Время",
- "explain.detail.loops": "Циклы",
- "explain.rerun": "Re-run",
- "explain.alertSuffix": " expensive operation(s) detected — consider adding indexes",
- "explain.running": "Running EXPLAIN…",
- "explain.failed": "⚠ EXPLAIN failed",
- "explain.noPlan": "No plan yet",
- "explain.rerunHint": "Press Re-run to execute EXPLAIN",
- "explain.header.operation": "ОПЕРАЦИЯ",
- "explain.header.cost": "СТОИМОСТЬ",
- "explain.header.rows": "СТРОКИ",
- "explain.header.alert": "ПРЕДУПРЕЖДЕНИЕ",
- "explain.mode.list": "Список",
- "explain.mode.tree": "Дерево",
- "explain.action.snapshot": "Сохранить снимок",
- "explain.action.copyJson": "Копировать JSON",
- "explain.action.copyText": "Копировать текст",
- "explain.action.saveJson": "Сохранить .json",
- "explain.action.openDalibo": "Открыть в Dalibo",
- "explain.legend.seqscan": "SEQ SCAN — full table read, no index",
- "explain.legend.sort": "SORT — in-memory sort",
- "explain.legend.hash": "HASH — hash join",
- "explain.escClose": "Esc to close",
- "flowVersion.title": "Flow Version History",
- "flowVersion.subtitle": "Create checkpoints, compare versions and restore",
- "flowVersion.watermark": "Checkpoint label (optional)…",
- "flowVersion.saveCheckpoint": "Save Checkpoint",
- "flowVersion.compareMode": "Compare Mode",
- "flowVersion.selectBase": "Select BASE version (from):",
- "flowVersion.clickAny": "Then click any version in the list below to compare.",
- "flowVersion.noCheckpoints": "No checkpoints yet",
- "flowVersion.noCheckpointsHint": "Save a checkpoint above to begin tracking versions.",
- "flowVersion.restore": "Restore",
- "flowVersion.diffResults": "Diff Results",
- "benchmark.title": "Query Benchmark",
- "benchmark.subtitle": "Measures avg / median / p95 latency over N iterations",
- "benchmark.sql": "SQL being benchmarked",
- "benchmark.runLabel": "Run label",
- "benchmark.runLabelWatermark": "Run 1",
- "benchmark.iterations": "Iterations (1–100)",
- "benchmark.warmup": "Warm-up passes (0–10)",
- "benchmark.interval": "Interval between runs (ms)",
- "benchmark.run": "Run Benchmark",
- "benchmark.cancel": "Cancel",
- "benchmark.clearHistory": "Clear History",
- "benchmark.latest": "LATEST RESULT",
- "benchmark.avg": "AVG",
- "benchmark.median": "MEDIAN",
- "benchmark.min": "MIN",
- "benchmark.max": "MAX",
- "benchmark.iterationsAt": " iterations · run at ",
- "benchmark.history": "HISTORY",
- "benchmark.header.label": "Метка",
- "benchmark.header.avg": "Средн.",
- "benchmark.header.median": "Медиана",
- "benchmark.header.min": "Мин",
- "benchmark.header.max": "Макс",
- "benchmark.itersSuffix": " iters",
- "diagnostics.title": "App Diagnostics",
- "diagnostics.run": "Run",
- "diagnostics.running": "Running checks…",
- "diagnostics.ok": "OK",
- "diagnostics.warning": "Warning",
- "diagnostics.error": "Error",
- "diagnostics.tooltip.rerun": "Re-run all checks",
- "diagnostics.tooltip.copy": "Copy diagnostic report to clipboard",
- "diagnostics.tooltip.close": "Close (Esc)",
- "autoJoin.title": "Auto-Join Suggestions",
- "autoJoin.titleForTable": "Auto-Join suggestions for {0}",
- "autoJoin.acceptAll": "Accept All",
- "autoJoin.accept": "Accept",
- "autoJoin.skip": "Skip",
- "autoJoin.allHandled": "All suggestions handled",
- "autoJoin.joinKeyword": "JOIN",
- "autoJoin.confidence.fkConstraint": "FK Constraint",
- "autoJoin.confidence.fkReverse": "FK (Reverse)",
- "autoJoin.confidence.namingMatch": "Naming Match",
- "autoJoin.confidence.weakMatch": "Weak Match",
- "autoJoin.runSelected": "Auto-Join Selected",
- "autoJoin.noSimilarityTitle": "No automatic join found",
- "autoJoin.noSimilarityDetails": "Choose the columns manually to create a simple join.",
- "autoJoin.appliedTitle": "Auto-join applied",
- "autoJoin.manual.title": "Create Manual Join",
- "autoJoin.manual.subtitle": "No reliable similarity was found. Select one column from each table.",
- "autoJoin.manual.leftColumn": "Left column",
- "autoJoin.manual.rightColumn": "Right column",
- "autoJoin.manual.joinType": "Join type",
- "autoJoin.manual.operator": "Operator",
- "autoJoin.manual.confirm": "Create join",
- "autoJoin.manual.noCompatible": "No compatible columns for the selected left pin type.",
- "autoJoin.manualJoinCreatedTitle": "Manual join created",
- "autoJoin.manualJoinFailedTitle": "Manual join could not be created",
- "autoJoin.manualJoinFailedDetails": "Check selected columns and existing joins, then try again.",
- "autoJoin.multipleCandidatesTitle": "Multiple join candidates found",
- "autoJoin.multipleCandidatesDetails": "{0} possible combinations were found. Confirm which columns should be used.",
- "autoJoin.suggestionsFoundTitle": "Auto-join suggestions available",
- "autoJoin.suggestionsFoundDetails": "{0} suggestion(s) found. Select two tables and run Auto-Join Selected.",
- "property.outputAlias": "OUTPUT ALIAS",
- "property.sourceAlias": "SOURCE ALIAS",
- "property.aliasWatermark": "e.g. MyColumn (optional)",
- "property.parameters": "PARAMETERS",
- "property.enabled": "Enabled",
- "property.datetimeWatermark": "YYYY-MM-DDTHH:mm:ss or leave empty",
- "property.dateWatermark": "YYYY-MM-DD or leave empty",
- "property.apply": "Apply",
- "property.inputPins": "INPUT PINS",
- "property.outputPins": "OUTPUT PINS",
- "property.sqlTrace": "SQL TRACE",
- "property.live": "live",
- "node.numericValue": "Numeric Value",
- "node.stringValue": "String Value",
- "node.enterText": "Enter text",
- "node.datetimeValue": "DateTime Value",
- "node.valueLabel": "Value:",
- "node.noInputs": "No inputs",
- "node.loadingSample": "Loading sample…",
- "node.previewFailed": "⚠ Preview failed",
- "node.sampleRowsHint": "5 sample rows · demo data",
- "sidebar.tab.nodes": "Узлы",
- "sidebar.tab.connection": "Подключение",
- "sidebar.tab.schema": "Схема",
- "sidebar.tab.diagnostics": "Диагностика",
- "sidebar.addNode": "+ Add Node (⇧A)",
- "sidebar.previewF3": "Preview (F3)",
- "nodesList.search": "Search nodes...",
- "search.watermark": "Search nodes… (Esc to close)",
- "search.snippets": "★ SNIPPETS",
- "commandPalette.watermark": "Выполнить команду… (Esc для закрытия)",
- "tooltip.newCanvas": "New canvas (Ctrl+N)",
- "tooltip.openCanvas": "Open canvas (Ctrl+O)",
- "tooltip.saveCanvas": "Save canvas (Ctrl+S)",
- "tooltip.fileHistory": "Local save/load history (Ctrl+Alt+H)",
- "tooltip.zoomOut": "Zoom out (Ctrl+-)",
- "tooltip.zoomIn": "Zoom in (Ctrl++)",
- "tooltip.fitToScreen": "Fit to screen (Ctrl+0)",
- "tooltip.autoLayout": "Auto Layout — arrange nodes into logical columns (Ctrl+L, Ctrl+Z to undo)",
- "tooltip.snapToGrid": "Toggle snap to grid (Ctrl+G)",
- "tooltip.dataPreview": "Data preview (F3)",
- "tooltip.toggleLanguage": "Toggle language (pt-BR / en-US)",
- "tooltip.appDiagnostics": "App Diagnostics (self-check)",
- "tooltip.keyboardShortcuts": "Keyboard shortcuts (F1)",
- "tooltip.cancelRunningQuery": "Cancel the running query",
- "tooltip.closeEsc": "Close (Esc)",
- "tooltip.recheckConnectionHealth": "Re-check connection health",
- "tooltip.deleteConnection": "Delete connection",
- "tooltip.testConnection": "Test connection",
- "tooltip.saveConnection": "Save connection",
- "tooltip.activateConnection": "Activate this connection",
- "tooltip.toggleDataSamplePreview": "Toggle data sample preview",
- "tooltip.liveSqlMutatingBlocked": "This SQL contains a data-mutating command and cannot be run in Safe Preview Mode",
- "tooltip.copySql": "Copy SQL to clipboard",
- "tooltip.formatSql": "Format SQL",
- "tooltip.openBenchmark": "Open Query Benchmark (measure avg / median / p95 latency)",
- "tooltip.openExplainPlan": "Open Explain Plan inspector — visualise the query execution plan",
- "tooltip.switchToQueryMode": "Switch to Query canvas",
- "tooltip.switchToDdlMode": "Switch to DDL canvas",
- "tooltip.autoJoinSelected": "Try auto-join between the two selected tables",
- "tooltip.pins.inputs": "Inputs",
- "tooltip.pins.outputs": "Outputs",
- "tooltip.pins.none": "None",
- "tooltip.tableColumns": "Columns",
- "tooltip.tableColumns.none": "No detailed columns",
- "window.minimize": "Minimize window",
- "window.maximizeRestore": "Maximize/restore window",
- "window.close": "Close window",
- "menu.newDiagram": "New diagram",
- "menu.openFile": "Open file",
- "menu.save": "Save",
- "menu.fileHistory": "File history",
- "menu.shortcuts": "Keyboard shortcuts",
- "menu.settings": "Settings",
- "menu.importDdlSchema": "Import DDL schema",
- "menu.viewDdlSql": "View DDL SQL",
- "menu.executeDdl": "Execute DDL",
- "menu.backToStart": "Back to start",
- "toast.ddlExecuteFailed": "Failed to execute DDL.",
- "toast.ddlOpenFailed": "Failed to open DDL SQL.",
- "toast.ddlImportFailed": "Failed to import schema into DDL.",
- "toast.ddlConnectToImportSchema": "Connect to a database to import schema into the DDL canvas.",
- "toast.ddlNoTablesFound": "No tables found to import in DDL mode.",
- "toast.ddlSchemaImported": "Schema imported into the DDL canvas.",
- "toast.ddlImportSummary": "{0} table(s), {1} column(s), {2} FK(s), {3} unique index(es).",
- "toast.ddlConnectToImportTable": "Connect to a database to import tables into the DDL canvas.",
- "toast.ddlTableAlreadyExists": "Table '{0}' already exists in the DDL canvas.",
- "toast.ddlTableImported": "Table imported into the DDL canvas.",
- "toast.ddlTableImportSummary": "Nodes: +{0}, connections: +{1}, FKs: +{2}.",
- "toast.ddlNoActiveConnection": "No active connection to execute DDL.",
- "toast.ddlExecutedSuccess": "DDL executed successfully.",
- "toast.ddlExecutedWithIssues": "DDL executed with issues.",
- "toast.switchToDdl": "Switch to DDL mode to generate SQL.",
- "toast.ddlInvalid": "Invalid DDL. Fix errors before continuing.",
- "toast.ddlNoStatements": "No DDL statements were generated in the canvas.",
- "toast.previewOpenFailed": "Failed to open preview.",
- "tab.switchFailed": "Failed to switch tab: {0}",
- "settings.status.darkApplied": "Dark theme applied.",
- "settings.status.lightApplied": "Light theme applied.",
- "settings.status.snapUpdated": "Snap updated: {0}.",
- "settings.status.languageToggled": "Language toggled.",
- "settings.status.languageSelected": "Language selected: {0}.",
- "settings.status.themeEditorReady": "Theme editor ready. Apply to save and use this theme.",
- "settings.section.appearance.title": "Themes",
- "settings.section.languageRegion.title": "Язык и регион",
- "settings.section.dateTime.title": "Дата и время",
- "settings.section.keyboard.title": "Горячие клавиши",
- "settings.section.privacy.title": "Конфиденциальность",
- "settings.section.notification.title": "Уведомления",
- "settings.section.accessibility.title": "Доступность",
- "settings.section.default.title": "Настройки",
- "settings.section.appearance.subtitle": "Выберите стиль или настройте тему",
- "settings.section.languageRegion.subtitle": "Управляйте языком и региональным форматированием",
- "settings.section.keyboard.subtitle": "Настройте сочетания клавиш для command palette и выполнения на canvas.",
- "settings.section.wip.subtitle": "В разработке.",
- "settings.section.default.subtitle": "Настройки приложения",
- "settings.general": "General",
- "settings.nav.appearance": "Appearance",
- "settings.theme.light": "Светлая тема",
- "settings.theme.dark": "Тёмная тема",
- "settings.theme.system": "Системная тема",
- "settings.gridSnap.title": "Grid Snap",
- "settings.gridSnap.subtitle": "Controls node snapping on the canvas.",
- "settings.language.subtitle": "Выберите язык приложения.",
- "settings.language.toggle": "Сменить язык",
- "settings.language.option.ptBR": "Португальский (Бразилия)",
- "settings.language.option.enUS": "Английский (США)",
- "settings.language.option.esES": "Испанский (Испания)",
- "settings.language.option.ruRU": "Русский",
- "settings.language.option.jaJP": "Японский",
- "settings.language.option.zhTW": "Традиционный китайский",
- "settings.themeJson.title": "JSON темы",
- "settings.themeJson.subtitle": "Вставьте JSON темы, примените и сохраните сразу.",
- "settings.themeJson.apply": "Применить JSON",
- "settings.themeJson.restoreDefault": "Восстановить тему по умолчанию",
- "mode.query": "Query",
- "mode.ddl": "DDL",
- "sidebar.left.close": "Close left sidebar",
- "sidebar.left.open": "Reopen left sidebar",
- "sidebar.right.close": "Close right sidebar",
- "sidebar.right.open": "Reopen right sidebar",
- "connection.completedTitle": "Connection completed",
- "connection.clearCanvasPrompt": "Do you want to clear the current canvas to start with the new connection?",
- "connection.close": "Close connection manager",
- "connection.refreshHealth": "Refresh connection health",
- "common.details": "Details",
- "common.cancel": "Cancel",
- "common.keep": "Keep",
- "common.clear": "Clear",
- "zoom.out": "Zoom out",
- "zoom.in": "Zoom in",
- "zoom.fit": "Fit zoom to screen",
- "zoom.level": "Zoom level",
- "settings.theme.mode": "Режим темы",
- "diagnostics.category.canvas": "Canvas Integrity",
- "diagnostics.category.output": "Output & Execution",
- "diagnostics.category.session": "Session & Safety",
- "diagnostics.category.notice": "Runtime Notices",
- "diagnostics.summary.ok": "All systems OK",
- "diagnostics.summary.warningCount": "{0} warning(s) detected",
- "diagnostics.summary.errorCount": "{0} error(s) detected",
- "diagnostics.canvasMigration": "Canvas Migration",
- "diagnostics.recommendation.resaveFile": "Re-save the file to update it to the latest schema version.",
- "diagnostics.canvasState.name": "Canvas State",
- "diagnostics.canvasState.recommendation": "Add at least one {0} and one {1}",
- "diagnostics.canvasState.empty": "Canvas is empty - no nodes present",
- "diagnostics.canvasState.counts": "{0} node(s), {1} connection(s)",
- "diagnostics.validation.name": "Validation Errors",
- "diagnostics.validation.recommendation": "Fix highlighted nodes before running output preview",
- "diagnostics.validation.errorWithWarnings": "{0} error(s) and {1} warning(s) in the graph",
- "diagnostics.validation.warningOnly": "{0} warning(s) in the graph",
- "diagnostics.validation.none": "No validation issues",
- "diagnostics.orphan.name": "Orphan Nodes",
- "diagnostics.orphan.recommendation": "Use the orphan cleanup action to remove unused nodes",
- "diagnostics.orphan.count": "{0} node(s) not connected to any output",
- "diagnostics.orphan.none": "No orphan nodes detected",
- "diagnostics.naming.name": "Naming Conventions",
- "diagnostics.naming.recommendation": "Use auto-fix alias naming when conformance is below 100%",
- "diagnostics.naming.conformance": "Naming conformance: {0}%",
- "diagnostics.naming.ok": "All aliases follow naming conventions (100%)",
- "diagnostics.queryCompilation.name": "Live SQL Compilation",
- "diagnostics.queryCompilation.recommendation": "Review SQL diagnostics in output when errors/warnings are reported.",
- "diagnostics.queryCompilation.errorFallback": "Live SQL compilation reported errors.",
- "diagnostics.queryCompilation.warningCounts": "{0} diagnostic item(s), {1} guardrail warning(s).",
- "diagnostics.queryCompilation.ok": "Live SQL compiled without diagnostics.",
- "diagnostics.previewSafety.name": "Preview Safety",
- "diagnostics.previewSafety.recommendation": "Preview executes read-only statements only.",
- "diagnostics.previewSafety.blocked": "Current SQL is mutating and blocked by Safe Preview mode.",
- "diagnostics.previewSafety.ok": "Preview safety checks passed.",
- "diagnostics.previewExecution.name": "Preview Execution",
- "diagnostics.previewExecution.recommendation": "Run preview and inspect diagnostics for execution/runtime errors.",
- "diagnostics.previewExecution.failed": "Preview execution failed.",
- "diagnostics.previewExecution.cancelled": "Preview execution was cancelled.",
- "diagnostics.previewExecution.done": "{0} row(s) in {1}ms.",
- "diagnostics.previewExecution.none": "No preview execution issues detected.",
- "diagnostics.ddlCompilation.name": "DDL Compilation",
- "diagnostics.ddlCompilation.recommendation": "Fix DDL compile diagnostics before execution.",
- "diagnostics.ddlCompilation.failed": "DDL compilation failed.",
- "diagnostics.ddlCompilation.warningCount": "{0} warning(s) reported by DDL compiler.",
- "diagnostics.ddlCompilation.ok": "DDL compilation succeeded.",
- "diagnostics.ddlOutput.name": "DDL Output",
- "diagnostics.ddlOutput.recommendation": "Add/complete DDL nodes until at least one statement is generated.",
- "diagnostics.ddlOutput.none": "No DDL statements generated yet.",
- "diagnostics.ddlOutput.lines": "{0} line(s) of DDL generated.",
- "diagnostics.undo.name": "Undo History",
- "diagnostics.undo.recommendation": "History is in-memory only; save your canvas regularly.",
- "diagnostics.undo.saved": "Canvas is saved (no unsaved changes).",
- "diagnostics.undo.unsavedDeep": "Unsaved changes with {0} undo steps.",
- "diagnostics.undo.unsaved": "Unsaved changes - {0} undo step(s) available.",
- "diagnostics.report.title": "DBWeaver - Diagnostic Report",
- "diagnostics.report.generated": "Generated",
- "diagnostics.report.overall": "Overall",
- "diagnostics.report.details": "Details",
- "diagnostics.report.recommendation": "Recommendation",
- "diagnostics.report.lastCheck": "Last Check",
- "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
- "node.datetimeFormat": "YYYY-MM-DDTHH:mm:ss",
- "preview.providerLabel": "Provider",
- "preview.ddlDiagnosticsHint": "Error/warning details are available in Diagnostics.",
- "preview.schemaAnalysis.run": "Run Analysis",
- "preview.schemaAnalysis.cancel": "Cancel",
- "preview.schemaAnalysis.issues": "Issues",
- "preview.schemaAnalysis.clearFilters": "Clear Filters",
- "preview.schemaAnalysis.severity": "Severity",
- "preview.schemaAnalysis.rule": "Rule",
- "preview.schemaAnalysis.minConfidence": "Min Confidence",
- "preview.schemaAnalysis.tableFilter": "Table Filter",
- "preview.schemaAnalysis.tableFilterWatermark": "schema.table",
- "preview.schemaAnalysis.details": "Details",
- "preview.schemaAnalysis.evidence": "Evidence",
- "preview.schemaAnalysis.suggestions": "Suggestions",
- "preview.schemaAnalysis.ruleDiagnostics": "Rule Diagnostics",
- "preview.schemaAnalysis.sqlCandidates": "SQL Candidates",
- "preview.schemaAnalysis.copySql": "Copy SQL",
- "preview.schemaAnalysis.applyToCanvas": "Apply to Canvas",
- "preview.schemaAnalysis.summary.issues": "Issues:",
- "preview.schemaAnalysis.summary.rawPrefix": "(raw:",
- "preview.schemaAnalysis.summary.critical": "| Critical:",
- "preview.schemaAnalysis.summary.warning": "| Warning:",
- "preview.schemaAnalysis.summary.info": "| Info:",
- "preview.schemaAnalysis.state.metadataUnavailable": "Metadata unavailable for structural analysis.",
- "preview.schemaAnalysis.state.cancelled": "Analysis cancelled by the user.",
- "preview.schemaAnalysis.state.partialTimeout": "Analysis finished partially due to timeout.",
- "preview.schemaAnalysis.state.failed": "Structural analysis failed.",
- "preview.schemaAnalysis.state.empty": "No inferable structural issue was detected.",
- "preview.schemaAnalysis.state.noFilterMatch": "No issue matches the selected filters.",
- "preview.schemaAnalysis.state.noIssueSelected": "No issue selected.",
- "preview.schemaAnalysis.state.noSqlCandidate": "No SQL candidate available.",
- "preview.schemaAnalysis.actionBlockedTooltip": "Action unavailable for the current risk level or capability.",
- "common.navigate": "Navigate",
- "common.close": "Close",
- "common.esc": "Esc",
- "common.ms": "ms",
- "common.zero": "0",
- "diagnostics.tip": "Tip: check Diagnostics whenever preview/output reports warnings or errors.",
- "nodesList.empty": "No nodes found",
- "nodesList.emptyHint": "Adjust the search term to explore available types",
- "schema.emptyFiltered": "No objects found for the current filter",
- "start.lastSnapshot": "Last snapshot",
- "app.brandBadge": "VS",
- "property.tab.properties": "Properties",
- "property.tab.projectSettings": "Project Settings",
- "property.nodeType": "NODE TYPE",
- "property.selectNodeHint": "Select a node to edit its properties.",
- "property.namingConventions": "Naming Conventions",
- "property.aliasConvention": "Alias convention",
- "property.enforceAliasNaming": "Enforce alias naming",
- "property.warnReservedSql": "Warn on reserved SQL keywords",
- "property.maxAliasLength": "Max alias length",
- "property.maxAliasLengthDefault": "64",
- "property.namingSettingsHint": "These settings are project-scoped and are used by naming and validation helpers.",
- "start.tips": "Tips",
- "start.tips.quick": "Quick tips",
- "start.tips.item1": "1. Click New Diagram to start from scratch.",
- "start.tips.item2": "2. Use templates to speed up prototyping.",
- "start.tips.item3": "3. Open saved connections to load real tables.",
- "start.tips.shortcut": "Shortcut: CTRL+SHIFT+P opens the command palette.",
- "start.workspace": "WORKSPACE",
- "start.resumeTitle": "Continue where you left off",
- "start.resumeSubtitle": "Quickly resume a recent project or start a new diagram.",
- "start.chip.quickFlow": "Quick flow",
- "start.chip.templates": "Templates",
- "start.chip.connections": "Connections",
- "start.savedConnectionsTitle": "Saved Connections",
- "start.savedConnectionsSubtitle": "Connect quickly to a database to load schema and tables.",
- "start.noConnectionsTitle": "No connections configured yet",
- "start.noConnectionsSubtitle": "Create a connection to explore real tables in the editor.",
- "start.newConnection": "+ New Connection",
- "start.recentProjectsTitle": "Recent Projects",
- "start.searchRecent": "Search recent project...",
- "start.quickActions": "Quick actions",
- "start.quickActionsSubtitle": "Open an existing file or start a new diagram.",
- "start.noRecentTitle": "No recent projects yet",
- "start.noRecentSubtitle": "Use the quick actions card above to get started.",
- "start.exploreTemplates": "Explore templates",
- "start.templatesFavoritesHint": "Favorites on top",
- "start.favoriteTemplate": "Favorite template",
- "node.columnSetPreview": "ColumnSet preview",
- "node.view": "VIEW",
- "node.tableDefinition": "Table Definition",
- "node.join": "JOIN",
- "node.window.addPartition": "Add PARTITION BY slot",
- "node.window.removePartition": "Remove PARTITION BY slot",
- "node.window.addOrder": "Add ORDER BY slot",
- "node.window.removeOrder": "Remove ORDER BY slot",
- "sql.keyword.select": "SELECT",
- "sql.keyword.from": "FROM",
- "sql.keyword.join": "JOIN",
- "sql.keyword.where": "WHERE",
- "sql.keyword.limit": "LIMIT",
- "sqlImporter.close": "Close SQL importer",
- "sqlImporter.report.imported": "Imported",
- "sqlImporter.report.partial": "Partial",
- "sqlImporter.report.skipped": "Skipped",
- "benchmark.close": "Close benchmark",
- "benchmark.p95": "P95",
- "benchmark.n": "N",
- "liveSql.safePreview": "SAFE PREVIEW MODE",
- "liveSql.title": "LIVE SQL",
- "liveSql.blocked": "BLOCKED",
- "liveSql.copy": "Copy",
- "liveSql.format": "Format",
- "liveSql.benchmark": "Benchmark",
- "liveSql.explain": "Explain",
- "liveSql.actionsHint": "Performance tools",
- "ddl.dialog.title": "Execute DDL",
- "ddl.dialog.execute": "Execute",
- "ddl.dialog.cancel": "Cancel",
- "ddl.dialog.close": "Close",
- "ddl.dialog.stopOnError": "Stop on first failure",
- "ddl.dialog.confirmDestructive": "I confirm execution of destructive statements (DROP TABLE)",
- "ddl.dialog.reviewBeforeRun": "Review the DDL script before confirming.",
- "ddl.dialog.confirmQuestion": "Confirm DDL execution on the connected database?",
- "ddl.dialog.irreversibleWarning": "This action can change the schema irreversibly.",
- "ddl.dialog.mustConfirmDestructive": "Confirm destructive execution to continue.",
- "ddl.dialog.executing": "Executing...",
- "ddl.execute.result.summary": "Statements: {0} | Success: {1} | Failures: {2} | Time: {3:0}ms",
- "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
- "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
- "ddl.execute.result.failed": "Failed to execute DDL.",
- "ddl.execute.result.cancelled": "Execution cancelled by the user.",
- "ddl.execute.result.cancelledDetails": "DDL execution was interrupted before completion.",
- "context.deleteSingle": "Delete {0}",
- "context.deleteMultiple": "Delete {0} nodes",
- "context.bringForward": "Bring Forward (Ctrl+PgUp)",
- "context.sendBackward": "Send Backward (Ctrl+PgDown)",
- "context.bringToFront": "Bring to Front (Ctrl+Shift+PgUp)",
- "context.sendToBack": "Send to Back (Ctrl+Shift+PgDown)",
- "context.normalizeLayers": "Normalize Layers",
- "context.deleteWire": "Delete wire",
- "context.addNode": "Add Node (Shift+A)",
- "context.undoWithDescription": "Undo {0}",
- "context.redo": "Redo",
- "shortcuts.windowTitle": "Keyboard Shortcuts",
- "shortcuts.headerTitle": "DBWeaver - Shortcuts",
- "shortcuts.headerHint": "Tip: use CTRL+SHIFT+P to open the Command Palette and search commands.",
- "shortcuts.filterWatermark": "Filter shortcuts by key or action...",
- "shortcuts.resultCount": "{0} shortcuts",
- "shortcuts.resultFilter": "{0} result(s) for \"{1}\"",
- "shortcuts.noneFound": "No shortcuts found.",
- "shortcuts.section.fileGeneral": "Файл и общее",
- "shortcuts.section.editing": "Редактирование",
- "shortcuts.section.canvasNavigation": "Холст и навигация",
- "shortcuts.section.zoomPanPrecision": "Масштаб, панорамирование и точность",
- "shortcuts.section.previewInspection": "Предпросмотр и инспекция",
- "shortcuts.key.deleteOrBackspace": "Del или Backspace",
- "shortcuts.key.middleDrag": "Средняя кнопка + перетаскивание",
- "shortcuts.key.rightDrag": "Правая кнопка + перетаскивание",
- "shortcuts.key.spaceDrag": "Пробел + перетаскивание",
- "shortcuts.key.altLeftDrag": "Alt + перетаскивание левой кнопкой",
- "shortcuts.key.arrows": "Стрелки",
- "shortcuts.key.shiftArrows": "Shift + Стрелки",
- "shortcuts.action.openShortcutScreen": "Открыть этот экран горячих клавиш",
- "shortcuts.action.newCanvas": "Новый холст",
- "shortcuts.action.openFile": "Открыть файл",
- "shortcuts.action.save": "Сохранить",
- "shortcuts.action.saveAs": "Сохранить как",
- "shortcuts.action.commandPalette": "Палитра команд",
- "shortcuts.action.undo": "Отменить",
- "shortcuts.action.redo": "Повторить",
- "shortcuts.action.selectAll": "Выделить всё",
- "shortcuts.action.deleteSelection": "Удалить выделение",
- "shortcuts.action.closeOverlayCancel": "Закрыть оверлеи / отменить действия",
- "shortcuts.action.openNodeSearch": "Открыть поиск узлов",
- "shortcuts.action.resetViewport": "Сбросить viewport",
- "shortcuts.action.centerSelection": "Центрировать выделение",
- "shortcuts.action.fitSelection": "Подогнать выделение",
- "shortcuts.action.autoLayout": "Авторазмещение",
- "shortcuts.action.toggleSnapToGrid": "Переключить привязку к сетке",
- "shortcuts.action.bringForward": "На слой выше",
- "shortcuts.action.sendBackward": "На слой ниже",
- "shortcuts.action.bringToFront": "На передний план",
- "shortcuts.action.sendToBack": "На задний план",
- "shortcuts.action.zoomInOut": "Увеличить / уменьшить",
- "shortcuts.action.pan": "Панорамирование",
- "shortcuts.action.temporaryPan": "Временное панорамирование",
- "shortcuts.action.alternatePan": "Альтернативное панорамирование",
- "shortcuts.action.fineNudge": "Точный сдвиг выделения",
- "shortcuts.action.fastNudge": "Быстрый сдвиг",
- "shortcuts.action.togglePreview": "Переключить предпросмотр данных",
- "shortcuts.action.explainPlan": "План выполнения",
- "shortcuts.action.runPreview": "Запустить предпросмотр",
- "shortcuts.action.connectionManager": "Менеджер подключений",
- "shortcuts.action.flowVersionHistory": "История версий потока",
- "shortcuts.resetAll": "Сбросить всё",
- "shortcuts.customized": "Изменено",
- "shortcuts.default": "По умолчанию",
- "shortcuts.apply": "Применить",
- "shortcuts.reset": "Сбросить",
- "shortcuts.status.resetAllSuccess": "Все сочетания сброшены к значениям по умолчанию.",
- "shortcuts.status.updated": "Сочетание обновлено.",
- "shortcuts.status.reset": "Сочетание сброшено по умолчанию.",
- "shortcuts.status.updateFailed": "Не удалось обновить сочетание.",
- "toast.severity.success": "Success",
- "toast.severity.warning": "Warning",
- "toast.severity.error": "Error",
- "toast.details.success": "Success Details",
- "toast.details.warning": "Warning Details",
- "toast.details.error": "Error Details",
- "diagnostics.area.cteEditor": "CTE Editor",
- "diagnostics.area.viewEditor": "View Editor",
- "diagnostics.area.subEditor": "Sub-editor",
- "diagnostics.cteEditor.restoreParentFailed": "Failed to restore the parent canvas. CTE edits were discarded.",
- "diagnostics.recommendation.reloadFileIfNeeded": "Reload the file if needed.",
- "diagnostics.viewEditor.exitFailed": "Could not exit: {0}",
- "diagnostics.viewEditor.canvasIncomplete": "the canvas is incomplete.",
- "diagnostics.viewEditor.exitRecommendation": "Connect a valid ResultOutput or use the discard command.",
- "diagnostics.viewEditor.restoreParentFailed": "Failed to restore the parent canvas. The subgraph was discarded.",
- "diagnostics.subEditor.executeFailed": "Failed to execute editor action: {0}",
- "diagnostics.subEditor.executeRecommendation": "Try again. If it persists, reload the canvas.",
- "diagnostics.canvasMigration.openWarning": "Open: {0}",
- "diagnostics.canvasMigration.sessionRestoreWarning": "Session restore: {0}",
- "diagnostics.canvasMigration.versionRestoreWarning": "Version restore: {0}",
- "diagnostics.recommendation.resaveLatestSchema": "Review diagnostics and re-save the canvas to persist the latest schema.",
- "diagnostics.recommendation.saveMigratedSchema": "Review diagnostics and save the canvas to persist the migrated schema.",
- "file.saveDialog.title": "Save Canvas",
- "file.saveDialog.suggestedName": "Query1",
- "file.save.success": "Canvas saved successfully.",
- "file.save.failedWithReason": "Save failed: {0}",
- "file.openDialog.title": "Open Canvas",
- "file.open.failedWithReason": "Open failed: {0}",
- "file.open.success": "Canvas opened successfully.",
- "file.open.successWithWarnings": "Canvas opened with warnings.",
- "session.restore.failedWithReason": "Restore failed: {0}",
- "session.restore.successWithWarnings": "Session restored with warnings.",
- "session.restore.success": "Session restored successfully.",
- "export.documentation.dialogTitle": "Export Flow Documentation",
- "export.documentation.success": "Documentation exported successfully.",
- "export.documentation.failed": "Documentation export failed.",
- "export.failed.pathPermissionsHint": "Check file path and permissions.",
- "export.nodeNotFound": "No {0} Export node found on the canvas. Add one via the node search menu.",
- "export.dialogTitleByExtension": "Export as {0}",
- "export.success": "Export completed successfully.",
- "export.failed": "Export failed.",
- "fileHistory.currentFile.none": "No file selected",
- "fileHistory.status.saveFirst": "Save the canvas first to enable local history.",
- "fileHistory.status.noneFound": "No local versions found yet. Save this file to create history entries.",
- "fileHistory.status.countAvailable": "{0} local version(s) available.",
- "fileHistory.restore.failedWithReason": "Restore failed: {0}",
- "fileHistory.restore.successFrom": "Restored version from {0}.",
- "preview.status.cancelled": "Cancelled",
- "preview.status.error": "Error",
- "preview.status.ready": "Ready",
- "preview.runningWithMs": "Running... {0}ms",
- "preview.runningWithTimeout": "Running... {0}ms (timeout: {1}s)",
- "preview.runningSlowWithTimeout": "Running... {0}ms (timeout: {1}s) · Slow query, timeout in {2}s",
- "explain.errorWithReason": "Explain plan error: {0}",
- "explain.noSql": "No SQL to explain. Build a query on the canvas first.",
- "ddl.compilationFailed": "Compilation failed",
- "ddl.compileErrorWithReason": "DDL compile error: {0}",
- "command.undo.name": "Undo",
- "command.undo.description": "Undo last action",
- "command.redo.name": "Redo",
- "command.redo.description": "Redo last undone action",
- "command.addNode.name": "Add Node",
- "command.addNode.description": "Open node search menu to add a node",
- "command.bringForward.name": "Bring Forward",
- "command.bringForward.description": "Move selected nodes one layer forward",
- "command.sendBackward.name": "Send Backward",
- "command.sendBackward.description": "Move selected nodes one layer backward",
- "command.bringToFront.name": "Bring to Front",
- "command.bringToFront.description": "Move selected nodes to top layer",
- "command.sendToBack.name": "Send to Back",
- "command.sendToBack.description": "Move selected nodes to bottom layer",
- "command.normalizeLayers.name": "Normalize Layers",
- "command.normalizeLayers.description": "Compact node layer indices to a clean 0..N order",
- "tooltip.cleanupOrphans": "Remove orphan nodes not connected to the output (Ctrl+Z to undo)",
- "main.orphanSuffix": "Orphan(s)",
- "tooltip.autoFixAliasNaming": "Fix alias naming to snake_case (Ctrl+Z to undo)",
- "main.namingPrefix": "Naming",
- "fileHistory.compressedLabel": "Compressed:",
- "schema.itemsSuffix": "item(s)",
- "property.panel.title": "Properties",
- "property.panel.multiSelected": "{0} nodes selected",
- "sqlImporter.status.pasteSelect": "Paste a SELECT statement above, then click Import.",
- "sqlImporter.status.inputTooLarge": "SQL input is too large ({0:N0} chars). Limit is {1:N0}. Split the query or increase the import limit.",
- "sqlImporter.status.parsing": "Parsing SQL...",
- "sqlImporter.status.done": "Done - {0} imported, {1} partial, {2} skipped.",
- "sqlImporter.status.cancelledByUser": "Import cancelled by user.",
- "sqlImporter.status.timeout": "Import timed out after {0:0.#}s. Try a smaller query or increase timeout.",
- "sqlImporter.status.parseError": "Parse error: {0}",
- "diagnostics.area.undoRedoTransaction": "Undo/Redo Transaction",
- "undoRedo.rollbackExecuted": "Rollback executed for '{0}' ({1} operation(s) reverted).",
- "undoRedo.rollbackRecommendation": "Review the canvas state and retry the action if needed.",
- "node.preview.noCatalog": "No catalog available",
- "connection.error.searchMenuNotInitialized": "search menu not initialized",
- "connection.error.timeoutReachability": "Connection timed out - check that the server is reachable and increase the timeout if needed.",
- "connection.error.authenticationFailedForProvider": "Authentication failed - verify username and password for {0}.",
- "connection.error.databaseNotFoundForProvider": "Database not found - confirm the database name exists on {0}.",
- "connection.error.hostNotFound": "Host not found - check the server address and DNS resolution.",
- "connection.error.portRefused": "Port connection refused - check the port number and that the server is running / firewall rules allow access.",
- "connection.error.sslTls": "SSL/TLS error - check the server's SSL configuration or disable SSL for local connections.",
- "connection.error.timeoutOverloaded": "Connection timed out - the server may be overloaded or unreachable. Try increasing the timeout.",
- "connection.error.insufficientPrivileges": "Insufficient privileges - the user may lack permission to connect to this database.",
- "diagnostics.area.connection": "Connection",
- "connection.warning.canvasMayContainOldTables": "The canvas may still contain tables from a previous connection.",
- "connection.warning.canvasMayContainOldTablesRecommendation": "Clear the canvas manually or reconnect and choose keep/clear again.",
- "undoRedo.transaction.unnamed": "unnamed transaction",
- "benchmark.runLabelDefault": "Run 1",
- "benchmark.runLabelPattern": "Run {0}",
- "benchmark.status.failedWithReason": "Benchmark failed: {0}",
- "benchmark.status.noSql": "No SQL to benchmark - build a query first.",
- "benchmark.status.warmupProgress": "Warm-up {0}/{1}...",
- "benchmark.status.iterationProgress": "Iteration {0}/{1}...",
- "benchmark.status.done": "Done - {0}",
- "benchmark.status.cancelled": "Benchmark cancelled.",
- "app.windowTitle": "DBWeaver",
- "preview.error.safePreviewBlocked": "Safe Preview Mode: data-mutating commands (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) cannot be executed in preview.",
- "preview.error.noActiveConnection": "No active database connection. Please connect to a database first.",
- "sqlImporter.error.selectFromNotFound": "Could not find SELECT ... FROM in the query.",
- "sqlImporter.error.fromClauseParseFailed": "Could not parse FROM clause.",
- "sqlImporter.error.syntaxUnterminatedString": "Syntax error at line {0}, column {1}: unterminated string literal.",
- "sqlImporter.error.missingClosingParenthesis": "missing closing ')'",
- "sqlImporter.error.unexpectedClosingParenthesis": "unexpected ')'",
- "sqlImporter.error.syntaxAtLineColumn": "Syntax error at line {0}, column {1}: {2}.",
- "errorDiagnostics.safePreview.label": "Blocked by Safe Preview Mode",
- "errorDiagnostics.safePreview.friendly": "This SQL contains a data-mutating command and cannot be executed in preview.",
- "errorDiagnostics.safePreview.suggestion": "Remove or replace the mutating command (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) before running preview.",
- "errorDiagnostics.connection.label": "Connection failed",
- "errorDiagnostics.connection.friendly": "Could not reach the database server. The host may be down, unreachable, or blocking connections.",
- "errorDiagnostics.connection.suggestion": "Verify the server address and port, ensure the database is running, and check firewall rules.",
- "errorDiagnostics.authorization.label": "Authorization error",
- "errorDiagnostics.authorization.friendly": "The current credentials do not have permission to perform this operation.",
- "errorDiagnostics.authorization.suggestion": "Confirm the database user has SELECT privileges on the target table/schema, or contact your DBA.",
- "errorDiagnostics.timeout.label": "Query timeout",
- "errorDiagnostics.timeout.friendly": "The query took too long to complete and was cancelled by the server or client.",
- "errorDiagnostics.timeout.suggestion": "Add a WHERE clause or LIMIT to reduce the result set, or increase the query timeout in connection settings.",
- "errorDiagnostics.schema.label": "Schema error",
- "errorDiagnostics.schema.friendly": "A referenced table, column, or object could not be found in the database.",
- "errorDiagnostics.schema.suggestion": "Check that all table/column names are spelled correctly and that the schema matches the active connection.",
- "errorDiagnostics.syntax.label": "SQL syntax error",
- "errorDiagnostics.syntax.friendly": "The query contains a syntax error and could not be parsed by the database engine.",
- "errorDiagnostics.syntax.suggestion": "Review the highlighted SQL for typos, mismatched parentheses, or unsupported clauses for the active provider.",
- "errorDiagnostics.compatibility.label": "Compatibility error",
- "errorDiagnostics.compatibility.friendly": "A function, operator, or syntax construct is not supported by the active database provider.",
- "errorDiagnostics.compatibility.suggestion": "Switch to the correct provider in the SQL bar, or replace the unsupported construct with an equivalent.",
- "errorDiagnostics.unknown.label": "Unexpected error",
- "errorDiagnostics.unknown.friendly": "An error occurred while running the preview query.",
- "errorDiagnostics.unknown.suggestion": "Check the technical details below and verify that your canvas is configured correctly.",
- "error.mainWindow.invalidDataContext": "DataContext MainWindow должен быть ShellViewModel.",
- "error.mainWindow.canvasNotInitialized": "CanvasViewModel не был инициализирован.",
- "error.mainWindow.ddlPreviewUnavailable": "DDL-предпросмотр недоступен для текущего canvas.",
- "themeJson.editor.template": "{\n \"meta\": { \"name\": \"Пользовательская тема\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
- "themeJson.error.pasteBeforeApply": "Вставьте JSON темы перед применением.",
- "themeJson.error.invalidJson": "Некорректный JSON: {0}",
- "themeJson.error.emptyPayload": "Некорректный JSON: пустой payload.",
- "themeJson.error.invalidTheme": "Некорректная тема: {0}",
- "themeJson.error.appliedButSaveFailed": "Тема применена, но не удалось сохранить: {0}",
- "themeJson.success.appliedAndSaved": "JSON-тема применена и сохранена.",
- "themeJson.success.customRemoved": "Пользовательская тема удалена. Перезапустите приложение для полного возврата к теме по умолчанию.",
- "themeJson.error.restoreDefaultFailed": "Не удалось восстановить тему по умолчанию: {0}",
- "themeValidator.error.configNull": "Конфигурация темы пуста.",
- "themeValidator.warning.noSections": "В теме нет разделов цветов или типографики; применять нечего.",
- "themeValidator.warning.invalidColor": "{0} содержит некорректный цвет '{1}'. Этот ключ будет проигнорирован.",
- "themeValidator.warning.sizeOutOfRange": "{0}={1} вне диапазона (8..48). Этот ключ будет проигнорирован.",
- "queryExecutor.error.openConnectionMethodNotFound": "Не удалось найти метод OpenConnectionAsync в оркестраторе",
- "queryExecutor.error.openConnectionInvokeFailed": "Не удалось вызвать OpenConnectionAsync",
- "ddlImporter.warning.viewSelectNotReconstructable": "View '{0}': SELECT представления нельзя визуально восстановить — отредактируйте вручную в subcanvas.",
- "ddlImporter.error.tableNotFoundInMetadata": "Таблица '{0}' не найдена в текущих метаданных.",
- "main.window.untitled": "Без названия",
- "main.subEditor.noSeedProvided": "Для {0} не предоставлен seed подредактора.",
- "main.layerOrder.bringToFront": "На передний план",
- "main.layerOrder.sendToBack": "На задний план",
- "main.layerOrder.bringForward": "Поднять слой",
- "main.layerOrder.sendBackward": "Опустить слой",
- "main.layerOrder.normalizeLayers": "Нормализовать слои",
- "export.fileType.html": "Файлы HTML",
- "export.fileType.json": "Файлы JSON",
- "export.fileType.csv": "Файлы CSV",
- "export.fileType.excel": "Файлы Excel",
- "commandPalette.templatePrefix": "Шаблон: {0}",
- "themeLoader.status.notFoundWithPath": "Файл темы не найден: {0}",
- "themeLoader.status.deserializedNull": "JSON темы десериализован в null.",
- "themeLoader.status.loaded": "JSON темы успешно загружен.",
- "credential.error.ciphertextTooShort": "Блок шифртекста слишком короткий.",
- "credential.error.dpapiWindowsOnly": "DPAPI доступен только в Windows.",
- "credential.warning.loadVaultFailed": "Не удалось загрузить хранилище учетных данных {0}: {1}",
- "credential.warning.persistVaultFailed": "Не удалось сохранить хранилище учетных данных {0}: {1}",
- "snippetStore.warning.loadFailed": "Не удалось загрузить сниппеты из {0}: {1}",
- "snippetStore.warning.saveFailed": "Не удалось сохранить сниппеты: {0}",
- "flowVersionStore.warning.loadFailed": "Не удалось загрузить версии потока из {0}: {1}",
- "flowVersionStore.warning.saveFailed": "Не удалось сохранить версии потока: {0}",
- "queryExecutor.error.queryEmpty": "Запрос не может быть пустым",
- "queryExecutor.error.providerNotSupported": "Провайдер {0} не поддерживается",
- "queryExecutor.error.singleStatementOnly": "Предпросмотр принимает только один SQL-оператор.",
- "queryExecutor.error.queryEmptyWithPeriod": "Запрос не может быть пустым.",
- "queryExecutor.error.readOnlyOnly": "Режим предпросмотра поддерживает только SQL-запросы только для чтения.",
- "queryExecutor.error.namedParametersNotSupported": "Режим предпросмотра не поддерживает именованные параметры в SQL. Используйте безопасные литералы inline или выполните запрос вне предпросмотра.",
- "queryExecutor.error.positionalParametersNotSupported": "Режим предпросмотра не поддерживает позиционные плейсхолдеры (? или ).",
- "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "Выровнять выбранные узлы по нижнему краю",
- "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "Выровнять выбранные узлы по левому краю",
- "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "Выровнять выбранные узлы по правому краю",
- "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "Выровнять выбранные узлы по верхнему краю",
- "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "Применить изменения подхолста CTE и вернуться на родительский холст",
- "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "Автоматически расположить узлы по логическим колонкам",
- "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "Центрировать выбранные узлы по горизонтали",
- "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "Центрировать выбранные узлы по вертикали",
- "commandPalette.description.clear_canvas_and_start_fresh": "Очистить холст и начать заново",
- "commandPalette.description.clear_node_selection": "Снять выделение узлов",
- "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "Преобразовать алиасы по правилу, заданному в настройках проекта",
- "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "Создавать контрольные точки, сравнивать версии и восстанавливать предыдущее состояние холста",
- "commandPalette.description.delete_the_selected_nodes": "Удалить выбранные узлы",
- "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "Отменить изменения в подредакторе и вернуться на родительский холст",
- "commandPalette.description.execute_the_current_query_in_preview": "Выполнить текущий запрос в предпросмотре",
- "commandPalette.description.fit_all_nodes_into_the_visible_area": "Уместить все узлы в видимой области",
- "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "Сгенерировать CSV из первого узла экспорта CSV",
- "commandPalette.description.generate_html_file_from_the_first_html_export_node": "Сгенерировать HTML из первого узла экспорта HTML",
- "commandPalette.description.generate_json_file_from_the_first_json_export_node": "Сгенерировать JSON из первого узла экспорта JSON",
- "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "Сгенерировать книгу XLSX из первого узла экспорта Excel",
- "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "Проверить план выполнения запроса: типы сканирования, стратегии join и оценки стоимости",
- "commandPalette.description.load_a_vsaq_canvas_file": "Загрузить файл холста .vsaq",
- "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "Измерить avg / median / p95 задержку текущего SQL за N итераций",
- "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "Открыть изолированный редактор подхолста для выбранного узла определения CTE",
- "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "Открыть локальную историю версий, создаваемую при сохранении, и восстановить предыдущие снимки",
- "commandPalette.description.open_output_preview_modal_for_the_active_mode": "Открыть модальное окно предпросмотра вывода для активного режима",
- "commandPalette.description.open_shortcut_reference_screen": "Открыть экран справки по горячим клавишам",
- "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "Открыть менеджер подключений для добавления, редактирования и переключения БД-подключений",
- "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "Вставить SELECT и автоматически сгенерировать узлы — поддерживаются FROM, JOIN, WHERE, LIMIT",
- "commandPalette.description.remove_all_nodes_not_connected_to_output": "Удалить все узлы, не подключенные к выходу",
- "commandPalette.description.reset_zoom_and_pan_to_default": "Сбросить масштаб и смещение к значениям по умолчанию",
- "commandPalette.description.save_canvas_to_a_new_file": "Сохранить холст в новый файл",
- "commandPalette.description.save_current_canvas": "Сохранить текущий холст",
- "commandPalette.description.save_markdown_documentation_of_the_current_flow": "Сохранить Markdown-документацию текущего потока",
- "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "Сохранить выбранные узлы как переиспользуемый сниппет и вставить позже через меню поиска узлов (⇧A)",
- "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "Проверить все исходные табличные узлы на холсте на возможные связи join по FK-конвенциям и шаблонам имен",
- "commandPalette.description.select_all_nodes_on_canvas": "Выбрать все узлы на холсте",
- "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "Привязать позиции узлов к сетке 16px (Ctrl+G)",
- "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "Распределить выбранные узлы с равным горизонтальным интервалом",
- "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "Распределить выбранные узлы с равным вертикальным интервалом",
- "commandPalette.description.zoom_into_the_canvas": "Увеличить холст",
- "commandPalette.description.zoom_out_of_the_canvas": "Уменьшить холст",
- "commandPalette.name.align_bottom": "Выровнять по низу",
- "commandPalette.name.align_left": "Выровнять по левому краю",
- "commandPalette.name.align_right": "Выровнять по правому краю",
- "commandPalette.name.align_top": "Выровнять по верху",
- "commandPalette.name.analyze_all_joins": "Анализировать все JOIN",
- "commandPalette.name.auto_fix_naming": "Автоисправление имен",
- "commandPalette.name.auto_layout": "Авторазмещение",
- "commandPalette.name.center_horizontally": "Центрировать по горизонтали",
- "commandPalette.name.center_vertically": "Центрировать по вертикали",
- "commandPalette.name.cleanup_orphans": "Очистить сироты",
- "commandPalette.name.delete_selected": "Удалить выделенные",
- "commandPalette.name.deselect_all": "Снять выделение",
- "commandPalette.name.discard_and_exit_editor": "Отменить и выйти из редактора",
- "commandPalette.name.distribute_horizontally": "Распределить по горизонтали",
- "commandPalette.name.distribute_vertically": "Распределить по вертикали",
- "commandPalette.name.edit_selected_cte": "Редактировать выбранный CTE",
- "commandPalette.name.exit_cte_editor": "Выйти из редактора CTE",
- "commandPalette.name.explain_plan": "План выполнения",
- "commandPalette.name.export_csv": "Экспорт CSV",
- "commandPalette.name.export_documentation": "Экспорт документации",
- "commandPalette.name.export_excel": "Экспорт Excel",
- "commandPalette.name.export_html": "Экспорт HTML",
- "commandPalette.name.export_json": "Экспорт JSON",
- "commandPalette.name.file_save_load_history": "История сохранений/загрузок",
- "commandPalette.name.fit_to_screen": "Уместить на экран",
- "commandPalette.name.flow_version_history": "История версий потока",
- "commandPalette.name.import_sql_to_graph": "Импорт SQL в граф",
- "commandPalette.name.keyboard_shortcuts": "Горячие клавиши",
- "commandPalette.name.manage_connections": "Управление подключениями",
- "commandPalette.name.new_canvas": "Новый canvas",
- "commandPalette.name.open_file": "Открыть файл",
- "commandPalette.name.reset_viewport": "Сбросить область просмотра",
- "commandPalette.name.run_preview": "Запустить предпросмотр",
- "commandPalette.name.run_query_benchmark": "Запустить бенчмарк запроса",
- "commandPalette.name.save": "Сохранить",
- "commandPalette.name.save_as": "Сохранить как",
- "commandPalette.name.save_selection_as_snippet": "Сохранить выделение как сниппет",
- "commandPalette.name.select_all": "Выделить все",
- "commandPalette.name.toggle_preview": "Переключить предпросмотр",
- "commandPalette.name.toggle_snap_to_grid": "Переключить привязку к сетке",
- "commandPalette.name.zoom_in": "Увеличить",
- "commandPalette.name.zoom_out": "Уменьшить",
- "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 percent restore zoom pan viewport",
- "commandPalette.tags.align_bottom_edge_selection_nodes": "align bottom edge selection nodes",
- "commandPalette.tags.align_center_middle_horizontal_nodes": "align center middle horizontal nodes",
- "commandPalette.tags.align_center_middle_vertical_nodes": "align center middle vertical nodes",
- "commandPalette.tags.align_left_edge_selection_nodes": "align left edge selection nodes",
- "commandPalette.tags.align_right_edge_selection_nodes": "align right edge selection nodes",
- "commandPalette.tags.align_top_edge_selection_nodes": "align top edge selection nodes",
- "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout view reset zoom",
- "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark performance latency timing profile measure speed",
- "commandPalette.tags.clear_selection": "clear selection",
- "commandPalette.tags.connection_database_server_host_provider_switch": "connection database server host provider switch",
- "commandPalette.tags.create_insert_search_transform": "create insert search transform",
- "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas exit apply back",
- "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte view subcanvas discard exit force",
- "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursive editor subgraph subcanvas isolate",
- "commandPalette.tags.data_results_table_panel": "data results table panel",
- "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribute space equal horizontal nodes",
- "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribute space equal vertical nodes",
- "commandPalette.tags.execute_run_sql_query_results": "execute run sql query results",
- "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan execution cost scan index join performance",
- "commandPalette.tags.export_csv_file_tabular_output_save": "export csv file tabular output save",
- "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "export excel xlsx file tabular output spreadsheet save",
- "commandPalette.tags.export_html_file_output_report_save": "export html file output report save",
- "commandPalette.tags.export_json_file_output_save": "export json file output save",
- "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "export markdown doc documentation flow save md",
- "commandPalette.tags.export_persist_copy": "export persist copy",
- "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "file history save load backup versions restore local",
- "commandPalette.tags.forward_history": "forward history",
- "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "help shortcuts hotkeys keyboard reference",
- "commandPalette.tags.highlight_mark_all_nodes": "highlight mark all nodes",
- "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "import sql paste convert graph reverse engineer query",
- "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analyze suggest detect foreign key relationships heuristic",
- "commandPalette.tags.layer_z_order_back_selected_nodes": "layer z-order back selected nodes",
- "commandPalette.tags.layer_z_order_backward_selected_nodes": "layer z-order backward selected nodes",
- "commandPalette.tags.layer_z_order_forward_selected_nodes": "layer z-order forward selected nodes",
- "commandPalette.tags.layer_z_order_front_selected_nodes": "layer z-order front selected nodes",
- "commandPalette.tags.layer_z_order_normalize_compact": "layer z-order normalize compact",
- "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout arrange columns auto organize readability",
- "commandPalette.tags.load_import_vsaq": "load import vsaq",
- "commandPalette.tags.magnify_enlarge": "magnify enlarge",
- "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "orphan unused disconnected clean delete nodes",
- "commandPalette.tags.persist_write_disk": "persist write disk",
- "commandPalette.tags.remove_erase_nodes": "remove erase nodes",
- "commandPalette.tags.rename_alias_fix_naming_convention": "rename alias fix naming convention",
- "commandPalette.tags.reset_clear_blank": "reset clear blank",
- "commandPalette.tags.revert_back_history": "revert back history",
- "commandPalette.tags.shrink_reduce": "shrink reduce",
- "commandPalette.tags.snap_grid_align_precision_position": "snap grid align precision position",
- "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet save selection reuse template favorite bookmark",
- "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "version history checkpoint diff restore snapshot compare undo flow",
- "sqlEditor.diffPreview.title": "Transactional Diff Preview",
- "sqlEditor.mutation.confirmExecute": "Confirm Execute",
- "sqlEditor.tab.closeAnyway": "Close Anyway",
- "sqlEditor.tab.keepTab": "Keep Tab",
- "sqlEditor.status.ready": "Ready.",
- "sqlEditor.telemetry.none": "No execution telemetry yet.",
- "sqlEditor.telemetry.summary": "Statements: {0} Success: {1} Failed: {2} Total: {3} ms",
- "sqlEditor.telemetry.errors.none": "No aggregated errors.",
- "sqlEditor.diff.none": "No transactional diff preview available.",
- "sqlEditor.mutation.estimate.none": "No mutation estimate available.",
- "sqlEditor.mutation.estimate.value": "Estimated affected rows: {0}",
- "sqlEditor.mutation.estimate.unavailable": "Could not estimate affected rows automatically.",
- "sqlEditor.tab.closePending": "Unsaved changes detected. Confirm tab close.",
- "sqlEditor.tab.noPendingClose": "No tab close pending.",
- "sqlEditor.tab.manyWarning": "High tab count: {0} open tabs.",
- "sqlEditor.mutation.pending.none": "No pending mutation confirmation.",
- "sqlEditor.mutation.pending.required": "Mutation requires confirmation before execution.",
- "sqlEditor.message.empty": "Execute a statement to see messages.",
- "sqlEditor.message.success": "Execution completed successfully.",
- "sqlEditor.result.summary.empty": "Rows: - Time: -",
- "sqlEditor.result.summary": "Rows: {0} Time: {1} ms",
- "sqlEditor.file.save.canceled": "Save canceled.",
- "sqlEditor.file.save.noPath": "No target path selected.",
- "sqlEditor.file.save.success": "SQL file saved.",
- "sqlEditor.file.save.failed": "Save failed.",
- "sqlEditor.file.open.failed": "Open failed.",
- "sqlEditor.file.open.notFound": "Selected SQL file was not found.",
- "sqlEditor.file.open.success": "SQL file opened.",
- "sqlEditor.status.executing": "Executing SQL...",
- "sqlEditor.status.executingScript": "Executing SQL script...",
- "sqlEditor.status.executingStep": "Executing {0}/{1}...",
- "sqlEditor.status.canceling": "Canceling execution...",
- "sqlEditor.status.executingConfirmedMutation": "Executing confirmed mutation...",
- "sqlEditor.status.mutationCanceled": "Mutation execution canceled.",
- "sqlEditor.detail.statementNotExecuted": "Statement was not executed.",
- "sqlEditor.status.success": "Execution succeeded.",
- "sqlEditor.detail.rowsAndTime": "{0} row(s) in {1} ms.",
- "sqlEditor.status.canceled": "Execution canceled.",
- "sqlEditor.status.failed": "Execution failed.",
- "sqlEditor.status.confirmationRequired": "Confirmation required before execution.",
- "sqlEditor.error.mutationConfirmationRequired": "Mutation confirmation required.",
- "sqlEditor.result.tabTitle": "Result {0}",
- "sqlEditor.tab.closeRequiresConfirmation": "Tab close requires confirmation.",
- "sqlEditor.tab.unsavedDetail": "This tab has unsaved changes.",
- "sqlEditor.tab.closed": "Tab closed.",
- "sqlEditor.tab.closeCanceled": "Tab close canceled.",
- "sqlEditor.tab.closeCanceledDetail": "Unsaved tab kept open.",
- "sqlEditor.error.noStatementSelected": "No SQL statement selected for execution.",
- "sqlEditor.error.noConnection": "No active database connection for SQL execution.",
- "sqlEditor.error.executionCanceled": "SQL execution was canceled.",
- "sqlEditor.tab.scriptTitle": "Script {0}",
- "sqlEditor.guard.delete.noWhere.message": "DELETE without WHERE can remove all rows.",
- "sqlEditor.guard.delete.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
- "sqlEditor.guard.delete.trivialWhere.message": "DELETE has a trivially true WHERE clause.",
- "sqlEditor.guard.delete.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
- "sqlEditor.guard.update.noWhere.message": "UPDATE without WHERE can affect all rows.",
- "sqlEditor.guard.update.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
- "sqlEditor.guard.update.trivialWhere.message": "UPDATE has a trivially true WHERE clause.",
- "sqlEditor.guard.update.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
- "sqlEditor.guard.insert.noColumnList.message": "INSERT without explicit column list is fragile against schema changes.",
- "sqlEditor.guard.insert.noColumnList.recommendation": "Prefer INSERT INTO table(col1, col2, ...) VALUES (...).",
- "sqlEditor.guard.ddl.message": "DDL statement may cause structural changes in the database.",
- "sqlEditor.guard.ddl.recommendation": "Confirm execution only when schema changes are intended.",
- "sqlEditor.diff.unavailable.noPreview": "No transactional diff preview available for this statement.",
- "sqlEditor.diff.unavailable.parseError": "Could not parse mutation target for transactional diff preview.",
- "sqlEditor.diff.unavailable.connection": "Transactional diff preview unavailable due to connection or query limitations.",
- "sqlEditor.diff.deleteSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, affected {2}, total rows after {3}.",
- "sqlEditor.diff.updateSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, candidate rows affected {2}, total rows after {3}.",
- "sqlEditor.diff.unavailable.unsupportedStatement": "Transactional diff preview currently supports UPDATE and DELETE only.",
- "sqlEditor.results.title": "Results",
- "sqlEditor.saveSql.fileType": "SQL Files",
- "sqlEditor.saveSql.pickerTitle": "Save SQL File",
- "sqlEditor.export.pickerTitle": "Export SQL Data",
- "sqlEditor.export.status.noResultTitle": "No execution result available for export.",
- "sqlEditor.export.status.noResultDetail": "Execute a query first.",
- "sqlEditor.export.status.successTitle": "Report exported.",
- "sqlEditor.export.status.failedTitle": "Failed to export report.",
- "sqlEditor.export.fileType.html": "HTML File",
- "sqlEditor.export.fileType.json": "JSON File",
- "sqlEditor.export.fileType.csv": "CSV File",
- "sqlEditor.export.fileType.xlsx": "Excel Workbook",
- "sqlEditor.export.defaultFileBase": "report",
- "sqlEditor.export.defaultTitle": "SQL Report",
- "sqlEditor.export.error.typeRequired": "A report type must be selected before export.",
- "sqlEditor.export.type.html.title": "HTML full-feature report",
- "sqlEditor.export.type.html.description": "Standalone, SQL-first HTML artifact for offline audit.",
- "sqlEditor.export.type.json.title": "JSON execution contract",
- "sqlEditor.export.type.json.description": "Machine-readable payload with SQL, metadata and execution result.",
- "sqlEditor.export.type.csv.title": "CSV data export",
- "sqlEditor.export.type.csv.description": "Tabular result data only, suitable for spreadsheet tools.",
- "sqlEditor.export.type.xlsx.title": "Excel workbook export",
- "sqlEditor.export.type.xlsx.description": "Spreadsheet workbook with query result data only.",
- "sqlEditor.export.dialog.windowTitle": "Export SQL Data",
- "sqlEditor.export.dialog.title": "Export SQL Data",
- "sqlEditor.export.dialog.subtitle": "Choose the artifact format and metadata before exporting.",
- "sqlEditor.export.dialog.confirm": "Export",
- "sqlEditor.export.dialog.fileNameWatermark": "report.html",
- "sqlEditor.export.dialog.titleWatermark": "SQL Report",
- "sqlEditor.export.dialog.descriptionWatermark": "Additional context for auditors and teammates.",
- "sqlEditor.export.dialog.section.reportType": "REPORT TYPE",
- "sqlEditor.export.dialog.section.fileName": "FILE NAME",
- "sqlEditor.export.dialog.section.reportTitle": "TITLE",
- "sqlEditor.export.dialog.section.description": "DESCRIPTION",
- "sqlEditor.export.dialog.section.options": "OPTIONS",
- "sqlEditor.export.option.includeSchema": "Include output schema",
- "sqlEditor.export.option.includeNodeDetails": "Include node/connection placeholders in JSON",
- "sqlEditor.export.option.includeMetadata": "Include optional metadata",
- "sqlEditor.export.option.useDashForEmpty": "Use '-' for empty fields",
- "sqlEditor.export.badge.offline": "OFFLINE READY",
- "sqlEditor.export.badge.structured": "STRUCTURED PAYLOAD",
- "sqlEditor.export.badge.dataOnly": "DATA ONLY"
-}
+{
+ "main.brand": "AkkornStudio",
+ "main.tab.query1": "Query 1",
+ "main.new": "New",
+ "main.open": "Open",
+ "main.save": "Save",
+ "main.history": "History",
+ "main.layout": "Layout",
+ "main.preview": "Preview",
+ "main.undo": "Undo",
+ "main.redo": "Redo",
+ "main.cleanupOrphans": "Cleanup orphan nodes",
+ "main.autoFixAliasNaming": "Auto-fix alias naming",
+ "main.autoLayoutCanvas": "Auto layout canvas",
+ "main.toggleDataPreview": "Toggle data preview",
+ "main.language": "Language",
+ "main.restore.prompt": "Previous session found — restore the last canvas?",
+ "main.restore.button": "Restore session",
+ "main.cteEditor.editingPrefix": "Editing CTE: ",
+ "main.cteEditor.backToCanvas": "Back to Canvas",
+ "main.cteEditor.exitA11y": "Exit CTE editor",
+ "main.viewEditor.editingPrefix": "DDL > View: ",
+ "main.viewEditor.backToCanvas": "Back to DDL",
+ "main.viewEditor.exitA11y": "Exit view editor",
+ "connection.title": "Connection Manager",
+ "connection.subtitle": "Настраивайте, проверяйте и активируйте подключения, не прерывая поток",
+ "connection.none": "No connection",
+ "connection.active": "ACTIVE",
+ "connection.health.online": "Online",
+ "connection.health.degraded": "Degraded",
+ "connection.health.offline": "Offline",
+ "connection.tooltip.none": "No active connection — click to manage",
+ "connection.ping": "Ping",
+ "connection.saved": "SAVED CONNECTIONS",
+ "connection.new": "New Connection",
+ "connection.selectOrCreate": "Select a connection or create a new one",
+ "connection.name": "Connection Name",
+ "connection.provider": "Provider",
+ "connection.host": "Host",
+ "connection.port": "Port",
+ "connection.database": "Database",
+ "connection.sqlitePath": "SQLite Path",
+ "connection.sqliteBrowse": "Browse",
+ "connection.sqliteCreate": "Create",
+ "connection.username": "Username",
+ "connection.password": "Password",
+ "connection.timeout": "Timeout (seconds)",
+ "connection.test": "Test",
+ "connection.save": "Save",
+ "connection.connect": "Connect",
+ "connection.action.testConnection": "Test connection",
+ "connection.action.saveConnection": "Save connection",
+ "connection.action.connectConnection": "Connect connection",
+ "connection.status.connecting": "Подключение...",
+ "connection.status.connected": "Подключено",
+ "connection.status.testing": "Проверка...",
+ "connection.status.failedPrefix": "Сбой подключения",
+ "connection.status.metadataUnavailable": "Сбой подключения: метаданные недоступны.",
+ "connection.status.highLatency": "высокая задержка",
+ "connection.watermark.name": "Моя Prod БД",
+ "connection.watermark.host": "localhost",
+ "connection.watermark.port": "5432",
+ "connection.watermark.database": "database_name",
+ "connection.watermark.username": "user",
+ "connection.watermark.password": "••••••••",
+ "connection.watermark.timeout": "30",
+ "main.connectingDb": "Connecting to database...",
+ "main.emptyHint": "Press ⇧A to add your first node, or drag a table from the sidebar",
+ "status.nodesSeparator": " nodes · ",
+ "status.connectionsSuffix": " connections",
+ "status.undo": "Undo: ",
+ "status.shortcuts": "⇧A Nodes · F3 Preview · Ctrl+Z Undo · Del Remove · Alt+Drag Pan",
+ "connection.disconnect": "Disconnect",
+ "connection.action.disconnectConnection": "Disconnect connection",
+ "connectionTab.active": "ACTIVE CONNECTION",
+ "connectionTab.none": "No active connection",
+ "connectionTab.saved": "SAVED CONNECTIONS",
+ "connectionTab.new": "+ New Connection",
+ "schema.database": "DATABASE",
+ "schema.search": "Search tables, columns...",
+ "schema.loading": "Searching tables, columns...",
+ "schema.noConnection": "No Connection",
+ "schema.noConnectionHint": "Connect to a database to see tables, columns, and relationships",
+ "schema.emptyNoTables": "No tables found",
+ "fileHistory.title": "Save/Load Version History",
+ "fileHistory.reload": "Reload",
+ "fileHistory.restoreSelected": "Restore selected",
+ "fileHistory.empty": "No local versions yet",
+ "fileHistory.emptyHint": "Save this file to generate version history.",
+ "preview.title": "Data Preview",
+ "preview.subtitle": "Review data and diagnostics before continuing",
+ "preview.run": "Run",
+ "preview.cancel": "Cancel",
+ "preview.tab.preview": "Preview",
+ "preview.tab.sql": "SQL",
+ "preview.close": "Close preview",
+ "preview.running": "Running preview query… ",
+ "preview.clickCancel": "Click Cancel to stop",
+ "preview.cancelled": "Query cancelled",
+ "preview.runAgain": "Press Run to execute again",
+ "preview.failed": "Preview execution failed",
+ "preview.technical": "TECHNICAL DETAILS",
+ "preview.noData": "No data yet",
+ "preview.f3Hint": "Press F3 or Space to run the current query",
+ "sqlImporter.title": "Import SQL to Graph",
+ "sqlImporter.subtitle": "Paste a SELECT statement — nodes are created automatically",
+ "sqlImporter.sqlStatement": "SQL STATEMENT",
+ "sqlImporter.supported": "Supported: ",
+ "sqlImporter.import": "Import",
+ "sqlImporter.report": "CONVERSION REPORT",
+ "sqlEditor.mutation.dialogTitle": "Подтверждение изменения",
+ "sqlEditor.mutation.dialogSubtitle": "Проверьте влияние перед подтверждением выполнения",
+ "search.empty": "No nodes found",
+ "search.emptyHint": "Try searching for UPPER, JSON, CAST, AND…",
+ "search.shortcut": "⇧A",
+ "search.spawn": "Spawn",
+ "commandPalette.empty": "Нет команд, соответствующих поиску",
+ "commandPalette.search": "Поиск команд",
+ "commandPalette.shortcut": "CTRL+SHIFT+P",
+ "commandPalette.execute": "Выполнить",
+ "context.editCte": "Edit Selected CTE",
+ "context.editViewSubcanvas": "Edit View Subcanvas",
+ "explain.title": "Explain Plan",
+ "explain.sql": "SQL",
+ "explain.option.analyze": "Анализ",
+ "explain.option.buffers": "Буферы",
+ "explain.badge.simulated": "СИМУЛИРОВАНО",
+ "explain.timing.planning": "Планирование:",
+ "explain.timing.execution": "Выполнение:",
+ "explain.section.snapshotComparison": "Сравнение снимков",
+ "explain.section.indexRecommendations": "Рекомендации по индексам",
+ "explain.section.history": "История",
+ "explain.detail.estimated": "Оценочные",
+ "explain.detail.actual": "Фактические",
+ "explain.detail.error": "Ошибка",
+ "explain.detail.time": "Время",
+ "explain.detail.loops": "Циклы",
+ "explain.rerun": "Re-run",
+ "explain.alertSuffix": " expensive operation(s) detected — consider adding indexes",
+ "explain.running": "Running EXPLAIN…",
+ "explain.failed": "⚠ EXPLAIN failed",
+ "explain.noPlan": "No plan yet",
+ "explain.rerunHint": "Press Re-run to execute EXPLAIN",
+ "explain.header.operation": "ОПЕРАЦИЯ",
+ "explain.header.cost": "СТОИМОСТЬ",
+ "explain.header.rows": "СТРОКИ",
+ "explain.header.alert": "ПРЕДУПРЕЖДЕНИЕ",
+ "explain.mode.list": "Список",
+ "explain.mode.tree": "Дерево",
+ "explain.action.snapshot": "Сохранить снимок",
+ "explain.action.copyJson": "Копировать JSON",
+ "explain.action.copyText": "Копировать текст",
+ "explain.action.saveJson": "Сохранить .json",
+ "explain.action.openDalibo": "Открыть в Dalibo",
+ "explain.legend.seqscan": "SEQ SCAN — full table read, no index",
+ "explain.legend.sort": "SORT — in-memory sort",
+ "explain.legend.hash": "HASH — hash join",
+ "explain.escClose": "Esc to close",
+ "flowVersion.title": "Flow Version History",
+ "flowVersion.subtitle": "Create checkpoints, compare versions and restore",
+ "flowVersion.watermark": "Checkpoint label (optional)…",
+ "flowVersion.saveCheckpoint": "Save Checkpoint",
+ "flowVersion.compareMode": "Compare Mode",
+ "flowVersion.selectBase": "Select BASE version (from):",
+ "flowVersion.clickAny": "Then click any version in the list below to compare.",
+ "flowVersion.noCheckpoints": "No checkpoints yet",
+ "flowVersion.noCheckpointsHint": "Save a checkpoint above to begin tracking versions.",
+ "flowVersion.restore": "Restore",
+ "flowVersion.diffResults": "Diff Results",
+ "benchmark.title": "Query Benchmark",
+ "benchmark.subtitle": "Measures avg / median / p95 latency over N iterations",
+ "benchmark.sql": "SQL being benchmarked",
+ "benchmark.runLabel": "Run label",
+ "benchmark.runLabelWatermark": "Run 1",
+ "benchmark.iterations": "Iterations (1–100)",
+ "benchmark.warmup": "Warm-up passes (0–10)",
+ "benchmark.interval": "Interval between runs (ms)",
+ "benchmark.run": "Run Benchmark",
+ "benchmark.cancel": "Cancel",
+ "benchmark.clearHistory": "Clear History",
+ "benchmark.latest": "LATEST RESULT",
+ "benchmark.avg": "AVG",
+ "benchmark.median": "MEDIAN",
+ "benchmark.min": "MIN",
+ "benchmark.max": "MAX",
+ "benchmark.iterationsAt": " iterations · run at ",
+ "benchmark.history": "HISTORY",
+ "benchmark.header.label": "Метка",
+ "benchmark.header.avg": "Средн.",
+ "benchmark.header.median": "Медиана",
+ "benchmark.header.min": "Мин",
+ "benchmark.header.max": "Макс",
+ "benchmark.itersSuffix": " iters",
+ "diagnostics.title": "App Diagnostics",
+ "diagnostics.run": "Run",
+ "diagnostics.running": "Running checks…",
+ "diagnostics.ok": "OK",
+ "diagnostics.warning": "Warning",
+ "diagnostics.error": "Error",
+ "diagnostics.tooltip.rerun": "Re-run all checks",
+ "diagnostics.tooltip.copy": "Copy diagnostic report to clipboard",
+ "diagnostics.tooltip.close": "Close (Esc)",
+ "autoJoin.title": "Auto-Join Suggestions",
+ "autoJoin.titleForTable": "Auto-Join suggestions for {0}",
+ "autoJoin.acceptAll": "Accept All",
+ "autoJoin.accept": "Accept",
+ "autoJoin.skip": "Skip",
+ "autoJoin.allHandled": "All suggestions handled",
+ "autoJoin.joinKeyword": "JOIN",
+ "autoJoin.confidence.fkConstraint": "FK Constraint",
+ "autoJoin.confidence.fkReverse": "FK (Reverse)",
+ "autoJoin.confidence.namingMatch": "Naming Match",
+ "autoJoin.confidence.weakMatch": "Weak Match",
+ "autoJoin.runSelected": "Auto-Join Selected",
+ "autoJoin.noSimilarityTitle": "No automatic join found",
+ "autoJoin.noSimilarityDetails": "Choose the columns manually to create a simple join.",
+ "autoJoin.appliedTitle": "Auto-join applied",
+ "autoJoin.manual.title": "Create Manual Join",
+ "autoJoin.manual.subtitle": "No reliable similarity was found. Select one column from each table.",
+ "autoJoin.manual.leftColumn": "Left column",
+ "autoJoin.manual.rightColumn": "Right column",
+ "autoJoin.manual.joinType": "Join type",
+ "autoJoin.manual.operator": "Operator",
+ "autoJoin.manual.confirm": "Create join",
+ "autoJoin.manual.noCompatible": "No compatible columns for the selected left pin type.",
+ "autoJoin.manualJoinCreatedTitle": "Manual join created",
+ "autoJoin.manualJoinFailedTitle": "Manual join could not be created",
+ "autoJoin.manualJoinFailedDetails": "Check selected columns and existing joins, then try again.",
+ "autoJoin.multipleCandidatesTitle": "Multiple join candidates found",
+ "autoJoin.multipleCandidatesDetails": "{0} possible combinations were found. Confirm which columns should be used.",
+ "autoJoin.suggestionsFoundTitle": "Auto-join suggestions available",
+ "autoJoin.suggestionsFoundDetails": "{0} suggestion(s) found. Select two tables and run Auto-Join Selected.",
+ "property.outputAlias": "OUTPUT ALIAS",
+ "property.sourceAlias": "SOURCE ALIAS",
+ "property.aliasWatermark": "e.g. MyColumn (optional)",
+ "property.parameters": "PARAMETERS",
+ "property.enabled": "Enabled",
+ "property.datetimeWatermark": "YYYY-MM-DDTHH:mm:ss or leave empty",
+ "property.dateWatermark": "YYYY-MM-DD or leave empty",
+ "property.apply": "Apply",
+ "property.inputPins": "INPUT PINS",
+ "property.outputPins": "OUTPUT PINS",
+ "property.sqlTrace": "SQL TRACE",
+ "property.live": "live",
+ "node.numericValue": "Numeric Value",
+ "node.stringValue": "String Value",
+ "node.enterText": "Enter text",
+ "node.datetimeValue": "DateTime Value",
+ "node.valueLabel": "Value:",
+ "node.noInputs": "No inputs",
+ "node.loadingSample": "Loading sample…",
+ "node.previewFailed": "⚠ Preview failed",
+ "node.sampleRowsHint": "5 sample rows · demo data",
+ "sidebar.tab.nodes": "Узлы",
+ "sidebar.tab.connection": "Подключение",
+ "sidebar.tab.schema": "Схема",
+ "sidebar.tab.diagnostics": "Диагностика",
+ "sidebar.addNode": "+ Add Node (⇧A)",
+ "sidebar.previewF3": "Preview (F3)",
+ "nodesList.search": "Search nodes...",
+ "search.watermark": "Search nodes… (Esc to close)",
+ "search.snippets": "★ SNIPPETS",
+ "commandPalette.watermark": "Выполнить команду… (Esc для закрытия)",
+ "tooltip.newCanvas": "New canvas (Ctrl+N)",
+ "tooltip.openCanvas": "Open canvas (Ctrl+O)",
+ "tooltip.saveCanvas": "Save canvas (Ctrl+S)",
+ "tooltip.fileHistory": "Local save/load history (Ctrl+Alt+H)",
+ "tooltip.zoomOut": "Zoom out (Ctrl+-)",
+ "tooltip.zoomIn": "Zoom in (Ctrl++)",
+ "tooltip.fitToScreen": "Fit to screen (Ctrl+0)",
+ "tooltip.autoLayout": "Auto Layout — arrange nodes into logical columns (Ctrl+L, Ctrl+Z to undo)",
+ "tooltip.snapToGrid": "Toggle snap to grid (Ctrl+G)",
+ "tooltip.dataPreview": "Data preview (F3)",
+ "tooltip.toggleLanguage": "Toggle language (pt-BR / en-US)",
+ "tooltip.appDiagnostics": "App Diagnostics (self-check)",
+ "tooltip.keyboardShortcuts": "Keyboard shortcuts (F1)",
+ "tooltip.cancelRunningQuery": "Cancel the running query",
+ "tooltip.closeEsc": "Close (Esc)",
+ "tooltip.recheckConnectionHealth": "Re-check connection health",
+ "tooltip.deleteConnection": "Delete connection",
+ "tooltip.testConnection": "Test connection",
+ "tooltip.saveConnection": "Save connection",
+ "tooltip.activateConnection": "Activate this connection",
+ "tooltip.toggleDataSamplePreview": "Toggle data sample preview",
+ "tooltip.liveSqlMutatingBlocked": "This SQL contains a data-mutating command and cannot be run in Safe Preview Mode",
+ "tooltip.copySql": "Copy SQL to clipboard",
+ "tooltip.formatSql": "Format SQL",
+ "tooltip.openBenchmark": "Open Query Benchmark (measure avg / median / p95 latency)",
+ "tooltip.openExplainPlan": "Open Explain Plan inspector — visualise the query execution plan",
+ "tooltip.switchToQueryMode": "Switch to Query canvas",
+ "tooltip.switchToDdlMode": "Switch to DDL canvas",
+ "tooltip.autoJoinSelected": "Try auto-join between the two selected tables",
+ "tooltip.pins.inputs": "Inputs",
+ "tooltip.pins.outputs": "Outputs",
+ "tooltip.pins.none": "None",
+ "tooltip.tableColumns": "Columns",
+ "tooltip.tableColumns.none": "No detailed columns",
+ "window.minimize": "Minimize window",
+ "window.maximizeRestore": "Maximize/restore window",
+ "window.close": "Close window",
+ "menu.newDiagram": "New diagram",
+ "menu.openFile": "Open file",
+ "menu.save": "Save",
+ "menu.fileHistory": "File history",
+ "menu.shortcuts": "Keyboard shortcuts",
+ "menu.settings": "Settings",
+ "menu.importDdlSchema": "Import DDL schema",
+ "menu.viewDdlSql": "View DDL SQL",
+ "menu.executeDdl": "Execute DDL",
+ "menu.backToStart": "Back to start",
+ "toast.ddlExecuteFailed": "Failed to execute DDL.",
+ "toast.ddlOpenFailed": "Failed to open DDL SQL.",
+ "toast.ddlImportFailed": "Failed to import schema into DDL.",
+ "toast.ddlConnectToImportSchema": "Connect to a database to import schema into the DDL canvas.",
+ "toast.ddlNoTablesFound": "No tables found to import in DDL mode.",
+ "toast.ddlSchemaImported": "Schema imported into the DDL canvas.",
+ "toast.ddlImportSummary": "{0} table(s), {1} column(s), {2} FK(s), {3} unique index(es).",
+ "toast.ddlConnectToImportTable": "Connect to a database to import tables into the DDL canvas.",
+ "toast.ddlTableAlreadyExists": "Table '{0}' already exists in the DDL canvas.",
+ "toast.ddlTableImported": "Table imported into the DDL canvas.",
+ "toast.ddlTableImportSummary": "Nodes: +{0}, connections: +{1}, FKs: +{2}.",
+ "toast.ddlNoActiveConnection": "No active connection to execute DDL.",
+ "toast.ddlExecutedSuccess": "DDL executed successfully.",
+ "toast.ddlExecutedWithIssues": "DDL executed with issues.",
+ "toast.switchToDdl": "Switch to DDL mode to generate SQL.",
+ "toast.ddlInvalid": "Invalid DDL. Fix errors before continuing.",
+ "toast.ddlNoStatements": "No DDL statements were generated in the canvas.",
+ "toast.previewOpenFailed": "Failed to open preview.",
+ "tab.switchFailed": "Failed to switch tab: {0}",
+ "settings.status.darkApplied": "Dark theme applied.",
+ "settings.status.lightApplied": "Light theme applied.",
+ "settings.status.snapUpdated": "Snap updated: {0}.",
+ "settings.status.languageToggled": "Language toggled.",
+ "settings.status.languageSelected": "Language selected: {0}.",
+ "settings.status.themeEditorReady": "Theme editor ready. Apply to save and use this theme.",
+ "settings.section.appearance.title": "Themes",
+ "settings.section.languageRegion.title": "Язык и регион",
+ "settings.section.dateTime.title": "Дата и время",
+ "settings.section.keyboard.title": "Горячие клавиши",
+ "settings.section.privacy.title": "Конфиденциальность",
+ "settings.section.notification.title": "Уведомления",
+ "settings.section.accessibility.title": "Доступность",
+ "settings.section.default.title": "Настройки",
+ "settings.section.appearance.subtitle": "Выберите стиль или настройте тему",
+ "settings.section.languageRegion.subtitle": "Управляйте языком и региональным форматированием",
+ "settings.section.keyboard.subtitle": "Настройте сочетания клавиш для command palette и выполнения на canvas.",
+ "settings.section.wip.subtitle": "В разработке.",
+ "settings.section.default.subtitle": "Настройки приложения",
+ "settings.general": "General",
+ "settings.nav.appearance": "Appearance",
+ "settings.theme.light": "Светлая тема",
+ "settings.theme.dark": "Тёмная тема",
+ "settings.theme.system": "Системная тема",
+ "settings.gridSnap.title": "Grid Snap",
+ "settings.gridSnap.subtitle": "Controls node snapping on the canvas.",
+ "settings.language.subtitle": "Выберите язык приложения.",
+ "settings.language.toggle": "Сменить язык",
+ "settings.language.option.ptBR": "Португальский (Бразилия)",
+ "settings.language.option.enUS": "Английский (США)",
+ "settings.language.option.esES": "Испанский (Испания)",
+ "settings.language.option.ruRU": "Русский",
+ "settings.language.option.jaJP": "Японский",
+ "settings.language.option.zhTW": "Традиционный китайский",
+ "settings.themeJson.title": "JSON темы",
+ "settings.themeJson.subtitle": "Вставьте JSON темы, примените и сохраните сразу.",
+ "settings.themeJson.apply": "Применить JSON",
+ "settings.themeJson.restoreDefault": "Восстановить тему по умолчанию",
+ "mode.query": "Query",
+ "mode.ddl": "DDL",
+ "sidebar.left.close": "Close left sidebar",
+ "sidebar.left.open": "Reopen left sidebar",
+ "sidebar.right.close": "Close right sidebar",
+ "sidebar.right.open": "Reopen right sidebar",
+ "connection.completedTitle": "Connection completed",
+ "connection.clearCanvasPrompt": "Do you want to clear the current canvas to start with the new connection?",
+ "connection.close": "Close connection manager",
+ "connection.refreshHealth": "Refresh connection health",
+ "common.details": "Details",
+ "common.cancel": "Cancel",
+ "common.keep": "Keep",
+ "common.clear": "Clear",
+ "zoom.out": "Zoom out",
+ "zoom.in": "Zoom in",
+ "zoom.fit": "Fit zoom to screen",
+ "zoom.level": "Zoom level",
+ "settings.theme.mode": "Режим темы",
+ "diagnostics.category.canvas": "Canvas Integrity",
+ "diagnostics.category.output": "Output & Execution",
+ "diagnostics.category.session": "Session & Safety",
+ "diagnostics.category.notice": "Runtime Notices",
+ "diagnostics.summary.ok": "All systems OK",
+ "diagnostics.summary.warningCount": "{0} warning(s) detected",
+ "diagnostics.summary.errorCount": "{0} error(s) detected",
+ "diagnostics.canvasMigration": "Canvas Migration",
+ "diagnostics.recommendation.resaveFile": "Re-save the file to update it to the latest schema version.",
+ "diagnostics.canvasState.name": "Canvas State",
+ "diagnostics.canvasState.recommendation": "Add at least one {0} and one {1}",
+ "diagnostics.canvasState.empty": "Canvas is empty - no nodes present",
+ "diagnostics.canvasState.counts": "{0} node(s), {1} connection(s)",
+ "diagnostics.validation.name": "Validation Errors",
+ "diagnostics.validation.recommendation": "Fix highlighted nodes before running output preview",
+ "diagnostics.validation.errorWithWarnings": "{0} error(s) and {1} warning(s) in the graph",
+ "diagnostics.validation.warningOnly": "{0} warning(s) in the graph",
+ "diagnostics.validation.none": "No validation issues",
+ "diagnostics.orphan.name": "Orphan Nodes",
+ "diagnostics.orphan.recommendation": "Use the orphan cleanup action to remove unused nodes",
+ "diagnostics.orphan.count": "{0} node(s) not connected to any output",
+ "diagnostics.orphan.none": "No orphan nodes detected",
+ "diagnostics.naming.name": "Naming Conventions",
+ "diagnostics.naming.recommendation": "Use auto-fix alias naming when conformance is below 100%",
+ "diagnostics.naming.conformance": "Naming conformance: {0}%",
+ "diagnostics.naming.ok": "All aliases follow naming conventions (100%)",
+ "diagnostics.queryCompilation.name": "Live SQL Compilation",
+ "diagnostics.queryCompilation.recommendation": "Review SQL diagnostics in output when errors/warnings are reported.",
+ "diagnostics.queryCompilation.errorFallback": "Live SQL compilation reported errors.",
+ "diagnostics.queryCompilation.warningCounts": "{0} diagnostic item(s), {1} guardrail warning(s).",
+ "diagnostics.queryCompilation.ok": "Live SQL compiled without diagnostics.",
+ "diagnostics.previewSafety.name": "Preview Safety",
+ "diagnostics.previewSafety.recommendation": "Preview executes read-only statements only.",
+ "diagnostics.previewSafety.blocked": "Current SQL is mutating and blocked by Safe Preview mode.",
+ "diagnostics.previewSafety.ok": "Preview safety checks passed.",
+ "diagnostics.previewExecution.name": "Preview Execution",
+ "diagnostics.previewExecution.recommendation": "Run preview and inspect diagnostics for execution/runtime errors.",
+ "diagnostics.previewExecution.failed": "Preview execution failed.",
+ "diagnostics.previewExecution.cancelled": "Preview execution was cancelled.",
+ "diagnostics.previewExecution.done": "{0} row(s) in {1}ms.",
+ "diagnostics.previewExecution.none": "No preview execution issues detected.",
+ "diagnostics.ddlCompilation.name": "DDL Compilation",
+ "diagnostics.ddlCompilation.recommendation": "Fix DDL compile diagnostics before execution.",
+ "diagnostics.ddlCompilation.failed": "DDL compilation failed.",
+ "diagnostics.ddlCompilation.warningCount": "{0} warning(s) reported by DDL compiler.",
+ "diagnostics.ddlCompilation.ok": "DDL compilation succeeded.",
+ "diagnostics.ddlOutput.name": "DDL Output",
+ "diagnostics.ddlOutput.recommendation": "Add/complete DDL nodes until at least one statement is generated.",
+ "diagnostics.ddlOutput.none": "No DDL statements generated yet.",
+ "diagnostics.ddlOutput.lines": "{0} line(s) of DDL generated.",
+ "diagnostics.undo.name": "Undo History",
+ "diagnostics.undo.recommendation": "History is in-memory only; save your canvas regularly.",
+ "diagnostics.undo.saved": "Canvas is saved (no unsaved changes).",
+ "diagnostics.undo.unsavedDeep": "Unsaved changes with {0} undo steps.",
+ "diagnostics.undo.unsaved": "Unsaved changes - {0} undo step(s) available.",
+ "diagnostics.report.title": "AkkornStudio - Diagnostic Report",
+ "diagnostics.report.generated": "Generated",
+ "diagnostics.report.overall": "Overall",
+ "diagnostics.report.details": "Details",
+ "diagnostics.report.recommendation": "Recommendation",
+ "diagnostics.report.lastCheck": "Last Check",
+ "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
+ "node.datetimeFormat": "YYYY-MM-DDTHH:mm:ss",
+ "preview.providerLabel": "Provider",
+ "preview.ddlDiagnosticsHint": "Error/warning details are available in Diagnostics.",
+ "preview.schemaAnalysis.run": "Run Analysis",
+ "preview.schemaAnalysis.cancel": "Cancel",
+ "preview.schemaAnalysis.issues": "Issues",
+ "preview.schemaAnalysis.clearFilters": "Clear Filters",
+ "preview.schemaAnalysis.severity": "Severity",
+ "preview.schemaAnalysis.rule": "Rule",
+ "preview.schemaAnalysis.minConfidence": "Min Confidence",
+ "preview.schemaAnalysis.tableFilter": "Table Filter",
+ "preview.schemaAnalysis.tableFilterWatermark": "schema.table",
+ "preview.schemaAnalysis.details": "Details",
+ "preview.schemaAnalysis.evidence": "Evidence",
+ "preview.schemaAnalysis.suggestions": "Suggestions",
+ "preview.schemaAnalysis.ruleDiagnostics": "Rule Diagnostics",
+ "preview.schemaAnalysis.sqlCandidates": "SQL Candidates",
+ "preview.schemaAnalysis.copySql": "Copy SQL",
+ "preview.schemaAnalysis.applyToCanvas": "Apply to Canvas",
+ "preview.schemaAnalysis.summary.issues": "Issues:",
+ "preview.schemaAnalysis.summary.rawPrefix": "(raw:",
+ "preview.schemaAnalysis.summary.critical": "| Critical:",
+ "preview.schemaAnalysis.summary.warning": "| Warning:",
+ "preview.schemaAnalysis.summary.info": "| Info:",
+ "preview.schemaAnalysis.state.metadataUnavailable": "Metadata unavailable for structural analysis.",
+ "preview.schemaAnalysis.state.cancelled": "Analysis cancelled by the user.",
+ "preview.schemaAnalysis.state.partialTimeout": "Analysis finished partially due to timeout.",
+ "preview.schemaAnalysis.state.failed": "Structural analysis failed.",
+ "preview.schemaAnalysis.state.empty": "No inferable structural issue was detected.",
+ "preview.schemaAnalysis.state.noFilterMatch": "No issue matches the selected filters.",
+ "preview.schemaAnalysis.state.noIssueSelected": "No issue selected.",
+ "preview.schemaAnalysis.state.noSqlCandidate": "No SQL candidate available.",
+ "preview.schemaAnalysis.actionBlockedTooltip": "Action unavailable for the current risk level or capability.",
+ "common.navigate": "Navigate",
+ "common.close": "Close",
+ "common.esc": "Esc",
+ "common.ms": "ms",
+ "common.zero": "0",
+ "diagnostics.tip": "Tip: check Diagnostics whenever preview/output reports warnings or errors.",
+ "nodesList.empty": "No nodes found",
+ "nodesList.emptyHint": "Adjust the search term to explore available types",
+ "schema.emptyFiltered": "No objects found for the current filter",
+ "start.lastSnapshot": "Last snapshot",
+ "app.brandBadge": "VS",
+ "property.tab.properties": "Properties",
+ "property.tab.projectSettings": "Project Settings",
+ "property.nodeType": "NODE TYPE",
+ "property.selectNodeHint": "Select a node to edit its properties.",
+ "property.namingConventions": "Naming Conventions",
+ "property.aliasConvention": "Alias convention",
+ "property.enforceAliasNaming": "Enforce alias naming",
+ "property.warnReservedSql": "Warn on reserved SQL keywords",
+ "property.maxAliasLength": "Max alias length",
+ "property.maxAliasLengthDefault": "64",
+ "property.namingSettingsHint": "These settings are project-scoped and are used by naming and validation helpers.",
+ "start.tips": "Tips",
+ "start.tips.quick": "Quick tips",
+ "start.tips.item1": "1. Click New Diagram to start from scratch.",
+ "start.tips.item2": "2. Use templates to speed up prototyping.",
+ "start.tips.item3": "3. Open saved connections to load real tables.",
+ "start.tips.shortcut": "Shortcut: CTRL+SHIFT+P opens the command palette.",
+ "start.workspace": "WORKSPACE",
+ "start.resumeTitle": "Continue where you left off",
+ "start.resumeSubtitle": "Quickly resume a recent project or start a new diagram.",
+ "start.chip.quickFlow": "Quick flow",
+ "start.chip.templates": "Templates",
+ "start.chip.connections": "Connections",
+ "start.savedConnectionsTitle": "Saved Connections",
+ "start.savedConnectionsSubtitle": "Connect quickly to a database to load schema and tables.",
+ "start.noConnectionsTitle": "No connections configured yet",
+ "start.noConnectionsSubtitle": "Create a connection to explore real tables in the editor.",
+ "start.newConnection": "+ New Connection",
+ "start.recentProjectsTitle": "Recent Projects",
+ "start.searchRecent": "Search recent project...",
+ "start.quickActions": "Quick actions",
+ "start.quickActionsSubtitle": "Open an existing file or start a new diagram.",
+ "start.noRecentTitle": "No recent projects yet",
+ "start.noRecentSubtitle": "Use the quick actions card above to get started.",
+ "start.exploreTemplates": "Explore templates",
+ "start.templatesFavoritesHint": "Favorites on top",
+ "start.favoriteTemplate": "Favorite template",
+ "node.columnSetPreview": "ColumnSet preview",
+ "node.view": "VIEW",
+ "node.tableDefinition": "Table Definition",
+ "node.join": "JOIN",
+ "node.window.addPartition": "Add PARTITION BY slot",
+ "node.window.removePartition": "Remove PARTITION BY slot",
+ "node.window.addOrder": "Add ORDER BY slot",
+ "node.window.removeOrder": "Remove ORDER BY slot",
+ "sql.keyword.select": "SELECT",
+ "sql.keyword.from": "FROM",
+ "sql.keyword.join": "JOIN",
+ "sql.keyword.where": "WHERE",
+ "sql.keyword.limit": "LIMIT",
+ "sqlImporter.close": "Close SQL importer",
+ "sqlImporter.report.imported": "Imported",
+ "sqlImporter.report.partial": "Partial",
+ "sqlImporter.report.skipped": "Skipped",
+ "benchmark.close": "Close benchmark",
+ "benchmark.p95": "P95",
+ "benchmark.n": "N",
+ "liveSql.safePreview": "SAFE PREVIEW MODE",
+ "liveSql.title": "LIVE SQL",
+ "liveSql.blocked": "BLOCKED",
+ "liveSql.copy": "Copy",
+ "liveSql.format": "Format",
+ "liveSql.benchmark": "Benchmark",
+ "liveSql.explain": "Explain",
+ "liveSql.actionsHint": "Performance tools",
+ "ddl.dialog.title": "Execute DDL",
+ "ddl.dialog.execute": "Execute",
+ "ddl.dialog.cancel": "Cancel",
+ "ddl.dialog.close": "Close",
+ "ddl.dialog.stopOnError": "Stop on first failure",
+ "ddl.dialog.confirmDestructive": "I confirm execution of destructive statements (DROP TABLE)",
+ "ddl.dialog.reviewBeforeRun": "Review the DDL script before confirming.",
+ "ddl.dialog.confirmQuestion": "Confirm DDL execution on the connected database?",
+ "ddl.dialog.irreversibleWarning": "This action can change the schema irreversibly.",
+ "ddl.dialog.mustConfirmDestructive": "Confirm destructive execution to continue.",
+ "ddl.dialog.executing": "Executing...",
+ "ddl.execute.result.summary": "Statements: {0} | Success: {1} | Failures: {2} | Time: {3:0}ms",
+ "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
+ "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
+ "ddl.execute.result.failed": "Failed to execute DDL.",
+ "ddl.execute.result.cancelled": "Execution cancelled by the user.",
+ "ddl.execute.result.cancelledDetails": "DDL execution was interrupted before completion.",
+ "context.deleteSingle": "Delete {0}",
+ "context.deleteMultiple": "Delete {0} nodes",
+ "context.bringForward": "Bring Forward (Ctrl+PgUp)",
+ "context.sendBackward": "Send Backward (Ctrl+PgDown)",
+ "context.bringToFront": "Bring to Front (Ctrl+Shift+PgUp)",
+ "context.sendToBack": "Send to Back (Ctrl+Shift+PgDown)",
+ "context.normalizeLayers": "Normalize Layers",
+ "context.deleteWire": "Delete wire",
+ "context.addNode": "Add Node (Shift+A)",
+ "context.undoWithDescription": "Undo {0}",
+ "context.redo": "Redo",
+ "shortcuts.windowTitle": "Keyboard Shortcuts",
+ "shortcuts.headerTitle": "AkkornStudio - Shortcuts",
+ "shortcuts.headerHint": "Tip: use CTRL+SHIFT+P to open the Command Palette and search commands.",
+ "shortcuts.filterWatermark": "Filter shortcuts by key or action...",
+ "shortcuts.resultCount": "{0} shortcuts",
+ "shortcuts.resultFilter": "{0} result(s) for \"{1}\"",
+ "shortcuts.noneFound": "No shortcuts found.",
+ "shortcuts.section.fileGeneral": "Файл и общее",
+ "shortcuts.section.editing": "Редактирование",
+ "shortcuts.section.canvasNavigation": "Холст и навигация",
+ "shortcuts.section.zoomPanPrecision": "Масштаб, панорамирование и точность",
+ "shortcuts.section.previewInspection": "Предпросмотр и инспекция",
+ "shortcuts.key.deleteOrBackspace": "Del или Backspace",
+ "shortcuts.key.middleDrag": "Средняя кнопка + перетаскивание",
+ "shortcuts.key.rightDrag": "Правая кнопка + перетаскивание",
+ "shortcuts.key.spaceDrag": "Пробел + перетаскивание",
+ "shortcuts.key.altLeftDrag": "Alt + перетаскивание левой кнопкой",
+ "shortcuts.key.arrows": "Стрелки",
+ "shortcuts.key.shiftArrows": "Shift + Стрелки",
+ "shortcuts.action.openShortcutScreen": "Открыть этот экран горячих клавиш",
+ "shortcuts.action.newCanvas": "Новый холст",
+ "shortcuts.action.openFile": "Открыть файл",
+ "shortcuts.action.save": "Сохранить",
+ "shortcuts.action.saveAs": "Сохранить как",
+ "shortcuts.action.commandPalette": "Палитра команд",
+ "shortcuts.action.undo": "Отменить",
+ "shortcuts.action.redo": "Повторить",
+ "shortcuts.action.selectAll": "Выделить всё",
+ "shortcuts.action.deleteSelection": "Удалить выделение",
+ "shortcuts.action.closeOverlayCancel": "Закрыть оверлеи / отменить действия",
+ "shortcuts.action.openNodeSearch": "Открыть поиск узлов",
+ "shortcuts.action.resetViewport": "Сбросить viewport",
+ "shortcuts.action.centerSelection": "Центрировать выделение",
+ "shortcuts.action.fitSelection": "Подогнать выделение",
+ "shortcuts.action.autoLayout": "Авторазмещение",
+ "shortcuts.action.toggleSnapToGrid": "Переключить привязку к сетке",
+ "shortcuts.action.bringForward": "На слой выше",
+ "shortcuts.action.sendBackward": "На слой ниже",
+ "shortcuts.action.bringToFront": "На передний план",
+ "shortcuts.action.sendToBack": "На задний план",
+ "shortcuts.action.zoomInOut": "Увеличить / уменьшить",
+ "shortcuts.action.pan": "Панорамирование",
+ "shortcuts.action.temporaryPan": "Временное панорамирование",
+ "shortcuts.action.alternatePan": "Альтернативное панорамирование",
+ "shortcuts.action.fineNudge": "Точный сдвиг выделения",
+ "shortcuts.action.fastNudge": "Быстрый сдвиг",
+ "shortcuts.action.togglePreview": "Переключить предпросмотр данных",
+ "shortcuts.action.explainPlan": "План выполнения",
+ "shortcuts.action.runPreview": "Запустить предпросмотр",
+ "shortcuts.action.connectionManager": "Менеджер подключений",
+ "shortcuts.action.flowVersionHistory": "История версий потока",
+ "shortcuts.resetAll": "Сбросить всё",
+ "shortcuts.customized": "Изменено",
+ "shortcuts.default": "По умолчанию",
+ "shortcuts.apply": "Применить",
+ "shortcuts.reset": "Сбросить",
+ "shortcuts.status.resetAllSuccess": "Все сочетания сброшены к значениям по умолчанию.",
+ "shortcuts.status.updated": "Сочетание обновлено.",
+ "shortcuts.status.reset": "Сочетание сброшено по умолчанию.",
+ "shortcuts.status.updateFailed": "Не удалось обновить сочетание.",
+ "toast.severity.success": "Success",
+ "toast.severity.warning": "Warning",
+ "toast.severity.error": "Error",
+ "toast.details.success": "Success Details",
+ "toast.details.warning": "Warning Details",
+ "toast.details.error": "Error Details",
+ "diagnostics.area.cteEditor": "CTE Editor",
+ "diagnostics.area.viewEditor": "View Editor",
+ "diagnostics.area.subEditor": "Sub-editor",
+ "diagnostics.cteEditor.restoreParentFailed": "Failed to restore the parent canvas. CTE edits were discarded.",
+ "diagnostics.recommendation.reloadFileIfNeeded": "Reload the file if needed.",
+ "diagnostics.viewEditor.exitFailed": "Could not exit: {0}",
+ "diagnostics.viewEditor.canvasIncomplete": "the canvas is incomplete.",
+ "diagnostics.viewEditor.exitRecommendation": "Connect a valid ResultOutput or use the discard command.",
+ "diagnostics.viewEditor.restoreParentFailed": "Failed to restore the parent canvas. The subgraph was discarded.",
+ "diagnostics.subEditor.executeFailed": "Failed to execute editor action: {0}",
+ "diagnostics.subEditor.executeRecommendation": "Try again. If it persists, reload the canvas.",
+ "diagnostics.canvasMigration.openWarning": "Open: {0}",
+ "diagnostics.canvasMigration.sessionRestoreWarning": "Session restore: {0}",
+ "diagnostics.canvasMigration.versionRestoreWarning": "Version restore: {0}",
+ "diagnostics.recommendation.resaveLatestSchema": "Review diagnostics and re-save the canvas to persist the latest schema.",
+ "diagnostics.recommendation.saveMigratedSchema": "Review diagnostics and save the canvas to persist the migrated schema.",
+ "file.saveDialog.title": "Save Canvas",
+ "file.saveDialog.suggestedName": "Query1",
+ "file.save.success": "Canvas saved successfully.",
+ "file.save.failedWithReason": "Save failed: {0}",
+ "file.openDialog.title": "Open Canvas",
+ "file.open.failedWithReason": "Open failed: {0}",
+ "file.open.success": "Canvas opened successfully.",
+ "file.open.successWithWarnings": "Canvas opened with warnings.",
+ "session.restore.failedWithReason": "Restore failed: {0}",
+ "session.restore.successWithWarnings": "Session restored with warnings.",
+ "session.restore.success": "Session restored successfully.",
+ "export.documentation.dialogTitle": "Export Flow Documentation",
+ "export.documentation.success": "Documentation exported successfully.",
+ "export.documentation.failed": "Documentation export failed.",
+ "export.failed.pathPermissionsHint": "Check file path and permissions.",
+ "export.nodeNotFound": "No {0} Export node found on the canvas. Add one via the node search menu.",
+ "export.dialogTitleByExtension": "Export as {0}",
+ "export.success": "Export completed successfully.",
+ "export.failed": "Export failed.",
+ "fileHistory.currentFile.none": "No file selected",
+ "fileHistory.status.saveFirst": "Save the canvas first to enable local history.",
+ "fileHistory.status.noneFound": "No local versions found yet. Save this file to create history entries.",
+ "fileHistory.status.countAvailable": "{0} local version(s) available.",
+ "fileHistory.restore.failedWithReason": "Restore failed: {0}",
+ "fileHistory.restore.successFrom": "Restored version from {0}.",
+ "preview.status.cancelled": "Cancelled",
+ "preview.status.error": "Error",
+ "preview.status.ready": "Ready",
+ "preview.runningWithMs": "Running... {0}ms",
+ "preview.runningWithTimeout": "Running... {0}ms (timeout: {1}s)",
+ "preview.runningSlowWithTimeout": "Running... {0}ms (timeout: {1}s) · Slow query, timeout in {2}s",
+ "explain.errorWithReason": "Explain plan error: {0}",
+ "explain.noSql": "No SQL to explain. Build a query on the canvas first.",
+ "ddl.compilationFailed": "Compilation failed",
+ "ddl.compileErrorWithReason": "DDL compile error: {0}",
+ "command.undo.name": "Undo",
+ "command.undo.description": "Undo last action",
+ "command.redo.name": "Redo",
+ "command.redo.description": "Redo last undone action",
+ "command.addNode.name": "Add Node",
+ "command.addNode.description": "Open node search menu to add a node",
+ "command.bringForward.name": "Bring Forward",
+ "command.bringForward.description": "Move selected nodes one layer forward",
+ "command.sendBackward.name": "Send Backward",
+ "command.sendBackward.description": "Move selected nodes one layer backward",
+ "command.bringToFront.name": "Bring to Front",
+ "command.bringToFront.description": "Move selected nodes to top layer",
+ "command.sendToBack.name": "Send to Back",
+ "command.sendToBack.description": "Move selected nodes to bottom layer",
+ "command.normalizeLayers.name": "Normalize Layers",
+ "command.normalizeLayers.description": "Compact node layer indices to a clean 0..N order",
+ "tooltip.cleanupOrphans": "Remove orphan nodes not connected to the output (Ctrl+Z to undo)",
+ "main.orphanSuffix": "Orphan(s)",
+ "tooltip.autoFixAliasNaming": "Fix alias naming to snake_case (Ctrl+Z to undo)",
+ "main.namingPrefix": "Naming",
+ "fileHistory.compressedLabel": "Compressed:",
+ "schema.itemsSuffix": "item(s)",
+ "property.panel.title": "Properties",
+ "property.panel.multiSelected": "{0} nodes selected",
+ "sqlImporter.status.pasteSelect": "Paste a SELECT statement above, then click Import.",
+ "sqlImporter.status.inputTooLarge": "SQL input is too large ({0:N0} chars). Limit is {1:N0}. Split the query or increase the import limit.",
+ "sqlImporter.status.parsing": "Parsing SQL...",
+ "sqlImporter.status.done": "Done - {0} imported, {1} partial, {2} skipped.",
+ "sqlImporter.status.cancelledByUser": "Import cancelled by user.",
+ "sqlImporter.status.timeout": "Import timed out after {0:0.#}s. Try a smaller query or increase timeout.",
+ "sqlImporter.status.parseError": "Parse error: {0}",
+ "diagnostics.area.undoRedoTransaction": "Undo/Redo Transaction",
+ "undoRedo.rollbackExecuted": "Rollback executed for '{0}' ({1} operation(s) reverted).",
+ "undoRedo.rollbackRecommendation": "Review the canvas state and retry the action if needed.",
+ "node.preview.noCatalog": "No catalog available",
+ "connection.error.searchMenuNotInitialized": "search menu not initialized",
+ "connection.error.timeoutReachability": "Connection timed out - check that the server is reachable and increase the timeout if needed.",
+ "connection.error.authenticationFailedForProvider": "Authentication failed - verify username and password for {0}.",
+ "connection.error.databaseNotFoundForProvider": "Database not found - confirm the database name exists on {0}.",
+ "connection.error.hostNotFound": "Host not found - check the server address and DNS resolution.",
+ "connection.error.portRefused": "Port connection refused - check the port number and that the server is running / firewall rules allow access.",
+ "connection.error.sslTls": "SSL/TLS error - check the server's SSL configuration or disable SSL for local connections.",
+ "connection.error.timeoutOverloaded": "Connection timed out - the server may be overloaded or unreachable. Try increasing the timeout.",
+ "connection.error.insufficientPrivileges": "Insufficient privileges - the user may lack permission to connect to this database.",
+ "diagnostics.area.connection": "Connection",
+ "connection.warning.canvasMayContainOldTables": "The canvas may still contain tables from a previous connection.",
+ "connection.warning.canvasMayContainOldTablesRecommendation": "Clear the canvas manually or reconnect and choose keep/clear again.",
+ "undoRedo.transaction.unnamed": "unnamed transaction",
+ "benchmark.runLabelDefault": "Run 1",
+ "benchmark.runLabelPattern": "Run {0}",
+ "benchmark.status.failedWithReason": "Benchmark failed: {0}",
+ "benchmark.status.noSql": "No SQL to benchmark - build a query first.",
+ "benchmark.status.warmupProgress": "Warm-up {0}/{1}...",
+ "benchmark.status.iterationProgress": "Iteration {0}/{1}...",
+ "benchmark.status.done": "Done - {0}",
+ "benchmark.status.cancelled": "Benchmark cancelled.",
+ "app.windowTitle": "AkkornStudio",
+ "preview.error.safePreviewBlocked": "Safe Preview Mode: data-mutating commands (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) cannot be executed in preview.",
+ "preview.error.noActiveConnection": "No active database connection. Please connect to a database first.",
+ "sqlImporter.error.selectFromNotFound": "Could not find SELECT ... FROM in the query.",
+ "sqlImporter.error.fromClauseParseFailed": "Could not parse FROM clause.",
+ "sqlImporter.error.syntaxUnterminatedString": "Syntax error at line {0}, column {1}: unterminated string literal.",
+ "sqlImporter.error.missingClosingParenthesis": "missing closing ')'",
+ "sqlImporter.error.unexpectedClosingParenthesis": "unexpected ')'",
+ "sqlImporter.error.syntaxAtLineColumn": "Syntax error at line {0}, column {1}: {2}.",
+ "errorDiagnostics.safePreview.label": "Blocked by Safe Preview Mode",
+ "errorDiagnostics.safePreview.friendly": "This SQL contains a data-mutating command and cannot be executed in preview.",
+ "errorDiagnostics.safePreview.suggestion": "Remove or replace the mutating command (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) before running preview.",
+ "errorDiagnostics.connection.label": "Connection failed",
+ "errorDiagnostics.connection.friendly": "Could not reach the database server. The host may be down, unreachable, or blocking connections.",
+ "errorDiagnostics.connection.suggestion": "Verify the server address and port, ensure the database is running, and check firewall rules.",
+ "errorDiagnostics.authorization.label": "Authorization error",
+ "errorDiagnostics.authorization.friendly": "The current credentials do not have permission to perform this operation.",
+ "errorDiagnostics.authorization.suggestion": "Confirm the database user has SELECT privileges on the target table/schema, or contact your DBA.",
+ "errorDiagnostics.timeout.label": "Query timeout",
+ "errorDiagnostics.timeout.friendly": "The query took too long to complete and was cancelled by the server or client.",
+ "errorDiagnostics.timeout.suggestion": "Add a WHERE clause or LIMIT to reduce the result set, or increase the query timeout in connection settings.",
+ "errorDiagnostics.schema.label": "Schema error",
+ "errorDiagnostics.schema.friendly": "A referenced table, column, or object could not be found in the database.",
+ "errorDiagnostics.schema.suggestion": "Check that all table/column names are spelled correctly and that the schema matches the active connection.",
+ "errorDiagnostics.syntax.label": "SQL syntax error",
+ "errorDiagnostics.syntax.friendly": "The query contains a syntax error and could not be parsed by the database engine.",
+ "errorDiagnostics.syntax.suggestion": "Review the highlighted SQL for typos, mismatched parentheses, or unsupported clauses for the active provider.",
+ "errorDiagnostics.compatibility.label": "Compatibility error",
+ "errorDiagnostics.compatibility.friendly": "A function, operator, or syntax construct is not supported by the active database provider.",
+ "errorDiagnostics.compatibility.suggestion": "Switch to the correct provider in the SQL bar, or replace the unsupported construct with an equivalent.",
+ "errorDiagnostics.unknown.label": "Unexpected error",
+ "errorDiagnostics.unknown.friendly": "An error occurred while running the preview query.",
+ "errorDiagnostics.unknown.suggestion": "Check the technical details below and verify that your canvas is configured correctly.",
+ "error.mainWindow.invalidDataContext": "DataContext MainWindow должен быть ShellViewModel.",
+ "error.mainWindow.canvasNotInitialized": "CanvasViewModel не был инициализирован.",
+ "error.mainWindow.ddlPreviewUnavailable": "DDL-предпросмотр недоступен для текущего canvas.",
+ "themeJson.editor.template": "{\n \"meta\": { \"name\": \"Пользовательская тема\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
+ "themeJson.error.pasteBeforeApply": "Вставьте JSON темы перед применением.",
+ "themeJson.error.invalidJson": "Некорректный JSON: {0}",
+ "themeJson.error.emptyPayload": "Некорректный JSON: пустой payload.",
+ "themeJson.error.invalidTheme": "Некорректная тема: {0}",
+ "themeJson.error.appliedButSaveFailed": "Тема применена, но не удалось сохранить: {0}",
+ "themeJson.success.appliedAndSaved": "JSON-тема применена и сохранена.",
+ "themeJson.success.customRemoved": "Пользовательская тема удалена. Перезапустите приложение для полного возврата к теме по умолчанию.",
+ "themeJson.error.restoreDefaultFailed": "Не удалось восстановить тему по умолчанию: {0}",
+ "themeValidator.error.configNull": "Конфигурация темы пуста.",
+ "themeValidator.warning.noSections": "В теме нет разделов цветов или типографики; применять нечего.",
+ "themeValidator.warning.invalidColor": "{0} содержит некорректный цвет '{1}'. Этот ключ будет проигнорирован.",
+ "themeValidator.warning.sizeOutOfRange": "{0}={1} вне диапазона (8..48). Этот ключ будет проигнорирован.",
+ "queryExecutor.error.openConnectionMethodNotFound": "Не удалось найти метод OpenConnectionAsync в оркестраторе",
+ "queryExecutor.error.openConnectionInvokeFailed": "Не удалось вызвать OpenConnectionAsync",
+ "ddlImporter.warning.viewSelectNotReconstructable": "View '{0}': SELECT представления нельзя визуально восстановить — отредактируйте вручную в subcanvas.",
+ "ddlImporter.error.tableNotFoundInMetadata": "Таблица '{0}' не найдена в текущих метаданных.",
+ "main.window.untitled": "Без названия",
+ "main.subEditor.noSeedProvided": "Для {0} не предоставлен seed подредактора.",
+ "main.layerOrder.bringToFront": "На передний план",
+ "main.layerOrder.sendToBack": "На задний план",
+ "main.layerOrder.bringForward": "Поднять слой",
+ "main.layerOrder.sendBackward": "Опустить слой",
+ "main.layerOrder.normalizeLayers": "Нормализовать слои",
+ "export.fileType.html": "Файлы HTML",
+ "export.fileType.json": "Файлы JSON",
+ "export.fileType.csv": "Файлы CSV",
+ "export.fileType.excel": "Файлы Excel",
+ "commandPalette.templatePrefix": "Шаблон: {0}",
+ "themeLoader.status.notFoundWithPath": "Файл темы не найден: {0}",
+ "themeLoader.status.deserializedNull": "JSON темы десериализован в null.",
+ "themeLoader.status.loaded": "JSON темы успешно загружен.",
+ "credential.error.ciphertextTooShort": "Блок шифртекста слишком короткий.",
+ "credential.error.dpapiWindowsOnly": "DPAPI доступен только в Windows.",
+ "credential.warning.loadVaultFailed": "Не удалось загрузить хранилище учетных данных {0}: {1}",
+ "credential.warning.persistVaultFailed": "Не удалось сохранить хранилище учетных данных {0}: {1}",
+ "snippetStore.warning.loadFailed": "Не удалось загрузить сниппеты из {0}: {1}",
+ "snippetStore.warning.saveFailed": "Не удалось сохранить сниппеты: {0}",
+ "flowVersionStore.warning.loadFailed": "Не удалось загрузить версии потока из {0}: {1}",
+ "flowVersionStore.warning.saveFailed": "Не удалось сохранить версии потока: {0}",
+ "queryExecutor.error.queryEmpty": "Запрос не может быть пустым",
+ "queryExecutor.error.providerNotSupported": "Провайдер {0} не поддерживается",
+ "queryExecutor.error.singleStatementOnly": "Предпросмотр принимает только один SQL-оператор.",
+ "queryExecutor.error.queryEmptyWithPeriod": "Запрос не может быть пустым.",
+ "queryExecutor.error.readOnlyOnly": "Режим предпросмотра поддерживает только SQL-запросы только для чтения.",
+ "queryExecutor.error.namedParametersNotSupported": "Режим предпросмотра не поддерживает именованные параметры в SQL. Используйте безопасные литералы inline или выполните запрос вне предпросмотра.",
+ "queryExecutor.error.positionalParametersNotSupported": "Режим предпросмотра не поддерживает позиционные плейсхолдеры (? или ).",
+ "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "Выровнять выбранные узлы по нижнему краю",
+ "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "Выровнять выбранные узлы по левому краю",
+ "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "Выровнять выбранные узлы по правому краю",
+ "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "Выровнять выбранные узлы по верхнему краю",
+ "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "Применить изменения подхолста CTE и вернуться на родительский холст",
+ "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "Автоматически расположить узлы по логическим колонкам",
+ "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "Центрировать выбранные узлы по горизонтали",
+ "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "Центрировать выбранные узлы по вертикали",
+ "commandPalette.description.clear_canvas_and_start_fresh": "Очистить холст и начать заново",
+ "commandPalette.description.clear_node_selection": "Снять выделение узлов",
+ "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "Преобразовать алиасы по правилу, заданному в настройках проекта",
+ "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "Создавать контрольные точки, сравнивать версии и восстанавливать предыдущее состояние холста",
+ "commandPalette.description.delete_the_selected_nodes": "Удалить выбранные узлы",
+ "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "Отменить изменения в подредакторе и вернуться на родительский холст",
+ "commandPalette.description.execute_the_current_query_in_preview": "Выполнить текущий запрос в предпросмотре",
+ "commandPalette.description.fit_all_nodes_into_the_visible_area": "Уместить все узлы в видимой области",
+ "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "Сгенерировать CSV из первого узла экспорта CSV",
+ "commandPalette.description.generate_html_file_from_the_first_html_export_node": "Сгенерировать HTML из первого узла экспорта HTML",
+ "commandPalette.description.generate_json_file_from_the_first_json_export_node": "Сгенерировать JSON из первого узла экспорта JSON",
+ "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "Сгенерировать книгу XLSX из первого узла экспорта Excel",
+ "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "Проверить план выполнения запроса: типы сканирования, стратегии join и оценки стоимости",
+ "commandPalette.description.load_a_vsaq_canvas_file": "Загрузить файл холста .vsaq",
+ "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "Измерить avg / median / p95 задержку текущего SQL за N итераций",
+ "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "Открыть изолированный редактор подхолста для выбранного узла определения CTE",
+ "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "Открыть локальную историю версий, создаваемую при сохранении, и восстановить предыдущие снимки",
+ "commandPalette.description.open_output_preview_modal_for_the_active_mode": "Открыть модальное окно предпросмотра вывода для активного режима",
+ "commandPalette.description.open_shortcut_reference_screen": "Открыть экран справки по горячим клавишам",
+ "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "Открыть менеджер подключений для добавления, редактирования и переключения БД-подключений",
+ "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "Вставить SELECT и автоматически сгенерировать узлы — поддерживаются FROM, JOIN, WHERE, LIMIT",
+ "commandPalette.description.remove_all_nodes_not_connected_to_output": "Удалить все узлы, не подключенные к выходу",
+ "commandPalette.description.reset_zoom_and_pan_to_default": "Сбросить масштаб и смещение к значениям по умолчанию",
+ "commandPalette.description.save_canvas_to_a_new_file": "Сохранить холст в новый файл",
+ "commandPalette.description.save_current_canvas": "Сохранить текущий холст",
+ "commandPalette.description.save_markdown_documentation_of_the_current_flow": "Сохранить Markdown-документацию текущего потока",
+ "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "Сохранить выбранные узлы как переиспользуемый сниппет и вставить позже через меню поиска узлов (⇧A)",
+ "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "Проверить все исходные табличные узлы на холсте на возможные связи join по FK-конвенциям и шаблонам имен",
+ "commandPalette.description.select_all_nodes_on_canvas": "Выбрать все узлы на холсте",
+ "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "Привязать позиции узлов к сетке 16px (Ctrl+G)",
+ "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "Распределить выбранные узлы с равным горизонтальным интервалом",
+ "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "Распределить выбранные узлы с равным вертикальным интервалом",
+ "commandPalette.description.zoom_into_the_canvas": "Увеличить холст",
+ "commandPalette.description.zoom_out_of_the_canvas": "Уменьшить холст",
+ "commandPalette.name.align_bottom": "Выровнять по низу",
+ "commandPalette.name.align_left": "Выровнять по левому краю",
+ "commandPalette.name.align_right": "Выровнять по правому краю",
+ "commandPalette.name.align_top": "Выровнять по верху",
+ "commandPalette.name.analyze_all_joins": "Анализировать все JOIN",
+ "commandPalette.name.auto_fix_naming": "Автоисправление имен",
+ "commandPalette.name.auto_layout": "Авторазмещение",
+ "commandPalette.name.center_horizontally": "Центрировать по горизонтали",
+ "commandPalette.name.center_vertically": "Центрировать по вертикали",
+ "commandPalette.name.cleanup_orphans": "Очистить сироты",
+ "commandPalette.name.delete_selected": "Удалить выделенные",
+ "commandPalette.name.deselect_all": "Снять выделение",
+ "commandPalette.name.discard_and_exit_editor": "Отменить и выйти из редактора",
+ "commandPalette.name.distribute_horizontally": "Распределить по горизонтали",
+ "commandPalette.name.distribute_vertically": "Распределить по вертикали",
+ "commandPalette.name.edit_selected_cte": "Редактировать выбранный CTE",
+ "commandPalette.name.exit_cte_editor": "Выйти из редактора CTE",
+ "commandPalette.name.explain_plan": "План выполнения",
+ "commandPalette.name.export_csv": "Экспорт CSV",
+ "commandPalette.name.export_documentation": "Экспорт документации",
+ "commandPalette.name.export_excel": "Экспорт Excel",
+ "commandPalette.name.export_html": "Экспорт HTML",
+ "commandPalette.name.export_json": "Экспорт JSON",
+ "commandPalette.name.file_save_load_history": "История сохранений/загрузок",
+ "commandPalette.name.fit_to_screen": "Уместить на экран",
+ "commandPalette.name.flow_version_history": "История версий потока",
+ "commandPalette.name.import_sql_to_graph": "Импорт SQL в граф",
+ "commandPalette.name.keyboard_shortcuts": "Горячие клавиши",
+ "commandPalette.name.manage_connections": "Управление подключениями",
+ "commandPalette.name.new_canvas": "Новый canvas",
+ "commandPalette.name.open_file": "Открыть файл",
+ "commandPalette.name.reset_viewport": "Сбросить область просмотра",
+ "commandPalette.name.run_preview": "Запустить предпросмотр",
+ "commandPalette.name.run_query_benchmark": "Запустить бенчмарк запроса",
+ "commandPalette.name.save": "Сохранить",
+ "commandPalette.name.save_as": "Сохранить как",
+ "commandPalette.name.save_selection_as_snippet": "Сохранить выделение как сниппет",
+ "commandPalette.name.select_all": "Выделить все",
+ "commandPalette.name.toggle_preview": "Переключить предпросмотр",
+ "commandPalette.name.toggle_snap_to_grid": "Переключить привязку к сетке",
+ "commandPalette.name.zoom_in": "Увеличить",
+ "commandPalette.name.zoom_out": "Уменьшить",
+ "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 percent restore zoom pan viewport",
+ "commandPalette.tags.align_bottom_edge_selection_nodes": "align bottom edge selection nodes",
+ "commandPalette.tags.align_center_middle_horizontal_nodes": "align center middle horizontal nodes",
+ "commandPalette.tags.align_center_middle_vertical_nodes": "align center middle vertical nodes",
+ "commandPalette.tags.align_left_edge_selection_nodes": "align left edge selection nodes",
+ "commandPalette.tags.align_right_edge_selection_nodes": "align right edge selection nodes",
+ "commandPalette.tags.align_top_edge_selection_nodes": "align top edge selection nodes",
+ "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout view reset zoom",
+ "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark performance latency timing profile measure speed",
+ "commandPalette.tags.clear_selection": "clear selection",
+ "commandPalette.tags.connection_database_server_host_provider_switch": "connection database server host provider switch",
+ "commandPalette.tags.create_insert_search_transform": "create insert search transform",
+ "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas exit apply back",
+ "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte view subcanvas discard exit force",
+ "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursive editor subgraph subcanvas isolate",
+ "commandPalette.tags.data_results_table_panel": "data results table panel",
+ "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribute space equal horizontal nodes",
+ "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribute space equal vertical nodes",
+ "commandPalette.tags.execute_run_sql_query_results": "execute run sql query results",
+ "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan execution cost scan index join performance",
+ "commandPalette.tags.export_csv_file_tabular_output_save": "export csv file tabular output save",
+ "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "export excel xlsx file tabular output spreadsheet save",
+ "commandPalette.tags.export_html_file_output_report_save": "export html file output report save",
+ "commandPalette.tags.export_json_file_output_save": "export json file output save",
+ "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "export markdown doc documentation flow save md",
+ "commandPalette.tags.export_persist_copy": "export persist copy",
+ "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "file history save load backup versions restore local",
+ "commandPalette.tags.forward_history": "forward history",
+ "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "help shortcuts hotkeys keyboard reference",
+ "commandPalette.tags.highlight_mark_all_nodes": "highlight mark all nodes",
+ "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "import sql paste convert graph reverse engineer query",
+ "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analyze suggest detect foreign key relationships heuristic",
+ "commandPalette.tags.layer_z_order_back_selected_nodes": "layer z-order back selected nodes",
+ "commandPalette.tags.layer_z_order_backward_selected_nodes": "layer z-order backward selected nodes",
+ "commandPalette.tags.layer_z_order_forward_selected_nodes": "layer z-order forward selected nodes",
+ "commandPalette.tags.layer_z_order_front_selected_nodes": "layer z-order front selected nodes",
+ "commandPalette.tags.layer_z_order_normalize_compact": "layer z-order normalize compact",
+ "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout arrange columns auto organize readability",
+ "commandPalette.tags.load_import_vsaq": "load import vsaq",
+ "commandPalette.tags.magnify_enlarge": "magnify enlarge",
+ "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "orphan unused disconnected clean delete nodes",
+ "commandPalette.tags.persist_write_disk": "persist write disk",
+ "commandPalette.tags.remove_erase_nodes": "remove erase nodes",
+ "commandPalette.tags.rename_alias_fix_naming_convention": "rename alias fix naming convention",
+ "commandPalette.tags.reset_clear_blank": "reset clear blank",
+ "commandPalette.tags.revert_back_history": "revert back history",
+ "commandPalette.tags.shrink_reduce": "shrink reduce",
+ "commandPalette.tags.snap_grid_align_precision_position": "snap grid align precision position",
+ "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet save selection reuse template favorite bookmark",
+ "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "version history checkpoint diff restore snapshot compare undo flow",
+ "sqlEditor.diffPreview.title": "Transactional Diff Preview",
+ "sqlEditor.mutation.confirmExecute": "Confirm Execute",
+ "sqlEditor.tab.closeAnyway": "Close Anyway",
+ "sqlEditor.tab.keepTab": "Keep Tab",
+ "sqlEditor.status.ready": "Ready.",
+ "sqlEditor.telemetry.none": "No execution telemetry yet.",
+ "sqlEditor.telemetry.summary": "Statements: {0} Success: {1} Failed: {2} Total: {3} ms",
+ "sqlEditor.telemetry.errors.none": "No aggregated errors.",
+ "sqlEditor.diff.none": "No transactional diff preview available.",
+ "sqlEditor.mutation.estimate.none": "No mutation estimate available.",
+ "sqlEditor.mutation.estimate.value": "Estimated affected rows: {0}",
+ "sqlEditor.mutation.estimate.unavailable": "Could not estimate affected rows automatically.",
+ "sqlEditor.tab.closePending": "Unsaved changes detected. Confirm tab close.",
+ "sqlEditor.tab.noPendingClose": "No tab close pending.",
+ "sqlEditor.tab.manyWarning": "High tab count: {0} open tabs.",
+ "sqlEditor.mutation.pending.none": "No pending mutation confirmation.",
+ "sqlEditor.mutation.pending.required": "Mutation requires confirmation before execution.",
+ "sqlEditor.message.empty": "Execute a statement to see messages.",
+ "sqlEditor.message.success": "Execution completed successfully.",
+ "sqlEditor.result.summary.empty": "Rows: - Time: -",
+ "sqlEditor.result.summary": "Rows: {0} Time: {1} ms",
+ "sqlEditor.file.save.canceled": "Save canceled.",
+ "sqlEditor.file.save.noPath": "No target path selected.",
+ "sqlEditor.file.save.success": "SQL file saved.",
+ "sqlEditor.file.save.failed": "Save failed.",
+ "sqlEditor.file.open.failed": "Open failed.",
+ "sqlEditor.file.open.notFound": "Selected SQL file was not found.",
+ "sqlEditor.file.open.success": "SQL file opened.",
+ "sqlEditor.status.executing": "Executing SQL...",
+ "sqlEditor.status.executingScript": "Executing SQL script...",
+ "sqlEditor.status.executingStep": "Executing {0}/{1}...",
+ "sqlEditor.status.canceling": "Canceling execution...",
+ "sqlEditor.status.executingConfirmedMutation": "Executing confirmed mutation...",
+ "sqlEditor.status.mutationCanceled": "Mutation execution canceled.",
+ "sqlEditor.detail.statementNotExecuted": "Statement was not executed.",
+ "sqlEditor.status.success": "Execution succeeded.",
+ "sqlEditor.detail.rowsAndTime": "{0} row(s) in {1} ms.",
+ "sqlEditor.status.canceled": "Execution canceled.",
+ "sqlEditor.status.failed": "Execution failed.",
+ "sqlEditor.status.confirmationRequired": "Confirmation required before execution.",
+ "sqlEditor.error.mutationConfirmationRequired": "Mutation confirmation required.",
+ "sqlEditor.result.tabTitle": "Result {0}",
+ "sqlEditor.tab.closeRequiresConfirmation": "Tab close requires confirmation.",
+ "sqlEditor.tab.unsavedDetail": "This tab has unsaved changes.",
+ "sqlEditor.tab.closed": "Tab closed.",
+ "sqlEditor.tab.closeCanceled": "Tab close canceled.",
+ "sqlEditor.tab.closeCanceledDetail": "Unsaved tab kept open.",
+ "sqlEditor.error.noStatementSelected": "No SQL statement selected for execution.",
+ "sqlEditor.error.noConnection": "No active database connection for SQL execution.",
+ "sqlEditor.error.executionCanceled": "SQL execution was canceled.",
+ "sqlEditor.tab.scriptTitle": "Script {0}",
+ "sqlEditor.guard.delete.noWhere.message": "DELETE without WHERE can remove all rows.",
+ "sqlEditor.guard.delete.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
+ "sqlEditor.guard.delete.trivialWhere.message": "DELETE has a trivially true WHERE clause.",
+ "sqlEditor.guard.delete.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
+ "sqlEditor.guard.update.noWhere.message": "UPDATE without WHERE can affect all rows.",
+ "sqlEditor.guard.update.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
+ "sqlEditor.guard.update.trivialWhere.message": "UPDATE has a trivially true WHERE clause.",
+ "sqlEditor.guard.update.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
+ "sqlEditor.guard.insert.noColumnList.message": "INSERT without explicit column list is fragile against schema changes.",
+ "sqlEditor.guard.insert.noColumnList.recommendation": "Prefer INSERT INTO table(col1, col2, ...) VALUES (...).",
+ "sqlEditor.guard.ddl.message": "DDL statement may cause structural changes in the database.",
+ "sqlEditor.guard.ddl.recommendation": "Confirm execution only when schema changes are intended.",
+ "sqlEditor.diff.unavailable.noPreview": "No transactional diff preview available for this statement.",
+ "sqlEditor.diff.unavailable.parseError": "Could not parse mutation target for transactional diff preview.",
+ "sqlEditor.diff.unavailable.connection": "Transactional diff preview unavailable due to connection or query limitations.",
+ "sqlEditor.diff.deleteSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, affected {2}, total rows after {3}.",
+ "sqlEditor.diff.updateSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, candidate rows affected {2}, total rows after {3}.",
+ "sqlEditor.diff.unavailable.unsupportedStatement": "Transactional diff preview currently supports UPDATE and DELETE only.",
+ "sqlEditor.results.title": "Results",
+ "sqlEditor.saveSql.fileType": "SQL Files",
+ "sqlEditor.saveSql.pickerTitle": "Save SQL File",
+ "sqlEditor.export.pickerTitle": "Export SQL Data",
+ "sqlEditor.export.status.noResultTitle": "No execution result available for export.",
+ "sqlEditor.export.status.noResultDetail": "Execute a query first.",
+ "sqlEditor.export.status.successTitle": "Report exported.",
+ "sqlEditor.export.status.failedTitle": "Failed to export report.",
+ "sqlEditor.export.fileType.html": "HTML File",
+ "sqlEditor.export.fileType.json": "JSON File",
+ "sqlEditor.export.fileType.csv": "CSV File",
+ "sqlEditor.export.fileType.xlsx": "Excel Workbook",
+ "sqlEditor.export.defaultFileBase": "report",
+ "sqlEditor.export.defaultTitle": "SQL Report",
+ "sqlEditor.export.error.typeRequired": "A report type must be selected before export.",
+ "sqlEditor.export.type.html.title": "HTML full-feature report",
+ "sqlEditor.export.type.html.description": "Standalone, SQL-first HTML artifact for offline audit.",
+ "sqlEditor.export.type.json.title": "JSON execution contract",
+ "sqlEditor.export.type.json.description": "Machine-readable payload with SQL, metadata and execution result.",
+ "sqlEditor.export.type.csv.title": "CSV data export",
+ "sqlEditor.export.type.csv.description": "Tabular result data only, suitable for spreadsheet tools.",
+ "sqlEditor.export.type.xlsx.title": "Excel workbook export",
+ "sqlEditor.export.type.xlsx.description": "Spreadsheet workbook with query result data only.",
+ "sqlEditor.export.dialog.windowTitle": "Export SQL Data",
+ "sqlEditor.export.dialog.title": "Export SQL Data",
+ "sqlEditor.export.dialog.subtitle": "Choose the artifact format and metadata before exporting.",
+ "sqlEditor.export.dialog.confirm": "Export",
+ "sqlEditor.export.dialog.fileNameWatermark": "report.html",
+ "sqlEditor.export.dialog.titleWatermark": "SQL Report",
+ "sqlEditor.export.dialog.descriptionWatermark": "Additional context for auditors and teammates.",
+ "sqlEditor.export.dialog.section.reportType": "REPORT TYPE",
+ "sqlEditor.export.dialog.section.fileName": "FILE NAME",
+ "sqlEditor.export.dialog.section.reportTitle": "TITLE",
+ "sqlEditor.export.dialog.section.description": "DESCRIPTION",
+ "sqlEditor.export.dialog.section.options": "OPTIONS",
+ "sqlEditor.export.option.includeSchema": "Include output schema",
+ "sqlEditor.export.option.includeNodeDetails": "Include node/connection placeholders in JSON",
+ "sqlEditor.export.option.includeMetadata": "Include optional metadata",
+ "sqlEditor.export.option.useDashForEmpty": "Use '-' for empty fields",
+ "sqlEditor.export.badge.offline": "OFFLINE READY",
+ "sqlEditor.export.badge.structured": "STRUCTURED PAYLOAD",
+ "sqlEditor.export.badge.dataOnly": "DATA ONLY"
+}
diff --git a/src/DBWeaver.UI/Assets/Localization/zh-TW.json b/src/AkkornStudio.UI/Assets/Localization/zh-TW.json
similarity index 98%
rename from src/DBWeaver.UI/Assets/Localization/zh-TW.json
rename to src/AkkornStudio.UI/Assets/Localization/zh-TW.json
index a96e8267..8c4c410a 100644
--- a/src/DBWeaver.UI/Assets/Localization/zh-TW.json
+++ b/src/AkkornStudio.UI/Assets/Localization/zh-TW.json
@@ -1,1057 +1,1057 @@
-{
- "main.brand": "DBWeaver",
- "main.tab.query1": "Query 1",
- "main.new": "New",
- "main.open": "Open",
- "main.save": "Save",
- "main.history": "History",
- "main.layout": "Layout",
- "main.preview": "Preview",
- "main.undo": "Undo",
- "main.redo": "Redo",
- "main.cleanupOrphans": "Cleanup orphan nodes",
- "main.autoFixAliasNaming": "Auto-fix alias naming",
- "main.autoLayoutCanvas": "Auto layout canvas",
- "main.toggleDataPreview": "Toggle data preview",
- "main.language": "Language",
- "main.restore.prompt": "Previous session found — restore the last canvas?",
- "main.restore.button": "Restore session",
- "main.cteEditor.editingPrefix": "Editing CTE: ",
- "main.cteEditor.backToCanvas": "Back to Canvas",
- "main.cteEditor.exitA11y": "Exit CTE editor",
- "main.viewEditor.editingPrefix": "DDL > View: ",
- "main.viewEditor.backToCanvas": "Back to DDL",
- "main.viewEditor.exitA11y": "Exit view editor",
- "connection.title": "Connection Manager",
- "connection.subtitle": "不中斷流程即可設定、測試與啟用連線",
- "connection.none": "No connection",
- "connection.active": "ACTIVE",
- "connection.health.online": "Online",
- "connection.health.degraded": "Degraded",
- "connection.health.offline": "Offline",
- "connection.tooltip.none": "No active connection — click to manage",
- "connection.ping": "Ping",
- "connection.saved": "SAVED CONNECTIONS",
- "connection.new": "New Connection",
- "connection.selectOrCreate": "Select a connection or create a new one",
- "connection.name": "Connection Name",
- "connection.provider": "Provider",
- "connection.host": "Host",
- "connection.port": "Port",
- "connection.database": "Database",
- "connection.sqlitePath": "SQLite Path",
- "connection.sqliteBrowse": "Browse",
- "connection.sqliteCreate": "Create",
- "connection.username": "Username",
- "connection.password": "Password",
- "connection.timeout": "Timeout (seconds)",
- "connection.test": "Test",
- "connection.save": "Save",
- "connection.connect": "Connect",
- "connection.action.testConnection": "Test connection",
- "connection.action.saveConnection": "Save connection",
- "connection.action.connectConnection": "Connect connection",
- "connection.status.connecting": "連線中...",
- "connection.status.connected": "已連線",
- "connection.status.testing": "測試中...",
- "connection.status.failedPrefix": "連線失敗",
- "connection.status.metadataUnavailable": "連線失敗:中繼資料不可用。",
- "connection.status.highLatency": "高延遲",
- "connection.watermark.name": "我的正式環境資料庫",
- "connection.watermark.host": "localhost",
- "connection.watermark.port": "5432",
- "connection.watermark.database": "database_name",
- "connection.watermark.username": "user",
- "connection.watermark.password": "••••••••",
- "connection.watermark.timeout": "30",
- "main.connectingDb": "Connecting to database...",
- "main.emptyHint": "Press ⇧A to add your first node, or drag a table from the sidebar",
- "status.nodesSeparator": " nodes · ",
- "status.connectionsSuffix": " connections",
- "status.undo": "Undo: ",
- "status.shortcuts": "⇧A Nodes · F3 Preview · Ctrl+Z Undo · Del Remove · Alt+Drag Pan",
- "connection.disconnect": "Disconnect",
- "connection.action.disconnectConnection": "Disconnect connection",
- "connectionTab.active": "ACTIVE CONNECTION",
- "connectionTab.none": "No active connection",
- "connectionTab.saved": "SAVED CONNECTIONS",
- "connectionTab.new": "+ New Connection",
- "schema.database": "DATABASE",
- "schema.search": "Search tables, columns...",
- "schema.loading": "Searching tables, columns...",
- "schema.noConnection": "No Connection",
- "schema.noConnectionHint": "Connect to a database to see tables, columns, and relationships",
- "schema.emptyNoTables": "No tables found",
- "fileHistory.title": "Save/Load Version History",
- "fileHistory.reload": "Reload",
- "fileHistory.restoreSelected": "Restore selected",
- "fileHistory.empty": "No local versions yet",
- "fileHistory.emptyHint": "Save this file to generate version history.",
- "preview.title": "Data Preview",
- "preview.subtitle": "Review data and diagnostics before continuing",
- "preview.run": "Run",
- "preview.cancel": "Cancel",
- "preview.tab.preview": "Preview",
- "preview.tab.sql": "SQL",
- "preview.close": "Close preview",
- "preview.running": "Running preview query… ",
- "preview.clickCancel": "Click Cancel to stop",
- "preview.cancelled": "Query cancelled",
- "preview.runAgain": "Press Run to execute again",
- "preview.failed": "Preview execution failed",
- "preview.technical": "TECHNICAL DETAILS",
- "preview.noData": "No data yet",
- "preview.f3Hint": "Press F3 or Space to run the current query",
- "sqlImporter.title": "Import SQL to Graph",
- "sqlImporter.subtitle": "Paste a SELECT statement — nodes are created automatically",
- "sqlImporter.sqlStatement": "SQL STATEMENT",
- "sqlImporter.supported": "Supported: ",
- "sqlImporter.import": "Import",
- "sqlImporter.report": "CONVERSION REPORT",
- "sqlEditor.mutation.dialogTitle": "變更確認",
- "sqlEditor.mutation.dialogSubtitle": "在確認執行前請先檢視影響",
- "search.empty": "No nodes found",
- "search.emptyHint": "Try searching for UPPER, JSON, CAST, AND…",
- "search.shortcut": "⇧A",
- "search.spawn": "Spawn",
- "commandPalette.empty": "沒有符合搜尋的命令",
- "commandPalette.search": "命令搜尋",
- "commandPalette.shortcut": "CTRL+SHIFT+P",
- "commandPalette.execute": "執行",
- "context.editCte": "Edit Selected CTE",
- "context.editViewSubcanvas": "Edit View Subcanvas",
- "explain.title": "Explain Plan",
- "explain.sql": "SQL",
- "explain.option.analyze": "分析",
- "explain.option.buffers": "緩衝區",
- "explain.badge.simulated": "模擬",
- "explain.timing.planning": "規劃:",
- "explain.timing.execution": "執行:",
- "explain.section.snapshotComparison": "快照比較",
- "explain.section.indexRecommendations": "索引建議",
- "explain.section.history": "歷程",
- "explain.detail.estimated": "估計",
- "explain.detail.actual": "實際",
- "explain.detail.error": "誤差",
- "explain.detail.time": "時間",
- "explain.detail.loops": "迴圈",
- "explain.rerun": "Re-run",
- "explain.alertSuffix": " expensive operation(s) detected — consider adding indexes",
- "explain.running": "Running EXPLAIN…",
- "explain.failed": "⚠ EXPLAIN failed",
- "explain.noPlan": "No plan yet",
- "explain.rerunHint": "Press Re-run to execute EXPLAIN",
- "explain.header.operation": "操作",
- "explain.header.cost": "成本",
- "explain.header.rows": "資料列",
- "explain.header.alert": "警示",
- "explain.mode.list": "清單",
- "explain.mode.tree": "樹狀",
- "explain.action.snapshot": "儲存快照",
- "explain.action.copyJson": "複製 JSON",
- "explain.action.copyText": "複製文字",
- "explain.action.saveJson": "儲存 .json",
- "explain.action.openDalibo": "在 Dalibo 開啟",
- "explain.legend.seqscan": "SEQ SCAN — full table read, no index",
- "explain.legend.sort": "SORT — in-memory sort",
- "explain.legend.hash": "HASH — hash join",
- "explain.escClose": "Esc to close",
- "flowVersion.title": "Flow Version History",
- "flowVersion.subtitle": "Create checkpoints, compare versions and restore",
- "flowVersion.watermark": "Checkpoint label (optional)…",
- "flowVersion.saveCheckpoint": "Save Checkpoint",
- "flowVersion.compareMode": "Compare Mode",
- "flowVersion.selectBase": "Select BASE version (from):",
- "flowVersion.clickAny": "Then click any version in the list below to compare.",
- "flowVersion.noCheckpoints": "No checkpoints yet",
- "flowVersion.noCheckpointsHint": "Save a checkpoint above to begin tracking versions.",
- "flowVersion.restore": "Restore",
- "flowVersion.diffResults": "Diff Results",
- "benchmark.title": "Query Benchmark",
- "benchmark.subtitle": "Measures avg / median / p95 latency over N iterations",
- "benchmark.sql": "SQL being benchmarked",
- "benchmark.runLabel": "Run label",
- "benchmark.runLabelWatermark": "Run 1",
- "benchmark.iterations": "Iterations (1–100)",
- "benchmark.warmup": "Warm-up passes (0–10)",
- "benchmark.interval": "Interval between runs (ms)",
- "benchmark.run": "Run Benchmark",
- "benchmark.cancel": "Cancel",
- "benchmark.clearHistory": "Clear History",
- "benchmark.latest": "LATEST RESULT",
- "benchmark.avg": "AVG",
- "benchmark.median": "MEDIAN",
- "benchmark.min": "MIN",
- "benchmark.max": "MAX",
- "benchmark.iterationsAt": " iterations · run at ",
- "benchmark.history": "HISTORY",
- "benchmark.header.label": "標籤",
- "benchmark.header.avg": "平均",
- "benchmark.header.median": "中位數",
- "benchmark.header.min": "最小",
- "benchmark.header.max": "最大",
- "benchmark.itersSuffix": " iters",
- "diagnostics.title": "App Diagnostics",
- "diagnostics.run": "Run",
- "diagnostics.running": "Running checks…",
- "diagnostics.ok": "OK",
- "diagnostics.warning": "Warning",
- "diagnostics.error": "Error",
- "diagnostics.tooltip.rerun": "Re-run all checks",
- "diagnostics.tooltip.copy": "Copy diagnostic report to clipboard",
- "diagnostics.tooltip.close": "Close (Esc)",
- "autoJoin.title": "Auto-Join Suggestions",
- "autoJoin.titleForTable": "Auto-Join suggestions for {0}",
- "autoJoin.acceptAll": "Accept All",
- "autoJoin.accept": "Accept",
- "autoJoin.skip": "Skip",
- "autoJoin.allHandled": "All suggestions handled",
- "autoJoin.joinKeyword": "JOIN",
- "autoJoin.confidence.fkConstraint": "FK Constraint",
- "autoJoin.confidence.fkReverse": "FK (Reverse)",
- "autoJoin.confidence.namingMatch": "Naming Match",
- "autoJoin.confidence.weakMatch": "Weak Match",
- "autoJoin.runSelected": "Auto-Join Selected",
- "autoJoin.noSimilarityTitle": "No automatic join found",
- "autoJoin.noSimilarityDetails": "Choose the columns manually to create a simple join.",
- "autoJoin.appliedTitle": "Auto-join applied",
- "autoJoin.manual.title": "Create Manual Join",
- "autoJoin.manual.subtitle": "No reliable similarity was found. Select one column from each table.",
- "autoJoin.manual.leftColumn": "Left column",
- "autoJoin.manual.rightColumn": "Right column",
- "autoJoin.manual.joinType": "Join type",
- "autoJoin.manual.operator": "Operator",
- "autoJoin.manual.confirm": "Create join",
- "autoJoin.manual.noCompatible": "No compatible columns for the selected left pin type.",
- "autoJoin.manualJoinCreatedTitle": "Manual join created",
- "autoJoin.manualJoinFailedTitle": "Manual join could not be created",
- "autoJoin.manualJoinFailedDetails": "Check selected columns and existing joins, then try again.",
- "autoJoin.multipleCandidatesTitle": "Multiple join candidates found",
- "autoJoin.multipleCandidatesDetails": "{0} possible combinations were found. Confirm which columns should be used.",
- "autoJoin.suggestionsFoundTitle": "Auto-join suggestions available",
- "autoJoin.suggestionsFoundDetails": "{0} suggestion(s) found. Select two tables and run Auto-Join Selected.",
- "property.outputAlias": "OUTPUT ALIAS",
- "property.sourceAlias": "SOURCE ALIAS",
- "property.aliasWatermark": "e.g. MyColumn (optional)",
- "property.parameters": "PARAMETERS",
- "property.enabled": "Enabled",
- "property.datetimeWatermark": "YYYY-MM-DDTHH:mm:ss or leave empty",
- "property.dateWatermark": "YYYY-MM-DD or leave empty",
- "property.apply": "Apply",
- "property.inputPins": "INPUT PINS",
- "property.outputPins": "OUTPUT PINS",
- "property.sqlTrace": "SQL TRACE",
- "property.live": "live",
- "node.numericValue": "Numeric Value",
- "node.stringValue": "String Value",
- "node.enterText": "Enter text",
- "node.datetimeValue": "DateTime Value",
- "node.valueLabel": "Value:",
- "node.noInputs": "No inputs",
- "node.loadingSample": "Loading sample…",
- "node.previewFailed": "⚠ Preview failed",
- "node.sampleRowsHint": "5 sample rows · demo data",
- "sidebar.tab.nodes": "節點",
- "sidebar.tab.connection": "連線",
- "sidebar.tab.schema": "結構",
- "sidebar.tab.diagnostics": "診斷",
- "sidebar.addNode": "+ Add Node (⇧A)",
- "sidebar.previewF3": "Preview (F3)",
- "nodesList.search": "Search nodes...",
- "search.watermark": "Search nodes… (Esc to close)",
- "search.snippets": "★ SNIPPETS",
- "commandPalette.watermark": "執行命令…(Esc 關閉)",
- "tooltip.newCanvas": "New canvas (Ctrl+N)",
- "tooltip.openCanvas": "Open canvas (Ctrl+O)",
- "tooltip.saveCanvas": "Save canvas (Ctrl+S)",
- "tooltip.fileHistory": "Local save/load history (Ctrl+Alt+H)",
- "tooltip.zoomOut": "Zoom out (Ctrl+-)",
- "tooltip.zoomIn": "Zoom in (Ctrl++)",
- "tooltip.fitToScreen": "Fit to screen (Ctrl+0)",
- "tooltip.autoLayout": "Auto Layout — arrange nodes into logical columns (Ctrl+L, Ctrl+Z to undo)",
- "tooltip.snapToGrid": "Toggle snap to grid (Ctrl+G)",
- "tooltip.dataPreview": "Data preview (F3)",
- "tooltip.toggleLanguage": "Toggle language (pt-BR / en-US)",
- "tooltip.appDiagnostics": "App Diagnostics (self-check)",
- "tooltip.keyboardShortcuts": "Keyboard shortcuts (F1)",
- "tooltip.cancelRunningQuery": "Cancel the running query",
- "tooltip.closeEsc": "Close (Esc)",
- "tooltip.recheckConnectionHealth": "Re-check connection health",
- "tooltip.deleteConnection": "Delete connection",
- "tooltip.testConnection": "Test connection",
- "tooltip.saveConnection": "Save connection",
- "tooltip.activateConnection": "Activate this connection",
- "tooltip.toggleDataSamplePreview": "Toggle data sample preview",
- "tooltip.liveSqlMutatingBlocked": "This SQL contains a data-mutating command and cannot be run in Safe Preview Mode",
- "tooltip.copySql": "Copy SQL to clipboard",
- "tooltip.formatSql": "Format SQL",
- "tooltip.openBenchmark": "Open Query Benchmark (measure avg / median / p95 latency)",
- "tooltip.openExplainPlan": "Open Explain Plan inspector — visualise the query execution plan",
- "tooltip.switchToQueryMode": "Switch to Query canvas",
- "tooltip.switchToDdlMode": "Switch to DDL canvas",
- "tooltip.autoJoinSelected": "Try auto-join between the two selected tables",
- "tooltip.pins.inputs": "Inputs",
- "tooltip.pins.outputs": "Outputs",
- "tooltip.pins.none": "None",
- "tooltip.tableColumns": "Columns",
- "tooltip.tableColumns.none": "No detailed columns",
- "window.minimize": "Minimize window",
- "window.maximizeRestore": "Maximize/restore window",
- "window.close": "Close window",
- "menu.newDiagram": "New diagram",
- "menu.openFile": "Open file",
- "menu.save": "Save",
- "menu.fileHistory": "File history",
- "menu.shortcuts": "Keyboard shortcuts",
- "menu.settings": "Settings",
- "menu.importDdlSchema": "Import DDL schema",
- "menu.viewDdlSql": "View DDL SQL",
- "menu.executeDdl": "Execute DDL",
- "menu.backToStart": "Back to start",
- "toast.ddlExecuteFailed": "Failed to execute DDL.",
- "toast.ddlOpenFailed": "Failed to open DDL SQL.",
- "toast.ddlImportFailed": "Failed to import schema into DDL.",
- "toast.ddlConnectToImportSchema": "Connect to a database to import schema into the DDL canvas.",
- "toast.ddlNoTablesFound": "No tables found to import in DDL mode.",
- "toast.ddlSchemaImported": "Schema imported into the DDL canvas.",
- "toast.ddlImportSummary": "{0} table(s), {1} column(s), {2} FK(s), {3} unique index(es).",
- "toast.ddlConnectToImportTable": "Connect to a database to import tables into the DDL canvas.",
- "toast.ddlTableAlreadyExists": "Table '{0}' already exists in the DDL canvas.",
- "toast.ddlTableImported": "Table imported into the DDL canvas.",
- "toast.ddlTableImportSummary": "Nodes: +{0}, connections: +{1}, FKs: +{2}.",
- "toast.ddlNoActiveConnection": "No active connection to execute DDL.",
- "toast.ddlExecutedSuccess": "DDL executed successfully.",
- "toast.ddlExecutedWithIssues": "DDL executed with issues.",
- "toast.switchToDdl": "Switch to DDL mode to generate SQL.",
- "toast.ddlInvalid": "Invalid DDL. Fix errors before continuing.",
- "toast.ddlNoStatements": "No DDL statements were generated in the canvas.",
- "toast.previewOpenFailed": "Failed to open preview.",
- "tab.switchFailed": "Failed to switch tab: {0}",
- "settings.status.darkApplied": "Dark theme applied.",
- "settings.status.lightApplied": "Light theme applied.",
- "settings.status.snapUpdated": "Snap updated: {0}.",
- "settings.status.languageToggled": "Language toggled.",
- "settings.status.languageSelected": "Language selected: {0}.",
- "settings.status.themeEditorReady": "Theme editor ready. Apply to save and use this theme.",
- "settings.section.appearance.title": "Themes",
- "settings.section.languageRegion.title": "語言與地區",
- "settings.section.dateTime.title": "日期與時間",
- "settings.section.keyboard.title": "鍵盤快速鍵",
- "settings.section.privacy.title": "隱私",
- "settings.section.notification.title": "通知",
- "settings.section.accessibility.title": "無障礙",
- "settings.section.default.title": "設定",
- "settings.section.appearance.subtitle": "選擇你的風格或自訂主題",
- "settings.section.languageRegion.subtitle": "管理語言與地區格式",
- "settings.section.keyboard.subtitle": "自訂 command palette 與畫布執行所使用的鍵盤快速鍵。",
- "settings.section.wip.subtitle": "開發中。",
- "settings.section.default.subtitle": "應用程式設定",
- "settings.general": "General",
- "settings.nav.appearance": "Appearance",
- "settings.theme.light": "淺色模式",
- "settings.theme.dark": "深色模式",
- "settings.theme.system": "系統偏好",
- "settings.gridSnap.title": "Grid Snap",
- "settings.gridSnap.subtitle": "Controls node snapping on the canvas.",
- "settings.language.subtitle": "請選擇應用程式語言。",
- "settings.language.toggle": "切換語言",
- "settings.language.option.ptBR": "葡萄牙語(巴西)",
- "settings.language.option.enUS": "英語(美國)",
- "settings.language.option.esES": "西班牙語(西班牙)",
- "settings.language.option.ruRU": "俄語",
- "settings.language.option.jaJP": "日語",
- "settings.language.option.zhTW": "繁體中文",
- "settings.themeJson.title": "主題 JSON",
- "settings.themeJson.subtitle": "貼上你的主題 JSON,立即套用並保存。",
- "settings.themeJson.apply": "套用 JSON",
- "settings.themeJson.restoreDefault": "還原預設主題",
- "mode.query": "Query",
- "mode.ddl": "DDL",
- "sidebar.left.close": "Close left sidebar",
- "sidebar.left.open": "Reopen left sidebar",
- "sidebar.right.close": "Close right sidebar",
- "sidebar.right.open": "Reopen right sidebar",
- "connection.completedTitle": "Connection completed",
- "connection.clearCanvasPrompt": "Do you want to clear the current canvas to start with the new connection?",
- "connection.close": "Close connection manager",
- "connection.refreshHealth": "Refresh connection health",
- "common.details": "Details",
- "common.cancel": "Cancel",
- "common.keep": "Keep",
- "common.clear": "Clear",
- "zoom.out": "Zoom out",
- "zoom.in": "Zoom in",
- "zoom.fit": "Fit zoom to screen",
- "zoom.level": "Zoom level",
- "settings.theme.mode": "主題模式",
- "diagnostics.category.canvas": "Canvas Integrity",
- "diagnostics.category.output": "Output & Execution",
- "diagnostics.category.session": "Session & Safety",
- "diagnostics.category.notice": "Runtime Notices",
- "diagnostics.summary.ok": "All systems OK",
- "diagnostics.summary.warningCount": "{0} warning(s) detected",
- "diagnostics.summary.errorCount": "{0} error(s) detected",
- "diagnostics.canvasMigration": "Canvas Migration",
- "diagnostics.recommendation.resaveFile": "Re-save the file to update it to the latest schema version.",
- "diagnostics.canvasState.name": "Canvas State",
- "diagnostics.canvasState.recommendation": "Add at least one {0} and one {1}",
- "diagnostics.canvasState.empty": "Canvas is empty - no nodes present",
- "diagnostics.canvasState.counts": "{0} node(s), {1} connection(s)",
- "diagnostics.validation.name": "Validation Errors",
- "diagnostics.validation.recommendation": "Fix highlighted nodes before running output preview",
- "diagnostics.validation.errorWithWarnings": "{0} error(s) and {1} warning(s) in the graph",
- "diagnostics.validation.warningOnly": "{0} warning(s) in the graph",
- "diagnostics.validation.none": "No validation issues",
- "diagnostics.orphan.name": "Orphan Nodes",
- "diagnostics.orphan.recommendation": "Use the orphan cleanup action to remove unused nodes",
- "diagnostics.orphan.count": "{0} node(s) not connected to any output",
- "diagnostics.orphan.none": "No orphan nodes detected",
- "diagnostics.naming.name": "Naming Conventions",
- "diagnostics.naming.recommendation": "Use auto-fix alias naming when conformance is below 100%",
- "diagnostics.naming.conformance": "Naming conformance: {0}%",
- "diagnostics.naming.ok": "All aliases follow naming conventions (100%)",
- "diagnostics.queryCompilation.name": "Live SQL Compilation",
- "diagnostics.queryCompilation.recommendation": "Review SQL diagnostics in output when errors/warnings are reported.",
- "diagnostics.queryCompilation.errorFallback": "Live SQL compilation reported errors.",
- "diagnostics.queryCompilation.warningCounts": "{0} diagnostic item(s), {1} guardrail warning(s).",
- "diagnostics.queryCompilation.ok": "Live SQL compiled without diagnostics.",
- "diagnostics.previewSafety.name": "Preview Safety",
- "diagnostics.previewSafety.recommendation": "Preview executes read-only statements only.",
- "diagnostics.previewSafety.blocked": "Current SQL is mutating and blocked by Safe Preview mode.",
- "diagnostics.previewSafety.ok": "Preview safety checks passed.",
- "diagnostics.previewExecution.name": "Preview Execution",
- "diagnostics.previewExecution.recommendation": "Run preview and inspect diagnostics for execution/runtime errors.",
- "diagnostics.previewExecution.failed": "Preview execution failed.",
- "diagnostics.previewExecution.cancelled": "Preview execution was cancelled.",
- "diagnostics.previewExecution.done": "{0} row(s) in {1}ms.",
- "diagnostics.previewExecution.none": "No preview execution issues detected.",
- "diagnostics.ddlCompilation.name": "DDL Compilation",
- "diagnostics.ddlCompilation.recommendation": "Fix DDL compile diagnostics before execution.",
- "diagnostics.ddlCompilation.failed": "DDL compilation failed.",
- "diagnostics.ddlCompilation.warningCount": "{0} warning(s) reported by DDL compiler.",
- "diagnostics.ddlCompilation.ok": "DDL compilation succeeded.",
- "diagnostics.ddlOutput.name": "DDL Output",
- "diagnostics.ddlOutput.recommendation": "Add/complete DDL nodes until at least one statement is generated.",
- "diagnostics.ddlOutput.none": "No DDL statements generated yet.",
- "diagnostics.ddlOutput.lines": "{0} line(s) of DDL generated.",
- "diagnostics.undo.name": "Undo History",
- "diagnostics.undo.recommendation": "History is in-memory only; save your canvas regularly.",
- "diagnostics.undo.saved": "Canvas is saved (no unsaved changes).",
- "diagnostics.undo.unsavedDeep": "Unsaved changes with {0} undo steps.",
- "diagnostics.undo.unsaved": "Unsaved changes - {0} undo step(s) available.",
- "diagnostics.report.title": "DBWeaver - Diagnostic Report",
- "diagnostics.report.generated": "Generated",
- "diagnostics.report.overall": "Overall",
- "diagnostics.report.details": "Details",
- "diagnostics.report.recommendation": "Recommendation",
- "diagnostics.report.lastCheck": "Last Check",
- "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
- "node.datetimeFormat": "YYYY-MM-DDTHH:mm:ss",
- "preview.providerLabel": "Provider",
- "preview.ddlDiagnosticsHint": "Error/warning details are available in Diagnostics.",
- "common.navigate": "Navigate",
- "common.close": "Close",
- "common.esc": "Esc",
- "common.ms": "ms",
- "common.zero": "0",
- "diagnostics.tip": "Tip: check Diagnostics whenever preview/output reports warnings or errors.",
- "nodesList.empty": "No nodes found",
- "nodesList.emptyHint": "Adjust the search term to explore available types",
- "schema.emptyFiltered": "No objects found for the current filter",
- "start.lastSnapshot": "Last snapshot",
- "app.brandBadge": "VS",
- "property.tab.properties": "Properties",
- "property.tab.projectSettings": "Project Settings",
- "property.nodeType": "NODE TYPE",
- "property.selectNodeHint": "Select a node to edit its properties.",
- "property.namingConventions": "Naming Conventions",
- "property.aliasConvention": "Alias convention",
- "property.enforceAliasNaming": "Enforce alias naming",
- "property.warnReservedSql": "Warn on reserved SQL keywords",
- "property.maxAliasLength": "Max alias length",
- "property.maxAliasLengthDefault": "64",
- "property.namingSettingsHint": "These settings are project-scoped and are used by naming and validation helpers.",
- "start.tips": "Tips",
- "start.tips.quick": "Quick tips",
- "start.tips.item1": "1. Click New Diagram to start from scratch.",
- "start.tips.item2": "2. Use templates to speed up prototyping.",
- "start.tips.item3": "3. Open saved connections to load real tables.",
- "start.tips.shortcut": "Shortcut: CTRL+SHIFT+P opens the command palette.",
- "start.workspace": "WORKSPACE",
- "start.resumeTitle": "Continue where you left off",
- "start.resumeSubtitle": "Quickly resume a recent project or start a new diagram.",
- "start.chip.quickFlow": "Quick flow",
- "start.chip.templates": "Templates",
- "start.chip.connections": "Connections",
- "start.savedConnectionsTitle": "Saved Connections",
- "start.savedConnectionsSubtitle": "Connect quickly to a database to load schema and tables.",
- "start.noConnectionsTitle": "No connections configured yet",
- "start.noConnectionsSubtitle": "Create a connection to explore real tables in the editor.",
- "start.newConnection": "+ New Connection",
- "start.recentProjectsTitle": "Recent Projects",
- "start.searchRecent": "Search recent project...",
- "start.quickActions": "Quick actions",
- "start.quickActionsSubtitle": "Open an existing file or start a new diagram.",
- "start.noRecentTitle": "No recent projects yet",
- "start.noRecentSubtitle": "Use the quick actions card above to get started.",
- "start.exploreTemplates": "Explore templates",
- "start.templatesFavoritesHint": "Favorites on top",
- "start.favoriteTemplate": "Favorite template",
- "node.columnSetPreview": "ColumnSet preview",
- "node.view": "VIEW",
- "node.tableDefinition": "Table Definition",
- "node.join": "JOIN",
- "node.window.addPartition": "Add PARTITION BY slot",
- "node.window.removePartition": "Remove PARTITION BY slot",
- "node.window.addOrder": "Add ORDER BY slot",
- "node.window.removeOrder": "Remove ORDER BY slot",
- "sql.keyword.select": "SELECT",
- "sql.keyword.from": "FROM",
- "sql.keyword.join": "JOIN",
- "sql.keyword.where": "WHERE",
- "sql.keyword.limit": "LIMIT",
- "sqlImporter.close": "Close SQL importer",
- "sqlImporter.report.imported": "Imported",
- "sqlImporter.report.partial": "Partial",
- "sqlImporter.report.skipped": "Skipped",
- "benchmark.close": "Close benchmark",
- "benchmark.p95": "P95",
- "benchmark.n": "N",
- "liveSql.safePreview": "SAFE PREVIEW MODE",
- "liveSql.title": "LIVE SQL",
- "liveSql.blocked": "BLOCKED",
- "liveSql.copy": "Copy",
- "liveSql.format": "Format",
- "liveSql.benchmark": "Benchmark",
- "liveSql.explain": "Explain",
- "liveSql.actionsHint": "Performance tools",
- "ddl.dialog.title": "Execute DDL",
- "ddl.dialog.execute": "Execute",
- "ddl.dialog.cancel": "Cancel",
- "ddl.dialog.close": "Close",
- "ddl.dialog.stopOnError": "Stop on first failure",
- "ddl.dialog.confirmDestructive": "I confirm execution of destructive statements (DROP TABLE)",
- "ddl.dialog.reviewBeforeRun": "Review the DDL script before confirming.",
- "ddl.dialog.confirmQuestion": "Confirm DDL execution on the connected database?",
- "ddl.dialog.irreversibleWarning": "This action can change the schema irreversibly.",
- "ddl.dialog.mustConfirmDestructive": "Confirm destructive execution to continue.",
- "ddl.dialog.executing": "Executing...",
- "ddl.execute.result.summary": "Statements: {0} | Success: {1} | Failures: {2} | Time: {3:0}ms",
- "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
- "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
- "ddl.execute.result.failed": "Failed to execute DDL.",
- "ddl.execute.result.cancelled": "Execution cancelled by the user.",
- "ddl.execute.result.cancelledDetails": "DDL execution was interrupted before completion.",
- "context.deleteSingle": "Delete {0}",
- "context.deleteMultiple": "Delete {0} nodes",
- "context.bringForward": "Bring Forward (Ctrl+PgUp)",
- "context.sendBackward": "Send Backward (Ctrl+PgDown)",
- "context.bringToFront": "Bring to Front (Ctrl+Shift+PgUp)",
- "context.sendToBack": "Send to Back (Ctrl+Shift+PgDown)",
- "context.normalizeLayers": "Normalize Layers",
- "context.deleteWire": "Delete wire",
- "context.addNode": "Add Node (Shift+A)",
- "context.undoWithDescription": "Undo {0}",
- "context.redo": "Redo",
- "shortcuts.windowTitle": "Keyboard Shortcuts",
- "shortcuts.headerTitle": "DBWeaver - Shortcuts",
- "shortcuts.headerHint": "Tip: use CTRL+SHIFT+P to open the Command Palette and search commands.",
- "shortcuts.filterWatermark": "Filter shortcuts by key or action...",
- "shortcuts.resultCount": "{0} shortcuts",
- "shortcuts.resultFilter": "{0} result(s) for \"{1}\"",
- "shortcuts.noneFound": "No shortcuts found.",
- "shortcuts.section.fileGeneral": "檔案與一般",
- "shortcuts.section.editing": "編輯",
- "shortcuts.section.canvasNavigation": "畫布與導覽",
- "shortcuts.section.zoomPanPrecision": "縮放、平移與精準控制",
- "shortcuts.section.previewInspection": "預覽與檢視",
- "shortcuts.key.deleteOrBackspace": "Del 或 Backspace",
- "shortcuts.key.middleDrag": "中鍵 + 拖曳",
- "shortcuts.key.rightDrag": "右鍵 + 拖曳",
- "shortcuts.key.spaceDrag": "空白鍵 + 拖曳",
- "shortcuts.key.altLeftDrag": "Alt + 左鍵拖曳",
- "shortcuts.key.arrows": "方向鍵",
- "shortcuts.key.shiftArrows": "Shift + 方向鍵",
- "shortcuts.action.openShortcutScreen": "開啟此快捷鍵畫面",
- "shortcuts.action.newCanvas": "新畫布",
- "shortcuts.action.openFile": "開啟檔案",
- "shortcuts.action.save": "儲存",
- "shortcuts.action.saveAs": "另存新檔",
- "shortcuts.action.commandPalette": "命令面板",
- "shortcuts.action.undo": "復原",
- "shortcuts.action.redo": "重做",
- "shortcuts.action.selectAll": "全選",
- "shortcuts.action.deleteSelection": "刪除選取",
- "shortcuts.action.closeOverlayCancel": "關閉覆蓋層 / 取消操作",
- "shortcuts.action.openNodeSearch": "開啟節點搜尋",
- "shortcuts.action.resetViewport": "重設視窗",
- "shortcuts.action.centerSelection": "置中選取",
- "shortcuts.action.fitSelection": "適配選取",
- "shortcuts.action.autoLayout": "自動佈局",
- "shortcuts.action.toggleSnapToGrid": "切換對齊格線",
- "shortcuts.action.bringForward": "往前一層",
- "shortcuts.action.sendBackward": "往後一層",
- "shortcuts.action.bringToFront": "移到最前",
- "shortcuts.action.sendToBack": "移到最後",
- "shortcuts.action.zoomInOut": "放大 / 縮小",
- "shortcuts.action.pan": "平移",
- "shortcuts.action.temporaryPan": "暫時平移",
- "shortcuts.action.alternatePan": "替代平移",
- "shortcuts.action.fineNudge": "精細移動選取",
- "shortcuts.action.fastNudge": "快速移動",
- "shortcuts.action.togglePreview": "切換資料預覽",
- "shortcuts.action.explainPlan": "執行計畫",
- "shortcuts.action.runPreview": "執行預覽",
- "shortcuts.action.connectionManager": "連線管理器",
- "shortcuts.action.flowVersionHistory": "流程版本歷史",
- "shortcuts.resetAll": "全部重設",
- "shortcuts.customized": "已自訂",
- "shortcuts.default": "預設",
- "shortcuts.apply": "套用",
- "shortcuts.reset": "重設",
- "shortcuts.status.resetAllSuccess": "所有快速鍵已重設為預設值。",
- "shortcuts.status.updated": "快速鍵已更新。",
- "shortcuts.status.reset": "快速鍵已重設為預設值。",
- "shortcuts.status.updateFailed": "無法更新快速鍵。",
- "toast.severity.success": "Success",
- "toast.severity.warning": "Warning",
- "toast.severity.error": "Error",
- "toast.details.success": "Success Details",
- "toast.details.warning": "Warning Details",
- "toast.details.error": "Error Details",
- "diagnostics.area.cteEditor": "CTE Editor",
- "diagnostics.area.viewEditor": "View Editor",
- "diagnostics.area.subEditor": "Sub-editor",
- "diagnostics.cteEditor.restoreParentFailed": "Failed to restore the parent canvas. CTE edits were discarded.",
- "diagnostics.recommendation.reloadFileIfNeeded": "Reload the file if needed.",
- "diagnostics.viewEditor.exitFailed": "Could not exit: {0}",
- "diagnostics.viewEditor.canvasIncomplete": "the canvas is incomplete.",
- "diagnostics.viewEditor.exitRecommendation": "Connect a valid ResultOutput or use the discard command.",
- "diagnostics.viewEditor.restoreParentFailed": "Failed to restore the parent canvas. The subgraph was discarded.",
- "diagnostics.subEditor.executeFailed": "Failed to execute editor action: {0}",
- "diagnostics.subEditor.executeRecommendation": "Try again. If it persists, reload the canvas.",
- "diagnostics.canvasMigration.openWarning": "Open: {0}",
- "diagnostics.canvasMigration.sessionRestoreWarning": "Session restore: {0}",
- "diagnostics.canvasMigration.versionRestoreWarning": "Version restore: {0}",
- "diagnostics.recommendation.resaveLatestSchema": "Review diagnostics and re-save the canvas to persist the latest schema.",
- "diagnostics.recommendation.saveMigratedSchema": "Review diagnostics and save the canvas to persist the migrated schema.",
- "file.saveDialog.title": "Save Canvas",
- "file.saveDialog.suggestedName": "Query1",
- "file.save.success": "Canvas saved successfully.",
- "file.save.failedWithReason": "Save failed: {0}",
- "file.openDialog.title": "Open Canvas",
- "file.open.failedWithReason": "Open failed: {0}",
- "file.open.success": "Canvas opened successfully.",
- "file.open.successWithWarnings": "Canvas opened with warnings.",
- "session.restore.failedWithReason": "Restore failed: {0}",
- "session.restore.successWithWarnings": "Session restored with warnings.",
- "session.restore.success": "Session restored successfully.",
- "export.documentation.dialogTitle": "Export Flow Documentation",
- "export.documentation.success": "Documentation exported successfully.",
- "export.documentation.failed": "Documentation export failed.",
- "export.failed.pathPermissionsHint": "Check file path and permissions.",
- "export.nodeNotFound": "No {0} Export node found on the canvas. Add one via the node search menu.",
- "export.dialogTitleByExtension": "Export as {0}",
- "export.success": "Export completed successfully.",
- "export.failed": "Export failed.",
- "fileHistory.currentFile.none": "No file selected",
- "fileHistory.status.saveFirst": "Save the canvas first to enable local history.",
- "fileHistory.status.noneFound": "No local versions found yet. Save this file to create history entries.",
- "fileHistory.status.countAvailable": "{0} local version(s) available.",
- "fileHistory.restore.failedWithReason": "Restore failed: {0}",
- "fileHistory.restore.successFrom": "Restored version from {0}.",
- "preview.status.cancelled": "Cancelled",
- "preview.status.error": "Error",
- "preview.status.ready": "Ready",
- "preview.runningWithMs": "Running... {0}ms",
- "preview.runningWithTimeout": "Running... {0}ms (timeout: {1}s)",
- "preview.runningSlowWithTimeout": "Running... {0}ms (timeout: {1}s) · Slow query, timeout in {2}s",
- "explain.errorWithReason": "Explain plan error: {0}",
- "explain.noSql": "No SQL to explain. Build a query on the canvas first.",
- "ddl.compilationFailed": "Compilation failed",
- "ddl.compileErrorWithReason": "DDL compile error: {0}",
- "command.undo.name": "Undo",
- "command.undo.description": "Undo last action",
- "command.redo.name": "Redo",
- "command.redo.description": "Redo last undone action",
- "command.addNode.name": "Add Node",
- "command.addNode.description": "Open node search menu to add a node",
- "command.bringForward.name": "Bring Forward",
- "command.bringForward.description": "Move selected nodes one layer forward",
- "command.sendBackward.name": "Send Backward",
- "command.sendBackward.description": "Move selected nodes one layer backward",
- "command.bringToFront.name": "Bring to Front",
- "command.bringToFront.description": "Move selected nodes to top layer",
- "command.sendToBack.name": "Send to Back",
- "command.sendToBack.description": "Move selected nodes to bottom layer",
- "command.normalizeLayers.name": "Normalize Layers",
- "command.normalizeLayers.description": "Compact node layer indices to a clean 0..N order",
- "tooltip.cleanupOrphans": "Remove orphan nodes not connected to the output (Ctrl+Z to undo)",
- "main.orphanSuffix": "Orphan(s)",
- "tooltip.autoFixAliasNaming": "Fix alias naming to snake_case (Ctrl+Z to undo)",
- "main.namingPrefix": "Naming",
- "fileHistory.compressedLabel": "Compressed:",
- "schema.itemsSuffix": "item(s)",
- "property.panel.title": "Properties",
- "property.panel.multiSelected": "{0} nodes selected",
- "sqlImporter.status.pasteSelect": "Paste a SELECT statement above, then click Import.",
- "sqlImporter.status.inputTooLarge": "SQL input is too large ({0:N0} chars). Limit is {1:N0}. Split the query or increase the import limit.",
- "sqlImporter.status.parsing": "Parsing SQL...",
- "sqlImporter.status.done": "Done - {0} imported, {1} partial, {2} skipped.",
- "sqlImporter.status.cancelledByUser": "Import cancelled by user.",
- "sqlImporter.status.timeout": "Import timed out after {0:0.#}s. Try a smaller query or increase timeout.",
- "sqlImporter.status.parseError": "Parse error: {0}",
- "diagnostics.area.undoRedoTransaction": "Undo/Redo Transaction",
- "undoRedo.rollbackExecuted": "Rollback executed for '{0}' ({1} operation(s) reverted).",
- "undoRedo.rollbackRecommendation": "Review the canvas state and retry the action if needed.",
- "node.preview.noCatalog": "No catalog available",
- "connection.error.searchMenuNotInitialized": "search menu not initialized",
- "connection.error.timeoutReachability": "Connection timed out - check that the server is reachable and increase the timeout if needed.",
- "connection.error.authenticationFailedForProvider": "Authentication failed - verify username and password for {0}.",
- "connection.error.databaseNotFoundForProvider": "Database not found - confirm the database name exists on {0}.",
- "connection.error.hostNotFound": "Host not found - check the server address and DNS resolution.",
- "connection.error.portRefused": "Port connection refused - check the port number and that the server is running / firewall rules allow access.",
- "connection.error.sslTls": "SSL/TLS error - check the server's SSL configuration or disable SSL for local connections.",
- "connection.error.timeoutOverloaded": "Connection timed out - the server may be overloaded or unreachable. Try increasing the timeout.",
- "connection.error.insufficientPrivileges": "Insufficient privileges - the user may lack permission to connect to this database.",
- "diagnostics.area.connection": "Connection",
- "connection.warning.canvasMayContainOldTables": "The canvas may still contain tables from a previous connection.",
- "connection.warning.canvasMayContainOldTablesRecommendation": "Clear the canvas manually or reconnect and choose keep/clear again.",
- "undoRedo.transaction.unnamed": "unnamed transaction",
- "benchmark.runLabelDefault": "Run 1",
- "benchmark.runLabelPattern": "Run {0}",
- "benchmark.status.failedWithReason": "Benchmark failed: {0}",
- "benchmark.status.noSql": "No SQL to benchmark - build a query first.",
- "benchmark.status.warmupProgress": "Warm-up {0}/{1}...",
- "benchmark.status.iterationProgress": "Iteration {0}/{1}...",
- "benchmark.status.done": "Done - {0}",
- "benchmark.status.cancelled": "Benchmark cancelled.",
- "app.windowTitle": "DBWeaver",
- "preview.error.safePreviewBlocked": "Safe Preview Mode: data-mutating commands (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) cannot be executed in preview.",
- "preview.error.noActiveConnection": "No active database connection. Please connect to a database first.",
- "sqlImporter.error.selectFromNotFound": "Could not find SELECT ... FROM in the query.",
- "sqlImporter.error.fromClauseParseFailed": "Could not parse FROM clause.",
- "sqlImporter.error.syntaxUnterminatedString": "Syntax error at line {0}, column {1}: unterminated string literal.",
- "sqlImporter.error.missingClosingParenthesis": "missing closing ')'",
- "sqlImporter.error.unexpectedClosingParenthesis": "unexpected ')'",
- "sqlImporter.error.syntaxAtLineColumn": "Syntax error at line {0}, column {1}: {2}.",
- "errorDiagnostics.safePreview.label": "Blocked by Safe Preview Mode",
- "errorDiagnostics.safePreview.friendly": "This SQL contains a data-mutating command and cannot be executed in preview.",
- "errorDiagnostics.safePreview.suggestion": "Remove or replace the mutating command (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) before running preview.",
- "errorDiagnostics.connection.label": "Connection failed",
- "errorDiagnostics.connection.friendly": "Could not reach the database server. The host may be down, unreachable, or blocking connections.",
- "errorDiagnostics.connection.suggestion": "Verify the server address and port, ensure the database is running, and check firewall rules.",
- "errorDiagnostics.authorization.label": "Authorization error",
- "errorDiagnostics.authorization.friendly": "The current credentials do not have permission to perform this operation.",
- "errorDiagnostics.authorization.suggestion": "Confirm the database user has SELECT privileges on the target table/schema, or contact your DBA.",
- "errorDiagnostics.timeout.label": "Query timeout",
- "errorDiagnostics.timeout.friendly": "The query took too long to complete and was cancelled by the server or client.",
- "errorDiagnostics.timeout.suggestion": "Add a WHERE clause or LIMIT to reduce the result set, or increase the query timeout in connection settings.",
- "errorDiagnostics.schema.label": "Schema error",
- "errorDiagnostics.schema.friendly": "A referenced table, column, or object could not be found in the database.",
- "errorDiagnostics.schema.suggestion": "Check that all table/column names are spelled correctly and that the schema matches the active connection.",
- "errorDiagnostics.syntax.label": "SQL syntax error",
- "errorDiagnostics.syntax.friendly": "The query contains a syntax error and could not be parsed by the database engine.",
- "errorDiagnostics.syntax.suggestion": "Review the highlighted SQL for typos, mismatched parentheses, or unsupported clauses for the active provider.",
- "errorDiagnostics.compatibility.label": "Compatibility error",
- "errorDiagnostics.compatibility.friendly": "A function, operator, or syntax construct is not supported by the active database provider.",
- "errorDiagnostics.compatibility.suggestion": "Switch to the correct provider in the SQL bar, or replace the unsupported construct with an equivalent.",
- "errorDiagnostics.unknown.label": "Unexpected error",
- "errorDiagnostics.unknown.friendly": "An error occurred while running the preview query.",
- "errorDiagnostics.unknown.suggestion": "Check the technical details below and verify that your canvas is configured correctly.",
- "error.mainWindow.invalidDataContext": "MainWindow 的 DataContext 必須是 ShellViewModel。",
- "error.mainWindow.canvasNotInitialized": "CanvasViewModel 尚未初始化。",
- "error.mainWindow.ddlPreviewUnavailable": "目前畫布無法使用 DDL 預覽。",
- "themeJson.editor.template": "{\n \"meta\": { \"name\": \"自訂主題\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
- "themeJson.error.pasteBeforeApply": "套用前請先貼上主題 JSON。",
- "themeJson.error.invalidJson": "無效的 JSON:{0}",
- "themeJson.error.emptyPayload": "無效的 JSON:內容為空。",
- "themeJson.error.invalidTheme": "無效的主題:{0}",
- "themeJson.error.appliedButSaveFailed": "主題已套用,但儲存失敗:{0}",
- "themeJson.success.appliedAndSaved": "JSON 主題已套用並儲存。",
- "themeJson.success.customRemoved": "已移除自訂主題。請重新啟動應用程式以完全回到預設主題。",
- "themeJson.error.restoreDefaultFailed": "還原預設主題失敗:{0}",
- "themeValidator.error.configNull": "主題設定為 null。",
- "themeValidator.warning.noSections": "主題沒有色彩或字體設定區段;無可套用內容。",
- "themeValidator.warning.invalidColor": "{0} 的色彩 '{1}' 無效。此鍵將被忽略。",
- "themeValidator.warning.sizeOutOfRange": "{0}={1} 超出範圍 (8..48)。此鍵將被忽略。",
- "queryExecutor.error.openConnectionMethodNotFound": "在 orchestrator 中找不到 OpenConnectionAsync 方法",
- "queryExecutor.error.openConnectionInvokeFailed": "呼叫 OpenConnectionAsync 失敗",
- "ddlImporter.warning.viewSelectNotReconstructable": "View '{0}':此 view 的 SELECT 無法以視覺方式重建,請在子畫布手動編輯。",
- "ddlImporter.error.tableNotFoundInMetadata": "在目前中繼資料中找不到資料表 '{0}'。",
- "main.window.untitled": "未命名",
- "main.subEditor.noSeedProvided": "未提供 {0} 的子編輯器 seed。",
- "main.layerOrder.bringToFront": "移到最上層",
- "main.layerOrder.sendToBack": "移到最下層",
- "main.layerOrder.bringForward": "向前一層",
- "main.layerOrder.sendBackward": "向後一層",
- "main.layerOrder.normalizeLayers": "正規化圖層",
- "export.fileType.html": "HTML 檔案",
- "export.fileType.json": "JSON 檔案",
- "export.fileType.csv": "CSV 檔案",
- "export.fileType.excel": "Excel 檔案",
- "commandPalette.templatePrefix": "範本:{0}",
- "themeLoader.status.notFoundWithPath": "找不到主題檔案:{0}",
- "themeLoader.status.deserializedNull": "主題 JSON 反序列化結果為 null。",
- "themeLoader.status.loaded": "主題 JSON 載入成功。",
- "credential.error.ciphertextTooShort": "密文資料太短。",
- "credential.error.dpapiWindowsOnly": "DPAPI 僅支援 Windows。",
- "credential.warning.loadVaultFailed": "載入憑證保險庫 {0} 失敗:{1}",
- "credential.warning.persistVaultFailed": "儲存憑證保險庫 {0} 失敗:{1}",
- "snippetStore.warning.loadFailed": "從 {0} 載入 snippet 失敗:{1}",
- "snippetStore.warning.saveFailed": "儲存 snippet 失敗:{0}",
- "flowVersionStore.warning.loadFailed": "從 {0} 載入流程版本失敗:{1}",
- "flowVersionStore.warning.saveFailed": "儲存流程版本失敗:{0}",
- "queryExecutor.error.queryEmpty": "查詢不可為空",
- "queryExecutor.error.providerNotSupported": "不支援供應者 {0}",
- "queryExecutor.error.singleStatementOnly": "預覽僅接受單一 SQL 語句。",
- "queryExecutor.error.queryEmptyWithPeriod": "查詢不可為空。",
- "queryExecutor.error.readOnlyOnly": "預覽模式僅支援唯讀 SQL。",
- "queryExecutor.error.namedParametersNotSupported": "預覽模式不支援執行 SQL 的命名參數。請改用安全內嵌常值或在預覽外執行查詢。",
- "queryExecutor.error.positionalParametersNotSupported": "預覽模式不支援位置參數佔位符(? 或 )。",
- "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "將所選節點對齊到底部邊緣",
- "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "將所選節點對齊到最左側邊緣",
- "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "將所選節點對齊到最右側邊緣",
- "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "將所選節點對齊到頂部邊緣",
- "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "套用 CTE 子畫布編輯並返回父畫布",
- "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "自動將節點排列為邏輯欄位",
- "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "在水平軸上置中所選節點",
- "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "在垂直軸上置中所選節點",
- "commandPalette.description.clear_canvas_and_start_fresh": "清空畫布並重新開始",
- "commandPalette.description.clear_node_selection": "清除節點選取",
- "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "將別名轉換為專案設定中的命名慣例",
- "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "建立檢查點、並排比較版本並還原先前畫布狀態",
- "commandPalette.description.delete_the_selected_nodes": "刪除所選節點",
- "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "捨棄目前子編輯器變更並返回父畫布",
- "commandPalette.description.execute_the_current_query_in_preview": "在預覽中執行目前查詢",
- "commandPalette.description.fit_all_nodes_into_the_visible_area": "將所有節點適配至可視區域",
- "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "從第一個 CSV 匯出節點產生 CSV 檔案",
- "commandPalette.description.generate_html_file_from_the_first_html_export_node": "從第一個 HTML 匯出節點產生 HTML 檔案",
- "commandPalette.description.generate_json_file_from_the_first_json_export_node": "從第一個 JSON 匯出節點產生 JSON 檔案",
- "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "從第一個 Excel 匯出節點產生 XLSX 活頁簿",
- "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "檢視查詢執行計畫:掃描類型、Join 策略與成本估算",
- "commandPalette.description.load_a_vsaq_canvas_file": "載入 .vsaq 畫布檔案",
- "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "測量目前 SQL 在 N 次迭代下的平均/中位/p95 延遲",
- "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "為所選 CTE 定義節點開啟獨立子畫布編輯器",
- "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "開啟每次儲存產生的本機版本歷史並還原先前快照",
- "commandPalette.description.open_output_preview_modal_for_the_active_mode": "開啟目前模式的輸出預覽對話框",
- "commandPalette.description.open_shortcut_reference_screen": "開啟快捷鍵參考畫面",
- "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "開啟連線管理器以新增、編輯或切換資料庫連線",
- "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "貼上 SELECT 語句並自動產生節點(支援 FROM、JOIN、WHERE、LIMIT)",
- "commandPalette.description.remove_all_nodes_not_connected_to_output": "移除所有未連接到輸出的節點",
- "commandPalette.description.reset_zoom_and_pan_to_default": "將縮放與平移重設為預設值",
- "commandPalette.description.save_canvas_to_a_new_file": "將畫布儲存為新檔案",
- "commandPalette.description.save_current_canvas": "儲存目前畫布",
- "commandPalette.description.save_markdown_documentation_of_the_current_flow": "儲存目前流程的 Markdown 文件",
- "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "將所選節點儲存為可重用片段,稍後可透過節點搜尋選單(⇧A)插入",
- "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "依據 FK 慣例與命名模式掃描畫布上的表來源節點,找出可能的 Join 關係",
- "commandPalette.description.select_all_nodes_on_canvas": "選取畫布上的所有節點",
- "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "將節點位置吸附到 16px 網格(Ctrl+G)",
- "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "將所選節點以相等水平間距分佈",
- "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "將所選節點以相等垂直間距分佈",
- "commandPalette.description.zoom_into_the_canvas": "放大畫布",
- "commandPalette.description.zoom_out_of_the_canvas": "縮小畫布",
- "commandPalette.name.align_bottom": "底部對齊",
- "commandPalette.name.align_left": "靠左對齊",
- "commandPalette.name.align_right": "靠右對齊",
- "commandPalette.name.align_top": "頂部對齊",
- "commandPalette.name.analyze_all_joins": "分析所有 Join",
- "commandPalette.name.auto_fix_naming": "自動修正命名",
- "commandPalette.name.auto_layout": "自動排版",
- "commandPalette.name.center_horizontally": "水平置中",
- "commandPalette.name.center_vertically": "垂直置中",
- "commandPalette.name.cleanup_orphans": "清理孤立節點",
- "commandPalette.name.delete_selected": "刪除已選取",
- "commandPalette.name.deselect_all": "取消全選",
- "commandPalette.name.discard_and_exit_editor": "放棄並離開編輯器",
- "commandPalette.name.distribute_horizontally": "水平平均分佈",
- "commandPalette.name.distribute_vertically": "垂直平均分佈",
- "commandPalette.name.edit_selected_cte": "編輯所選 CTE",
- "commandPalette.name.exit_cte_editor": "離開 CTE 編輯器",
- "commandPalette.name.explain_plan": "執行計畫",
- "commandPalette.name.export_csv": "匯出 CSV",
- "commandPalette.name.export_documentation": "匯出文件",
- "commandPalette.name.export_excel": "匯出 Excel",
- "commandPalette.name.export_html": "匯出 HTML",
- "commandPalette.name.export_json": "匯出 JSON",
- "commandPalette.name.file_save_load_history": "檔案儲存/載入歷史",
- "commandPalette.name.fit_to_screen": "符合畫面",
- "commandPalette.name.flow_version_history": "流程版本歷史",
- "commandPalette.name.import_sql_to_graph": "將 SQL 匯入為圖形",
- "commandPalette.name.keyboard_shortcuts": "鍵盤快捷鍵",
- "commandPalette.name.manage_connections": "管理連線",
- "commandPalette.name.new_canvas": "新增畫布",
- "commandPalette.name.open_file": "開啟檔案",
- "commandPalette.name.reset_viewport": "重設檢視區域",
- "commandPalette.name.run_preview": "執行預覽",
- "commandPalette.name.run_query_benchmark": "執行查詢效能測試",
- "commandPalette.name.save": "儲存",
- "commandPalette.name.save_as": "另存新檔",
- "commandPalette.name.save_selection_as_snippet": "將選取儲存為片段",
- "commandPalette.name.select_all": "全選",
- "commandPalette.name.toggle_preview": "切換預覽",
- "commandPalette.name.toggle_snap_to_grid": "切換格線吸附",
- "commandPalette.name.zoom_in": "放大",
- "commandPalette.name.zoom_out": "縮小",
- "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 percent restore zoom pan viewport",
- "commandPalette.tags.align_bottom_edge_selection_nodes": "align bottom edge selection nodes",
- "commandPalette.tags.align_center_middle_horizontal_nodes": "align center middle horizontal nodes",
- "commandPalette.tags.align_center_middle_vertical_nodes": "align center middle vertical nodes",
- "commandPalette.tags.align_left_edge_selection_nodes": "align left edge selection nodes",
- "commandPalette.tags.align_right_edge_selection_nodes": "align right edge selection nodes",
- "commandPalette.tags.align_top_edge_selection_nodes": "align top edge selection nodes",
- "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout view reset zoom",
- "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark performance latency timing profile measure speed",
- "commandPalette.tags.clear_selection": "clear selection",
- "commandPalette.tags.connection_database_server_host_provider_switch": "connection database server host provider switch",
- "commandPalette.tags.create_insert_search_transform": "create insert search transform",
- "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas exit apply back",
- "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte view subcanvas discard exit force",
- "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursive editor subgraph subcanvas isolate",
- "commandPalette.tags.data_results_table_panel": "data results table panel",
- "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribute space equal horizontal nodes",
- "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribute space equal vertical nodes",
- "commandPalette.tags.execute_run_sql_query_results": "execute run sql query results",
- "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan execution cost scan index join performance",
- "commandPalette.tags.export_csv_file_tabular_output_save": "export csv file tabular output save",
- "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "export excel xlsx file tabular output spreadsheet save",
- "commandPalette.tags.export_html_file_output_report_save": "export html file output report save",
- "commandPalette.tags.export_json_file_output_save": "export json file output save",
- "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "export markdown doc documentation flow save md",
- "commandPalette.tags.export_persist_copy": "export persist copy",
- "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "file history save load backup versions restore local",
- "commandPalette.tags.forward_history": "forward history",
- "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "help shortcuts hotkeys keyboard reference",
- "commandPalette.tags.highlight_mark_all_nodes": "highlight mark all nodes",
- "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "import sql paste convert graph reverse engineer query",
- "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analyze suggest detect foreign key relationships heuristic",
- "commandPalette.tags.layer_z_order_back_selected_nodes": "layer z-order back selected nodes",
- "commandPalette.tags.layer_z_order_backward_selected_nodes": "layer z-order backward selected nodes",
- "commandPalette.tags.layer_z_order_forward_selected_nodes": "layer z-order forward selected nodes",
- "commandPalette.tags.layer_z_order_front_selected_nodes": "layer z-order front selected nodes",
- "commandPalette.tags.layer_z_order_normalize_compact": "layer z-order normalize compact",
- "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout arrange columns auto organize readability",
- "commandPalette.tags.load_import_vsaq": "load import vsaq",
- "commandPalette.tags.magnify_enlarge": "magnify enlarge",
- "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "orphan unused disconnected clean delete nodes",
- "commandPalette.tags.persist_write_disk": "persist write disk",
- "commandPalette.tags.remove_erase_nodes": "remove erase nodes",
- "commandPalette.tags.rename_alias_fix_naming_convention": "rename alias fix naming convention",
- "commandPalette.tags.reset_clear_blank": "reset clear blank",
- "commandPalette.tags.revert_back_history": "revert back history",
- "commandPalette.tags.shrink_reduce": "shrink reduce",
- "commandPalette.tags.snap_grid_align_precision_position": "snap grid align precision position",
- "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet save selection reuse template favorite bookmark",
- "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "version history checkpoint diff restore snapshot compare undo flow",
- "sqlEditor.diffPreview.title": "Transactional Diff Preview",
- "sqlEditor.mutation.confirmExecute": "Confirm Execute",
- "sqlEditor.tab.closeAnyway": "Close Anyway",
- "sqlEditor.tab.keepTab": "Keep Tab",
- "sqlEditor.status.ready": "Ready.",
- "sqlEditor.telemetry.none": "No execution telemetry yet.",
- "sqlEditor.telemetry.summary": "Statements: {0} Success: {1} Failed: {2} Total: {3} ms",
- "sqlEditor.telemetry.errors.none": "No aggregated errors.",
- "sqlEditor.diff.none": "No transactional diff preview available.",
- "sqlEditor.mutation.estimate.none": "No mutation estimate available.",
- "sqlEditor.mutation.estimate.value": "Estimated affected rows: {0}",
- "sqlEditor.mutation.estimate.unavailable": "Could not estimate affected rows automatically.",
- "sqlEditor.tab.closePending": "Unsaved changes detected. Confirm tab close.",
- "sqlEditor.tab.noPendingClose": "No tab close pending.",
- "sqlEditor.tab.manyWarning": "High tab count: {0} open tabs.",
- "sqlEditor.mutation.pending.none": "No pending mutation confirmation.",
- "sqlEditor.mutation.pending.required": "Mutation requires confirmation before execution.",
- "sqlEditor.message.empty": "Execute a statement to see messages.",
- "sqlEditor.message.success": "Execution completed successfully.",
- "sqlEditor.result.summary.empty": "Rows: - Time: -",
- "sqlEditor.result.summary": "Rows: {0} Time: {1} ms",
- "sqlEditor.file.save.canceled": "Save canceled.",
- "sqlEditor.file.save.noPath": "No target path selected.",
- "sqlEditor.file.save.success": "SQL file saved.",
- "sqlEditor.file.save.failed": "Save failed.",
- "sqlEditor.file.open.failed": "Open failed.",
- "sqlEditor.file.open.notFound": "Selected SQL file was not found.",
- "sqlEditor.file.open.success": "SQL file opened.",
- "sqlEditor.status.executing": "Executing SQL...",
- "sqlEditor.status.executingScript": "Executing SQL script...",
- "sqlEditor.status.executingStep": "Executing {0}/{1}...",
- "sqlEditor.status.canceling": "Canceling execution...",
- "sqlEditor.status.executingConfirmedMutation": "Executing confirmed mutation...",
- "sqlEditor.status.mutationCanceled": "Mutation execution canceled.",
- "sqlEditor.detail.statementNotExecuted": "Statement was not executed.",
- "sqlEditor.status.success": "Execution succeeded.",
- "sqlEditor.detail.rowsAndTime": "{0} row(s) in {1} ms.",
- "sqlEditor.status.canceled": "Execution canceled.",
- "sqlEditor.status.failed": "Execution failed.",
- "sqlEditor.status.confirmationRequired": "Confirmation required before execution.",
- "sqlEditor.error.mutationConfirmationRequired": "Mutation confirmation required.",
- "sqlEditor.result.tabTitle": "Result {0}",
- "sqlEditor.tab.closeRequiresConfirmation": "Tab close requires confirmation.",
- "sqlEditor.tab.unsavedDetail": "This tab has unsaved changes.",
- "sqlEditor.tab.closed": "Tab closed.",
- "sqlEditor.tab.closeCanceled": "Tab close canceled.",
- "sqlEditor.tab.closeCanceledDetail": "Unsaved tab kept open.",
- "sqlEditor.error.noStatementSelected": "No SQL statement selected for execution.",
- "sqlEditor.error.noConnection": "No active database connection for SQL execution.",
- "sqlEditor.error.executionCanceled": "SQL execution was canceled.",
- "sqlEditor.tab.scriptTitle": "Script {0}",
- "sqlEditor.guard.delete.noWhere.message": "DELETE without WHERE can remove all rows.",
- "sqlEditor.guard.delete.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
- "sqlEditor.guard.delete.trivialWhere.message": "DELETE has a trivially true WHERE clause.",
- "sqlEditor.guard.delete.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
- "sqlEditor.guard.update.noWhere.message": "UPDATE without WHERE can affect all rows.",
- "sqlEditor.guard.update.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
- "sqlEditor.guard.update.trivialWhere.message": "UPDATE has a trivially true WHERE clause.",
- "sqlEditor.guard.update.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
- "sqlEditor.guard.insert.noColumnList.message": "INSERT without explicit column list is fragile against schema changes.",
- "sqlEditor.guard.insert.noColumnList.recommendation": "Prefer INSERT INTO table(col1, col2, ...) VALUES (...).",
- "sqlEditor.guard.ddl.message": "DDL statement may cause structural changes in the database.",
- "sqlEditor.guard.ddl.recommendation": "Confirm execution only when schema changes are intended.",
- "sqlEditor.diff.unavailable.noPreview": "No transactional diff preview available for this statement.",
- "sqlEditor.diff.unavailable.parseError": "Could not parse mutation target for transactional diff preview.",
- "sqlEditor.diff.unavailable.connection": "Transactional diff preview unavailable due to connection or query limitations.",
- "sqlEditor.diff.deleteSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, affected {2}, total rows after {3}.",
- "sqlEditor.diff.updateSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, candidate rows affected {2}, total rows after {3}.",
- "sqlEditor.diff.unavailable.unsupportedStatement": "Transactional diff preview currently supports UPDATE and DELETE only.",
- "sqlEditor.results.title": "Results",
- "sqlEditor.saveSql.fileType": "SQL Files",
- "sqlEditor.saveSql.pickerTitle": "Save SQL File",
- "sqlEditor.export.pickerTitle": "Export SQL Data",
- "sqlEditor.export.status.noResultTitle": "No execution result available for export.",
- "sqlEditor.export.status.noResultDetail": "Execute a query first.",
- "sqlEditor.export.status.successTitle": "Report exported.",
- "sqlEditor.export.status.failedTitle": "Failed to export report.",
- "sqlEditor.export.fileType.html": "HTML File",
- "sqlEditor.export.fileType.json": "JSON File",
- "sqlEditor.export.fileType.csv": "CSV File",
- "sqlEditor.export.fileType.xlsx": "Excel Workbook",
- "sqlEditor.export.defaultFileBase": "report",
- "sqlEditor.export.defaultTitle": "SQL Report",
- "sqlEditor.export.error.typeRequired": "A report type must be selected before export.",
- "sqlEditor.export.type.html.title": "HTML full-feature report",
- "sqlEditor.export.type.html.description": "Standalone, SQL-first HTML artifact for offline audit.",
- "sqlEditor.export.type.json.title": "JSON execution contract",
- "sqlEditor.export.type.json.description": "Machine-readable payload with SQL, metadata and execution result.",
- "sqlEditor.export.type.csv.title": "CSV data export",
- "sqlEditor.export.type.csv.description": "Tabular result data only, suitable for spreadsheet tools.",
- "sqlEditor.export.type.xlsx.title": "Excel workbook export",
- "sqlEditor.export.type.xlsx.description": "Spreadsheet workbook with query result data only.",
- "sqlEditor.export.dialog.windowTitle": "Export SQL Data",
- "sqlEditor.export.dialog.title": "Export SQL Data",
- "sqlEditor.export.dialog.subtitle": "Choose the artifact format and metadata before exporting.",
- "sqlEditor.export.dialog.confirm": "Export",
- "sqlEditor.export.dialog.fileNameWatermark": "report.html",
- "sqlEditor.export.dialog.titleWatermark": "SQL Report",
- "sqlEditor.export.dialog.descriptionWatermark": "Additional context for auditors and teammates.",
- "sqlEditor.export.dialog.section.reportType": "REPORT TYPE",
- "sqlEditor.export.dialog.section.fileName": "FILE NAME",
- "sqlEditor.export.dialog.section.reportTitle": "TITLE",
- "sqlEditor.export.dialog.section.description": "DESCRIPTION",
- "sqlEditor.export.dialog.section.options": "OPTIONS",
- "sqlEditor.export.option.includeSchema": "Include output schema",
- "sqlEditor.export.option.includeNodeDetails": "Include node/connection placeholders in JSON",
- "sqlEditor.export.option.includeMetadata": "Include optional metadata",
- "sqlEditor.export.option.useDashForEmpty": "Use '-' for empty fields",
- "sqlEditor.export.badge.offline": "OFFLINE READY",
- "sqlEditor.export.badge.structured": "STRUCTURED PAYLOAD",
- "sqlEditor.export.badge.dataOnly": "DATA ONLY"
-}
+{
+ "main.brand": "AkkornStudio",
+ "main.tab.query1": "Query 1",
+ "main.new": "New",
+ "main.open": "Open",
+ "main.save": "Save",
+ "main.history": "History",
+ "main.layout": "Layout",
+ "main.preview": "Preview",
+ "main.undo": "Undo",
+ "main.redo": "Redo",
+ "main.cleanupOrphans": "Cleanup orphan nodes",
+ "main.autoFixAliasNaming": "Auto-fix alias naming",
+ "main.autoLayoutCanvas": "Auto layout canvas",
+ "main.toggleDataPreview": "Toggle data preview",
+ "main.language": "Language",
+ "main.restore.prompt": "Previous session found — restore the last canvas?",
+ "main.restore.button": "Restore session",
+ "main.cteEditor.editingPrefix": "Editing CTE: ",
+ "main.cteEditor.backToCanvas": "Back to Canvas",
+ "main.cteEditor.exitA11y": "Exit CTE editor",
+ "main.viewEditor.editingPrefix": "DDL > View: ",
+ "main.viewEditor.backToCanvas": "Back to DDL",
+ "main.viewEditor.exitA11y": "Exit view editor",
+ "connection.title": "Connection Manager",
+ "connection.subtitle": "不中斷流程即可設定、測試與啟用連線",
+ "connection.none": "No connection",
+ "connection.active": "ACTIVE",
+ "connection.health.online": "Online",
+ "connection.health.degraded": "Degraded",
+ "connection.health.offline": "Offline",
+ "connection.tooltip.none": "No active connection — click to manage",
+ "connection.ping": "Ping",
+ "connection.saved": "SAVED CONNECTIONS",
+ "connection.new": "New Connection",
+ "connection.selectOrCreate": "Select a connection or create a new one",
+ "connection.name": "Connection Name",
+ "connection.provider": "Provider",
+ "connection.host": "Host",
+ "connection.port": "Port",
+ "connection.database": "Database",
+ "connection.sqlitePath": "SQLite Path",
+ "connection.sqliteBrowse": "Browse",
+ "connection.sqliteCreate": "Create",
+ "connection.username": "Username",
+ "connection.password": "Password",
+ "connection.timeout": "Timeout (seconds)",
+ "connection.test": "Test",
+ "connection.save": "Save",
+ "connection.connect": "Connect",
+ "connection.action.testConnection": "Test connection",
+ "connection.action.saveConnection": "Save connection",
+ "connection.action.connectConnection": "Connect connection",
+ "connection.status.connecting": "連線中...",
+ "connection.status.connected": "已連線",
+ "connection.status.testing": "測試中...",
+ "connection.status.failedPrefix": "連線失敗",
+ "connection.status.metadataUnavailable": "連線失敗:中繼資料不可用。",
+ "connection.status.highLatency": "高延遲",
+ "connection.watermark.name": "我的正式環境資料庫",
+ "connection.watermark.host": "localhost",
+ "connection.watermark.port": "5432",
+ "connection.watermark.database": "database_name",
+ "connection.watermark.username": "user",
+ "connection.watermark.password": "••••••••",
+ "connection.watermark.timeout": "30",
+ "main.connectingDb": "Connecting to database...",
+ "main.emptyHint": "Press ⇧A to add your first node, or drag a table from the sidebar",
+ "status.nodesSeparator": " nodes · ",
+ "status.connectionsSuffix": " connections",
+ "status.undo": "Undo: ",
+ "status.shortcuts": "⇧A Nodes · F3 Preview · Ctrl+Z Undo · Del Remove · Alt+Drag Pan",
+ "connection.disconnect": "Disconnect",
+ "connection.action.disconnectConnection": "Disconnect connection",
+ "connectionTab.active": "ACTIVE CONNECTION",
+ "connectionTab.none": "No active connection",
+ "connectionTab.saved": "SAVED CONNECTIONS",
+ "connectionTab.new": "+ New Connection",
+ "schema.database": "DATABASE",
+ "schema.search": "Search tables, columns...",
+ "schema.loading": "Searching tables, columns...",
+ "schema.noConnection": "No Connection",
+ "schema.noConnectionHint": "Connect to a database to see tables, columns, and relationships",
+ "schema.emptyNoTables": "No tables found",
+ "fileHistory.title": "Save/Load Version History",
+ "fileHistory.reload": "Reload",
+ "fileHistory.restoreSelected": "Restore selected",
+ "fileHistory.empty": "No local versions yet",
+ "fileHistory.emptyHint": "Save this file to generate version history.",
+ "preview.title": "Data Preview",
+ "preview.subtitle": "Review data and diagnostics before continuing",
+ "preview.run": "Run",
+ "preview.cancel": "Cancel",
+ "preview.tab.preview": "Preview",
+ "preview.tab.sql": "SQL",
+ "preview.close": "Close preview",
+ "preview.running": "Running preview query… ",
+ "preview.clickCancel": "Click Cancel to stop",
+ "preview.cancelled": "Query cancelled",
+ "preview.runAgain": "Press Run to execute again",
+ "preview.failed": "Preview execution failed",
+ "preview.technical": "TECHNICAL DETAILS",
+ "preview.noData": "No data yet",
+ "preview.f3Hint": "Press F3 or Space to run the current query",
+ "sqlImporter.title": "Import SQL to Graph",
+ "sqlImporter.subtitle": "Paste a SELECT statement — nodes are created automatically",
+ "sqlImporter.sqlStatement": "SQL STATEMENT",
+ "sqlImporter.supported": "Supported: ",
+ "sqlImporter.import": "Import",
+ "sqlImporter.report": "CONVERSION REPORT",
+ "sqlEditor.mutation.dialogTitle": "變更確認",
+ "sqlEditor.mutation.dialogSubtitle": "在確認執行前請先檢視影響",
+ "search.empty": "No nodes found",
+ "search.emptyHint": "Try searching for UPPER, JSON, CAST, AND…",
+ "search.shortcut": "⇧A",
+ "search.spawn": "Spawn",
+ "commandPalette.empty": "沒有符合搜尋的命令",
+ "commandPalette.search": "命令搜尋",
+ "commandPalette.shortcut": "CTRL+SHIFT+P",
+ "commandPalette.execute": "執行",
+ "context.editCte": "Edit Selected CTE",
+ "context.editViewSubcanvas": "Edit View Subcanvas",
+ "explain.title": "Explain Plan",
+ "explain.sql": "SQL",
+ "explain.option.analyze": "分析",
+ "explain.option.buffers": "緩衝區",
+ "explain.badge.simulated": "模擬",
+ "explain.timing.planning": "規劃:",
+ "explain.timing.execution": "執行:",
+ "explain.section.snapshotComparison": "快照比較",
+ "explain.section.indexRecommendations": "索引建議",
+ "explain.section.history": "歷程",
+ "explain.detail.estimated": "估計",
+ "explain.detail.actual": "實際",
+ "explain.detail.error": "誤差",
+ "explain.detail.time": "時間",
+ "explain.detail.loops": "迴圈",
+ "explain.rerun": "Re-run",
+ "explain.alertSuffix": " expensive operation(s) detected — consider adding indexes",
+ "explain.running": "Running EXPLAIN…",
+ "explain.failed": "⚠ EXPLAIN failed",
+ "explain.noPlan": "No plan yet",
+ "explain.rerunHint": "Press Re-run to execute EXPLAIN",
+ "explain.header.operation": "操作",
+ "explain.header.cost": "成本",
+ "explain.header.rows": "資料列",
+ "explain.header.alert": "警示",
+ "explain.mode.list": "清單",
+ "explain.mode.tree": "樹狀",
+ "explain.action.snapshot": "儲存快照",
+ "explain.action.copyJson": "複製 JSON",
+ "explain.action.copyText": "複製文字",
+ "explain.action.saveJson": "儲存 .json",
+ "explain.action.openDalibo": "在 Dalibo 開啟",
+ "explain.legend.seqscan": "SEQ SCAN — full table read, no index",
+ "explain.legend.sort": "SORT — in-memory sort",
+ "explain.legend.hash": "HASH — hash join",
+ "explain.escClose": "Esc to close",
+ "flowVersion.title": "Flow Version History",
+ "flowVersion.subtitle": "Create checkpoints, compare versions and restore",
+ "flowVersion.watermark": "Checkpoint label (optional)…",
+ "flowVersion.saveCheckpoint": "Save Checkpoint",
+ "flowVersion.compareMode": "Compare Mode",
+ "flowVersion.selectBase": "Select BASE version (from):",
+ "flowVersion.clickAny": "Then click any version in the list below to compare.",
+ "flowVersion.noCheckpoints": "No checkpoints yet",
+ "flowVersion.noCheckpointsHint": "Save a checkpoint above to begin tracking versions.",
+ "flowVersion.restore": "Restore",
+ "flowVersion.diffResults": "Diff Results",
+ "benchmark.title": "Query Benchmark",
+ "benchmark.subtitle": "Measures avg / median / p95 latency over N iterations",
+ "benchmark.sql": "SQL being benchmarked",
+ "benchmark.runLabel": "Run label",
+ "benchmark.runLabelWatermark": "Run 1",
+ "benchmark.iterations": "Iterations (1–100)",
+ "benchmark.warmup": "Warm-up passes (0–10)",
+ "benchmark.interval": "Interval between runs (ms)",
+ "benchmark.run": "Run Benchmark",
+ "benchmark.cancel": "Cancel",
+ "benchmark.clearHistory": "Clear History",
+ "benchmark.latest": "LATEST RESULT",
+ "benchmark.avg": "AVG",
+ "benchmark.median": "MEDIAN",
+ "benchmark.min": "MIN",
+ "benchmark.max": "MAX",
+ "benchmark.iterationsAt": " iterations · run at ",
+ "benchmark.history": "HISTORY",
+ "benchmark.header.label": "標籤",
+ "benchmark.header.avg": "平均",
+ "benchmark.header.median": "中位數",
+ "benchmark.header.min": "最小",
+ "benchmark.header.max": "最大",
+ "benchmark.itersSuffix": " iters",
+ "diagnostics.title": "App Diagnostics",
+ "diagnostics.run": "Run",
+ "diagnostics.running": "Running checks…",
+ "diagnostics.ok": "OK",
+ "diagnostics.warning": "Warning",
+ "diagnostics.error": "Error",
+ "diagnostics.tooltip.rerun": "Re-run all checks",
+ "diagnostics.tooltip.copy": "Copy diagnostic report to clipboard",
+ "diagnostics.tooltip.close": "Close (Esc)",
+ "autoJoin.title": "Auto-Join Suggestions",
+ "autoJoin.titleForTable": "Auto-Join suggestions for {0}",
+ "autoJoin.acceptAll": "Accept All",
+ "autoJoin.accept": "Accept",
+ "autoJoin.skip": "Skip",
+ "autoJoin.allHandled": "All suggestions handled",
+ "autoJoin.joinKeyword": "JOIN",
+ "autoJoin.confidence.fkConstraint": "FK Constraint",
+ "autoJoin.confidence.fkReverse": "FK (Reverse)",
+ "autoJoin.confidence.namingMatch": "Naming Match",
+ "autoJoin.confidence.weakMatch": "Weak Match",
+ "autoJoin.runSelected": "Auto-Join Selected",
+ "autoJoin.noSimilarityTitle": "No automatic join found",
+ "autoJoin.noSimilarityDetails": "Choose the columns manually to create a simple join.",
+ "autoJoin.appliedTitle": "Auto-join applied",
+ "autoJoin.manual.title": "Create Manual Join",
+ "autoJoin.manual.subtitle": "No reliable similarity was found. Select one column from each table.",
+ "autoJoin.manual.leftColumn": "Left column",
+ "autoJoin.manual.rightColumn": "Right column",
+ "autoJoin.manual.joinType": "Join type",
+ "autoJoin.manual.operator": "Operator",
+ "autoJoin.manual.confirm": "Create join",
+ "autoJoin.manual.noCompatible": "No compatible columns for the selected left pin type.",
+ "autoJoin.manualJoinCreatedTitle": "Manual join created",
+ "autoJoin.manualJoinFailedTitle": "Manual join could not be created",
+ "autoJoin.manualJoinFailedDetails": "Check selected columns and existing joins, then try again.",
+ "autoJoin.multipleCandidatesTitle": "Multiple join candidates found",
+ "autoJoin.multipleCandidatesDetails": "{0} possible combinations were found. Confirm which columns should be used.",
+ "autoJoin.suggestionsFoundTitle": "Auto-join suggestions available",
+ "autoJoin.suggestionsFoundDetails": "{0} suggestion(s) found. Select two tables and run Auto-Join Selected.",
+ "property.outputAlias": "OUTPUT ALIAS",
+ "property.sourceAlias": "SOURCE ALIAS",
+ "property.aliasWatermark": "e.g. MyColumn (optional)",
+ "property.parameters": "PARAMETERS",
+ "property.enabled": "Enabled",
+ "property.datetimeWatermark": "YYYY-MM-DDTHH:mm:ss or leave empty",
+ "property.dateWatermark": "YYYY-MM-DD or leave empty",
+ "property.apply": "Apply",
+ "property.inputPins": "INPUT PINS",
+ "property.outputPins": "OUTPUT PINS",
+ "property.sqlTrace": "SQL TRACE",
+ "property.live": "live",
+ "node.numericValue": "Numeric Value",
+ "node.stringValue": "String Value",
+ "node.enterText": "Enter text",
+ "node.datetimeValue": "DateTime Value",
+ "node.valueLabel": "Value:",
+ "node.noInputs": "No inputs",
+ "node.loadingSample": "Loading sample…",
+ "node.previewFailed": "⚠ Preview failed",
+ "node.sampleRowsHint": "5 sample rows · demo data",
+ "sidebar.tab.nodes": "節點",
+ "sidebar.tab.connection": "連線",
+ "sidebar.tab.schema": "結構",
+ "sidebar.tab.diagnostics": "診斷",
+ "sidebar.addNode": "+ Add Node (⇧A)",
+ "sidebar.previewF3": "Preview (F3)",
+ "nodesList.search": "Search nodes...",
+ "search.watermark": "Search nodes… (Esc to close)",
+ "search.snippets": "★ SNIPPETS",
+ "commandPalette.watermark": "執行命令…(Esc 關閉)",
+ "tooltip.newCanvas": "New canvas (Ctrl+N)",
+ "tooltip.openCanvas": "Open canvas (Ctrl+O)",
+ "tooltip.saveCanvas": "Save canvas (Ctrl+S)",
+ "tooltip.fileHistory": "Local save/load history (Ctrl+Alt+H)",
+ "tooltip.zoomOut": "Zoom out (Ctrl+-)",
+ "tooltip.zoomIn": "Zoom in (Ctrl++)",
+ "tooltip.fitToScreen": "Fit to screen (Ctrl+0)",
+ "tooltip.autoLayout": "Auto Layout — arrange nodes into logical columns (Ctrl+L, Ctrl+Z to undo)",
+ "tooltip.snapToGrid": "Toggle snap to grid (Ctrl+G)",
+ "tooltip.dataPreview": "Data preview (F3)",
+ "tooltip.toggleLanguage": "Toggle language (pt-BR / en-US)",
+ "tooltip.appDiagnostics": "App Diagnostics (self-check)",
+ "tooltip.keyboardShortcuts": "Keyboard shortcuts (F1)",
+ "tooltip.cancelRunningQuery": "Cancel the running query",
+ "tooltip.closeEsc": "Close (Esc)",
+ "tooltip.recheckConnectionHealth": "Re-check connection health",
+ "tooltip.deleteConnection": "Delete connection",
+ "tooltip.testConnection": "Test connection",
+ "tooltip.saveConnection": "Save connection",
+ "tooltip.activateConnection": "Activate this connection",
+ "tooltip.toggleDataSamplePreview": "Toggle data sample preview",
+ "tooltip.liveSqlMutatingBlocked": "This SQL contains a data-mutating command and cannot be run in Safe Preview Mode",
+ "tooltip.copySql": "Copy SQL to clipboard",
+ "tooltip.formatSql": "Format SQL",
+ "tooltip.openBenchmark": "Open Query Benchmark (measure avg / median / p95 latency)",
+ "tooltip.openExplainPlan": "Open Explain Plan inspector — visualise the query execution plan",
+ "tooltip.switchToQueryMode": "Switch to Query canvas",
+ "tooltip.switchToDdlMode": "Switch to DDL canvas",
+ "tooltip.autoJoinSelected": "Try auto-join between the two selected tables",
+ "tooltip.pins.inputs": "Inputs",
+ "tooltip.pins.outputs": "Outputs",
+ "tooltip.pins.none": "None",
+ "tooltip.tableColumns": "Columns",
+ "tooltip.tableColumns.none": "No detailed columns",
+ "window.minimize": "Minimize window",
+ "window.maximizeRestore": "Maximize/restore window",
+ "window.close": "Close window",
+ "menu.newDiagram": "New diagram",
+ "menu.openFile": "Open file",
+ "menu.save": "Save",
+ "menu.fileHistory": "File history",
+ "menu.shortcuts": "Keyboard shortcuts",
+ "menu.settings": "Settings",
+ "menu.importDdlSchema": "Import DDL schema",
+ "menu.viewDdlSql": "View DDL SQL",
+ "menu.executeDdl": "Execute DDL",
+ "menu.backToStart": "Back to start",
+ "toast.ddlExecuteFailed": "Failed to execute DDL.",
+ "toast.ddlOpenFailed": "Failed to open DDL SQL.",
+ "toast.ddlImportFailed": "Failed to import schema into DDL.",
+ "toast.ddlConnectToImportSchema": "Connect to a database to import schema into the DDL canvas.",
+ "toast.ddlNoTablesFound": "No tables found to import in DDL mode.",
+ "toast.ddlSchemaImported": "Schema imported into the DDL canvas.",
+ "toast.ddlImportSummary": "{0} table(s), {1} column(s), {2} FK(s), {3} unique index(es).",
+ "toast.ddlConnectToImportTable": "Connect to a database to import tables into the DDL canvas.",
+ "toast.ddlTableAlreadyExists": "Table '{0}' already exists in the DDL canvas.",
+ "toast.ddlTableImported": "Table imported into the DDL canvas.",
+ "toast.ddlTableImportSummary": "Nodes: +{0}, connections: +{1}, FKs: +{2}.",
+ "toast.ddlNoActiveConnection": "No active connection to execute DDL.",
+ "toast.ddlExecutedSuccess": "DDL executed successfully.",
+ "toast.ddlExecutedWithIssues": "DDL executed with issues.",
+ "toast.switchToDdl": "Switch to DDL mode to generate SQL.",
+ "toast.ddlInvalid": "Invalid DDL. Fix errors before continuing.",
+ "toast.ddlNoStatements": "No DDL statements were generated in the canvas.",
+ "toast.previewOpenFailed": "Failed to open preview.",
+ "tab.switchFailed": "Failed to switch tab: {0}",
+ "settings.status.darkApplied": "Dark theme applied.",
+ "settings.status.lightApplied": "Light theme applied.",
+ "settings.status.snapUpdated": "Snap updated: {0}.",
+ "settings.status.languageToggled": "Language toggled.",
+ "settings.status.languageSelected": "Language selected: {0}.",
+ "settings.status.themeEditorReady": "Theme editor ready. Apply to save and use this theme.",
+ "settings.section.appearance.title": "Themes",
+ "settings.section.languageRegion.title": "語言與地區",
+ "settings.section.dateTime.title": "日期與時間",
+ "settings.section.keyboard.title": "鍵盤快速鍵",
+ "settings.section.privacy.title": "隱私",
+ "settings.section.notification.title": "通知",
+ "settings.section.accessibility.title": "無障礙",
+ "settings.section.default.title": "設定",
+ "settings.section.appearance.subtitle": "選擇你的風格或自訂主題",
+ "settings.section.languageRegion.subtitle": "管理語言與地區格式",
+ "settings.section.keyboard.subtitle": "自訂 command palette 與畫布執行所使用的鍵盤快速鍵。",
+ "settings.section.wip.subtitle": "開發中。",
+ "settings.section.default.subtitle": "應用程式設定",
+ "settings.general": "General",
+ "settings.nav.appearance": "Appearance",
+ "settings.theme.light": "淺色模式",
+ "settings.theme.dark": "深色模式",
+ "settings.theme.system": "系統偏好",
+ "settings.gridSnap.title": "Grid Snap",
+ "settings.gridSnap.subtitle": "Controls node snapping on the canvas.",
+ "settings.language.subtitle": "請選擇應用程式語言。",
+ "settings.language.toggle": "切換語言",
+ "settings.language.option.ptBR": "葡萄牙語(巴西)",
+ "settings.language.option.enUS": "英語(美國)",
+ "settings.language.option.esES": "西班牙語(西班牙)",
+ "settings.language.option.ruRU": "俄語",
+ "settings.language.option.jaJP": "日語",
+ "settings.language.option.zhTW": "繁體中文",
+ "settings.themeJson.title": "主題 JSON",
+ "settings.themeJson.subtitle": "貼上你的主題 JSON,立即套用並保存。",
+ "settings.themeJson.apply": "套用 JSON",
+ "settings.themeJson.restoreDefault": "還原預設主題",
+ "mode.query": "Query",
+ "mode.ddl": "DDL",
+ "sidebar.left.close": "Close left sidebar",
+ "sidebar.left.open": "Reopen left sidebar",
+ "sidebar.right.close": "Close right sidebar",
+ "sidebar.right.open": "Reopen right sidebar",
+ "connection.completedTitle": "Connection completed",
+ "connection.clearCanvasPrompt": "Do you want to clear the current canvas to start with the new connection?",
+ "connection.close": "Close connection manager",
+ "connection.refreshHealth": "Refresh connection health",
+ "common.details": "Details",
+ "common.cancel": "Cancel",
+ "common.keep": "Keep",
+ "common.clear": "Clear",
+ "zoom.out": "Zoom out",
+ "zoom.in": "Zoom in",
+ "zoom.fit": "Fit zoom to screen",
+ "zoom.level": "Zoom level",
+ "settings.theme.mode": "主題模式",
+ "diagnostics.category.canvas": "Canvas Integrity",
+ "diagnostics.category.output": "Output & Execution",
+ "diagnostics.category.session": "Session & Safety",
+ "diagnostics.category.notice": "Runtime Notices",
+ "diagnostics.summary.ok": "All systems OK",
+ "diagnostics.summary.warningCount": "{0} warning(s) detected",
+ "diagnostics.summary.errorCount": "{0} error(s) detected",
+ "diagnostics.canvasMigration": "Canvas Migration",
+ "diagnostics.recommendation.resaveFile": "Re-save the file to update it to the latest schema version.",
+ "diagnostics.canvasState.name": "Canvas State",
+ "diagnostics.canvasState.recommendation": "Add at least one {0} and one {1}",
+ "diagnostics.canvasState.empty": "Canvas is empty - no nodes present",
+ "diagnostics.canvasState.counts": "{0} node(s), {1} connection(s)",
+ "diagnostics.validation.name": "Validation Errors",
+ "diagnostics.validation.recommendation": "Fix highlighted nodes before running output preview",
+ "diagnostics.validation.errorWithWarnings": "{0} error(s) and {1} warning(s) in the graph",
+ "diagnostics.validation.warningOnly": "{0} warning(s) in the graph",
+ "diagnostics.validation.none": "No validation issues",
+ "diagnostics.orphan.name": "Orphan Nodes",
+ "diagnostics.orphan.recommendation": "Use the orphan cleanup action to remove unused nodes",
+ "diagnostics.orphan.count": "{0} node(s) not connected to any output",
+ "diagnostics.orphan.none": "No orphan nodes detected",
+ "diagnostics.naming.name": "Naming Conventions",
+ "diagnostics.naming.recommendation": "Use auto-fix alias naming when conformance is below 100%",
+ "diagnostics.naming.conformance": "Naming conformance: {0}%",
+ "diagnostics.naming.ok": "All aliases follow naming conventions (100%)",
+ "diagnostics.queryCompilation.name": "Live SQL Compilation",
+ "diagnostics.queryCompilation.recommendation": "Review SQL diagnostics in output when errors/warnings are reported.",
+ "diagnostics.queryCompilation.errorFallback": "Live SQL compilation reported errors.",
+ "diagnostics.queryCompilation.warningCounts": "{0} diagnostic item(s), {1} guardrail warning(s).",
+ "diagnostics.queryCompilation.ok": "Live SQL compiled without diagnostics.",
+ "diagnostics.previewSafety.name": "Preview Safety",
+ "diagnostics.previewSafety.recommendation": "Preview executes read-only statements only.",
+ "diagnostics.previewSafety.blocked": "Current SQL is mutating and blocked by Safe Preview mode.",
+ "diagnostics.previewSafety.ok": "Preview safety checks passed.",
+ "diagnostics.previewExecution.name": "Preview Execution",
+ "diagnostics.previewExecution.recommendation": "Run preview and inspect diagnostics for execution/runtime errors.",
+ "diagnostics.previewExecution.failed": "Preview execution failed.",
+ "diagnostics.previewExecution.cancelled": "Preview execution was cancelled.",
+ "diagnostics.previewExecution.done": "{0} row(s) in {1}ms.",
+ "diagnostics.previewExecution.none": "No preview execution issues detected.",
+ "diagnostics.ddlCompilation.name": "DDL Compilation",
+ "diagnostics.ddlCompilation.recommendation": "Fix DDL compile diagnostics before execution.",
+ "diagnostics.ddlCompilation.failed": "DDL compilation failed.",
+ "diagnostics.ddlCompilation.warningCount": "{0} warning(s) reported by DDL compiler.",
+ "diagnostics.ddlCompilation.ok": "DDL compilation succeeded.",
+ "diagnostics.ddlOutput.name": "DDL Output",
+ "diagnostics.ddlOutput.recommendation": "Add/complete DDL nodes until at least one statement is generated.",
+ "diagnostics.ddlOutput.none": "No DDL statements generated yet.",
+ "diagnostics.ddlOutput.lines": "{0} line(s) of DDL generated.",
+ "diagnostics.undo.name": "Undo History",
+ "diagnostics.undo.recommendation": "History is in-memory only; save your canvas regularly.",
+ "diagnostics.undo.saved": "Canvas is saved (no unsaved changes).",
+ "diagnostics.undo.unsavedDeep": "Unsaved changes with {0} undo steps.",
+ "diagnostics.undo.unsaved": "Unsaved changes - {0} undo step(s) available.",
+ "diagnostics.report.title": "AkkornStudio - Diagnostic Report",
+ "diagnostics.report.generated": "Generated",
+ "diagnostics.report.overall": "Overall",
+ "diagnostics.report.details": "Details",
+ "diagnostics.report.recommendation": "Recommendation",
+ "diagnostics.report.lastCheck": "Last Check",
+ "sqlImporter.watermark": "SELECT column_a, column_b FROM schema_name.table_name WHERE condition LIMIT 100",
+ "node.datetimeFormat": "YYYY-MM-DDTHH:mm:ss",
+ "preview.providerLabel": "Provider",
+ "preview.ddlDiagnosticsHint": "Error/warning details are available in Diagnostics.",
+ "common.navigate": "Navigate",
+ "common.close": "Close",
+ "common.esc": "Esc",
+ "common.ms": "ms",
+ "common.zero": "0",
+ "diagnostics.tip": "Tip: check Diagnostics whenever preview/output reports warnings or errors.",
+ "nodesList.empty": "No nodes found",
+ "nodesList.emptyHint": "Adjust the search term to explore available types",
+ "schema.emptyFiltered": "No objects found for the current filter",
+ "start.lastSnapshot": "Last snapshot",
+ "app.brandBadge": "VS",
+ "property.tab.properties": "Properties",
+ "property.tab.projectSettings": "Project Settings",
+ "property.nodeType": "NODE TYPE",
+ "property.selectNodeHint": "Select a node to edit its properties.",
+ "property.namingConventions": "Naming Conventions",
+ "property.aliasConvention": "Alias convention",
+ "property.enforceAliasNaming": "Enforce alias naming",
+ "property.warnReservedSql": "Warn on reserved SQL keywords",
+ "property.maxAliasLength": "Max alias length",
+ "property.maxAliasLengthDefault": "64",
+ "property.namingSettingsHint": "These settings are project-scoped and are used by naming and validation helpers.",
+ "start.tips": "Tips",
+ "start.tips.quick": "Quick tips",
+ "start.tips.item1": "1. Click New Diagram to start from scratch.",
+ "start.tips.item2": "2. Use templates to speed up prototyping.",
+ "start.tips.item3": "3. Open saved connections to load real tables.",
+ "start.tips.shortcut": "Shortcut: CTRL+SHIFT+P opens the command palette.",
+ "start.workspace": "WORKSPACE",
+ "start.resumeTitle": "Continue where you left off",
+ "start.resumeSubtitle": "Quickly resume a recent project or start a new diagram.",
+ "start.chip.quickFlow": "Quick flow",
+ "start.chip.templates": "Templates",
+ "start.chip.connections": "Connections",
+ "start.savedConnectionsTitle": "Saved Connections",
+ "start.savedConnectionsSubtitle": "Connect quickly to a database to load schema and tables.",
+ "start.noConnectionsTitle": "No connections configured yet",
+ "start.noConnectionsSubtitle": "Create a connection to explore real tables in the editor.",
+ "start.newConnection": "+ New Connection",
+ "start.recentProjectsTitle": "Recent Projects",
+ "start.searchRecent": "Search recent project...",
+ "start.quickActions": "Quick actions",
+ "start.quickActionsSubtitle": "Open an existing file or start a new diagram.",
+ "start.noRecentTitle": "No recent projects yet",
+ "start.noRecentSubtitle": "Use the quick actions card above to get started.",
+ "start.exploreTemplates": "Explore templates",
+ "start.templatesFavoritesHint": "Favorites on top",
+ "start.favoriteTemplate": "Favorite template",
+ "node.columnSetPreview": "ColumnSet preview",
+ "node.view": "VIEW",
+ "node.tableDefinition": "Table Definition",
+ "node.join": "JOIN",
+ "node.window.addPartition": "Add PARTITION BY slot",
+ "node.window.removePartition": "Remove PARTITION BY slot",
+ "node.window.addOrder": "Add ORDER BY slot",
+ "node.window.removeOrder": "Remove ORDER BY slot",
+ "sql.keyword.select": "SELECT",
+ "sql.keyword.from": "FROM",
+ "sql.keyword.join": "JOIN",
+ "sql.keyword.where": "WHERE",
+ "sql.keyword.limit": "LIMIT",
+ "sqlImporter.close": "Close SQL importer",
+ "sqlImporter.report.imported": "Imported",
+ "sqlImporter.report.partial": "Partial",
+ "sqlImporter.report.skipped": "Skipped",
+ "benchmark.close": "Close benchmark",
+ "benchmark.p95": "P95",
+ "benchmark.n": "N",
+ "liveSql.safePreview": "SAFE PREVIEW MODE",
+ "liveSql.title": "LIVE SQL",
+ "liveSql.blocked": "BLOCKED",
+ "liveSql.copy": "Copy",
+ "liveSql.format": "Format",
+ "liveSql.benchmark": "Benchmark",
+ "liveSql.explain": "Explain",
+ "liveSql.actionsHint": "Performance tools",
+ "ddl.dialog.title": "Execute DDL",
+ "ddl.dialog.execute": "Execute",
+ "ddl.dialog.cancel": "Cancel",
+ "ddl.dialog.close": "Close",
+ "ddl.dialog.stopOnError": "Stop on first failure",
+ "ddl.dialog.confirmDestructive": "I confirm execution of destructive statements (DROP TABLE)",
+ "ddl.dialog.reviewBeforeRun": "Review the DDL script before confirming.",
+ "ddl.dialog.confirmQuestion": "Confirm DDL execution on the connected database?",
+ "ddl.dialog.irreversibleWarning": "This action can change the schema irreversibly.",
+ "ddl.dialog.mustConfirmDestructive": "Confirm destructive execution to continue.",
+ "ddl.dialog.executing": "Executing...",
+ "ddl.execute.result.summary": "Statements: {0} | Success: {1} | Failures: {2} | Time: {3:0}ms",
+ "ddl.execute.result.okLine": "[{0}] OK | rows={1} | {2}",
+ "ddl.execute.result.failLine": "[{0}] FAIL | {1} | {2}",
+ "ddl.execute.result.failed": "Failed to execute DDL.",
+ "ddl.execute.result.cancelled": "Execution cancelled by the user.",
+ "ddl.execute.result.cancelledDetails": "DDL execution was interrupted before completion.",
+ "context.deleteSingle": "Delete {0}",
+ "context.deleteMultiple": "Delete {0} nodes",
+ "context.bringForward": "Bring Forward (Ctrl+PgUp)",
+ "context.sendBackward": "Send Backward (Ctrl+PgDown)",
+ "context.bringToFront": "Bring to Front (Ctrl+Shift+PgUp)",
+ "context.sendToBack": "Send to Back (Ctrl+Shift+PgDown)",
+ "context.normalizeLayers": "Normalize Layers",
+ "context.deleteWire": "Delete wire",
+ "context.addNode": "Add Node (Shift+A)",
+ "context.undoWithDescription": "Undo {0}",
+ "context.redo": "Redo",
+ "shortcuts.windowTitle": "Keyboard Shortcuts",
+ "shortcuts.headerTitle": "AkkornStudio - Shortcuts",
+ "shortcuts.headerHint": "Tip: use CTRL+SHIFT+P to open the Command Palette and search commands.",
+ "shortcuts.filterWatermark": "Filter shortcuts by key or action...",
+ "shortcuts.resultCount": "{0} shortcuts",
+ "shortcuts.resultFilter": "{0} result(s) for \"{1}\"",
+ "shortcuts.noneFound": "No shortcuts found.",
+ "shortcuts.section.fileGeneral": "檔案與一般",
+ "shortcuts.section.editing": "編輯",
+ "shortcuts.section.canvasNavigation": "畫布與導覽",
+ "shortcuts.section.zoomPanPrecision": "縮放、平移與精準控制",
+ "shortcuts.section.previewInspection": "預覽與檢視",
+ "shortcuts.key.deleteOrBackspace": "Del 或 Backspace",
+ "shortcuts.key.middleDrag": "中鍵 + 拖曳",
+ "shortcuts.key.rightDrag": "右鍵 + 拖曳",
+ "shortcuts.key.spaceDrag": "空白鍵 + 拖曳",
+ "shortcuts.key.altLeftDrag": "Alt + 左鍵拖曳",
+ "shortcuts.key.arrows": "方向鍵",
+ "shortcuts.key.shiftArrows": "Shift + 方向鍵",
+ "shortcuts.action.openShortcutScreen": "開啟此快捷鍵畫面",
+ "shortcuts.action.newCanvas": "新畫布",
+ "shortcuts.action.openFile": "開啟檔案",
+ "shortcuts.action.save": "儲存",
+ "shortcuts.action.saveAs": "另存新檔",
+ "shortcuts.action.commandPalette": "命令面板",
+ "shortcuts.action.undo": "復原",
+ "shortcuts.action.redo": "重做",
+ "shortcuts.action.selectAll": "全選",
+ "shortcuts.action.deleteSelection": "刪除選取",
+ "shortcuts.action.closeOverlayCancel": "關閉覆蓋層 / 取消操作",
+ "shortcuts.action.openNodeSearch": "開啟節點搜尋",
+ "shortcuts.action.resetViewport": "重設視窗",
+ "shortcuts.action.centerSelection": "置中選取",
+ "shortcuts.action.fitSelection": "適配選取",
+ "shortcuts.action.autoLayout": "自動佈局",
+ "shortcuts.action.toggleSnapToGrid": "切換對齊格線",
+ "shortcuts.action.bringForward": "往前一層",
+ "shortcuts.action.sendBackward": "往後一層",
+ "shortcuts.action.bringToFront": "移到最前",
+ "shortcuts.action.sendToBack": "移到最後",
+ "shortcuts.action.zoomInOut": "放大 / 縮小",
+ "shortcuts.action.pan": "平移",
+ "shortcuts.action.temporaryPan": "暫時平移",
+ "shortcuts.action.alternatePan": "替代平移",
+ "shortcuts.action.fineNudge": "精細移動選取",
+ "shortcuts.action.fastNudge": "快速移動",
+ "shortcuts.action.togglePreview": "切換資料預覽",
+ "shortcuts.action.explainPlan": "執行計畫",
+ "shortcuts.action.runPreview": "執行預覽",
+ "shortcuts.action.connectionManager": "連線管理器",
+ "shortcuts.action.flowVersionHistory": "流程版本歷史",
+ "shortcuts.resetAll": "全部重設",
+ "shortcuts.customized": "已自訂",
+ "shortcuts.default": "預設",
+ "shortcuts.apply": "套用",
+ "shortcuts.reset": "重設",
+ "shortcuts.status.resetAllSuccess": "所有快速鍵已重設為預設值。",
+ "shortcuts.status.updated": "快速鍵已更新。",
+ "shortcuts.status.reset": "快速鍵已重設為預設值。",
+ "shortcuts.status.updateFailed": "無法更新快速鍵。",
+ "toast.severity.success": "Success",
+ "toast.severity.warning": "Warning",
+ "toast.severity.error": "Error",
+ "toast.details.success": "Success Details",
+ "toast.details.warning": "Warning Details",
+ "toast.details.error": "Error Details",
+ "diagnostics.area.cteEditor": "CTE Editor",
+ "diagnostics.area.viewEditor": "View Editor",
+ "diagnostics.area.subEditor": "Sub-editor",
+ "diagnostics.cteEditor.restoreParentFailed": "Failed to restore the parent canvas. CTE edits were discarded.",
+ "diagnostics.recommendation.reloadFileIfNeeded": "Reload the file if needed.",
+ "diagnostics.viewEditor.exitFailed": "Could not exit: {0}",
+ "diagnostics.viewEditor.canvasIncomplete": "the canvas is incomplete.",
+ "diagnostics.viewEditor.exitRecommendation": "Connect a valid ResultOutput or use the discard command.",
+ "diagnostics.viewEditor.restoreParentFailed": "Failed to restore the parent canvas. The subgraph was discarded.",
+ "diagnostics.subEditor.executeFailed": "Failed to execute editor action: {0}",
+ "diagnostics.subEditor.executeRecommendation": "Try again. If it persists, reload the canvas.",
+ "diagnostics.canvasMigration.openWarning": "Open: {0}",
+ "diagnostics.canvasMigration.sessionRestoreWarning": "Session restore: {0}",
+ "diagnostics.canvasMigration.versionRestoreWarning": "Version restore: {0}",
+ "diagnostics.recommendation.resaveLatestSchema": "Review diagnostics and re-save the canvas to persist the latest schema.",
+ "diagnostics.recommendation.saveMigratedSchema": "Review diagnostics and save the canvas to persist the migrated schema.",
+ "file.saveDialog.title": "Save Canvas",
+ "file.saveDialog.suggestedName": "Query1",
+ "file.save.success": "Canvas saved successfully.",
+ "file.save.failedWithReason": "Save failed: {0}",
+ "file.openDialog.title": "Open Canvas",
+ "file.open.failedWithReason": "Open failed: {0}",
+ "file.open.success": "Canvas opened successfully.",
+ "file.open.successWithWarnings": "Canvas opened with warnings.",
+ "session.restore.failedWithReason": "Restore failed: {0}",
+ "session.restore.successWithWarnings": "Session restored with warnings.",
+ "session.restore.success": "Session restored successfully.",
+ "export.documentation.dialogTitle": "Export Flow Documentation",
+ "export.documentation.success": "Documentation exported successfully.",
+ "export.documentation.failed": "Documentation export failed.",
+ "export.failed.pathPermissionsHint": "Check file path and permissions.",
+ "export.nodeNotFound": "No {0} Export node found on the canvas. Add one via the node search menu.",
+ "export.dialogTitleByExtension": "Export as {0}",
+ "export.success": "Export completed successfully.",
+ "export.failed": "Export failed.",
+ "fileHistory.currentFile.none": "No file selected",
+ "fileHistory.status.saveFirst": "Save the canvas first to enable local history.",
+ "fileHistory.status.noneFound": "No local versions found yet. Save this file to create history entries.",
+ "fileHistory.status.countAvailable": "{0} local version(s) available.",
+ "fileHistory.restore.failedWithReason": "Restore failed: {0}",
+ "fileHistory.restore.successFrom": "Restored version from {0}.",
+ "preview.status.cancelled": "Cancelled",
+ "preview.status.error": "Error",
+ "preview.status.ready": "Ready",
+ "preview.runningWithMs": "Running... {0}ms",
+ "preview.runningWithTimeout": "Running... {0}ms (timeout: {1}s)",
+ "preview.runningSlowWithTimeout": "Running... {0}ms (timeout: {1}s) · Slow query, timeout in {2}s",
+ "explain.errorWithReason": "Explain plan error: {0}",
+ "explain.noSql": "No SQL to explain. Build a query on the canvas first.",
+ "ddl.compilationFailed": "Compilation failed",
+ "ddl.compileErrorWithReason": "DDL compile error: {0}",
+ "command.undo.name": "Undo",
+ "command.undo.description": "Undo last action",
+ "command.redo.name": "Redo",
+ "command.redo.description": "Redo last undone action",
+ "command.addNode.name": "Add Node",
+ "command.addNode.description": "Open node search menu to add a node",
+ "command.bringForward.name": "Bring Forward",
+ "command.bringForward.description": "Move selected nodes one layer forward",
+ "command.sendBackward.name": "Send Backward",
+ "command.sendBackward.description": "Move selected nodes one layer backward",
+ "command.bringToFront.name": "Bring to Front",
+ "command.bringToFront.description": "Move selected nodes to top layer",
+ "command.sendToBack.name": "Send to Back",
+ "command.sendToBack.description": "Move selected nodes to bottom layer",
+ "command.normalizeLayers.name": "Normalize Layers",
+ "command.normalizeLayers.description": "Compact node layer indices to a clean 0..N order",
+ "tooltip.cleanupOrphans": "Remove orphan nodes not connected to the output (Ctrl+Z to undo)",
+ "main.orphanSuffix": "Orphan(s)",
+ "tooltip.autoFixAliasNaming": "Fix alias naming to snake_case (Ctrl+Z to undo)",
+ "main.namingPrefix": "Naming",
+ "fileHistory.compressedLabel": "Compressed:",
+ "schema.itemsSuffix": "item(s)",
+ "property.panel.title": "Properties",
+ "property.panel.multiSelected": "{0} nodes selected",
+ "sqlImporter.status.pasteSelect": "Paste a SELECT statement above, then click Import.",
+ "sqlImporter.status.inputTooLarge": "SQL input is too large ({0:N0} chars). Limit is {1:N0}. Split the query or increase the import limit.",
+ "sqlImporter.status.parsing": "Parsing SQL...",
+ "sqlImporter.status.done": "Done - {0} imported, {1} partial, {2} skipped.",
+ "sqlImporter.status.cancelledByUser": "Import cancelled by user.",
+ "sqlImporter.status.timeout": "Import timed out after {0:0.#}s. Try a smaller query or increase timeout.",
+ "sqlImporter.status.parseError": "Parse error: {0}",
+ "diagnostics.area.undoRedoTransaction": "Undo/Redo Transaction",
+ "undoRedo.rollbackExecuted": "Rollback executed for '{0}' ({1} operation(s) reverted).",
+ "undoRedo.rollbackRecommendation": "Review the canvas state and retry the action if needed.",
+ "node.preview.noCatalog": "No catalog available",
+ "connection.error.searchMenuNotInitialized": "search menu not initialized",
+ "connection.error.timeoutReachability": "Connection timed out - check that the server is reachable and increase the timeout if needed.",
+ "connection.error.authenticationFailedForProvider": "Authentication failed - verify username and password for {0}.",
+ "connection.error.databaseNotFoundForProvider": "Database not found - confirm the database name exists on {0}.",
+ "connection.error.hostNotFound": "Host not found - check the server address and DNS resolution.",
+ "connection.error.portRefused": "Port connection refused - check the port number and that the server is running / firewall rules allow access.",
+ "connection.error.sslTls": "SSL/TLS error - check the server's SSL configuration or disable SSL for local connections.",
+ "connection.error.timeoutOverloaded": "Connection timed out - the server may be overloaded or unreachable. Try increasing the timeout.",
+ "connection.error.insufficientPrivileges": "Insufficient privileges - the user may lack permission to connect to this database.",
+ "diagnostics.area.connection": "Connection",
+ "connection.warning.canvasMayContainOldTables": "The canvas may still contain tables from a previous connection.",
+ "connection.warning.canvasMayContainOldTablesRecommendation": "Clear the canvas manually or reconnect and choose keep/clear again.",
+ "undoRedo.transaction.unnamed": "unnamed transaction",
+ "benchmark.runLabelDefault": "Run 1",
+ "benchmark.runLabelPattern": "Run {0}",
+ "benchmark.status.failedWithReason": "Benchmark failed: {0}",
+ "benchmark.status.noSql": "No SQL to benchmark - build a query first.",
+ "benchmark.status.warmupProgress": "Warm-up {0}/{1}...",
+ "benchmark.status.iterationProgress": "Iteration {0}/{1}...",
+ "benchmark.status.done": "Done - {0}",
+ "benchmark.status.cancelled": "Benchmark cancelled.",
+ "app.windowTitle": "AkkornStudio",
+ "preview.error.safePreviewBlocked": "Safe Preview Mode: data-mutating commands (INSERT/UPDATE/DELETE/DROP/ALTER/TRUNCATE) cannot be executed in preview.",
+ "preview.error.noActiveConnection": "No active database connection. Please connect to a database first.",
+ "sqlImporter.error.selectFromNotFound": "Could not find SELECT ... FROM in the query.",
+ "sqlImporter.error.fromClauseParseFailed": "Could not parse FROM clause.",
+ "sqlImporter.error.syntaxUnterminatedString": "Syntax error at line {0}, column {1}: unterminated string literal.",
+ "sqlImporter.error.missingClosingParenthesis": "missing closing ')'",
+ "sqlImporter.error.unexpectedClosingParenthesis": "unexpected ')'",
+ "sqlImporter.error.syntaxAtLineColumn": "Syntax error at line {0}, column {1}: {2}.",
+ "errorDiagnostics.safePreview.label": "Blocked by Safe Preview Mode",
+ "errorDiagnostics.safePreview.friendly": "This SQL contains a data-mutating command and cannot be executed in preview.",
+ "errorDiagnostics.safePreview.suggestion": "Remove or replace the mutating command (INSERT / UPDATE / DELETE / DROP / ALTER / TRUNCATE) before running preview.",
+ "errorDiagnostics.connection.label": "Connection failed",
+ "errorDiagnostics.connection.friendly": "Could not reach the database server. The host may be down, unreachable, or blocking connections.",
+ "errorDiagnostics.connection.suggestion": "Verify the server address and port, ensure the database is running, and check firewall rules.",
+ "errorDiagnostics.authorization.label": "Authorization error",
+ "errorDiagnostics.authorization.friendly": "The current credentials do not have permission to perform this operation.",
+ "errorDiagnostics.authorization.suggestion": "Confirm the database user has SELECT privileges on the target table/schema, or contact your DBA.",
+ "errorDiagnostics.timeout.label": "Query timeout",
+ "errorDiagnostics.timeout.friendly": "The query took too long to complete and was cancelled by the server or client.",
+ "errorDiagnostics.timeout.suggestion": "Add a WHERE clause or LIMIT to reduce the result set, or increase the query timeout in connection settings.",
+ "errorDiagnostics.schema.label": "Schema error",
+ "errorDiagnostics.schema.friendly": "A referenced table, column, or object could not be found in the database.",
+ "errorDiagnostics.schema.suggestion": "Check that all table/column names are spelled correctly and that the schema matches the active connection.",
+ "errorDiagnostics.syntax.label": "SQL syntax error",
+ "errorDiagnostics.syntax.friendly": "The query contains a syntax error and could not be parsed by the database engine.",
+ "errorDiagnostics.syntax.suggestion": "Review the highlighted SQL for typos, mismatched parentheses, or unsupported clauses for the active provider.",
+ "errorDiagnostics.compatibility.label": "Compatibility error",
+ "errorDiagnostics.compatibility.friendly": "A function, operator, or syntax construct is not supported by the active database provider.",
+ "errorDiagnostics.compatibility.suggestion": "Switch to the correct provider in the SQL bar, or replace the unsupported construct with an equivalent.",
+ "errorDiagnostics.unknown.label": "Unexpected error",
+ "errorDiagnostics.unknown.friendly": "An error occurred while running the preview query.",
+ "errorDiagnostics.unknown.suggestion": "Check the technical details below and verify that your canvas is configured correctly.",
+ "error.mainWindow.invalidDataContext": "MainWindow 的 DataContext 必須是 ShellViewModel。",
+ "error.mainWindow.canvasNotInitialized": "CanvasViewModel 尚未初始化。",
+ "error.mainWindow.ddlPreviewUnavailable": "目前畫布無法使用 DDL 預覽。",
+ "themeJson.editor.template": "{\n \"meta\": { \"name\": \"自訂主題\" },\n \"colors\": {\n \"macroBg0\": \"#0B1020\",\n \"textPrimary\": \"#E8EAED\",\n \"textSecondary\": \"#8B95A8\"\n }\n}",
+ "themeJson.error.pasteBeforeApply": "套用前請先貼上主題 JSON。",
+ "themeJson.error.invalidJson": "無效的 JSON:{0}",
+ "themeJson.error.emptyPayload": "無效的 JSON:內容為空。",
+ "themeJson.error.invalidTheme": "無效的主題:{0}",
+ "themeJson.error.appliedButSaveFailed": "主題已套用,但儲存失敗:{0}",
+ "themeJson.success.appliedAndSaved": "JSON 主題已套用並儲存。",
+ "themeJson.success.customRemoved": "已移除自訂主題。請重新啟動應用程式以完全回到預設主題。",
+ "themeJson.error.restoreDefaultFailed": "還原預設主題失敗:{0}",
+ "themeValidator.error.configNull": "主題設定為 null。",
+ "themeValidator.warning.noSections": "主題沒有色彩或字體設定區段;無可套用內容。",
+ "themeValidator.warning.invalidColor": "{0} 的色彩 '{1}' 無效。此鍵將被忽略。",
+ "themeValidator.warning.sizeOutOfRange": "{0}={1} 超出範圍 (8..48)。此鍵將被忽略。",
+ "queryExecutor.error.openConnectionMethodNotFound": "在 orchestrator 中找不到 OpenConnectionAsync 方法",
+ "queryExecutor.error.openConnectionInvokeFailed": "呼叫 OpenConnectionAsync 失敗",
+ "ddlImporter.warning.viewSelectNotReconstructable": "View '{0}':此 view 的 SELECT 無法以視覺方式重建,請在子畫布手動編輯。",
+ "ddlImporter.error.tableNotFoundInMetadata": "在目前中繼資料中找不到資料表 '{0}'。",
+ "main.window.untitled": "未命名",
+ "main.subEditor.noSeedProvided": "未提供 {0} 的子編輯器 seed。",
+ "main.layerOrder.bringToFront": "移到最上層",
+ "main.layerOrder.sendToBack": "移到最下層",
+ "main.layerOrder.bringForward": "向前一層",
+ "main.layerOrder.sendBackward": "向後一層",
+ "main.layerOrder.normalizeLayers": "正規化圖層",
+ "export.fileType.html": "HTML 檔案",
+ "export.fileType.json": "JSON 檔案",
+ "export.fileType.csv": "CSV 檔案",
+ "export.fileType.excel": "Excel 檔案",
+ "commandPalette.templatePrefix": "範本:{0}",
+ "themeLoader.status.notFoundWithPath": "找不到主題檔案:{0}",
+ "themeLoader.status.deserializedNull": "主題 JSON 反序列化結果為 null。",
+ "themeLoader.status.loaded": "主題 JSON 載入成功。",
+ "credential.error.ciphertextTooShort": "密文資料太短。",
+ "credential.error.dpapiWindowsOnly": "DPAPI 僅支援 Windows。",
+ "credential.warning.loadVaultFailed": "載入憑證保險庫 {0} 失敗:{1}",
+ "credential.warning.persistVaultFailed": "儲存憑證保險庫 {0} 失敗:{1}",
+ "snippetStore.warning.loadFailed": "從 {0} 載入 snippet 失敗:{1}",
+ "snippetStore.warning.saveFailed": "儲存 snippet 失敗:{0}",
+ "flowVersionStore.warning.loadFailed": "從 {0} 載入流程版本失敗:{1}",
+ "flowVersionStore.warning.saveFailed": "儲存流程版本失敗:{0}",
+ "queryExecutor.error.queryEmpty": "查詢不可為空",
+ "queryExecutor.error.providerNotSupported": "不支援供應者 {0}",
+ "queryExecutor.error.singleStatementOnly": "預覽僅接受單一 SQL 語句。",
+ "queryExecutor.error.queryEmptyWithPeriod": "查詢不可為空。",
+ "queryExecutor.error.readOnlyOnly": "預覽模式僅支援唯讀 SQL。",
+ "queryExecutor.error.namedParametersNotSupported": "預覽模式不支援執行 SQL 的命名參數。請改用安全內嵌常值或在預覽外執行查詢。",
+ "queryExecutor.error.positionalParametersNotSupported": "預覽模式不支援位置參數佔位符(? 或 )。",
+ "commandPalette.description.align_selected_nodes_to_the_bottom_edge": "將所選節點對齊到底部邊緣",
+ "commandPalette.description.align_selected_nodes_to_the_leftmost_edge": "將所選節點對齊到最左側邊緣",
+ "commandPalette.description.align_selected_nodes_to_the_rightmost_edge": "將所選節點對齊到最右側邊緣",
+ "commandPalette.description.align_selected_nodes_to_the_topmost_edge": "將所選節點對齊到頂部邊緣",
+ "commandPalette.description.apply_cte_sub_canvas_edits_and_return_to_the_parent_canvas": "套用 CTE 子畫布編輯並返回父畫布",
+ "commandPalette.description.arrange_nodes_into_logical_columns_automatically": "自動將節點排列為邏輯欄位",
+ "commandPalette.description.centre_selected_nodes_on_a_horizontal_axis": "在水平軸上置中所選節點",
+ "commandPalette.description.centre_selected_nodes_on_a_vertical_axis": "在垂直軸上置中所選節點",
+ "commandPalette.description.clear_canvas_and_start_fresh": "清空畫布並重新開始",
+ "commandPalette.description.clear_node_selection": "清除節點選取",
+ "commandPalette.description.convert_aliases_to_the_convention_configured_in_project_settings": "將別名轉換為專案設定中的命名慣例",
+ "commandPalette.description.create_checkpoints_compare_versions_side_by_side_and_restore_a_previous_canvas_state": "建立檢查點、並排比較版本並還原先前畫布狀態",
+ "commandPalette.description.delete_the_selected_nodes": "刪除所選節點",
+ "commandPalette.description.discard_current_sub_editor_edits_and_return_to_the_parent_canvas": "捨棄目前子編輯器變更並返回父畫布",
+ "commandPalette.description.execute_the_current_query_in_preview": "在預覽中執行目前查詢",
+ "commandPalette.description.fit_all_nodes_into_the_visible_area": "將所有節點適配至可視區域",
+ "commandPalette.description.generate_csv_file_from_the_first_csv_export_node": "從第一個 CSV 匯出節點產生 CSV 檔案",
+ "commandPalette.description.generate_html_file_from_the_first_html_export_node": "從第一個 HTML 匯出節點產生 HTML 檔案",
+ "commandPalette.description.generate_json_file_from_the_first_json_export_node": "從第一個 JSON 匯出節點產生 JSON 檔案",
+ "commandPalette.description.generate_xlsx_workbook_from_the_first_excel_export_node": "從第一個 Excel 匯出節點產生 XLSX 活頁簿",
+ "commandPalette.description.inspect_the_query_execution_plan_see_scan_types_join_strategies_and_cost_estimates": "檢視查詢執行計畫:掃描類型、Join 策略與成本估算",
+ "commandPalette.description.load_a_vsaq_canvas_file": "載入 .vsaq 畫布檔案",
+ "commandPalette.description.measure_avg_median_p95_latency_of_the_current_sql_over_n_iterations": "測量目前 SQL 在 N 次迭代下的平均/中位/p95 延遲",
+ "commandPalette.description.open_isolated_sub_canvas_editor_for_the_selected_cte_definition_node": "為所選 CTE 定義節點開啟獨立子畫布編輯器",
+ "commandPalette.description.open_local_file_version_history_created_on_each_save_and_restore_previous_saved_snapshots": "開啟每次儲存產生的本機版本歷史並還原先前快照",
+ "commandPalette.description.open_output_preview_modal_for_the_active_mode": "開啟目前模式的輸出預覽對話框",
+ "commandPalette.description.open_shortcut_reference_screen": "開啟快捷鍵參考畫面",
+ "commandPalette.description.open_the_connection_manager_to_add_edit_or_switch_database_connections": "開啟連線管理器以新增、編輯或切換資料庫連線",
+ "commandPalette.description.paste_a_select_statement_and_generate_nodes_automatically_from_join_where_limit_are_supported": "貼上 SELECT 語句並自動產生節點(支援 FROM、JOIN、WHERE、LIMIT)",
+ "commandPalette.description.remove_all_nodes_not_connected_to_output": "移除所有未連接到輸出的節點",
+ "commandPalette.description.reset_zoom_and_pan_to_default": "將縮放與平移重設為預設值",
+ "commandPalette.description.save_canvas_to_a_new_file": "將畫布儲存為新檔案",
+ "commandPalette.description.save_current_canvas": "儲存目前畫布",
+ "commandPalette.description.save_markdown_documentation_of_the_current_flow": "儲存目前流程的 Markdown 文件",
+ "commandPalette.description.save_the_selected_nodes_as_a_reusable_snippet_insert_it_later_via_the_node_search_menu_a": "將所選節點儲存為可重用片段,稍後可透過節點搜尋選單(⇧A)插入",
+ "commandPalette.description.scan_all_table_source_nodes_on_the_canvas_for_possible_join_relationships_based_on_fk_conventions_and_naming_patterns": "依據 FK 慣例與命名模式掃描畫布上的表來源節點,找出可能的 Join 關係",
+ "commandPalette.description.select_all_nodes_on_canvas": "選取畫布上的所有節點",
+ "commandPalette.description.snap_node_positions_to_16px_grid_ctrl_g": "將節點位置吸附到 16px 網格(Ctrl+G)",
+ "commandPalette.description.spread_selected_nodes_with_equal_horizontal_spacing": "將所選節點以相等水平間距分佈",
+ "commandPalette.description.spread_selected_nodes_with_equal_vertical_spacing": "將所選節點以相等垂直間距分佈",
+ "commandPalette.description.zoom_into_the_canvas": "放大畫布",
+ "commandPalette.description.zoom_out_of_the_canvas": "縮小畫布",
+ "commandPalette.name.align_bottom": "底部對齊",
+ "commandPalette.name.align_left": "靠左對齊",
+ "commandPalette.name.align_right": "靠右對齊",
+ "commandPalette.name.align_top": "頂部對齊",
+ "commandPalette.name.analyze_all_joins": "分析所有 Join",
+ "commandPalette.name.auto_fix_naming": "自動修正命名",
+ "commandPalette.name.auto_layout": "自動排版",
+ "commandPalette.name.center_horizontally": "水平置中",
+ "commandPalette.name.center_vertically": "垂直置中",
+ "commandPalette.name.cleanup_orphans": "清理孤立節點",
+ "commandPalette.name.delete_selected": "刪除已選取",
+ "commandPalette.name.deselect_all": "取消全選",
+ "commandPalette.name.discard_and_exit_editor": "放棄並離開編輯器",
+ "commandPalette.name.distribute_horizontally": "水平平均分佈",
+ "commandPalette.name.distribute_vertically": "垂直平均分佈",
+ "commandPalette.name.edit_selected_cte": "編輯所選 CTE",
+ "commandPalette.name.exit_cte_editor": "離開 CTE 編輯器",
+ "commandPalette.name.explain_plan": "執行計畫",
+ "commandPalette.name.export_csv": "匯出 CSV",
+ "commandPalette.name.export_documentation": "匯出文件",
+ "commandPalette.name.export_excel": "匯出 Excel",
+ "commandPalette.name.export_html": "匯出 HTML",
+ "commandPalette.name.export_json": "匯出 JSON",
+ "commandPalette.name.file_save_load_history": "檔案儲存/載入歷史",
+ "commandPalette.name.fit_to_screen": "符合畫面",
+ "commandPalette.name.flow_version_history": "流程版本歷史",
+ "commandPalette.name.import_sql_to_graph": "將 SQL 匯入為圖形",
+ "commandPalette.name.keyboard_shortcuts": "鍵盤快捷鍵",
+ "commandPalette.name.manage_connections": "管理連線",
+ "commandPalette.name.new_canvas": "新增畫布",
+ "commandPalette.name.open_file": "開啟檔案",
+ "commandPalette.name.reset_viewport": "重設檢視區域",
+ "commandPalette.name.run_preview": "執行預覽",
+ "commandPalette.name.run_query_benchmark": "執行查詢效能測試",
+ "commandPalette.name.save": "儲存",
+ "commandPalette.name.save_as": "另存新檔",
+ "commandPalette.name.save_selection_as_snippet": "將選取儲存為片段",
+ "commandPalette.name.select_all": "全選",
+ "commandPalette.name.toggle_preview": "切換預覽",
+ "commandPalette.name.toggle_snap_to_grid": "切換格線吸附",
+ "commandPalette.name.zoom_in": "放大",
+ "commandPalette.name.zoom_out": "縮小",
+ "commandPalette.tags.100_percent_restore_zoom_pan_viewport": "100 percent restore zoom pan viewport",
+ "commandPalette.tags.align_bottom_edge_selection_nodes": "align bottom edge selection nodes",
+ "commandPalette.tags.align_center_middle_horizontal_nodes": "align center middle horizontal nodes",
+ "commandPalette.tags.align_center_middle_vertical_nodes": "align center middle vertical nodes",
+ "commandPalette.tags.align_left_edge_selection_nodes": "align left edge selection nodes",
+ "commandPalette.tags.align_right_edge_selection_nodes": "align right edge selection nodes",
+ "commandPalette.tags.align_top_edge_selection_nodes": "align top edge selection nodes",
+ "commandPalette.tags.auto_layout_view_reset_zoom": "auto layout view reset zoom",
+ "commandPalette.tags.benchmark_performance_latency_timing_profile_measure_speed": "benchmark performance latency timing profile measure speed",
+ "commandPalette.tags.clear_selection": "clear selection",
+ "commandPalette.tags.connection_database_server_host_provider_switch": "connection database server host provider switch",
+ "commandPalette.tags.create_insert_search_transform": "create insert search transform",
+ "commandPalette.tags.cte_subcanvas_exit_apply_back": "cte subcanvas exit apply back",
+ "commandPalette.tags.cte_view_subcanvas_discard_exit_force": "cte view subcanvas discard exit force",
+ "commandPalette.tags.cte_with_recursive_editor_subgraph_subcanvas_isolate": "cte with recursive editor subgraph subcanvas isolate",
+ "commandPalette.tags.data_results_table_panel": "data results table panel",
+ "commandPalette.tags.distribute_space_equal_horizontal_nodes": "distribute space equal horizontal nodes",
+ "commandPalette.tags.distribute_space_equal_vertical_nodes": "distribute space equal vertical nodes",
+ "commandPalette.tags.execute_run_sql_query_results": "execute run sql query results",
+ "commandPalette.tags.explain_plan_execution_cost_scan_index_join_performance": "explain plan execution cost scan index join performance",
+ "commandPalette.tags.export_csv_file_tabular_output_save": "export csv file tabular output save",
+ "commandPalette.tags.export_excel_xlsx_file_tabular_output_spreadsheet_save": "export excel xlsx file tabular output spreadsheet save",
+ "commandPalette.tags.export_html_file_output_report_save": "export html file output report save",
+ "commandPalette.tags.export_json_file_output_save": "export json file output save",
+ "commandPalette.tags.export_markdown_doc_documentation_flow_save_md": "export markdown doc documentation flow save md",
+ "commandPalette.tags.export_persist_copy": "export persist copy",
+ "commandPalette.tags.file_history_save_load_backup_versions_restore_local": "file history save load backup versions restore local",
+ "commandPalette.tags.forward_history": "forward history",
+ "commandPalette.tags.help_shortcuts_hotkeys_keyboard_reference": "help shortcuts hotkeys keyboard reference",
+ "commandPalette.tags.highlight_mark_all_nodes": "highlight mark all nodes",
+ "commandPalette.tags.import_sql_paste_convert_graph_reverse_engineer_query": "import sql paste convert graph reverse engineer query",
+ "commandPalette.tags.join_autojoin_analyze_suggest_detect_foreign_key_relationships_heuristic": "join autojoin analyze suggest detect foreign key relationships heuristic",
+ "commandPalette.tags.layer_z_order_back_selected_nodes": "layer z-order back selected nodes",
+ "commandPalette.tags.layer_z_order_backward_selected_nodes": "layer z-order backward selected nodes",
+ "commandPalette.tags.layer_z_order_forward_selected_nodes": "layer z-order forward selected nodes",
+ "commandPalette.tags.layer_z_order_front_selected_nodes": "layer z-order front selected nodes",
+ "commandPalette.tags.layer_z_order_normalize_compact": "layer z-order normalize compact",
+ "commandPalette.tags.layout_arrange_columns_auto_organize_readability": "layout arrange columns auto organize readability",
+ "commandPalette.tags.load_import_vsaq": "load import vsaq",
+ "commandPalette.tags.magnify_enlarge": "magnify enlarge",
+ "commandPalette.tags.orphan_unused_disconnected_clean_delete_nodes": "orphan unused disconnected clean delete nodes",
+ "commandPalette.tags.persist_write_disk": "persist write disk",
+ "commandPalette.tags.remove_erase_nodes": "remove erase nodes",
+ "commandPalette.tags.rename_alias_fix_naming_convention": "rename alias fix naming convention",
+ "commandPalette.tags.reset_clear_blank": "reset clear blank",
+ "commandPalette.tags.revert_back_history": "revert back history",
+ "commandPalette.tags.shrink_reduce": "shrink reduce",
+ "commandPalette.tags.snap_grid_align_precision_position": "snap grid align precision position",
+ "commandPalette.tags.snippet_save_selection_reuse_template_favorite_bookmark": "snippet save selection reuse template favorite bookmark",
+ "commandPalette.tags.version_history_checkpoint_diff_restore_snapshot_compare_undo_flow": "version history checkpoint diff restore snapshot compare undo flow",
+ "sqlEditor.diffPreview.title": "Transactional Diff Preview",
+ "sqlEditor.mutation.confirmExecute": "Confirm Execute",
+ "sqlEditor.tab.closeAnyway": "Close Anyway",
+ "sqlEditor.tab.keepTab": "Keep Tab",
+ "sqlEditor.status.ready": "Ready.",
+ "sqlEditor.telemetry.none": "No execution telemetry yet.",
+ "sqlEditor.telemetry.summary": "Statements: {0} Success: {1} Failed: {2} Total: {3} ms",
+ "sqlEditor.telemetry.errors.none": "No aggregated errors.",
+ "sqlEditor.diff.none": "No transactional diff preview available.",
+ "sqlEditor.mutation.estimate.none": "No mutation estimate available.",
+ "sqlEditor.mutation.estimate.value": "Estimated affected rows: {0}",
+ "sqlEditor.mutation.estimate.unavailable": "Could not estimate affected rows automatically.",
+ "sqlEditor.tab.closePending": "Unsaved changes detected. Confirm tab close.",
+ "sqlEditor.tab.noPendingClose": "No tab close pending.",
+ "sqlEditor.tab.manyWarning": "High tab count: {0} open tabs.",
+ "sqlEditor.mutation.pending.none": "No pending mutation confirmation.",
+ "sqlEditor.mutation.pending.required": "Mutation requires confirmation before execution.",
+ "sqlEditor.message.empty": "Execute a statement to see messages.",
+ "sqlEditor.message.success": "Execution completed successfully.",
+ "sqlEditor.result.summary.empty": "Rows: - Time: -",
+ "sqlEditor.result.summary": "Rows: {0} Time: {1} ms",
+ "sqlEditor.file.save.canceled": "Save canceled.",
+ "sqlEditor.file.save.noPath": "No target path selected.",
+ "sqlEditor.file.save.success": "SQL file saved.",
+ "sqlEditor.file.save.failed": "Save failed.",
+ "sqlEditor.file.open.failed": "Open failed.",
+ "sqlEditor.file.open.notFound": "Selected SQL file was not found.",
+ "sqlEditor.file.open.success": "SQL file opened.",
+ "sqlEditor.status.executing": "Executing SQL...",
+ "sqlEditor.status.executingScript": "Executing SQL script...",
+ "sqlEditor.status.executingStep": "Executing {0}/{1}...",
+ "sqlEditor.status.canceling": "Canceling execution...",
+ "sqlEditor.status.executingConfirmedMutation": "Executing confirmed mutation...",
+ "sqlEditor.status.mutationCanceled": "Mutation execution canceled.",
+ "sqlEditor.detail.statementNotExecuted": "Statement was not executed.",
+ "sqlEditor.status.success": "Execution succeeded.",
+ "sqlEditor.detail.rowsAndTime": "{0} row(s) in {1} ms.",
+ "sqlEditor.status.canceled": "Execution canceled.",
+ "sqlEditor.status.failed": "Execution failed.",
+ "sqlEditor.status.confirmationRequired": "Confirmation required before execution.",
+ "sqlEditor.error.mutationConfirmationRequired": "Mutation confirmation required.",
+ "sqlEditor.result.tabTitle": "Result {0}",
+ "sqlEditor.tab.closeRequiresConfirmation": "Tab close requires confirmation.",
+ "sqlEditor.tab.unsavedDetail": "This tab has unsaved changes.",
+ "sqlEditor.tab.closed": "Tab closed.",
+ "sqlEditor.tab.closeCanceled": "Tab close canceled.",
+ "sqlEditor.tab.closeCanceledDetail": "Unsaved tab kept open.",
+ "sqlEditor.error.noStatementSelected": "No SQL statement selected for execution.",
+ "sqlEditor.error.noConnection": "No active database connection for SQL execution.",
+ "sqlEditor.error.executionCanceled": "SQL execution was canceled.",
+ "sqlEditor.tab.scriptTitle": "Script {0}",
+ "sqlEditor.guard.delete.noWhere.message": "DELETE without WHERE can remove all rows.",
+ "sqlEditor.guard.delete.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
+ "sqlEditor.guard.delete.trivialWhere.message": "DELETE has a trivially true WHERE clause.",
+ "sqlEditor.guard.delete.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
+ "sqlEditor.guard.update.noWhere.message": "UPDATE without WHERE can affect all rows.",
+ "sqlEditor.guard.update.noWhere.recommendation": "Add a restrictive WHERE clause before executing.",
+ "sqlEditor.guard.update.trivialWhere.message": "UPDATE has a trivially true WHERE clause.",
+ "sqlEditor.guard.update.trivialWhere.recommendation": "Use a selective filter to target only intended rows.",
+ "sqlEditor.guard.insert.noColumnList.message": "INSERT without explicit column list is fragile against schema changes.",
+ "sqlEditor.guard.insert.noColumnList.recommendation": "Prefer INSERT INTO table(col1, col2, ...) VALUES (...).",
+ "sqlEditor.guard.ddl.message": "DDL statement may cause structural changes in the database.",
+ "sqlEditor.guard.ddl.recommendation": "Confirm execution only when schema changes are intended.",
+ "sqlEditor.diff.unavailable.noPreview": "No transactional diff preview available for this statement.",
+ "sqlEditor.diff.unavailable.parseError": "Could not parse mutation target for transactional diff preview.",
+ "sqlEditor.diff.unavailable.connection": "Transactional diff preview unavailable due to connection or query limitations.",
+ "sqlEditor.diff.deleteSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, affected {2}, total rows after {3}.",
+ "sqlEditor.diff.updateSummary": "Transactional diff preview (ROLLBACK guaranteed): table {0}, total rows before {1}, candidate rows affected {2}, total rows after {3}.",
+ "sqlEditor.diff.unavailable.unsupportedStatement": "Transactional diff preview currently supports UPDATE and DELETE only.",
+ "sqlEditor.results.title": "Results",
+ "sqlEditor.saveSql.fileType": "SQL Files",
+ "sqlEditor.saveSql.pickerTitle": "Save SQL File",
+ "sqlEditor.export.pickerTitle": "Export SQL Data",
+ "sqlEditor.export.status.noResultTitle": "No execution result available for export.",
+ "sqlEditor.export.status.noResultDetail": "Execute a query first.",
+ "sqlEditor.export.status.successTitle": "Report exported.",
+ "sqlEditor.export.status.failedTitle": "Failed to export report.",
+ "sqlEditor.export.fileType.html": "HTML File",
+ "sqlEditor.export.fileType.json": "JSON File",
+ "sqlEditor.export.fileType.csv": "CSV File",
+ "sqlEditor.export.fileType.xlsx": "Excel Workbook",
+ "sqlEditor.export.defaultFileBase": "report",
+ "sqlEditor.export.defaultTitle": "SQL Report",
+ "sqlEditor.export.error.typeRequired": "A report type must be selected before export.",
+ "sqlEditor.export.type.html.title": "HTML full-feature report",
+ "sqlEditor.export.type.html.description": "Standalone, SQL-first HTML artifact for offline audit.",
+ "sqlEditor.export.type.json.title": "JSON execution contract",
+ "sqlEditor.export.type.json.description": "Machine-readable payload with SQL, metadata and execution result.",
+ "sqlEditor.export.type.csv.title": "CSV data export",
+ "sqlEditor.export.type.csv.description": "Tabular result data only, suitable for spreadsheet tools.",
+ "sqlEditor.export.type.xlsx.title": "Excel workbook export",
+ "sqlEditor.export.type.xlsx.description": "Spreadsheet workbook with query result data only.",
+ "sqlEditor.export.dialog.windowTitle": "Export SQL Data",
+ "sqlEditor.export.dialog.title": "Export SQL Data",
+ "sqlEditor.export.dialog.subtitle": "Choose the artifact format and metadata before exporting.",
+ "sqlEditor.export.dialog.confirm": "Export",
+ "sqlEditor.export.dialog.fileNameWatermark": "report.html",
+ "sqlEditor.export.dialog.titleWatermark": "SQL Report",
+ "sqlEditor.export.dialog.descriptionWatermark": "Additional context for auditors and teammates.",
+ "sqlEditor.export.dialog.section.reportType": "REPORT TYPE",
+ "sqlEditor.export.dialog.section.fileName": "FILE NAME",
+ "sqlEditor.export.dialog.section.reportTitle": "TITLE",
+ "sqlEditor.export.dialog.section.description": "DESCRIPTION",
+ "sqlEditor.export.dialog.section.options": "OPTIONS",
+ "sqlEditor.export.option.includeSchema": "Include output schema",
+ "sqlEditor.export.option.includeNodeDetails": "Include node/connection placeholders in JSON",
+ "sqlEditor.export.option.includeMetadata": "Include optional metadata",
+ "sqlEditor.export.option.useDashForEmpty": "Use '-' for empty fields",
+ "sqlEditor.export.badge.offline": "OFFLINE READY",
+ "sqlEditor.export.badge.structured": "STRUCTURED PAYLOAD",
+ "sqlEditor.export.badge.dataOnly": "DATA ONLY"
+}
diff --git a/src/AkkornStudio.UI/Assets/ReportFrontend/dist/report-app.css b/src/AkkornStudio.UI/Assets/ReportFrontend/dist/report-app.css
new file mode 100644
index 00000000..4b1aafc4
--- /dev/null
+++ b/src/AkkornStudio.UI/Assets/ReportFrontend/dist/report-app.css
@@ -0,0 +1 @@
+:root{color-scheme:dark;--bg: #0a101b;--surface: #0f1728;--surface-2: #141f35;--surface-3: #1b2942;--border: #2a3b5d;--border-strong: #385180;--text: #edf3ff;--text-soft: #9eb0d2;--text-strong: #f8fbff;--accent: #6ea8fe;--accent-strong: #88b4ff;--accent-soft: rgba(110, 168, 254, .14);--success: #72e2a1;--warning: #f4c26b;--danger: #ff8d94;--shadow: 0 20px 60px rgba(3, 10, 21, .28)}:root[data-theme=light]{color-scheme:light;--bg: #f4f7fb;--surface: #ffffff;--surface-2: #f6f8fc;--surface-3: #eef2f9;--border: #d4dceb;--border-strong: #bbc7dc;--text: #162136;--text-soft: #5e6d88;--text-strong: #0d1728;--accent: #356ef1;--accent-strong: #275ad7;--accent-soft: rgba(53, 110, 241, .12);--success: #2f8f57;--warning: #b26d00;--danger: #d14255;--shadow: 0 24px 54px rgba(23, 42, 79, .12)}*{box-sizing:border-box}body{margin:0;font-family:Segoe UI,system-ui,sans-serif;background:var(--bg);color:var(--text)}button,input,select{font:inherit;outline:none}button:focus,input:focus,select:focus,button:focus-visible,input:focus-visible,select:focus-visible{outline:none}.report-shell{max-width:1680px;margin:0 auto;padding:28px}.page-header,.panel,.mini-panel,.modal-card,.toast{box-shadow:var(--shadow)}.page-header,.panel,.mini-panel,.modal-card,.ghost-btn,.collapse-btn,.field-input,.chip,.pager,.pick-item,.icon-only{border:1px solid var(--border)}.page-header,.panel,.mini-panel,.modal-card{background:#0f1728db;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}:root[data-theme=light] .page-header,:root[data-theme=light] .panel,:root[data-theme=light] .mini-panel,:root[data-theme=light] .modal-card{background:#ffffffeb}.page-header{display:grid;grid-template-columns:260px minmax(320px,1fr) auto;gap:24px;align-items:center;border-radius:24px;padding:24px}.brand-wrap{display:flex;gap:14px;align-items:center}.brand-mark{width:48px;height:48px;display:grid;place-items:center;border-radius:16px;background:var(--surface-2);color:var(--accent);font-weight:800;font-size:1.15rem;border:1px solid var(--border)}.brand-name{font-size:.76rem;font-weight:800;letter-spacing:.16em;text-transform:uppercase;color:var(--text-soft)}.brand-sub{font-size:.95rem;font-weight:700;color:var(--text-strong)}.page-intro h1{margin:0 0 10px;font-size:clamp(1.4rem,2vw,2rem);line-height:1.1}.toolbar{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:10px;align-items:center}.main-content{display:grid;gap:18px;margin-top:20px}.panel{border-radius:24px;padding:18px}.section-head{display:flex;justify-content:space-between;gap:18px;align-items:center;margin-bottom:14px}.section-head h2{margin:0;font-size:1.05rem}.section-copy{margin-top:6px;font-size:.92rem;color:var(--text-soft)}.section-actions{display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-end;align-items:center}.overview-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px}.overview-card{display:flex;gap:14px;align-items:start;padding:18px;border-radius:20px;background:var(--surface);border:1px solid var(--border)}.overview-card.is-wide{grid-column:1 / -1}.overview-card.is-warning{border-color:#f4c26b59}.overview-icon{width:42px;height:42px;display:grid;place-items:center;border-radius:14px;background:var(--accent-soft);color:var(--accent)}.overview-label{font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;color:var(--text-soft)}.overview-value{margin-top:8px;font-size:1rem;font-weight:700;line-height:1.45}.dataset-body{display:grid;gap:14px}.summary-strip{display:grid;gap:12px}.mini-panel{border-radius:18px;padding:14px;background:var(--surface-2)}.mini-panel-head{display:flex;justify-content:space-between;gap:12px;align-items:center}.mini-panel-title{font-weight:700}.mini-panel-actions{display:flex;gap:8px}.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.chip{display:inline-flex;align-items:center;gap:6px;padding:8px 12px;border-radius:999px;background:var(--surface);color:var(--text-soft)}.chip.empty{opacity:.8}.chip.removable{cursor:pointer}.table-shell{position:relative;display:grid;gap:12px}.table-shell.is-page-busy .table-scroll,.table-shell.is-page-busy .pager{opacity:.72}.table-loading{position:absolute;top:56px;right:0;bottom:72px;left:0;display:grid;place-items:center;pointer-events:none;z-index:8}.table-loading-card{display:inline-flex;align-items:center;gap:10px;padding:10px 14px;border-radius:999px;border:1px solid var(--border);background:#0f1728eb;color:var(--text);box-shadow:var(--shadow)}:root[data-theme=light] .table-loading-card{background:#fffffff2}.table-loading-spinner{width:14px;height:14px;border-radius:999px;border:2px solid var(--border-strong);border-top-color:var(--accent);animation:spin .8s linear infinite}.table-meta{display:flex;justify-content:space-between;gap:14px;align-items:flex-start;flex-wrap:wrap}.table-meta-main,.preset-toolbar,.preset-actions,.preset-secondary,.table-status,.table-quick-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.table-meta-main{flex:1 1 420px}.preset-toolbar{gap:10px}.preset-segmented{display:inline-flex;flex-wrap:wrap;gap:4px;padding:4px;border:1px solid var(--border);border-radius:999px;background:var(--surface-2)}.segment-btn,.icon-chip{border:0;border-radius:999px;background:transparent;color:var(--text-soft);cursor:pointer}.segment-btn{padding:9px 12px;font-weight:700}.segment-btn:hover,.icon-chip:hover{background:var(--surface);color:var(--text)}.icon-chip{width:34px;height:34px;display:inline-grid;place-items:center;border:1px solid var(--border);background:var(--surface)}.quick-filters-wrap{overflow-x:auto;padding-bottom:2px}.quick-filters{display:flex;flex-wrap:nowrap;gap:8px;align-items:center;min-width:max-content}.quick-filters-label{color:var(--text-soft);font-size:.86rem;font-weight:700;position:sticky;left:0;padding-right:4px;background:var(--surface)}.quick-chip{background:var(--surface-2);border:1px solid var(--border);padding:6px 10px}.quick-chip small{opacity:.72;padding:2px 6px;border-radius:999px;background:var(--surface)}.result-count{font-weight:700;color:var(--text-soft);padding-inline:2px}.status-pill{display:inline-flex;align-items:center;gap:6px;padding:8px 12px;border-radius:999px;background:var(--surface-2);color:var(--text-soft);border:1px solid var(--border);font-size:.88rem}.pager-wrap{display:flex;flex-wrap:wrap;gap:14px;align-items:center;justify-content:flex-end}.pager-wrap-bottom{padding-top:4px}.page-size-wrap{display:grid;gap:6px}.pager{display:flex;align-items:center;gap:8px;border-radius:16px;padding:8px;background:var(--surface-2)}.pager-readout{min-width:110px;text-align:center;color:var(--text-soft);font-weight:700}.pager-input{width:70px;padding:10px 12px;border-radius:12px;border:1px solid var(--border);background:var(--surface);color:var(--text)}.table-scroll{position:relative;overflow-x:auto;overflow-y:hidden;border-radius:18px;border:1px solid var(--border)}.table-scroll.has-left-shadow:before,.table-scroll.has-right-shadow:after{content:"";position:sticky;top:0;bottom:0;width:18px;pointer-events:none;z-index:6}.table-scroll.has-left-shadow:before{left:0;float:left;background:linear-gradient(90deg,rgba(10,16,27,.7),transparent)}.table-scroll.has-right-shadow:after{right:0;float:right;background:linear-gradient(270deg,rgba(10,16,27,.7),transparent)}:root[data-theme=light] .table-scroll.has-left-shadow:before{background:linear-gradient(90deg,rgba(244,247,251,.9),transparent)}:root[data-theme=light] .table-scroll.has-right-shadow:after{background:linear-gradient(270deg,rgba(244,247,251,.9),transparent)}.report-table{width:max-content;min-width:100%;border-collapse:separate;border-spacing:0;min-width:920px}.report-table thead th{background:var(--surface-2);border-bottom:1px solid var(--border);padding:0;z-index:1}.th-shell{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:stretch}.sort-head{width:100%;display:flex;justify-content:space-between;align-items:center;gap:10px;border:0;background:transparent;color:inherit;padding:14px;font-weight:700;cursor:pointer}.resize-handle{width:28px;min-width:28px;border:0;border-left:1px solid var(--border);background:transparent;color:var(--text-soft);cursor:col-resize;display:grid;place-items:center}.resize-handle:hover{color:var(--accent);background:var(--accent-soft)}.resize-handle:active{background:var(--surface-3)}.report-table tbody td{padding:0;border-bottom:1px solid rgba(255,255,255,.06)}:root[data-theme=light] .report-table tbody td{border-bottom-color:#1a233614}.cell-body{display:flex;align-items:start;gap:10px;padding:13px 14px}.cell{cursor:pointer;vertical-align:top}.cell-text{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.cell-expand{flex:0 0 auto;border:0;background:transparent;color:var(--text-soft);cursor:pointer}.select-col{width:28px;min-width:28px;background:var(--surface-2)}.select-col-width{width:28px}.sticky-select{position:sticky;left:0;z-index:4}.sticky-main-col{position:sticky;left:28px;z-index:3;background:var(--surface);box-shadow:8px 0 18px #050a1224}.report-table thead .sticky-main-col{background:var(--surface-2)}.row-selector{width:100%;min-height:100%;min-width:28px;padding:0;border:0;background:transparent;cursor:pointer;color:var(--text-soft)}.row-selector:hover,.is-row-selected .row-selector{color:var(--accent)}.is-row-selected td{background:#6ea8fe14}.is-selected-cell{outline:2px solid var(--accent);outline-offset:-2px;background:#6ea8fe1f}.is-number .cell-text{color:#7cc7ff}.is-date .cell-text{color:#f4c26b}.is-boolean .cell-text{color:#78dba5;font-weight:700}.is-null .cell-text{color:var(--text-soft);font-style:italic}.empty-state{padding:28px;text-align:center;color:var(--text-soft)}.sql-box{padding:18px;border-radius:18px;background:#0a1120;border:1px solid var(--border);overflow:auto}.sql-box pre,.cell-modal-text{margin:0;white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.page-footer{margin:18px 0 8px;text-align:center;color:var(--text-soft)}.modal-shell{position:fixed;top:0;right:0;bottom:0;left:0;display:grid;place-items:center;padding:24px;background:#040a12a8;z-index:20}.modal-card{width:min(980px,100%);max-height:88vh;overflow:hidden;border-radius:22px;display:grid;grid-template-rows:auto 1fr auto}.modal-card.modal-wide{width:min(1180px,100%)}.modal-card.modal-cell{width:min(1080px,100%)}.modal-head,.modal-foot{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:18px 20px;border-bottom:1px solid var(--border)}.modal-foot{border-top:1px solid var(--border);border-bottom:0;justify-content:flex-end}.modal-title{font-size:1.08rem;font-weight:800}.modal-body{overflow:auto;padding:20px}.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.field-span{grid-column:1 / -1}.field-stack{display:grid;gap:8px}.field-label{display:inline-flex;align-items:center;gap:8px;font-size:.84rem;font-weight:700;color:var(--text-soft)}.field-input{width:100%;border-radius:14px;padding:12px 14px;background:var(--surface);color:var(--text)}.field-input.compact-search{min-width:220px;border:0;background:transparent;padding-left:0;padding-right:0}.preset-select{min-width:180px}.sort-rules{display:grid;gap:12px}.sort-rule{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr) auto;gap:12px;align-items:end;padding:14px;border:1px solid var(--border);border-radius:16px;background:var(--surface-2)}.sort-remove{align-self:end}.field-input:focus,.field-input:focus-visible,.compact-select:focus,.compact-select:focus-visible,.pager-input:focus,.pager-input:focus-visible,.compact-search:focus,.compact-search:focus-visible{outline:none;box-shadow:none;border-color:var(--border)}.compact-select{width:84px}.search-field{display:inline-flex;align-items:center;gap:10px;min-width:260px;padding:0 12px;border:1px solid var(--border);border-radius:14px;background:var(--surface);color:var(--text-soft)}.ghost-btn,.collapse-btn,.icon-only{display:inline-flex;align-items:center;justify-content:center;gap:8px;border-radius:14px;padding:11px 14px;background:var(--surface);color:var(--text);cursor:pointer}.ghost-btn.small{padding:8px 10px}.icon-only{width:42px;height:42px;padding:0}.ghost-btn:disabled,.icon-only:disabled{opacity:.45;cursor:not-allowed}.ghost-btn:hover:not(:disabled),.collapse-btn:hover,.icon-only:hover:not(:disabled),.sort-head:hover,.pick-item:hover{border-color:var(--border-strong);background:var(--surface-3)}.picklist{display:grid;grid-template-columns:minmax(0,1fr) 96px minmax(0,1fr);gap:14px;align-items:center}.pick-pane{display:grid;gap:10px}.pick-list{display:grid;gap:8px;min-height:320px;max-height:440px;overflow:auto;padding:10px;border:1px solid var(--border);border-radius:18px;background:var(--surface-2)}.pick-item{text-align:left;border-radius:12px;padding:12px 14px;background:var(--surface);color:var(--text);cursor:pointer}.pick-item.active{border-color:var(--accent);background:var(--accent-soft)}.pick-actions{display:grid;gap:10px}.icon-glyph,.icon-glyph svg{width:16px;height:16px;display:inline-block}.toast{position:fixed;right:24px;bottom:24px;padding:14px 18px;border-radius:16px;background:var(--surface);color:var(--text-strong);z-index:30}@keyframes spin{to{transform:rotate(360deg)}}.context-menu{position:fixed;min-width:220px;display:grid;gap:4px;padding:8px;border-radius:16px;border:1px solid var(--border-strong);background:var(--surface);box-shadow:var(--shadow);z-index:40}.context-item{display:inline-flex;align-items:center;gap:8px;width:100%;padding:10px 12px;border:0;border-radius:12px;background:transparent;color:var(--text);cursor:pointer}.context-item:hover{background:var(--surface-3)}@media(max-width:1160px){.page-header{grid-template-columns:1fr}.toolbar{justify-content:flex-start}}@media(max-width:920px){.report-shell{padding:16px}.section-head,.table-meta,.modal-head,.modal-foot{flex-direction:column;align-items:stretch}.section-actions{justify-content:stretch}.form-grid,.picklist,.sort-rule{grid-template-columns:1fr}.field-span{grid-column:auto}}
diff --git a/src/AkkornStudio.UI/Assets/ReportFrontend/dist/report-app.js b/src/AkkornStudio.UI/Assets/ReportFrontend/dist/report-app.js
new file mode 100644
index 00000000..9a565aa0
--- /dev/null
+++ b/src/AkkornStudio.UI/Assets/ReportFrontend/dist/report-app.js
@@ -0,0 +1,214 @@
+(function(){"use strict";/**
+* @vue/shared v3.5.33
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/function yn(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const ce={},Ft=[],We=()=>{},uo=()=>!1,Ps=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Rs=e=>e.startsWith("onUpdate:"),ve=Object.assign,gn=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},vl=Object.prototype.hasOwnProperty,ee=(e,t)=>vl.call(e,t),W=Array.isArray,jt=e=>ss(e)==="[object Map]",Kt=e=>ss(e)==="[object Set]",fo=e=>ss(e)==="[object Date]",z=e=>typeof e=="function",pe=e=>typeof e=="string",Be=e=>typeof e=="symbol",oe=e=>e!==null&&typeof e=="object",po=e=>(oe(e)||z(e))&&z(e.then)&&z(e.catch),ho=Object.prototype.toString,ss=e=>ho.call(e),_l=e=>ss(e).slice(8,-1),mo=e=>ss(e)==="[object Object]",bn=e=>pe(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,ns=yn(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Es=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},xl=/-\w/g,Le=Es(e=>e.replace(xl,t=>t.slice(1).toUpperCase())),Cl=/\B([A-Z])/g,wt=Es(e=>e.replace(Cl,"-$1").toLowerCase()),yo=Es(e=>e.charAt(0).toUpperCase()+e.slice(1)),vn=Es(e=>e?`on${yo(e)}`:""),st=(e,t)=>!Object.is(e,t),Ds=(e,...t)=>{for(let s=0;s{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Os=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let bo;const $s=()=>bo||(bo=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function gt(e){if(W(e)){const t={};for(let s=0;s{if(s){const n=s.split(wl);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Ne(e){let t="";if(pe(e))t=e;else if(W(e))for(let s=0;sbt(s,t))}const _o=e=>!!(e&&e.__v_isRef===!0),x=e=>pe(e)?e:e==null?"":W(e)||oe(e)&&(e.toString===ho||!z(e.toString))?_o(e)?x(e.value):JSON.stringify(e,xo,2):String(e),xo=(e,t)=>_o(t)?xo(e,t.value):jt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,o],i)=>(s[xn(n,i)+" =>"]=o,s),{})}:Kt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>xn(s))}:Be(t)?xn(t):oe(t)&&!W(t)&&!mo(t)?String(t):t,xn=(e,t="")=>{var s;return Be(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/**
+* @vue/reactivity v3.5.33
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/let _e;class Pl{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.__v_skip=!0,this.parent=_e,!t&&_e&&(this.index=(_e.scopes||(_e.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t0&&--this._on===0){if(_e===this)_e=this.prevScope;else{let t=_e;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s0)return;if(is){let t=is;for(is=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;os;){let t=os;for(os=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function So(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Mo(e){let t,s=e.depsTail,n=s;for(;n;){const o=n.prevDep;n.version===-1?(n===s&&(s=o),Mn(n),El(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=o}e.deps=t,e.depsTail=s}function Sn(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Ao(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Ao(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===ls)||(e.globalVersion=ls,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Sn(e))))return;e.flags|=2;const t=e.dep,s=ue,n=He;ue=e,He=!0;try{So(e);const o=e.fn(e._value);(t.version===0||st(o,e._value))&&(e.flags|=128,e._value=o,t.version++)}catch(o){throw t.version++,o}finally{ue=s,He=n,Mo(e),e.flags&=-3}}function Mn(e,t=!1){const{dep:s,prevSub:n,nextSub:o}=e;if(n&&(n.nextSub=o,e.prevSub=void 0),o&&(o.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let i=s.computed.deps;i;i=i.nextDep)Mn(i,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function El(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let He=!0;const To=[];function ze(){To.push(He),He=!1}function qe(){const e=To.pop();He=e===void 0?!0:e}function Po(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=ue;ue=void 0;try{t()}finally{ue=s}}}let ls=0;class Dl{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Ro{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!ue||!He||ue===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==ue)s=this.activeLink=new Dl(ue,this),ue.deps?(s.prevDep=ue.depsTail,ue.depsTail.nextDep=s,ue.depsTail=s):ue.deps=ue.depsTail=s,Eo(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=ue.depsTail,s.nextDep=void 0,ue.depsTail.nextDep=s,ue.depsTail=s,ue.deps===s&&(ue.deps=n)}return s}trigger(t){this.version++,ls++,this.notify(t)}notify(t){kn();try{for(let s=this.subs;s;s=s.prevSub)s.sub.notify()&&s.sub.dep.notify()}finally{wn()}}}function Eo(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let n=t.deps;n;n=n.nextDep)Eo(n)}const s=e.dep.subs;s!==e&&(e.prevSub=s,s&&(s.nextSub=e)),e.dep.subs=e}}const An=new WeakMap,St=Symbol(""),Tn=Symbol(""),rs=Symbol("");function xe(e,t,s){if(He&&ue){let n=An.get(e);n||An.set(e,n=new Map);let o=n.get(s);o||(n.set(s,o=new Ro),o.map=n,o.key=s),o.track()}}function nt(e,t,s,n,o,i){const r=An.get(e);if(!r){ls++;return}const c=u=>{u&&u.trigger()};if(kn(),t==="clear")r.forEach(c);else{const u=W(e),v=u&&bn(s);if(u&&s==="length"){const y=Number(n);r.forEach((C,$)=>{($==="length"||$===rs||!Be($)&&$>=y)&&c(C)})}else switch((s!==void 0||r.has(void 0))&&c(r.get(s)),v&&c(r.get(rs)),t){case"add":u?v&&c(r.get("length")):(c(r.get(St)),jt(e)&&c(r.get(Tn)));break;case"delete":u||(c(r.get(St)),jt(e)&&c(r.get(Tn)));break;case"set":jt(e)&&c(r.get(St));break}}wn()}function Lt(e){const t=te(e);return t===e?t:(xe(t,"iterate",rs),Ue(e)?t:t.map(it))}function Is(e){return xe(e=te(e),"iterate",rs),e}function Je(e,t){return vt(e)?Nt(Mt(e)?it(t):t):it(t)}const Ol={__proto__:null,[Symbol.iterator](){return Pn(this,Symbol.iterator,e=>Je(this,e))},concat(...e){return Lt(this).concat(...e.map(t=>W(t)?Lt(t):t))},entries(){return Pn(this,"entries",e=>(e[1]=Je(this,e[1]),e))},every(e,t){return ot(this,"every",e,t,void 0,arguments)},filter(e,t){return ot(this,"filter",e,t,s=>s.map(n=>Je(this,n)),arguments)},find(e,t){return ot(this,"find",e,t,s=>Je(this,s),arguments)},findIndex(e,t){return ot(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return ot(this,"findLast",e,t,s=>Je(this,s),arguments)},findLastIndex(e,t){return ot(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return ot(this,"forEach",e,t,void 0,arguments)},includes(...e){return Rn(this,"includes",e)},indexOf(...e){return Rn(this,"indexOf",e)},join(e){return Lt(this).join(e)},lastIndexOf(...e){return Rn(this,"lastIndexOf",e)},map(e,t){return ot(this,"map",e,t,void 0,arguments)},pop(){return cs(this,"pop")},push(...e){return cs(this,"push",e)},reduce(e,...t){return Do(this,"reduce",e,t)},reduceRight(e,...t){return Do(this,"reduceRight",e,t)},shift(){return cs(this,"shift")},some(e,t){return ot(this,"some",e,t,void 0,arguments)},splice(...e){return cs(this,"splice",e)},toReversed(){return Lt(this).toReversed()},toSorted(e){return Lt(this).toSorted(e)},toSpliced(...e){return Lt(this).toSpliced(...e)},unshift(...e){return cs(this,"unshift",e)},values(){return Pn(this,"values",e=>Je(this,e))}};function Pn(e,t,s){const n=Is(e),o=n[t]();return n!==e&&!Ue(e)&&(o._next=o.next,o.next=()=>{const i=o._next();return i.done||(i.value=s(i.value)),i}),o}const $l=Array.prototype;function ot(e,t,s,n,o,i){const r=Is(e),c=r!==e&&!Ue(e),u=r[t];if(u!==$l[t]){const C=u.apply(e,i);return c?it(C):C}let v=s;r!==e&&(c?v=function(C,$){return s.call(this,Je(e,C),$,e)}:s.length>2&&(v=function(C,$){return s.call(this,C,$,e)}));const y=u.call(r,v,n);return c&&o?o(y):y}function Do(e,t,s,n){const o=Is(e),i=o!==e&&!Ue(e);let r=s,c=!1;o!==e&&(i?(c=n.length===0,r=function(v,y,C){return c&&(c=!1,v=Je(e,v)),s.call(this,v,Je(e,y),C,e)}):s.length>3&&(r=function(v,y,C){return s.call(this,v,y,C,e)}));const u=o[t](r,...n);return c?Je(e,u):u}function Rn(e,t,s){const n=te(e);xe(n,"iterate",rs);const o=n[t](...s);return(o===-1||o===!1)&&On(s[0])?(s[0]=te(s[0]),n[t](...s)):o}function cs(e,t,s=[]){ze(),kn();const n=te(e)[t].apply(e,s);return wn(),qe(),n}const Il=yn("__proto__,__v_isRef,__isVue"),Oo=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Be));function Vl(e){Be(e)||(e=String(e));const t=te(this);return xe(t,"has",e),t.hasOwnProperty(e)}class $o{constructor(t=!1,s=!1){this._isReadonly=t,this._isShallow=s}get(t,s,n){if(s==="__v_skip")return t.__v_skip;const o=this._isReadonly,i=this._isShallow;if(s==="__v_isReactive")return!o;if(s==="__v_isReadonly")return o;if(s==="__v_isShallow")return i;if(s==="__v_raw")return n===(o?i?Lo:Ko:i?jo:Fo).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(n)?t:void 0;const r=W(t);if(!o){let u;if(r&&(u=Ol[s]))return u;if(s==="hasOwnProperty")return Vl}const c=Reflect.get(t,s,Ce(t)?t:n);if((Be(s)?Oo.has(s):Il(s))||(o||xe(t,"get",s),i))return c;if(Ce(c)){const u=r&&bn(s)?c:c.value;return o&&oe(u)?Dn(u):u}return oe(c)?o?Dn(c):as(c):c}}class Io extends $o{constructor(t=!1){super(!1,t)}set(t,s,n,o){let i=t[s];const r=W(t)&&bn(s);if(!this._isShallow){const v=vt(i);if(!Ue(n)&&!vt(n)&&(i=te(i),n=te(n)),!r&&Ce(i)&&!Ce(n))return v||(i.value=n),!0}const c=r?Number(s)e,Vs=e=>Reflect.getPrototypeOf(e);function Nl(e,t,s){return function(...n){const o=this.__v_raw,i=te(o),r=jt(i),c=e==="entries"||e===Symbol.iterator&&r,u=e==="keys"&&r,v=o[e](...n),y=s?En:t?Nt:it;return!t&&xe(i,"iterate",u?Tn:St),ve(Object.create(v),{next(){const{value:C,done:$}=v.next();return $?{value:C,done:$}:{value:c?[y(C[0]),y(C[1])]:y(C),done:$}}})}}function Fs(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Hl(e,t){const s={get(o){const i=this.__v_raw,r=te(i),c=te(o);e||(st(o,c)&&xe(r,"get",o),xe(r,"get",c));const{has:u}=Vs(r),v=t?En:e?Nt:it;if(u.call(r,o))return v(i.get(o));if(u.call(r,c))return v(i.get(c));i!==r&&i.get(o)},get size(){const o=this.__v_raw;return!e&&xe(te(o),"iterate",St),o.size},has(o){const i=this.__v_raw,r=te(i),c=te(o);return e||(st(o,c)&&xe(r,"has",o),xe(r,"has",c)),o===c?i.has(o):i.has(o)||i.has(c)},forEach(o,i){const r=this,c=r.__v_raw,u=te(c),v=t?En:e?Nt:it;return!e&&xe(u,"iterate",St),c.forEach((y,C)=>o.call(i,v(y),v(C),r))}};return ve(s,e?{add:Fs("add"),set:Fs("set"),delete:Fs("delete"),clear:Fs("clear")}:{add(o){const i=te(this),r=Vs(i),c=te(o),u=!t&&!Ue(o)&&!vt(o)?c:o;return r.has.call(i,u)||st(o,u)&&r.has.call(i,o)||st(c,u)&&r.has.call(i,c)||(i.add(u),nt(i,"add",u,u)),this},set(o,i){!t&&!Ue(i)&&!vt(i)&&(i=te(i));const r=te(this),{has:c,get:u}=Vs(r);let v=c.call(r,o);v||(o=te(o),v=c.call(r,o));const y=u.call(r,o);return r.set(o,i),v?st(i,y)&&nt(r,"set",o,i):nt(r,"add",o,i),this},delete(o){const i=te(this),{has:r,get:c}=Vs(i);let u=r.call(i,o);u||(o=te(o),u=r.call(i,o)),c&&c.call(i,o);const v=i.delete(o);return u&&nt(i,"delete",o,void 0),v},clear(){const o=te(this),i=o.size!==0,r=o.clear();return i&&nt(o,"clear",void 0,void 0),r}}),["keys","values","entries",Symbol.iterator].forEach(o=>{s[o]=Nl(o,e,t)}),s}function js(e,t){const s=Hl(e,t);return(n,o,i)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_raw"?n:Reflect.get(ee(s,o)&&o in n?s:n,o,i)}const Ul={get:js(!1,!1)},Wl={get:js(!1,!0)},Bl={get:js(!0,!1)},zl={get:js(!0,!0)},Fo=new WeakMap,jo=new WeakMap,Ko=new WeakMap,Lo=new WeakMap;function ql(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Jl(e){return e.__v_skip||!Object.isExtensible(e)?0:ql(_l(e))}function as(e){return vt(e)?e:Ks(e,!1,Fl,Ul,Fo)}function Gl(e){return Ks(e,!1,Kl,Wl,jo)}function Dn(e){return Ks(e,!0,jl,Bl,Ko)}function Pp(e){return Ks(e,!0,Ll,zl,Lo)}function Ks(e,t,s,n,o){if(!oe(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=Jl(e);if(i===0)return e;const r=o.get(e);if(r)return r;const c=new Proxy(e,i===2?n:s);return o.set(e,c),c}function Mt(e){return vt(e)?Mt(e.__v_raw):!!(e&&e.__v_isReactive)}function vt(e){return!!(e&&e.__v_isReadonly)}function Ue(e){return!!(e&&e.__v_isShallow)}function On(e){return e?!!e.__v_raw:!1}function te(e){const t=e&&e.__v_raw;return t?te(t):e}function Yl(e){return!ee(e,"__v_skip")&&Object.isExtensible(e)&&go(e,"__v_skip",!0),e}const it=e=>oe(e)?as(e):e,Nt=e=>oe(e)?Dn(e):e;function Ce(e){return e?e.__v_isRef===!0:!1}function l(e){return Ce(e)?e.value:e}const Xl={get:(e,t,s)=>t==="__v_raw"?e:l(Reflect.get(e,t,s)),set:(e,t,s,n)=>{const o=e[t];return Ce(o)&&!Ce(s)?(o.value=s,!0):Reflect.set(e,t,s,n)}};function $n(e){return Mt(e)?e:new Proxy(e,Xl)}class Ql{constructor(t,s,n){this.fn=t,this.setter=s,this._value=void 0,this.dep=new Ro(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=ls-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!s,this.isSSR=n}notify(){if(this.flags|=16,!(this.flags&8)&&ue!==this)return wo(this,!0),!0}get value(){const t=this.dep.track();return Ao(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Zl(e,t,s=!1){let n,o;return z(e)?n=e:(n=e.get,o=e.set),new Ql(n,o,s)}const Ls={},Ns=new WeakMap;let At;function er(e,t=!1,s=At){if(s){let n=Ns.get(s);n||Ns.set(s,n=[]),n.push(e)}}function tr(e,t,s=ce){const{immediate:n,deep:o,once:i,scheduler:r,augmentJob:c,call:u}=s,v=B=>o?B:Ue(B)||o===!1||o===0?lt(B,1):lt(B);let y,C,$,a,b=!1,T=!1;if(Ce(e)?(C=()=>e.value,b=Ue(e)):Mt(e)?(C=()=>v(e),b=!0):W(e)?(T=!0,b=e.some(B=>Mt(B)||Ue(B)),C=()=>e.map(B=>{if(Ce(B))return B.value;if(Mt(B))return v(B);if(z(B))return u?u(B,2):B()})):z(e)?t?C=u?()=>u(e,2):e:C=()=>{if($){ze();try{$()}finally{qe()}}const B=At;At=y;try{return u?u(e,3,[a]):e(a)}finally{At=B}}:C=We,t&&o){const B=C,me=o===!0?1/0:o;C=()=>lt(B(),me)}const q=Rl(),X=()=>{y.stop(),q&&q.active&&gn(q.effects,y)};if(i&&t){const B=t;t=(...me)=>{B(...me),X()}}let G=T?new Array(e.length).fill(Ls):Ls;const ae=B=>{if(!(!(y.flags&1)||!y.dirty&&!B))if(t){const me=y.run();if(o||b||(T?me.some((Ze,Ve)=>st(Ze,G[Ve])):st(me,G))){$&&$();const Ze=At;At=y;try{const Ve=[me,G===Ls?void 0:T&&G[0]===Ls?[]:G,a];G=me,u?u(t,3,Ve):t(...Ve)}finally{At=Ze}}}else y.run()};return c&&c(ae),y=new Co(C),y.scheduler=r?()=>r(ae,!1):ae,a=B=>er(B,!1,y),$=y.onStop=()=>{const B=Ns.get(y);if(B){if(u)u(B,4);else for(const me of B)me();Ns.delete(y)}},t?n?ae(!0):G=y.run():r?r(ae.bind(null,!0),!0):y.run(),X.pause=y.pause.bind(y),X.resume=y.resume.bind(y),X.stop=X,X}function lt(e,t=1/0,s){if(t<=0||!oe(e)||e.__v_skip||(s=s||new Map,(s.get(e)||0)>=t))return e;if(s.set(e,t),t--,Ce(e))lt(e.value,t,s);else if(W(e))for(let n=0;n{lt(n,t,s)});else if(mo(e)){for(const n in e)lt(e[n],t,s);for(const n of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,n)&<(e[n],t,s)}return e}/**
+* @vue/runtime-core v3.5.33
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/const us=[];let In=!1;function Rp(e,...t){if(In)return;In=!0,ze();const s=us.length?us[us.length-1].component:null,n=s&&s.appContext.config.warnHandler,o=sr();if(n)Ht(n,s,11,[e+t.map(i=>{var r,c;return(c=(r=i.toString)==null?void 0:r.call(i))!=null?c:JSON.stringify(i)}).join(""),s&&s.proxy,o.map(({vnode:i})=>`at <${$i(s,i.type)}>`).join(`
+`),o]);else{const i=[`[Vue warn]: ${e}`,...t];o.length&&i.push(`
+`,...nr(o)),console.warn(...i)}qe(),In=!1}function sr(){let e=us[us.length-1];if(!e)return[];const t=[];for(;e;){const s=t[0];s&&s.vnode===e?s.recurseCount++:t.push({vnode:e,recurseCount:0});const n=e.component&&e.component.parent;e=n&&n.vnode}return t}function nr(e){const t=[];return e.forEach((s,n)=>{t.push(...n===0?[]:[`
+`],...or(s))}),t}function or({vnode:e,recurseCount:t}){const s=t>0?`... (${t} recursive calls)`:"",n=e.component?e.component.parent==null:!1,o=` at <${$i(e.component,e.type,n)}`,i=">"+s;return e.props?[o,...ir(e.props),i]:[o+i]}function ir(e){const t=[],s=Object.keys(e);return s.slice(0,3).forEach(n=>{t.push(...No(n,e[n]))}),s.length>3&&t.push(" ..."),t}function No(e,t,s){return pe(t)?(t=JSON.stringify(t),s?t:[`${e}=${t}`]):typeof t=="number"||typeof t=="boolean"||t==null?s?t:[`${e}=${t}`]:Ce(t)?(t=No(e,te(t.value),!0),s?t:[`${e}=Ref<`,t,">"]):z(t)?[`${e}=fn${t.name?`<${t.name}>`:""}`]:(t=te(t),s?t:[`${e}=`,t])}function Ht(e,t,s,n){try{return n?e(...n):e()}catch(o){Hs(o,t,s)}}function Ge(e,t,s,n){if(z(e)){const o=Ht(e,t,s,n);return o&&po(o)&&o.catch(i=>{Hs(i,t,s)}),o}if(W(e)){const o=[];for(let i=0;i>>1,o=ke[n],i=ds(o);i=ds(s)?ke.push(e):ke.splice(rr(t),0,e),e.flags|=1,Wo()}}function Wo(){Us||(Us=Ho.then(qo))}function cr(e){W(e)?Ut.push(...e):_t&&e.id===-1?_t.splice(Wt+1,0,e):e.flags&1||(Ut.push(e),e.flags|=1),Wo()}function Bo(e,t,s=Ye+1){for(;sds(s)-ds(n));if(Ut.length=0,_t){_t.push(...t);return}for(_t=t,Wt=0;Wt<_t.length;Wt++){const s=_t[Wt];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}_t=null,Wt=0}}const ds=e=>e.id==null?e.flags&2?-1:1/0:e.id;function qo(e){try{for(Ye=0;Ye{n._d&&Xs(-1);const i=Ws(t);let r;try{r=e(...o)}finally{Ws(i),n._d&&Xs(1)}return r};return n._n=!0,n._c=!0,n._d=!0,n}function rt(e,t){if(De===null)return e;const s=tn(De),n=e.dirs||(e.dirs=[]);for(let o=0;o1)return s&&z(t)?t.call(n&&n.proxy):t}}const dr=Symbol.for("v-scx"),fr=()=>Bs(dr);function fs(e,t,s){return Go(e,t,s)}function Go(e,t,s=ce){const{immediate:n,deep:o,flush:i,once:r}=s,c=ve({},s),u=t&&n||!t&&i!=="post";let v;if(xs){if(i==="sync"){const a=fr();v=a.__watcherHandles||(a.__watcherHandles=[])}else if(!u){const a=()=>{};return a.stop=We,a.resume=We,a.pause=We,a}}const y=Se;c.call=(a,b,T)=>Ge(a,y,b,T);let C=!1;i==="post"?c.scheduler=a=>{Ae(a,y&&y.suspense)}:i!=="sync"&&(C=!0,c.scheduler=(a,b)=>{b?a():Vn(a)}),c.augmentJob=a=>{t&&(a.flags|=4),C&&(a.flags|=2,y&&(a.id=y.uid,a.i=y))};const $=tr(e,t,c);return xs&&(v?v.push($):u&&$()),$}function pr(e,t,s){const n=this.proxy,o=pe(e)?e.includes(".")?Yo(n,e):()=>n[e]:e.bind(n,n);let i;z(t)?i=t:(i=t.handler,s=t);const r=_s(this),c=Go(o,i.bind(n),s);return r(),c}function Yo(e,t){const s=t.split(".");return()=>{let n=e;for(let o=0;oe.__isTeleport,yr=Symbol("_leaveCb");function Fn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Fn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Xo(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function Qo(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const zs=new WeakMap;function ps(e,t,s,n,o=!1){if(W(e)){e.forEach((T,q)=>ps(T,t&&(W(t)?t[q]:t),s,n,o));return}if(hs(n)&&!o){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&ps(e,t,s,n.component.subTree);return}const i=n.shapeFlag&4?tn(n.component):n.el,r=o?null:i,{i:c,r:u}=e,v=t&&t.r,y=c.refs===ce?c.refs={}:c.refs,C=c.setupState,$=te(C),a=C===ce?uo:T=>Qo(y,T)?!1:ee($,T),b=(T,q)=>!(q&&Qo(y,q));if(v!=null&&v!==u){if(Zo(t),pe(v))y[v]=null,a(v)&&(C[v]=null);else if(Ce(v)){const T=t;b(v,T.k)&&(v.value=null),T.k&&(y[T.k]=null)}}if(z(u))Ht(u,c,12,[r,y]);else{const T=pe(u),q=Ce(u);if(T||q){const X=()=>{if(e.f){const G=T?a(u)?C[u]:y[u]:b()||!e.k?u.value:y[e.k];if(o)W(G)&&gn(G,i);else if(W(G))G.includes(i)||G.push(i);else if(T)y[u]=[i],a(u)&&(C[u]=y[u]);else{const ae=[i];b(u,e.k)&&(u.value=ae),e.k&&(y[e.k]=ae)}}else T?(y[u]=r,a(u)&&(C[u]=r)):q&&(b(u,e.k)&&(u.value=r),e.k&&(y[e.k]=r))};if(r){const G=()=>{X(),zs.delete(e)};G.id=-1,zs.set(e,G),Ae(G,s)}else Zo(e),X()}}}function Zo(e){const t=zs.get(e);t&&(t.flags|=8,zs.delete(e))}$s().requestIdleCallback,$s().cancelIdleCallback;const hs=e=>!!e.type.__asyncLoader,ei=e=>e.type.__isKeepAlive;function gr(e,t){ti(e,"a",t)}function br(e,t){ti(e,"da",t)}function ti(e,t,s=Se){const n=e.__wdc||(e.__wdc=()=>{let o=s;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(qs(t,n,s),s){let o=s.parent;for(;o&&o.parent;)ei(o.parent.vnode)&&vr(n,t,s,o),o=o.parent}}function vr(e,t,s,n){const o=qs(t,e,n,!0);si(()=>{gn(n[t],o)},s)}function qs(e,t,s=Se,n=!1){if(s){const o=s[e]||(s[e]=[]),i=t.__weh||(t.__weh=(...r)=>{ze();const c=_s(s),u=Ge(t,s,e,r);return c(),qe(),u});return n?o.unshift(i):o.push(i),i}}const ct=e=>(t,s=Se)=>{(!xs||e==="sp")&&qs(e,(...n)=>t(...n),s)},_r=ct("bm"),xr=ct("m"),Cr=ct("bu"),kr=ct("u"),wr=ct("bum"),si=ct("um"),Sr=ct("sp"),Mr=ct("rtg"),Ar=ct("rtc");function Tr(e,t=Se){qs("ec",e,t)}const Pr=Symbol.for("v-ndc");function ge(e,t,s,n){let o;const i=s,r=W(e);if(r||pe(e)){const c=r&&Mt(e);let u=!1,v=!1;c&&(u=!Ue(e),v=vt(e),e=Is(e)),o=new Array(e.length);for(let y=0,C=e.length;yt(c,u,void 0,i));else{const c=Object.keys(e);o=new Array(c.length);for(let u=0,v=c.length;ue?Ei(e)?tn(e):jn(e.parent):null,ms=ve(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>jn(e.parent),$root:e=>jn(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>li(e),$forceUpdate:e=>e.f||(e.f=()=>{Vn(e.update)}),$nextTick:e=>e.n||(e.n=Uo.bind(e.proxy)),$watch:e=>pr.bind(e)}),Kn=(e,t)=>e!==ce&&!e.__isScriptSetup&&ee(e,t),Rr={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:s,setupState:n,data:o,props:i,accessCache:r,type:c,appContext:u}=e;if(t[0]!=="$"){const $=r[t];if($!==void 0)switch($){case 1:return n[t];case 2:return o[t];case 4:return s[t];case 3:return i[t]}else{if(Kn(n,t))return r[t]=1,n[t];if(o!==ce&&ee(o,t))return r[t]=2,o[t];if(ee(i,t))return r[t]=3,i[t];if(s!==ce&&ee(s,t))return r[t]=4,s[t];Ln&&(r[t]=0)}}const v=ms[t];let y,C;if(v)return t==="$attrs"&&xe(e.attrs,"get",""),v(e);if((y=c.__cssModules)&&(y=y[t]))return y;if(s!==ce&&ee(s,t))return r[t]=4,s[t];if(C=u.config.globalProperties,ee(C,t))return C[t]},set({_:e},t,s){const{data:n,setupState:o,ctx:i}=e;return Kn(o,t)?(o[t]=s,!0):n!==ce&&ee(n,t)?(n[t]=s,!0):ee(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=s,!0)},has({_:{data:e,setupState:t,accessCache:s,ctx:n,appContext:o,props:i,type:r}},c){let u;return!!(s[c]||e!==ce&&c[0]!=="$"&&ee(e,c)||Kn(t,c)||ee(i,c)||ee(n,c)||ee(ms,c)||ee(o.config.globalProperties,c)||(u=r.__cssModules)&&u[c])},defineProperty(e,t,s){return s.get!=null?e._.accessCache[t]=0:ee(s,"value")&&this.set(e,t,s.value,null),Reflect.defineProperty(e,t,s)}};function ni(e){return W(e)?e.reduce((t,s)=>(t[s]=null,t),{}):e}let Ln=!0;function Er(e){const t=li(e),s=e.proxy,n=e.ctx;Ln=!1,t.beforeCreate&&oi(t.beforeCreate,e,"bc");const{data:o,computed:i,methods:r,watch:c,provide:u,inject:v,created:y,beforeMount:C,mounted:$,beforeUpdate:a,updated:b,activated:T,deactivated:q,beforeDestroy:X,beforeUnmount:G,destroyed:ae,unmounted:B,render:me,renderTracked:Ze,renderTriggered:Ve,errorCaptured:et,serverPrefetch:Xt,expose:ht,inheritAttrs:Ot,components:Qt,directives:Zt,filters:Ms}=t;if(v&&Dr(v,n,null),r)for(const fe in r){const se=r[fe];z(se)&&(n[fe]=se.bind(s))}if(o){const fe=o.call(s,s);oe(fe)&&(e.data=as(fe))}if(Ln=!0,i)for(const fe in i){const se=i[fe],mt=z(se)?se.bind(s,s):z(se.get)?se.get.bind(s,s):We,es=!z(se)&&z(se.set)?se.set.bind(s):We,yt=qt({get:mt,set:es});Object.defineProperty(n,fe,{enumerable:!0,configurable:!0,get:()=>yt.value,set:Ee=>yt.value=Ee})}if(c)for(const fe in c)ii(c[fe],n,s,fe);if(u){const fe=z(u)?u.call(s):u;Reflect.ownKeys(fe).forEach(se=>{ur(se,fe[se])})}y&&oi(y,e,"c");function be(fe,se){W(se)?se.forEach(mt=>fe(mt.bind(s))):se&&fe(se.bind(s))}if(be(_r,C),be(xr,$),be(Cr,a),be(kr,b),be(gr,T),be(br,q),be(Tr,et),be(Ar,Ze),be(Mr,Ve),be(wr,G),be(si,B),be(Sr,Xt),W(ht))if(ht.length){const fe=e.exposed||(e.exposed={});ht.forEach(se=>{Object.defineProperty(fe,se,{get:()=>s[se],set:mt=>s[se]=mt,enumerable:!0})})}else e.exposed||(e.exposed={});me&&e.render===We&&(e.render=me),Ot!=null&&(e.inheritAttrs=Ot),Qt&&(e.components=Qt),Zt&&(e.directives=Zt),Xt&&Xo(e)}function Dr(e,t,s=We){W(e)&&(e=Nn(e));for(const n in e){const o=e[n];let i;oe(o)?"default"in o?i=Bs(o.from||n,o.default,!0):i=Bs(o.from||n):i=Bs(o),Ce(i)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>i.value,set:r=>i.value=r}):t[n]=i}}function oi(e,t,s){Ge(W(e)?e.map(n=>n.bind(t.proxy)):e.bind(t.proxy),t,s)}function ii(e,t,s,n){let o=n.includes(".")?Yo(s,n):()=>s[n];if(pe(e)){const i=t[e];z(i)&&fs(o,i)}else if(z(e))fs(o,e.bind(s));else if(oe(e))if(W(e))e.forEach(i=>ii(i,t,s,n));else{const i=z(e.handler)?e.handler.bind(s):t[e.handler];z(i)&&fs(o,i,e)}}function li(e){const t=e.type,{mixins:s,extends:n}=t,{mixins:o,optionsCache:i,config:{optionMergeStrategies:r}}=e.appContext,c=i.get(t);let u;return c?u=c:!o.length&&!s&&!n?u=t:(u={},o.length&&o.forEach(v=>Js(u,v,r,!0)),Js(u,t,r)),oe(t)&&i.set(t,u),u}function Js(e,t,s,n=!1){const{mixins:o,extends:i}=t;i&&Js(e,i,s,!0),o&&o.forEach(r=>Js(e,r,s,!0));for(const r in t)if(!(n&&r==="expose")){const c=Or[r]||s&&s[r];e[r]=c?c(e[r],t[r]):t[r]}return e}const Or={data:ri,props:ci,emits:ci,methods:ys,computed:ys,beforeCreate:we,created:we,beforeMount:we,mounted:we,beforeUpdate:we,updated:we,beforeDestroy:we,beforeUnmount:we,destroyed:we,unmounted:we,activated:we,deactivated:we,errorCaptured:we,serverPrefetch:we,components:ys,directives:ys,watch:Ir,provide:ri,inject:$r};function ri(e,t){return t?e?function(){return ve(z(e)?e.call(this,this):e,z(t)?t.call(this,this):t)}:t:e}function $r(e,t){return ys(Nn(e),Nn(t))}function Nn(e){if(W(e)){const t={};for(let s=0;st==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Le(t)}Modifiers`]||e[`${wt(t)}Modifiers`];function Kr(e,t,...s){if(e.isUnmounted)return;const n=e.vnode.props||ce;let o=s;const i=t.startsWith("update:"),r=i&&jr(n,t.slice(7));r&&(r.trim&&(o=s.map(y=>pe(y)?y.trim():y)),r.number&&(o=s.map(Os)));let c,u=n[c=vn(t)]||n[c=vn(Le(t))];!u&&i&&(u=n[c=vn(wt(t))]),u&&Ge(u,e,6,o);const v=n[c+"Once"];if(v){if(!e.emitted)e.emitted={};else if(e.emitted[c])return;e.emitted[c]=!0,Ge(v,e,6,o)}}const Lr=new WeakMap;function ui(e,t,s=!1){const n=s?Lr:t.emitsCache,o=n.get(e);if(o!==void 0)return o;const i=e.emits;let r={},c=!1;if(!z(e)){const u=v=>{const y=ui(v,t,!0);y&&(c=!0,ve(r,y))};!s&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}return!i&&!c?(oe(e)&&n.set(e,null),null):(W(i)?i.forEach(u=>r[u]=null):ve(r,i),oe(e)&&n.set(e,r),r)}function Gs(e,t){return!e||!Ps(t)?!1:(t=t.slice(2).replace(/Once$/,""),ee(e,t[0].toLowerCase()+t.slice(1))||ee(e,wt(t))||ee(e,t))}function Ep(){}function di(e){const{type:t,vnode:s,proxy:n,withProxy:o,propsOptions:[i],slots:r,attrs:c,emit:u,render:v,renderCache:y,props:C,data:$,setupState:a,ctx:b,inheritAttrs:T}=e,q=Ws(e);let X,G;try{if(s.shapeFlag&4){const B=o||n,me=B;X=Xe(v.call(me,B,y,C,a,$,b)),G=c}else{const B=t;X=Xe(B.length>1?B(C,{attrs:c,slots:r,emit:u}):B(C,null)),G=t.props?c:Nr(c)}}catch(B){gs.length=0,Hs(B,e,1),X=O(xt)}let ae=X;if(G&&T!==!1){const B=Object.keys(G),{shapeFlag:me}=ae;B.length&&me&7&&(i&&B.some(Rs)&&(G=Hr(G,i)),ae=zt(ae,G,!1,!0))}return s.dirs&&(ae=zt(ae,null,!1,!0),ae.dirs=ae.dirs?ae.dirs.concat(s.dirs):s.dirs),s.transition&&Fn(ae,s.transition),X=ae,Ws(q),X}const Nr=e=>{let t;for(const s in e)(s==="class"||s==="style"||Ps(s))&&((t||(t={}))[s]=e[s]);return t},Hr=(e,t)=>{const s={};for(const n in e)(!Rs(n)||!(n.slice(9)in t))&&(s[n]=e[n]);return s};function Ur(e,t,s){const{props:n,children:o,component:i}=e,{props:r,children:c,patchFlag:u}=t,v=i.emitsOptions;if(t.dirs||t.transition)return!0;if(s&&u>=0){if(u&1024)return!0;if(u&16)return n?fi(n,r,v):!!r;if(u&8){const y=t.dynamicProps;for(let C=0;CObject.create(hi),yi=e=>Object.getPrototypeOf(e)===hi;function Br(e,t,s,n=!1){const o={},i=mi();e.propsDefaults=Object.create(null),gi(e,t,o,i);for(const r in e.propsOptions[0])r in o||(o[r]=void 0);s?e.props=n?o:Gl(o):e.type.props?e.props=o:e.props=i,e.attrs=i}function zr(e,t,s,n){const{props:o,attrs:i,vnode:{patchFlag:r}}=e,c=te(o),[u]=e.propsOptions;let v=!1;if((n||r>0)&&!(r&16)){if(r&8){const y=e.vnode.dynamicProps;for(let C=0;C{u=!0;const[$,a]=bi(C,t,!0);ve(r,$),a&&c.push(...a)};!s&&t.mixins.length&&t.mixins.forEach(y),e.extends&&y(e.extends),e.mixins&&e.mixins.forEach(y)}if(!i&&!u)return oe(e)&&n.set(e,Ft),Ft;if(W(i))for(let y=0;ye==="_"||e==="_ctx"||e==="$stable",Wn=e=>W(e)?e.map(Xe):[Xe(e)],Jr=(e,t,s)=>{if(t._n)return t;const n=ar((...o)=>Wn(t(...o)),s);return n._c=!1,n},_i=(e,t,s)=>{const n=e._ctx;for(const o in e){if(Un(o))continue;const i=e[o];if(z(i))t[o]=Jr(o,i,n);else if(i!=null){const r=Wn(i);t[o]=()=>r}}},xi=(e,t)=>{const s=Wn(t);e.slots.default=()=>s},Ci=(e,t,s)=>{for(const n in t)(s||!Un(n))&&(e[n]=t[n])},Gr=(e,t,s)=>{const n=e.slots=mi();if(e.vnode.shapeFlag&32){const o=t._;o?(Ci(n,t,s),s&&go(n,"_",o,!0)):_i(t,n)}else t&&xi(e,t)},Yr=(e,t,s)=>{const{vnode:n,slots:o}=e;let i=!0,r=ce;if(n.shapeFlag&32){const c=t._;c?s&&c===1?i=!1:Ci(o,t,s):(i=!t.$stable,_i(t,o)),r=t}else t&&(xi(e,t),r={default:1});if(i)for(const c in o)!Un(c)&&r[c]==null&&delete o[c]},Ae=tc;function Xr(e){return Qr(e)}function Qr(e,t){const s=$s();s.__VUE__=!0;const{insert:n,remove:o,patchProp:i,createElement:r,createText:c,createComment:u,setText:v,setElementText:y,parentNode:C,nextSibling:$,setScopeId:a=We,insertStaticContent:b}=e,T=(f,m,_,A=null,k=null,w=null,D=void 0,E=null,P=!!m.dynamicChildren)=>{if(f===m)return;f&&!vs(f,m)&&(A=ts(f),Ee(f,k,w,!0),f=null),m.patchFlag===-2&&(P=!1,m.dynamicChildren=null);const{type:S,ref:H,shapeFlag:V}=m;switch(S){case Ys:q(f,m,_,A);break;case xt:X(f,m,_,A);break;case zn:f==null&&G(m,_,A,D);break;case ie:Qt(f,m,_,A,k,w,D,E,P);break;default:V&1?me(f,m,_,A,k,w,D,E,P):V&6?Zt(f,m,_,A,k,w,D,E,P):(V&64||V&128)&&S.process(f,m,_,A,k,w,D,E,P,It)}H!=null&&k?ps(H,f&&f.ref,w,m||f,!m):H==null&&f&&f.ref!=null&&ps(f.ref,null,w,f,!0)},q=(f,m,_,A)=>{if(f==null)n(m.el=c(m.children),_,A);else{const k=m.el=f.el;m.children!==f.children&&v(k,m.children)}},X=(f,m,_,A)=>{f==null?n(m.el=u(m.children||""),_,A):m.el=f.el},G=(f,m,_,A)=>{[f.el,f.anchor]=b(f.children,m,_,A,f.el,f.anchor)},ae=({el:f,anchor:m},_,A)=>{let k;for(;f&&f!==m;)k=$(f),n(f,_,A),f=k;n(m,_,A)},B=({el:f,anchor:m})=>{let _;for(;f&&f!==m;)_=$(f),o(f),f=_;o(m)},me=(f,m,_,A,k,w,D,E,P)=>{if(m.type==="svg"?D="svg":m.type==="math"&&(D="mathml"),f==null)Ze(m,_,A,k,w,D,E,P);else{const S=f.el&&f.el._isVueCE?f.el:null;try{S&&S._beginPatch(),Xt(f,m,k,w,D,E,P)}finally{S&&S._endPatch()}}},Ze=(f,m,_,A,k,w,D,E)=>{let P,S;const{props:H,shapeFlag:V,transition:N,dirs:U}=f;if(P=f.el=r(f.type,w,H&&H.is,H),V&8?y(P,f.children):V&16&&et(f.children,P,null,A,k,Bn(f,w),D,E),U&&Tt(f,null,A,"created"),Ve(P,f,f.scopeId,D,A),H){for(const Z in H)Z!=="value"&&!ns(Z)&&i(P,Z,null,H[Z],w,A);"value"in H&&i(P,"value",null,H.value,w),(S=H.onVnodeBeforeMount)&&Qe(S,A,f)}U&&Tt(f,null,A,"beforeMount");const Y=Zr(k,N);Y&&N.beforeEnter(P),n(P,m,_),((S=H&&H.onVnodeMounted)||Y||U)&&Ae(()=>{try{S&&Qe(S,A,f),Y&&N.enter(P),U&&Tt(f,null,A,"mounted")}finally{}},k)},Ve=(f,m,_,A,k)=>{if(_&&a(f,_),A)for(let w=0;w{for(let S=P;S{const E=m.el=f.el;let{patchFlag:P,dynamicChildren:S,dirs:H}=m;P|=f.patchFlag&16;const V=f.props||ce,N=m.props||ce;let U;if(_&&Pt(_,!1),(U=N.onVnodeBeforeUpdate)&&Qe(U,_,m,f),H&&Tt(m,f,_,"beforeUpdate"),_&&Pt(_,!0),(V.innerHTML&&N.innerHTML==null||V.textContent&&N.textContent==null)&&y(E,""),S?ht(f.dynamicChildren,S,E,_,A,Bn(m,k),w):D||se(f,m,E,null,_,A,Bn(m,k),w,!1),P>0){if(P&16)Ot(E,V,N,_,k);else if(P&2&&V.class!==N.class&&i(E,"class",null,N.class,k),P&4&&i(E,"style",V.style,N.style,k),P&8){const Y=m.dynamicProps;for(let Z=0;Z{U&&Qe(U,_,m,f),H&&Tt(m,f,_,"updated")},A)},ht=(f,m,_,A,k,w,D)=>{for(let E=0;E{if(m!==_){if(m!==ce)for(const w in m)!ns(w)&&!(w in _)&&i(f,w,m[w],null,k,A);for(const w in _){if(ns(w))continue;const D=_[w],E=m[w];D!==E&&w!=="value"&&i(f,w,E,D,k,A)}"value"in _&&i(f,"value",m.value,_.value,k)}},Qt=(f,m,_,A,k,w,D,E,P)=>{const S=m.el=f?f.el:c(""),H=m.anchor=f?f.anchor:c("");let{patchFlag:V,dynamicChildren:N,slotScopeIds:U}=m;U&&(E=E?E.concat(U):U),f==null?(n(S,_,A),n(H,_,A),et(m.children||[],_,H,k,w,D,E,P)):V>0&&V&64&&N&&f.dynamicChildren&&f.dynamicChildren.length===N.length?(ht(f.dynamicChildren,N,_,k,w,D,E),(m.key!=null||k&&m===k.subTree)&&ki(f,m,!0)):se(f,m,_,H,k,w,D,E,P)},Zt=(f,m,_,A,k,w,D,E,P)=>{m.slotScopeIds=E,f==null?m.shapeFlag&512?k.ctx.activate(m,_,A,D,P):Ms(m,_,A,k,w,D,P):un(f,m,P)},Ms=(f,m,_,A,k,w,D)=>{const E=f.component=ac(f,A,k);if(ei(f)&&(E.ctx.renderer=It),dc(E,!1,D),E.asyncDep){if(k&&k.registerDep(E,be,D),!f.el){const P=E.subTree=O(xt);X(null,P,m,_),f.placeholder=P.el}}else be(E,f,m,_,k,w,D)},un=(f,m,_)=>{const A=m.component=f.component;if(Ur(f,m,_))if(A.asyncDep&&!A.asyncResolved){fe(A,m,_);return}else A.next=m,A.update();else m.el=f.el,A.vnode=m},be=(f,m,_,A,k,w,D)=>{const E=()=>{if(f.isMounted){let{next:V,bu:N,u:U,parent:Y,vnode:Z}=f;{const je=wi(f);if(je){V&&(V.el=Z.el,fe(f,V,D)),je.asyncDep.then(()=>{Ae(()=>{f.isUnmounted||S()},k)});return}}let re=V,he;Pt(f,!1),V?(V.el=Z.el,fe(f,V,D)):V=Z,N&&Ds(N),(he=V.props&&V.props.onVnodeBeforeUpdate)&&Qe(he,Y,V,Z),Pt(f,!0);const ye=di(f),Fe=f.subTree;f.subTree=ye,T(Fe,ye,C(Fe.el),ts(Fe),f,k,w),V.el=ye.el,re===null&&Wr(f,ye.el),U&&Ae(U,k),(he=V.props&&V.props.onVnodeUpdated)&&Ae(()=>Qe(he,Y,V,Z),k)}else{let V;const{el:N,props:U}=m,{bm:Y,m:Z,parent:re,root:he,type:ye}=f,Fe=hs(m);Pt(f,!1),Y&&Ds(Y),!Fe&&(V=U&&U.onVnodeBeforeMount)&&Qe(V,re,m),Pt(f,!0);{he.ce&&he.ce._hasShadowRoot()&&he.ce._injectChildStyle(ye,f.parent?f.parent.type:void 0);const je=f.subTree=di(f);T(null,je,_,A,f,k,w),m.el=je.el}if(Z&&Ae(Z,k),!Fe&&(V=U&&U.onVnodeMounted)){const je=m;Ae(()=>Qe(V,re,je),k)}(m.shapeFlag&256||re&&hs(re.vnode)&&re.vnode.shapeFlag&256)&&f.a&&Ae(f.a,k),f.isMounted=!0,m=_=A=null}};f.scope.on();const P=f.effect=new Co(E);f.scope.off();const S=f.update=P.run.bind(P),H=f.job=P.runIfDirty.bind(P);H.i=f,H.id=f.uid,P.scheduler=()=>Vn(H),Pt(f,!0),S()},fe=(f,m,_)=>{m.component=f;const A=f.vnode.props;f.vnode=m,f.next=null,zr(f,m.props,A,_),Yr(f,m.children,_),ze(),Bo(f),qe()},se=(f,m,_,A,k,w,D,E,P=!1)=>{const S=f&&f.children,H=f?f.shapeFlag:0,V=m.children,{patchFlag:N,shapeFlag:U}=m;if(N>0){if(N&128){es(S,V,_,A,k,w,D,E,P);return}else if(N&256){mt(S,V,_,A,k,w,D,E,P);return}}U&8?(H&16&&$t(S,k,w),V!==S&&y(_,V)):H&16?U&16?es(S,V,_,A,k,w,D,E,P):$t(S,k,w,!0):(H&8&&y(_,""),U&16&&et(V,_,A,k,w,D,E,P))},mt=(f,m,_,A,k,w,D,E,P)=>{f=f||Ft,m=m||Ft;const S=f.length,H=m.length,V=Math.min(S,H);let N;for(N=0;NH?$t(f,k,w,!0,!1,V):et(m,_,A,k,w,D,E,P,V)},es=(f,m,_,A,k,w,D,E,P)=>{let S=0;const H=m.length;let V=f.length-1,N=H-1;for(;S<=V&&S<=N;){const U=f[S],Y=m[S]=P?ut(m[S]):Xe(m[S]);if(vs(U,Y))T(U,Y,_,null,k,w,D,E,P);else break;S++}for(;S<=V&&S<=N;){const U=f[V],Y=m[N]=P?ut(m[N]):Xe(m[N]);if(vs(U,Y))T(U,Y,_,null,k,w,D,E,P);else break;V--,N--}if(S>V){if(S<=N){const U=N+1,Y=UN)for(;S<=V;)Ee(f[S],k,w,!0),S++;else{const U=S,Y=S,Z=new Map;for(S=Y;S<=N;S++){const Me=m[S]=P?ut(m[S]):Xe(m[S]);Me.key!=null&&Z.set(Me.key,S)}let re,he=0;const ye=N-Y+1;let Fe=!1,je=0;const Vt=new Array(ye);for(S=0;S=ye){Ee(Me,k,w,!0);continue}let Ke;if(Me.key!=null)Ke=Z.get(Me.key);else for(re=Y;re<=N;re++)if(Vt[re-Y]===0&&vs(Me,m[re])){Ke=re;break}Ke===void 0?Ee(Me,k,w,!0):(Vt[Ke-Y]=S+1,Ke>=je?je=Ke:Fe=!0,T(Me,m[Ke],_,null,k,w,D,E,P),he++)}const pn=Fe?ec(Vt):Ft;for(re=pn.length-1,S=ye-1;S>=0;S--){const Me=Y+S,Ke=m[Me],hn=m[Me+1],mn=Me+1{const{el:w,type:D,transition:E,children:P,shapeFlag:S}=f;if(S&6){yt(f.component.subTree,m,_,A);return}if(S&128){f.suspense.move(m,_,A);return}if(S&64){D.move(f,m,_,It);return}if(D===ie){n(w,m,_);for(let V=0;VE.enter(w),k);else{const{leave:V,delayLeave:N,afterLeave:U}=E,Y=()=>{f.ctx.isUnmounted?o(w):n(w,m,_)},Z=()=>{w._isLeaving&&w[yr](!0),V(w,()=>{Y(),U&&U()})};N?N(w,Y,Z):Z()}else n(w,m,_)},Ee=(f,m,_,A=!1,k=!1)=>{const{type:w,props:D,ref:E,children:P,dynamicChildren:S,shapeFlag:H,patchFlag:V,dirs:N,cacheIndex:U,memo:Y}=f;if(V===-2&&(k=!1),E!=null&&(ze(),ps(E,null,_,f,!0),qe()),U!=null&&(m.renderCache[U]=void 0),H&256){m.ctx.deactivate(f);return}const Z=H&1&&N,re=!hs(f);let he;if(re&&(he=D&&D.onVnodeBeforeUnmount)&&Qe(he,m,f),H&6)ro(f.component,_,A);else{if(H&128){f.suspense.unmount(_,A);return}Z&&Tt(f,null,m,"beforeUnmount"),H&64?f.type.remove(f,m,_,It,A):S&&!S.hasOnce&&(w!==ie||V>0&&V&64)?$t(S,m,_,!1,!0):(w===ie&&V&384||!k&&H&16)&&$t(P,m,_),A&&dn(f)}const ye=Y!=null&&U==null;(re&&(he=D&&D.onVnodeUnmounted)||Z||ye)&&Ae(()=>{he&&Qe(he,m,f),Z&&Tt(f,null,m,"unmounted"),ye&&(f.el=null)},_)},dn=f=>{const{type:m,el:_,anchor:A,transition:k}=f;if(m===ie){lo(_,A);return}if(m===zn){B(f);return}const w=()=>{o(_),k&&!k.persisted&&k.afterLeave&&k.afterLeave()};if(f.shapeFlag&1&&k&&!k.persisted){const{leave:D,delayLeave:E}=k,P=()=>D(_,w);E?E(f.el,w,P):P()}else w()},lo=(f,m)=>{let _;for(;f!==m;)_=$(f),o(f),f=_;o(m)},ro=(f,m,_)=>{const{bum:A,scope:k,job:w,subTree:D,um:E,m:P,a:S}=f;Si(P),Si(S),A&&Ds(A),k.stop(),w&&(w.flags|=8,Ee(D,f,m,_)),E&&Ae(E,m),Ae(()=>{f.isUnmounted=!0},m)},$t=(f,m,_,A=!1,k=!1,w=0)=>{for(let D=w;D{if(f.shapeFlag&6)return ts(f.component.subTree);if(f.shapeFlag&128)return f.suspense.next();const m=$(f.anchor||f.el),_=m&&m[hr];return _?$(_):m};let As=!1;const fn=(f,m,_)=>{let A;f==null?m._vnode&&(Ee(m._vnode,null,null,!0),A=m._vnode.component):T(m._vnode||null,f,m,null,null,null,_),m._vnode=f,As||(As=!0,Bo(A),zo(),As=!1)},It={p:T,um:Ee,m:yt,r:dn,mt:Ms,mc:et,pc:se,pbc:ht,n:ts,o:e};return{render:fn,hydrate:void 0,createApp:Fr(fn)}}function Bn({type:e,props:t},s){return s==="svg"&&e==="foreignObject"||s==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:s}function Pt({effect:e,job:t},s){s?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Zr(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function ki(e,t,s=!1){const n=e.children,o=t.children;if(W(n)&&W(o))for(let i=0;i>1,e[s[c]]0&&(t[n]=s[i-1]),s[i]=n)}}for(i=s.length,r=s[i-1];i-- >0;)s[i]=r,r=t[r];return s}function wi(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:wi(t)}function Si(e){if(e)for(let t=0;te.__isSuspense;function tc(e,t){t&&t.pendingBranch?W(e)?t.effects.push(...e):t.effects.push(e):cr(e)}const ie=Symbol.for("v-fgt"),Ys=Symbol.for("v-txt"),xt=Symbol.for("v-cmt"),zn=Symbol.for("v-stc"),gs=[];let Re=null;function I(e=!1){gs.push(Re=e?null:[])}function sc(){gs.pop(),Re=gs[gs.length-1]||null}let bs=1;function Xs(e,t=!1){bs+=e,e<0&&Re&&t&&(Re.hasOnce=!0)}function Ti(e){return e.dynamicChildren=bs>0?Re||Ft:null,sc(),bs>0&&Re&&Re.push(e),e}function F(e,t,s,n,o,i){return Ti(d(e,t,s,n,o,i,!0))}function nc(e,t,s,n,o){return Ti(O(e,t,s,n,o,!0))}function Qs(e){return e?e.__v_isVNode===!0:!1}function vs(e,t){return e.type===t.type&&e.key===t.key}const Pi=({key:e})=>e??null,Zs=({ref:e,ref_key:t,ref_for:s})=>(typeof e=="number"&&(e=""+e),e!=null?pe(e)||Ce(e)||z(e)?{i:De,r:e,k:t,f:!!s}:e:null);function d(e,t=null,s=null,n=0,o=null,i=e===ie?0:1,r=!1,c=!1){const u={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Pi(t),ref:t&&Zs(t),scopeId:Jo,slotScopeIds:null,children:s,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:n,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:De};return c?(qn(u,s),i&128&&e.normalize(u)):s&&(u.shapeFlag|=pe(s)?8:16),bs>0&&!r&&Re&&(u.patchFlag>0||i&6)&&u.patchFlag!==32&&Re.push(u),u}const O=oc;function oc(e,t=null,s=null,n=0,o=null,i=!1){if((!e||e===Pr)&&(e=xt),Qs(e)){const c=zt(e,t,!0);return s&&qn(c,s),bs>0&&!i&&Re&&(c.shapeFlag&6?Re[Re.indexOf(e)]=c:Re.push(c)),c.patchFlag=-2,c}if(bc(e)&&(e=e.__vccOpts),t){t=ic(t);let{class:c,style:u}=t;c&&!pe(c)&&(t.class=Ne(c)),oe(u)&&(On(u)&&!W(u)&&(u=ve({},u)),t.style=gt(u))}const r=pe(e)?1:Ai(e)?128:mr(e)?64:oe(e)?4:z(e)?2:0;return d(e,t,s,n,o,r,i,!0)}function ic(e){return e?On(e)||yi(e)?ve({},e):e:null}function zt(e,t,s=!1,n=!1){const{props:o,ref:i,patchFlag:r,children:c,transition:u}=e,v=t?lc(o||{},t):o,y={__v_isVNode:!0,__v_skip:!0,type:e.type,props:v,key:v&&Pi(v),ref:t&&t.ref?s&&i?W(i)?i.concat(Zs(t)):[i,Zs(t)]:Zs(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:c,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ie?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:u,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&zt(e.ssContent),ssFallback:e.ssFallback&&zt(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return u&&n&&Fn(y,u.clone(y)),y}function at(e=" ",t=0){return O(Ys,null,e,t)}function le(e="",t=!1){return t?(I(),nc(xt,null,e)):O(xt,null,e)}function Xe(e){return e==null||typeof e=="boolean"?O(xt):W(e)?O(ie,null,e.slice()):Qs(e)?ut(e):O(Ys,null,String(e))}function ut(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:zt(e)}function qn(e,t){let s=0;const{shapeFlag:n}=e;if(t==null)t=null;else if(W(t))s=16;else if(typeof t=="object")if(n&65){const o=t.default;o&&(o._c&&(o._d=!1),qn(e,o()),o._c&&(o._d=!0));return}else{s=32;const o=t._;!o&&!yi(t)?t._ctx=De:o===3&&De&&(De.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else z(t)?(t={default:t,_ctx:De},s=32):(t=String(t),n&64?(s=16,t=[at(t)]):s=8);e.children=t,e.shapeFlag|=s}function lc(...e){const t={};for(let s=0;sSe||De;let en,Jn;{const e=$s(),t=(s,n)=>{let o;return(o=e[s])||(o=e[s]=[]),o.push(n),i=>{o.length>1?o.forEach(r=>r(i)):o[0](i)}};en=t("__VUE_INSTANCE_SETTERS__",s=>Se=s),Jn=t("__VUE_SSR_SETTERS__",s=>xs=s)}const _s=e=>{const t=Se;return en(e),e.scope.on(),()=>{e.scope.off(),en(t)}},Ri=()=>{Se&&Se.scope.off(),en(null)};function Ei(e){return e.vnode.shapeFlag&4}let xs=!1;function dc(e,t=!1,s=!1){t&&Jn(t);const{props:n,children:o}=e.vnode,i=Ei(e);Br(e,n,i,t),Gr(e,o,s||t);const r=i?fc(e,t):void 0;return t&&Jn(!1),r}function fc(e,t){const s=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Rr);const{setup:n}=s;if(n){ze();const o=e.setupContext=n.length>1?hc(e):null,i=_s(e),r=Ht(n,e,0,[e.props,o]),c=po(r);if(qe(),i(),(c||e.sp)&&!hs(e)&&Xo(e),c){if(r.then(Ri,Ri),t)return r.then(u=>{Di(e,u)}).catch(u=>{Hs(u,e,0)});e.asyncDep=r}else Di(e,r)}else Oi(e)}function Di(e,t,s){z(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:oe(t)&&(e.setupState=$n(t)),Oi(e)}function Oi(e,t,s){const n=e.type;e.render||(e.render=n.render||We);{const o=_s(e);ze();try{Er(e)}finally{qe(),o()}}}const pc={get(e,t){return xe(e,"get",""),e[t]}};function hc(e){const t=s=>{e.exposed=s||{}};return{attrs:new Proxy(e.attrs,pc),slots:e.slots,emit:e.emit,expose:t}}function tn(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy($n(Yl(e.exposed)),{get(t,s){if(s in t)return t[s];if(s in ms)return ms[s](e)},has(t,s){return s in t||s in ms}})):e.proxy}const mc=/(?:^|[-_])\w/g,yc=e=>e.replace(mc,t=>t.toUpperCase()).replace(/[-_]/g,"");function gc(e,t=!0){return z(e)?e.displayName||e.name:e.name||t&&e.__name}function $i(e,t,s=!1){let n=gc(t);if(!n&&t.__file){const o=t.__file.match(/([^/\\]+)\.\w+$/);o&&(n=o[1])}if(!n&&e){const o=i=>{for(const r in i)if(i[r]===t)return r};n=o(e.components)||e.parent&&o(e.parent.type.components)||o(e.appContext.components)}return n?yc(n):s?"App":"Anonymous"}function bc(e){return z(e)&&"__vccOpts"in e}const qt=(e,t)=>Zl(e,t,xs);function Cs(e,t,s){try{Xs(-1);const n=arguments.length;return n===2?oe(t)&&!W(t)?Qs(t)?O(e,null,[t]):O(e,t):O(e,null,t):(n>3?s=Array.prototype.slice.call(arguments,2):n===3&&Qs(s)&&(s=[s]),O(e,t,s))}finally{Xs(1)}}const vc="3.5.33";/**
+* @vue/runtime-dom v3.5.33
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/let Gn;const Ii=typeof window<"u"&&window.trustedTypes;if(Ii)try{Gn=Ii.createPolicy("vue",{createHTML:e=>e})}catch{}const Vi=Gn?e=>Gn.createHTML(e):e=>e,_c="http://www.w3.org/2000/svg",xc="http://www.w3.org/1998/Math/MathML",dt=typeof document<"u"?document:null,Fi=dt&&dt.createElement("template"),Cc={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,n)=>{const o=t==="svg"?dt.createElementNS(_c,e):t==="mathml"?dt.createElementNS(xc,e):s?dt.createElement(e,{is:s}):dt.createElement(e);return e==="select"&&n&&n.multiple!=null&&o.setAttribute("multiple",n.multiple),o},createText:e=>dt.createTextNode(e),createComment:e=>dt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>dt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,o,i){const r=s?s.previousSibling:t.lastChild;if(o&&(o===i||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),s),!(o===i||!(o=o.nextSibling)););else{Fi.innerHTML=Vi(n==="svg"?`${e} `:n==="mathml"?`${e} `:e);const c=Fi.content;if(n==="svg"||n==="mathml"){const u=c.firstChild;for(;u.firstChild;)c.appendChild(u.firstChild);c.removeChild(u)}t.insertBefore(c,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},kc=Symbol("_vtc");function wc(e,t,s){const n=e[kc];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const ji=Symbol("_vod"),Sc=Symbol("_vsh"),Mc=Symbol(""),Ac=/(?:^|;)\s*display\s*:/;function Tc(e,t,s){const n=e.style,o=pe(s);let i=!1;if(s&&!o){if(t)if(pe(t))for(const r of t.split(";")){const c=r.slice(0,r.indexOf(":")).trim();s[c]==null&&ks(n,c,"")}else for(const r in t)s[r]==null&&ks(n,r,"");for(const r in s){r==="display"&&(i=!0);const c=s[r];c!=null?Rc(e,r,!pe(t)&&t?t[r]:void 0,c)||ks(n,r,c):ks(n,r,"")}}else if(o){if(t!==s){const r=n[Mc];r&&(s+=";"+r),n.cssText=s,i=Ac.test(s)}}else t&&e.removeAttribute("style");ji in e&&(e[ji]=i?n.display:"",e[Sc]&&(n.display="none"))}const Ki=/\s*!important$/;function ks(e,t,s){if(W(s))s.forEach(n=>ks(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Pc(e,t);Ki.test(s)?e.setProperty(wt(n),s.replace(Ki,""),"important"):e[n]=s}}const Li=["Webkit","Moz","ms"],Yn={};function Pc(e,t){const s=Yn[t];if(s)return s;let n=Le(t);if(n!=="filter"&&n in e)return Yn[t]=n;n=yo(n);for(let o=0;oXn||($c.then(()=>Xn=0),Xn=Date.now());function Vc(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;Ge(Fc(n,s.value),t,5,[n])};return s.value=e,s.attached=Ic(),s}function Fc(e,t){if(W(t)){const s=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{s.call(e),e._stopped=!0},t.map(n=>o=>!o._stopped&&n&&n(o))}else return t}const zi=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,jc=(e,t,s,n,o,i)=>{const r=o==="svg";t==="class"?wc(e,n,r):t==="style"?Tc(e,s,n):Ps(t)?Rs(t)||Dc(e,t,s,n,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Kc(e,t,n,r))?(Ui(e,t,n),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Hi(e,t,n,r,i,t!=="value")):e._isVueCE&&(Lc(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!pe(n)))?Ui(e,Le(t),n,i,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),Hi(e,t,n,r))};function Kc(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&zi(t)&&z(s));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const o=e.tagName;if(o==="IMG"||o==="VIDEO"||o==="CANVAS"||o==="SOURCE")return!1}return zi(t)&&pe(s)?!1:t in e}function Lc(e,t){const s=e._def.props;if(!s)return!1;const n=Le(t);return Array.isArray(s)?s.some(o=>Le(o)===n):Object.keys(s).some(o=>Le(o)===n)}const Ct=e=>{const t=e.props["onUpdate:modelValue"]||!1;return W(t)?s=>Ds(t,s):t};function Nc(e){e.target.composing=!0}function qi(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Oe=Symbol("_assign");function Ji(e,t,s){return t&&(e=e.trim()),s&&(e=Os(e)),e}const sn={created(e,{modifiers:{lazy:t,trim:s,number:n}},o){e[Oe]=Ct(o);const i=n||o.props&&o.props.type==="number";ft(e,t?"change":"input",r=>{r.target.composing||e[Oe](Ji(e.value,s,i))}),(s||i)&&ft(e,"change",()=>{e.value=Ji(e.value,s,i)}),t||(ft(e,"compositionstart",Nc),ft(e,"compositionend",qi),ft(e,"change",qi))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:s,modifiers:{lazy:n,trim:o,number:i}},r){if(e[Oe]=Ct(r),e.composing)return;const c=(i||e.type==="number")&&!/^0\d/.test(e.value)?Os(e.value):e.value,u=t??"";if(c===u)return;const v=e.getRootNode();(v instanceof Document||v instanceof ShadowRoot)&&v.activeElement===e&&e.type!=="range"&&(n&&t===s||o&&e.value.trim()===u)||(e.value=u)}},Hc={deep:!0,created(e,t,s){e[Oe]=Ct(s),ft(e,"change",()=>{const n=e._modelValue,o=Jt(e),i=e.checked,r=e[Oe];if(W(n)){const c=_n(n,o),u=c!==-1;if(i&&!u)r(n.concat(o));else if(!i&&u){const v=[...n];v.splice(c,1),r(v)}}else if(Kt(n)){const c=new Set(n);i?c.add(o):c.delete(o),r(c)}else r(Xi(e,i))})},mounted:Gi,beforeUpdate(e,t,s){e[Oe]=Ct(s),Gi(e,t,s)}};function Gi(e,{value:t,oldValue:s},n){e._modelValue=t;let o;if(W(t))o=_n(t,n.props.value)>-1;else if(Kt(t))o=t.has(n.props.value);else{if(t===s)return;o=bt(t,Xi(e,!0))}e.checked!==o&&(e.checked=o)}const Uc={created(e,{value:t},s){e.checked=bt(t,s.props.value),e[Oe]=Ct(s),ft(e,"change",()=>{e[Oe](Jt(e))})},beforeUpdate(e,{value:t,oldValue:s},n){e[Oe]=Ct(n),t!==s&&(e.checked=bt(t,n.props.value))}},ws={deep:!0,created(e,{value:t,modifiers:{number:s}},n){const o=Kt(t);ft(e,"change",()=>{const i=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>s?Os(Jt(r)):Jt(r));e[Oe](e.multiple?o?new Set(i):i:i[0]),e._assigning=!0,Uo(()=>{e._assigning=!1})}),e[Oe]=Ct(n)},mounted(e,{value:t}){Yi(e,t)},beforeUpdate(e,t,s){e[Oe]=Ct(s)},updated(e,{value:t}){e._assigning||Yi(e,t)}};function Yi(e,t){const s=e.multiple,n=W(t);if(!(s&&!n&&!Kt(t))){for(let o=0,i=e.options.length;oString(v)===String(c)):r.selected=_n(t,c)>-1}else r.selected=t.has(c);else if(bt(Jt(r),t)){e.selectedIndex!==o&&(e.selectedIndex=o);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Jt(e){return"_value"in e?e._value:e.value}function Xi(e,t){const s=t?"_trueValue":"_falseValue";return s in e?e[s]:t}const Qn={created(e,t,s){nn(e,t,s,null,"created")},mounted(e,t,s){nn(e,t,s,null,"mounted")},beforeUpdate(e,t,s,n){nn(e,t,s,n,"beforeUpdate")},updated(e,t,s,n){nn(e,t,s,n,"updated")}};function Wc(e,t){switch(e){case"SELECT":return ws;case"TEXTAREA":return sn;default:switch(t){case"checkbox":return Hc;case"radio":return Uc;default:return sn}}}function nn(e,t,s,n,o){const r=Wc(e.tagName,s.props&&s.props.type)[o];r&&r(e,t,s,n)}const Bc=["ctrl","shift","alt","meta"],zc={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Bc.some(s=>e[`${s}Key`]&&!t.includes(s))},kt=(e,t)=>{if(!e)return e;const s=e._withMods||(e._withMods={}),n=t.join(".");return s[n]||(s[n]=((o,...i)=>{for(let r=0;r{const t=Jc().createApp(...e),{mount:s}=t;return t.mount=n=>{const o=Xc(n);if(!o)return;const i=t._component;!z(i)&&!i.render&&!i.template&&(i.template=o.innerHTML),o.nodeType===1&&(o.textContent="");const r=s(o,!1,Yc(o));return o instanceof Element&&(o.removeAttribute("v-cloak"),o.setAttribute("data-v-app","")),r},t});function Yc(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Xc(e){return pe(e)?document.querySelector(e):e}/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const Zi=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),Qc=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(t,s,n)=>n?n.toUpperCase():s.toLowerCase()),Zc=e=>{const t=Qc(e);return t.charAt(0).toUpperCase()+t.slice(1)},ea=(...e)=>e.filter((t,s,n)=>!!t&&t.trim()!==""&&n.indexOf(t)===s).join(" ").trim();/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */var on={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"};/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ta=({size:e,strokeWidth:t=2,absoluteStrokeWidth:s,color:n,iconNode:o,name:i,class:r,...c},{slots:u})=>Cs("svg",{...on,width:e||on.width,height:e||on.height,stroke:n||on.stroke,"stroke-width":s?Number(t)*24/Number(e):t,class:ea("lucide",...i?[`lucide-${Zi(Zc(i))}-icon`,`lucide-${Zi(i)}`]:["lucide-icon"]),...c},[...o.map(v=>Cs(...v)),...u.default?[u.default()]:[]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const J=(e,t)=>(s,{slots:n})=>Cs(ta,{...s,iconNode:t,name:e},n);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const sa=J("arrow-down-a-z",[["path",{d:"m3 16 4 4 4-4",key:"1co6wj"}],["path",{d:"M7 20V4",key:"1yoxec"}],["path",{d:"M20 8h-5",key:"1vsyxs"}],["path",{d:"M15 10V6.5a2.5 2.5 0 0 1 5 0V10",key:"ag13bf"}],["path",{d:"M15 14h5l-5 6h5",key:"ur5jdg"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const na=J("arrow-down-wide-narrow",[["path",{d:"m3 16 4 4 4-4",key:"1co6wj"}],["path",{d:"M7 20V4",key:"1yoxec"}],["path",{d:"M11 4h10",key:"1w87gc"}],["path",{d:"M11 8h7",key:"djye34"}],["path",{d:"M11 12h4",key:"q8tih4"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const oa=J("arrow-up-a-z",[["path",{d:"m3 8 4-4 4 4",key:"11wl7u"}],["path",{d:"M7 4v16",key:"1glfcx"}],["path",{d:"M20 8h-5",key:"1vsyxs"}],["path",{d:"M15 10V6.5a2.5 2.5 0 0 1 5 0V10",key:"ag13bf"}],["path",{d:"M15 14h5l-5 6h5",key:"ur5jdg"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const el=J("arrow-up-down",[["path",{d:"m21 16-4 4-4-4",key:"f6ql7i"}],["path",{d:"M17 20V4",key:"1ejh1v"}],["path",{d:"m3 8 4-4 4 4",key:"11wl7u"}],["path",{d:"M7 4v16",key:"1glfcx"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ia=J("check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const la=J("chevron-down",[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ra=J("chevron-left",[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ca=J("chevron-up",[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const aa=J("chevron-right",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const tl=J("circle-dot",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ua=J("clipboard-list",[["rect",{width:"8",height:"4",x:"8",y:"2",rx:"1",ry:"1",key:"tgr4d6"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",key:"116196"}],["path",{d:"M12 11h4",key:"1jrz19"}],["path",{d:"M12 16h4",key:"n85exb"}],["path",{d:"M8 11h.01",key:"1dfujw"}],["path",{d:"M8 16h.01",key:"18s6g9"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const da=J("clock-3",[["path",{d:"M12 6v6h4",key:"135r8i"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const fa=J("code-xml",[["path",{d:"m18 16 4-4-4-4",key:"1inbqp"}],["path",{d:"m6 8-4 4 4 4",key:"15zrgr"}],["path",{d:"m14.5 4-5 16",key:"e7oirm"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const pa=J("columns-3",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M9 3v18",key:"fh3hqa"}],["path",{d:"M15 3v18",key:"14nvp0"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ha=J("database",[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3",key:"msslwz"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5",key:"1wlel7"}],["path",{d:"M3 12A9 3 0 0 0 21 12",key:"mv7ke4"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ma=J("download",[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ya=J("expand",[["path",{d:"m15 15 6 6",key:"1s409w"}],["path",{d:"m15 9 6-6",key:"ko1vev"}],["path",{d:"M21 16v5h-5",key:"1ck2sf"}],["path",{d:"M21 8V3h-5",key:"1qoq8a"}],["path",{d:"M3 16v5h5",key:"1t08am"}],["path",{d:"m3 21 6-6",key:"wwnumi"}],["path",{d:"M3 8V3h5",key:"1ln10m"}],["path",{d:"M9 9 3 3",key:"v551iv"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const sl=J("file-json-2",[["path",{d:"M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4",key:"1pf5j1"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M4 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1",key:"fq0c9t"}],["path",{d:"M8 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1",key:"4gibmv"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ga=J("funnel",[["path",{d:"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z",key:"sc7q7i"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ba=J("grip-vertical",[["circle",{cx:"9",cy:"12",r:"1",key:"1vctgf"}],["circle",{cx:"9",cy:"5",r:"1",key:"hp0tcf"}],["circle",{cx:"9",cy:"19",r:"1",key:"fkjjf6"}],["circle",{cx:"15",cy:"12",r:"1",key:"1tmaij"}],["circle",{cx:"15",cy:"5",r:"1",key:"19l28e"}],["circle",{cx:"15",cy:"19",r:"1",key:"f4zoj3"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const va=J("list-filter",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M7 12h10",key:"b7w52i"}],["path",{d:"M10 18h4",key:"1ulq68"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const _a=J("moon",[["path",{d:"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z",key:"a7tn18"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const xa=J("pin",[["path",{d:"M12 17v5",key:"bb1du9"}],["path",{d:"M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z",key:"1nkz8b"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const Ca=J("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const ka=J("rotate-ccw",[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const wa=J("rows-3",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M21 9H3",key:"1338ky"}],["path",{d:"M21 15H3",key:"9uk58r"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const Sa=J("save",[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const Ma=J("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const Aa=J("sun",[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const Ta=J("text-cursor-input",[["path",{d:"M12 20h-1a2 2 0 0 1-2-2 2 2 0 0 1-2 2H6",key:"1528k5"}],["path",{d:"M13 8h7a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-7",key:"13ksps"}],["path",{d:"M5 16H4a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h1",key:"1n9rhb"}],["path",{d:"M6 4h1a2 2 0 0 1 2 2 2 2 0 0 1 2-2h1",key:"1mj8rg"}],["path",{d:"M9 6v12",key:"velyjx"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const Pa=J("trash-2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const Ra=J("triangle-alert",[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const Ea=J("upload",[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]]);/**
+ * @license lucide-vue-next v0.525.0 - ISC
+ *
+ * This source code is licensed under the ISC license.
+ * See the LICENSE file in the root directory of this source tree.
+ */const Da=J("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]),Oa={moon:_a,sun:Aa,clipboard:ua,code:fa,download:ma,json:sl,filter:va,sort:na,sortAsc:oa,sortDesc:sa,sortAppend:el,columns:pa,rotate:ka,chevronDown:la,plus:Ca,x:Da,check:ia,text:Ta,funnel:ga,arrowUpDown:el,left:ra,right:aa,up:ca,expand:ya,rows:wa,clock:da,database:ha,alert:Ra,rowSelect:tl,search:Ma,resize:ba,pin:xa,save:Sa,trash:Pa,uploadPreset:Ea,downloadPreset:sl},K={name:"IconGlyph",props:{name:{type:String,required:!0},title:{type:String,default:""},size:{type:Number,default:16},strokeWidth:{type:Number,default:1.9}},render(){const e=Oa[this.name]??tl;return Cs("span",{class:"icon-glyph",title:this.title,"aria-hidden":"true"},[Cs(e,{size:this.size,strokeWidth:this.strokeWidth})])}},nl="akkorn-report-view-vue-v7",ol=[10,25,50,100],Rt="-",Zn=140;function $a(){const e=window.__AKKORN_REPORT__??{},t=e.labels??{},s=e.meta??{},n=(p,h)=>t[p]??t[h]??p,o=qt(()=>Ia(e,n)),i=as(Va(o.value)),r=as({activeModal:"",modalDatasetId:"",longCellValue:"",toast:"",toastTimer:0,resizing:null,contextMenu:null,scrollHints:{}}),c=new Map,u=qt(()=>{const p={};for(const h of o.value)p[h.id]=Na(h,i.datasets[h.id]);return p}),v=qt(()=>Ya(s,e,n)),y=qt(()=>i.theme==="dark"?"moon":"sun"),C=qt(()=>`${s.title??"Report"} • Vue 3 • v${e.version??"1.0"}`);fs(()=>i,()=>ja(i),{deep:!0}),fs(()=>i.theme,p=>{document.documentElement.setAttribute("data-theme",p)},{immediate:!0});function $(){return o.value.find(p=>p.id===r.modalDatasetId)??null}function a(){return r.modalDatasetId?i.datasets[r.modalDatasetId]:null}function b(p,h=""){r.activeModal=p,r.modalDatasetId=h}function T(){r.activeModal="",r.modalDatasetId=""}function q(){r.contextMenu=null}function X(){i.theme=i.theme==="dark"?"light":"dark"}function G(p){i.sections[p]=!i.sections[p]}function ae(p){const h=o.value.find(g=>g.id===p);h&&(i.datasets[p]=il(h,{}))}function B(p){i.datasets[p].filters=[],i.datasets[p].page=1}function me(p,h){i.datasets[p].filters.splice(h,1),i.datasets[p].page=1}function Ze(p){const h=o.value.find(g=>g.id===p);h&&(i.datasets[p].pendingFilter=eo(h,i.datasets[p].pendingFilter),b("filter",p))}function Ve(p){b("sort",p)}function et(p){b("columns",p)}function Xt(){const p=$(),h=a();if(!p||!h||!h.pendingFilter.key)return;h.filters.push({...h.pendingFilter}),h.page=1;const g=h.pendingFilter.key;h.pendingFilter=eo(p,{key:g})}function ht(){const p=a();p&&(p.page=1,T())}function Ot(){const p=a();p&&(p.sorts=[],pt(p),p.page=1)}function Qt(p,h){const g=i.datasets[p],M=g.sorts[0];(M==null?void 0:M.key)===h?g.sorts=[{key:h,dir:M.dir==="asc"?"desc":"asc"},...g.sorts.slice(1)]:g.sorts=[{key:h,dir:"asc"},...g.sorts.filter(R=>R.key!==h)],pt(g),g.page=1}function Zt(){var M,R;const p=$(),h=a();if(!p||!h)return;const g=((M=p.columns.find(L=>!h.sorts.some(j=>j.key===L.key)))==null?void 0:M.key)??((R=p.columns[0])==null?void 0:R.key)??"";g&&(h.sorts.push({key:g,dir:"asc"}),pt(h))}function Ms(p){const h=a();h&&(h.sorts.splice(p,1),pt(h))}function un(p,h){const g=a();!g||!g.sorts[p]||(g.sorts[p].key=h,g.sorts=ln(g.sorts),pt(g))}function be(p,h){const g=a();!g||!g.sorts[p]||(g.sorts[p].dir=h==="desc"?"desc":"asc",pt(g))}function fe(p,h,g=null){const M=i.datasets[p].selectedRows,R=i.datasets[p],L=u.value[p];if(g!=null&&g.shiftKey&&R.lastRowSelection&&L){const ne=L.rows.map(Pe=>Pe.rowId),de=ne.indexOf(R.lastRowSelection),Q=ne.indexOf(h);if(de>=0&&Q>=0){const[Pe,tt]=de=0?M.splice(j,1):M.push(h),R.lastRowSelection=h}function se(p,h,g){i.datasets[p].selectedCell={rowId:h,key:g},i.datasets[p].selectedCells=[`${h}::${g}`],i.datasets[p].anchorCell={rowId:h,key:g},q()}function mt(p,h,g,M=null){const R=i.datasets[p],L=u.value[p];if(M!=null&&M.shiftKey&&R.anchorCell&&L){const j=L.rows.map(Ts=>Ts.rowId),ne=L.visibleColumns.map(Ts=>Ts.key),de=j.indexOf(R.anchorCell.rowId),Q=j.indexOf(h),Pe=ne.indexOf(R.anchorCell.key),tt=ne.indexOf(g);if(de>=0&&Q>=0&&Pe>=0&&tt>=0){const[Ts,Sp]=de0)return M.selectedCells.includes(`${h}::${g}`);const R=M.selectedCell;return!!R&&R.rowId===h&&R.key===g}function yt(p,h){return i.datasets[p].selectedRows.includes(h)}function Ee(p,h){const g=u.value[p];if(!g)return;const M=Math.min(Math.max(1,Ss(h,1)),g.pageCount),R=i.datasets[p];if(R.page===M&&!R.pageBusy)return;c.has(p)&&window.clearTimeout(c.get(p)),R.pageBusy=!0;const L=window.setTimeout(()=>{R.page=M,window.requestAnimationFrame(()=>{R.pageBusy=!1,c.delete(p)})},0);c.set(p,L)}function dn(p,h){Ee(h,p.target.value)}function lo(p){r.longCellValue=Ie(p),q(),b("cell")}function ro(p){return $e(p).length>96}function $t(){Yt(e.sql??"",n("SQL copiado","SQL copied"),r)}function ts(){const p=[s.title??"",s.description??"",`${n("Linhas","Rows")}: ${(e.rows??[]).length}`,`${n("Colunas","Columns")}: ${(e.schema??[]).length}`,`${n("Gerado em","Generated at")}: ${s.generatedAt??""}`].filter(Boolean);Yt(p.join(`
+`),n("Resumo copiado","Summary copied"),r)}function As(){const p=u.value.results;if(!p)return;const h=p.visibleColumns.map(ne=>ne.label),g=p.rows.map(ne=>p.visibleColumns.map(de=>hl(Te(ne.raw,de.key)))),M=[h.map(hl).join(","),...g.map(ne=>ne.join(","))].join(`\r
+`),R=new Blob([M],{type:"text/csv;charset=utf-8;"}),L=URL.createObjectURL(R),j=document.createElement("a");j.href=L,j.download=`${(s.title??"report").replace(/[^\w\-]+/g,"_")}.csv`,j.click(),URL.revokeObjectURL(L)}function fn(){const p=`${yl(s.title??"report")||"report"}.json`,h=new Blob([JSON.stringify(e,null,2)],{type:"application/json;charset=utf-8;"});ml(h,p)}function It(p,h,g,M=!1){const R=i.datasets[p].pickSelection[h];if(!M){R.splice(0,R.length,g);return}const L=R.indexOf(g);L>=0?R.splice(L,1):R.push(g)}function gl(p,h){const g=i.datasets[p],M=u.value[p];if(M){if(h==="add"){for(const R of g.pickSelection.available)g.visibleKeys.includes(R)||g.visibleKeys.push(R);g.pickSelection.available=[];return}h==="remove"&&(g.visibleKeys=g.visibleKeys.filter(R=>!g.pickSelection.visible.includes(R)),g.visibleKeys.length===0&&(g.visibleKeys=M.dataset.columns.slice(0,1).map(R=>R.key)),g.pickSelection.visible=[])}}function f(p,h){const g=i.datasets[p],M=g.pickSelection.visible[0];if(!M)return;const R=g.visibleKeys.indexOf(M);if(R<0)return;const L=h==="up"?R-1:R+1;if(L<0||L>=g.visibleKeys.length)return;const j=[...g.visibleKeys];[j[R],j[L]]=[j[L],j[R]],g.visibleKeys=j}function m(p,h){const g=o.value.find(M=>M.id===p);if(g){if(h==="all"){i.datasets[p].visibleKeys=g.columns.map(M=>M.key);return}i.datasets[p].visibleKeys=g.columns.slice(0,1).map(M=>M.key)}}function _(p){var h;return((h=u.value[p])==null?void 0:h.shownColumns)??[]}function A(p){var h,g;return((g=(h=i.datasets[p])==null?void 0:h.selectedRows)==null?void 0:g.length)??0}function k(p){var L;const h=i.datasets[p],g=h==null?void 0:h.selectedCell,M=u.value[p];if(!g||!M)return;if(((L=h.selectedCells)==null?void 0:L.length)>1){const j=[...new Set(h.selectedCells.map(Q=>Q.split("::")[0]))],ne=M.visibleColumns.map(Q=>Q.key).filter(Q=>h.selectedCells.some(Pe=>Pe.endsWith(`::${Q}`))),de=j.map(Q=>{const Pe=M.rows.find(tt=>tt.rowId===Q);return ne.map(tt=>Ie(Te(Pe==null?void 0:Pe.raw,tt))).join(" ")});Yt(de.join(`
+`),n("Selecao copiada","Selection copied"),r);return}const R=M.rows.find(j=>j.rowId===g.rowId);R&&Yt(Ie(Te(R.raw,g.key)),n("Celula copiada","Cell copied"),r)}function w(p){var j;const h=((j=i.datasets[p])==null?void 0:j.selectedRows)??[],g=u.value[p];if(!g||h.length===0)return;const M=g.rows.filter(ne=>h.includes(ne.rowId));if(M.length===0)return;const R=g.visibleColumns.map(ne=>ne.label),L=M.map(ne=>g.visibleColumns.map(de=>Ie(Te(ne.raw,de.key))).join(" "));Yt([R.join(" "),...L].join(`
+`),n("Linhas copiadas","Rows copied"),r)}function D(p,h,g,M){p.preventDefault(),se(h,g,M);const R=u.value[h],L=R==null?void 0:R.rows.find(ne=>ne.rowId===g),j=L?Te(L.raw,M):"";r.contextMenu={type:"cell",datasetId:h,rowId:g,key:M,value:j,x:p.clientX,y:p.clientY}}function E(p,h,g){p.preventDefault(),q(),r.contextMenu={type:"header",datasetId:h,key:g,x:p.clientX,y:p.clientY}}function P(){const p=r.contextMenu;p&&(i.datasets[p.datasetId].filters.push({key:p.key,operator:"eq",value:Ie(p.value)===Rt?"":$e(p.value)}),i.datasets[p.datasetId].page=1,q())}function S(){const p=r.contextMenu;if(!p)return;const h=i.datasets[p.datasetId];h.visibleKeys=h.visibleKeys.filter(g=>g!==p.key),h.visibleKeys.length===0&&(h.visibleKeys=[p.key]),q()}function H(){const p=r.contextMenu;p&&(i.datasets[p.datasetId].visibleKeys=[p.key],q())}function V(){const p=r.contextMenu;p&&(Yt(Ie(p.value),n("Celula copiada","Cell copied"),r),q())}function N(){const p=r.contextMenu;if(!p)return;const h=i.datasets[p.datasetId];h.pinnedColumnKey=h.pinnedColumnKey===p.key?"":p.key,q()}function U(p,h){var g;return((g=i.datasets[p])==null?void 0:g.pinnedColumnKey)===h}function Y(p,h="primary"){const g=r.contextMenu;if(!g)return;const M=i.datasets[g.datasetId],R=p==="desc"?"desc":"asc",L={key:g.key,dir:R};M.sorts=ln(h==="secondary"?[...M.sorts.filter(j=>j.key!==g.key),L]:[L,...M.sorts.filter(j=>j.key!==g.key)]),pt(M),M.page=1,q()}function Z(p,h){var M,R;const g=(R=(M=i.datasets[p])==null?void 0:M.columnWidths)==null?void 0:R[h];return rn(g)}function re(p,h){return{width:`${Z(p,h)}px`,minWidth:`${Zn}px`}}function he(p,h){return{"sticky-main-col":U(p,h)}}function ye(p,h){return U(p,h)?{left:"28px"}:{}}function Fe(p,h,g){if(p.button!==0)return;const M=Z(h,g);r.resizing={id:h,key:g,startX:p.clientX,startWidth:M};const R=j=>{if(!r.resizing||r.resizing.id!==h||r.resizing.key!==g)return;const ne=r.resizing.startWidth+(j.clientX-r.resizing.startX);i.datasets[h].columnWidths[g]=rn(ne)},L=()=>{window.removeEventListener("mousemove",R),window.removeEventListener("mouseup",L),r.resizing=null};window.addEventListener("mousemove",R),window.addEventListener("mouseup",L),p.preventDefault(),p.stopPropagation()}function je(p,h){const g=u.value[p];if(!g)return;const M=g.visibleColumns.find(j=>j.key===h);if(!M)return;const R=[M.label,...g.rows.slice(0,120).map(j=>Ie(Te(j.raw,h)))],L=Math.max(...R.map(j=>Ha(j,M.kind)));i.datasets[p].columnWidths[h]=rn(L,dl(M.kind))}function Vt(p){const h=i.datasets[p],g=(window.prompt(n("Nome do preset","Preset name"),h.activeCustomPreset||n("Meu preset","My preset"))??"").trim();if(!g)return;const M={name:g,visibleKeys:[...h.visibleKeys],sort:{...h.sort},sorts:h.sorts.map(R=>({...R})),size:h.size,columnWidths:{...h.columnWidths},pinnedColumnKey:h.pinnedColumnKey||"",filters:[...h.filters]};h.customPresets=[...h.customPresets.filter(R=>R.name!==g),M],h.activeCustomPreset=g}function pn(p,h){const g=i.datasets[p],M=o.value.find(j=>j.id===p),R=g.customPresets.find(j=>j.name===h);if(!R||!M)return;const L=so(M,R);g.visibleKeys=[...L.visibleKeys],g.sorts=[...L.sorts],pt(g),g.size=L.size,g.columnWidths={...g.columnWidths,...L.columnWidths},g.pinnedColumnKey=L.pinnedColumnKey||"",g.filters=[...L.filters],g.page=1,g.activeCustomPreset=L.name}function Me(p,h){const g=i.datasets[p];g.customPresets=g.customPresets.filter(M=>M.name!==h),g.activeCustomPreset===h&&(g.activeCustomPreset="")}function Ke(p){const h=i.datasets[p];if(!h||h.customPresets.length===0)return;const g=new Blob([JSON.stringify(h.customPresets,null,2)],{type:"application/json;charset=utf-8;"});ml(g,`${yl(`${s.title??"report"}-${p}-presets`)||"report-presets"}.json`)}function hn(p){const h=document.createElement("input");h.type="file",h.accept="application/json,.json",h.onchange=async()=>{var M;const g=(M=h.files)==null?void 0:M[0];if(g)try{const R=await g.text(),L=JSON.parse(R);if(!Array.isArray(L))throw new Error("invalid");const j=o.value.find(Q=>Q.id===p);if(!j)return;const ne=L.filter(Q=>Q&&typeof Q.name=="string").map(Q=>so(j,Q)),de=i.datasets[p];de.customPresets=Ka([...de.customPresets,...ne]),an(n("Presets importados","Presets imported"),r)}catch{an(n("Falha ao importar presets","Could not import presets"),r)}},h.click()}function mn(p){var j,ne;const h=u.value[p],g=i.datasets[p];if(!h||h.rows.length===0)return[];const M=((j=g.selectedCell)==null?void 0:j.key)||g.pinnedColumnKey||((ne=h.visibleColumns[0])==null?void 0:ne.key),R=h.visibleColumns.find(de=>de.key===M);if(!R)return[];const L=new Map;for(const de of h.rows.slice(0,200)){const Q=$e(Te(de.raw,M)).trim();Q&&L.set(Q,(L.get(Q)??0)+1)}return[...L.entries()].sort((de,Q)=>Q[1]-de[1]).slice(0,5).map(([de,Q])=>({key:M,value:de,count:Q,label:R.label}))}function yp(p,h,g){i.datasets[p].filters.push({key:h,operator:"eq",value:g}),i.datasets[p].page=1}function gp(p,h){const g=o.value.find(j=>j.id===p),M=i.datasets[p];if(!g||!M)return;const R=g.columns.filter(j=>j.kind==="text"),L=g.columns.filter(j=>j.kind!=="text");if(h==="summary")M.visibleKeys=[...L.slice(0,4),...R.slice(0,3)].slice(0,7).map(j=>j.key),M.size=10;else if(h==="audit")M.visibleKeys=g.columns.map(j=>j.key),M.size=25;else if(h==="detailed"){M.visibleKeys=g.columns.map(j=>j.key),M.size=10;for(const j of R)M.columnWidths[j.key]=Math.max(M.columnWidths[j.key]??0,320)}M.page=1,M.activePreset=h}function bp(p,h){const g=(h==null?void 0:h.currentTarget)??(h==null?void 0:h.target);if(!g)return;const M=Math.max(0,g.scrollWidth-g.clientWidth);r.scrollHints[p]={left:g.scrollLeft>8,right:g.scrollLeft{const L=h.dataset.columns.find(j=>j.key===M.key);return L?{index:R,key:M.key,dir:M.dir,label:L.label}:null}).filter(Boolean)}function xp(p){var h;return!!((h=i.datasets[p])!=null&&h.pageBusy)}function Cp(){const p=$(),h=a();return!p||!h?null:p.columns.find(g=>g.key===h.pendingFilter.key)??null}function kp(p,h){return(p==="number"||p==="date")&&h==="between"}function wp(p){return p==="number"?"number":p==="date"?"date":"text"}return $n({payload:e,meta:s,txt:n,state:i,ui:r,datasets:o,datasetViews:u,overviewCards:v,themeIcon:y,footerText:C,activeDataset:$,activeDatasetState:a,toggleTheme:X,toggleSection:G,resetDataset:ae,clearFilters:B,removeFilter:me,openFilterModal:Ze,openSortModal:Ve,openColumnsModal:et,addFilter:Xt,applySort:ht,clearSort:Ot,setSortFromHeader:Qt,toggleRow:fe,selectCell:se,selectCellWithEvent:mt,isCellSelected:es,isRowSelected:yt,changePage:Ee,pageJump:dn,openCell:lo,isLongText:ro,copySql:$t,copySummary:ts,exportCsv:As,exportJson:fn,choosePick:It,moveColumns:gl,moveAllColumns:m,moveVisibleColumnOrder:f,visibleColumnSummary:_,selectedRowsCount:A,copySelectedCell:k,copySelectedRows:w,openCellMenu:D,openHeaderMenu:E,contextFilterByValue:P,contextHideColumn:S,contextShowOnlyColumn:H,copyContextValue:V,contextSort:Y,togglePinnedColumn:N,isPinnedColumn:U,getColumnWidth:Z,columnStyle:re,columnStickyClass:he,columnStickyStyle:ye,startResize:Fe,autoFitColumn:je,applyPreset:gp,saveCustomPreset:Vt,applyCustomPreset:pn,deleteCustomPreset:Me,exportCustomPresets:Ke,importCustomPresets:hn,quickFilterValues:mn,addQuickFilter:yp,updateScrollHint:bp,scrollClass:vp,activeSortSummary:_p,activePendingColumn:Cp,filterUsesRange:kp,filterInputType:wp,isPageBusy:xp,addSortRule:Zt,removeSortRule:Ms,updateSortRuleKey:un,updateSortRuleDirection:be,openModal:b,closeModal:T,closeContextMenu:q,summaryChipText:Qa,columnTone:Xa,allowedOperators:pl,operatorLabel:oo,getValue:Te,displayValue:Ie,stringifyValue:$e,PAGE_SIZES:ol,DEFAULT_EMPTY:Rt})}function Ia(e,t){const s=[],n=La(e.rows??[],e.schema??[]);s.push({id:"results",title:t("Resultados","Results"),searchPlaceholder:t("Buscar resultados","Search results"),columns:n,rows:e.rows??[],preparedRows:fl(e.rows??[],n),collapsed:!1}),(e.schema??[]).length>0&&s.push({id:"schema",title:t("Colunas e schema","Columns and schema"),searchPlaceholder:t("Buscar schema","Search schema"),columns:[{key:"name",label:t("Nome","Name"),kind:"text"},{key:"kind",label:t("Tipo","Type"),kind:"text"},{key:"nullCount",label:t("Nulos","Nulls"),kind:"number"},{key:"distinctCount",label:t("Distintos","Distinct"),kind:"number"},{key:"example",label:t("Exemplo","Example"),kind:"text"},{key:"minValue",label:t("Minimo","Minimum"),kind:"text"},{key:"maxValue",label:t("Maximo","Maximum"),kind:"text"}],rows:(e.schema??[]).map(o=>({name:o.name??o.Name??"",kind:o.kind??o.Kind??"",nullCount:o.nullCount??o.NullCount??0,distinctCount:o.distinctCount??o.DistinctCount??0,example:o.example??o.Example??"",minValue:o.minValue??o.MinValue??"",maxValue:o.maxValue??o.MaxValue??""})),preparedRows:[],collapsed:!0});for(const o of[["metadata",t("Metadados","Metadata"),t("Buscar metadados","Search metadata"),e.metadata??[]],["lineageNodes",t("Nos de linhagem","Lineage nodes"),t("Buscar nos","Search nodes"),e.lineageNodes??[]],["lineageConnections",t("Conexoes de linhagem","Lineage connections"),t("Buscar conexoes","Search connections"),e.lineageConnections??[]]])o[3].length>0&&s.push({id:o[0],title:o[1],searchPlaceholder:o[2],columns:no(o[3]),rows:o[3],preparedRows:[],collapsed:!0});return s}function Va(e){var n;const t=Fa(),s={theme:t.theme==="light"?"light":"dark",sections:{overview:!1,sql:!0},datasets:{}};for(const o of e){const i=((n=t.datasets)==null?void 0:n[o.id])??{};s.sections[o.id]=typeof i.collapsed=="boolean"?i.collapsed:!!o.collapsed,s.datasets[o.id]=il(o,i)}return s}function Fa(){try{return JSON.parse(window.localStorage.getItem(nl)??"{}")}catch{return{}}}function ja(e){const t={theme:e.theme,sections:JSON.parse(JSON.stringify(e.sections)),datasets:JSON.parse(JSON.stringify(e.datasets))};window.localStorage.setItem(nl,JSON.stringify(t))}function il(e,t){var r,c;const s=Gt(e.columns);e.columns=s;const n=s.map(u=>u.key),o=Array.isArray(t.visibleKeys)&&t.visibleKeys.length>0?t.visibleKeys.filter(u=>n.includes(u)):[...n],i={search:typeof t.search=="string"?t.search:"",filters:Array.isArray(t.filters)?t.filters.filter(u=>n.includes(u.key)):[],sort:rl(t.sort,n),sorts:cl(t.sorts,n,t.sort),visibleKeys:o.length>0?o:[...n],page:Ss(t.page,1),pageBusy:!1,size:to(t.size),inlineFiltersOpen:!!t.inlineFiltersOpen,inlineColumnsOpen:!!t.inlineColumnsOpen,selectedRows:Array.isArray(t.selectedRows)?t.selectedRows.map(String):[],selectedCell:t.selectedCell&&typeof t.selectedCell.key=="string"?{rowId:String(t.selectedCell.rowId??""),key:t.selectedCell.key}:null,selectedCells:Array.isArray(t.selectedCells)?t.selectedCells.map(String):[],anchorCell:t.anchorCell&&typeof t.anchorCell.key=="string"?{rowId:String(t.anchorCell.rowId??""),key:t.anchorCell.key}:null,columnWidths:ll(t.columnWidths,s),pendingFilter:eo(e,t.pendingFilter),columnSearch:typeof t.columnSearch=="string"?t.columnSearch:"",activePreset:typeof t.activePreset=="string"?t.activePreset:"",activeCustomPreset:typeof t.activeCustomPreset=="string"?t.activeCustomPreset:"",lastRowSelection:typeof t.lastRowSelection=="string"?t.lastRowSelection:"",pinnedColumnKey:typeof t.pinnedColumnKey=="string"?t.pinnedColumnKey:"",customPresets:Array.isArray(t.customPresets)?t.customPresets.filter(u=>u&&typeof u.name=="string").map(u=>so(e,u)):[],pickSelection:{available:Array.isArray((r=t.pickSelection)==null?void 0:r.available)?t.pickSelection.available.filter(u=>n.includes(u)):[],visible:Array.isArray((c=t.pickSelection)==null?void 0:c.visible)?t.pickSelection.visible.filter(u=>n.includes(u)):[]}};return pt(i),i}function eo(e,t){const s=e.columns[0],n=e.columns.some(r=>r.key===(t==null?void 0:t.key))?t.key:(s==null?void 0:s.key)??"",o=e.columns.find(r=>r.key===n)??s??{kind:"text"},i=pl(o.kind).includes(t==null?void 0:t.operator)?t.operator:qa(o.kind);return{key:n,operator:i,value:(t==null?void 0:t.value)??"",valueTo:(t==null?void 0:t.valueTo)??""}}function ll(e,t){const s={},n=e&&typeof e=="object"?e:{};for(const o of t)s[o.key]=rn(n[o.key],dl(o.kind));return s}function rl(e,t){return!e||!t.includes(e.key)?{key:"",dir:"asc"}:{key:e.key,dir:e.dir==="desc"?"desc":"asc"}}function cl(e,t,s=null){const n=Array.isArray(e)&&e.length>0?e:s?[s]:[];return ln(n.filter(o=>o&&t.includes(o.key)).map(o=>({key:o.key,dir:o.dir==="desc"?"desc":"asc"})))}function ln(e){const t=new Set,s=[];for(const n of e)!(n!=null&&n.key)||t.has(n.key)||(t.add(n.key),s.push({key:n.key,dir:n.dir==="desc"?"desc":"asc"}));return s}function pt(e){e.sort=e.sorts[0]?{...e.sorts[0]}:{key:"",dir:"asc"}}function Ss(e,t){const s=Number.parseInt(e,10);return Number.isFinite(s)&&s>0?s:t}function to(e){const t=Ss(e,10);return ol.includes(t)?t:10}function so(e,t){const s=Gt(e.columns).map(n=>n.key);return{name:String(t.name??"").trim()||"Preset",visibleKeys:Array.isArray(t.visibleKeys)?t.visibleKeys.filter(n=>s.includes(n)):[...s],sort:rl(t.sort,s),sorts:cl(t.sorts,s,t.sort),size:to(t.size),columnWidths:ll(t.columnWidths,e.columns),pinnedColumnKey:typeof t.pinnedColumnKey=="string"&&s.includes(t.pinnedColumnKey)?t.pinnedColumnKey:"",filters:Array.isArray(t.filters)?t.filters.filter(n=>s.includes(n.key)).map(n=>({...n,valueTo:n.valueTo??""})):[]}}function Ka(e){const t=new Map;for(const s of e)s!=null&&s.name&&t.set(s.name,s);return[...t.values()]}function La(e,t){const s=t.filter(n=>n&&typeof n=="object").map(n=>({key:n.name??n.Name??"",label:n.name??n.Name??"",kind:ul(n.kind??n.Kind??al(e,n.name??n.Name??""))}));return s.length>0?Gt(s):Gt(no(e))}function no(e){return e.length?Object.keys(e[0]??{}).map(t=>({key:t,label:t,kind:al(e,t)})):[]}function Gt(e){return(Array.isArray(e)?e:[]).filter(t=>t&&typeof t=="object").map(t=>{const s=String(t.key??t.name??t.Name??"").trim(),n=String(t.label??s).trim(),o=ul(t.kind??"text");return s?{key:s,label:n||s,kind:o}:null}).filter(Boolean)}function al(e,t){for(const s of e){const n=Te(s,t);if(n==null||n==="")continue;if(typeof n=="number")return"number";if(typeof n=="boolean")return"boolean";const o=String(n).trim();return/^-?\d+([.,]\d+)?$/.test(o)?"number":/\d{4}-\d{2}-\d{2}|\d{2}\/\d{2}\/\d{4}/.test(o)?"date":/^(true|false|sim|nao|não)$/i.test(o)?"boolean":"text"}return"text"}function ul(e){const t=String(e??"").toLowerCase();return t.includes("date")||t.includes("time")?"date":t.includes("bool")?"boolean":t.includes("int")||t.includes("number")||t.includes("decimal")||t.includes("float")?"number":"text"}function Na(e,t){const s=Gt(e.columns);e.columns=s;const n=s.filter(b=>t.visibleKeys.includes(b.key)),o=n.length>0?n:s.slice(0,1),i=Array.isArray(e.preparedRows)&&e.preparedRows.length===e.rows.length?e.preparedRows:fl(e.rows,s),r=i.filter(b=>Wa(b,e,t)),c=Ba(r,e,t.sorts),u=to(t.size),v=Math.max(1,Math.ceil(c.length/u)),y=Math.min(Math.max(1,Ss(t.page,1)),v);t.page=y,t.size=u;const C=(y-1)*u,$=c.slice(C,C+u),a=s.find(b=>{var T;return b.key===((T=t.sorts[0])==null?void 0:T.key)})??null;return o.length>0&&!t.visibleKeys.some(b=>o.some(T=>T.key===b))&&(t.visibleKeys=o.map(b=>b.key)),{dataset:e,visibleColumns:o,rows:c,pageRows:$,page:y,pageCount:v,totalRows:i.length,filteredCount:c.length,size:u,sortColumn:a,sortRules:t.sorts,availableColumns:s.filter(b=>!t.visibleKeys.includes(b.key)&&(b.label||b.key).toLowerCase().includes(t.columnSearch.toLowerCase())),shownColumns:s.filter(b=>t.visibleKeys.includes(b.key)),hasRows:c.length>0}}function rn(e,t=Zn){const s=Ss(e,t);return Math.max(Zn,s)}function dl(e){switch(e){case"number":return 160;case"date":return 180;case"boolean":return 150;default:return 240}}function Ha(e,t){const s=$e(e),n=Math.min(Math.max(s.length,8),t==="text"?48:22);return Math.ceil(n*(t==="number"?9:8.2)+48)}function Ua(e,t){for(const s of["id","ID","Id","codigo","Codigo","key","Key"]){const n=Te(e,s);if(n!=null&&n!=="")return`${s}:${String(n)}`}return`row:${t}`}function fl(e,t){const s=Gt(t);return(Array.isArray(e)?e:[]).map((n,o)=>({raw:n,rowId:Ua(n,o),searchText:s.map(i=>$e(Te(n,i.key))).join(" ").toLowerCase()}))}function Wa(e,t,s){const n=s.search.trim().toLowerCase();if(n&&!e.searchText.includes(n))return!1;for(const o of s.filters){const i=t.columns.find(r=>r.key===o.key);if(i&&!Ja(Te(e.raw,i.key),i.kind,o))return!1}return!0}function Ba(e,t,s){const n=Array.isArray(s)?s:[];return n.length===0?e:[...e].sort((o,i)=>{for(const r of n){const c=t.columns.find(y=>y.key===r.key);if(!c)continue;const u=r.dir==="desc"?-1:1,v=za(Te(o.raw,c.key),Te(i.raw,c.key),c.kind)*u;if(v!==0)return v}return 0})}function za(e,t,s){return e===t?0:e==null||e===""?1:t==null||t===""?-1:s==="number"?Et(e)-Et(t):s==="date"?Dt(e)-Dt(t):s==="boolean"?Number(cn(e))-Number(cn(t)):$e(e).localeCompare($e(t),void 0,{numeric:!0,sensitivity:"base"})}function Et(e){if(typeof e=="number")return e;const t=String(e).replace(/\./g,"").replace(",","."),s=Number.parseFloat(t);return Number.isFinite(s)?s:0}function Dt(e){if(e instanceof Date)return e.getTime();const t=String(e).trim();if(/^\d{2}\/\d{2}\/\d{4}$/.test(t)){const[n,o,i]=t.split("/");return new Date(`${i}-${o}-${n}T00:00:00`).getTime()}const s=Date.parse(t);return Number.isFinite(s)?s:0}function cn(e){return typeof e=="boolean"?e:/^(true|sim|yes|1)$/i.test(String(e))}function Te(e,t){if(!e||typeof e!="object")return;if(Object.prototype.hasOwnProperty.call(e,t))return e[t];const s=Object.keys(e).find(n=>n.toLowerCase()===String(t).toLowerCase());return s?e[s]:void 0}function $e(e){return e==null||e===""?"":String(e)}function Ie(e){return $e(e)||Rt}function pl(e){return e==="number"||e==="date"?["between","eq","neq","gt","gte","lt","lte"]:e==="boolean"?["eq","neq"]:["contains","like","regex","eq","neq","starts","ends"]}function qa(e){return e==="text"?"contains":e==="number"||e==="date"?"between":"eq"}function oo(e){return{contains:"Contains",like:"Like",regex:"Regex",between:"Between",eq:"Equals",neq:"Different",gt:"Greater than",gte:"Greater or equal",lt:"Less than",lte:"Less or equal",starts:"Starts with",ends:"Ends with"}[e]??e}function Ja(e,t,s){const n=$e(e),o=$e(s.value),i=$e(s.valueTo);if(t==="number"){if(s.operator==="between"){const u=Et(n);return u>=Et(o)&&u<=Et(i)}return io(Et(n),Et(o),s.operator)}if(t==="date"){if(s.operator==="between"){const u=Dt(n);return u>=Dt(o)&&u<=Dt(i)}return io(Dt(n),Dt(o),s.operator)}if(t==="boolean")return io(cn(n),cn(o),s.operator);const r=n.toLowerCase(),c=o.toLowerCase();switch(s.operator){case"contains":return r.includes(c);case"starts":return r.startsWith(c);case"ends":return r.endsWith(c);case"like":return Ga(o).test(n);case"regex":try{return new RegExp(o,"i").test(n)}catch{return!1}case"eq":return r===c;case"neq":return r!==c;default:return!0}}function io(e,t,s){switch(s){case"eq":return e===t;case"neq":return e!==t;case"gt":return e>t;case"gte":return e>=t;case"lt":return ean(t,s)).catch(()=>an("Could not copy",s))}function an(e,t){t&&(window.clearTimeout(t.toastTimer),t.toast=e,t.toastTimer=window.setTimeout(()=>{t.toast=""},1800))}function yl(e){return String(e??"").normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function Ya(e,t,s){const n=e.warnings??[];return[{label:s("Linhas","Rows"),value:new Intl.NumberFormat().format(Number((t.rows??[]).length)),icon:"rows"},{label:s("Colunas","Columns"),value:new Intl.NumberFormat().format(Number((t.schema??[]).length||no(t.rows??[]).length)),icon:"columns"},{label:s("Tempo","Duration"),value:e.duration??Rt,icon:"clock"},{label:s("Conexao","Connection"),value:e.connectionName??Rt,icon:"database"},{label:s("Gerado em","Generated at"),value:e.generatedAt??Rt,icon:"clock"},{label:s("Descricao","Description"),value:e.description||Rt,icon:"clipboard",span:"wide"},{label:"Warnings",value:n.length>0?n.join(" • "):s("Nenhum","None"),icon:"alert",tone:n.length>0?"warning":""}]}function Xa(e,t){return t==null||t===""?"is-null":e==="number"?"is-number":e==="date"?"is-date":e==="boolean"?"is-boolean":"is-text"}function Qa(e){return e.operator==="between"?`${e.key} • ${oo(e.operator)} • ${Ie(e.value)} → ${Ie(e.valueTo)}`:`${e.key} • ${oo(e.operator)} • ${Ie(e.value)}`}const Za={class:"page-header"},eu={class:"brand-wrap"},tu={class:"brand-copy"},su={class:"brand-sub"},nu={class:"page-intro"},ou={class:"toolbar"},iu=["disabled"],lu=["disabled"],ru={class:"main-content"},cu={class:"panel"},au={class:"section-head"},uu={class:"section-copy"},du={key:0,class:"overview-grid"},fu={class:"overview-icon"},pu={class:"overview-content"},hu={class:"overview-label"},mu={class:"overview-value"},yu={class:"section-head"},gu={class:"section-copy"},bu={class:"section-actions"},vu={class:"search-field"},_u=["onUpdate:modelValue","placeholder"],xu=["onClick"],Cu=["onClick"],ku=["onClick"],wu=["onClick"],Su=["onClick"],Mu={key:0,class:"dataset-body"},Au={class:"summary-strip"},Tu={class:"mini-panel"},Pu={class:"mini-panel-head"},Ru={class:"mini-panel-title"},Eu={class:"mini-panel-actions"},Du=["onClick"],Ou=["onClick"],$u={key:0,class:"chips"},Iu=["onClick"],Vu={key:0,class:"chip empty"},Fu={class:"mini-panel"},ju={class:"mini-panel-head"},Ku={class:"mini-panel-title"},Lu={class:"mini-panel-actions"},Nu=["onClick"],Hu=["onClick"],Uu={key:0,class:"chips"},Wu={class:"mini-panel"},Bu={class:"mini-panel-head"},zu={class:"mini-panel-title"},qu={class:"chips"},Ju={key:0,class:"chip empty"},Gu={class:"table-meta"},Yu={class:"table-meta-main"},Xu={class:"result-count"},Qu={key:0,class:"preset-toolbar"},Zu={class:"preset-segmented"},ed=["onClick"],td=["onClick"],sd=["onClick"],nd={class:"preset-actions"},od=["onClick","title"],id=["disabled","onClick","title"],ld=["onClick","title"],rd=["value","onChange"],cd={value:""},ad=["value"],ud={key:0,class:"preset-secondary"},dd=["disabled","onClick"],fd={class:"table-status"},pd={class:"status-pill"},hd={class:"status-pill"},md={key:0,class:"status-pill"},yd={key:1,class:"table-quick-actions"},gd=["disabled","onClick"],bd=["disabled","onClick"],vd={key:0,class:"quick-filters-wrap"},_d={class:"quick-filters"},xd={class:"quick-filters-label"},Cd=["onClick"],kd=["onScroll","onMouseenter"],wd={class:"report-table"},Sd=["onContextmenu"],Md={class:"th-shell"},Ad=["onClick"],Td={key:0,class:"sort-mark"},Pd=["title","onMousedown","onDblclick"],Rd={key:0},Ed={class:"select-col sticky-select"},Dd=["onClick"],Od=["onClick","onDblclick","onContextmenu"],$d={class:"cell-body"},Id={class:"cell-text"},Vd=["onClick"],Fd={key:1},jd=["colspan"],Kd={key:1,class:"table-loading"},Ld={class:"table-loading-card"},Nd={class:"pager-wrap pager-wrap-bottom"},Hd={class:"page-size-wrap"},Ud={class:"field-label"},Wd=["onUpdate:modelValue"],Bd=["value"],zd={class:"pager"},qd=["disabled","onClick"],Jd={class:"pager-readout"},Gd=["max","value","onChange"],Yd=["disabled","onClick"],Xd={key:0,class:"panel"},Qd={class:"section-head"},Zd={class:"section-copy"},ef={key:0,class:"sql-box"},tf={class:"page-footer"},sf={class:"modal-card"},nf={class:"modal-head"},of={class:"modal-title"},lf={class:"section-copy"},rf={key:0,class:"modal-body"},cf={class:"form-grid"},af={class:"field-stack"},uf={class:"field-label"},df=["value"],ff={class:"field-stack"},pf={class:"field-label"},hf=["value"],mf={key:0,class:"field-stack field-span"},yf={class:"field-label"},gf={class:"field-stack"},bf={class:"field-label"},vf=["type"],_f={class:"field-stack"},xf={class:"field-label"},Cf=["type"],kf={key:2,class:"field-stack field-span"},wf={class:"field-label"},Sf=["type"],Mf={class:"modal-foot"},Af={class:"modal-card"},Tf={class:"modal-head"},Pf={class:"modal-title"},Rf={class:"section-copy"},Ef={key:0,class:"modal-body"},Df={class:"sort-rules"},Of={class:"field-stack"},$f={class:"field-label"},If=["value","onChange"],Vf={value:""},Ff=["value"],jf={class:"field-stack"},Kf={class:"field-label"},Lf=["value","onChange"],Nf={value:"asc"},Hf={value:"desc"},Uf=["onClick"],Wf={key:0,class:"chip empty"},Bf={class:"modal-foot"},zf={class:"modal-card modal-wide"},qf={class:"modal-head"},Jf={class:"modal-title"},Gf={class:"section-copy"},Yf={key:0,class:"modal-body"},Xf={class:"picklist"},Qf={class:"pick-pane"},Zf={class:"field-label"},ep=["placeholder"],tp={class:"pick-list"},sp=["onClick"],np={class:"pick-actions"},op={class:"pick-pane"},ip={class:"field-label"},lp={class:"pick-list"},rp=["onClick"],cp={class:"modal-foot"},ap={class:"modal-card modal-cell"},up={class:"modal-head"},dp={class:"modal-title"},fp={class:"section-copy"},pp={class:"modal-body"},hp={class:"cell-modal-text"},mp={key:6,class:"toast"};Gc({__name:"App",setup(e){const t=$a();return(s,n)=>{var o,i,r,c,u,v,y,C,$;return I(),F("div",{class:"report-shell",onClick:n[47]||(n[47]=(...a)=>l(t).closeContextMenu&&l(t).closeContextMenu(...a))},[d("header",Za,[d("div",eu,[n[49]||(n[49]=d("div",{class:"brand-mark"},"A",-1)),d("div",tu,[n[48]||(n[48]=d("div",{class:"brand-name"},"AkkornStudio",-1)),d("div",su,x(l(t).meta.tabTitle||l(t).meta.title),1)])]),d("div",nu,[d("h1",null,x(l(t).meta.title),1)]),d("div",ou,[d("button",{class:"ghost-btn",type:"button",onClick:n[0]||(n[0]=(...a)=>l(t).toggleTheme&&l(t).toggleTheme(...a))},[O(l(K),{name:l(t).themeIcon},null,8,["name"]),d("span",null,x(l(t).txt("Tema","Theme")),1)]),d("button",{class:"ghost-btn",type:"button",onClick:n[1]||(n[1]=(...a)=>l(t).copySummary&&l(t).copySummary(...a))},[O(l(K),{name:"clipboard"}),d("span",null,x(l(t).txt("Copiar resumo","Copy summary")),1)]),d("button",{class:"ghost-btn",type:"button",onClick:n[2]||(n[2]=(...a)=>l(t).copySql&&l(t).copySql(...a)),disabled:!(l(t).payload.sql??"").trim()},[O(l(K),{name:"code"}),d("span",null,x(l(t).txt("Copiar SQL","Copy SQL")),1)],8,iu),d("button",{class:"ghost-btn",type:"button",onClick:n[3]||(n[3]=(...a)=>l(t).exportCsv&&l(t).exportCsv(...a)),disabled:!l(t).datasetViews.results},[O(l(K),{name:"download"}),d("span",null,x(l(t).txt("Exportar visivel CSV","Export visible CSV")),1)],8,lu),d("button",{class:"ghost-btn",type:"button",onClick:n[4]||(n[4]=(...a)=>l(t).exportJson&&l(t).exportJson(...a))},[O(l(K),{name:"json"}),d("span",null,x(l(t).txt("Exportar JSON","Export JSON")),1)])])]),d("main",ru,[d("section",cu,[d("div",au,[d("div",null,[d("h2",null,x(l(t).txt("Visao geral","Overview")),1),d("p",uu,x(l(t).txt("Panorama rapido da consulta e do resultado exportado.","Quick summary of the query and exported result.")),1)]),d("button",{class:"collapse-btn",type:"button",onClick:n[5]||(n[5]=a=>l(t).toggleSection("overview"))},[O(l(K),{name:"chevronDown"}),d("span",null,x(l(t).state.sections.overview?l(t).txt("Expandir","Expand"):l(t).txt("Recolher","Collapse")),1)])]),l(t).state.sections.overview?le("",!0):(I(),F("div",du,[(I(!0),F(ie,null,ge((l(t).overviewCards??[]).filter(Boolean),a=>(I(),F("article",{key:a.label,class:Ne(["overview-card",[a.span==="wide"?"is-wide":"",a.tone?`is-${a.tone}`:""]])},[d("div",fu,[O(l(K),{name:a.icon},null,8,["name"])]),d("div",pu,[d("div",hu,x(a.label),1),d("div",mu,x(a.value),1)])],2))),128))]))]),(I(!0),F(ie,null,ge(l(t).datasets,a=>(I(),F("section",{key:a.id,class:"panel"},[d("div",yu,[d("div",null,[d("h2",null,x(a.title),1),d("p",gu,x(a.searchPlaceholder),1)]),d("div",bu,[d("label",vu,[O(l(K),{name:"search"}),rt(d("input",{"onUpdate:modelValue":b=>l(t).state.datasets[a.id].search=b,class:"field-input compact-search",type:"search",placeholder:a.searchPlaceholder},null,8,_u),[[sn,l(t).state.datasets[a.id].search]])]),d("button",{class:"ghost-btn",type:"button",onClick:b=>l(t).openFilterModal(a.id)},[O(l(K),{name:"filter"}),d("span",null,x(l(t).txt("Filtros","Filters")),1)],8,xu),d("button",{class:"ghost-btn",type:"button",onClick:b=>l(t).openSortModal(a.id)},[O(l(K),{name:"sort"}),d("span",null,x(l(t).txt("Ordenacao","Sorting")),1)],8,Cu),d("button",{class:"ghost-btn",type:"button",onClick:b=>l(t).openColumnsModal(a.id)},[O(l(K),{name:"columns"}),d("span",null,x(l(t).txt("Colunas","Columns")),1)],8,ku),d("button",{class:"ghost-btn",type:"button",onClick:b=>l(t).resetDataset(a.id)},[O(l(K),{name:"rotate"}),d("span",null,x(l(t).txt("Resetar visao","Reset view")),1)],8,wu),d("button",{class:"collapse-btn",type:"button",onClick:b=>l(t).toggleSection(a.id)},[O(l(K),{name:"chevronDown"}),d("span",null,x(l(t).state.sections[a.id]?l(t).txt("Expandir","Expand"):l(t).txt("Recolher","Collapse")),1)],8,Su)])]),l(t).state.sections[a.id]?le("",!0):(I(),F("div",Mu,[d("div",Au,[d("article",Tu,[d("div",Pu,[d("div",Ru,x(l(t).txt("Filtros ativos","Active filters")),1),d("div",Eu,[d("button",{class:"icon-only",type:"button",onClick:b=>l(t).state.datasets[a.id].inlineFiltersOpen=!l(t).state.datasets[a.id].inlineFiltersOpen},[O(l(K),{name:"chevronDown"})],8,Du),d("button",{class:"ghost-btn small",type:"button",onClick:b=>l(t).clearFilters(a.id)},[O(l(K),{name:"rotate"}),d("span",null,x(l(t).txt("Limpar","Clear")),1)],8,Ou)])]),l(t).state.datasets[a.id].inlineFiltersOpen?(I(),F("div",$u,[(I(!0),F(ie,null,ge(l(t).state.datasets[a.id].filters,(b,T)=>(I(),F("button",{key:`${b.key}-${T}`,class:"chip removable",type:"button",onClick:q=>l(t).removeFilter(a.id,T)},[d("span",null,x(l(t).summaryChipText(b)),1),O(l(K),{name:"x"})],8,Iu))),128)),l(t).state.datasets[a.id].filters.length===0?(I(),F("div",Vu,x(l(t).txt("Nenhum filtro aplicado","No active filters")),1)):le("",!0)])):le("",!0)]),d("article",Fu,[d("div",ju,[d("div",Ku,x(l(t).txt("Colunas visiveis","Visible columns")),1),d("div",Lu,[d("button",{class:"icon-only",type:"button",onClick:b=>l(t).state.datasets[a.id].inlineColumnsOpen=!l(t).state.datasets[a.id].inlineColumnsOpen},[O(l(K),{name:"chevronDown"})],8,Nu),d("button",{class:"ghost-btn small",type:"button",onClick:b=>l(t).moveAllColumns(a.id,"all")},[O(l(K),{name:"rotate"}),d("span",null,x(l(t).txt("Resetar","Reset")),1)],8,Hu)])]),l(t).state.datasets[a.id].inlineColumnsOpen?(I(),F("div",Uu,[(I(!0),F(ie,null,ge((l(t).visibleColumnSummary(a.id)??[]).filter(Boolean),b=>(I(),F("div",{key:b.key,class:"chip"},x(b.label??b.key??l(t).DEFAULT_EMPTY),1))),128))])):le("",!0)]),d("article",Wu,[d("div",Bu,[d("div",zu,x(l(t).txt("Ordenacao ativa","Active sorting")),1)]),d("div",qu,[(I(!0),F(ie,null,ge(l(t).activeSortSummary(a.id),b=>(I(),F("div",{key:`${b.key}-${b.index}`,class:"chip"},x(b.index+1)+" • "+x(b.label??b.key??l(t).DEFAULT_EMPTY)+" • "+x(b.dir==="desc"?l(t).txt("Decrescente","Descending"):l(t).txt("Crescente","Ascending")),1))),128)),l(t).activeSortSummary(a.id).length===0?(I(),F("div",Ju,x(l(t).txt("Sem ordenacao ativa","No active sorting")),1)):le("",!0)])])]),d("div",{class:Ne(["table-shell",{"is-page-busy":l(t).isPageBusy(a.id)}])},[d("div",Gu,[d("div",Yu,[d("div",Xu,x(l(t).datasetViews[a.id].filteredCount)+" / "+x(l(t).datasetViews[a.id].totalRows),1),a.id==="results"?(I(),F("div",Qu,[d("div",Zu,[d("button",{class:"segment-btn",type:"button",onClick:b=>l(t).applyPreset(a.id,"summary")},x(l(t).txt("Resumo","Summary")),9,ed),d("button",{class:"segment-btn",type:"button",onClick:b=>l(t).applyPreset(a.id,"audit")},x(l(t).txt("Auditoria","Audit")),9,td),d("button",{class:"segment-btn",type:"button",onClick:b=>l(t).applyPreset(a.id,"detailed")},x(l(t).txt("Detalhado","Detailed")),9,sd)]),d("div",nd,[d("button",{class:"icon-chip",type:"button",onClick:b=>l(t).saveCustomPreset(a.id),title:l(t).txt("Salvar preset","Save preset")},[O(l(K),{name:"save"})],8,od),d("button",{class:"icon-chip",type:"button",disabled:l(t).state.datasets[a.id].customPresets.length===0,onClick:b=>l(t).exportCustomPresets(a.id),title:l(t).txt("Exportar presets","Export presets")},[O(l(K),{name:"downloadPreset"})],8,id),d("button",{class:"icon-chip",type:"button",onClick:b=>l(t).importCustomPresets(a.id),title:l(t).txt("Importar presets","Import presets")},[O(l(K),{name:"uploadPreset"})],8,ld)])])):le("",!0),a.id==="results"&&l(t).state.datasets[a.id].customPresets.length>0?(I(),F("select",{key:1,value:l(t).state.datasets[a.id].activeCustomPreset,class:"field-input preset-select",onChange:b=>l(t).applyCustomPreset(a.id,b.target.value)},[d("option",cd,x(l(t).txt("Presets salvos","Saved presets")),1),(I(!0),F(ie,null,ge(l(t).state.datasets[a.id].customPresets,b=>(I(),F("option",{key:b.name,value:b.name},x(b.name),9,ad))),128))],40,rd)):le("",!0)]),a.id==="results"&&l(t).state.datasets[a.id].customPresets.length>0?(I(),F("div",ud,[d("button",{class:"ghost-btn small",type:"button",disabled:!l(t).state.datasets[a.id].activeCustomPreset,onClick:b=>l(t).deleteCustomPreset(a.id,l(t).state.datasets[a.id].activeCustomPreset)},[O(l(K),{name:"trash"}),d("span",null,x(l(t).txt("Excluir preset","Delete preset")),1)],8,dd)])):le("",!0),d("div",fd,[d("span",pd,x(l(t).txt("Colunas visiveis","Visible columns"))+": "+x(l(t).datasetViews[a.id].visibleColumns.length),1),d("span",hd,x(l(t).txt("Linhas selecionadas","Selected rows"))+": "+x(l(t).selectedRowsCount(a.id)),1),l(t).state.datasets[a.id].selectedCell?(I(),F("span",md,x(l(t).txt("Celula selecionada","Selected cell")),1)):le("",!0)]),a.id==="results"?(I(),F("div",yd,[d("button",{class:"ghost-btn small",type:"button",disabled:!l(t).state.datasets[a.id].selectedCell,onClick:b=>l(t).copySelectedCell(a.id)},[O(l(K),{name:"clipboard"}),d("span",null,x(l(t).txt("Copiar celula","Copy cell")),1)],8,gd),d("button",{class:"ghost-btn small",type:"button",disabled:l(t).selectedRowsCount(a.id)===0,onClick:b=>l(t).copySelectedRows(a.id)},[O(l(K),{name:"rows"}),d("span",null,x(l(t).txt("Copiar linhas","Copy rows")),1)],8,bd)])):le("",!0)]),a.id==="results"&&l(t).quickFilterValues(a.id).length>0?(I(),F("div",vd,[d("div",_d,[d("span",xd,x(l(t).txt("Filtros rapidos","Quick filters")),1),(I(!0),F(ie,null,ge(l(t).quickFilterValues(a.id),b=>(I(),F("button",{key:`${b.key}-${b.value}`,class:"chip quick-chip",type:"button",onClick:T=>l(t).addQuickFilter(a.id,b.key,b.value)},[d("span",null,x(b.value),1),d("small",null,x(b.count),1)],8,Cd))),128))])])):le("",!0),d("div",{class:Ne(["table-scroll",l(t).scrollClass(a.id)]),onScroll:b=>l(t).updateScrollHint(a.id,b),onMouseenter:b=>l(t).updateScrollHint(a.id,b)},[d("table",wd,[d("colgroup",null,[n[50]||(n[50]=d("col",{class:"select-col-width"},null,-1)),(I(!0),F(ie,null,ge((l(t).datasetViews[a.id].visibleColumns??[]).filter(Boolean),b=>(I(),F("col",{key:`col-${b.key}`,style:gt(l(t).columnStyle(a.id,b.key))},null,4))),128))]),d("thead",null,[d("tr",null,[n[51]||(n[51]=d("th",{class:"select-col sticky-select"},null,-1)),(I(!0),F(ie,null,ge((l(t).datasetViews[a.id].visibleColumns??[]).filter(Boolean),b=>{var T,q;return I(),F("th",{key:b.key,style:gt([l(t).columnStyle(a.id,b.key),l(t).columnStickyStyle(a.id,b.key)]),class:Ne([l(t).columnStickyClass(a.id,b.key)]),onContextmenu:X=>l(t).openHeaderMenu(X,a.id,b.key)},[d("div",Md,[d("button",{class:"sort-head",type:"button",onClick:X=>l(t).setSortFromHeader(a.id,b.key)},[d("span",null,x(b.label??b.key??l(t).DEFAULT_EMPTY),1),((T=l(t).state.datasets[a.id].sorts[0])==null?void 0:T.key)===b.key?(I(),F("span",Td,x(((q=l(t).state.datasets[a.id].sorts[0])==null?void 0:q.dir)==="asc"?"▲":"▼"),1)):le("",!0)],8,Ad),d("button",{class:"resize-handle",type:"button",title:l(t).txt("Redimensionar coluna","Resize column"),onMousedown:X=>l(t).startResize(X,a.id,b.key),onDblclick:kt(X=>l(t).autoFitColumn(a.id,b.key),["stop"])},[O(l(K),{name:"resize",size:14})],40,Pd)])],46,Sd)}),128))])]),l(t).datasetViews[a.id].pageRows.length>0?(I(),F("tbody",Rd,[(I(!0),F(ie,null,ge(l(t).datasetViews[a.id].pageRows,b=>(I(),F("tr",{key:b.rowId,class:Ne({"is-row-selected":l(t).isRowSelected(a.id,b.rowId)})},[d("td",Ed,[d("button",{class:"row-selector",type:"button",onClick:T=>l(t).toggleRow(a.id,b.rowId,T)},[O(l(K),{name:"rowSelect",size:14,"stroke-width":2.1})],8,Dd)]),(I(!0),F(ie,null,ge((l(t).datasetViews[a.id].visibleColumns??[]).filter(Boolean),T=>(I(),F("td",{key:`${b.rowId}-${T.key}`,style:gt([l(t).columnStyle(a.id,T.key),l(t).columnStickyStyle(a.id,T.key)]),class:Ne(["cell",l(t).columnTone(T.kind,l(t).getValue(b.raw,T.key)),l(t).columnStickyClass(a.id,T.key),{"is-selected-cell":l(t).isCellSelected(a.id,b.rowId,T.key)}]),onClick:q=>l(t).selectCellWithEvent(a.id,b.rowId,T.key,q),onDblclick:q=>l(t).isLongText(l(t).getValue(b.raw,T.key))&&l(t).openCell(l(t).getValue(b.raw,T.key)),onContextmenu:q=>l(t).openCellMenu(q,a.id,b.rowId,T.key)},[d("div",$d,[d("span",Id,x(l(t).displayValue(l(t).getValue(b.raw,T.key))),1),l(t).isLongText(l(t).getValue(b.raw,T.key))?(I(),F("button",{key:0,class:"cell-expand",type:"button",onClick:kt(q=>l(t).openCell(l(t).getValue(b.raw,T.key)),["stop"])},[O(l(K),{name:"expand"})],8,Vd)):le("",!0)])],46,Od))),128))],2))),128))])):(I(),F("tbody",Fd,[d("tr",null,[d("td",{colspan:Math.max(1,l(t).datasetViews[a.id].visibleColumns.length+1),class:"empty-state"},x(l(t).txt("Nenhuma linha disponivel","No rows available")),9,jd)])]))])],42,kd),l(t).isPageBusy(a.id)?(I(),F("div",Kd,[d("div",Ld,[n[52]||(n[52]=d("span",{class:"table-loading-spinner"},null,-1)),d("span",null,x(l(t).txt("Atualizando pagina","Updating page")),1)])])):le("",!0),d("div",Nd,[d("div",Hd,[d("label",Ud,x(l(t).txt("Tamanho da pagina","Page size")),1),rt(d("select",{"onUpdate:modelValue":b=>l(t).state.datasets[a.id].size=b,class:"field-input compact-select"},[(I(!0),F(ie,null,ge(l(t).PAGE_SIZES,b=>(I(),F("option",{key:b,value:b},x(b),9,Bd))),128))],8,Wd),[[ws,l(t).state.datasets[a.id].size,void 0,{number:!0}]])]),d("div",zd,[d("button",{class:"icon-only",type:"button",disabled:l(t).datasetViews[a.id].page<=1,onClick:b=>l(t).changePage(a.id,l(t).datasetViews[a.id].page-1)},[O(l(K),{name:"left",title:l(t).txt("Pagina anterior","Previous page")},null,8,["title"])],8,qd),d("div",Jd,x(l(t).txt("Pagina","Page"))+" "+x(l(t).datasetViews[a.id].page)+" "+x(l(t).txt("de","of"))+" "+x(l(t).datasetViews[a.id].pageCount),1),d("input",{class:"pager-input",type:"number",min:"1",max:l(t).datasetViews[a.id].pageCount,value:l(t).datasetViews[a.id].page,onChange:b=>l(t).pageJump(b,a.id)},null,40,Gd),d("button",{class:"icon-only",type:"button",disabled:l(t).datasetViews[a.id].page>=l(t).datasetViews[a.id].pageCount,onClick:b=>l(t).changePage(a.id,l(t).datasetViews[a.id].page+1)},[O(l(K),{name:"right",title:l(t).txt("Proxima pagina","Next page")},null,8,["title"])],8,Yd)])])],2)]))]))),128)),(l(t).payload.sql??"").trim().length>0?(I(),F("section",Xd,[d("div",Qd,[d("div",null,[n[53]||(n[53]=d("h2",null,"SQL",-1)),d("p",Zd,x(l(t).txt("Consulta completa exportada no relatorio.","Full query exported in the report.")),1)]),d("button",{class:"collapse-btn",type:"button",onClick:n[6]||(n[6]=a=>l(t).toggleSection("sql"))},[O(l(K),{name:"chevronDown"}),d("span",null,x(l(t).state.sections.sql?l(t).txt("Expandir","Expand"):l(t).txt("Recolher","Collapse")),1)])]),l(t).state.sections.sql?le("",!0):(I(),F("div",ef,[d("pre",null,x(l(t).payload.sql),1)]))])):le("",!0)]),d("footer",tf,x(l(t).footerText),1),l(t).ui.activeModal==="filter"?(I(),F("div",{key:0,class:"modal-shell",onClick:n[16]||(n[16]=kt((...a)=>l(t).closeModal&&l(t).closeModal(...a),["self"]))},[d("div",sf,[d("div",nf,[d("div",null,[d("div",of,x(l(t).txt("Adicionar filtro","Add filter")),1),d("div",lf,x(l(t).txt("Escolha coluna, condicao e valor.","Choose column, condition and value.")),1)]),d("button",{class:"icon-only",type:"button",onClick:n[7]||(n[7]=(...a)=>l(t).closeModal&&l(t).closeModal(...a))},[O(l(K),{name:"x"})])]),l(t).activeDataset()&&l(t).activeDatasetState()?(I(),F("div",rf,[d("div",cf,[d("label",af,[d("span",uf,[O(l(K),{name:"columns"}),at(" "+x(l(t).txt("Coluna","Column")),1)]),rt(d("select",{"onUpdate:modelValue":n[8]||(n[8]=a=>l(t).activeDatasetState().pendingFilter.key=a),class:"field-input"},[(I(!0),F(ie,null,ge((l(t).activeDataset().columns??[]).filter(Boolean),a=>(I(),F("option",{key:a.key,value:a.key},x(a.label??a.key??l(t).DEFAULT_EMPTY),9,df))),128))],512),[[ws,l(t).activeDatasetState().pendingFilter.key]])]),d("label",ff,[d("span",pf,[O(l(K),{name:"funnel"}),at(" "+x(l(t).txt("Condicao","Condition")),1)]),rt(d("select",{"onUpdate:modelValue":n[9]||(n[9]=a=>l(t).activeDatasetState().pendingFilter.operator=a),class:"field-input"},[(I(!0),F(ie,null,ge(l(t).allowedOperators((l(t).activePendingColumn()??{kind:"text"}).kind),a=>(I(),F("option",{key:a,value:a},x(l(t).operatorLabel(a)),9,hf))),128))],512),[[ws,l(t).activeDatasetState().pendingFilter.operator]])]),(((o=l(t).activePendingColumn())==null?void 0:o.kind)??"text")==="boolean"?(I(),F("label",mf,[d("span",yf,[O(l(K),{name:"text"}),at(" "+x(l(t).txt("Valor","Value")),1)]),rt(d("select",{"onUpdate:modelValue":n[10]||(n[10]=a=>l(t).activeDatasetState().pendingFilter.value=a),class:"field-input"},[...n[54]||(n[54]=[d("option",{value:"true"},"True",-1),d("option",{value:"false"},"False",-1),d("option",{value:"sim"},"Sim",-1),d("option",{value:"nao"},"Não",-1)])],512),[[ws,l(t).activeDatasetState().pendingFilter.value]])])):l(t).filterUsesRange(((i=l(t).activePendingColumn())==null?void 0:i.kind)??"text",l(t).activeDatasetState().pendingFilter.operator)?(I(),F(ie,{key:1},[d("label",gf,[d("span",bf,[O(l(K),{name:"text"}),at(" "+x(l(t).txt("De","From")),1)]),rt(d("input",{"onUpdate:modelValue":n[11]||(n[11]=a=>l(t).activeDatasetState().pendingFilter.value=a),class:"field-input",type:l(t).filterInputType(((r=l(t).activePendingColumn())==null?void 0:r.kind)??"text")},null,8,vf),[[Qn,l(t).activeDatasetState().pendingFilter.value]])]),d("label",_f,[d("span",xf,[O(l(K),{name:"text"}),at(" "+x(l(t).txt("Ate","To")),1)]),rt(d("input",{"onUpdate:modelValue":n[12]||(n[12]=a=>l(t).activeDatasetState().pendingFilter.valueTo=a),class:"field-input",type:l(t).filterInputType(((c=l(t).activePendingColumn())==null?void 0:c.kind)??"text")},null,8,Cf),[[Qn,l(t).activeDatasetState().pendingFilter.valueTo]])])],64)):(I(),F("label",kf,[d("span",wf,[O(l(K),{name:"text"}),at(" "+x(l(t).txt("Valor","Value")),1)]),rt(d("input",{"onUpdate:modelValue":n[13]||(n[13]=a=>l(t).activeDatasetState().pendingFilter.value=a),class:"field-input",type:l(t).filterInputType(((u=l(t).activePendingColumn())==null?void 0:u.kind)??"text")},null,8,Sf),[[Qn,l(t).activeDatasetState().pendingFilter.value]])]))])])):le("",!0),d("div",Mf,[d("button",{class:"ghost-btn",type:"button",onClick:n[14]||(n[14]=(...a)=>l(t).addFilter&&l(t).addFilter(...a))},[O(l(K),{name:"plus"}),d("span",null,x(l(t).txt("Adicionar filtro","Add filter")),1)]),d("button",{class:"ghost-btn",type:"button",onClick:n[15]||(n[15]=(...a)=>l(t).closeModal&&l(t).closeModal(...a))},x(l(t).txt("Fechar","Close")),1)])])])):le("",!0),l(t).ui.activeModal==="sort"?(I(),F("div",{key:1,class:"modal-shell",onClick:n[21]||(n[21]=kt((...a)=>l(t).closeModal&&l(t).closeModal(...a),["self"]))},[d("div",Af,[d("div",Tf,[d("div",null,[d("div",Pf,x(l(t).txt("Gerenciar ordenacao","Manage sorting")),1),d("div",Rf,x(l(t).txt("Defina prioridade e direcao de cada criterio.","Set priority and direction for each sort rule.")),1)]),d("button",{class:"icon-only",type:"button",onClick:n[17]||(n[17]=(...a)=>l(t).closeModal&&l(t).closeModal(...a))},[O(l(K),{name:"x"})])]),l(t).activeDataset()&&l(t).activeDatasetState()?(I(),F("div",Ef,[d("div",Df,[(I(!0),F(ie,null,ge(l(t).activeDatasetState().sorts,(a,b)=>(I(),F("div",{key:`${a.key}-${b}`,class:"sort-rule"},[d("label",Of,[d("span",$f,[O(l(K),{name:"sort"}),at(" "+x(l(t).txt("Coluna de ordenacao","Sort column"))+" "+x(b+1),1)]),d("select",{value:a.key,class:"field-input",onChange:T=>l(t).updateSortRuleKey(b,T.target.value)},[d("option",Vf,x(l(t).txt("Nenhuma","None")),1),(I(!0),F(ie,null,ge((l(t).activeDataset().columns??[]).filter(Boolean),T=>(I(),F("option",{key:T.key,value:T.key},x(T.label??T.key??l(t).DEFAULT_EMPTY),9,Ff))),128))],40,If)]),d("label",jf,[d("span",Kf,[O(l(K),{name:"arrowUpDown"}),at(" "+x(l(t).txt("Direcao","Direction")),1)]),d("select",{value:a.dir,class:"field-input",onChange:T=>l(t).updateSortRuleDirection(b,T.target.value)},[d("option",Nf,x(l(t).txt("Crescente","Ascending")),1),d("option",Hf,x(l(t).txt("Decrescente","Descending")),1)],40,Lf)]),d("button",{class:"ghost-btn small sort-remove",type:"button",onClick:T=>l(t).removeSortRule(b)},[O(l(K),{name:"trash"}),d("span",null,x(l(t).txt("Remover","Remove")),1)],8,Uf)]))),128)),l(t).activeDatasetState().sorts.length===0?(I(),F("div",Wf,x(l(t).txt("Sem criterios de ordenacao","No sort rules yet")),1)):le("",!0)])])):le("",!0),d("div",Bf,[d("button",{class:"ghost-btn",type:"button",onClick:n[18]||(n[18]=(...a)=>l(t).addSortRule&&l(t).addSortRule(...a))},[O(l(K),{name:"plus"}),d("span",null,x(l(t).txt("Adicionar nivel","Add level")),1)]),d("button",{class:"ghost-btn",type:"button",onClick:n[19]||(n[19]=(...a)=>l(t).applySort&&l(t).applySort(...a))},[O(l(K),{name:"check"}),d("span",null,x(l(t).txt("Aplicar ordenacao","Apply sorting")),1)]),d("button",{class:"ghost-btn",type:"button",onClick:n[20]||(n[20]=(...a)=>l(t).clearSort&&l(t).clearSort(...a))},[O(l(K),{name:"rotate"}),d("span",null,x(l(t).txt("Resetar","Reset")),1)])])])])):le("",!0),l(t).ui.activeModal==="columns"?(I(),F("div",{key:2,class:"modal-shell",onClick:n[31]||(n[31]=kt((...a)=>l(t).closeModal&&l(t).closeModal(...a),["self"]))},[d("div",zf,[d("div",qf,[d("div",null,[d("div",Jf,x(l(t).txt("Colunas visiveis","Visible columns")),1),d("div",Gf,x(l(t).txt("Gerencie o que permanece na tabela.","Manage what stays visible in the table.")),1)]),d("button",{class:"icon-only",type:"button",onClick:n[22]||(n[22]=(...a)=>l(t).closeModal&&l(t).closeModal(...a))},[O(l(K),{name:"x"})])]),l(t).activeDataset()&&l(t).activeDatasetState()?(I(),F("div",Yf,[d("div",Xf,[d("div",Qf,[d("label",Zf,x(l(t).txt("Disponiveis","Available")),1),rt(d("input",{"onUpdate:modelValue":n[23]||(n[23]=a=>l(t).activeDatasetState().columnSearch=a),class:"field-input",type:"search",placeholder:l(t).txt("Buscar colunas","Search columns")},null,8,ep),[[sn,l(t).activeDatasetState().columnSearch]]),d("div",tp,[(I(!0),F(ie,null,ge((((v=l(t).datasetViews[l(t).ui.modalDatasetId])==null?void 0:v.availableColumns)??[]).filter(Boolean),a=>(I(),F("button",{key:a.key,class:Ne(["pick-item",{active:l(t).activeDatasetState().pickSelection.available.includes(a.key)}]),type:"button",onClick:b=>l(t).choosePick(l(t).ui.modalDatasetId,"available",a.key,!0)},x(a.label??a.key??l(t).DEFAULT_EMPTY),11,sp))),128))])]),d("div",np,[d("button",{class:"ghost-btn",type:"button",onClick:n[24]||(n[24]=a=>l(t).moveColumns(l(t).ui.modalDatasetId,"add"))},">"),d("button",{class:"ghost-btn",type:"button",onClick:n[25]||(n[25]=a=>l(t).moveColumns(l(t).ui.modalDatasetId,"remove"))},"<"),d("button",{class:"ghost-btn",type:"button",onClick:n[26]||(n[26]=a=>l(t).moveAllColumns(l(t).ui.modalDatasetId,"all"))},">>"),d("button",{class:"ghost-btn",type:"button",onClick:n[27]||(n[27]=a=>l(t).moveAllColumns(l(t).ui.modalDatasetId,"none"))},"<<"),d("button",{class:"ghost-btn",type:"button",onClick:n[28]||(n[28]=a=>l(t).moveVisibleColumnOrder(l(t).ui.modalDatasetId,"up"))},[O(l(K),{name:"up"})]),d("button",{class:"ghost-btn",type:"button",onClick:n[29]||(n[29]=a=>l(t).moveVisibleColumnOrder(l(t).ui.modalDatasetId,"down"))},[O(l(K),{name:"chevronDown"})])]),d("div",op,[d("label",ip,x(l(t).txt("Em exibicao","Showing")),1),d("div",lp,[(I(!0),F(ie,null,ge((((y=l(t).datasetViews[l(t).ui.modalDatasetId])==null?void 0:y.shownColumns)??[]).filter(Boolean),a=>(I(),F("button",{key:a.key,class:Ne(["pick-item",{active:l(t).activeDatasetState().pickSelection.visible.includes(a.key)}]),type:"button",onClick:b=>l(t).choosePick(l(t).ui.modalDatasetId,"visible",a.key,!0)},x(a.label??a.key??l(t).DEFAULT_EMPTY),11,rp))),128))])])])])):le("",!0),d("div",cp,[d("button",{class:"ghost-btn",type:"button",onClick:n[30]||(n[30]=(...a)=>l(t).closeModal&&l(t).closeModal(...a))},[O(l(K),{name:"check"}),d("span",null,x(l(t).txt("Concluir","Done")),1)])])])])):le("",!0),l(t).ui.activeModal==="cell"?(I(),F("div",{key:3,class:"modal-shell",onClick:n[33]||(n[33]=kt((...a)=>l(t).closeModal&&l(t).closeModal(...a),["self"]))},[d("div",ap,[d("div",up,[d("div",null,[d("div",dp,x(l(t).txt("Conteudo completo","Full content")),1),d("div",fp,x(l(t).txt("Visualizacao ampliada da celula selecionada.","Expanded view for the selected cell.")),1)]),d("button",{class:"icon-only",type:"button",onClick:n[32]||(n[32]=(...a)=>l(t).closeModal&&l(t).closeModal(...a))},[O(l(K),{name:"x"})])]),d("div",pp,[d("pre",hp,x(l(t).ui.longCellValue),1)])])])):le("",!0),((C=l(t).ui.contextMenu)==null?void 0:C.type)==="cell"?(I(),F("div",{key:4,class:"context-menu",style:gt({left:`${l(t).ui.contextMenu.x}px`,top:`${l(t).ui.contextMenu.y}px`}),onClick:n[38]||(n[38]=kt(()=>{},["stop"]))},[d("button",{class:"context-item",type:"button",onClick:n[34]||(n[34]=a=>l(t).copyContextValue())},[O(l(K),{name:"clipboard"}),d("span",null,x(l(t).txt("Copiar valor","Copy value")),1)]),d("button",{class:"context-item",type:"button",onClick:n[35]||(n[35]=a=>l(t).contextFilterByValue())},[O(l(K),{name:"filter"}),d("span",null,x(l(t).txt("Filtrar por este valor","Filter by this value")),1)]),d("button",{class:"context-item",type:"button",onClick:n[36]||(n[36]=a=>l(t).contextHideColumn())},[O(l(K),{name:"columns"}),d("span",null,x(l(t).txt("Ocultar coluna","Hide column")),1)]),d("button",{class:"context-item",type:"button",onClick:n[37]||(n[37]=a=>l(t).openCell(l(t).ui.contextMenu.value))},[O(l(K),{name:"expand"}),d("span",null,x(l(t).txt("Abrir valor completo","Open full value")),1)])],4)):le("",!0),(($=l(t).ui.contextMenu)==null?void 0:$.type)==="header"?(I(),F("div",{key:5,class:"context-menu",style:gt({left:`${l(t).ui.contextMenu.x}px`,top:`${l(t).ui.contextMenu.y}px`}),onClick:n[46]||(n[46]=kt(()=>{},["stop"]))},[d("button",{class:"context-item",type:"button",onClick:n[39]||(n[39]=a=>l(t).contextSort("asc","primary"))},[O(l(K),{name:"sortAsc"}),d("span",null,x(l(t).txt("Ordenar crescente","Sort ascending")),1)]),d("button",{class:"context-item",type:"button",onClick:n[40]||(n[40]=a=>l(t).contextSort("desc","primary"))},[O(l(K),{name:"sortDesc"}),d("span",null,x(l(t).txt("Ordenar decrescente","Sort descending")),1)]),d("button",{class:"context-item",type:"button",onClick:n[41]||(n[41]=a=>l(t).contextSort("asc","secondary"))},[O(l(K),{name:"sortAppend"}),d("span",null,x(l(t).txt("Adicionar como criterio","Add as sort level")),1)]),d("button",{class:"context-item",type:"button",onClick:n[42]||(n[42]=a=>l(t).autoFitColumn(l(t).ui.contextMenu.datasetId,l(t).ui.contextMenu.key))},[O(l(K),{name:"resize"}),d("span",null,x(l(t).txt("Auto ajustar coluna","Auto fit column")),1)]),d("button",{class:"context-item",type:"button",onClick:n[43]||(n[43]=a=>l(t).togglePinnedColumn())},[O(l(K),{name:"pin"}),d("span",null,x(l(t).isPinnedColumn(l(t).ui.contextMenu.datasetId,l(t).ui.contextMenu.key)?l(t).txt("Desafixar coluna","Unpin column"):l(t).txt("Fixar coluna","Pin column")),1)]),d("button",{class:"context-item",type:"button",onClick:n[44]||(n[44]=a=>l(t).contextHideColumn())},[O(l(K),{name:"columns"}),d("span",null,x(l(t).txt("Ocultar coluna","Hide column")),1)]),d("button",{class:"context-item",type:"button",onClick:n[45]||(n[45]=a=>l(t).contextShowOnlyColumn())},[O(l(K),{name:"check"}),d("span",null,x(l(t).txt("Mostrar apenas esta","Show only this")),1)])],4)):le("",!0),l(t).ui.toast?(I(),F("div",mp,x(l(t).ui.toast),1)):le("",!0)])}}}).mount("#app")})();
diff --git a/src/AkkornStudio.UI/Assets/ReportFrontend/package-lock.json b/src/AkkornStudio.UI/Assets/ReportFrontend/package-lock.json
new file mode 100644
index 00000000..3bd40574
--- /dev/null
+++ b/src/AkkornStudio.UI/Assets/ReportFrontend/package-lock.json
@@ -0,0 +1,1373 @@
+{
+ "name": "akkornstudio-report-frontend",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "akkornstudio-report-frontend",
+ "version": "1.0.0",
+ "dependencies": {
+ "lucide-vue-next": "^0.525.0",
+ "vue": "^3.5.13"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.2.1",
+ "vite": "^6.3.5"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz",
+ "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
+ "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
+ "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
+ "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
+ "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
+ "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
+ "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
+ "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
+ "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
+ "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
+ "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
+ "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
+ "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
+ "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
+ "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
+ "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
+ "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
+ "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
+ "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
+ "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
+ "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
+ "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz",
+ "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz",
+ "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz",
+ "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz",
+ "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz",
+ "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz",
+ "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz",
+ "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz",
+ "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz",
+ "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz",
+ "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz",
+ "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz",
+ "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz",
+ "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz",
+ "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz",
+ "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz",
+ "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz",
+ "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz",
+ "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz",
+ "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz",
+ "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz",
+ "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz",
+ "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz",
+ "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz",
+ "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz",
+ "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
+ "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.33.tgz",
+ "integrity": "sha512-3PZLQwFw4Za3TC8t0FvTy3wI16Kt+pmwcgNZca4Pj9iWL2E72a/gZlpBtAJvEdDMdCxdG/qq0C7PN0bsJuv0Rw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.2",
+ "@vue/shared": "3.5.33",
+ "entities": "^7.0.1",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.33.tgz",
+ "integrity": "sha512-PXq0yrfCLzzL07rbXO4awtXY1Z06LG2eu6Adg3RJFa/j3Cii217XxxLXG22N330gw7GmALCY0Z8RgXEviwgpjA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.33",
+ "@vue/shared": "3.5.33"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.33.tgz",
+ "integrity": "sha512-UTUvRO9cY+rROrx/pvN9P5Z7FgA6QGfokUCfhQE4EnmUj3rVnK+CHI0LsEO1pg+I7//iRYMUfcNcCPe7tg0CoA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.2",
+ "@vue/compiler-core": "3.5.33",
+ "@vue/compiler-dom": "3.5.33",
+ "@vue/compiler-ssr": "3.5.33",
+ "@vue/shared": "3.5.33",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.21",
+ "postcss": "^8.5.10",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.33.tgz",
+ "integrity": "sha512-IErjYdnj1qIupG5xxiVIYiiRvDhGWV4zuh/RCrwfYpuL+HWQzeU6lCk/nF9r7olWMnjKxCAkOctT2qFWFkzb1A==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.33",
+ "@vue/shared": "3.5.33"
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.33.tgz",
+ "integrity": "sha512-p8UfIqyIhb0rYGlSgSBV+lPhF2iUSBcRy7enhTmPqKWadHy9kcOFYF1AejYBP9P+avnd3OBbD49DU4pLWX/94A==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.33"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.33.tgz",
+ "integrity": "sha512-UpFF45RI9//a7rvq7RdOQblb4tup7hHG9QsmIrxkFQLzQ7R8/iNQ5LE15NhLZ1/WcHMU2b47u6P33CPUelHyIQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.33",
+ "@vue/shared": "3.5.33"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.33.tgz",
+ "integrity": "sha512-IOxMsAOwquhfITgmOgaPYl7/j8gKUxUFoflRc+u4LxyD3+783xne8vNta1PONVCvCV9A0w7hkyEepINDqfO0tw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.33",
+ "@vue/runtime-core": "3.5.33",
+ "@vue/shared": "3.5.33",
+ "csstype": "^3.2.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.33.tgz",
+ "integrity": "sha512-0xylq/8/h44lVG0pZFknv1XIdEgymq2E9n59uTWJBG+dIgiT0TMCSsxrN7nO16Z0MU0MPjFcguBbZV8Itk52Hw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.33",
+ "@vue/shared": "3.5.33"
+ },
+ "peerDependencies": {
+ "vue": "3.5.33"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.33.tgz",
+ "integrity": "sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ==",
+ "license": "MIT"
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "license": "MIT"
+ },
+ "node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
+ "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.12",
+ "@esbuild/android-arm": "0.25.12",
+ "@esbuild/android-arm64": "0.25.12",
+ "@esbuild/android-x64": "0.25.12",
+ "@esbuild/darwin-arm64": "0.25.12",
+ "@esbuild/darwin-x64": "0.25.12",
+ "@esbuild/freebsd-arm64": "0.25.12",
+ "@esbuild/freebsd-x64": "0.25.12",
+ "@esbuild/linux-arm": "0.25.12",
+ "@esbuild/linux-arm64": "0.25.12",
+ "@esbuild/linux-ia32": "0.25.12",
+ "@esbuild/linux-loong64": "0.25.12",
+ "@esbuild/linux-mips64el": "0.25.12",
+ "@esbuild/linux-ppc64": "0.25.12",
+ "@esbuild/linux-riscv64": "0.25.12",
+ "@esbuild/linux-s390x": "0.25.12",
+ "@esbuild/linux-x64": "0.25.12",
+ "@esbuild/netbsd-arm64": "0.25.12",
+ "@esbuild/netbsd-x64": "0.25.12",
+ "@esbuild/openbsd-arm64": "0.25.12",
+ "@esbuild/openbsd-x64": "0.25.12",
+ "@esbuild/openharmony-arm64": "0.25.12",
+ "@esbuild/sunos-x64": "0.25.12",
+ "@esbuild/win32-arm64": "0.25.12",
+ "@esbuild/win32-ia32": "0.25.12",
+ "@esbuild/win32-x64": "0.25.12"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "license": "MIT"
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/lucide-vue-next": {
+ "version": "0.525.0",
+ "resolved": "https://registry.npmjs.org/lucide-vue-next/-/lucide-vue-next-0.525.0.tgz",
+ "integrity": "sha512-Xf8+x8B2DrnGDV/rxylS+KBp2FIe6ljwDn2JsGTZZvXIfhmm/q+nv8RuGO1OyoMjOVkkz7CqtUqJfwtFPRbB2w==",
+ "license": "ISC",
+ "peerDependencies": {
+ "vue": ">=3.0.1"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.12",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.12.tgz",
+ "integrity": "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz",
+ "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.60.2",
+ "@rollup/rollup-android-arm64": "4.60.2",
+ "@rollup/rollup-darwin-arm64": "4.60.2",
+ "@rollup/rollup-darwin-x64": "4.60.2",
+ "@rollup/rollup-freebsd-arm64": "4.60.2",
+ "@rollup/rollup-freebsd-x64": "4.60.2",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.60.2",
+ "@rollup/rollup-linux-arm-musleabihf": "4.60.2",
+ "@rollup/rollup-linux-arm64-gnu": "4.60.2",
+ "@rollup/rollup-linux-arm64-musl": "4.60.2",
+ "@rollup/rollup-linux-loong64-gnu": "4.60.2",
+ "@rollup/rollup-linux-loong64-musl": "4.60.2",
+ "@rollup/rollup-linux-ppc64-gnu": "4.60.2",
+ "@rollup/rollup-linux-ppc64-musl": "4.60.2",
+ "@rollup/rollup-linux-riscv64-gnu": "4.60.2",
+ "@rollup/rollup-linux-riscv64-musl": "4.60.2",
+ "@rollup/rollup-linux-s390x-gnu": "4.60.2",
+ "@rollup/rollup-linux-x64-gnu": "4.60.2",
+ "@rollup/rollup-linux-x64-musl": "4.60.2",
+ "@rollup/rollup-openbsd-x64": "4.60.2",
+ "@rollup/rollup-openharmony-arm64": "4.60.2",
+ "@rollup/rollup-win32-arm64-msvc": "4.60.2",
+ "@rollup/rollup-win32-ia32-msvc": "4.60.2",
+ "@rollup/rollup-win32-x64-gnu": "4.60.2",
+ "@rollup/rollup-win32-x64-msvc": "4.60.2",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.16",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
+ "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/vite": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz",
+ "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.3",
+ "rollup": "^4.34.9",
+ "tinyglobby": "^0.2.13"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.33.tgz",
+ "integrity": "sha512-1AgChhx5w3ALgT4oK3acm2Es/7jyZhWSVUfs3rOBlGQC0rjEDkS7G4lWlJJGGNQD+BV3reCwbQrOe1mPNwKHBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.33",
+ "@vue/compiler-sfc": "3.5.33",
+ "@vue/runtime-dom": "3.5.33",
+ "@vue/server-renderer": "3.5.33",
+ "@vue/shared": "3.5.33"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/src/AkkornStudio.UI/Assets/ReportFrontend/package.json b/src/AkkornStudio.UI/Assets/ReportFrontend/package.json
new file mode 100644
index 00000000..36c67a2d
--- /dev/null
+++ b/src/AkkornStudio.UI/Assets/ReportFrontend/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "akkornstudio-report-frontend",
+ "private": true,
+ "version": "1.0.0",
+ "type": "module",
+ "scripts": {
+ "build": "vite build"
+ },
+ "dependencies": {
+ "lucide-vue-next": "^0.525.0",
+ "vue": "^3.5.13"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.2.1",
+ "vite": "^6.3.5"
+ }
+}
diff --git a/src/AkkornStudio.UI/Assets/ReportFrontend/src/App.vue b/src/AkkornStudio.UI/Assets/ReportFrontend/src/App.vue
new file mode 100644
index 00000000..a21fd5a4
--- /dev/null
+++ b/src/AkkornStudio.UI/Assets/ReportFrontend/src/App.vue
@@ -0,0 +1,347 @@
+
+
+
+
+
+
+
+
+
+
+
{{ report.txt("Visao geral", "Overview") }}
+
{{ report.txt("Panorama rapido da consulta e do resultado exportado.", "Quick summary of the query and exported result.") }}
+
+
{{ report.state.sections.overview ? report.txt("Expandir", "Expand") : report.txt("Recolher", "Collapse") }}
+
+
+
+
+
+
{{ card.label }}
+
{{ card.value }}
+
+
+
+
+
+
+
+
+
{{ dataset.title }}
+
{{ dataset.searchPlaceholder }}
+
+
+
+
+
+
+ {{ report.txt("Filtros", "Filters") }}
+ {{ report.txt("Ordenacao", "Sorting") }}
+ {{ report.txt("Colunas", "Columns") }}
+ {{ report.txt("Resetar visao", "Reset view") }}
+ {{ report.state.sections[dataset.id] ? report.txt("Expandir", "Expand") : report.txt("Recolher", "Collapse") }}
+
+
+
+
+
+
+
+
{{ report.txt("Filtros ativos", "Active filters") }}
+
+
+ {{ report.txt("Limpar", "Clear") }}
+
+
+
+
+ {{ report.summaryChipText(filter) }}
+
+
+
{{ report.txt("Nenhum filtro aplicado", "No active filters") }}
+
+
+
+
+
+
{{ report.txt("Colunas visiveis", "Visible columns") }}
+
+
+ {{ report.txt("Resetar", "Reset") }}
+
+
+
+
{{ column.label ?? column.key ?? report.DEFAULT_EMPTY }}
+
+
+
+
+
+
{{ report.txt("Ordenacao ativa", "Active sorting") }}
+
+
+
+ {{ item.index + 1 }} • {{ item.label ?? item.key ?? report.DEFAULT_EMPTY }} • {{ item.dir === 'desc' ? report.txt("Decrescente", "Descending") : report.txt("Crescente", "Ascending") }}
+
+
{{ report.txt("Sem ordenacao ativa", "No active sorting") }}
+
+
+
+
+
+
+
+
+
+ {{ report.txt("Filtros rapidos", "Quick filters") }}
+
+ {{ item.value }}
+ {{ item.count }}
+
+
+
+
+
+
+
+
+
+ {{ report.txt("Atualizando pagina", "Updating page") }}
+
+
+
+
+
+
+
+
+
+
+
SQL {{ report.txt("Consulta completa exportada no relatorio.", "Full query exported in the report.") }}
+
{{ report.state.sections.sql ? report.txt("Expandir", "Expand") : report.txt("Recolher", "Collapse") }}
+
+
+
+
+
+
+
+
+
+
+
{{ report.txt("Adicionar filtro", "Add filter") }}
{{ report.txt("Escolha coluna, condicao e valor.", "Choose column, condition and value.") }}
+
+
+
+
+
+
+
+
+
+
+
{{ report.txt("Gerenciar ordenacao", "Manage sorting") }}
{{ report.txt("Defina prioridade e direcao de cada criterio.", "Set priority and direction for each sort rule.") }}
+
+
+
+
+
+ {{ report.txt("Coluna de ordenacao", "Sort column") }} {{ index + 1 }}{{ report.txt("Nenhuma", "None") }} {{ column.label ?? column.key ?? report.DEFAULT_EMPTY }}
+ {{ report.txt("Direcao", "Direction") }}{{ report.txt("Crescente", "Ascending") }} {{ report.txt("Decrescente", "Descending") }}
+ {{ report.txt("Remover", "Remove") }}
+
+
{{ report.txt("Sem criterios de ordenacao", "No sort rules yet") }}
+
+
+
+
+
+
+
+
+
+
{{ report.txt("Colunas visiveis", "Visible columns") }}
{{ report.txt("Gerencie o que permanece na tabela.", "Manage what stays visible in the table.") }}
+
+
+
+
+
+
{{ report.txt("Disponiveis", "Available") }}
+
+
+ {{ column.label ?? column.key ?? report.DEFAULT_EMPTY }}
+
+
+
+ >
+ <
+ >>
+ <<
+
+
+
+
+
{{ report.txt("Em exibicao", "Showing") }}
+
+ {{ column.label ?? column.key ?? report.DEFAULT_EMPTY }}
+
+
+
+
+
+
+
+
+
+
+
+
{{ report.txt("Conteudo completo", "Full content") }}
{{ report.txt("Visualizacao ampliada da celula selecionada.", "Expanded view for the selected cell.") }}
+
+
+
{{ report.ui.longCellValue }}
+
+
+
+
+
+
+
+
{{ report.ui.toast }}
+
+
diff --git a/src/AkkornStudio.UI/Assets/ReportFrontend/src/icons.js b/src/AkkornStudio.UI/Assets/ReportFrontend/src/icons.js
new file mode 100644
index 00000000..09221812
--- /dev/null
+++ b/src/AkkornStudio.UI/Assets/ReportFrontend/src/icons.js
@@ -0,0 +1,103 @@
+import { h } from "vue";
+import {
+ AlertTriangle,
+ ArrowDownWideNarrow,
+ ArrowDownAZ,
+ ArrowUpDown,
+ ArrowUpAZ,
+ Check,
+ ChevronDown,
+ ChevronLeft,
+ ChevronRight,
+ ChevronUp,
+ CircleDot,
+ ClipboardList,
+ Clock3,
+ Code2,
+ Columns3,
+ Database,
+ Download,
+ Expand,
+ FileJson2,
+ Funnel,
+ GripVertical,
+ ListFilter,
+ Moon,
+ Pin,
+ Plus,
+ Rows3,
+ RotateCcw,
+ Search,
+ Save,
+ Sun,
+ TextCursorInput,
+ Trash2,
+ Upload,
+ X
+} from "lucide-vue-next";
+
+const iconMap = {
+ moon: Moon,
+ sun: Sun,
+ clipboard: ClipboardList,
+ code: Code2,
+ download: Download,
+ json: FileJson2,
+ filter: ListFilter,
+ sort: ArrowDownWideNarrow,
+ sortAsc: ArrowUpAZ,
+ sortDesc: ArrowDownAZ,
+ sortAppend: ArrowUpDown,
+ columns: Columns3,
+ rotate: RotateCcw,
+ chevronDown: ChevronDown,
+ plus: Plus,
+ x: X,
+ check: Check,
+ text: TextCursorInput,
+ funnel: Funnel,
+ arrowUpDown: ArrowUpDown,
+ left: ChevronLeft,
+ right: ChevronRight,
+ up: ChevronUp,
+ expand: Expand,
+ rows: Rows3,
+ clock: Clock3,
+ database: Database,
+ alert: AlertTriangle,
+ rowSelect: CircleDot,
+ search: Search,
+ resize: GripVertical,
+ pin: Pin,
+ save: Save,
+ trash: Trash2,
+ uploadPreset: Upload,
+ downloadPreset: FileJson2
+};
+
+export const IconGlyph = {
+ name: "IconGlyph",
+ props: {
+ name: { type: String, required: true },
+ title: { type: String, default: "" },
+ size: { type: Number, default: 16 },
+ strokeWidth: { type: Number, default: 1.9 }
+ },
+ render() {
+ const IconComponent = iconMap[this.name] ?? CircleDot;
+ return h(
+ "span",
+ {
+ class: "icon-glyph",
+ title: this.title,
+ "aria-hidden": "true"
+ },
+ [
+ h(IconComponent, {
+ size: this.size,
+ strokeWidth: this.strokeWidth
+ })
+ ]
+ );
+ }
+};
diff --git a/src/AkkornStudio.UI/Assets/ReportFrontend/src/main.js b/src/AkkornStudio.UI/Assets/ReportFrontend/src/main.js
new file mode 100644
index 00000000..b670de8b
--- /dev/null
+++ b/src/AkkornStudio.UI/Assets/ReportFrontend/src/main.js
@@ -0,0 +1,4 @@
+import { createApp } from "vue";
+import App from "./App.vue";
+
+createApp(App).mount("#app");
diff --git a/src/AkkornStudio.UI/Assets/ReportFrontend/src/report-data.js b/src/AkkornStudio.UI/Assets/ReportFrontend/src/report-data.js
new file mode 100644
index 00000000..3b4826db
--- /dev/null
+++ b/src/AkkornStudio.UI/Assets/ReportFrontend/src/report-data.js
@@ -0,0 +1,1731 @@
+import { computed, proxyRefs, reactive, watch } from "vue";
+
+export const STORAGE_KEY = "akkorn-report-view-vue-v7";
+export const PAGE_SIZES = [10, 25, 50, 100];
+export const DEFAULT_EMPTY = "-";
+export const MIN_COLUMN_WIDTH = 140;
+
+export function createReportModel() {
+ const payload = window.__AKKORN_REPORT__ ?? {};
+ const labels = payload.labels ?? {};
+ const meta = payload.meta ?? {};
+ const txt = (pt, en) => labels[pt] ?? labels[en] ?? pt;
+
+ const datasets = computed(() => buildDatasets(payload, txt));
+ const state = reactive(loadState(datasets.value));
+ const ui = reactive({
+ activeModal: "",
+ modalDatasetId: "",
+ longCellValue: "",
+ toast: "",
+ toastTimer: 0,
+ resizing: null,
+ contextMenu: null,
+ scrollHints: {}
+ });
+
+ const pageJobs = new Map();
+
+ const datasetViews = computed(() => {
+ const entries = {};
+ for (const dataset of datasets.value) {
+ entries[dataset.id] = buildDatasetView(dataset, state.datasets[dataset.id]);
+ }
+
+ return entries;
+ });
+
+ const overviewCards = computed(() => buildOverviewCards(meta, payload, txt));
+ const themeIcon = computed(() => (state.theme === "dark" ? "moon" : "sun"));
+ const footerText = computed(() => `${meta.title ?? "Report"} • Vue 3 • v${payload.version ?? "1.0"}`);
+
+ watch(
+ () => state,
+ () => saveState(state),
+ { deep: true }
+ );
+
+ watch(
+ () => state.theme,
+ (theme) => {
+ document.documentElement.setAttribute("data-theme", theme);
+ },
+ { immediate: true }
+ );
+
+ function activeDataset() {
+ return datasets.value.find((dataset) => dataset.id === ui.modalDatasetId) ?? null;
+ }
+
+ function activeDatasetState() {
+ return ui.modalDatasetId ? state.datasets[ui.modalDatasetId] : null;
+ }
+
+ function openModal(name, datasetId = "") {
+ ui.activeModal = name;
+ ui.modalDatasetId = datasetId;
+ }
+
+ function closeModal() {
+ ui.activeModal = "";
+ ui.modalDatasetId = "";
+ }
+
+ function closeContextMenu() {
+ ui.contextMenu = null;
+ }
+
+ function toggleTheme() {
+ state.theme = state.theme === "dark" ? "light" : "dark";
+ }
+
+ function toggleSection(id) {
+ state.sections[id] = !state.sections[id];
+ }
+
+ function resetDataset(id) {
+ const dataset = datasets.value.find((item) => item.id === id);
+ if (!dataset) {
+ return;
+ }
+
+ state.datasets[id] = normalizeDatasetState(dataset, {});
+ }
+
+ function clearFilters(id) {
+ state.datasets[id].filters = [];
+ state.datasets[id].page = 1;
+ }
+
+ function removeFilter(id, index) {
+ state.datasets[id].filters.splice(index, 1);
+ state.datasets[id].page = 1;
+ }
+
+ function openFilterModal(id) {
+ const dataset = datasets.value.find((item) => item.id === id);
+ if (!dataset) {
+ return;
+ }
+
+ state.datasets[id].pendingFilter = normalizePendingFilter(dataset, state.datasets[id].pendingFilter);
+ openModal("filter", id);
+ }
+
+ function openSortModal(id) {
+ openModal("sort", id);
+ }
+
+ function openColumnsModal(id) {
+ openModal("columns", id);
+ }
+
+ function addFilter() {
+ const dataset = activeDataset();
+ const datasetState = activeDatasetState();
+ if (!dataset || !datasetState || !datasetState.pendingFilter.key) {
+ return;
+ }
+
+ datasetState.filters.push({ ...datasetState.pendingFilter });
+ datasetState.page = 1;
+ const currentKey = datasetState.pendingFilter.key;
+ datasetState.pendingFilter = normalizePendingFilter(dataset, { key: currentKey });
+ }
+
+ function applySort() {
+ const datasetState = activeDatasetState();
+ if (!datasetState) {
+ return;
+ }
+
+ datasetState.page = 1;
+ closeModal();
+ }
+
+ function clearSort() {
+ const datasetState = activeDatasetState();
+ if (!datasetState) {
+ return;
+ }
+
+ datasetState.sorts = [];
+ syncPrimarySort(datasetState);
+ datasetState.page = 1;
+ }
+
+ function setSortFromHeader(id, key) {
+ const datasetState = state.datasets[id];
+ const current = datasetState.sorts[0];
+ if (current?.key === key) {
+ datasetState.sorts = [{ key, dir: current.dir === "asc" ? "desc" : "asc" }, ...datasetState.sorts.slice(1)];
+ } else {
+ datasetState.sorts = [{ key, dir: "asc" }, ...datasetState.sorts.filter((item) => item.key !== key)];
+ }
+ syncPrimarySort(datasetState);
+ datasetState.page = 1;
+ }
+
+ function addSortRule() {
+ const dataset = activeDataset();
+ const datasetState = activeDatasetState();
+ if (!dataset || !datasetState) {
+ return;
+ }
+
+ const key = dataset.columns.find((column) => !datasetState.sorts.some((item) => item.key === column.key))?.key ?? dataset.columns[0]?.key ?? "";
+ if (!key) {
+ return;
+ }
+
+ datasetState.sorts.push({ key, dir: "asc" });
+ syncPrimarySort(datasetState);
+ }
+
+ function removeSortRule(index) {
+ const datasetState = activeDatasetState();
+ if (!datasetState) {
+ return;
+ }
+
+ datasetState.sorts.splice(index, 1);
+ syncPrimarySort(datasetState);
+ }
+
+ function updateSortRuleKey(index, key) {
+ const datasetState = activeDatasetState();
+ if (!datasetState || !datasetState.sorts[index]) {
+ return;
+ }
+
+ datasetState.sorts[index].key = key;
+ datasetState.sorts = dedupeSortRules(datasetState.sorts);
+ syncPrimarySort(datasetState);
+ }
+
+ function updateSortRuleDirection(index, dir) {
+ const datasetState = activeDatasetState();
+ if (!datasetState || !datasetState.sorts[index]) {
+ return;
+ }
+
+ datasetState.sorts[index].dir = dir === "desc" ? "desc" : "asc";
+ syncPrimarySort(datasetState);
+ }
+
+ function toggleRow(id, rowId, event = null) {
+ const selected = state.datasets[id].selectedRows;
+ const datasetState = state.datasets[id];
+ const view = datasetViews.value[id];
+ if (event?.shiftKey && datasetState.lastRowSelection && view) {
+ const rowIds = view.rows.map((entry) => entry.rowId);
+ const start = rowIds.indexOf(datasetState.lastRowSelection);
+ const end = rowIds.indexOf(rowId);
+ if (start >= 0 && end >= 0) {
+ const [from, to] = start < end ? [start, end] : [end, start];
+ datasetState.selectedRows = [...new Set([...selected, ...rowIds.slice(from, to + 1)])];
+ datasetState.lastRowSelection = rowId;
+ return;
+ }
+ }
+
+ const index = selected.indexOf(rowId);
+ if (index >= 0) {
+ selected.splice(index, 1);
+ } else {
+ selected.push(rowId);
+ }
+ datasetState.lastRowSelection = rowId;
+ }
+
+ function selectCell(id, rowId, key) {
+ state.datasets[id].selectedCell = { rowId, key };
+ state.datasets[id].selectedCells = [`${rowId}::${key}`];
+ state.datasets[id].anchorCell = { rowId, key };
+ closeContextMenu();
+ }
+
+ function selectCellWithEvent(id, rowId, key, event = null) {
+ const datasetState = state.datasets[id];
+ const view = datasetViews.value[id];
+ if (event?.shiftKey && datasetState.anchorCell && view) {
+ const rowIds = view.rows.map((entry) => entry.rowId);
+ const colKeys = view.visibleColumns.map((column) => column.key);
+ const startRow = rowIds.indexOf(datasetState.anchorCell.rowId);
+ const endRow = rowIds.indexOf(rowId);
+ const startCol = colKeys.indexOf(datasetState.anchorCell.key);
+ const endCol = colKeys.indexOf(key);
+ if (startRow >= 0 && endRow >= 0 && startCol >= 0 && endCol >= 0) {
+ const [rowFrom, rowTo] = startRow < endRow ? [startRow, endRow] : [endRow, startRow];
+ const [colFrom, colTo] = startCol < endCol ? [startCol, endCol] : [endCol, startCol];
+ const selectedCells = [];
+ for (let rowIndex = rowFrom; rowIndex <= rowTo; rowIndex += 1) {
+ for (let colIndex = colFrom; colIndex <= colTo; colIndex += 1) {
+ selectedCells.push(`${rowIds[rowIndex]}::${colKeys[colIndex]}`);
+ }
+ }
+ datasetState.selectedCell = { rowId, key };
+ datasetState.selectedCells = selectedCells;
+ closeContextMenu();
+ return;
+ }
+ }
+
+ selectCell(id, rowId, key);
+ }
+
+ function isCellSelected(id, rowId, key) {
+ const datasetState = state.datasets[id];
+ if (datasetState.selectedCells?.length > 0) {
+ return datasetState.selectedCells.includes(`${rowId}::${key}`);
+ }
+
+ const selected = datasetState.selectedCell;
+ return !!selected && selected.rowId === rowId && selected.key === key;
+ }
+
+ function isRowSelected(id, rowId) {
+ return state.datasets[id].selectedRows.includes(rowId);
+ }
+
+ function changePage(id, target) {
+ const view = datasetViews.value[id];
+ if (!view) {
+ return;
+ }
+
+ const safeTarget = Math.min(Math.max(1, normalizePositiveInt(target, 1)), view.pageCount);
+ const datasetState = state.datasets[id];
+ if (datasetState.page === safeTarget && !datasetState.pageBusy) {
+ return;
+ }
+
+ if (pageJobs.has(id)) {
+ window.clearTimeout(pageJobs.get(id));
+ }
+
+ datasetState.pageBusy = true;
+ const handle = window.setTimeout(() => {
+ datasetState.page = safeTarget;
+ window.requestAnimationFrame(() => {
+ datasetState.pageBusy = false;
+ pageJobs.delete(id);
+ });
+ }, 0);
+ pageJobs.set(id, handle);
+ }
+
+ function pageJump(event, id) {
+ changePage(id, event.target.value);
+ }
+
+ function openCell(value) {
+ ui.longCellValue = displayValue(value);
+ closeContextMenu();
+ openModal("cell");
+ }
+
+ function isLongText(value) {
+ return stringifyValue(value).length > 96;
+ }
+
+ function copySql() {
+ copyText(payload.sql ?? "", txt("SQL copiado", "SQL copied"), ui);
+ }
+
+ function copySummary() {
+ const lines = [
+ meta.title ?? "",
+ meta.description ?? "",
+ `${txt("Linhas", "Rows")}: ${(payload.rows ?? []).length}`,
+ `${txt("Colunas", "Columns")}: ${(payload.schema ?? []).length}`,
+ `${txt("Gerado em", "Generated at")}: ${meta.generatedAt ?? ""}`
+ ].filter(Boolean);
+ copyText(lines.join("\n"), txt("Resumo copiado", "Summary copied"), ui);
+ }
+
+ function exportCsv() {
+ const view = datasetViews.value.results;
+ if (!view) {
+ return;
+ }
+
+ const headers = view.visibleColumns.map((column) => column.label);
+ const rows = view.rows.map((entry) => view.visibleColumns.map((column) => csvEscape(getValue(entry.raw, column.key))));
+ const content = [headers.map(csvEscape).join(","), ...rows.map((row) => row.join(","))].join("\r\n");
+ const blob = new Blob([content], { type: "text/csv;charset=utf-8;" });
+ const url = URL.createObjectURL(blob);
+ const anchor = document.createElement("a");
+ anchor.href = url;
+ anchor.download = `${(meta.title ?? "report").replace(/[^\w\-]+/g, "_")}.csv`;
+ anchor.click();
+ URL.revokeObjectURL(url);
+ }
+
+ function exportJson() {
+ const fileName = `${slugify(meta.title ?? "report") || "report"}.json`;
+ const blob = new Blob([JSON.stringify(payload, null, 2)], { type: "application/json;charset=utf-8;" });
+ downloadBlob(blob, fileName);
+ }
+
+ function choosePick(id, bucket, key, multi = false) {
+ const list = state.datasets[id].pickSelection[bucket];
+ if (!multi) {
+ list.splice(0, list.length, key);
+ return;
+ }
+
+ const index = list.indexOf(key);
+ if (index >= 0) {
+ list.splice(index, 1);
+ } else {
+ list.push(key);
+ }
+ }
+
+ function moveColumns(id, direction) {
+ const datasetState = state.datasets[id];
+ const view = datasetViews.value[id];
+ if (!view) {
+ return;
+ }
+
+ if (direction === "add") {
+ for (const key of datasetState.pickSelection.available) {
+ if (!datasetState.visibleKeys.includes(key)) {
+ datasetState.visibleKeys.push(key);
+ }
+ }
+ datasetState.pickSelection.available = [];
+ return;
+ }
+
+ if (direction === "remove") {
+ datasetState.visibleKeys = datasetState.visibleKeys.filter((key) => !datasetState.pickSelection.visible.includes(key));
+ if (datasetState.visibleKeys.length === 0) {
+ datasetState.visibleKeys = view.dataset.columns.slice(0, 1).map((column) => column.key);
+ }
+ datasetState.pickSelection.visible = [];
+ }
+ }
+
+ function moveVisibleColumnOrder(id, direction) {
+ const datasetState = state.datasets[id];
+ const selectedKey = datasetState.pickSelection.visible[0];
+ if (!selectedKey) {
+ return;
+ }
+
+ const currentIndex = datasetState.visibleKeys.indexOf(selectedKey);
+ if (currentIndex < 0) {
+ return;
+ }
+
+ const targetIndex = direction === "up" ? currentIndex - 1 : currentIndex + 1;
+ if (targetIndex < 0 || targetIndex >= datasetState.visibleKeys.length) {
+ return;
+ }
+
+ const next = [...datasetState.visibleKeys];
+ [next[currentIndex], next[targetIndex]] = [next[targetIndex], next[currentIndex]];
+ datasetState.visibleKeys = next;
+ }
+
+ function moveAllColumns(id, mode) {
+ const dataset = datasets.value.find((item) => item.id === id);
+ if (!dataset) {
+ return;
+ }
+
+ if (mode === "all") {
+ state.datasets[id].visibleKeys = dataset.columns.map((column) => column.key);
+ return;
+ }
+
+ state.datasets[id].visibleKeys = dataset.columns.slice(0, 1).map((column) => column.key);
+ }
+
+ function visibleColumnSummary(id) {
+ return datasetViews.value[id]?.shownColumns ?? [];
+ }
+
+ function selectedRowsCount(id) {
+ return state.datasets[id]?.selectedRows?.length ?? 0;
+ }
+
+ function copySelectedCell(id) {
+ const datasetState = state.datasets[id];
+ const selected = datasetState?.selectedCell;
+ const view = datasetViews.value[id];
+ if (!selected || !view) {
+ return;
+ }
+
+ if (datasetState.selectedCells?.length > 1) {
+ const rowIds = [...new Set(datasetState.selectedCells.map((item) => item.split("::")[0]))];
+ const colKeys = view.visibleColumns
+ .map((column) => column.key)
+ .filter((key) => datasetState.selectedCells.some((item) => item.endsWith(`::${key}`)));
+ const body = rowIds.map((rowId) => {
+ const entry = view.rows.find((item) => item.rowId === rowId);
+ return colKeys.map((key) => displayValue(getValue(entry?.raw, key))).join("\t");
+ });
+ copyText(body.join("\n"), txt("Selecao copiada", "Selection copied"), ui);
+ return;
+ }
+
+ const entry = view.rows.find((item) => item.rowId === selected.rowId);
+ if (!entry) {
+ return;
+ }
+
+ copyText(displayValue(getValue(entry.raw, selected.key)), txt("Celula copiada", "Cell copied"), ui);
+ }
+
+ function copySelectedRows(id) {
+ const selected = state.datasets[id]?.selectedRows ?? [];
+ const view = datasetViews.value[id];
+ if (!view || selected.length === 0) {
+ return;
+ }
+
+ const rows = view.rows.filter((entry) => selected.includes(entry.rowId));
+ if (rows.length === 0) {
+ return;
+ }
+
+ const headers = view.visibleColumns.map((column) => column.label);
+ const body = rows.map((entry) => view.visibleColumns.map((column) => displayValue(getValue(entry.raw, column.key))).join("\t"));
+ copyText([headers.join("\t"), ...body].join("\n"), txt("Linhas copiadas", "Rows copied"), ui);
+ }
+
+ function openCellMenu(event, id, rowId, key) {
+ event.preventDefault();
+ selectCell(id, rowId, key);
+ const view = datasetViews.value[id];
+ const entry = view?.rows.find((item) => item.rowId === rowId);
+ const value = entry ? getValue(entry.raw, key) : "";
+ ui.contextMenu = {
+ type: "cell",
+ datasetId: id,
+ rowId,
+ key,
+ value,
+ x: event.clientX,
+ y: event.clientY
+ };
+ }
+
+ function openHeaderMenu(event, id, key) {
+ event.preventDefault();
+ closeContextMenu();
+ ui.contextMenu = {
+ type: "header",
+ datasetId: id,
+ key,
+ x: event.clientX,
+ y: event.clientY
+ };
+ }
+
+ function contextFilterByValue() {
+ const menu = ui.contextMenu;
+ if (!menu) {
+ return;
+ }
+
+ state.datasets[menu.datasetId].filters.push({
+ key: menu.key,
+ operator: "eq",
+ value: displayValue(menu.value) === DEFAULT_EMPTY ? "" : stringifyValue(menu.value)
+ });
+ state.datasets[menu.datasetId].page = 1;
+ closeContextMenu();
+ }
+
+ function contextHideColumn() {
+ const menu = ui.contextMenu;
+ if (!menu) {
+ return;
+ }
+
+ const datasetState = state.datasets[menu.datasetId];
+ datasetState.visibleKeys = datasetState.visibleKeys.filter((item) => item !== menu.key);
+ if (datasetState.visibleKeys.length === 0) {
+ datasetState.visibleKeys = [menu.key];
+ }
+ closeContextMenu();
+ }
+
+ function contextShowOnlyColumn() {
+ const menu = ui.contextMenu;
+ if (!menu) {
+ return;
+ }
+
+ state.datasets[menu.datasetId].visibleKeys = [menu.key];
+ closeContextMenu();
+ }
+
+ function copyContextValue() {
+ const menu = ui.contextMenu;
+ if (!menu) {
+ return;
+ }
+
+ copyText(displayValue(menu.value), txt("Celula copiada", "Cell copied"), ui);
+ closeContextMenu();
+ }
+
+ function togglePinnedColumn() {
+ const menu = ui.contextMenu;
+ if (!menu) {
+ return;
+ }
+
+ const datasetState = state.datasets[menu.datasetId];
+ datasetState.pinnedColumnKey = datasetState.pinnedColumnKey === menu.key ? "" : menu.key;
+ closeContextMenu();
+ }
+
+ function isPinnedColumn(id, key) {
+ return state.datasets[id]?.pinnedColumnKey === key;
+ }
+
+ function contextSort(direction, mode = "primary") {
+ const menu = ui.contextMenu;
+ if (!menu) {
+ return;
+ }
+
+ const datasetState = state.datasets[menu.datasetId];
+ const dir = direction === "desc" ? "desc" : "asc";
+ const nextRule = { key: menu.key, dir };
+ datasetState.sorts = mode === "secondary"
+ ? dedupeSortRules([...datasetState.sorts.filter((item) => item.key !== menu.key), nextRule])
+ : dedupeSortRules([nextRule, ...datasetState.sorts.filter((item) => item.key !== menu.key)]);
+ syncPrimarySort(datasetState);
+ datasetState.page = 1;
+ closeContextMenu();
+ }
+
+ function getColumnWidth(id, key) {
+ const width = state.datasets[id]?.columnWidths?.[key];
+ return clampColumnWidth(width);
+ }
+
+ function columnStyle(id, key) {
+ const width = getColumnWidth(id, key);
+ return {
+ width: `${width}px`,
+ minWidth: `${MIN_COLUMN_WIDTH}px`
+ };
+ }
+
+ function columnStickyClass(id, key) {
+ return { "sticky-main-col": isPinnedColumn(id, key) };
+ }
+
+ function columnStickyStyle(id, key) {
+ return isPinnedColumn(id, key) ? { left: "28px" } : {};
+ }
+
+ function startResize(event, id, key) {
+ if (event.button !== 0) {
+ return;
+ }
+
+ const startWidth = getColumnWidth(id, key);
+ ui.resizing = {
+ id,
+ key,
+ startX: event.clientX,
+ startWidth
+ };
+
+ const onMove = (moveEvent) => {
+ if (!ui.resizing || ui.resizing.id !== id || ui.resizing.key !== key) {
+ return;
+ }
+
+ const nextWidth = ui.resizing.startWidth + (moveEvent.clientX - ui.resizing.startX);
+ state.datasets[id].columnWidths[key] = clampColumnWidth(nextWidth);
+ };
+
+ const onUp = () => {
+ window.removeEventListener("mousemove", onMove);
+ window.removeEventListener("mouseup", onUp);
+ ui.resizing = null;
+ };
+
+ window.addEventListener("mousemove", onMove);
+ window.addEventListener("mouseup", onUp);
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ function autoFitColumn(id, key) {
+ const view = datasetViews.value[id];
+ if (!view) {
+ return;
+ }
+
+ const column = view.visibleColumns.find((item) => item.key === key);
+ if (!column) {
+ return;
+ }
+
+ const sample = [column.label, ...view.rows.slice(0, 120).map((entry) => displayValue(getValue(entry.raw, key)))];
+ const contentWidth = Math.max(...sample.map((value) => estimateColumnWidth(value, column.kind)));
+ state.datasets[id].columnWidths[key] = clampColumnWidth(contentWidth, defaultColumnWidth(column.kind));
+ }
+
+ function saveCustomPreset(id) {
+ const datasetState = state.datasets[id];
+ const name = (window.prompt(txt("Nome do preset", "Preset name"), datasetState.activeCustomPreset || txt("Meu preset", "My preset")) ?? "").trim();
+ if (!name) {
+ return;
+ }
+
+ const preset = {
+ name,
+ visibleKeys: [...datasetState.visibleKeys],
+ sort: { ...datasetState.sort },
+ sorts: datasetState.sorts.map((item) => ({ ...item })),
+ size: datasetState.size,
+ columnWidths: { ...datasetState.columnWidths },
+ pinnedColumnKey: datasetState.pinnedColumnKey || "",
+ filters: [...datasetState.filters]
+ };
+
+ datasetState.customPresets = [...datasetState.customPresets.filter((item) => item.name !== name), preset];
+ datasetState.activeCustomPreset = name;
+ }
+
+ function applyCustomPreset(id, name) {
+ const datasetState = state.datasets[id];
+ const dataset = datasets.value.find((item) => item.id === id);
+ const preset = datasetState.customPresets.find((item) => item.name === name);
+ if (!preset || !dataset) {
+ return;
+ }
+
+ const normalized = normalizePreset(dataset, preset);
+ datasetState.visibleKeys = [...normalized.visibleKeys];
+ datasetState.sorts = [...normalized.sorts];
+ syncPrimarySort(datasetState);
+ datasetState.size = normalized.size;
+ datasetState.columnWidths = { ...datasetState.columnWidths, ...normalized.columnWidths };
+ datasetState.pinnedColumnKey = normalized.pinnedColumnKey || "";
+ datasetState.filters = [...normalized.filters];
+ datasetState.page = 1;
+ datasetState.activeCustomPreset = normalized.name;
+ }
+
+ function deleteCustomPreset(id, name) {
+ const datasetState = state.datasets[id];
+ datasetState.customPresets = datasetState.customPresets.filter((item) => item.name !== name);
+ if (datasetState.activeCustomPreset === name) {
+ datasetState.activeCustomPreset = "";
+ }
+ }
+
+ function exportCustomPresets(id) {
+ const datasetState = state.datasets[id];
+ if (!datasetState || datasetState.customPresets.length === 0) {
+ return;
+ }
+
+ const blob = new Blob([JSON.stringify(datasetState.customPresets, null, 2)], { type: "application/json;charset=utf-8;" });
+ downloadBlob(blob, `${slugify(`${meta.title ?? "report"}-${id}-presets`) || "report-presets"}.json`);
+ }
+
+ function importCustomPresets(id) {
+ const input = document.createElement("input");
+ input.type = "file";
+ input.accept = "application/json,.json";
+ input.onchange = async () => {
+ const file = input.files?.[0];
+ if (!file) {
+ return;
+ }
+
+ try {
+ const text = await file.text();
+ const imported = JSON.parse(text);
+ if (!Array.isArray(imported)) {
+ throw new Error("invalid");
+ }
+
+ const dataset = datasets.value.find((item) => item.id === id);
+ if (!dataset) {
+ return;
+ }
+
+ const normalized = imported
+ .filter((item) => item && typeof item.name === "string")
+ .map((item) => normalizePreset(dataset, item));
+ const datasetState = state.datasets[id];
+ datasetState.customPresets = dedupePresets([...datasetState.customPresets, ...normalized]);
+ showToast(txt("Presets importados", "Presets imported"), ui);
+ } catch {
+ showToast(txt("Falha ao importar presets", "Could not import presets"), ui);
+ }
+ };
+ input.click();
+ }
+
+ function quickFilterValues(id) {
+ const view = datasetViews.value[id];
+ const datasetState = state.datasets[id];
+ if (!view || view.rows.length === 0) {
+ return [];
+ }
+
+ const activeKey = datasetState.selectedCell?.key || datasetState.pinnedColumnKey || view.visibleColumns[0]?.key;
+ const column = view.visibleColumns.find((item) => item.key === activeKey);
+ if (!column) {
+ return [];
+ }
+
+ const counts = new Map();
+ for (const entry of view.rows.slice(0, 200)) {
+ const value = stringifyValue(getValue(entry.raw, activeKey)).trim();
+ if (!value) {
+ continue;
+ }
+ counts.set(value, (counts.get(value) ?? 0) + 1);
+ }
+
+ return [...counts.entries()]
+ .sort((left, right) => right[1] - left[1])
+ .slice(0, 5)
+ .map(([value, count]) => ({ key: activeKey, value, count, label: column.label }));
+ }
+
+ function addQuickFilter(id, key, value) {
+ state.datasets[id].filters.push({ key, operator: "eq", value });
+ state.datasets[id].page = 1;
+ }
+
+ function applyPreset(id, preset) {
+ const dataset = datasets.value.find((item) => item.id === id);
+ const datasetState = state.datasets[id];
+ if (!dataset || !datasetState) {
+ return;
+ }
+
+ const textColumns = dataset.columns.filter((column) => column.kind === "text");
+ const compactColumns = dataset.columns.filter((column) => column.kind !== "text");
+ if (preset === "summary") {
+ datasetState.visibleKeys = [...compactColumns.slice(0, 4), ...textColumns.slice(0, 3)].slice(0, 7).map((column) => column.key);
+ datasetState.size = 10;
+ } else if (preset === "audit") {
+ datasetState.visibleKeys = dataset.columns.map((column) => column.key);
+ datasetState.size = 25;
+ } else if (preset === "detailed") {
+ datasetState.visibleKeys = dataset.columns.map((column) => column.key);
+ datasetState.size = 10;
+ for (const column of textColumns) {
+ datasetState.columnWidths[column.key] = Math.max(datasetState.columnWidths[column.key] ?? 0, 320);
+ }
+ }
+ datasetState.page = 1;
+ datasetState.activePreset = preset;
+ }
+
+ function updateScrollHint(id, event) {
+ const element = event?.currentTarget ?? event?.target;
+ if (!element) {
+ return;
+ }
+
+ const maxScrollLeft = Math.max(0, element.scrollWidth - element.clientWidth);
+ ui.scrollHints[id] = {
+ left: element.scrollLeft > 8,
+ right: element.scrollLeft < maxScrollLeft - 8
+ };
+ }
+
+ function scrollClass(id) {
+ const hint = ui.scrollHints[id] ?? { left: false, right: true };
+ return {
+ "has-left-shadow": !!hint.left,
+ "has-right-shadow": !!hint.right
+ };
+ }
+
+ function activeSortSummary(id) {
+ const view = datasetViews.value[id];
+ const datasetState = state.datasets[id];
+ if (!view || !datasetState) {
+ return [];
+ }
+
+ return datasetState.sorts
+ .map((sortRule, index) => {
+ const column = view.dataset.columns.find((item) => item.key === sortRule.key);
+ return column
+ ? {
+ index,
+ key: sortRule.key,
+ dir: sortRule.dir,
+ label: column.label
+ }
+ : null;
+ })
+ .filter(Boolean);
+ }
+
+ function isPageBusy(id) {
+ return !!state.datasets[id]?.pageBusy;
+ }
+
+ function activePendingColumn() {
+ const dataset = activeDataset();
+ const datasetState = activeDatasetState();
+ if (!dataset || !datasetState) {
+ return null;
+ }
+
+ return dataset.columns.find((item) => item.key === datasetState.pendingFilter.key) ?? null;
+ }
+
+ function filterUsesRange(kind, operator) {
+ return (kind === "number" || kind === "date") && operator === "between";
+ }
+
+ function filterInputType(kind) {
+ if (kind === "number") {
+ return "number";
+ }
+
+ if (kind === "date") {
+ return "date";
+ }
+
+ return "text";
+ }
+
+ return proxyRefs({
+ payload,
+ meta,
+ txt,
+ state,
+ ui,
+ datasets,
+ datasetViews,
+ overviewCards,
+ themeIcon,
+ footerText,
+ activeDataset,
+ activeDatasetState,
+ toggleTheme,
+ toggleSection,
+ resetDataset,
+ clearFilters,
+ removeFilter,
+ openFilterModal,
+ openSortModal,
+ openColumnsModal,
+ addFilter,
+ applySort,
+ clearSort,
+ setSortFromHeader,
+ toggleRow,
+ selectCell,
+ selectCellWithEvent,
+ isCellSelected,
+ isRowSelected,
+ changePage,
+ pageJump,
+ openCell,
+ isLongText,
+ copySql,
+ copySummary,
+ exportCsv,
+ exportJson,
+ choosePick,
+ moveColumns,
+ moveAllColumns,
+ moveVisibleColumnOrder,
+ visibleColumnSummary,
+ selectedRowsCount,
+ copySelectedCell,
+ copySelectedRows,
+ openCellMenu,
+ openHeaderMenu,
+ contextFilterByValue,
+ contextHideColumn,
+ contextShowOnlyColumn,
+ copyContextValue,
+ contextSort,
+ togglePinnedColumn,
+ isPinnedColumn,
+ getColumnWidth,
+ columnStyle,
+ columnStickyClass,
+ columnStickyStyle,
+ startResize,
+ autoFitColumn,
+ applyPreset,
+ saveCustomPreset,
+ applyCustomPreset,
+ deleteCustomPreset,
+ exportCustomPresets,
+ importCustomPresets,
+ quickFilterValues,
+ addQuickFilter,
+ updateScrollHint,
+ scrollClass,
+ activeSortSummary,
+ activePendingColumn,
+ filterUsesRange,
+ filterInputType,
+ isPageBusy,
+ addSortRule,
+ removeSortRule,
+ updateSortRuleKey,
+ updateSortRuleDirection,
+ openModal,
+ closeModal,
+ closeContextMenu,
+ summaryChipText: formatSummaryChip,
+ columnTone,
+ allowedOperators,
+ operatorLabel,
+ getValue,
+ displayValue,
+ stringifyValue,
+ PAGE_SIZES,
+ DEFAULT_EMPTY
+ });
+}
+
+function buildDatasets(payload, txt) {
+ const sections = [];
+ const resultColumns = buildResultColumns(payload.rows ?? [], payload.schema ?? []);
+ sections.push({
+ id: "results",
+ title: txt("Resultados", "Results"),
+ searchPlaceholder: txt("Buscar resultados", "Search results"),
+ columns: resultColumns,
+ rows: payload.rows ?? [],
+ preparedRows: prepareDatasetRows(payload.rows ?? [], resultColumns),
+ collapsed: false
+ });
+
+ if ((payload.schema ?? []).length > 0) {
+ sections.push({
+ id: "schema",
+ title: txt("Colunas e schema", "Columns and schema"),
+ searchPlaceholder: txt("Buscar schema", "Search schema"),
+ columns: [
+ { key: "name", label: txt("Nome", "Name"), kind: "text" },
+ { key: "kind", label: txt("Tipo", "Type"), kind: "text" },
+ { key: "nullCount", label: txt("Nulos", "Nulls"), kind: "number" },
+ { key: "distinctCount", label: txt("Distintos", "Distinct"), kind: "number" },
+ { key: "example", label: txt("Exemplo", "Example"), kind: "text" },
+ { key: "minValue", label: txt("Minimo", "Minimum"), kind: "text" },
+ { key: "maxValue", label: txt("Maximo", "Maximum"), kind: "text" }
+ ],
+ rows: (payload.schema ?? []).map((item) => ({
+ name: item.name ?? item.Name ?? "",
+ kind: item.kind ?? item.Kind ?? "",
+ nullCount: item.nullCount ?? item.NullCount ?? 0,
+ distinctCount: item.distinctCount ?? item.DistinctCount ?? 0,
+ example: item.example ?? item.Example ?? "",
+ minValue: item.minValue ?? item.MinValue ?? "",
+ maxValue: item.maxValue ?? item.MaxValue ?? ""
+ })),
+ preparedRows: [],
+ collapsed: true
+ });
+ }
+
+ for (const entry of [
+ ["metadata", txt("Metadados", "Metadata"), txt("Buscar metadados", "Search metadata"), payload.metadata ?? []],
+ ["lineageNodes", txt("Nos de linhagem", "Lineage nodes"), txt("Buscar nos", "Search nodes"), payload.lineageNodes ?? []],
+ ["lineageConnections", txt("Conexoes de linhagem", "Lineage connections"), txt("Buscar conexoes", "Search connections"), payload.lineageConnections ?? []]
+ ]) {
+ if (entry[3].length > 0) {
+ sections.push({
+ id: entry[0],
+ title: entry[1],
+ searchPlaceholder: entry[2],
+ columns: buildColumnsFromRows(entry[3]),
+ rows: entry[3],
+ preparedRows: [],
+ collapsed: true
+ });
+ }
+ }
+
+ return sections;
+}
+
+function loadState(datasetDefs) {
+ const stored = readStoredState();
+ const base = {
+ theme: stored.theme === "light" ? "light" : "dark",
+ sections: {
+ overview: false,
+ sql: true
+ },
+ datasets: {}
+ };
+
+ for (const dataset of datasetDefs) {
+ const previous = stored.datasets?.[dataset.id] ?? {};
+ base.sections[dataset.id] = typeof previous.collapsed === "boolean" ? previous.collapsed : !!dataset.collapsed;
+ base.datasets[dataset.id] = normalizeDatasetState(dataset, previous);
+ }
+
+ return base;
+}
+
+function readStoredState() {
+ try {
+ return JSON.parse(window.localStorage.getItem(STORAGE_KEY) ?? "{}");
+ } catch {
+ return {};
+ }
+}
+
+function saveState(appState) {
+ const serializable = {
+ theme: appState.theme,
+ sections: JSON.parse(JSON.stringify(appState.sections)),
+ datasets: JSON.parse(JSON.stringify(appState.datasets))
+ };
+
+ window.localStorage.setItem(STORAGE_KEY, JSON.stringify(serializable));
+}
+
+function normalizeDatasetState(dataset, input) {
+ const safeColumns = sanitizeColumns(dataset.columns);
+ dataset.columns = safeColumns;
+ const availableKeys = safeColumns.map((column) => column.key);
+ const visibleKeys = Array.isArray(input.visibleKeys) && input.visibleKeys.length > 0
+ ? input.visibleKeys.filter((key) => availableKeys.includes(key))
+ : [...availableKeys];
+
+ const normalized = {
+ search: typeof input.search === "string" ? input.search : "",
+ filters: Array.isArray(input.filters) ? input.filters.filter((item) => availableKeys.includes(item.key)) : [],
+ sort: normalizeSort(input.sort, availableKeys),
+ sorts: normalizeSorts(input.sorts, availableKeys, input.sort),
+ visibleKeys: visibleKeys.length > 0 ? visibleKeys : [...availableKeys],
+ page: normalizePositiveInt(input.page, 1),
+ pageBusy: false,
+ size: normalizePageSize(input.size),
+ inlineFiltersOpen: !!input.inlineFiltersOpen,
+ inlineColumnsOpen: !!input.inlineColumnsOpen,
+ selectedRows: Array.isArray(input.selectedRows) ? input.selectedRows.map(String) : [],
+ selectedCell: input.selectedCell && typeof input.selectedCell.key === "string"
+ ? { rowId: String(input.selectedCell.rowId ?? ""), key: input.selectedCell.key }
+ : null,
+ selectedCells: Array.isArray(input.selectedCells) ? input.selectedCells.map(String) : [],
+ anchorCell: input.anchorCell && typeof input.anchorCell.key === "string"
+ ? { rowId: String(input.anchorCell.rowId ?? ""), key: input.anchorCell.key }
+ : null,
+ columnWidths: normalizeColumnWidths(input.columnWidths, safeColumns),
+ pendingFilter: normalizePendingFilter(dataset, input.pendingFilter),
+ columnSearch: typeof input.columnSearch === "string" ? input.columnSearch : "",
+ activePreset: typeof input.activePreset === "string" ? input.activePreset : "",
+ activeCustomPreset: typeof input.activeCustomPreset === "string" ? input.activeCustomPreset : "",
+ lastRowSelection: typeof input.lastRowSelection === "string" ? input.lastRowSelection : "",
+ pinnedColumnKey: typeof input.pinnedColumnKey === "string" ? input.pinnedColumnKey : "",
+ customPresets: Array.isArray(input.customPresets) ? input.customPresets.filter((item) => item && typeof item.name === "string").map((item) => normalizePreset(dataset, item)) : [],
+ pickSelection: {
+ available: Array.isArray(input.pickSelection?.available) ? input.pickSelection.available.filter((key) => availableKeys.includes(key)) : [],
+ visible: Array.isArray(input.pickSelection?.visible) ? input.pickSelection.visible.filter((key) => availableKeys.includes(key)) : []
+ }
+ };
+
+ syncPrimarySort(normalized);
+ return normalized;
+}
+
+function normalizePendingFilter(dataset, pendingFilter) {
+ const firstColumn = dataset.columns[0];
+ const key = dataset.columns.some((column) => column.key === pendingFilter?.key) ? pendingFilter.key : firstColumn?.key ?? "";
+ const column = dataset.columns.find((item) => item.key === key) ?? firstColumn ?? { kind: "text" };
+ const operator = allowedOperators(column.kind).includes(pendingFilter?.operator) ? pendingFilter.operator : defaultOperator(column.kind);
+ return {
+ key,
+ operator,
+ value: pendingFilter?.value ?? "",
+ valueTo: pendingFilter?.valueTo ?? ""
+ };
+}
+
+function normalizeColumnWidths(input, columns) {
+ const widths = {};
+ const source = input && typeof input === "object" ? input : {};
+ for (const column of columns) {
+ widths[column.key] = clampColumnWidth(source[column.key], defaultColumnWidth(column.kind));
+ }
+
+ return widths;
+}
+
+function normalizeSort(sort, availableKeys) {
+ if (!sort || !availableKeys.includes(sort.key)) {
+ return { key: "", dir: "asc" };
+ }
+
+ return {
+ key: sort.key,
+ dir: sort.dir === "desc" ? "desc" : "asc"
+ };
+}
+
+function normalizeSorts(sorts, availableKeys, fallbackSort = null) {
+ const source = Array.isArray(sorts) && sorts.length > 0 ? sorts : (fallbackSort ? [fallbackSort] : []);
+ return dedupeSortRules(
+ source
+ .filter((item) => item && availableKeys.includes(item.key))
+ .map((item) => ({
+ key: item.key,
+ dir: item.dir === "desc" ? "desc" : "asc"
+ }))
+ );
+}
+
+function dedupeSortRules(sorts) {
+ const seen = new Set();
+ const output = [];
+ for (const item of sorts) {
+ if (!item?.key || seen.has(item.key)) {
+ continue;
+ }
+ seen.add(item.key);
+ output.push({ key: item.key, dir: item.dir === "desc" ? "desc" : "asc" });
+ }
+ return output;
+}
+
+function syncPrimarySort(datasetState) {
+ datasetState.sort = datasetState.sorts[0] ? { ...datasetState.sorts[0] } : { key: "", dir: "asc" };
+}
+
+function normalizePositiveInt(value, fallback) {
+ const parsed = Number.parseInt(value, 10);
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
+}
+
+function normalizePageSize(value) {
+ const size = normalizePositiveInt(value, 10);
+ return PAGE_SIZES.includes(size) ? size : 10;
+}
+
+function normalizePreset(dataset, input) {
+ const availableKeys = sanitizeColumns(dataset.columns).map((column) => column.key);
+ return {
+ name: String(input.name ?? "").trim() || "Preset",
+ visibleKeys: Array.isArray(input.visibleKeys) ? input.visibleKeys.filter((key) => availableKeys.includes(key)) : [...availableKeys],
+ sort: normalizeSort(input.sort, availableKeys),
+ sorts: normalizeSorts(input.sorts, availableKeys, input.sort),
+ size: normalizePageSize(input.size),
+ columnWidths: normalizeColumnWidths(input.columnWidths, dataset.columns),
+ pinnedColumnKey: typeof input.pinnedColumnKey === "string" && availableKeys.includes(input.pinnedColumnKey) ? input.pinnedColumnKey : "",
+ filters: Array.isArray(input.filters) ? input.filters.filter((item) => availableKeys.includes(item.key)).map((item) => ({ ...item, valueTo: item.valueTo ?? "" })) : []
+ };
+}
+
+function dedupePresets(presets) {
+ const map = new Map();
+ for (const item of presets) {
+ if (item?.name) {
+ map.set(item.name, item);
+ }
+ }
+ return [...map.values()];
+}
+
+function buildResultColumns(rows, schema) {
+ const schemaDetails = schema
+ .filter((item) => item && typeof item === "object")
+ .map((item) => ({
+ key: item.name ?? item.Name ?? "",
+ label: item.name ?? item.Name ?? "",
+ kind: normalizeKind(item.kind ?? item.Kind ?? inferKindFromRows(rows, item.name ?? item.Name ?? ""))
+ }));
+
+ if (schemaDetails.length > 0) {
+ return sanitizeColumns(schemaDetails);
+ }
+
+ return sanitizeColumns(buildColumnsFromRows(rows));
+}
+
+function buildColumnsFromRows(rows) {
+ if (!rows.length) {
+ return [];
+ }
+
+ return Object.keys(rows[0] ?? {}).map((key) => ({
+ key,
+ label: key,
+ kind: inferKindFromRows(rows, key)
+ }));
+}
+
+function sanitizeColumns(columns) {
+ return (Array.isArray(columns) ? columns : [])
+ .filter((column) => column && typeof column === "object")
+ .map((column) => {
+ const key = String(column.key ?? column.name ?? column.Name ?? "").trim();
+ const label = String(column.label ?? key).trim();
+ const kind = normalizeKind(column.kind ?? "text");
+ return key ? { key, label: label || key, kind } : null;
+ })
+ .filter(Boolean);
+}
+
+function inferKindFromRows(rows, key) {
+ for (const row of rows) {
+ const value = getValue(row, key);
+ if (value === null || value === undefined || value === "") {
+ continue;
+ }
+
+ if (typeof value === "number") {
+ return "number";
+ }
+
+ if (typeof value === "boolean") {
+ return "boolean";
+ }
+
+ const text = String(value).trim();
+ if (/^-?\d+([.,]\d+)?$/.test(text)) {
+ return "number";
+ }
+
+ if (/\d{4}-\d{2}-\d{2}|\d{2}\/\d{2}\/\d{4}/.test(text)) {
+ return "date";
+ }
+
+ if (/^(true|false|sim|nao|não)$/i.test(text)) {
+ return "boolean";
+ }
+
+ return "text";
+ }
+
+ return "text";
+}
+
+function normalizeKind(kind) {
+ const text = String(kind ?? "").toLowerCase();
+ if (text.includes("date") || text.includes("time")) {
+ return "date";
+ }
+
+ if (text.includes("bool")) {
+ return "boolean";
+ }
+
+ if (text.includes("int") || text.includes("number") || text.includes("decimal") || text.includes("float")) {
+ return "number";
+ }
+
+ return "text";
+}
+
+function buildDatasetView(dataset, datasetState) {
+ const safeColumns = sanitizeColumns(dataset.columns);
+ dataset.columns = safeColumns;
+ const visibleColumns = safeColumns.filter((column) => datasetState.visibleKeys.includes(column.key));
+ const effectiveVisibleColumns = visibleColumns.length > 0 ? visibleColumns : safeColumns.slice(0, 1);
+ const allRows = Array.isArray(dataset.preparedRows) && dataset.preparedRows.length === dataset.rows.length
+ ? dataset.preparedRows
+ : prepareDatasetRows(dataset.rows, safeColumns);
+
+ const filteredRows = allRows.filter((entry) => matchesDataset(entry, dataset, datasetState));
+ const sortedRows = sortRows(filteredRows, dataset, datasetState.sorts);
+ const size = normalizePageSize(datasetState.size);
+ const pageCount = Math.max(1, Math.ceil(sortedRows.length / size));
+ const page = Math.min(Math.max(1, normalizePositiveInt(datasetState.page, 1)), pageCount);
+ datasetState.page = page;
+ datasetState.size = size;
+ const start = (page - 1) * size;
+ const pageRows = sortedRows.slice(start, start + size);
+ const sortColumn = safeColumns.find((column) => column.key === datasetState.sorts[0]?.key) ?? null;
+ if (effectiveVisibleColumns.length > 0 && !datasetState.visibleKeys.some((key) => effectiveVisibleColumns.some((column) => column.key === key))) {
+ datasetState.visibleKeys = effectiveVisibleColumns.map((column) => column.key);
+ }
+
+ return {
+ dataset,
+ visibleColumns: effectiveVisibleColumns,
+ rows: sortedRows,
+ pageRows,
+ page,
+ pageCount,
+ totalRows: allRows.length,
+ filteredCount: sortedRows.length,
+ size,
+ sortColumn,
+ sortRules: datasetState.sorts,
+ availableColumns: safeColumns.filter((column) => !datasetState.visibleKeys.includes(column.key) && (column.label || column.key).toLowerCase().includes(datasetState.columnSearch.toLowerCase())),
+ shownColumns: safeColumns.filter((column) => datasetState.visibleKeys.includes(column.key)),
+ hasRows: sortedRows.length > 0
+ };
+}
+
+function clampColumnWidth(value, fallback = MIN_COLUMN_WIDTH) {
+ const normalized = normalizePositiveInt(value, fallback);
+ return Math.max(MIN_COLUMN_WIDTH, normalized);
+}
+
+function defaultColumnWidth(kind) {
+ switch (kind) {
+ case "number":
+ return 160;
+ case "date":
+ return 180;
+ case "boolean":
+ return 150;
+ default:
+ return 240;
+ }
+}
+
+function estimateColumnWidth(value, kind) {
+ const text = stringifyValue(value);
+ const maxChars = Math.min(Math.max(text.length, 8), kind === "text" ? 48 : 22);
+ const charWidth = kind === "number" ? 9 : 8.2;
+ return Math.ceil((maxChars * charWidth) + 48);
+}
+
+function buildRowId(row, index) {
+ for (const key of ["id", "ID", "Id", "codigo", "Codigo", "key", "Key"]) {
+ const value = getValue(row, key);
+ if (value !== undefined && value !== null && value !== "") {
+ return `${key}:${String(value)}`;
+ }
+ }
+
+ return `row:${index}`;
+}
+
+function prepareDatasetRows(rows, columns) {
+ const safeColumns = sanitizeColumns(columns);
+ return (Array.isArray(rows) ? rows : []).map((row, index) => ({
+ raw: row,
+ rowId: buildRowId(row, index),
+ searchText: safeColumns.map((column) => stringifyValue(getValue(row, column.key))).join(" ").toLowerCase()
+ }));
+}
+
+function matchesDataset(entry, dataset, datasetState) {
+ const search = datasetState.search.trim().toLowerCase();
+ if (search && !entry.searchText.includes(search)) {
+ return false;
+ }
+
+ for (const filter of datasetState.filters) {
+ const column = dataset.columns.find((item) => item.key === filter.key);
+ if (!column) {
+ continue;
+ }
+
+ if (!matchesFilter(getValue(entry.raw, column.key), column.kind, filter)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+function sortRows(rows, dataset, sorts) {
+ const rules = Array.isArray(sorts) ? sorts : [];
+ if (rules.length === 0) {
+ return rows;
+ }
+
+ return [...rows].sort((left, right) => {
+ for (const sort of rules) {
+ const column = dataset.columns.find((item) => item.key === sort.key);
+ if (!column) {
+ continue;
+ }
+
+ const direction = sort.dir === "desc" ? -1 : 1;
+ const comparison = compareValues(getValue(left.raw, column.key), getValue(right.raw, column.key), column.kind) * direction;
+ if (comparison !== 0) {
+ return comparison;
+ }
+ }
+
+ return 0;
+ });
+}
+
+function compareValues(left, right, kind) {
+ if (left === right) {
+ return 0;
+ }
+
+ if (left === null || left === undefined || left === "") {
+ return 1;
+ }
+
+ if (right === null || right === undefined || right === "") {
+ return -1;
+ }
+
+ if (kind === "number") {
+ return parseNumeric(left) - parseNumeric(right);
+ }
+
+ if (kind === "date") {
+ return parseDate(left) - parseDate(right);
+ }
+
+ if (kind === "boolean") {
+ return Number(parseBoolean(left)) - Number(parseBoolean(right));
+ }
+
+ return stringifyValue(left).localeCompare(stringifyValue(right), undefined, { numeric: true, sensitivity: "base" });
+}
+
+function parseNumeric(value) {
+ if (typeof value === "number") {
+ return value;
+ }
+
+ const normalized = String(value).replace(/\./g, "").replace(",", ".");
+ const parsed = Number.parseFloat(normalized);
+ return Number.isFinite(parsed) ? parsed : 0;
+}
+
+function parseDate(value) {
+ if (value instanceof Date) {
+ return value.getTime();
+ }
+
+ const text = String(value).trim();
+ if (/^\d{2}\/\d{2}\/\d{4}$/.test(text)) {
+ const [day, month, year] = text.split("/");
+ return new Date(`${year}-${month}-${day}T00:00:00`).getTime();
+ }
+
+ const time = Date.parse(text);
+ return Number.isFinite(time) ? time : 0;
+}
+
+function parseBoolean(value) {
+ if (typeof value === "boolean") {
+ return value;
+ }
+
+ return /^(true|sim|yes|1)$/i.test(String(value));
+}
+
+export function getValue(row, key) {
+ if (!row || typeof row !== "object") {
+ return undefined;
+ }
+
+ if (Object.prototype.hasOwnProperty.call(row, key)) {
+ return row[key];
+ }
+
+ const match = Object.keys(row).find((candidate) => candidate.toLowerCase() === String(key).toLowerCase());
+ return match ? row[match] : undefined;
+}
+
+export function stringifyValue(value) {
+ if (value === null || value === undefined || value === "") {
+ return "";
+ }
+
+ return String(value);
+}
+
+export function displayValue(value) {
+ const text = stringifyValue(value);
+ return text || DEFAULT_EMPTY;
+}
+
+export function allowedOperators(kind) {
+ if (kind === "number" || kind === "date") {
+ return ["between", "eq", "neq", "gt", "gte", "lt", "lte"];
+ }
+
+ if (kind === "boolean") {
+ return ["eq", "neq"];
+ }
+
+ return ["contains", "like", "regex", "eq", "neq", "starts", "ends"];
+}
+
+function defaultOperator(kind) {
+ return kind === "text" ? "contains" : kind === "number" || kind === "date" ? "between" : "eq";
+}
+
+export function operatorLabel(operator) {
+ return {
+ contains: "Contains",
+ like: "Like",
+ regex: "Regex",
+ between: "Between",
+ eq: "Equals",
+ neq: "Different",
+ gt: "Greater than",
+ gte: "Greater or equal",
+ lt: "Less than",
+ lte: "Less or equal",
+ starts: "Starts with",
+ ends: "Ends with"
+ }[operator] ?? operator;
+}
+
+function matchesFilter(value, kind, filter) {
+ const left = stringifyValue(value);
+ const right = stringifyValue(filter.value);
+ const rightTo = stringifyValue(filter.valueTo);
+
+ if (kind === "number") {
+ if (filter.operator === "between") {
+ const leftValue = parseNumeric(left);
+ return leftValue >= parseNumeric(right) && leftValue <= parseNumeric(rightTo);
+ }
+ return compareByOperator(parseNumeric(left), parseNumeric(right), filter.operator);
+ }
+
+ if (kind === "date") {
+ if (filter.operator === "between") {
+ const leftValue = parseDate(left);
+ return leftValue >= parseDate(right) && leftValue <= parseDate(rightTo);
+ }
+ return compareByOperator(parseDate(left), parseDate(right), filter.operator);
+ }
+
+ if (kind === "boolean") {
+ return compareByOperator(parseBoolean(left), parseBoolean(right), filter.operator);
+ }
+
+ const leftLower = left.toLowerCase();
+ const rightLower = right.toLowerCase();
+ switch (filter.operator) {
+ case "contains": return leftLower.includes(rightLower);
+ case "starts": return leftLower.startsWith(rightLower);
+ case "ends": return leftLower.endsWith(rightLower);
+ case "like": return buildLikeRegex(right).test(left);
+ case "regex":
+ try {
+ return new RegExp(right, "i").test(left);
+ } catch {
+ return false;
+ }
+ case "eq": return leftLower === rightLower;
+ case "neq": return leftLower !== rightLower;
+ default: return true;
+ }
+}
+
+function compareByOperator(left, right, operator) {
+ switch (operator) {
+ case "eq": return left === right;
+ case "neq": return left !== right;
+ case "gt": return left > right;
+ case "gte": return left >= right;
+ case "lt": return left < right;
+ case "lte": return left <= right;
+ default: return true;
+ }
+}
+
+function buildLikeRegex(pattern) {
+ const escaped = pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/%/g, ".*").replace(/_/g, ".");
+ return new RegExp(`^${escaped}$`, "i");
+}
+
+function csvEscape(value) {
+ const text = displayValue(value);
+ return /[,"\r\n]/.test(text) ? `"${text.replaceAll("\"", "\"\"")}"` : text;
+}
+
+function downloadBlob(blob, fileName) {
+ const url = URL.createObjectURL(blob);
+ const anchor = document.createElement("a");
+ anchor.href = url;
+ anchor.download = fileName;
+ anchor.click();
+ URL.revokeObjectURL(url);
+}
+
+function copyText(text, message, ui = null) {
+ navigator.clipboard?.writeText(text).then(() => showToast(message, ui)).catch(() => showToast("Could not copy", ui));
+}
+
+function showToast(message, ui) {
+ if (!ui) {
+ return;
+ }
+
+ window.clearTimeout(ui.toastTimer);
+ ui.toast = message;
+ ui.toastTimer = window.setTimeout(() => {
+ ui.toast = "";
+ }, 1800);
+}
+
+function slugify(value) {
+ return String(value ?? "")
+ .normalize("NFD")
+ .replace(/[\u0300-\u036f]/g, "")
+ .toLowerCase()
+ .replace(/[^a-z0-9]+/g, "-")
+ .replace(/^-+|-+$/g, "");
+}
+
+function buildOverviewCards(meta, payload, txt) {
+ const warnings = meta.warnings ?? [];
+ return [
+ { label: txt("Linhas", "Rows"), value: new Intl.NumberFormat().format(Number((payload.rows ?? []).length)), icon: "rows" },
+ { label: txt("Colunas", "Columns"), value: new Intl.NumberFormat().format(Number((payload.schema ?? []).length || buildColumnsFromRows(payload.rows ?? []).length)), icon: "columns" },
+ { label: txt("Tempo", "Duration"), value: meta.duration ?? DEFAULT_EMPTY, icon: "clock" },
+ { label: txt("Conexao", "Connection"), value: meta.connectionName ?? DEFAULT_EMPTY, icon: "database" },
+ { label: txt("Gerado em", "Generated at"), value: meta.generatedAt ?? DEFAULT_EMPTY, icon: "clock" },
+ { label: txt("Descricao", "Description"), value: meta.description || DEFAULT_EMPTY, icon: "clipboard", span: "wide" },
+ { label: "Warnings", value: warnings.length > 0 ? warnings.join(" • ") : txt("Nenhum", "None"), icon: "alert", tone: warnings.length > 0 ? "warning" : "" }
+ ];
+}
+
+export function summaryChipText(filter) {
+ return `${filter.key} • ${operatorLabel(filter.operator)} • ${displayValue(filter.value)}`;
+}
+
+export function columnTone(kind, value) {
+ if (value === null || value === undefined || value === "") {
+ return "is-null";
+ }
+
+ if (kind === "number") {
+ return "is-number";
+ }
+
+ if (kind === "date") {
+ return "is-date";
+ }
+
+ if (kind === "boolean") {
+ return "is-boolean";
+ }
+
+ return "is-text";
+}
+
+function formatSummaryChip(filter) {
+ if (filter.operator === "between") {
+ return `${filter.key} • ${operatorLabel(filter.operator)} • ${displayValue(filter.value)} → ${displayValue(filter.valueTo)}`;
+ }
+
+ return `${filter.key} • ${operatorLabel(filter.operator)} • ${displayValue(filter.value)}`;
+}
diff --git a/src/AkkornStudio.UI/Assets/ReportFrontend/src/styles.css b/src/AkkornStudio.UI/Assets/ReportFrontend/src/styles.css
new file mode 100644
index 00000000..b59f9562
--- /dev/null
+++ b/src/AkkornStudio.UI/Assets/ReportFrontend/src/styles.css
@@ -0,0 +1,1073 @@
+:root {
+ color-scheme: dark;
+ --bg: #0a101b;
+ --surface: #0f1728;
+ --surface-2: #141f35;
+ --surface-3: #1b2942;
+ --border: #2a3b5d;
+ --border-strong: #385180;
+ --text: #edf3ff;
+ --text-soft: #9eb0d2;
+ --text-strong: #f8fbff;
+ --accent: #6ea8fe;
+ --accent-strong: #88b4ff;
+ --accent-soft: rgba(110, 168, 254, 0.14);
+ --success: #72e2a1;
+ --warning: #f4c26b;
+ --danger: #ff8d94;
+ --shadow: 0 20px 60px rgba(3, 10, 21, 0.28);
+}
+
+:root[data-theme="light"] {
+ color-scheme: light;
+ --bg: #f4f7fb;
+ --surface: #ffffff;
+ --surface-2: #f6f8fc;
+ --surface-3: #eef2f9;
+ --border: #d4dceb;
+ --border-strong: #bbc7dc;
+ --text: #162136;
+ --text-soft: #5e6d88;
+ --text-strong: #0d1728;
+ --accent: #356ef1;
+ --accent-strong: #275ad7;
+ --accent-soft: rgba(53, 110, 241, 0.12);
+ --success: #2f8f57;
+ --warning: #b26d00;
+ --danger: #d14255;
+ --shadow: 0 24px 54px rgba(23, 42, 79, 0.12);
+}
+
+* {
+ box-sizing: border-box;
+}
+
+body {
+ margin: 0;
+ font-family: "Segoe UI", system-ui, sans-serif;
+ background: var(--bg);
+ color: var(--text);
+}
+
+button,
+input,
+select {
+ font: inherit;
+ outline: none;
+}
+
+button:focus,
+input:focus,
+select:focus,
+button:focus-visible,
+input:focus-visible,
+select:focus-visible {
+ outline: none;
+}
+
+.report-shell {
+ max-width: 1680px;
+ margin: 0 auto;
+ padding: 28px;
+}
+
+.page-header,
+.panel,
+.mini-panel,
+.modal-card,
+.toast {
+ box-shadow: var(--shadow);
+}
+
+.page-header,
+.panel,
+.mini-panel,
+.modal-card,
+.ghost-btn,
+.collapse-btn,
+.field-input,
+.chip,
+.pager,
+.pick-item,
+.icon-only {
+ border: 1px solid var(--border);
+}
+
+.page-header,
+.panel,
+.mini-panel,
+.modal-card {
+ background: rgba(15, 23, 40, 0.86);
+ backdrop-filter: blur(10px);
+}
+
+:root[data-theme="light"] .page-header,
+:root[data-theme="light"] .panel,
+:root[data-theme="light"] .mini-panel,
+:root[data-theme="light"] .modal-card {
+ background: rgba(255, 255, 255, 0.92);
+}
+
+.page-header {
+ display: grid;
+ grid-template-columns: 260px minmax(320px, 1fr) auto;
+ gap: 24px;
+ align-items: center;
+ border-radius: 24px;
+ padding: 24px;
+}
+
+.brand-wrap {
+ display: flex;
+ gap: 14px;
+ align-items: center;
+}
+
+.brand-mark {
+ width: 48px;
+ height: 48px;
+ display: grid;
+ place-items: center;
+ border-radius: 16px;
+ background: var(--surface-2);
+ color: var(--accent);
+ font-weight: 800;
+ font-size: 1.15rem;
+ border: 1px solid var(--border);
+}
+
+.brand-name {
+ font-size: 0.76rem;
+ font-weight: 800;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--text-soft);
+}
+
+.brand-sub {
+ font-size: 0.95rem;
+ font-weight: 700;
+ color: var(--text-strong);
+}
+
+.page-intro h1 {
+ margin: 0 0 10px;
+ font-size: clamp(1.4rem, 2vw, 2rem);
+ line-height: 1.1;
+}
+
+.toolbar {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-end;
+ gap: 10px;
+ align-items: center;
+}
+
+.main-content {
+ display: grid;
+ gap: 18px;
+ margin-top: 20px;
+}
+
+.panel {
+ border-radius: 24px;
+ padding: 18px;
+}
+
+.section-head {
+ display: flex;
+ justify-content: space-between;
+ gap: 18px;
+ align-items: center;
+ margin-bottom: 14px;
+}
+
+.section-head h2 {
+ margin: 0;
+ font-size: 1.05rem;
+}
+
+.section-copy {
+ margin-top: 6px;
+ font-size: 0.92rem;
+ color: var(--text-soft);
+}
+
+.section-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ justify-content: flex-end;
+ align-items: center;
+}
+
+.overview-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+ gap: 14px;
+}
+
+.overview-card {
+ display: flex;
+ gap: 14px;
+ align-items: start;
+ padding: 18px;
+ border-radius: 20px;
+ background: var(--surface);
+ border: 1px solid var(--border);
+}
+
+.overview-card.is-wide {
+ grid-column: 1 / -1;
+}
+
+.overview-card.is-warning {
+ border-color: rgba(244, 194, 107, 0.35);
+}
+
+.overview-icon {
+ width: 42px;
+ height: 42px;
+ display: grid;
+ place-items: center;
+ border-radius: 14px;
+ background: var(--accent-soft);
+ color: var(--accent);
+}
+
+.overview-label {
+ font-size: 0.78rem;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ color: var(--text-soft);
+}
+
+.overview-value {
+ margin-top: 8px;
+ font-size: 1rem;
+ font-weight: 700;
+ line-height: 1.45;
+}
+
+.dataset-body {
+ display: grid;
+ gap: 14px;
+}
+
+.summary-strip {
+ display: grid;
+ gap: 12px;
+}
+
+.mini-panel {
+ border-radius: 18px;
+ padding: 14px;
+ background: var(--surface-2);
+}
+
+.mini-panel-head {
+ display: flex;
+ justify-content: space-between;
+ gap: 12px;
+ align-items: center;
+}
+
+.mini-panel-title {
+ font-weight: 700;
+}
+
+.mini-panel-actions {
+ display: flex;
+ gap: 8px;
+}
+
+.chips {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-top: 12px;
+}
+
+.chip {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 12px;
+ border-radius: 999px;
+ background: var(--surface);
+ color: var(--text-soft);
+}
+
+.chip.empty {
+ opacity: 0.8;
+}
+
+.chip.removable {
+ cursor: pointer;
+}
+
+.table-shell {
+ position: relative;
+ display: grid;
+ gap: 12px;
+}
+
+.table-shell.is-page-busy .table-scroll,
+.table-shell.is-page-busy .pager {
+ opacity: 0.72;
+}
+
+.table-loading {
+ position: absolute;
+ inset: 56px 0 72px 0;
+ display: grid;
+ place-items: center;
+ pointer-events: none;
+ z-index: 8;
+}
+
+.table-loading-card {
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 14px;
+ border-radius: 999px;
+ border: 1px solid var(--border);
+ background: rgba(15, 23, 40, 0.92);
+ color: var(--text);
+ box-shadow: var(--shadow);
+}
+
+:root[data-theme="light"] .table-loading-card {
+ background: rgba(255, 255, 255, 0.95);
+}
+
+.table-loading-spinner {
+ width: 14px;
+ height: 14px;
+ border-radius: 999px;
+ border: 2px solid var(--border-strong);
+ border-top-color: var(--accent);
+ animation: spin 0.8s linear infinite;
+}
+
+.table-meta {
+ display: flex;
+ justify-content: space-between;
+ gap: 14px;
+ align-items: flex-start;
+ flex-wrap: wrap;
+}
+
+.table-meta-main,
+.preset-toolbar,
+.preset-actions,
+.preset-secondary,
+.table-status,
+.table-quick-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ align-items: center;
+}
+
+.table-meta-main {
+ flex: 1 1 420px;
+}
+
+.preset-toolbar {
+ gap: 10px;
+}
+
+.preset-segmented {
+ display: inline-flex;
+ flex-wrap: wrap;
+ gap: 4px;
+ padding: 4px;
+ border: 1px solid var(--border);
+ border-radius: 999px;
+ background: var(--surface-2);
+}
+
+.segment-btn,
+.icon-chip {
+ border: 0;
+ border-radius: 999px;
+ background: transparent;
+ color: var(--text-soft);
+ cursor: pointer;
+}
+
+.segment-btn {
+ padding: 9px 12px;
+ font-weight: 700;
+}
+
+.segment-btn:hover,
+.icon-chip:hover {
+ background: var(--surface);
+ color: var(--text);
+}
+
+.icon-chip {
+ width: 34px;
+ height: 34px;
+ display: inline-grid;
+ place-items: center;
+ border: 1px solid var(--border);
+ background: var(--surface);
+}
+
+.quick-filters-wrap {
+ overflow-x: auto;
+ padding-bottom: 2px;
+}
+
+.quick-filters {
+ display: flex;
+ flex-wrap: nowrap;
+ gap: 8px;
+ align-items: center;
+ min-width: max-content;
+}
+
+.quick-filters-label {
+ color: var(--text-soft);
+ font-size: 0.86rem;
+ font-weight: 700;
+ position: sticky;
+ left: 0;
+ padding-right: 4px;
+ background: var(--surface);
+}
+
+.quick-chip {
+ background: var(--surface-2);
+ border: 1px solid var(--border);
+ padding: 6px 10px;
+}
+
+.quick-chip small {
+ opacity: 0.72;
+ padding: 2px 6px;
+ border-radius: 999px;
+ background: var(--surface);
+}
+
+.result-count {
+ font-weight: 700;
+ color: var(--text-soft);
+ padding-inline: 2px;
+}
+
+.status-pill {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 12px;
+ border-radius: 999px;
+ background: var(--surface-2);
+ color: var(--text-soft);
+ border: 1px solid var(--border);
+ font-size: 0.88rem;
+}
+
+.pager-wrap {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 14px;
+ align-items: center;
+ justify-content: flex-end;
+}
+
+.pager-wrap-bottom {
+ padding-top: 4px;
+}
+
+.page-size-wrap {
+ display: grid;
+ gap: 6px;
+}
+
+.pager {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ border-radius: 16px;
+ padding: 8px;
+ background: var(--surface-2);
+}
+
+.pager-readout {
+ min-width: 110px;
+ text-align: center;
+ color: var(--text-soft);
+ font-weight: 700;
+}
+
+.pager-input {
+ width: 70px;
+ padding: 10px 12px;
+ border-radius: 12px;
+ border: 1px solid var(--border);
+ background: var(--surface);
+ color: var(--text);
+}
+
+.table-scroll {
+ position: relative;
+ overflow-x: auto;
+ overflow-y: hidden;
+ border-radius: 18px;
+ border: 1px solid var(--border);
+}
+
+.table-scroll.has-left-shadow::before,
+.table-scroll.has-right-shadow::after {
+ content: "";
+ position: sticky;
+ top: 0;
+ bottom: 0;
+ width: 18px;
+ pointer-events: none;
+ z-index: 6;
+}
+
+.table-scroll.has-left-shadow::before {
+ left: 0;
+ float: left;
+ background: linear-gradient(90deg, rgba(10, 16, 27, 0.7), transparent);
+}
+
+.table-scroll.has-right-shadow::after {
+ right: 0;
+ float: right;
+ background: linear-gradient(270deg, rgba(10, 16, 27, 0.7), transparent);
+}
+
+:root[data-theme="light"] .table-scroll.has-left-shadow::before {
+ background: linear-gradient(90deg, rgba(244, 247, 251, 0.9), transparent);
+}
+
+:root[data-theme="light"] .table-scroll.has-right-shadow::after {
+ background: linear-gradient(270deg, rgba(244, 247, 251, 0.9), transparent);
+}
+
+.report-table {
+ width: max-content;
+ min-width: 100%;
+ border-collapse: separate;
+ border-spacing: 0;
+ min-width: 920px;
+}
+
+.report-table thead th {
+ background: var(--surface-2);
+ border-bottom: 1px solid var(--border);
+ padding: 0;
+ z-index: 1;
+}
+
+.th-shell {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) auto;
+ align-items: stretch;
+}
+
+.sort-head {
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 10px;
+ border: 0;
+ background: transparent;
+ color: inherit;
+ padding: 14px;
+ font-weight: 700;
+ cursor: pointer;
+}
+
+.resize-handle {
+ width: 28px;
+ min-width: 28px;
+ border: 0;
+ border-left: 1px solid var(--border);
+ background: transparent;
+ color: var(--text-soft);
+ cursor: col-resize;
+ display: grid;
+ place-items: center;
+}
+
+.resize-handle:hover {
+ color: var(--accent);
+ background: var(--accent-soft);
+}
+
+.resize-handle:active {
+ background: var(--surface-3);
+}
+
+.report-table tbody td {
+ padding: 0;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06);
+}
+
+:root[data-theme="light"] .report-table tbody td {
+ border-bottom-color: rgba(26, 35, 54, 0.08);
+}
+
+.cell-body {
+ display: flex;
+ align-items: start;
+ gap: 10px;
+ padding: 13px 14px;
+}
+
+.cell {
+ cursor: pointer;
+ vertical-align: top;
+}
+
+.cell-text {
+ display: -webkit-box;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ white-space: pre-wrap;
+ word-break: break-word;
+ overflow-wrap: anywhere;
+}
+
+.cell-expand {
+ flex: 0 0 auto;
+ border: 0;
+ background: transparent;
+ color: var(--text-soft);
+ cursor: pointer;
+}
+
+.select-col {
+ width: 28px;
+ min-width: 28px;
+ background: var(--surface-2);
+}
+
+.select-col-width {
+ width: 28px;
+}
+
+.sticky-select {
+ position: sticky;
+ left: 0;
+ z-index: 4;
+}
+
+.sticky-main-col {
+ position: sticky;
+ left: 28px;
+ z-index: 3;
+ background: var(--surface);
+ box-shadow: 8px 0 18px rgba(5, 10, 18, 0.14);
+}
+
+.report-table thead .sticky-main-col {
+ background: var(--surface-2);
+}
+
+.row-selector {
+ width: 100%;
+ min-height: 100%;
+ min-width: 28px;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ cursor: pointer;
+ color: var(--text-soft);
+}
+
+.row-selector:hover {
+ color: var(--accent);
+}
+
+.is-row-selected .row-selector {
+ color: var(--accent);
+}
+
+.is-row-selected td {
+ background: rgba(110, 168, 254, 0.08);
+}
+
+.is-selected-cell {
+ outline: 2px solid var(--accent);
+ outline-offset: -2px;
+ background: rgba(110, 168, 254, 0.12);
+}
+
+.is-number .cell-text {
+ color: #7cc7ff;
+}
+
+.is-date .cell-text {
+ color: #f4c26b;
+}
+
+.is-boolean .cell-text {
+ color: #78dba5;
+ font-weight: 700;
+}
+
+.is-null .cell-text {
+ color: var(--text-soft);
+ font-style: italic;
+}
+
+.empty-state {
+ padding: 28px;
+ text-align: center;
+ color: var(--text-soft);
+}
+
+.sql-box {
+ padding: 18px;
+ border-radius: 18px;
+ background: #0a1120;
+ border: 1px solid var(--border);
+ overflow: auto;
+}
+
+.sql-box pre,
+.cell-modal-text {
+ margin: 0;
+ white-space: pre-wrap;
+ word-break: break-word;
+ overflow-wrap: anywhere;
+}
+
+.page-footer {
+ margin: 18px 0 8px;
+ text-align: center;
+ color: var(--text-soft);
+}
+
+.modal-shell {
+ position: fixed;
+ inset: 0;
+ display: grid;
+ place-items: center;
+ padding: 24px;
+ background: rgba(4, 10, 18, 0.66);
+ z-index: 20;
+}
+
+.modal-card {
+ width: min(980px, 100%);
+ max-height: 88vh;
+ overflow: hidden;
+ border-radius: 22px;
+ display: grid;
+ grid-template-rows: auto 1fr auto;
+}
+
+.modal-card.modal-wide {
+ width: min(1180px, 100%);
+}
+
+.modal-card.modal-cell {
+ width: min(1080px, 100%);
+}
+
+.modal-head,
+.modal-foot {
+ display: flex;
+ justify-content: space-between;
+ gap: 12px;
+ align-items: center;
+ padding: 18px 20px;
+ border-bottom: 1px solid var(--border);
+}
+
+.modal-foot {
+ border-top: 1px solid var(--border);
+ border-bottom: 0;
+ justify-content: flex-end;
+}
+
+.modal-title {
+ font-size: 1.08rem;
+ font-weight: 800;
+}
+
+.modal-body {
+ overflow: auto;
+ padding: 20px;
+}
+
+.form-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 14px;
+}
+
+.field-span {
+ grid-column: 1 / -1;
+}
+
+.field-stack {
+ display: grid;
+ gap: 8px;
+}
+
+.field-label {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 0.84rem;
+ font-weight: 700;
+ color: var(--text-soft);
+}
+
+.field-input {
+ width: 100%;
+ border-radius: 14px;
+ padding: 12px 14px;
+ background: var(--surface);
+ color: var(--text);
+}
+
+.field-input.compact-search {
+ min-width: 220px;
+ border: 0;
+ background: transparent;
+ padding-left: 0;
+ padding-right: 0;
+}
+
+.preset-select {
+ min-width: 180px;
+}
+
+.sort-rules {
+ display: grid;
+ gap: 12px;
+}
+
+.sort-rule {
+ display: grid;
+ grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) auto;
+ gap: 12px;
+ align-items: end;
+ padding: 14px;
+ border: 1px solid var(--border);
+ border-radius: 16px;
+ background: var(--surface-2);
+}
+
+.sort-remove {
+ align-self: end;
+}
+
+.field-input:focus,
+.field-input:focus-visible,
+.compact-select:focus,
+.compact-select:focus-visible,
+.pager-input:focus,
+.pager-input:focus-visible,
+.compact-search:focus,
+.compact-search:focus-visible {
+ outline: none;
+ box-shadow: none;
+ border-color: var(--border);
+}
+
+.compact-select {
+ width: 84px;
+}
+
+.search-field {
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+ min-width: 260px;
+ padding: 0 12px;
+ border: 1px solid var(--border);
+ border-radius: 14px;
+ background: var(--surface);
+ color: var(--text-soft);
+}
+
+.ghost-btn,
+.collapse-btn,
+.icon-only {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ border-radius: 14px;
+ padding: 11px 14px;
+ background: var(--surface);
+ color: var(--text);
+ cursor: pointer;
+}
+
+.ghost-btn.small {
+ padding: 8px 10px;
+}
+
+.icon-only {
+ width: 42px;
+ height: 42px;
+ padding: 0;
+}
+
+.ghost-btn:disabled,
+.icon-only:disabled {
+ opacity: 0.45;
+ cursor: not-allowed;
+}
+
+.ghost-btn:hover:not(:disabled),
+.collapse-btn:hover,
+.icon-only:hover:not(:disabled),
+.sort-head:hover,
+.pick-item:hover {
+ border-color: var(--border-strong);
+ background: var(--surface-3);
+}
+
+.picklist {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) 96px minmax(0, 1fr);
+ gap: 14px;
+ align-items: center;
+}
+
+.pick-pane {
+ display: grid;
+ gap: 10px;
+}
+
+.pick-list {
+ display: grid;
+ gap: 8px;
+ min-height: 320px;
+ max-height: 440px;
+ overflow: auto;
+ padding: 10px;
+ border: 1px solid var(--border);
+ border-radius: 18px;
+ background: var(--surface-2);
+}
+
+.pick-item {
+ text-align: left;
+ border-radius: 12px;
+ padding: 12px 14px;
+ background: var(--surface);
+ color: var(--text);
+ cursor: pointer;
+}
+
+.pick-item.active {
+ border-color: var(--accent);
+ background: var(--accent-soft);
+}
+
+.pick-actions {
+ display: grid;
+ gap: 10px;
+}
+
+.icon-glyph,
+.icon-glyph svg {
+ width: 16px;
+ height: 16px;
+ display: inline-block;
+}
+
+.toast {
+ position: fixed;
+ right: 24px;
+ bottom: 24px;
+ padding: 14px 18px;
+ border-radius: 16px;
+ background: var(--surface);
+ color: var(--text-strong);
+ z-index: 30;
+}
+
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.context-menu {
+ position: fixed;
+ min-width: 220px;
+ display: grid;
+ gap: 4px;
+ padding: 8px;
+ border-radius: 16px;
+ border: 1px solid var(--border-strong);
+ background: var(--surface);
+ box-shadow: var(--shadow);
+ z-index: 40;
+}
+
+.context-item {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ width: 100%;
+ padding: 10px 12px;
+ border: 0;
+ border-radius: 12px;
+ background: transparent;
+ color: var(--text);
+ cursor: pointer;
+}
+
+.context-item:hover {
+ background: var(--surface-3);
+}
+
+@media (max-width: 1160px) {
+ .page-header {
+ grid-template-columns: 1fr;
+ }
+
+ .toolbar {
+ justify-content: flex-start;
+ }
+}
+
+@media (max-width: 920px) {
+ .report-shell {
+ padding: 16px;
+ }
+
+ .section-head,
+ .table-meta,
+ .modal-head,
+ .modal-foot {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .section-actions {
+ justify-content: stretch;
+ }
+
+ .form-grid,
+ .picklist,
+ .sort-rule {
+ grid-template-columns: 1fr;
+ }
+
+ .field-span {
+ grid-column: auto;
+ }
+}
diff --git a/src/AkkornStudio.UI/Assets/ReportFrontend/vite.config.js b/src/AkkornStudio.UI/Assets/ReportFrontend/vite.config.js
new file mode 100644
index 00000000..fe817316
--- /dev/null
+++ b/src/AkkornStudio.UI/Assets/ReportFrontend/vite.config.js
@@ -0,0 +1,32 @@
+import { defineConfig } from "vite";
+import vue from "@vitejs/plugin-vue";
+
+export default defineConfig({
+ plugins: [vue()],
+ define: {
+ "process.env.NODE_ENV": JSON.stringify("production"),
+ "process.env": "{}"
+ },
+ build: {
+ emptyOutDir: true,
+ outDir: "dist",
+ cssCodeSplit: false,
+ lib: {
+ entry: "src/main.js",
+ name: "AkkornReportApp",
+ formats: ["iife"],
+ fileName: () => "report-app.js"
+ },
+ rollupOptions: {
+ output: {
+ assetFileNames: (assetInfo) => {
+ if (assetInfo.name?.endsWith(".css")) {
+ return "report-app.css";
+ }
+
+ return "report-app.[ext]";
+ }
+ }
+ }
+ }
+});
diff --git a/src/DBWeaver.UI/Assets/Syntax/Sql.xshd b/src/AkkornStudio.UI/Assets/Syntax/Sql.xshd
similarity index 100%
rename from src/DBWeaver.UI/Assets/Syntax/Sql.xshd
rename to src/AkkornStudio.UI/Assets/Syntax/Sql.xshd
diff --git a/src/DBWeaver.UI/Assets/Themes/AppStyles.axaml b/src/AkkornStudio.UI/Assets/Themes/AppStyles.axaml
similarity index 61%
rename from src/DBWeaver.UI/Assets/Themes/AppStyles.axaml
rename to src/AkkornStudio.UI/Assets/Themes/AppStyles.axaml
index 088583fd..44f06dae 100644
--- a/src/DBWeaver.UI/Assets/Themes/AppStyles.axaml
+++ b/src/AkkornStudio.UI/Assets/Themes/AppStyles.axaml
@@ -1,459 +1,761 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Assets/Themes/DesignTokens.axaml b/src/AkkornStudio.UI/Assets/Themes/DesignTokens.axaml
similarity index 98%
rename from src/DBWeaver.UI/Assets/Themes/DesignTokens.axaml
rename to src/AkkornStudio.UI/Assets/Themes/DesignTokens.axaml
index 96ccf492..770176e9 100644
--- a/src/DBWeaver.UI/Assets/Themes/DesignTokens.axaml
+++ b/src/AkkornStudio.UI/Assets/Themes/DesignTokens.axaml
@@ -1,319 +1,319 @@
-
-
-
-
-
- #090B14
- #0F1220
- #151A2C
- #1C2338
- #252F49
-
- #090B14
- #2A3554
- #1D2740
-
- #101629
- #171E34
- #1E2740
- #243150
- #202D48
- #263556
- #2A3B5F
- #7C96FF22
-
- #E7ECFF
- #AEB9D9
- #7F8AAE
- #66708F
- #0B0F1D
- #8FA7FF
- #8FA7FF
-
- #B9C6EA
- #7E8BB1
- #616A86
-
- #2A3554
- #334164
- #42527B
- #6B8CFF
- #2C3348
-
- #5B7CFA
- #6C8CFF
- #4E6EE8
- #8A63F6
- #9A76FF
- #7752DD
-
- #2FBF84
- #D9A441
- #E16174
- #4D9BFF
-
- #1A2031
- #252C40
- #7D87A5
-
-
- #5B7CFA
- #4E6EE8
- #666B8CFF
- #6C8CFF
- #5B7CFA
- #4E6EE8
-
-
- #5B7CFA
- #EAF0FF
- #1C2338
- #D0DAF5
- #1D2E52
- #CAE1FF
- #153A2C
- #C5F6E5
- #3A2A12
- #F8DEB0
- #41202A
- #FFD2DB
- #151A2C
- #C5D2F0
-
-
- #4F78F4
- #6B93FF
- #7E66E8
- #9C89FF
- #B38B5E
- #D0AC7A
- #946EF0
- #B094FF
- #D36A7B
- #E48C99
- #8E9BC2
- #A8B4D6
- #7A87BC
- #97A3CF
- #B38B5E
- #C8A275
- #7B90C7
- #9AB0E0
- #A486E8
- #B8A1F1
- #6F86D9
- #7EA6FF
-
-
- #8FB9FF
- #B98BFF
- #D36A7B
- #7AB6FF
- #7E8CC3
- #97A4C8
- #CDA35A
- #E1B24F
- #73A7FF
- #CDA35A
- #A878FF
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Manrope,Sora,Plus Jakarta Sans,Segoe UI,Arial,sans-serif
- Space Grotesk,Manrope,Segoe UI,Arial,sans-serif
- JetBrainsMono Nerd Font,JetBrains Mono,IBM Plex Mono,Cascadia Code,Consolas,monospace
-
- 24
- 18
- 15
- 14
- 13
- 12
- 11
- 12
- 11
-
- Bold
- Bold
- SemiBold
- SemiBold
- Medium
- Normal
- Normal
- Normal
- Medium
- SemiBold
- Medium
-
- 1.4
- 1.3
- 1.2
- 1.45
- 0
-
-
- 4
- 6
- 10
- 14
- 18
- 999
- 14,14,0,0
- 0,0,14,14
-
-
- 12
- 12,12,0,0
- 5
-
-
- 200
- 10
- 0.85
- 1
- 1
- 0.95
- 0.7
- 0.4
- 0.8
- 0.4
-
- 4
- 10
- 14
- 18
- 24
-
- 14
- 18,10
- 10,6
- 18,12
-
- 0,18,0,0
- 18,18,0,0
- 0,10,0,0
- 0,10,0,10
- 0,0,10,10
- 0,0,22,18
-
-
- 0 0 0 0 #00000000
- 0 2 8 0 #00000033
- 0 6 18 0 #00000040
- 0 10 28 0 #00000052
- 0 16 40 0 #00000066
- 0 0 7 2 #AAFFFFFF
-
-
- 0 4 24 0 #40000000, 0 1 4 0 #50000000
- 0 0 0 2 #6B8CFF, 0 8 32 0 #556B8CFF
- 0 10 28 0 #00000052
-
-
+
+
+
+
+
+ #090B14
+ #0F1220
+ #151A2C
+ #1C2338
+ #252F49
+
+ #090B14
+ #2A3554
+ #1D2740
+
+ #101629
+ #171E34
+ #1E2740
+ #243150
+ #202D48
+ #263556
+ #2A3B5F
+ #7C96FF22
+
+ #E7ECFF
+ #AEB9D9
+ #7F8AAE
+ #66708F
+ #0B0F1D
+ #8FA7FF
+ #8FA7FF
+
+ #B9C6EA
+ #7E8BB1
+ #616A86
+
+ #2A3554
+ #334164
+ #42527B
+ #6B8CFF
+ #2C3348
+
+ #5B7CFA
+ #6C8CFF
+ #4E6EE8
+ #8A63F6
+ #9A76FF
+ #7752DD
+
+ #2FBF84
+ #D9A441
+ #E16174
+ #4D9BFF
+
+ #1A2031
+ #252C40
+ #7D87A5
+
+
+ #5B7CFA
+ #4E6EE8
+ #666B8CFF
+ #6C8CFF
+ #5B7CFA
+ #4E6EE8
+
+
+ #5B7CFA
+ #EAF0FF
+ #1C2338
+ #D0DAF5
+ #1D2E52
+ #CAE1FF
+ #153A2C
+ #C5F6E5
+ #3A2A12
+ #F8DEB0
+ #41202A
+ #FFD2DB
+ #151A2C
+ #C5D2F0
+
+
+ #4F78F4
+ #6B93FF
+ #7E66E8
+ #9C89FF
+ #B38B5E
+ #D0AC7A
+ #946EF0
+ #B094FF
+ #D36A7B
+ #E48C99
+ #8E9BC2
+ #A8B4D6
+ #7A87BC
+ #97A3CF
+ #B38B5E
+ #C8A275
+ #7B90C7
+ #9AB0E0
+ #A486E8
+ #B8A1F1
+ #6F86D9
+ #7EA6FF
+
+
+ #8FB9FF
+ #B98BFF
+ #D36A7B
+ #7AB6FF
+ #7E8CC3
+ #97A4C8
+ #CDA35A
+ #E1B24F
+ #73A7FF
+ #CDA35A
+ #A878FF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Manrope,Sora,Plus Jakarta Sans,Segoe UI,Arial,sans-serif
+ Space Grotesk,Manrope,Segoe UI,Arial,sans-serif
+ JetBrainsMono Nerd Font,JetBrains Mono,IBM Plex Mono,Cascadia Code,Consolas,monospace
+
+ 24
+ 18
+ 15
+ 14
+ 13
+ 12
+ 11
+ 12
+ 11
+
+ Bold
+ Bold
+ SemiBold
+ SemiBold
+ Medium
+ Normal
+ Normal
+ Normal
+ Medium
+ SemiBold
+ Medium
+
+ 1.4
+ 1.3
+ 1.2
+ 1.45
+ 0
+
+
+ 4
+ 6
+ 10
+ 14
+ 18
+ 999
+ 14,14,0,0
+ 0,0,14,14
+
+
+ 12
+ 12,12,0,0
+ 5
+
+
+ 200
+ 10
+ 0.85
+ 1
+ 1
+ 0.95
+ 0.7
+ 0.4
+ 0.8
+ 0.4
+
+ 4
+ 10
+ 14
+ 18
+ 24
+
+ 14
+ 18,10
+ 10,6
+ 18,12
+
+ 0,18,0,0
+ 18,18,0,0
+ 0,10,0,0
+ 0,10,0,10
+ 0,0,10,10
+ 0,0,22,18
+
+
+ 0 0 0 0 #00000000
+ 0 2 8 0 #00000033
+ 0 6 18 0 #00000040
+ 0 10 28 0 #00000052
+ 0 16 40 0 #00000066
+ 0 0 7 2 #AAFFFFFF
+
+
+ 0 4 24 0 #40000000, 0 1 4 0 #50000000
+ 0 0 0 2 #6B8CFF, 0 8 32 0 #556B8CFF
+ 0 10 28 0 #00000052
+
+
diff --git a/src/DBWeaver.UI/Assets/Themes/user-theme.high-contrast.sample.json b/src/AkkornStudio.UI/Assets/Themes/user-theme.high-contrast.sample.json
similarity index 96%
rename from src/DBWeaver.UI/Assets/Themes/user-theme.high-contrast.sample.json
rename to src/AkkornStudio.UI/Assets/Themes/user-theme.high-contrast.sample.json
index f6da959f..9fafeea7 100644
--- a/src/DBWeaver.UI/Assets/Themes/user-theme.high-contrast.sample.json
+++ b/src/AkkornStudio.UI/Assets/Themes/user-theme.high-contrast.sample.json
@@ -1,37 +1,37 @@
-{
- "meta": {
- "name": "High Contrast Verification",
- "version": "1.0"
- },
- "colors": {
- "bg0": "#05070D",
- "bg1": "#0A1220",
- "bg2": "#13213A",
- "bg3": "#1D2D4D",
- "bg4": "#29416E",
- "textPrimary": "#F5FAFF",
- "textSecondary": "#B4C5DC",
- "textMuted": "#8FA3BF",
- "textDisabled": "#6C7F9D",
- "textInverse": "#03050A",
- "textAccent": "#9BB8FF",
- "btnPrimaryBg": "#1D4ED8",
- "btnPrimaryFg": "#FFFFFF",
- "btnWarningBg": "#9A3412",
- "btnWarningFg": "#FFF1E8"
- },
- "typography": {
- "uiFont": "Manrope,Segoe UI,Arial,sans-serif",
- "nodeFont": "Space Grotesk,Manrope,Segoe UI,Arial,sans-serif",
- "monoFont": "JetBrainsMono Nerd Font,JetBrains Mono,Cascadia Code,Consolas,monospace",
- "displaySize": 24,
- "headingSize": 18,
- "titleSize": 15,
- "nodeTitleSize": 14,
- "labelSize": 13,
- "bodySize": 12,
- "captionSize": 11,
- "monoBodySize": 12,
- "monoSmallSize": 11
- }
-}
+{
+ "meta": {
+ "name": "High Contrast Verification",
+ "version": "1.0"
+ },
+ "colors": {
+ "bg0": "#05070D",
+ "bg1": "#0A1220",
+ "bg2": "#13213A",
+ "bg3": "#1D2D4D",
+ "bg4": "#29416E",
+ "textPrimary": "#F5FAFF",
+ "textSecondary": "#B4C5DC",
+ "textMuted": "#8FA3BF",
+ "textDisabled": "#6C7F9D",
+ "textInverse": "#03050A",
+ "textAccent": "#9BB8FF",
+ "btnPrimaryBg": "#1D4ED8",
+ "btnPrimaryFg": "#FFFFFF",
+ "btnWarningBg": "#9A3412",
+ "btnWarningFg": "#FFF1E8"
+ },
+ "typography": {
+ "uiFont": "Manrope,Segoe UI,Arial,sans-serif",
+ "nodeFont": "Space Grotesk,Manrope,Segoe UI,Arial,sans-serif",
+ "monoFont": "JetBrainsMono Nerd Font,JetBrains Mono,Cascadia Code,Consolas,monospace",
+ "displaySize": 24,
+ "headingSize": 18,
+ "titleSize": 15,
+ "nodeTitleSize": 14,
+ "labelSize": 13,
+ "bodySize": 12,
+ "captionSize": 11,
+ "monoBodySize": 12,
+ "monoSmallSize": 11
+ }
+}
diff --git a/src/DBWeaver.UI/Assets/Themes/user-theme.json b/src/AkkornStudio.UI/Assets/Themes/user-theme.json
similarity index 96%
rename from src/DBWeaver.UI/Assets/Themes/user-theme.json
rename to src/AkkornStudio.UI/Assets/Themes/user-theme.json
index cfc3fb23..0193680a 100644
--- a/src/DBWeaver.UI/Assets/Themes/user-theme.json
+++ b/src/AkkornStudio.UI/Assets/Themes/user-theme.json
@@ -1,37 +1,37 @@
-{
- "meta": {
- "name": "Studio Dark",
- "version": "1.0"
- },
- "colors": {
- "bg0": "#090B14",
- "bg1": "#0F1220",
- "bg2": "#151A2C",
- "bg3": "#1C2338",
- "bg4": "#252F49",
- "textPrimary": "#E7ECFF",
- "textSecondary": "#AEB9D9",
- "textMuted": "#7F8AAE",
- "textDisabled": "#66708F",
- "textInverse": "#0B0F1D",
- "textAccent": "#8FA7FF",
- "btnPrimaryBg": "#2563EB",
- "btnPrimaryFg": "#F8FAFC",
- "btnWarningBg": "#7C2D12",
- "btnWarningFg": "#FED7AA"
- },
- "typography": {
- "uiFont": "Manrope,Sora,Plus Jakarta Sans,Segoe UI,Arial,sans-serif",
- "nodeFont": "Space Grotesk,Manrope,Segoe UI,Arial,sans-serif",
- "monoFont": "JetBrainsMono Nerd Font,JetBrains Mono,IBM Plex Mono,Cascadia Code,Consolas,monospace",
- "displaySize": 24,
- "headingSize": 18,
- "titleSize": 15,
- "nodeTitleSize": 14,
- "labelSize": 13,
- "bodySize": 12,
- "captionSize": 11,
- "monoBodySize": 12,
- "monoSmallSize": 11
- }
-}
+{
+ "meta": {
+ "name": "Studio Dark",
+ "version": "1.0"
+ },
+ "colors": {
+ "bg0": "#090B14",
+ "bg1": "#0F1220",
+ "bg2": "#151A2C",
+ "bg3": "#1C2338",
+ "bg4": "#252F49",
+ "textPrimary": "#E7ECFF",
+ "textSecondary": "#AEB9D9",
+ "textMuted": "#7F8AAE",
+ "textDisabled": "#66708F",
+ "textInverse": "#0B0F1D",
+ "textAccent": "#8FA7FF",
+ "btnPrimaryBg": "#2563EB",
+ "btnPrimaryFg": "#F8FAFC",
+ "btnWarningBg": "#7C2D12",
+ "btnWarningFg": "#FED7AA"
+ },
+ "typography": {
+ "uiFont": "Manrope,Sora,Plus Jakarta Sans,Segoe UI,Arial,sans-serif",
+ "nodeFont": "Space Grotesk,Manrope,Segoe UI,Arial,sans-serif",
+ "monoFont": "JetBrainsMono Nerd Font,JetBrains Mono,IBM Plex Mono,Cascadia Code,Consolas,monospace",
+ "displaySize": 24,
+ "headingSize": 18,
+ "titleSize": 15,
+ "nodeTitleSize": 14,
+ "labelSize": 13,
+ "bodySize": 12,
+ "captionSize": 11,
+ "monoBodySize": 12,
+ "monoSmallSize": 11
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml b/src/AkkornStudio.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml
similarity index 83%
rename from src/DBWeaver.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml
rename to src/AkkornStudio.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml
index 249e2124..b728c8a6 100644
--- a/src/DBWeaver.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml
+++ b/src/AkkornStudio.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml
@@ -1,231 +1,215 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml.cs b/src/AkkornStudio.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml.cs
similarity index 84%
rename from src/DBWeaver.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml.cs
rename to src/AkkornStudio.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml.cs
index 1d260d70..d6e0499c 100644
--- a/src/DBWeaver.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml.cs
+++ b/src/AkkornStudio.UI/Controls/AppDiagnostics/AppDiagnosticsControl.axaml.cs
@@ -1,23 +1,23 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using DBWeaver.UI.ViewModels;
-
-namespace DBWeaver.UI.Controls;
-
-public sealed partial class AppDiagnosticsControl : UserControl
-{
- public AppDiagnosticsControl()
- {
- InitializeComponent();
- }
-
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- if (e.Key == Key.Escape && DataContext is AppDiagnosticsViewModel vm)
- {
- vm.CloseCommand.Execute(null);
- e.Handled = true;
- }
- }
-}
+using Avalonia.Controls;
+using Avalonia.Input;
+using AkkornStudio.UI.ViewModels;
+
+namespace AkkornStudio.UI.Controls;
+
+public sealed partial class AppDiagnosticsControl : UserControl
+{
+ public AppDiagnosticsControl()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+ if (e.Key == Key.Escape && DataContext is AppDiagnosticsViewModel vm)
+ {
+ vm.CloseCommand.Execute(null);
+ e.Handled = true;
+ }
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/AutoJoin/AutoJoinOverlay.axaml b/src/AkkornStudio.UI/Controls/AutoJoin/AutoJoinOverlay.axaml
similarity index 87%
rename from src/DBWeaver.UI/Controls/AutoJoin/AutoJoinOverlay.axaml
rename to src/AkkornStudio.UI/Controls/AutoJoin/AutoJoinOverlay.axaml
index 644fd002..e1a66ab2 100644
--- a/src/DBWeaver.UI/Controls/AutoJoin/AutoJoinOverlay.axaml
+++ b/src/AkkornStudio.UI/Controls/AutoJoin/AutoJoinOverlay.axaml
@@ -1,255 +1,241 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Controls/AutoJoin/AutoJoinOverlay.axaml.cs b/src/AkkornStudio.UI/Controls/AutoJoin/AutoJoinOverlay.axaml.cs
similarity index 78%
rename from src/DBWeaver.UI/Controls/AutoJoin/AutoJoinOverlay.axaml.cs
rename to src/AkkornStudio.UI/Controls/AutoJoin/AutoJoinOverlay.axaml.cs
index c508577f..195e3067 100644
--- a/src/DBWeaver.UI/Controls/AutoJoin/AutoJoinOverlay.axaml.cs
+++ b/src/AkkornStudio.UI/Controls/AutoJoin/AutoJoinOverlay.axaml.cs
@@ -1,11 +1,11 @@
-using Avalonia.Controls;
-
-namespace DBWeaver.UI.Controls;
-
-public sealed partial class AutoJoinOverlay : UserControl
-{
- public AutoJoinOverlay()
- {
- InitializeComponent();
- }
-}
+using Avalonia.Controls;
+
+namespace AkkornStudio.UI.Controls;
+
+public sealed partial class AutoJoinOverlay : UserControl
+{
+ public AutoJoinOverlay()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/AutoJoin/ManualJoinDialog.axaml b/src/AkkornStudio.UI/Controls/AutoJoin/ManualJoinDialog.axaml
similarity index 96%
rename from src/DBWeaver.UI/Controls/AutoJoin/ManualJoinDialog.axaml
rename to src/AkkornStudio.UI/Controls/AutoJoin/ManualJoinDialog.axaml
index 4d207fa0..96fac51c 100644
--- a/src/DBWeaver.UI/Controls/AutoJoin/ManualJoinDialog.axaml
+++ b/src/AkkornStudio.UI/Controls/AutoJoin/ManualJoinDialog.axaml
@@ -1,207 +1,207 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Controls/AutoJoin/ManualJoinDialog.axaml.cs b/src/AkkornStudio.UI/Controls/AutoJoin/ManualJoinDialog.axaml.cs
similarity index 79%
rename from src/DBWeaver.UI/Controls/AutoJoin/ManualJoinDialog.axaml.cs
rename to src/AkkornStudio.UI/Controls/AutoJoin/ManualJoinDialog.axaml.cs
index 6c39454d..9e6ccf22 100644
--- a/src/DBWeaver.UI/Controls/AutoJoin/ManualJoinDialog.axaml.cs
+++ b/src/AkkornStudio.UI/Controls/AutoJoin/ManualJoinDialog.axaml.cs
@@ -1,11 +1,11 @@
-using Avalonia.Controls;
-
-namespace DBWeaver.UI.Controls;
-
-public sealed partial class ManualJoinDialog : UserControl
-{
- public ManualJoinDialog()
- {
- InitializeComponent();
- }
-}
+using Avalonia.Controls;
+
+namespace AkkornStudio.UI.Controls;
+
+public sealed partial class ManualJoinDialog : UserControl
+{
+ public ManualJoinDialog()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/Benchmark/BenchmarkOverlay.axaml b/src/AkkornStudio.UI/Controls/Benchmark/BenchmarkOverlay.axaml
similarity index 87%
rename from src/DBWeaver.UI/Controls/Benchmark/BenchmarkOverlay.axaml
rename to src/AkkornStudio.UI/Controls/Benchmark/BenchmarkOverlay.axaml
index faf9df8c..bc83eab6 100644
--- a/src/DBWeaver.UI/Controls/Benchmark/BenchmarkOverlay.axaml
+++ b/src/AkkornStudio.UI/Controls/Benchmark/BenchmarkOverlay.axaml
@@ -1,333 +1,302 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Controls/Benchmark/BenchmarkOverlay.axaml.cs b/src/AkkornStudio.UI/Controls/Benchmark/BenchmarkOverlay.axaml.cs
similarity index 83%
rename from src/DBWeaver.UI/Controls/Benchmark/BenchmarkOverlay.axaml.cs
rename to src/AkkornStudio.UI/Controls/Benchmark/BenchmarkOverlay.axaml.cs
index 0ba89f20..c6f05169 100644
--- a/src/DBWeaver.UI/Controls/Benchmark/BenchmarkOverlay.axaml.cs
+++ b/src/AkkornStudio.UI/Controls/Benchmark/BenchmarkOverlay.axaml.cs
@@ -1,23 +1,23 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using DBWeaver.UI.ViewModels;
-
-namespace DBWeaver.UI.Controls;
-
-public sealed partial class BenchmarkOverlay : UserControl
-{
- public BenchmarkOverlay()
- {
- InitializeComponent();
- }
-
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- if (e.Key == Key.Escape && DataContext is BenchmarkViewModel vm)
- {
- vm.CloseCommand.Execute(null);
- e.Handled = true;
- }
- }
-}
+using Avalonia.Controls;
+using Avalonia.Input;
+using AkkornStudio.UI.ViewModels;
+
+namespace AkkornStudio.UI.Controls;
+
+public sealed partial class BenchmarkOverlay : UserControl
+{
+ public BenchmarkOverlay()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+ if (e.Key == Key.Escape && DataContext is BenchmarkViewModel vm)
+ {
+ vm.CloseCommand.Execute(null);
+ e.Handled = true;
+ }
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/CommandPalette/CommandPaletteControl.axaml b/src/AkkornStudio.UI/Controls/CommandPalette/CommandPaletteControl.axaml
similarity index 77%
rename from src/DBWeaver.UI/Controls/CommandPalette/CommandPaletteControl.axaml
rename to src/AkkornStudio.UI/Controls/CommandPalette/CommandPaletteControl.axaml
index 6979431c..da17f2d2 100644
--- a/src/DBWeaver.UI/Controls/CommandPalette/CommandPaletteControl.axaml
+++ b/src/AkkornStudio.UI/Controls/CommandPalette/CommandPaletteControl.axaml
@@ -1,178 +1,156 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Controls/CommandPalette/CommandPaletteControl.axaml.cs b/src/AkkornStudio.UI/Controls/CommandPalette/CommandPaletteControl.axaml.cs
similarity index 94%
rename from src/DBWeaver.UI/Controls/CommandPalette/CommandPaletteControl.axaml.cs
rename to src/AkkornStudio.UI/Controls/CommandPalette/CommandPaletteControl.axaml.cs
index e7158470..e03ffa30 100644
--- a/src/DBWeaver.UI/Controls/CommandPalette/CommandPaletteControl.axaml.cs
+++ b/src/AkkornStudio.UI/Controls/CommandPalette/CommandPaletteControl.axaml.cs
@@ -1,106 +1,106 @@
-using System.ComponentModel;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.LogicalTree;
-using Avalonia.Threading;
-using DBWeaver.UI.ViewModels;
-
-namespace DBWeaver.UI.Controls;
-
-public sealed partial class CommandPaletteControl : UserControl
-{
- private CommandPaletteViewModel? _vm;
-
- public CommandPaletteControl()
- {
- InitializeComponent();
- DataContextChanged += (_, _) => BindViewModel();
-
- ItemsControl? list = this.FindControl("ResultsList");
- list?.AddHandler(
- PointerPressedEvent,
- OnResultPointerPressed,
- Avalonia.Interactivity.RoutingStrategies.Bubble
- );
- }
-
- private void BindViewModel()
- {
- if (_vm is not null)
- _vm.PropertyChanged -= OnVmPropertyChanged;
-
- _vm = DataContext as CommandPaletteViewModel;
-
- if (_vm is not null)
- _vm.PropertyChanged += OnVmPropertyChanged;
- }
-
- private void OnVmPropertyChanged(object? sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == nameof(CommandPaletteViewModel.IsVisible) && _vm?.IsVisible == true)
- Dispatcher.UIThread.Post(FocusSearch, DispatcherPriority.Input);
- }
-
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- if (DataContext is not CommandPaletteViewModel vm)
- return;
-
- switch (e.Key)
- {
- case Key.Down:
- vm.SelectNext();
- e.Handled = true;
- break;
-
- case Key.Up:
- vm.SelectPrev();
- e.Handled = true;
- break;
-
- case Key.Return
- or Key.Enter:
- vm.ExecuteSelected();
- e.Handled = true;
- break;
-
- case Key.Escape:
- vm.Close();
- e.Handled = true;
- break;
- }
- }
-
- private void OnResultPointerPressed(object? sender, PointerPressedEventArgs e)
- {
- if (DataContext is not CommandPaletteViewModel vm)
- return;
- if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
- return;
-
- PaletteCommandItem? item =
- (e.Source as Avalonia.LogicalTree.ILogical)
- ?.GetLogicalAncestors()
- .OfType()
- .Select(c => c.DataContext)
- .OfType()
- .FirstOrDefault()
- ?? (e.Source as Control)?.DataContext as PaletteCommandItem;
-
- if (item is null)
- return;
-
- int idx = vm.Results.IndexOf(item);
- if (idx >= 0)
- vm.SelectedIndex = idx;
- vm.ExecuteSelected();
- e.Handled = true;
- }
-
- private void FocusSearch()
- {
- TextBox? input = this.FindControl("SearchInput");
- input?.Focus();
- }
-}
+using System.ComponentModel;
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.LogicalTree;
+using Avalonia.Threading;
+using AkkornStudio.UI.ViewModels;
+
+namespace AkkornStudio.UI.Controls;
+
+public sealed partial class CommandPaletteControl : UserControl
+{
+ private CommandPaletteViewModel? _vm;
+
+ public CommandPaletteControl()
+ {
+ InitializeComponent();
+ DataContextChanged += (_, _) => BindViewModel();
+
+ ItemsControl? list = this.FindControl("ResultsList");
+ list?.AddHandler(
+ PointerPressedEvent,
+ OnResultPointerPressed,
+ Avalonia.Interactivity.RoutingStrategies.Bubble
+ );
+ }
+
+ private void BindViewModel()
+ {
+ if (_vm is not null)
+ _vm.PropertyChanged -= OnVmPropertyChanged;
+
+ _vm = DataContext as CommandPaletteViewModel;
+
+ if (_vm is not null)
+ _vm.PropertyChanged += OnVmPropertyChanged;
+ }
+
+ private void OnVmPropertyChanged(object? sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == nameof(CommandPaletteViewModel.IsVisible) && _vm?.IsVisible == true)
+ Dispatcher.UIThread.Post(FocusSearch, DispatcherPriority.Input);
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+ if (DataContext is not CommandPaletteViewModel vm)
+ return;
+
+ switch (e.Key)
+ {
+ case Key.Down:
+ vm.SelectNext();
+ e.Handled = true;
+ break;
+
+ case Key.Up:
+ vm.SelectPrev();
+ e.Handled = true;
+ break;
+
+ case Key.Return
+ or Key.Enter:
+ vm.ExecuteSelected();
+ e.Handled = true;
+ break;
+
+ case Key.Escape:
+ vm.Close();
+ e.Handled = true;
+ break;
+ }
+ }
+
+ private void OnResultPointerPressed(object? sender, PointerPressedEventArgs e)
+ {
+ if (DataContext is not CommandPaletteViewModel vm)
+ return;
+ if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
+ return;
+
+ PaletteCommandItem? item =
+ (e.Source as Avalonia.LogicalTree.ILogical)
+ ?.GetLogicalAncestors()
+ .OfType()
+ .Select(c => c.DataContext)
+ .OfType()
+ .FirstOrDefault()
+ ?? (e.Source as Control)?.DataContext as PaletteCommandItem;
+
+ if (item is null)
+ return;
+
+ int idx = vm.Results.IndexOf(item);
+ if (idx >= 0)
+ vm.SelectedIndex = idx;
+ vm.ExecuteSelected();
+ e.Handled = true;
+ }
+
+ private void FocusSearch()
+ {
+ TextBox? input = this.FindControl("SearchInput");
+ input?.Focus();
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml b/src/AkkornStudio.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml
similarity index 83%
rename from src/DBWeaver.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml
rename to src/AkkornStudio.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml
index c7824208..089e1757 100644
--- a/src/DBWeaver.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml
+++ b/src/AkkornStudio.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml
@@ -1,409 +1,362 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml.cs b/src/AkkornStudio.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml.cs
similarity index 94%
rename from src/DBWeaver.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml.cs
rename to src/AkkornStudio.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml.cs
index 6a0909cf..faa14ab3 100644
--- a/src/DBWeaver.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml.cs
+++ b/src/AkkornStudio.UI/Controls/ConnectionManager/ConnectionManagerControl.axaml.cs
@@ -1,99 +1,99 @@
-using System.Linq;
-using System.IO;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using Avalonia.Platform.Storage;
-using DBWeaver.UI.ViewModels;
-
-namespace DBWeaver.UI.Controls;
-
-public sealed partial class ConnectionManagerControl : UserControl
-{
- public ConnectionManagerControl()
- {
- InitializeComponent();
- }
-
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- if (e.Key == Key.Escape && DataContext is ConnectionManagerViewModel vm)
- {
- vm.CloseCommand.Execute(null);
- e.Handled = true;
- }
- }
-
- private async void BrowseSqliteFile_Click(object? sender, RoutedEventArgs e)
- {
- if (DataContext is not ConnectionManagerViewModel vm)
- return;
-
- TopLevel? topLevel = TopLevel.GetTopLevel(this);
- if (topLevel?.StorageProvider is null)
- return;
-
- var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
- {
- Title = "Select SQLite database",
- AllowMultiple = false,
- FileTypeFilter =
- [
- new FilePickerFileType("SQLite")
- {
- Patterns = ["*.sqlite", "*.sqlite3", "*.db", "*.db3"],
- },
- FilePickerFileTypes.All,
- ],
- });
-
- IStorageFile? selected = files.FirstOrDefault();
- if (selected is null)
- return;
-
- string? localPath = selected.TryGetLocalPath();
- vm.EditDatabase = string.IsNullOrWhiteSpace(localPath)
- ? selected.Path.LocalPath
- : localPath;
- }
-
- private async void CreateSqliteFile_Click(object? sender, RoutedEventArgs e)
- {
- if (DataContext is not ConnectionManagerViewModel vm)
- return;
-
- TopLevel? topLevel = TopLevel.GetTopLevel(this);
- if (topLevel?.StorageProvider is null)
- return;
-
- IStorageFile? file = await topLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
- {
- Title = "Create SQLite database",
- SuggestedFileName = "database.sqlite3",
- FileTypeChoices =
- [
- new FilePickerFileType("SQLite")
- {
- Patterns = ["*.sqlite", "*.sqlite3", "*.db", "*.db3"],
- },
- ],
- });
-
- if (file is null)
- return;
-
- string? localPath = file.TryGetLocalPath();
- string targetPath = string.IsNullOrWhiteSpace(localPath)
- ? file.Path.LocalPath
- : localPath;
-
- if (!string.IsNullOrWhiteSpace(targetPath) && !File.Exists(targetPath))
- {
- Directory.CreateDirectory(Path.GetDirectoryName(targetPath)!);
- File.WriteAllBytes(targetPath, []);
- }
-
- vm.EditDatabase = targetPath;
- }
-}
+using System.Linq;
+using System.IO;
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using Avalonia.Platform.Storage;
+using AkkornStudio.UI.ViewModels;
+
+namespace AkkornStudio.UI.Controls;
+
+public sealed partial class ConnectionManagerControl : UserControl
+{
+ public ConnectionManagerControl()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+ if (e.Key == Key.Escape && DataContext is ConnectionManagerViewModel vm)
+ {
+ vm.CloseCommand.Execute(null);
+ e.Handled = true;
+ }
+ }
+
+ private async void BrowseSqliteFile_Click(object? sender, RoutedEventArgs e)
+ {
+ if (DataContext is not ConnectionManagerViewModel vm)
+ return;
+
+ TopLevel? topLevel = TopLevel.GetTopLevel(this);
+ if (topLevel?.StorageProvider is null)
+ return;
+
+ var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
+ {
+ Title = "Select SQLite database",
+ AllowMultiple = false,
+ FileTypeFilter =
+ [
+ new FilePickerFileType("SQLite")
+ {
+ Patterns = ["*.sqlite", "*.sqlite3", "*.db", "*.db3"],
+ },
+ FilePickerFileTypes.All,
+ ],
+ });
+
+ IStorageFile? selected = files.FirstOrDefault();
+ if (selected is null)
+ return;
+
+ string? localPath = selected.TryGetLocalPath();
+ vm.EditDatabase = string.IsNullOrWhiteSpace(localPath)
+ ? selected.Path.LocalPath
+ : localPath;
+ }
+
+ private async void CreateSqliteFile_Click(object? sender, RoutedEventArgs e)
+ {
+ if (DataContext is not ConnectionManagerViewModel vm)
+ return;
+
+ TopLevel? topLevel = TopLevel.GetTopLevel(this);
+ if (topLevel?.StorageProvider is null)
+ return;
+
+ IStorageFile? file = await topLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
+ {
+ Title = "Create SQLite database",
+ SuggestedFileName = "database.sqlite3",
+ FileTypeChoices =
+ [
+ new FilePickerFileType("SQLite")
+ {
+ Patterns = ["*.sqlite", "*.sqlite3", "*.db", "*.db3"],
+ },
+ ],
+ });
+
+ if (file is null)
+ return;
+
+ string? localPath = file.TryGetLocalPath();
+ string targetPath = string.IsNullOrWhiteSpace(localPath)
+ ? file.Path.LocalPath
+ : localPath;
+
+ if (!string.IsNullOrWhiteSpace(targetPath) && !File.Exists(targetPath))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(targetPath)!);
+ File.WriteAllBytes(targetPath, []);
+ }
+
+ vm.EditDatabase = targetPath;
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/Ddl/DdlExecuteDialogWindow.cs b/src/AkkornStudio.UI/Controls/Ddl/DdlExecuteDialogWindow.cs
similarity index 96%
rename from src/DBWeaver.UI/Controls/Ddl/DdlExecuteDialogWindow.cs
rename to src/AkkornStudio.UI/Controls/Ddl/DdlExecuteDialogWindow.cs
index aaf02241..4fd743c5 100644
--- a/src/DBWeaver.UI/Controls/Ddl/DdlExecuteDialogWindow.cs
+++ b/src/AkkornStudio.UI/Controls/Ddl/DdlExecuteDialogWindow.cs
@@ -1,414 +1,414 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Controls.Primitives;
-using Avalonia.Controls.Templates;
-using Avalonia.Input;
-using Avalonia.Layout;
-using Avalonia.Media;
-using DBWeaver.Core;
-using DBWeaver.UI.Services.Localization;
-using DBWeaver.UI.ViewModels;
-using DBWeaver.UI.Services.Theming;
-
-namespace DBWeaver.UI.Controls.Ddl;
-
-public sealed class DdlExecuteDialogWindow : Window
-{
- private readonly DdlExecuteDialogViewModel _vm;
- private readonly Func> _executor;
- private Button? _runButton;
- private Button? _cancelButton;
- private CheckBox? _stopOnErrorCheck;
- private CheckBox? _confirmDestructiveCheck;
- private TextBox? _resultBox;
- private TextBlock? _summaryText;
- private CancellationTokenSource? _runCts;
-
- public DdlExecuteDialogWindow(
- DdlExecuteDialogViewModel vm,
- Func> executor)
- {
- _vm = vm;
- _executor = executor;
-
- Title = L("ddl.dialog.title", "Execute DDL");
- Width = 920;
- Height = 680;
- MinWidth = 740;
- MinHeight = 520;
- WindowStartupLocation = WindowStartupLocation.CenterOwner;
- SystemDecorations = SystemDecorations.None;
- ExtendClientAreaToDecorationsHint = true;
- ExtendClientAreaChromeHints = Avalonia.Platform.ExtendClientAreaChromeHints.NoChrome;
- ExtendClientAreaTitleBarHeightHint = -1;
- Background = new SolidColorBrush(Color.Parse(UiColorConstants.C_0D0F14));
-
- KeyDown += OnKeyDown;
- Content = BuildContent();
- }
-
- private Control BuildContent()
- {
- _runButton = new Button
- {
- Content = L("ddl.dialog.execute", "Execute"),
- Padding = new Thickness(12, 6),
- HorizontalAlignment = HorizontalAlignment.Right,
- MinWidth = 110,
- IsEnabled = _vm.CanExecute,
- };
- _runButton.Click += async (_, _) => await RunAsync();
-
- _cancelButton = new Button
- {
- Content = L("ddl.dialog.cancel", "Cancel"),
- Padding = new Thickness(12, 6),
- HorizontalAlignment = HorizontalAlignment.Right,
- MinWidth = 110,
- IsEnabled = false,
- };
- _cancelButton.Click += (_, _) => _runCts?.Cancel();
-
- Button closeButton = new()
- {
- Content = L("ddl.dialog.close", "Close"),
- Padding = new Thickness(12, 6),
- HorizontalAlignment = HorizontalAlignment.Right,
- MinWidth = 110,
- };
- closeButton.Click += (_, _) => Close();
-
- _stopOnErrorCheck = new CheckBox
- {
- Content = L("ddl.dialog.stopOnError", "Stop on first failure"),
- IsChecked = _vm.StopOnError,
- VerticalAlignment = VerticalAlignment.Center,
- };
- _stopOnErrorCheck.IsCheckedChanged += (_, _) => _vm.StopOnError = _stopOnErrorCheck.IsChecked ?? false;
-
- _confirmDestructiveCheck = new CheckBox
- {
- Content = L(
- "ddl.dialog.confirmDestructive",
- "I confirm execution of destructive statements (DROP TABLE)"
- ),
- IsVisible = _vm.HasDestructiveStatements,
- IsChecked = _vm.ConfirmDestructiveExecution,
- VerticalAlignment = VerticalAlignment.Center,
- Foreground = new SolidColorBrush(Color.Parse(UiColorConstants.C_FCA5A5)),
- };
- _confirmDestructiveCheck.IsCheckedChanged += (_, _) =>
- {
- _vm.ConfirmDestructiveExecution = _confirmDestructiveCheck.IsChecked ?? false;
- if (_runButton is not null)
- _runButton.IsEnabled = _vm.CanExecute;
- };
-
- TextBox sqlPreview = new()
- {
- Text = _vm.SqlPreview,
- IsReadOnly = true,
- AcceptsReturn = true,
- TextWrapping = TextWrapping.Wrap,
- FontFamily = new FontFamily("JetBrains Mono,IBM Plex Mono,Cascadia Code,Consolas,monospace"),
- MinHeight = 260,
- };
-
- _summaryText = new TextBlock
- {
- Text = L("ddl.dialog.reviewBeforeRun", "Review the DDL script before confirming."),
- Foreground = new SolidColorBrush(Color.Parse(UiColorConstants.C_C8D0DC)),
- FontSize = ResolveFontSize("FontSizeBody", 12),
- };
-
- ItemsControl statementList = new()
- {
- ItemsSource = _vm.StatementPreviews,
- ItemTemplate = new FuncDataTemplate((item, _) =>
- new TextBlock
- {
- Text = item.CompactSql,
- FontFamily = new FontFamily("JetBrains Mono,IBM Plex Mono,Cascadia Code,Consolas,monospace"),
- FontSize = ResolveFontSize("FontSizeCaption", 11),
- Margin = new Thickness(0, 1, 0, 1),
- Foreground = item.IsDestructive
- ? new SolidColorBrush(Color.Parse(UiColorConstants.C_FCA5A5))
- : new SolidColorBrush(Color.Parse(UiColorConstants.C_9CA3AF)),
- }
- ),
- Margin = new Thickness(0, 6, 0, 0),
- };
-
- Border statementListHost = new()
- {
- BorderBrush = new SolidColorBrush(Color.Parse(UiColorConstants.C_1F2937)),
- BorderThickness = new Thickness(1),
- CornerRadius = new CornerRadius(6),
- Padding = new Thickness(8),
- MaxHeight = 120,
- Child = new ScrollViewer
- {
- Content = statementList,
- VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
- HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
- },
- };
-
- Button headerCloseButton = new()
- {
- Content = "×",
- Padding = new Thickness(8, 4),
- MinWidth = 32,
- };
- headerCloseButton.Click += (_, _) => Close();
-
- _resultBox = new TextBox
- {
- IsReadOnly = true,
- AcceptsReturn = true,
- TextWrapping = TextWrapping.Wrap,
- FontFamily = new FontFamily("JetBrains Mono,IBM Plex Mono,Cascadia Code,Consolas,monospace"),
- MinHeight = 200,
- };
-
- return new Border
- {
- Background = new SolidColorBrush(Color.Parse(UiColorConstants.C_070A12)),
- Child = new Grid
- {
- RowDefinitions = new RowDefinitions("Auto,*,Auto"),
- Children =
- {
- new Border
- {
- Background = ResolveBrush("Bg1Brush", UiColorConstants.C_0F1220),
- BorderBrush = ResolveBrush("BorderSubtleBrush", UiColorConstants.C_1E2A3F),
- BorderThickness = new Thickness(0, 0, 0, 1),
- Padding = new Thickness(16, 12),
- Child = new Grid
- {
- ColumnDefinitions = new ColumnDefinitions("Auto,*,Auto"),
- Children =
- {
- new Border
- {
- Width = 28,
- Height = 28,
- CornerRadius = ResolveCornerRadius("RadiusSM", 6),
- Background = ResolveBrush("BtnWarningBgBrush", UiColorConstants.C_10291A),
- BorderBrush = ResolveBrush("StatusWarningBrush", UiColorConstants.C_FBBF24),
- BorderThickness = new Thickness(1),
- Child = new TextBlock
- {
- Text = "!",
- FontWeight = ResolveFontWeight("FontWeightTitle", FontWeight.SemiBold),
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center,
- Foreground = ResolveBrush("StatusWarningBrush", UiColorConstants.C_FBBF24),
- },
- },
- PlaceAtCol(new StackPanel
- {
- Margin = new Thickness(10, 0, 0, 0),
- Spacing = 2,
- Children =
- {
- new TextBlock
- {
- Text = L("ddl.dialog.title", "Execute DDL"),
- FontSize = ResolveFontSize("FontSizeNodeTitle", 14),
- FontWeight = ResolveFontWeight("FontWeightTitle", FontWeight.SemiBold),
- Foreground = ResolveBrush("TextPrimaryBrush", UiColorConstants.C_E8EAED),
- },
- new TextBlock
- {
- Text = L("ddl.dialog.subtitle", "Review and execute DDL changes safely"),
- FontSize = ResolveFontSize("FontSizeCaption", 11),
- Foreground = ResolveBrush("TextMutedBrush", UiColorConstants.C_9CA3AF),
- },
- },
- }, 1),
- PlaceAtCol(headerCloseButton, 2),
- },
- },
- },
- PlaceAtRow(new ScrollViewer
- {
- VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
- HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
- Content = new Border
- {
- Padding = new Thickness(16, 12),
- Child = new StackPanel
- {
- Spacing = 10,
- Children =
- {
- new TextBlock
- {
- Text = L("ddl.dialog.confirmQuestion", "Confirm DDL execution on the connected database?"),
- FontSize = ResolveFontSize("FontSizeHeading", 18),
- FontWeight = ResolveFontWeight("FontWeightTitle", FontWeight.SemiBold),
- Foreground = new SolidColorBrush(Color.Parse(UiColorConstants.C_E8EAED)),
- },
- new TextBlock
- {
- Text = L("ddl.dialog.irreversibleWarning", "This action can change the schema irreversibly."),
- Foreground = new SolidColorBrush(Color.Parse(UiColorConstants.C_FBBF24)),
- FontSize = ResolveFontSize("FontSizeBody", 12),
- },
- sqlPreview,
- _summaryText,
- statementListHost,
- _resultBox,
- },
- },
- },
- }, 1),
- PlaceAtRow(new Border
- {
- Background = ResolveBrush("Bg1Brush", UiColorConstants.C_0F1220),
- BorderBrush = ResolveBrush("BorderSubtleBrush", UiColorConstants.C_1E2A3F),
- BorderThickness = new Thickness(0, 1, 0, 0),
- Padding = new Thickness(16, 10),
- Child = new Grid
- {
- ColumnDefinitions = new ColumnDefinitions("*,Auto,Auto,Auto"),
- Children =
- {
- new StackPanel
- {
- Spacing = 4,
- Children =
- {
- _stopOnErrorCheck,
- _confirmDestructiveCheck,
- },
- },
- PlaceAtCol(_runButton, 1),
- PlaceAtCol(_cancelButton, 2),
- PlaceAtCol(closeButton, 3),
- },
- },
- }, 2),
- },
- },
- };
- }
-
- private static Control PlaceAtRow(Control control, int row)
- {
- Grid.SetRow(control, row);
- return control;
- }
-
- private static Control PlaceAtCol(Control control, int col)
- {
- Grid.SetColumn(control, col);
- return control;
- }
-
- private async Task RunAsync()
- {
- if (_runButton is null || _cancelButton is null || _stopOnErrorCheck is null || _resultBox is null || _summaryText is null || _confirmDestructiveCheck is null)
- return;
-
- if (_vm.HasDestructiveStatements && !_vm.ConfirmDestructiveExecution)
- {
- _summaryText.Text = L("ddl.dialog.mustConfirmDestructive", "Confirm destructive execution to continue.");
- return;
- }
-
- _vm.IsExecuting = true;
- _runButton.IsEnabled = false;
- _cancelButton.IsEnabled = true;
- _stopOnErrorCheck.IsEnabled = false;
- _confirmDestructiveCheck.IsEnabled = false;
- _summaryText.Text = L("ddl.dialog.executing", "Executing...");
- _runCts = new CancellationTokenSource();
-
- try
- {
- DdlExecutionResult result = await _executor(_vm.StopOnError, _runCts.Token);
- _vm.ApplyResult(result);
- }
- catch (OperationCanceledException)
- {
- _vm.ApplyCancelled();
- }
- catch (Exception ex)
- {
- _vm.ApplyError(ex);
- }
- finally
- {
- _runCts?.Dispose();
- _runCts = null;
- _vm.IsExecuting = false;
- _runButton.IsEnabled = _vm.CanExecute;
- _cancelButton.IsEnabled = false;
- _stopOnErrorCheck.IsEnabled = true;
- _confirmDestructiveCheck.IsEnabled = true;
- _summaryText.Text = _vm.ResultSummary;
- _resultBox.Text = _vm.ResultDetails;
- }
- }
-
- private void OnKeyDown(object? sender, KeyEventArgs e)
- {
- if (e.Key != Key.Escape)
- return;
-
- if (_vm.IsExecuting)
- _runCts?.Cancel();
- else
- Close();
- e.Handled = true;
- }
-
- private static string L(string key, string fallback)
- {
- string value = LocalizationService.Instance[key];
- return string.Equals(value, key, StringComparison.Ordinal) ? fallback : value;
- }
-
- private static IBrush ResolveBrush(string key, string fallbackHex)
- {
- if (Application.Current?.TryFindResource(key, out object? resource) == true && resource is IBrush brush)
- return brush;
-
- return new SolidColorBrush(Color.Parse(fallbackHex));
- }
-
- private static CornerRadius ResolveCornerRadius(string key, double fallbackValue)
- {
- if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true && resource is CornerRadius radius)
- return radius;
-
- return new CornerRadius(fallbackValue);
- }
-
- private static double ResolveFontSize(string key, double fallback)
- {
- if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true)
- {
- if (resource is double size)
- return size;
- if (resource is int intSize)
- return intSize;
- }
-
- return fallback;
- }
-
- private static FontWeight ResolveFontWeight(string key, FontWeight fallback)
- {
- if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true
- && resource is FontWeight fontWeight)
- {
- return fontWeight;
- }
-
- return fallback;
- }
-}
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.Controls.Templates;
+using Avalonia.Input;
+using Avalonia.Layout;
+using Avalonia.Media;
+using AkkornStudio.Core;
+using AkkornStudio.UI.Services.Localization;
+using AkkornStudio.UI.ViewModels;
+using AkkornStudio.UI.Services.Theming;
+
+namespace AkkornStudio.UI.Controls.Ddl;
+
+public sealed class DdlExecuteDialogWindow : Window
+{
+ private readonly DdlExecuteDialogViewModel _vm;
+ private readonly Func> _executor;
+ private Button? _runButton;
+ private Button? _cancelButton;
+ private CheckBox? _stopOnErrorCheck;
+ private CheckBox? _confirmDestructiveCheck;
+ private TextBox? _resultBox;
+ private TextBlock? _summaryText;
+ private CancellationTokenSource? _runCts;
+
+ public DdlExecuteDialogWindow(
+ DdlExecuteDialogViewModel vm,
+ Func> executor)
+ {
+ _vm = vm;
+ _executor = executor;
+
+ Title = L("ddl.dialog.title", "Execute DDL");
+ Width = 920;
+ Height = 680;
+ MinWidth = 740;
+ MinHeight = 520;
+ WindowStartupLocation = WindowStartupLocation.CenterOwner;
+ SystemDecorations = SystemDecorations.None;
+ ExtendClientAreaToDecorationsHint = true;
+ ExtendClientAreaChromeHints = Avalonia.Platform.ExtendClientAreaChromeHints.NoChrome;
+ ExtendClientAreaTitleBarHeightHint = -1;
+ Background = new SolidColorBrush(Color.Parse(UiColorConstants.C_0D0F14));
+
+ KeyDown += OnKeyDown;
+ Content = BuildContent();
+ }
+
+ private Control BuildContent()
+ {
+ _runButton = new Button
+ {
+ Content = L("ddl.dialog.execute", "Execute"),
+ Padding = new Thickness(12, 6),
+ HorizontalAlignment = HorizontalAlignment.Right,
+ MinWidth = 110,
+ IsEnabled = _vm.CanExecute,
+ };
+ _runButton.Click += async (_, _) => await RunAsync();
+
+ _cancelButton = new Button
+ {
+ Content = L("ddl.dialog.cancel", "Cancel"),
+ Padding = new Thickness(12, 6),
+ HorizontalAlignment = HorizontalAlignment.Right,
+ MinWidth = 110,
+ IsEnabled = false,
+ };
+ _cancelButton.Click += (_, _) => _runCts?.Cancel();
+
+ Button closeButton = new()
+ {
+ Content = L("ddl.dialog.close", "Close"),
+ Padding = new Thickness(12, 6),
+ HorizontalAlignment = HorizontalAlignment.Right,
+ MinWidth = 110,
+ };
+ closeButton.Click += (_, _) => Close();
+
+ _stopOnErrorCheck = new CheckBox
+ {
+ Content = L("ddl.dialog.stopOnError", "Stop on first failure"),
+ IsChecked = _vm.StopOnError,
+ VerticalAlignment = VerticalAlignment.Center,
+ };
+ _stopOnErrorCheck.IsCheckedChanged += (_, _) => _vm.StopOnError = _stopOnErrorCheck.IsChecked ?? false;
+
+ _confirmDestructiveCheck = new CheckBox
+ {
+ Content = L(
+ "ddl.dialog.confirmDestructive",
+ "I confirm execution of destructive statements (DROP TABLE)"
+ ),
+ IsVisible = _vm.HasDestructiveStatements,
+ IsChecked = _vm.ConfirmDestructiveExecution,
+ VerticalAlignment = VerticalAlignment.Center,
+ Foreground = new SolidColorBrush(Color.Parse(UiColorConstants.C_FCA5A5)),
+ };
+ _confirmDestructiveCheck.IsCheckedChanged += (_, _) =>
+ {
+ _vm.ConfirmDestructiveExecution = _confirmDestructiveCheck.IsChecked ?? false;
+ if (_runButton is not null)
+ _runButton.IsEnabled = _vm.CanExecute;
+ };
+
+ TextBox sqlPreview = new()
+ {
+ Text = _vm.SqlPreview,
+ IsReadOnly = true,
+ AcceptsReturn = true,
+ TextWrapping = TextWrapping.Wrap,
+ FontFamily = new FontFamily("JetBrains Mono,IBM Plex Mono,Cascadia Code,Consolas,monospace"),
+ MinHeight = 260,
+ };
+
+ _summaryText = new TextBlock
+ {
+ Text = L("ddl.dialog.reviewBeforeRun", "Review the DDL script before confirming."),
+ Foreground = new SolidColorBrush(Color.Parse(UiColorConstants.C_C8D0DC)),
+ FontSize = ResolveFontSize("FontSizeBody", 12),
+ };
+
+ ItemsControl statementList = new()
+ {
+ ItemsSource = _vm.StatementPreviews,
+ ItemTemplate = new FuncDataTemplate((item, _) =>
+ new TextBlock
+ {
+ Text = item.CompactSql,
+ FontFamily = new FontFamily("JetBrains Mono,IBM Plex Mono,Cascadia Code,Consolas,monospace"),
+ FontSize = ResolveFontSize("FontSizeCaption", 11),
+ Margin = new Thickness(0, 1, 0, 1),
+ Foreground = item.IsDestructive
+ ? new SolidColorBrush(Color.Parse(UiColorConstants.C_FCA5A5))
+ : new SolidColorBrush(Color.Parse(UiColorConstants.C_9CA3AF)),
+ }
+ ),
+ Margin = new Thickness(0, 6, 0, 0),
+ };
+
+ Border statementListHost = new()
+ {
+ BorderBrush = new SolidColorBrush(Color.Parse(UiColorConstants.C_1F2937)),
+ BorderThickness = new Thickness(1),
+ CornerRadius = new CornerRadius(6),
+ Padding = new Thickness(8),
+ MaxHeight = 120,
+ Child = new ScrollViewer
+ {
+ Content = statementList,
+ VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
+ HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
+ },
+ };
+
+ Button headerCloseButton = new()
+ {
+ Content = "×",
+ Padding = new Thickness(8, 4),
+ MinWidth = 32,
+ };
+ headerCloseButton.Click += (_, _) => Close();
+
+ _resultBox = new TextBox
+ {
+ IsReadOnly = true,
+ AcceptsReturn = true,
+ TextWrapping = TextWrapping.Wrap,
+ FontFamily = new FontFamily("JetBrains Mono,IBM Plex Mono,Cascadia Code,Consolas,monospace"),
+ MinHeight = 200,
+ };
+
+ return new Border
+ {
+ Background = new SolidColorBrush(Color.Parse(UiColorConstants.C_070A12)),
+ Child = new Grid
+ {
+ RowDefinitions = new RowDefinitions("Auto,*,Auto"),
+ Children =
+ {
+ new Border
+ {
+ Background = ResolveBrush("Bg1Brush", UiColorConstants.C_0F1220),
+ BorderBrush = ResolveBrush("BorderSubtleBrush", UiColorConstants.C_1E2A3F),
+ BorderThickness = new Thickness(0, 0, 0, 1),
+ Padding = new Thickness(16, 12),
+ Child = new Grid
+ {
+ ColumnDefinitions = new ColumnDefinitions("Auto,*,Auto"),
+ Children =
+ {
+ new Border
+ {
+ Width = 28,
+ Height = 28,
+ CornerRadius = ResolveCornerRadius("RadiusSM", 6),
+ Background = ResolveBrush("BtnWarningBgBrush", UiColorConstants.C_10291A),
+ BorderBrush = ResolveBrush("StatusWarningBrush", UiColorConstants.C_FBBF24),
+ BorderThickness = new Thickness(1),
+ Child = new TextBlock
+ {
+ Text = "!",
+ FontWeight = ResolveFontWeight("FontWeightTitle", FontWeight.SemiBold),
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center,
+ Foreground = ResolveBrush("StatusWarningBrush", UiColorConstants.C_FBBF24),
+ },
+ },
+ PlaceAtCol(new StackPanel
+ {
+ Margin = new Thickness(10, 0, 0, 0),
+ Spacing = 2,
+ Children =
+ {
+ new TextBlock
+ {
+ Text = L("ddl.dialog.title", "Execute DDL"),
+ FontSize = ResolveFontSize("FontSizeNodeTitle", 14),
+ FontWeight = ResolveFontWeight("FontWeightTitle", FontWeight.SemiBold),
+ Foreground = ResolveBrush("TextPrimaryBrush", UiColorConstants.C_E8EAED),
+ },
+ new TextBlock
+ {
+ Text = L("ddl.dialog.subtitle", "Review and execute DDL changes safely"),
+ FontSize = ResolveFontSize("FontSizeCaption", 11),
+ Foreground = ResolveBrush("TextMutedBrush", UiColorConstants.C_9CA3AF),
+ },
+ },
+ }, 1),
+ PlaceAtCol(headerCloseButton, 2),
+ },
+ },
+ },
+ PlaceAtRow(new ScrollViewer
+ {
+ VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
+ HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
+ Content = new Border
+ {
+ Padding = new Thickness(16, 12),
+ Child = new StackPanel
+ {
+ Spacing = 10,
+ Children =
+ {
+ new TextBlock
+ {
+ Text = L("ddl.dialog.confirmQuestion", "Confirm DDL execution on the connected database?"),
+ FontSize = ResolveFontSize("FontSizeHeading", 18),
+ FontWeight = ResolveFontWeight("FontWeightTitle", FontWeight.SemiBold),
+ Foreground = new SolidColorBrush(Color.Parse(UiColorConstants.C_E8EAED)),
+ },
+ new TextBlock
+ {
+ Text = L("ddl.dialog.irreversibleWarning", "This action can change the schema irreversibly."),
+ Foreground = new SolidColorBrush(Color.Parse(UiColorConstants.C_FBBF24)),
+ FontSize = ResolveFontSize("FontSizeBody", 12),
+ },
+ sqlPreview,
+ _summaryText,
+ statementListHost,
+ _resultBox,
+ },
+ },
+ },
+ }, 1),
+ PlaceAtRow(new Border
+ {
+ Background = ResolveBrush("Bg1Brush", UiColorConstants.C_0F1220),
+ BorderBrush = ResolveBrush("BorderSubtleBrush", UiColorConstants.C_1E2A3F),
+ BorderThickness = new Thickness(0, 1, 0, 0),
+ Padding = new Thickness(16, 10),
+ Child = new Grid
+ {
+ ColumnDefinitions = new ColumnDefinitions("*,Auto,Auto,Auto"),
+ Children =
+ {
+ new StackPanel
+ {
+ Spacing = 4,
+ Children =
+ {
+ _stopOnErrorCheck,
+ _confirmDestructiveCheck,
+ },
+ },
+ PlaceAtCol(_runButton, 1),
+ PlaceAtCol(_cancelButton, 2),
+ PlaceAtCol(closeButton, 3),
+ },
+ },
+ }, 2),
+ },
+ },
+ };
+ }
+
+ private static Control PlaceAtRow(Control control, int row)
+ {
+ Grid.SetRow(control, row);
+ return control;
+ }
+
+ private static Control PlaceAtCol(Control control, int col)
+ {
+ Grid.SetColumn(control, col);
+ return control;
+ }
+
+ private async Task RunAsync()
+ {
+ if (_runButton is null || _cancelButton is null || _stopOnErrorCheck is null || _resultBox is null || _summaryText is null || _confirmDestructiveCheck is null)
+ return;
+
+ if (_vm.HasDestructiveStatements && !_vm.ConfirmDestructiveExecution)
+ {
+ _summaryText.Text = L("ddl.dialog.mustConfirmDestructive", "Confirm destructive execution to continue.");
+ return;
+ }
+
+ _vm.IsExecuting = true;
+ _runButton.IsEnabled = false;
+ _cancelButton.IsEnabled = true;
+ _stopOnErrorCheck.IsEnabled = false;
+ _confirmDestructiveCheck.IsEnabled = false;
+ _summaryText.Text = L("ddl.dialog.executing", "Executing...");
+ _runCts = new CancellationTokenSource();
+
+ try
+ {
+ DdlExecutionResult result = await _executor(_vm.StopOnError, _runCts.Token);
+ _vm.ApplyResult(result);
+ }
+ catch (OperationCanceledException)
+ {
+ _vm.ApplyCancelled();
+ }
+ catch (Exception ex)
+ {
+ _vm.ApplyError(ex);
+ }
+ finally
+ {
+ _runCts?.Dispose();
+ _runCts = null;
+ _vm.IsExecuting = false;
+ _runButton.IsEnabled = _vm.CanExecute;
+ _cancelButton.IsEnabled = false;
+ _stopOnErrorCheck.IsEnabled = true;
+ _confirmDestructiveCheck.IsEnabled = true;
+ _summaryText.Text = _vm.ResultSummary;
+ _resultBox.Text = _vm.ResultDetails;
+ }
+ }
+
+ private void OnKeyDown(object? sender, KeyEventArgs e)
+ {
+ if (e.Key != Key.Escape)
+ return;
+
+ if (_vm.IsExecuting)
+ _runCts?.Cancel();
+ else
+ Close();
+ e.Handled = true;
+ }
+
+ private static string L(string key, string fallback)
+ {
+ string value = LocalizationService.Instance[key];
+ return string.Equals(value, key, StringComparison.Ordinal) ? fallback : value;
+ }
+
+ private static IBrush ResolveBrush(string key, string fallbackHex)
+ {
+ if (Application.Current?.TryFindResource(key, out object? resource) == true && resource is IBrush brush)
+ return brush;
+
+ return new SolidColorBrush(Color.Parse(fallbackHex));
+ }
+
+ private static CornerRadius ResolveCornerRadius(string key, double fallbackValue)
+ {
+ if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true && resource is CornerRadius radius)
+ return radius;
+
+ return new CornerRadius(fallbackValue);
+ }
+
+ private static double ResolveFontSize(string key, double fallback)
+ {
+ if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true)
+ {
+ if (resource is double size)
+ return size;
+ if (resource is int intSize)
+ return intSize;
+ }
+
+ return fallback;
+ }
+
+ private static FontWeight ResolveFontWeight(string key, FontWeight fallback)
+ {
+ if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true
+ && resource is FontWeight fontWeight)
+ {
+ return fontWeight;
+ }
+
+ return fallback;
+ }
+}
diff --git a/src/AkkornStudio.UI/Controls/DragDrop/CanvasDragDropDataFormats.cs b/src/AkkornStudio.UI/Controls/DragDrop/CanvasDragDropDataFormats.cs
new file mode 100644
index 00000000..9544763f
--- /dev/null
+++ b/src/AkkornStudio.UI/Controls/DragDrop/CanvasDragDropDataFormats.cs
@@ -0,0 +1,7 @@
+namespace AkkornStudio.UI.Controls.DragDrop;
+
+public static class CanvasDragDropDataFormats
+{
+ public const string NodeType = "akkornstudio/node-type";
+ public const string SchemaTableFullName = "akkornstudio/schema-table-full-name";
+}
diff --git a/src/AkkornStudio.UI/Controls/ErDiagram/ErCanvasControl.axaml b/src/AkkornStudio.UI/Controls/ErDiagram/ErCanvasControl.axaml
new file mode 100644
index 00000000..814bbeb3
--- /dev/null
+++ b/src/AkkornStudio.UI/Controls/ErDiagram/ErCanvasControl.axaml
@@ -0,0 +1,203 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AkkornStudio.UI/Controls/ErDiagram/ErCanvasControl.axaml.cs b/src/AkkornStudio.UI/Controls/ErDiagram/ErCanvasControl.axaml.cs
new file mode 100644
index 00000000..b57613a2
--- /dev/null
+++ b/src/AkkornStudio.UI/Controls/ErDiagram/ErCanvasControl.axaml.cs
@@ -0,0 +1,246 @@
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using Avalonia.Threading;
+using Avalonia;
+using AkkornStudio.UI.ViewModels.ErDiagram;
+using System.ComponentModel;
+using AkkornStudio.UI.Controls;
+
+namespace AkkornStudio.UI.Controls.ErDiagram;
+
+public sealed partial class ErCanvasControl : UserControl
+{
+ private readonly CanvasViewportInteractionHost _interactionHost =
+ new(CanvasViewportGesturePolicy.ErCanvasDefault);
+ private readonly CanvasViewportSelectionAdornerController _selectionAdornerController = new();
+ private readonly CanvasViewportSelectionNavigationController _selectionNavigationController = new();
+ private readonly CanvasViewportGesturePolicy _gesturePolicy = CanvasViewportGesturePolicy.ErCanvasDefault;
+ private ErCanvasViewModel? _observedCanvas;
+
+ public ErCanvasControl()
+ {
+ InitializeComponent();
+ DataContextChanged += OnDataContextChanged;
+ LayoutUpdated += (_, _) => UpdateViewportState();
+ }
+
+ private void Edge_PointerPressed(object? sender, PointerPressedEventArgs e)
+ {
+ if (DataContext is not ErCanvasViewModel canvas)
+ return;
+
+ PointerPointProperties pointerProperties = e.GetCurrentPoint(this).Properties;
+ bool isPanGesture = CanvasViewportGestureDecisions.IsPanGesture(
+ _gesturePolicy,
+ pointerProperties,
+ e.KeyModifiers);
+ if (isPanGesture)
+ return;
+
+ if (sender is not Control control || control.DataContext is not ErRelationEdgeViewModel edge)
+ return;
+
+ canvas.SelectedEdge = edge;
+ e.Handled = true;
+ }
+
+ private void CanvasBackground_PointerPressed(object? sender, PointerPressedEventArgs e)
+ {
+ if (e.Source is not Canvas)
+ return;
+
+ PointerPointProperties pointerProperties = e.GetCurrentPoint(this).Properties;
+ bool isPanGesture = CanvasViewportGestureDecisions.IsPanGesture(
+ _gesturePolicy,
+ pointerProperties,
+ e.KeyModifiers);
+ if (isPanGesture)
+ return;
+
+ // Deixa o evento subir para o ViewportSurface decidir entre pan/marquee.
+ }
+
+ private void OnDataContextChanged(object? sender, EventArgs e)
+ {
+ if (_observedCanvas is not null)
+ _observedCanvas.PropertyChanged -= OnCanvasPropertyChanged;
+
+ _observedCanvas = DataContext as ErCanvasViewModel;
+
+ Canvas? sceneContentCanvas = this.FindControl("SceneContentCanvas");
+ if (sceneContentCanvas is not null)
+ sceneContentCanvas.DataContext = _observedCanvas;
+
+ Canvas? overlayCanvas = this.FindControl("SelectionMarquee")?.Parent as Canvas;
+ if (overlayCanvas is not null)
+ overlayCanvas.DataContext = _observedCanvas;
+
+ ItemsControl? edgeItems = this.FindControl("EdgeItems");
+ if (edgeItems is not null)
+ edgeItems.ItemsSource = _observedCanvas?.Edges;
+
+ ItemsControl? entityItems = this.FindControl("EntityItems");
+ if (entityItems is not null)
+ entityItems.ItemsSource = _observedCanvas?.Entities;
+
+ if (_observedCanvas is not null)
+ _observedCanvas.PropertyChanged += OnCanvasPropertyChanged;
+
+ SyncTransform();
+ }
+
+ private void OnCanvasPropertyChanged(object? sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == nameof(ErCanvasViewModel.FocusRequestVersion))
+ {
+ Dispatcher.UIThread.Post(CenterViewportOnFocusTarget, DispatcherPriority.Background);
+ return;
+ }
+
+ if (e.PropertyName is nameof(ErCanvasViewModel.Zoom)
+ or nameof(ErCanvasViewModel.ViewportX)
+ or nameof(ErCanvasViewModel.ViewportY)
+ or nameof(ErCanvasViewModel.SelectedEntity)
+ or nameof(ErCanvasViewModel.SelectedEdge))
+ {
+ SyncTransform();
+ }
+ }
+
+ private void CenterViewportOnFocusTarget()
+ {
+ if (_observedCanvas is null)
+ return;
+
+ UpdateViewportState();
+ if (!_selectionNavigationController.TryCenterSelection(_observedCanvas, Bounds.Size))
+ _observedCanvas.CenterViewportOnCanvasPoint(_observedCanvas.FocusTargetX, _observedCanvas.FocusTargetY);
+ SyncTransform();
+ }
+
+ private void CenterSelection_Click(object? sender, RoutedEventArgs e)
+ {
+ if (_observedCanvas is null)
+ return;
+
+ UpdateViewportState();
+ if (_selectionNavigationController.TryCenterSelection(_observedCanvas, Bounds.Size))
+ SyncTransform();
+ }
+
+ private void FitSelection_Click(object? sender, RoutedEventArgs e)
+ {
+ if (_observedCanvas is null)
+ return;
+
+ UpdateViewportState();
+ if (_selectionNavigationController.TryFitSelection(
+ _observedCanvas,
+ Bounds.Size,
+ padding: 40,
+ minZoom: 0.15,
+ maxZoom: 2.0))
+ {
+ SyncTransform();
+ }
+ }
+
+ private void Viewport_PointerWheelChanged(object? sender, PointerWheelEventArgs e)
+ {
+ if (_observedCanvas is null || sender is not InfiniteCanvasCoreControl viewportHost)
+ return;
+
+ _interactionHost.HandlePointerWheel(_observedCanvas, viewportHost.ViewportSurface, e);
+ viewportHost.SyncViewport();
+ }
+
+ private void Viewport_PointerPressed(object? sender, PointerPressedEventArgs e)
+ {
+ if (_observedCanvas is null || sender is not InfiniteCanvasCoreControl viewportHost)
+ return;
+
+ PointerPointProperties props = e.GetCurrentPoint(viewportHost.ViewportSurface).Properties;
+ bool isPanGesture = CanvasViewportGestureDecisions.IsPanGesture(_gesturePolicy, props, e.KeyModifiers);
+ if (!isPanGesture && !props.IsLeftButtonPressed)
+ return;
+
+ if (_interactionHost.HandlePointerPressed(_observedCanvas, viewportHost.ViewportSurface, e))
+ UpdateMarqueeVisual();
+ }
+
+ private void Viewport_PointerMoved(object? sender, PointerEventArgs e)
+ {
+ if (_observedCanvas is null || sender is not InfiniteCanvasCoreControl viewportHost)
+ return;
+
+ if (!_interactionHost.HandlePointerMoved(_observedCanvas, viewportHost.ViewportSurface, e, out bool marqueeChanged))
+ return;
+
+ if (marqueeChanged)
+ {
+ UpdateMarqueeVisual();
+ return;
+ }
+
+ viewportHost.SyncViewport();
+ }
+
+ private void Viewport_PointerReleased(object? sender, PointerReleasedEventArgs e)
+ {
+ CanvasViewportPointerReleaseKind releaseKind = _interactionHost.HandlePointerReleased(e);
+ if (releaseKind == CanvasViewportPointerReleaseKind.PanEnded)
+ return;
+
+ if (releaseKind != CanvasViewportPointerReleaseKind.MarqueeCompleted
+ || _observedCanvas is null
+ || sender is not InfiniteCanvasCoreControl viewportHost)
+ return;
+
+ CanvasMarqueeAdorner? marquee = this.FindControl("SelectionMarquee");
+ _selectionAdornerController.CompleteMarqueeSelection(_observedCanvas, _interactionHost, marquee);
+ viewportHost.SyncViewport();
+ }
+
+ private void UpdateViewportState()
+ {
+ if (_observedCanvas is null)
+ return;
+
+ InfiniteCanvasCoreControl? viewportHost = this.FindControl("ViewportSurface");
+ if (viewportHost is null)
+ return;
+
+ _observedCanvas.SetViewportSize(viewportHost.Bounds.Width, viewportHost.Bounds.Height);
+ viewportHost.SyncViewport();
+ }
+
+ private void SyncTransform()
+ {
+ this.FindControl("ViewportSurface")?.SyncViewport();
+ UpdateFocusAdorner();
+ UpdateMarqueeVisual();
+ }
+
+ private void UpdateFocusAdorner()
+ {
+ if (_observedCanvas is null)
+ return;
+
+ CanvasFocusAdorner? adorner = this.FindControl("FocusOverlay");
+ _selectionAdornerController.SyncFocusAdorner(_observedCanvas, adorner, padding: 12);
+ }
+
+ private void UpdateMarqueeVisual()
+ {
+ CanvasMarqueeAdorner? marquee = this.FindControl("SelectionMarquee");
+ if (_observedCanvas is null)
+ {
+ if (marquee is not null)
+ marquee.SelectionRect = default;
+ return;
+ }
+
+ _selectionAdornerController.SyncMarqueeAdorner(_observedCanvas, _interactionHost, marquee);
+ }
+}
diff --git a/src/AkkornStudio.UI/Controls/ErDiagram/ErEntityControl.axaml b/src/AkkornStudio.UI/Controls/ErDiagram/ErEntityControl.axaml
new file mode 100644
index 00000000..6a410c3a
--- /dev/null
+++ b/src/AkkornStudio.UI/Controls/ErDiagram/ErEntityControl.axaml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AkkornStudio.UI/Controls/ErDiagram/ErEntityControl.axaml.cs b/src/AkkornStudio.UI/Controls/ErDiagram/ErEntityControl.axaml.cs
new file mode 100644
index 00000000..3bb3614b
--- /dev/null
+++ b/src/AkkornStudio.UI/Controls/ErDiagram/ErEntityControl.axaml.cs
@@ -0,0 +1,40 @@
+using Avalonia.Input;
+using Avalonia.VisualTree;
+using Avalonia.Controls;
+using AkkornStudio.UI.ViewModels.ErDiagram;
+
+namespace AkkornStudio.UI.Controls.ErDiagram;
+
+public sealed partial class ErEntityControl : UserControl
+{
+ private static readonly CanvasViewportGesturePolicy GesturePolicy = CanvasViewportGesturePolicy.ErCanvasDefault;
+
+ public ErEntityControl()
+ {
+ InitializeComponent();
+ }
+
+ private void Root_PointerPressed(object? sender, PointerPressedEventArgs e)
+ {
+ PointerPointProperties pointerProperties = e.GetCurrentPoint(this).Properties;
+ bool isPanGesture = CanvasViewportGestureDecisions.IsPanGesture(
+ GesturePolicy,
+ pointerProperties,
+ e.KeyModifiers);
+ if (isPanGesture)
+ return;
+
+ if (DataContext is not ErEntityNodeViewModel entity)
+ return;
+
+ ErCanvasControl? canvasControl = this.FindAncestorOfType();
+ if (canvasControl is null)
+ return;
+
+ if (canvasControl.DataContext is not ErCanvasViewModel canvas)
+ return;
+
+ canvas.SelectedEntity = entity;
+ e.Handled = true;
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml b/src/AkkornStudio.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml
similarity index 95%
rename from src/DBWeaver.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml
rename to src/AkkornStudio.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml
index afbe5be4..d4984ac9 100644
--- a/src/DBWeaver.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml
+++ b/src/AkkornStudio.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml
@@ -1,695 +1,680 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml.cs b/src/AkkornStudio.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml.cs
similarity index 95%
rename from src/DBWeaver.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml.cs
rename to src/AkkornStudio.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml.cs
index 7fe0dcbf..8adc2487 100644
--- a/src/DBWeaver.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml.cs
+++ b/src/AkkornStudio.UI/Controls/ExplainPlan/ExplainPlanOverlay.axaml.cs
@@ -1,293 +1,293 @@
-using System.Diagnostics;
-using System.IO;
-using System.ComponentModel;
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Media;
-using Avalonia.Controls.Shapes;
-using Avalonia.Platform.Storage;
-using DBWeaver.UI.Services.Explain;
-using DBWeaver.UI.Services.Workspace.Models;
-using DBWeaver.UI.ViewModels;
-using DBWeaver.UI.ViewModels.Canvas;
-using DBWeaver.UI.Services.Theming;
-
-namespace DBWeaver.UI.Controls;
-
-public sealed partial class ExplainPlanOverlay : UserControl
-{
- private PropertyChangedEventHandler? _viewModelPropertyChangedHandler;
- private ExplainPlanViewModel? _currentVm;
-
- public ExplainPlanOverlay()
- {
- InitializeComponent();
-
- Button? closeBtn = this.FindControl("CloseBtn");
- Button? runBtn = this.FindControl("RunBtn");
- Button? snapshotBtn = this.FindControl("SnapshotBtn");
- Button? listModeBtn = this.FindControl("ListModeBtn");
- Button? treeModeBtn = this.FindControl("TreeModeBtn");
- Button? copyJsonBtn = this.FindControl("CopyJsonBtn");
- Button? copyTextBtn = this.FindControl("CopyTextBtn");
- Button? saveJsonBtn = this.FindControl("SaveJsonBtn");
- Button? openDaliboBtn = this.FindControl("OpenDaliboBtn");
-
- if (closeBtn is not null)
- closeBtn.Click += (_, _) => (DataContext as ExplainPlanViewModel)?.Close();
-
- if (runBtn is not null)
- runBtn.Click += async (_, _) =>
- {
- if (DataContext is ExplainPlanViewModel vm)
- await vm.RunExplainAsync();
- };
- if (snapshotBtn is not null)
- snapshotBtn.Click += (_, _) => (DataContext as ExplainPlanViewModel)?.CaptureSnapshot();
- if (listModeBtn is not null)
- listModeBtn.Click += (_, _) => (DataContext as ExplainPlanViewModel)?.SetListMode();
- if (treeModeBtn is not null)
- treeModeBtn.Click += (_, _) => (DataContext as ExplainPlanViewModel)?.SetTreeMode();
- if (copyJsonBtn is not null)
- copyJsonBtn.Click += async (_, _) => await CopyJsonAsync();
- if (copyTextBtn is not null)
- copyTextBtn.Click += async (_, _) => await CopyTextAsync();
- if (saveJsonBtn is not null)
- saveJsonBtn.Click += async (_, _) => await SaveJsonAsync();
- if (openDaliboBtn is not null)
- openDaliboBtn.Click += (_, _) => OpenDalibo();
-
- DataContextChanged += OnDataContextChanged;
- }
-
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- if (e.Key == Key.Escape && DataContext is ExplainPlanViewModel vm)
- {
- vm.Close();
- e.Handled = true;
- }
- }
-
- private void OnStepRowClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
- {
- if (sender is not Control control)
- return;
- if (control.DataContext is not ExplainStep step)
- return;
- if (DataContext is not ExplainPlanViewModel vm)
- return;
-
- vm.SelectStepCommand.Execute(step);
- }
-
- private void OnDataContextChanged(object? sender, EventArgs e)
- {
- if (_viewModelPropertyChangedHandler is not null && _currentVm is not null)
- _currentVm.PropertyChanged -= _viewModelPropertyChangedHandler;
-
- if (DataContext is not ExplainPlanViewModel vm)
- {
- _currentVm = null;
- RenderTree(null);
- return;
- }
-
- _currentVm = vm;
- _viewModelPropertyChangedHandler = (_, args) =>
- {
- if (args.PropertyName is nameof(ExplainPlanViewModel.TreeNodes)
- or nameof(ExplainPlanViewModel.TreeEdges)
- or nameof(ExplainPlanViewModel.ShowTreeView)
- or nameof(ExplainPlanViewModel.TreeCanvasWidth)
- or nameof(ExplainPlanViewModel.TreeCanvasHeight))
- {
- RenderTree(vm);
- }
- };
- vm.PropertyChanged += _viewModelPropertyChangedHandler;
- RenderTree(vm);
- }
-
- private void RenderTree(ExplainPlanViewModel? vm)
- {
- Canvas? treeCanvas = this.FindControl("TreeCanvas");
- if (treeCanvas is null)
- return;
-
- treeCanvas.Children.Clear();
- if (vm is null || !vm.ShowTreeView)
- return;
-
- foreach (ExplainTreeVisualEdge edge in vm.TreeEdges)
- {
- var line = new Line
- {
- StartPoint = new Avalonia.Point(edge.X1, edge.Y1),
- EndPoint = new Avalonia.Point(edge.X2, edge.Y2),
- Stroke = ResourceBrush("BorderBrush", UiColorConstants.C_334164),
- StrokeThickness = 1.4,
- };
- treeCanvas.Children.Add(line);
- }
-
- foreach (ExplainTreeVisualNode node in vm.TreeNodes)
- {
- var border = new Border
- {
- Width = node.Width,
- Height = node.Height,
- CornerRadius = ResourceCornerRadius("RadiusSM", 6),
- Background = ResourceBrush("Bg1Brush", UiColorConstants.C_0F1220),
- BorderBrush = node.HasAlert
- ? ResourceBrush("StatusWarningBrush", UiColorConstants.C_D9A441)
- : ResourceBrush("BorderBrush", UiColorConstants.C_334164),
- BorderThickness = new Thickness(1),
- Padding = new Thickness(8, 6),
- Cursor = new Cursor(StandardCursorType.Hand),
- Child = new StackPanel
- {
- Spacing = 2,
- Children =
- {
- new TextBlock
- {
- Text = node.Operation,
- FontSize = ResourceFontSize("FontSizeBody", 12),
- Foreground = ResourceBrush("TextPrimaryBrush", UiColorConstants.C_E7ECFF),
- },
- new TextBlock
- {
- Text = $"cost={node.CostText}",
- FontSize = ResourceFontSize("FontSizeMonoSmall", 11),
- Foreground = ResourceBrush("TextSecondaryBrush", UiColorConstants.C_AEB9D9),
- },
- new TextBlock
- {
- Text = node.AlertLabel,
- FontSize = ResourceFontSize("FontSizeCaption", 11),
- Foreground = ResourceBrush("StatusWarningBrush", UiColorConstants.C_D9A441),
- IsVisible = node.HasAlert,
- },
- },
- },
- };
-
- border.PointerPressed += (_, _) => vm.SelectStepCommand.Execute(node.Step);
- Canvas.SetLeft(border, node.X);
- Canvas.SetTop(border, node.Y);
- treeCanvas.Children.Add(border);
- }
- }
-
- private async void OnIndexSuggestionClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
- {
- if (sender is not Control control)
- return;
- if (control.DataContext is not ExplainIndexSuggestion suggestion)
- return;
- if (DataContext is not ExplainPlanViewModel vm)
- return;
-
- vm.SelectIndexSuggestion(suggestion);
-
- Avalonia.Input.Platform.IClipboard? clipboard = TopLevel.GetTopLevel(this)?.Clipboard;
- if (clipboard is not null)
- await clipboard.SetTextAsync(suggestion.Sql);
-
- if (TopLevel.GetTopLevel(this)?.DataContext is ShellViewModel shell)
- shell.ActivateDocument(WorkspaceDocumentType.DdlCanvas);
- }
-
- private async Task CopyJsonAsync()
- {
- if (DataContext is not ExplainPlanViewModel vm || string.IsNullOrWhiteSpace(vm.RawOutput))
- return;
-
- Avalonia.Input.Platform.IClipboard? clipboard = TopLevel.GetTopLevel(this)?.Clipboard;
- if (clipboard is not null)
- await clipboard.SetTextAsync(vm.RawOutput);
- }
-
- private async Task CopyTextAsync()
- {
- if (DataContext is not ExplainPlanViewModel vm)
- return;
-
- Avalonia.Input.Platform.IClipboard? clipboard = TopLevel.GetTopLevel(this)?.Clipboard;
- if (clipboard is not null)
- await clipboard.SetTextAsync(vm.BuildExportText());
- }
-
- private async Task SaveJsonAsync()
- {
- if (DataContext is not ExplainPlanViewModel vm || string.IsNullOrWhiteSpace(vm.RawOutput))
- return;
-
- TopLevel? topLevel = TopLevel.GetTopLevel(this);
- if (topLevel?.StorageProvider is null)
- return;
-
- var jsonType = new FilePickerFileType("JSON Files") { Patterns = ["*.json"] };
- IStorageFile? result = await topLevel.StorageProvider.SaveFilePickerAsync(
- new FilePickerSaveOptions
- {
- Title = "Salvar plano EXPLAIN",
- DefaultExtension = "json",
- FileTypeChoices = [jsonType],
- SuggestedFileName = "explain-plan",
- }
- );
-
- string? path = result?.TryGetLocalPath();
- if (!string.IsNullOrWhiteSpace(path))
- await File.WriteAllTextAsync(path, vm.RawOutput);
- }
-
- private void OpenDalibo()
- {
- if (DataContext is not ExplainPlanViewModel vm)
- return;
-
- string? url = vm.BuildDaliboUrl();
- if (string.IsNullOrWhiteSpace(url))
- return;
-
- Process.Start(new ProcessStartInfo
- {
- FileName = url,
- UseShellExecute = true,
- });
- }
-
- private static IBrush ResourceBrush(string key, string fallbackHex)
- {
- if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true && resource is IBrush brush)
- return brush;
-
- return new SolidColorBrush(Color.Parse(fallbackHex));
- }
-
- private static CornerRadius ResourceCornerRadius(string key, double fallbackValue)
- {
- if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true && resource is CornerRadius radius)
- return radius;
-
- return new CornerRadius(fallbackValue);
- }
-
- private static double ResourceFontSize(string key, double fallbackValue)
- {
- if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true)
- {
- if (resource is double sized)
- return sized;
- if (resource is int sizei)
- return sizei;
- }
-
- return fallbackValue;
- }
-}
+using System.Diagnostics;
+using System.IO;
+using System.ComponentModel;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.Media;
+using Avalonia.Controls.Shapes;
+using Avalonia.Platform.Storage;
+using AkkornStudio.UI.Services.Explain;
+using AkkornStudio.UI.Services.Workspace.Models;
+using AkkornStudio.UI.ViewModels;
+using AkkornStudio.UI.ViewModels.Canvas;
+using AkkornStudio.UI.Services.Theming;
+
+namespace AkkornStudio.UI.Controls;
+
+public sealed partial class ExplainPlanOverlay : UserControl
+{
+ private PropertyChangedEventHandler? _viewModelPropertyChangedHandler;
+ private ExplainPlanViewModel? _currentVm;
+
+ public ExplainPlanOverlay()
+ {
+ InitializeComponent();
+
+ Button? closeBtn = this.FindControl("CloseBtn");
+ Button? runBtn = this.FindControl("RunBtn");
+ Button? snapshotBtn = this.FindControl("SnapshotBtn");
+ Button? listModeBtn = this.FindControl("ListModeBtn");
+ Button? treeModeBtn = this.FindControl("TreeModeBtn");
+ Button? copyJsonBtn = this.FindControl("CopyJsonBtn");
+ Button? copyTextBtn = this.FindControl("CopyTextBtn");
+ Button? saveJsonBtn = this.FindControl("SaveJsonBtn");
+ Button? openDaliboBtn = this.FindControl("OpenDaliboBtn");
+
+ if (closeBtn is not null)
+ closeBtn.Click += (_, _) => (DataContext as ExplainPlanViewModel)?.Close();
+
+ if (runBtn is not null)
+ runBtn.Click += async (_, _) =>
+ {
+ if (DataContext is ExplainPlanViewModel vm)
+ await vm.RunExplainAsync();
+ };
+ if (snapshotBtn is not null)
+ snapshotBtn.Click += (_, _) => (DataContext as ExplainPlanViewModel)?.CaptureSnapshot();
+ if (listModeBtn is not null)
+ listModeBtn.Click += (_, _) => (DataContext as ExplainPlanViewModel)?.SetListMode();
+ if (treeModeBtn is not null)
+ treeModeBtn.Click += (_, _) => (DataContext as ExplainPlanViewModel)?.SetTreeMode();
+ if (copyJsonBtn is not null)
+ copyJsonBtn.Click += async (_, _) => await CopyJsonAsync();
+ if (copyTextBtn is not null)
+ copyTextBtn.Click += async (_, _) => await CopyTextAsync();
+ if (saveJsonBtn is not null)
+ saveJsonBtn.Click += async (_, _) => await SaveJsonAsync();
+ if (openDaliboBtn is not null)
+ openDaliboBtn.Click += (_, _) => OpenDalibo();
+
+ DataContextChanged += OnDataContextChanged;
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+ if (e.Key == Key.Escape && DataContext is ExplainPlanViewModel vm)
+ {
+ vm.Close();
+ e.Handled = true;
+ }
+ }
+
+ private void OnStepRowClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
+ {
+ if (sender is not Control control)
+ return;
+ if (control.DataContext is not ExplainStep step)
+ return;
+ if (DataContext is not ExplainPlanViewModel vm)
+ return;
+
+ vm.SelectStepCommand.Execute(step);
+ }
+
+ private void OnDataContextChanged(object? sender, EventArgs e)
+ {
+ if (_viewModelPropertyChangedHandler is not null && _currentVm is not null)
+ _currentVm.PropertyChanged -= _viewModelPropertyChangedHandler;
+
+ if (DataContext is not ExplainPlanViewModel vm)
+ {
+ _currentVm = null;
+ RenderTree(null);
+ return;
+ }
+
+ _currentVm = vm;
+ _viewModelPropertyChangedHandler = (_, args) =>
+ {
+ if (args.PropertyName is nameof(ExplainPlanViewModel.TreeNodes)
+ or nameof(ExplainPlanViewModel.TreeEdges)
+ or nameof(ExplainPlanViewModel.ShowTreeView)
+ or nameof(ExplainPlanViewModel.TreeCanvasWidth)
+ or nameof(ExplainPlanViewModel.TreeCanvasHeight))
+ {
+ RenderTree(vm);
+ }
+ };
+ vm.PropertyChanged += _viewModelPropertyChangedHandler;
+ RenderTree(vm);
+ }
+
+ private void RenderTree(ExplainPlanViewModel? vm)
+ {
+ Canvas? treeCanvas = this.FindControl("TreeCanvas");
+ if (treeCanvas is null)
+ return;
+
+ treeCanvas.Children.Clear();
+ if (vm is null || !vm.ShowTreeView)
+ return;
+
+ foreach (ExplainTreeVisualEdge edge in vm.TreeEdges)
+ {
+ var line = new Line
+ {
+ StartPoint = new Avalonia.Point(edge.X1, edge.Y1),
+ EndPoint = new Avalonia.Point(edge.X2, edge.Y2),
+ Stroke = ResourceBrush("BorderBrush", UiColorConstants.C_334164),
+ StrokeThickness = 1.4,
+ };
+ treeCanvas.Children.Add(line);
+ }
+
+ foreach (ExplainTreeVisualNode node in vm.TreeNodes)
+ {
+ var border = new Border
+ {
+ Width = node.Width,
+ Height = node.Height,
+ CornerRadius = ResourceCornerRadius("RadiusSM", 6),
+ Background = ResourceBrush("Bg1Brush", UiColorConstants.C_0F1220),
+ BorderBrush = node.HasAlert
+ ? ResourceBrush("StatusWarningBrush", UiColorConstants.C_D9A441)
+ : ResourceBrush("BorderBrush", UiColorConstants.C_334164),
+ BorderThickness = new Thickness(1),
+ Padding = new Thickness(8, 6),
+ Cursor = new Cursor(StandardCursorType.Hand),
+ Child = new StackPanel
+ {
+ Spacing = 2,
+ Children =
+ {
+ new TextBlock
+ {
+ Text = node.Operation,
+ FontSize = ResourceFontSize("FontSizeBody", 12),
+ Foreground = ResourceBrush("TextPrimaryBrush", UiColorConstants.C_E7ECFF),
+ },
+ new TextBlock
+ {
+ Text = $"cost={node.CostText}",
+ FontSize = ResourceFontSize("FontSizeMonoSmall", 11),
+ Foreground = ResourceBrush("TextSecondaryBrush", UiColorConstants.C_AEB9D9),
+ },
+ new TextBlock
+ {
+ Text = node.AlertLabel,
+ FontSize = ResourceFontSize("FontSizeCaption", 11),
+ Foreground = ResourceBrush("StatusWarningBrush", UiColorConstants.C_D9A441),
+ IsVisible = node.HasAlert,
+ },
+ },
+ },
+ };
+
+ border.PointerPressed += (_, _) => vm.SelectStepCommand.Execute(node.Step);
+ Canvas.SetLeft(border, node.X);
+ Canvas.SetTop(border, node.Y);
+ treeCanvas.Children.Add(border);
+ }
+ }
+
+ private async void OnIndexSuggestionClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
+ {
+ if (sender is not Control control)
+ return;
+ if (control.DataContext is not ExplainIndexSuggestion suggestion)
+ return;
+ if (DataContext is not ExplainPlanViewModel vm)
+ return;
+
+ vm.SelectIndexSuggestion(suggestion);
+
+ Avalonia.Input.Platform.IClipboard? clipboard = TopLevel.GetTopLevel(this)?.Clipboard;
+ if (clipboard is not null)
+ await clipboard.SetTextAsync(suggestion.Sql);
+
+ if (TopLevel.GetTopLevel(this)?.DataContext is ShellViewModel shell)
+ shell.ActivateDocument(WorkspaceDocumentType.DdlCanvas);
+ }
+
+ private async Task CopyJsonAsync()
+ {
+ if (DataContext is not ExplainPlanViewModel vm || string.IsNullOrWhiteSpace(vm.RawOutput))
+ return;
+
+ Avalonia.Input.Platform.IClipboard? clipboard = TopLevel.GetTopLevel(this)?.Clipboard;
+ if (clipboard is not null)
+ await clipboard.SetTextAsync(vm.RawOutput);
+ }
+
+ private async Task CopyTextAsync()
+ {
+ if (DataContext is not ExplainPlanViewModel vm)
+ return;
+
+ Avalonia.Input.Platform.IClipboard? clipboard = TopLevel.GetTopLevel(this)?.Clipboard;
+ if (clipboard is not null)
+ await clipboard.SetTextAsync(vm.BuildExportText());
+ }
+
+ private async Task SaveJsonAsync()
+ {
+ if (DataContext is not ExplainPlanViewModel vm || string.IsNullOrWhiteSpace(vm.RawOutput))
+ return;
+
+ TopLevel? topLevel = TopLevel.GetTopLevel(this);
+ if (topLevel?.StorageProvider is null)
+ return;
+
+ var jsonType = new FilePickerFileType("JSON Files") { Patterns = ["*.json"] };
+ IStorageFile? result = await topLevel.StorageProvider.SaveFilePickerAsync(
+ new FilePickerSaveOptions
+ {
+ Title = "Salvar plano EXPLAIN",
+ DefaultExtension = "json",
+ FileTypeChoices = [jsonType],
+ SuggestedFileName = "explain-plan",
+ }
+ );
+
+ string? path = result?.TryGetLocalPath();
+ if (!string.IsNullOrWhiteSpace(path))
+ await File.WriteAllTextAsync(path, vm.RawOutput);
+ }
+
+ private void OpenDalibo()
+ {
+ if (DataContext is not ExplainPlanViewModel vm)
+ return;
+
+ string? url = vm.BuildDaliboUrl();
+ if (string.IsNullOrWhiteSpace(url))
+ return;
+
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = url,
+ UseShellExecute = true,
+ });
+ }
+
+ private static IBrush ResourceBrush(string key, string fallbackHex)
+ {
+ if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true && resource is IBrush brush)
+ return brush;
+
+ return new SolidColorBrush(Color.Parse(fallbackHex));
+ }
+
+ private static CornerRadius ResourceCornerRadius(string key, double fallbackValue)
+ {
+ if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true && resource is CornerRadius radius)
+ return radius;
+
+ return new CornerRadius(fallbackValue);
+ }
+
+ private static double ResourceFontSize(string key, double fallbackValue)
+ {
+ if (Application.Current?.Resources.TryGetResource(key, null, out object? resource) == true)
+ {
+ if (resource is double sized)
+ return sized;
+ if (resource is int sizei)
+ return sizei;
+ }
+
+ return fallbackValue;
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/Feedback/BottomSheetToast.axaml b/src/AkkornStudio.UI/Controls/Feedback/BottomSheetToast.axaml
similarity index 91%
rename from src/DBWeaver.UI/Controls/Feedback/BottomSheetToast.axaml
rename to src/AkkornStudio.UI/Controls/Feedback/BottomSheetToast.axaml
index 377e30ff..7ecb3cd5 100644
--- a/src/DBWeaver.UI/Controls/Feedback/BottomSheetToast.axaml
+++ b/src/AkkornStudio.UI/Controls/Feedback/BottomSheetToast.axaml
@@ -1,61 +1,61 @@
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Controls/Feedback/BottomSheetToast.axaml.cs b/src/AkkornStudio.UI/Controls/Feedback/BottomSheetToast.axaml.cs
similarity index 79%
rename from src/DBWeaver.UI/Controls/Feedback/BottomSheetToast.axaml.cs
rename to src/AkkornStudio.UI/Controls/Feedback/BottomSheetToast.axaml.cs
index 1ead866f..d0d03341 100644
--- a/src/DBWeaver.UI/Controls/Feedback/BottomSheetToast.axaml.cs
+++ b/src/AkkornStudio.UI/Controls/Feedback/BottomSheetToast.axaml.cs
@@ -1,11 +1,11 @@
-using Avalonia.Controls;
-
-namespace DBWeaver.UI.Controls;
-
-public sealed partial class BottomSheetToast : UserControl
-{
- public BottomSheetToast()
- {
- InitializeComponent();
- }
-}
+using Avalonia.Controls;
+
+namespace AkkornStudio.UI.Controls;
+
+public sealed partial class BottomSheetToast : UserControl
+{
+ public BottomSheetToast()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml b/src/AkkornStudio.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml
similarity index 95%
rename from src/DBWeaver.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml
rename to src/AkkornStudio.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml
index 2bf57ce4..64a65073 100644
--- a/src/DBWeaver.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml
+++ b/src/AkkornStudio.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml
@@ -1,110 +1,110 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml.cs b/src/AkkornStudio.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml.cs
similarity index 91%
rename from src/DBWeaver.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml.cs
rename to src/AkkornStudio.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml.cs
index ea8e058d..d74e4466 100644
--- a/src/DBWeaver.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml.cs
+++ b/src/AkkornStudio.UI/Controls/FileHistory/FileVersionHistoryOverlay.axaml.cs
@@ -1,46 +1,46 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using DBWeaver.UI.ViewModels.Canvas;
-
-namespace DBWeaver.UI.Controls;
-
-public sealed partial class FileVersionHistoryOverlay : UserControl
-{
- private FileVersionHistoryViewModel? Vm => DataContext as FileVersionHistoryViewModel;
-
- public FileVersionHistoryOverlay()
- {
- InitializeComponent();
-
- Button? closeBtn = this.FindControl("CloseBtn");
- Button? reloadBtn = this.FindControl("ReloadBtn");
- Button? restoreBtn = this.FindControl("RestoreBtn");
-
- if (closeBtn is not null)
- closeBtn.Click += (_, _) => Vm?.Close();
-
- if (reloadBtn is not null)
- reloadBtn.Click += async (_, _) =>
- {
- if (Vm is not null)
- await Vm.ReloadAsync();
- };
-
- if (restoreBtn is not null)
- restoreBtn.Click += async (_, _) =>
- {
- if (Vm is not null)
- await Vm.RestoreSelectedAsync();
- };
- }
-
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- if (e.Key == Key.Escape)
- {
- Vm?.Close();
- e.Handled = true;
- }
- }
-}
+using Avalonia.Controls;
+using Avalonia.Input;
+using AkkornStudio.UI.ViewModels.Canvas;
+
+namespace AkkornStudio.UI.Controls;
+
+public sealed partial class FileVersionHistoryOverlay : UserControl
+{
+ private FileVersionHistoryViewModel? Vm => DataContext as FileVersionHistoryViewModel;
+
+ public FileVersionHistoryOverlay()
+ {
+ InitializeComponent();
+
+ Button? closeBtn = this.FindControl("CloseBtn");
+ Button? reloadBtn = this.FindControl("ReloadBtn");
+ Button? restoreBtn = this.FindControl("RestoreBtn");
+
+ if (closeBtn is not null)
+ closeBtn.Click += (_, _) => Vm?.Close();
+
+ if (reloadBtn is not null)
+ reloadBtn.Click += async (_, _) =>
+ {
+ if (Vm is not null)
+ await Vm.ReloadAsync();
+ };
+
+ if (restoreBtn is not null)
+ restoreBtn.Click += async (_, _) =>
+ {
+ if (Vm is not null)
+ await Vm.RestoreSelectedAsync();
+ };
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+ if (e.Key == Key.Escape)
+ {
+ Vm?.Close();
+ e.Handled = true;
+ }
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/FlowVersions/FlowVersionOverlay.axaml b/src/AkkornStudio.UI/Controls/FlowVersions/FlowVersionOverlay.axaml
similarity index 89%
rename from src/DBWeaver.UI/Controls/FlowVersions/FlowVersionOverlay.axaml
rename to src/AkkornStudio.UI/Controls/FlowVersions/FlowVersionOverlay.axaml
index 146ad920..a1d653ad 100644
--- a/src/DBWeaver.UI/Controls/FlowVersions/FlowVersionOverlay.axaml
+++ b/src/AkkornStudio.UI/Controls/FlowVersions/FlowVersionOverlay.axaml
@@ -1,362 +1,347 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DBWeaver.UI/Controls/FlowVersions/FlowVersionOverlay.axaml.cs b/src/AkkornStudio.UI/Controls/FlowVersions/FlowVersionOverlay.axaml.cs
similarity index 94%
rename from src/DBWeaver.UI/Controls/FlowVersions/FlowVersionOverlay.axaml.cs
rename to src/AkkornStudio.UI/Controls/FlowVersions/FlowVersionOverlay.axaml.cs
index 7e9e7444..aab35b32 100644
--- a/src/DBWeaver.UI/Controls/FlowVersions/FlowVersionOverlay.axaml.cs
+++ b/src/AkkornStudio.UI/Controls/FlowVersions/FlowVersionOverlay.axaml.cs
@@ -1,86 +1,86 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-using DBWeaver.UI.ViewModels.Canvas;
-
-namespace DBWeaver.UI.Controls;
-
-public sealed partial class FlowVersionOverlay : UserControl
-{
- private FlowVersionOverlayViewModel? Vm => DataContext as FlowVersionOverlayViewModel;
-
- public FlowVersionOverlay()
- {
- InitializeComponent();
-
- Button? closeBtn = this.FindControl("CloseBtn");
- Button? saveBtn = this.FindControl("SaveBtn");
- Button? diffModeBtn = this.FindControl("DiffModeBtn");
-
- if (closeBtn is not null)
- closeBtn.Click += (_, _) => Vm?.Close();
-
- if (saveBtn is not null)
- saveBtn.Click += (_, _) =>
- {
- if (Vm is null) return;
- Vm.CreateCheckpoint(Vm.NewLabel);
- };
-
- if (diffModeBtn is not null)
- diffModeBtn.Click += (_, _) =>
- {
- if (Vm is not null)
- Vm.IsDiffMode = !Vm.IsDiffMode;
- };
-
- // Wire per-row buttons via event bubbling on the ItemsControl
- this.AddHandler(Button.ClickEvent, OnRowButtonClick);
- }
-
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- if (e.Key == Avalonia.Input.Key.Escape)
- {
- Vm?.Close();
- e.Handled = true;
- }
- }
-
- private void OnRowButtonClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
- {
- if (Vm is null) return;
- if (e.Source is not Button btn) return;
-
- // Tag holds the version ID
- string? id = btn.Tag as string;
- if (string.IsNullOrEmpty(id)) return;
-
- switch (btn.Name)
- {
- case "RestoreBtn":
- {
- var version = Vm.Versions.FirstOrDefault(v => v.Id == id)?.Version;
- if (version is not null)
- Vm.Restore(version);
- break;
- }
- case "DeleteBtn":
- Vm.DeleteVersion(id);
- break;
-
- case "CompareBtn":
- {
- var row = Vm.Versions.FirstOrDefault(v => v.Id == id);
- if (row is null) break;
- if (!Vm.IsDiffMode)
- Vm.IsDiffMode = true;
- if (Vm.DiffBaseVersion is not null && Vm.DiffBaseVersion.Id != id)
- Vm.ComputeDiff(Vm.DiffBaseVersion.Version, row.Version);
- else
- Vm.DiffBaseVersion = row;
- break;
- }
- }
- }
-}
+using Avalonia.Controls;
+using Avalonia.Input;
+using AkkornStudio.UI.ViewModels.Canvas;
+
+namespace AkkornStudio.UI.Controls;
+
+public sealed partial class FlowVersionOverlay : UserControl
+{
+ private FlowVersionOverlayViewModel? Vm => DataContext as FlowVersionOverlayViewModel;
+
+ public FlowVersionOverlay()
+ {
+ InitializeComponent();
+
+ Button? closeBtn = this.FindControl("CloseBtn");
+ Button? saveBtn = this.FindControl("SaveBtn");
+ Button? diffModeBtn = this.FindControl("DiffModeBtn");
+
+ if (closeBtn is not null)
+ closeBtn.Click += (_, _) => Vm?.Close();
+
+ if (saveBtn is not null)
+ saveBtn.Click += (_, _) =>
+ {
+ if (Vm is null) return;
+ Vm.CreateCheckpoint(Vm.NewLabel);
+ };
+
+ if (diffModeBtn is not null)
+ diffModeBtn.Click += (_, _) =>
+ {
+ if (Vm is not null)
+ Vm.IsDiffMode = !Vm.IsDiffMode;
+ };
+
+ // Wire per-row buttons via event bubbling on the ItemsControl
+ this.AddHandler(Button.ClickEvent, OnRowButtonClick);
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+ if (e.Key == Avalonia.Input.Key.Escape)
+ {
+ Vm?.Close();
+ e.Handled = true;
+ }
+ }
+
+ private void OnRowButtonClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
+ {
+ if (Vm is null) return;
+ if (e.Source is not Button btn) return;
+
+ // Tag holds the version ID
+ string? id = btn.Tag as string;
+ if (string.IsNullOrEmpty(id)) return;
+
+ switch (btn.Name)
+ {
+ case "RestoreBtn":
+ {
+ var version = Vm.Versions.FirstOrDefault(v => v.Id == id)?.Version;
+ if (version is not null)
+ Vm.Restore(version);
+ break;
+ }
+ case "DeleteBtn":
+ Vm.DeleteVersion(id);
+ break;
+
+ case "CompareBtn":
+ {
+ var row = Vm.Versions.FirstOrDefault(v => v.Id == id);
+ if (row is null) break;
+ if (!Vm.IsDiffMode)
+ Vm.IsDiffMode = true;
+ if (Vm.DiffBaseVersion is not null && Vm.DiffBaseVersion.Id != id)
+ Vm.ComputeDiff(Vm.DiffBaseVersion.Version, row.Version);
+ else
+ Vm.DiffBaseVersion = row;
+ break;
+ }
+ }
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/InfiniteCanvas/AlignGuidesLayer.cs b/src/AkkornStudio.UI/Controls/InfiniteCanvas/AlignGuidesLayer.cs
similarity index 95%
rename from src/DBWeaver.UI/Controls/InfiniteCanvas/AlignGuidesLayer.cs
rename to src/AkkornStudio.UI/Controls/InfiniteCanvas/AlignGuidesLayer.cs
index cc310f81..6bc8e3e2 100644
--- a/src/DBWeaver.UI/Controls/InfiniteCanvas/AlignGuidesLayer.cs
+++ b/src/AkkornStudio.UI/Controls/InfiniteCanvas/AlignGuidesLayer.cs
@@ -1,66 +1,66 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Media;
-
-namespace DBWeaver.UI.Controls;
-
-///
-/// Transparent overlay rendered on top of the canvas that draws horizontal and
-/// vertical alignment guides while the user is dragging a node.
-///
-/// Guides are expressed as canvas-space coordinates and are converted to screen
-/// space via the current zoom and pan offset before rendering.
-///
-public sealed class AlignGuidesLayer : Control
-{
- private static readonly Pen GuidePen = new(
- new SolidColorBrush(Color.FromArgb(200, 59, 130, 246)),
- 1,
- lineCap: PenLineCap.Flat
- );
-
- public double Zoom { get; set; } = 1.0;
- public Point PanOffset { get; set; }
-
- private List _hGuides = []; // canvas-space Y values
- private List _vGuides = []; // canvas-space X values
-
- public void SetGuides(List hGuides, List vGuides)
- {
- _hGuides = hGuides;
- _vGuides = vGuides;
- InvalidateVisual();
- }
-
- public void ClearGuides()
- {
- if (_hGuides.Count == 0 && _vGuides.Count == 0)
- return;
- _hGuides = [];
- _vGuides = [];
- InvalidateVisual();
- }
-
- public override void Render(DrawingContext ctx)
- {
- if (_hGuides.Count == 0 && _vGuides.Count == 0)
- return;
-
- double w = Bounds.Width;
- double h = Bounds.Height;
-
- // Horizontal guides (fixed Y, span full width)
- foreach (double cy in _hGuides)
- {
- double sy = cy * Zoom + PanOffset.Y;
- ctx.DrawLine(GuidePen, new Point(0, sy), new Point(w, sy));
- }
-
- // Vertical guides (fixed X, span full height)
- foreach (double cx in _vGuides)
- {
- double sx = cx * Zoom + PanOffset.X;
- ctx.DrawLine(GuidePen, new Point(sx, 0), new Point(sx, h));
- }
- }
-}
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Media;
+
+namespace AkkornStudio.UI.Controls;
+
+///
+/// Transparent overlay rendered on top of the canvas that draws horizontal and
+/// vertical alignment guides while the user is dragging a node.
+///
+/// Guides are expressed as canvas-space coordinates and are converted to screen
+/// space via the current zoom and pan offset before rendering.
+///
+public sealed class AlignGuidesLayer : Control
+{
+ private static readonly Pen GuidePen = new(
+ new SolidColorBrush(Color.FromArgb(200, 59, 130, 246)),
+ 1,
+ lineCap: PenLineCap.Flat
+ );
+
+ public double Zoom { get; set; } = 1.0;
+ public Point PanOffset { get; set; }
+
+ private List _hGuides = []; // canvas-space Y values
+ private List _vGuides = []; // canvas-space X values
+
+ public void SetGuides(List hGuides, List vGuides)
+ {
+ _hGuides = hGuides;
+ _vGuides = vGuides;
+ InvalidateVisual();
+ }
+
+ public void ClearGuides()
+ {
+ if (_hGuides.Count == 0 && _vGuides.Count == 0)
+ return;
+ _hGuides = [];
+ _vGuides = [];
+ InvalidateVisual();
+ }
+
+ public override void Render(DrawingContext ctx)
+ {
+ if (_hGuides.Count == 0 && _vGuides.Count == 0)
+ return;
+
+ double w = Bounds.Width;
+ double h = Bounds.Height;
+
+ // Horizontal guides (fixed Y, span full width)
+ foreach (double cy in _hGuides)
+ {
+ double sy = cy * Zoom + PanOffset.Y;
+ ctx.DrawLine(GuidePen, new Point(0, sy), new Point(w, sy));
+ }
+
+ // Vertical guides (fixed X, span full height)
+ foreach (double cx in _vGuides)
+ {
+ double sx = cx * Zoom + PanOffset.X;
+ ctx.DrawLine(GuidePen, new Point(sx, 0), new Point(sx, h));
+ }
+ }
+}
diff --git a/src/DBWeaver.UI/Controls/InfiniteCanvas/BezierWireLayer.cs b/src/AkkornStudio.UI/Controls/InfiniteCanvas/BezierWireLayer.cs
similarity index 97%
rename from src/DBWeaver.UI/Controls/InfiniteCanvas/BezierWireLayer.cs
rename to src/AkkornStudio.UI/Controls/InfiniteCanvas/BezierWireLayer.cs
index b1c7d38f..155a6017 100644
--- a/src/DBWeaver.UI/Controls/InfiniteCanvas/BezierWireLayer.cs
+++ b/src/AkkornStudio.UI/Controls/InfiniteCanvas/BezierWireLayer.cs
@@ -1,1319 +1,1319 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Media;
-using Avalonia.Rendering.Composition;
-using Avalonia.Threading;
-using System.Linq;
-using System.Globalization;
-using DBWeaver.CanvasKit;
-using DBWeaver.UI.ViewModels;
-using DBWeaver.UI.Services.Theming;
-
-namespace DBWeaver.UI.Controls;
-
-///
-/// Transparent overlay canvas that draws all Bézier connection wires.
-/// Sits behind all node controls but above the grid background.
-///
-/// Performance optimizations applied (Tarefa 18):
-/// • Geometry cache: is only rebuilt when endpoints change.
-/// • Brush/pen cache: pens and brushes are reused across frames, keyed by color+thickness.
-/// • Viewport culling: wires whose AABB lies entirely outside are skipped.
-/// • Static shared brushes for constant-color elements (endpoint background, grid bg).
-///
-public sealed class BezierWireLayer : Control
-{
- public enum WireToolbarAction
- {
- SetBezier,
- SetStraight,
- SetOrthogonal,
- Delete,
- }
-
- public readonly record struct WireToolbarHit(ConnectionViewModel Wire, WireToolbarAction Action);
- internal readonly record struct WireToolbarLayout(
- Rect Toolbar,
- Rect Bezier,
- Rect Straight,
- Rect Orthogonal,
- Rect Delete);
-
- private static readonly Typeface OverlayTypeface = new(new FontFamily("Segoe UI"));
- private sealed record RemovalFlash(
- Point From,
- Point To,
- CanvasWireRoutingMode RoutingMode,
- Color Color,
- double Thickness,
- CanvasWireDashKind DashKind,
- long StartedAtMs
- );
-
- private readonly List _removalFlashes = [];
- private const long RemovalFlashDurationMs = 180;
-
- // ── Avalonia Properties ───────────────────────────────────────────────────
-
- public static readonly StyledProperty> ConnectionsProperty =
- AvaloniaProperty.Register>(
- nameof(Connections),
- defaultValue: []
- );
-
- public static readonly StyledProperty PendingConnectionProperty =
- AvaloniaProperty.Register(nameof(PendingConnection));
-
- public static readonly StyledProperty InvalidPreviewConnectionProperty =
- AvaloniaProperty.Register(
- nameof(InvalidPreviewConnection)
- );
-
- public static readonly StyledProperty WireCurveModeProperty =
- AvaloniaProperty.Register(
- nameof(WireCurveMode),
- defaultValue: CanvasWireCurveMode.Bezier
- );
-
- public static readonly StyledProperty SelectedBreakpointConnectionProperty =
- AvaloniaProperty.Register(
- nameof(SelectedBreakpointConnection));
-
- public static readonly StyledProperty