diff --git a/GUIDE.md b/GUIDE.md index f4f142e8..a589fbee 100644 --- a/GUIDE.md +++ b/GUIDE.md @@ -36,6 +36,23 @@ npm run build runtime assets. The generated Rust contract bindings are checked in so normal builds do not require a sibling Echo checkout or generator invocation. +## Files explorer + +Ctrl+B opens Files in navigation mode. Click a folder or press Enter to expand +or collapse it inline. Right/l expands a folder or selects its first visible +child; Left/h collapses it or selects its parent. Backspace and Alt+Up move the +explorer root upward. Refresh with r or Ctrl+R reloads the root and collapses +expanded branches. + +Click a file to select it and preview its contents in the main viewer. Enter +opens that file for editing. Previews use Graft syntax colors, prefer unsaved +open-buffer text, and remain read-only. Unsupported syntax or a parser failure +leaves a readable plain-text preview. + +Press / to filter known visible paths; matching children retain their folder +ancestors, and the matching file stays selected. Esc/Enter exits filter editing +and keeps the query. Closed directories are loaded only when expanded. + ## Validate The Workspace Use the normal local gate: diff --git a/docs/design/0164-explorer-inline-tree-preview-syntax.md b/docs/design/0164-explorer-inline-tree-preview-syntax.md new file mode 100644 index 00000000..ed54b054 --- /dev/null +++ b/docs/design/0164-explorer-inline-tree-preview-syntax.md @@ -0,0 +1,236 @@ +--- +title: "DX-0164 - Inline explorer tree and preview syntax" +legend: "DX" +lane: "design" +issue: "https://github.com/flyingrobots/jedit/issues/348" +status: "active" +owners: ["@flyingrobots"] +created: "2026-10-15" +updated: "2026-10-15" +--- + +# DX-0164 - Inline explorer tree and preview syntax + +## Linked Issue + +https://github.com/flyingrobots/jedit/issues/348 + +## Decision Summary + +The workspace Files explorer expands directories inline on click or Enter, +with indentation and disclosure markers. File click remains selection/preview; +file Enter remains an explicit open. Bounded read-only previews receive Graft +syntax spans without creating a buffer or claiming an Echo head. + +## Sponsored Human + +A Jim user wants to browse several open folders and read colored source previews +without repeatedly changing the explorer root or opening unwanted buffers. + +## Sponsored Agent + +An agent needs inspectable expansion state, selected entry identity, bounded +preview text and stale-result rejection to prove input and authority boundaries. + +## Hill + +Click and Enter reveal/hide folder children in place. Selecting a source file +renders syntax colors in the main preview while buffer authority remains intact. + +## Current Truth + +The fetched base is +[af1fad8ab3356fa6d96548c8793aa6f2afea8c6b](https://github.com/flyingrobots/jedit/commit/af1fad8ab3356fa6d96548c8793aa6f2afea8c6b), +footer PR #344. `file-tree.ts` changes cwd for a directory. `mouse.ts` only selects +rows. `file-explorer-preview-view.ts` builds an uncolored text Surface. +`file-explorer-preview.ts` already bounds reads and rejects stale results. +The Graft adapter currently accepts an editor-head basis; Graft itself allows +basis-free projections for disposable content. + +## Problem + +Entering a directory loses sibling context, clicking cannot expand it, and source +previews lose the syntax information available in the editor. + +## Scope + +Lazy inline expansion/collapse, nested indentation, directory pointer/keyboard +actions, filtered ancestry, refresh behavior, and read-only preview syntax. + +## Non-Goals + +Recursive filesystem indexing, watchers, persisted expansion, symbol search, +preview editing, new Echo buffer authorities, or changes to the startup picker. + +## User Experience / Product Shape + +Folders show ▸ when closed and ▾ when open; each child is indented two cells. +Clicking any part of a folder row selects and toggles it. Enter toggles it too. +Right/l expands a closed folder or enters its first child; Left/h collapses an +open folder or selects its parent. Backspace and Alt+Up retain root-parent +navigation. Refresh reloads the current root and collapses expanded branches. +An empty folder still shows its open disclosure. An unreadable folder shows the +existing directory error toast and keeps the current tree intact. + +The filter searches the currently known visible rows. Matching children retain +their directory ancestors. Filtering never recursively loads closed directories. +Hover remains distinct from selection; a file click only previews, while Enter +opens it. Folder actions do not modify cwd, editor text or Echo authority. + +Source previews load/highlight asynchronously. Parser errors or unsupported +languages retain readable text. The existing loading/binary/unavailable/truncated +labels remain. Header and truncation notice receive no source syntax colors. + +### User Journey + +Open Files with Ctrl+B, expand src and a nested folder, select a file to inspect +its highlighted preview, then Enter to open it or collapse the folder to keep +browsing. Closing Files reveals the existing editor unchanged. + +### Wide UI Mockup + +100x32, current theme. [Native capture](0164-explorer-witness/nested-syntax-dark-100x32.png): + +```text +Files / filter Preview · main.ts + ▾ src/ + ▸ components/ export const answer = 42; + › main.ts ^ keyword ^ number + ▸ tests/ + README.md +``` + +### Narrow UI Mockup + +60x12, [native capture](0164-explorer-witness/nested-syntax-dark-60x12.png): the same pinned header and indented rows use the existing list viewport. +The selected row remains visible through collapse/expand and scrolling. The +preview occupies the existing main viewer, with clipped lines and syntax tokens. + +### Accessibility Considerations + +Disclosure characters communicate state without color; selection keeps the +existing filled token and hover keeps its separate token. Keyboard-only and +pointer flows share the same visible row projection and directory operation. + +## Runtime / API Contract + +Files entries remain the visible ordered list; optional tree metadata records +per-path depth, parent and expanded state. Loading is lazy through FileSystemPort. +The startup picker and command-path directory opens retain their existing API. + +A basis-free PreviewHighlighter port accepts only preview path/text and bounded +line coordinates. The Graft adapter shares syntax-span conversion with editor +highlighting but omits the editor-head basis for previews. Preview text is +sanitized once before both parsing and rendering. The existing preview request +identity gates the combined text/syntax result. Open-buffer text remains preferred. + +## Lower Modes + +Unsupported syntax and parser failures produce plain text; no new required +service. Unicode, tabs and stripped controls must keep text/color alignment. +Existing minimum terminal dimensions and no-color text state remain valid. + +## Data / State Model + +UI-only tree metadata and preview spans are ephemeral. Collapse drops the +visible descendants and their expansion metadata. Refresh/root changes clear +metadata. Expansion loads immediate children only and excludes parent rows. +No filesystem content cache, serialization, buffer import or Echo Tick is added. + +## Accessibility Posture + +Folder disclosure, nesting and error state are visible without accent colors. +Active input ownership stays with Files. The main document remains a preview +until an explicit file open; hover performs no filesystem read. + +## Localization / Directionality Posture + +Reuse localized preview and directory-error copy. Keep literal path order in +RTL locales and reuse the existing Files indentation convention. Update the +existing Enter hint to communicate toggle/open in all 20 authored locales. + +## Agent Inspectability / Explainability Posture + +Tests can inspect tree metadata, selected indexes, preview result/spans and +rendered token colors. Native witnesses must show nested expansion and a colored +preview rather than infer either feature from source strings. + +## Linked Invariants + +Hover is not selection. Selection is not open. A preview is disposable and +read-only. Filesystem/Graft work belongs behind ports. Echo owns buffer authority. + +## Design Alternatives Considered + +Recursively walking the repository would delay the requested interaction and +increase read scope. Replacing cwd preserves the current defect. Lazy visible +rows with small per-path metadata fit existing selection/filter geometry. +Reusing a made-up editor head for preview syntax would misrepresent provenance; +a basis-free Graft projection is the appropriate read-only boundary. + +## Decision + +Implement the lazy tree and basis-free syntax projection. Preserve the existing +startup-picker and explicit file-opening behaviors. + +## Implementation Slices + +- [x] Slice 1: Inline directory state, rendering, keyboard and pointer behavior. +- [x] Slice 2: Basis-free Graft preview highlighting and stale/failure protection. +- [x] Slice 3: Native witnesses, full checks and review handoff. + +## Tests To Write First + +- [x] Enter/click expand and collapse nested directories without changing root. +- [x] Sibling branches, selection, indentation and filter ancestors stay coherent. +- [x] Empty/unreadable directories and root refresh preserve safe navigation. +- [x] Real Graft syntax colors reach the preview, including unsaved buffer text. +- [x] Stale results, parser failure, tabs, Unicode and truncation remain safe. + +## Acceptance Criteria + +Both actions work through the real runtime; selected previews display theme +syntax tokens. Focus/filter and explicit-open behavior remain intact. Native +terminal witnesses and focused/full checks pass. No new buffer authority exists. + +## Validation Plan + +TypeScript compile, focused explorer/preview/Graft tests, quality, full npm run +check, shard coverage, native wide/narrow dark/light/RTL witnesses and hosted CI. + +## Playback / Witness + +Ctrl+B; click or Enter on a folder; expand another level; select a TypeScript +file; verify keyword/number colors; collapse/reopen; explicitly open a file. + +## Risks + +A flat visible list must keep stable entry identity while indexes shift. Metadata +and rendering share one projection; mouse uses the renderer's exact rows. Syntax +must parse the same sanitized text it paints, without coloring the notice row. + +## Follow-On Debt + +None introduced by this scope. Global recursive search remains outside this cycle. + +## Retrospective + +Inline expansion, collapse, filtered ancestry and read-only syntax are implemented. +File clicks remain previews; Enter remains an explicit open for files. Directory +clicks and Enter share one lazy filesystem operation. The preview port omits an +editor-head basis, and parser failures preserve readable text. + +Tests exposed one interaction refinement: filter ancestry must not steal the +initial selection from the actual match. A later full check found that row +identity needed to remain index-based rather than path-based. Both have focused +regressions, and the corrected full check passed 907 tests: 895 passed, 12 existing +skips, zero failures. Quality has no new debt; all 140 specs are assigned. + +[Native evidence](0164-explorer-witness/README.md) covers mouse and Enter toggles, +root preservation, nested/filtered rows, dark 100x32 and minimum 60x12, and Arabic +light 60x16. Graft produced 13 syntax spans while preview authority remained none +and textRequestId remained 0. Only explicit file Enter opened a buffer. +Arabic rasterization proves alignment, not terminal-specific shaping. + +PR: https://github.com/flyingrobots/jedit/pull/349. The change is stacked on footer +PR #344; the separate Dojo Feed branch is not part of this change. diff --git a/docs/design/0164-explorer-witness/README.md b/docs/design/0164-explorer-witness/README.md new file mode 100644 index 00000000..43e4f503 --- /dev/null +++ b/docs/design/0164-explorer-witness/README.md @@ -0,0 +1,46 @@ +# Inline explorer and preview syntax witnesses + +These captures render Surface cells from the native Bijou terminal loop with +production Echo and the installed Graft parser. The fixture is synthetic local +TypeScript source. The committed helper reproduces the flow. + +| Capture | Behavior | +| --- | --- | +| [Nested folders and colored source, 100x32](nested-syntax-dark-100x32.png) | Click expanded src/components; clicking panel.ts previewed 13 syntax spans. | +| [Filtered hierarchy, 100x32](filtered-nested-dark-100x32.png) | /panel retained src and components, selected panel.ts, and kept its colored preview. | +| [Collapsed folder, 100x32](collapsed-nested-dark-100x32.png) | Enter removed components' children and kept sibling main.ts visible. | +| [Minimum-size dark, 60x12](nested-syntax-dark-60x12.png) | Enter expanded both levels; selection/indentation and keyword/string/number colors fit. | +| [Arabic/light, 60x16](nested-syntax-light-rtl-60x16.png) | Localized preview label and footer, literal paths/source, themed syntax colors. | + +Recorded native observations: + +- The explorer cwd stayed identical across all wide-run operations. +- The selected preview contained 13 Graft syntax spans; textRequestId stayed 0 + and authority stayed none during folder operations and preview selection. +- Enter on the selected file then produced textRequestId 1, editor focus and + opened authority through the production Echo path. +- Mouse expanded directories; keyboard Enter collapsed and reopened them. + +The cell images use Menlo with Apple Symbols/Geeza Pro fallback fonts. +Arabic glyph shaping is terminal-dependent; this rasterization verifies cell +alignment and literal code/path order, not full Arabic shaping. +`receipt.json` records dimensions and captured-cell digests. + +Reproduce after `npm run build`: + +```sh +node scripts/explorer-inline-witness.mjs +JIM_EXPLORER_WITNESS_LOCALE=ar JIM_EXPLORER_WITNESS_LIGHT=1 node scripts/explorer-inline-witness.mjs +``` + +The helper writes synthetic files, isolated preferences and Echo WAL to a fresh +temporary directory. Its path is in `/tmp/jim-inline-tree-witness-directory.txt`. +Use Ctrl+B, then j Enter j Enter j to expand both levels and select panel.ts. +Clicking the same directory rows exercises pointer toggling. Type /panel to +filter; Esc exits filtering. Enter on the file opens it. Ctrl+C exits. + +Validation: 47 focused explorer/Graft tests passed; the selection-index +correction then passed 24 focused navigation/tree/syntax tests. The final full +local check passed 907 tests: 895 passed, 12 existing skips, zero failures, and +no quality regressions. All 140 specs belong to CI shards. Hosted exact-head +checks are recorded in PR #349. diff --git a/docs/design/0164-explorer-witness/collapsed-nested-dark-100x32.png b/docs/design/0164-explorer-witness/collapsed-nested-dark-100x32.png new file mode 100644 index 00000000..170170b9 Binary files /dev/null and b/docs/design/0164-explorer-witness/collapsed-nested-dark-100x32.png differ diff --git a/docs/design/0164-explorer-witness/filtered-nested-dark-100x32.png b/docs/design/0164-explorer-witness/filtered-nested-dark-100x32.png new file mode 100644 index 00000000..5e015835 Binary files /dev/null and b/docs/design/0164-explorer-witness/filtered-nested-dark-100x32.png differ diff --git a/docs/design/0164-explorer-witness/nested-syntax-dark-100x32.png b/docs/design/0164-explorer-witness/nested-syntax-dark-100x32.png new file mode 100644 index 00000000..571853af Binary files /dev/null and b/docs/design/0164-explorer-witness/nested-syntax-dark-100x32.png differ diff --git a/docs/design/0164-explorer-witness/nested-syntax-dark-60x12.png b/docs/design/0164-explorer-witness/nested-syntax-dark-60x12.png new file mode 100644 index 00000000..6706a17e Binary files /dev/null and b/docs/design/0164-explorer-witness/nested-syntax-dark-60x12.png differ diff --git a/docs/design/0164-explorer-witness/nested-syntax-light-rtl-60x16.png b/docs/design/0164-explorer-witness/nested-syntax-light-rtl-60x16.png new file mode 100644 index 00000000..d8d6c006 Binary files /dev/null and b/docs/design/0164-explorer-witness/nested-syntax-light-rtl-60x16.png differ diff --git a/docs/design/0164-explorer-witness/receipt.json b/docs/design/0164-explorer-witness/receipt.json new file mode 100644 index 00000000..d6efba7d --- /dev/null +++ b/docs/design/0164-explorer-witness/receipt.json @@ -0,0 +1,35 @@ +{ + "method": "Native Echo/Bijou PTY cells rendered with Menlo, Apple Symbols and Geeza Pro. Glyph shaping depends on the terminal.", + "captures": [ + { + "image": "collapsed-nested-dark-100x32.png", + "columns": 100, + "rows": 32, + "cellsSha256": "05243d7105c217e0d0f6d1c24eedda85881dda2eb7527015e7bdc6446aa05606" + }, + { + "image": "filtered-nested-dark-100x32.png", + "columns": 100, + "rows": 32, + "cellsSha256": "c752224892407378f0be614a1cc79d6541f030b2f50f72f209a85f5796a818d6" + }, + { + "image": "nested-syntax-dark-100x32.png", + "columns": 100, + "rows": 32, + "cellsSha256": "79b8061e1e9ad6bbb95cdd2e80b0b21c46e00c763a280f0facf3a79824e8b359" + }, + { + "image": "nested-syntax-dark-60x12.png", + "columns": 60, + "rows": 12, + "cellsSha256": "6f0a04658851d160d4ec32ad264e5b9123564e9d887d6bf8cb2b725dc5ff1f71" + }, + { + "image": "nested-syntax-light-rtl-60x16.png", + "columns": 60, + "rows": 16, + "cellsSha256": "e0ddd64ee03dec8deca3c987f0e6ea5e4c16872700093e39e811e31282bef156" + } + ] +} diff --git a/docs/jim-component-ownership.md b/docs/jim-component-ownership.md index c79b9f39..fb106c4f 100644 --- a/docs/jim-component-ownership.md +++ b/docs/jim-component-ownership.md @@ -303,6 +303,23 @@ continues through the native Echo text-import path. a future workspace or symbol index must remain a rebuildable projection and declare its observation basis and staleness policy. +The Files explorer owns ephemeral inline-tree metadata alongside its visible +entry list. Directory click/Enter toggle immediate children in place through the +filesystem port, preserving cwd and other branches. Disclosure, indentation, +selection and hover derive from the same rows used by pointer hit testing. +Filtering retains ancestors of matching known rows without recursively reading +closed directories; it selects the first actual match. Collapse drops descendant +metadata, and refresh/root changes reset expansion. The startup picker retains +its existing directory-changing behavior. + +Preview syntax is a disposable Graft projection through a basis-free preview +highlighting port, separate from editor-head highlighting. Both parse and render +use the same sanitized bounded text. Open-buffer text remains preferred, and +request/entry identity rejects stale text and spans together. Parser failure +retains plain text. Preview colors do not introduce a buffer, head, Tick or save +authority. [DX-0164](design/0164-explorer-inline-tree-preview-syntax.md) refines +[DX-0161](design/0161-file-explorer-search.md) and owns this cycle's evidence. + The footer layout is a Jedit presentation preference, remembered across launches through an injected preferences port and the `~/.jimrc` JSON adapter. The `filepathStyle` preference shares that adapter and chooses paths relative to diff --git a/scripts/explorer-inline-witness.mjs b/scripts/explorer-inline-witness.mjs new file mode 100644 index 00000000..6a856d1b --- /dev/null +++ b/scripts/explorer-inline-witness.mjs @@ -0,0 +1,55 @@ +import { mkdtempSync, mkdirSync, writeFileSync, realpathSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { initDefaultContext } from '@flyingrobots/bijou-node'; +import { getDefaultContext } from '@flyingrobots/bijou'; +import { run } from '@flyingrobots/bijou-tui'; +import { workspaceTerminalIO } from '../dist/adapters/workspace-terminal-io.js'; +import { JEDIT_TERMINAL_MOUSE_OPTIONS } from '../dist/ui/terminal-mouse.js'; +import { createWorkspaceApp } from '../dist/adapters/workspace-app.js'; +import { createWorkspaceProductionTextDependencies, closingProductionText } from '../dist/adapters/workspace-production-text-dependencies.js'; +import { createInitialModelSnapshot } from '../dist/adapters/workspace-initial-model-snapshot.js'; +import { createFooterPreferences } from '../dist/adapters/footer-preferences.js'; +import { BijouI18nAdapter } from '../dist/adapters/bijou-i18n-adapter.js'; +import { oppositeJeditTheme } from '../dist/ui/jedit-themes.js'; + +const directory = realpathSync(mkdtempSync(join(tmpdir(), 'jim-inline-tree-'))); +writeFileSync('/tmp/jim-inline-tree-witness-directory.txt', directory); +mkdirSync(join(directory, 'src', 'components'), { recursive: true }); +mkdirSync(join(directory, 'tests')); +writeFileSync(join(directory, 'src', 'components', 'panel.ts'), '// Preview syntax from Graft\nexport const title = "Panel";\nexport const answer = 42;\n'); +writeFileSync(join(directory, 'src', 'main.ts'), 'import { answer } from "./components/panel";\nconsole.log(answer);\n'); +writeFileSync(join(directory, 'README.md'), 'Synthetic explorer witness fixture.\n'); +process.env.JEDIT_ECHO_WAL_DIR = join(directory, 'wal'); +process.env.TERM = 'xterm-256color'; +for (const name of ['NO_COLOR', 'CI', 'BIJOU_ACCESSIBLE']) delete process.env[name]; +initDefaultContext(); +const seed = createInitialModelSnapshot(Date.now(), directory); +seed.i18n = new BijouI18nAdapter(process.env.JIM_EXPLORER_WITNESS_LOCALE ?? 'en'); +if (process.env.JIM_EXPLORER_WITNESS_LIGHT === '1') seed.jeditTheme = oppositeJeditTheme(seed.jeditTheme); +const production = await createWorkspaceProductionTextDependencies(); +await closingProductionText(production, async () => { + const app = createWorkspaceApp({ initialColumns: process.stdout.columns, initialRows: process.stdout.rows, + initialWorkingDirectory: directory, perfEnabled: false, seed, + footerPreferences: createFooterPreferences(join(directory, '.jimrc')) }, production); + const update = app.update; + const history = []; + app.update = (message, model) => { + const result = update(message, model); + if (!['key', 'mouse', 'file-explorer-preview-result', 'text-open-result'].includes(message.type)) return result; + const next = result[0]; + const surface = app.view(next); + const cells = Array.from({ length: surface.height }, (_, y) => + Array.from({ length: surface.width }, (_, x) => surface.get(x, y))); + history.push({ message: { type: message.type, key: message.key, action: message.action, col: message.col, row: message.row }, + cwd: next.cwd, focus: next.focusPane, selected: next.selectedIndex, tree: next.fileTree, + paths: next.entries.map((entry) => entry.path), previewPath: next.fileExplorerPreview?.entry.path, + syntaxSpans: next.fileExplorerPreview?.highlight?.spans.length, authority: next.textAuthority.kind, + textRequestId: next.textRequestId, commands: result[1].length }); + writeFileSync(join(directory, 'events.json'), JSON.stringify(history, null, 2)); + writeFileSync(join(directory, `frame-${history.length}.json`), JSON.stringify(cells)); + return result; + }; + const context = getDefaultContext(); + await run(app, { ...JEDIT_TERMINAL_MOUSE_OPTIONS, ctx: { ...context, io: workspaceTerminalIO(context.io) } }); +}); diff --git a/spec/file-explorer-inline-tree.spec.mjs b/spec/file-explorer-inline-tree.spec.mjs new file mode 100644 index 00000000..adadd501 --- /dev/null +++ b/spec/file-explorer-inline-tree.spec.mjs @@ -0,0 +1,94 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { importDist, mockRuntime } from './workspace-helpers.mjs'; + +const src = { kind: 'dir', name: 'src', path: '/repo/src' }; +const tests = { kind: 'dir', name: 'tests', path: '/repo/tests' }; +const nested = { kind: 'dir', name: 'nested', path: '/repo/src/nested' }; +const main = { kind: 'file', name: 'main.ts', path: '/repo/src/main.ts' }; +const deep = { kind: 'file', name: 'deep.ts', path: '/repo/src/nested/deep.ts' }; +const parent = { kind: 'parent', name: '..', path: '/repo' }; +const key = (runtime, model, key, extra = {}) => runtime.update({ type: 'key', key, ...extra }, model); +const text = (surface) => Array.from({ length: surface.height }, (_, y) => + Array.from({ length: surface.width }, (_, x) => surface.get(x, y).char).join('')).join('\n'); +async function setup() { + const { createWorkspaceRuntime } = await importDist('app', 'workspace', 'runtime.js'); + const { BijouI18nAdapter } = await importDist('adapters', 'bijou-i18n-adapter.js'); + const { availableJeditThemes } = await importDist('ui', 'jedit-themes.js'); + const deps = mockRuntime(); const reads = []; + deps.initialModel.entries = [src, tests]; + deps.initialModel.i18n = new BijouI18nAdapter(); deps.initialModel.jeditTheme = availableJeditThemes()[0]; + const children = new Map([['/repo', [src, tests]], ['/repo/src', [parent, nested, main]], ['/repo/src/nested', [parent, deep]], ['/repo/tests', []]]); + deps.fileSystem.loadEntries = (path) => { reads.push(path); return children.get(path) ?? []; }; + const runtime = createWorkspaceRuntime(deps); const initial = runtime.init()[0]; + return { runtime, deps, reads, model: { ...initial, fileDrawerOpen: true, fileDrawerProgress: 1, focusPane: 'files' } }; +} + +test('Enter toggles immediate children inline and nested collapse preserves sibling branches', async () => { + const { runtime, model, reads } = await setup(); + const [open, effects] = key(runtime, model, 'enter'); + assert.equal(open.cwd, model.cwd); assert.equal(open.textAuthority, model.textAuthority); assert.deepEqual(effects, []); + assert.deepEqual(open.entries, [src, nested, main, tests]); assert.deepEqual(reads, ['/repo/src']); + const nestedOpen = key(runtime, { ...open, selectedIndex: 1 }, 'enter')[0]; + assert.deepEqual(nestedOpen.entries, [src, nested, deep, main, tests]); + const both = key(runtime, { ...nestedOpen, selectedIndex: 4 }, 'enter')[0]; + assert.equal(both.fileTree[tests.path].expanded, true); + const closed = key(runtime, { ...both, selectedIndex: 0 }, 'enter')[0]; + assert.deepEqual(closed.entries, [src, tests]); assert.equal(closed.fileTree[tests.path].expanded, true); + assert.equal(closed.fileTree[deep.path], undefined); assert.equal(closed.selectedIndex, 0); + const reopened = key(runtime, closed, 'enter')[0]; + assert.deepEqual(reopened.entries, [src, nested, main, tests]); +}); + +test('Directory clicks toggle inline while file clicks only select and file Enter explicitly opens', async () => { + const { runtime, model } = await setup(); + const mouse = (model, row) => runtime.update({ type: 'mouse', action: 'press', button: 'left', col: 6, row }, model); + const [expanded] = mouse(model, 4); + assert.deepEqual(expanded.entries, [src, nested, main, tests]); assert.equal(expanded.cwd, model.cwd); + const [selected, effects] = mouse(expanded, 6); + assert.equal(selected.selectedIndex, 2); assert.equal(selected.entries[2], main); + assert.equal(selected.textAuthority, model.textAuthority); assert.deepEqual(effects, []); + const [opening, commands] = key(runtime, selected, 'enter'); + assert.equal(opening.textAuthority.filePath, main.path); assert.equal(commands.length, 1); + assert.deepEqual(mouse(expanded, 4)[0].entries, [src, tests]); +}); + +test('Right enters a child, Left selects its parent and collapses it without changing the root', async () => { + const { runtime, model } = await setup(); + const expanded = key(runtime, model, 'right')[0]; + const child = key(runtime, expanded, 'right')[0]; assert.equal(child.entries[child.selectedIndex], nested); + const up = key(runtime, child, 'left')[0]; assert.equal(up.selectedIndex, 0); assert.equal(up.cwd, model.cwd); + const closed = key(runtime, up, 'left')[0]; assert.deepEqual(closed.entries, [src, tests]); +}); + +test('Tree rows render nesting/disclosure and filters retain matching children with their ancestors', async () => { + const { runtime, model } = await setup(); + let next = key(runtime, model, 'enter')[0]; next = key(runtime, { ...next, selectedIndex: 1 }, 'enter')[0]; + const rendered = text(runtime.view(next)); assert.match(rendered, /▾ src\//); assert.match(rendered, / ▾ nested\//); + assert.match(rendered, / deep\.ts/); + const { fileSearchEntries, fileSearchWithInput } = await importDist('app', 'workspace', 'file-search.js'); + const filtered = fileSearchWithInput(next, { input: 'deep', cursorIndex: 4 }); + assert.deepEqual(fileSearchEntries(filtered).map(({ entry }) => entry.path), [src.path, nested.path, deep.path]); + assert.equal(filtered.entries, next.entries); +}); + +test('Unreadable directories preserve the tree and refresh resets expansion at the same root', async () => { + const { runtime, model, deps } = await setup(); + deps.fileSystem.loadEntries = () => { throw new Error('permission denied'); }; + const [failed] = key(runtime, model, 'enter'); assert.equal(failed.entries, model.entries); + assert.equal(failed.fileTree?.[src.path]?.expanded, undefined); assert.equal(failed.cwd, model.cwd); + assert.notEqual(failed.notifications, model.notifications); + const second = await setup(); const open = key(second.runtime, second.model, 'enter')[0]; + const refreshed = key(second.runtime, open, 'r')[0]; assert.deepEqual(refreshed.entries, [src, tests]); + assert.equal(refreshed.fileTree, undefined); assert.equal(refreshed.cwd, second.model.cwd); +}); + +test('Filtering selects the matching file and Right uses the visible first child', async () => { + const { runtime, model } = await setup(); + const open = key(runtime, model, 'enter')[0]; + const { fileSearchWithInput } = await importDist('app', 'workspace', 'file-search.js'); + const filtered = fileSearchWithInput(open, { input: 'main', cursorIndex: 4 }); + assert.equal(filtered.entries[filtered.selectedIndex], main); + const next = key(runtime, { ...filtered, selectedIndex: 0 }, 'right')[0]; + assert.equal(next.entries[next.selectedIndex], main); +}); diff --git a/spec/file-preview-syntax.spec.mjs b/spec/file-preview-syntax.spec.mjs new file mode 100644 index 00000000..1dc1d758 --- /dev/null +++ b/spec/file-preview-syntax.spec.mjs @@ -0,0 +1,81 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { importDist, mockRuntime } from './workspace-helpers.mjs'; +const entry = { kind: 'file', name: 'main.ts', path: '/repo/main.ts' }; +const key = (key, flags = {}) => ({ type: 'key', key, ...flags }); +async function setup(options = {}) { + const { createWorkspaceRuntime } = await importDist('app', 'workspace', 'runtime.js'); + const { BijouI18nAdapter } = await importDist('adapters', 'bijou-i18n-adapter.js'); + const { availableJeditThemes } = await importDist('ui', 'jedit-themes.js'); + const { createGraftSourceHighlighter } = await importDist('adapters', 'graft-source-highlighter.js'); + const deps = mockRuntime(); const reads = []; + deps.initialModel.entries = [entry]; deps.initialModel.i18n = new BijouI18nAdapter(); + deps.initialModel.jeditTheme = availableJeditThemes()[0]; + deps.previewHighlighter = options.highlighter ?? createGraftSourceHighlighter(); + deps.filePreviewSource = { loadFilePreview: (path) => { + reads.push(path); return { kind: 'loaded', lines: options.lines ?? ['export const answer = 42;'], truncated: options.truncated ?? false }; + } }; + const runtime = createWorkspaceRuntime(deps); + return { runtime, reads, model: { ...runtime.init()[0], ...options.model }, deps }; +} +async function preview(fixture) { + const [opened, commands] = fixture.runtime.update(key('b', { ctrl: true }), fixture.model); + const message = await commands.at(-1)(); + return fixture.runtime.update(message, { ...opened, fileDrawerProgress: 1 })[0]; +} +const rowText = (surface, row) => Array.from({ length: surface.width }, (_, x) => surface.get(x, row).char).join(''); + +test('Real Graft syntax colors reach the read-only preview without opening an Echo buffer', async () => { + const fixture = await setup(); const next = await preview(fixture); + assert.ok(next.fileExplorerPreview.highlight.spans.length > 0); + const { renderFileExplorerPreview } = await importDist('app', 'workspace', 'file-explorer-preview-view.js'); + const { JEDIT_SOURCE_TOKEN } = await importDist('ui', 'jedit-theme.js'); + const surface = renderFileExplorerPreview(next, 60, 12); + assert.match(rowText(surface, 3), /export const answer = 42/); + assert.equal(surface.get(1, 3).fg, next.jeditTheme.source.get(JEDIT_SOURCE_TOKEN.Keyword).fg); + assert.equal(surface.get(23, 3).fg, next.jeditTheme.source.get(JEDIT_SOURCE_TOKEN.Number).fg); + assert.equal(next.textAuthority, fixture.model.textAuthority); assert.equal(next.textRequestId, fixture.model.textRequestId); +}); + +test('Preview Graft projections omit an editor-head basis', async () => { + const { createGraftSourceHighlighter } = await importDist('adapters', 'graft-source-highlighter.js'); + const calls = []; + const highlighter = createGraftSourceHighlighter({ loadRuntime: async () => ({ ensureParserReady: async () => {}, + createProjectionBundle: (path, content, options) => { calls.push({ path, content, options }); return { syntax: { spans: [] } }; } }) }); + await highlighter.highlightPreview({ path: entry.path, text: 'const x = 1', startLine: 0, lineCount: 1 }); + assert.equal('basis' in calls[0].options, false); + await highlighter.highlight({ path: entry.path, text: 'const x = 1', startLine: 0, lineCount: 1, headId: 'real-head', tick: 2 }); + assert.deepEqual(calls[1].options.basis, { kind: 'editor_head', headId: 'real-head', tick: 2 }); +}); + +test('Unsaved preview text is highlighted without disk reads and parser failure keeps readable text', async () => { + const inputs = []; + const editor = { path: entry.path, lines: ['\tconst unsaved = 7;\u001b'], dirty: true }; + const fixture = await setup({ model: { editor }, highlighter: { highlightPreview: async (input) => { + inputs.push(input); throw new Error('parser unavailable'); + } } }); + const next = await preview(fixture); + assert.deepEqual(fixture.reads, []); assert.equal(inputs[0].text, ' const unsaved = 7;'); + assert.equal(next.editor, editor); assert.equal(next.textAuthority, fixture.model.textAuthority); + const { renderFileExplorerPreview } = await importDist('app', 'workspace', 'file-explorer-preview-view.js'); + assert.match(rowText(renderFileExplorerPreview(next, 60, 12), 3), /const unsaved = 7/); +}); + +test('Preview highlights align after tabs, wide Unicode and a truncation notice without coloring the notice', async () => { + const fixture = await setup({ lines: ['\tconst 界 = 42;'], truncated: true }); const next = await preview(fixture); + const { renderFileExplorerPreview } = await importDist('app', 'workspace', 'file-explorer-preview-view.js'); + const { JEDIT_SOURCE_TOKEN } = await importDist('ui', 'jedit-theme.js'); + const surface = renderFileExplorerPreview(next, 60, 12); + assert.match(rowText(surface, 3), /truncated/i); assert.match(rowText(surface, 4), /const.*42/); + assert.equal(surface.get(5, 4).fg, next.jeditTheme.source.get(JEDIT_SOURCE_TOKEN.Keyword).fg); + const x = Array.from({ length: surface.width }, (_, x) => x).find((x) => surface.get(x, 4).char === '4'); + assert.equal(surface.get(x, 4).fg, next.jeditTheme.source.get(JEDIT_SOURCE_TOKEN.Number).fg); +}); + +test('A late highlighted preview cannot repaint a closed drawer or a different selection', async () => { + const fixture = await setup(); const [opened, commands] = fixture.runtime.update(key('b', { ctrl: true }), fixture.model); + const [closed] = fixture.runtime.update(key('b', { ctrl: true }), opened); const message = await commands.at(-1)(); + assert.ok(message.highlight.spans.length > 0); + const [late] = fixture.runtime.update(message, closed); assert.equal(late.fileExplorerPreview, undefined); + assert.equal(late.textAuthority, fixture.model.textAuthority); +}); diff --git a/src/adapters/graft-source-highlighter.ts b/src/adapters/graft-source-highlighter.ts index 6987806a..e4576ec9 100644 --- a/src/adapters/graft-source-highlighter.ts +++ b/src/adapters/graft-source-highlighter.ts @@ -3,6 +3,7 @@ import { SOURCE_HIGHLIGHT_ROLE, type SourceHighlightReading, type SourceHighlighter, + type PreviewHighlighter, type PreviewHighlightInput, type SourceHighlightInput, type SourceHighlightRole, type SourceHighlightSpan, @@ -75,7 +76,7 @@ interface GraftProjectionBundle { } interface GraftProjectionOptions { - readonly basis: { + readonly basis?: { readonly kind: typeof EDITOR_HEAD_BASIS_KIND; readonly headId: string; readonly tick: number; @@ -166,42 +167,43 @@ export function createGraftSourceHighlighterProcessRunner(): GraftProcessRunner }; } -export function createGraftSourceHighlighter(options: GraftSourceHighlighterOptions = {}): SourceHighlighter { +export function createGraftSourceHighlighter(options: GraftSourceHighlighterOptions = {}): SourceHighlighter & PreviewHighlighter { const loadRuntime = options.loadRuntime ?? defaultRuntimeLoader(); return { - async highlight(input: SourceHighlightInput): Promise { - const runtime = await loadRuntime(); - await runtime.ensureParserReady(); - const bundle = readProjectionBundle(runtime, input); + highlight: (input) => highlightInput(loadRuntime, input), + highlightPreview: (input) => highlightInput(loadRuntime, input), + }; +} - return { - path: input.path, - partial: bundle.partial, - spans: graftSyntaxSpansToSourceHighlights(bundle.spans, input.textStartLine), - projection: input.projection, - ...(bundle.reason == null ? {} : { notice: bundle.reason }), - }; - }, +async function highlightInput( + loadRuntime: LoadGraftSourceHighlighterRuntime, + input: SourceHighlightInput | PreviewHighlightInput, +): Promise { + const runtime = await loadRuntime(); + await runtime.ensureParserReady(); + const bundle = readProjectionBundle(runtime, input); + const textStartLine = 'textStartLine' in input ? input.textStartLine : undefined; + return { + path: input.path, partial: bundle.partial, + spans: graftSyntaxSpansToSourceHighlights(bundle.spans, textStartLine), + projection: 'projection' in input ? input.projection : undefined, + ...(bundle.reason == null ? {} : { notice: bundle.reason }), }; } function readProjectionBundle( runtime: GraftSourceHighlighterRuntime, - input: SourceHighlightInput, + input: SourceHighlightInput | PreviewHighlightInput, ): { readonly partial: boolean; readonly spans: readonly GraftSyntaxSpan[]; readonly reason?: string; } { try { - const textStartLine = input.textStartLine ?? FIRST_PROJECTED_LINE; + const textStartLine = ('textStartLine' in input ? input.textStartLine : undefined) ?? FIRST_PROJECTED_LINE; const bundle = runtime.createProjectionBundle(input.path, input.text, { - basis: { - kind: EDITOR_HEAD_BASIS_KIND, - headId: input.headId, - tick: input.tick, - }, + ...projectionBasis(input), viewport: { start: { row: input.startLine - textStartLine, column: VIEWPORT_START_COLUMN }, end: { row: input.startLine - textStartLine + input.lineCount, column: VIEWPORT_END_COLUMN }, @@ -223,6 +225,10 @@ function readProjectionBundle( } } +function projectionBasis(input: SourceHighlightInput | PreviewHighlightInput): Pick { + return 'headId' in input ? { basis: { kind: EDITOR_HEAD_BASIS_KIND, headId: input.headId, tick: input.tick } } : {}; +} + export function graftSyntaxSpansToSourceHighlights( spans: readonly GraftSyntaxSpan[], textStartLine: number = FIRST_PROJECTED_LINE, diff --git a/src/adapters/workspace-app.ts b/src/adapters/workspace-app.ts index 5e037e12..0bc77e1b 100644 --- a/src/adapters/workspace-app.ts +++ b/src/adapters/workspace-app.ts @@ -68,6 +68,7 @@ function workspaceRuntimeDependencies( productionTextSession: productionText.productionTextSession, graftSession, sourceHighlighter, + previewHighlighter: sourceHighlighter, profiler: createRaytracerProfilerPort(nowMs), profileOnStartup: options.profileEnabled ?? false, initialModel: { diff --git a/src/app/workspace/directory-change-failure.ts b/src/app/workspace/directory-change-failure.ts new file mode 100644 index 00000000..a010e542 --- /dev/null +++ b/src/app/workspace/directory-change-failure.ts @@ -0,0 +1,22 @@ +import type { Cmd } from '@flyingrobots/bijou-tui'; +import type { DirectoryAction, FileSystemPort } from '../../ports/file-system.js'; +import { createNotificationTickCmd, pushErrorToast } from '../../ui/feedback.js'; +import type { WorkspaceModel } from './model.js'; +import { WorkspaceMessageTypes, type WorkspaceMsg } from './msg.js'; + +export interface DirectoryExpansionContext { + readonly fileSystem: FileSystemPort; + readonly nowMs: () => number; +} + +export function directoryChangeFailure( + model: WorkspaceModel, + path: string, + action: DirectoryAction, + cause: Error | string, + context: DirectoryExpansionContext, +): [WorkspaceModel, Cmd[]] { + const issue = context.fileSystem.describeDirectoryIssue(action, path, cause); + return pushErrorToast(model, issue.title, issue.message, context.nowMs(), + () => createNotificationTickCmd((atMs: number): WorkspaceMsg => ({ type: WorkspaceMessageTypes.NotificationTick, atMs }))); +} diff --git a/src/app/workspace/file-explorer-pointer.ts b/src/app/workspace/file-explorer-pointer.ts new file mode 100644 index 00000000..166ee664 --- /dev/null +++ b/src/app/workspace/file-explorer-pointer.ts @@ -0,0 +1,106 @@ +import type { Cmd, MouseMsg } from '@flyingrobots/bijou-tui'; +import { fileSearchCursorAtColumn } from '../../ui/file-search-input.js'; +import { fileSearchInputOptions, fileFilterPromptWidth, fileFilterPromptX } from '../../ui/workspace-file-filter-prompt.js'; +import { resolveWorkspaceLayout } from '../../ui/drawer-layout.js'; +import { FocusPanes } from '../../ui/panel-focus.js'; +import { fileSearchEntries, fileSearchState } from './file-search.js'; +import { DRAWER_INNER_PAD, listScrollOffset, workspaceBodyHeight, WORKSPACE_BODY_TOP_OFFSET, + FILE_SEARCH_ROW, FILE_SEARCH_LIST_TOP, fileSearchListHeight, workspaceFooterRows } from './viewport.js'; +import { toggleFileTreeDirectory } from './file-tree-expansion.js'; +import type { DirectoryExpansionContext } from './directory-change-failure.js'; +import type { WorkspaceModel } from './model.js'; +import type { WorkspaceMsg } from './msg.js'; + +const MOUSE_PRESS = 'press'; +const MOUSE_MOVE = 'move'; +const MOUSE_BUTTON_LEFT = 'left'; + +export function updateFileExplorerPointer( + msg: MouseMsg, + model: WorkspaceModel, + context?: DirectoryExpansionContext, +): [WorkspaceModel, Cmd[]] | undefined { + const hover = updateFileDrawerHover(msg, model); + if (hover != null) return [hover, []]; + const input = updateFooterFilterFromClick(msg, model) ?? updateFileSearchFromClick(msg, model); + if (input != null) return [input, []]; + const clicked = updateFileDrawerFromClick(msg, model); + if (clicked == null) return undefined; + return context == null ? [clicked, []] : toggleFileTreeDirectory(clicked, context); +} + +function updateFileDrawerFromClick( + msg: MouseMsg, + model: WorkspaceModel, +): WorkspaceModel | undefined { + if (msg.action !== MOUSE_PRESS || msg.button !== MOUSE_BUTTON_LEFT) { + return undefined; + } + const index = fileDrawerEntryIndexAt(msg, model); + return index == null + ? undefined + : { ...model, focusPane: FocusPanes.Files, selectedIndex: index, fileSearchEditing: false }; +} + +function fileDrawerEntryIndexAt( + msg: MouseMsg, + model: WorkspaceModel, +): number | undefined { + if (!fileDrawerPointerEnabled(model)) { + return undefined; + } + const drawer = resolveWorkspaceLayout( + model.columns, + model.fileDrawerProgress, + model.graftDrawerProgress, + ).fileDrawer; + const withinDrawer = drawer.width > 0 + && msg.col >= drawer.x + DRAWER_INNER_PAD + && msg.col < (drawer.x + drawer.width) - DRAWER_INNER_PAD; + if (!withinDrawer) { + return undefined; + } + const row = msg.row - WORKSPACE_BODY_TOP_OFFSET - FILE_SEARCH_LIST_TOP; + const listHeight = fileSearchListHeight(workspaceBodyHeight(model)); + if (row < 0 || row >= listHeight) { + return undefined; + } + const entries = fileSearchEntries(model); + const position = entries.findIndex(({ index }) => index === model.selectedIndex); + const index = row + listScrollOffset( + position, + entries.length, + listHeight, + ); + return entries[index]?.index; +} + +function updateFileDrawerHover(msg: MouseMsg, model: WorkspaceModel): WorkspaceModel | undefined { + if (msg.action !== MOUSE_MOVE) return undefined; + const index = fileDrawerEntryIndexAt(msg, model); + return model.fileHoveredIndex === index ? model : { ...model, fileHoveredIndex: index }; +} + +function fileDrawerPointerEnabled(model: WorkspaceModel): boolean { + return model.fileDrawerOpen && !model.settingsOpen && !model.quitConfirmOpen && + !model.startupFileModalOpen && !model.commandLine?.active; +} + +function updateFileSearchFromClick(msg: MouseMsg, model: WorkspaceModel): WorkspaceModel | undefined { + if (msg.action !== MOUSE_PRESS || msg.button !== MOUSE_BUTTON_LEFT || !fileDrawerPointerEnabled(model)) return undefined; + if (msg.row !== WORKSPACE_BODY_TOP_OFFSET + FILE_SEARCH_ROW) return undefined; + if (fileSearchState(model).input.length === 0) return undefined; + const layout = resolveWorkspaceLayout(model.columns, model.fileDrawerProgress, model.graftDrawerProgress).fileDrawer; + if (msg.col <= layout.x || msg.col >= layout.x + layout.width - DRAWER_INNER_PAD) return undefined; + return { ...model, focusPane: FocusPanes.Files, fileSearchEditing: true }; +} + +function updateFooterFilterFromClick(msg: MouseMsg, model: WorkspaceModel): WorkspaceModel | undefined { + if (!model.fileSearchEditing || !fileDrawerPointerEnabled(model)) return undefined; + if (msg.action !== MOUSE_PRESS || msg.button !== MOUSE_BUTTON_LEFT || msg.row !== model.rows - workspaceFooterRows(model)) return undefined; + const width = fileFilterPromptWidth(model); + const column = msg.col - fileFilterPromptX(model); + if (column < 0 || column >= width) return undefined; + return { ...model, fileSearch: { ...fileSearchState(model), + cursorIndex: fileSearchCursorAtColumn(fileSearchInputOptions(model, width), column) } }; +} diff --git a/src/app/workspace/file-explorer-preview-view.ts b/src/app/workspace/file-explorer-preview-view.ts index 89debbd0..1d604647 100644 --- a/src/app/workspace/file-explorer-preview-view.ts +++ b/src/app/workspace/file-explorer-preview-view.ts @@ -1,3 +1,5 @@ +import { paintPreviewSyntax } from '../../ui/file-preview-syntax.js'; +import { filePreviewSourceLines } from './file-preview-syntax.js'; import { createSurface, stringToSurface, type Surface } from '@flyingrobots/bijou'; import { FilePreviewKinds, type FilePreviewResult } from '../../ports/file-preview.js'; import { fitBlock } from '../../ui/workspace-render.js'; @@ -14,8 +16,6 @@ const PREVIEW_LOADING = 'fileExplorer.preview_loading'; const PREVIEW_BINARY = 'fileExplorer.preview_binary'; const PREVIEW_UNAVAILABLE = 'fileExplorer.preview_unavailable'; const PREVIEW_TRUNCATED = 'fileExplorer.preview_truncated'; -const TAB_SPACES = ' '; -const UNSAFE_CONTROLS = /[\p{Cc}\p{Cf}]/gu; export function renderFileExplorerPreview(model: WorkspaceModel, width: number, height: number): Surface | undefined { if (!fileExplorerHasFocus(model)) return undefined; @@ -34,6 +34,12 @@ export function renderFileExplorerPreview(model: WorkspaceModel, width: number, const body = stringToSurface(fitBlock(lines.join('\n'), innerWidth, bodyHeight), innerWidth, bodyHeight); applyBackground(body, model.jeditTheme.surface.workspace); surface.blit(body, PREVIEW_PAD, PREVIEW_BODY_TOP); + if (result?.kind === FilePreviewKinds.Loaded) { + const offset = result.truncated ? 1 : 0; + paintPreviewSyntax(surface, filePreviewSourceLines(result.lines), model.fileExplorerPreview?.highlight, { + x: PREVIEW_PAD, y: PREVIEW_BODY_TOP + offset, width: innerWidth, height: Math.max(0, bodyHeight - offset), theme: model.jeditTheme, + }); + } return surface; } @@ -41,6 +47,6 @@ function previewLines(model: WorkspaceModel, result: FilePreviewResult | undefin if (result == null) return [model.i18n.t(PREVIEW_LOADING)]; if (result.kind === FilePreviewKinds.Binary) return [model.i18n.t(PREVIEW_BINARY)]; if (result.kind === FilePreviewKinds.Unavailable) return [model.i18n.t(PREVIEW_UNAVAILABLE)]; - const lines = result.lines.map((line) => line.replaceAll('\t', TAB_SPACES).replace(UNSAFE_CONTROLS, '')); + const lines = filePreviewSourceLines(result.lines); return result.truncated ? [model.i18n.t(PREVIEW_TRUNCATED), ...lines] : lines; } diff --git a/src/app/workspace/file-explorer-preview.ts b/src/app/workspace/file-explorer-preview.ts index 16591f03..d5cf845e 100644 --- a/src/app/workspace/file-explorer-preview.ts +++ b/src/app/workspace/file-explorer-preview.ts @@ -1,3 +1,5 @@ +import type { PreviewHighlighter, SourceHighlightReading } from '../../ports/source-highlighter.js'; +import { highlightFilePreview } from './file-preview-syntax.js'; import type { Cmd } from '@flyingrobots/bijou-tui'; import { FilePreviewKinds, FILE_PREVIEW_MAX_LINES, type FilePreviewSource, type FilePreviewResult } from '../../ports/file-preview.js'; import { FileEntryKinds, type FileEntry } from '../../ports/file-system.js'; @@ -10,6 +12,7 @@ export interface FileExplorerPreview { readonly requestId: number; readonly entry: FileEntry; readonly result?: FilePreviewResult; + readonly highlight?: SourceHighlightReading; } export interface FileExplorerPreviewMessage extends FileExplorerPreview { @@ -18,15 +21,16 @@ export interface FileExplorerPreviewMessage extends FileExplorerPreview { type Result = [WorkspaceModel, Cmd[]]; -export function synchronizeFileExplorerPreview(result: Result, source: FilePreviewSource | undefined): Result { +export function synchronizeFileExplorerPreview(result: Result, source: FilePreviewSource | undefined, highlighter?: PreviewHighlighter): Result { const [model, commands] = result; const entry = fileExplorerHasFocus(model) ? selectedFileSearchEntry(model) : undefined; if (entry?.kind !== FileEntryKinds.File) return clearFileExplorerPreview(result); - if (model.fileExplorerPreview?.entry === entry || source == null) return result; + if (model.fileExplorerPreview?.entry === entry) return result; const requestId = (model.fileExplorerPreviewRequestId ?? 0) + 1; const preview = { requestId, entry, result: bufferPreview(model, entry.path) }; + if (preview.result == null && source == null) return result; const next = { ...model, fileExplorerPreviewRequestId: requestId, fileExplorerPreview: preview }; - return preview.result != null ? [next, commands] : [next, [...commands, loadPreviewCmd(preview, source)]]; + return [next, [...commands, ...previewLoadCommands(preview, source, highlighter)]]; } export function applyFileExplorerPreview(model: WorkspaceModel, msg: FileExplorerPreviewMessage): WorkspaceModel { @@ -50,11 +54,16 @@ function bufferPreview(model: WorkspaceModel, path: string): FilePreviewResult | }; } -function loadPreviewCmd(preview: FileExplorerPreview, source: FilePreviewSource): Cmd { - return () => { +function loadPreviewCmd(preview: FileExplorerPreview, source: FilePreviewSource | undefined, highlighter?: PreviewHighlighter): Cmd { + return async () => { let result: FilePreviewResult; - try { result = source.loadFilePreview(preview.entry.path); } + try { result = preview.result ?? source?.loadFilePreview(preview.entry.path) ?? { kind: FilePreviewKinds.Unavailable }; } catch { result = { kind: FilePreviewKinds.Unavailable }; } - return { type: WorkspaceMessageTypes.FileExplorerPreviewResult, ...preview, result }; + return { type: WorkspaceMessageTypes.FileExplorerPreviewResult, ...preview, result, + highlight: await highlightFilePreview(preview.entry.path, result, highlighter) }; }; } + +function previewLoadCommands(preview: FileExplorerPreview, source: FilePreviewSource | undefined, highlighter?: PreviewHighlighter): Cmd[] { + return preview.result != null && highlighter == null ? [] : [loadPreviewCmd(preview, source, highlighter)]; +} diff --git a/src/app/workspace/file-explorer-view.ts b/src/app/workspace/file-explorer-view.ts index 82379fdc..0a1a0c80 100644 --- a/src/app/workspace/file-explorer-view.ts +++ b/src/app/workspace/file-explorer-view.ts @@ -36,8 +36,8 @@ function paintFileSearchResults(surface: Surface, model: WorkspaceModel, width: const offset = listScrollOffset(selected, entries.length, height); const lines = entries.length === 0 ? [model.i18n.t(SEARCH_EMPTY_KEY)] - : entries.slice(offset, offset + height).map(({ entry, index }) => formatTreeLine(entry, { - selected: index === model.selectedIndex, + : entries.slice(offset, offset + height).map(({ entry, index, depth, expanded }) => formatTreeLine(entry, { + selected: index === model.selectedIndex, depth, expanded, })); const content = stringToSurface(fitBlock(lines.join('\n'), width, height), width, height); applyBackground(content, model.jeditTheme.surface.drawer); diff --git a/src/app/workspace/file-preview-syntax.ts b/src/app/workspace/file-preview-syntax.ts new file mode 100644 index 00000000..2478985b --- /dev/null +++ b/src/app/workspace/file-preview-syntax.ts @@ -0,0 +1,22 @@ +import type { PreviewHighlighter, SourceHighlightReading } from '../../ports/source-highlighter.js'; +import { FilePreviewKinds, type FilePreviewResult } from '../../ports/file-preview.js'; + +const TAB_SPACES = ' '; +const UNSAFE_CONTROLS = /[\p{Cc}\p{Cf}]/gu; + +export function filePreviewSourceLines(lines: readonly string[]): readonly string[] { + return lines.map((line) => line.replaceAll('\t', TAB_SPACES).replace(UNSAFE_CONTROLS, '')); +} + +export async function highlightFilePreview( + path: string, + result: FilePreviewResult, + highlighter: PreviewHighlighter | undefined, +): Promise { + if (result.kind !== FilePreviewKinds.Loaded || highlighter == null) return undefined; + const lines = filePreviewSourceLines(result.lines); + try { + const highlight = await highlighter.highlightPreview({ path, text: lines.join('\n'), startLine: 0, lineCount: lines.length }); + return highlight.path === path ? highlight : undefined; + } catch { return undefined; } +} diff --git a/src/app/workspace/file-search.ts b/src/app/workspace/file-search.ts index 055901a2..9e6871a5 100644 --- a/src/app/workspace/file-search.ts +++ b/src/app/workspace/file-search.ts @@ -14,6 +14,9 @@ export interface FileSearchEntry { readonly entry: FileEntry; readonly index: number; readonly matchIndexes: readonly number[]; + readonly depth?: number; + readonly expanded?: boolean; + readonly matchesQuery?: boolean; } export const EMPTY_FILE_SEARCH: FileSearchState = Object.freeze({ input: '', cursorIndex: 0 }); @@ -33,17 +36,35 @@ export function fileSearchHasFocus(model: WorkspaceModel): boolean { return fileExplorerHasFocus(model) && model.fileSearchEditing === true; } -export function fileSearchEntries(model: Pick): readonly FileSearchEntry[] { +type FileSearchModel = Pick; + +export function fileSearchEntries(model: FileSearchModel): readonly FileSearchEntry[] { const query = fileSearchState(model).input.toLowerCase(); - return model.entries.flatMap((entry, index) => { - if (query.length === 0) return [{ entry, index, matchIndexes: [] }]; + const matches = model.entries.flatMap((entry, index) => { + if (query.length === 0) return [{ entry, index, matchIndexes: [], matchesQuery: true }]; if (entry.kind === FileEntryKinds.Parent) return []; const path = fuzzyPathMatches(entry.name, query) != null ? entry.name : relativeFilePath(model.workspaceSearchRoot ?? model.workspaceRoot, entry); const matches = fuzzyPathMatches(path, query); if (matches == null) return []; const nameStart = Array.from(path).length - Array.from(entry.name).length; - return [{ entry, index, matchIndexes: matches.filter((offset) => offset >= nameStart).map((offset) => offset - nameStart) }]; + return [{ entry, index, matchesQuery: true, matchIndexes: matches.filter((offset) => offset >= nameStart).map((offset) => offset - nameStart) }]; }); + return withTreeAncestors(model, matches); +} + +function withTreeAncestors(model: FileSearchModel, matches: readonly FileSearchEntry[]): readonly FileSearchEntry[] { + const rows = new Map(matches.map((row) => [row.index, row])); + const included = new Set(matches.map((row) => row.entry.path)); + for (const match of matches) { + let parent = model.fileTree?.[match.entry.path]?.parentPath; + while (parent != null && !included.has(parent)) { + included.add(parent); + parent = model.fileTree?.[parent]?.parentPath; + } + } + return model.entries.flatMap((entry, index) => included.has(entry.path) + ? [{ ...(rows.get(index) ?? { entry, index, matchIndexes: [], matchesQuery: false }), ...model.fileTree?.[entry.path] }] + : []); } function relativeFilePath(root: string, entry: FileEntry): string { @@ -74,7 +95,7 @@ export function selectedFileSearchEntry(model: WorkspaceModel): FileEntry | unde export function fileSearchWithInput(model: WorkspaceModel, search: FileSearchState): WorkspaceModel { const next = { ...model, fileSearch: search, fileHoveredIndex: undefined }; - return { ...next, selectedIndex: fileSearchEntries(next)[0]?.index ?? NO_SELECTION }; + return { ...next, selectedIndex: fileSearchEntries(next).find((row) => row.matchesQuery !== false)?.index ?? NO_SELECTION }; } export function moveFileSearchSelection(model: WorkspaceModel, delta: number): WorkspaceModel { diff --git a/src/app/workspace/file-tree-expansion.ts b/src/app/workspace/file-tree-expansion.ts new file mode 100644 index 00000000..a5582fb6 --- /dev/null +++ b/src/app/workspace/file-tree-expansion.ts @@ -0,0 +1,97 @@ +import type { Cmd, KeyMsg } from '@flyingrobots/bijou-tui'; +import { DIRECTORY_ACTION_OPEN, FileEntryKinds } from '../../ports/file-system.js'; +import { directoryChangeFailure, type DirectoryExpansionContext } from './directory-change-failure.js'; +import { fileSearchEntries, selectedFileSearchEntry } from './file-search.js'; +import type { WorkspaceModel } from './model.js'; +import type { WorkspaceMsg } from './msg.js'; +import { WorkspaceKeys } from './workspace-key.js'; + +export interface FileTreeNode { + readonly depth: number; + readonly parentPath?: string; + readonly expanded: boolean; +} +const CHILD_DEPTH = 1; +const FIRST_CHILD_OFFSET = 1; +const NO_SELECTION = -1; +const COLLAPSE_KEYS = new Set([WorkspaceKeys.ArrowLeft, WorkspaceKeys.H]); +const TOGGLE_KEYS = new Set([WorkspaceKeys.Enter, WorkspaceKeys.Return]); +const EXPAND_KEYS = new Set([WorkspaceKeys.ArrowRight, WorkspaceKeys.L]); +type Result = [WorkspaceModel, Cmd[]]; + +export function toggleFileTreeDirectory(model: WorkspaceModel, context: DirectoryExpansionContext): Result { + const entry = selectedFileSearchEntry(model); + if (entry?.kind !== FileEntryKinds.Directory) return [model, []]; + if (model.fileTree?.[entry.path]?.expanded) return [collapseDirectory(model), []]; + try { return [expandDirectory(model, context), []]; } + catch (cause) { + return directoryChangeFailure(model, entry.path, DIRECTORY_ACTION_OPEN, cause instanceof Error ? cause : String(cause), context); + } +} + +export function updateInlineDirectoryKey(msg: KeyMsg, model: WorkspaceModel, context: DirectoryExpansionContext): Result | undefined { + const entry = selectedFileSearchEntry(model); + if (entry == null) return undefined; + if (COLLAPSE_KEYS.has(msg.key)) return collapseOrParent(model); + if (entry.kind !== FileEntryKinds.Directory) return undefined; + if (TOGGLE_KEYS.has(msg.key)) return toggleFileTreeDirectory(model, context); + if (!EXPAND_KEYS.has(msg.key)) return undefined; + return expandOrEnterChild(model, context); +} + +function expandOrEnterChild(model: WorkspaceModel, context: DirectoryExpansionContext): Result { + const entry = model.entries[model.selectedIndex]; + if (entry == null) return [model, []]; + if (!model.fileTree?.[entry.path]?.expanded) return toggleFileTreeDirectory(model, context); + const child = fileSearchEntries(model).find((row) => row.index > model.selectedIndex); + const parentPath = child == null ? undefined : model.fileTree?.[child.entry.path]?.parentPath; + return [parentPath === entry.path && child != null ? { ...model, selectedIndex: child.index } : model, []]; +} + +function collapseOrParent(model: WorkspaceModel): Result | undefined { + const entry = selectedFileSearchEntry(model); + if (entry == null) return undefined; + const node = model.fileTree?.[entry.path]; + if (node?.expanded) return [collapseDirectory(model), []]; + const parent = model.entries.findIndex((candidate) => candidate.path === node?.parentPath); + return parent < 0 ? undefined : [{ ...model, selectedIndex: parent, fileHoveredIndex: undefined }, []]; +} + +function expandDirectory(model: WorkspaceModel, context: DirectoryExpansionContext): WorkspaceModel { + const entry = model.entries[model.selectedIndex]; + if (entry == null) return model; + const node = model.fileTree?.[entry.path] ?? { depth: 0, expanded: false }; + const paths = new Set(model.entries.map((row) => row.path)); + const children = context.fileSystem.loadEntries(entry.path).filter((row) => row.kind !== FileEntryKinds.Parent && !paths.has(row.path)); + const fileTree = { ...model.fileTree, [entry.path]: { ...node, expanded: true } }; + for (const child of children) fileTree[child.path] = { depth: node.depth + CHILD_DEPTH, parentPath: entry.path, expanded: false }; + const entries = [...model.entries.slice(0, model.selectedIndex + FIRST_CHILD_OFFSET), ...children, + ...model.entries.slice(model.selectedIndex + FIRST_CHILD_OFFSET)]; + return { ...model, entries, fileTree, fileHoveredIndex: undefined }; +} + +function collapseDirectory(model: WorkspaceModel): WorkspaceModel { + const entry = model.entries[model.selectedIndex]; + if (entry == null) return model; + const node = model.fileTree?.[entry.path]; + if (node == null) return model; + const end = descendantEnd(model, node.depth); + const removed = new Set(model.entries.slice(model.selectedIndex + FIRST_CHILD_OFFSET, end).map((row) => row.path)); + const fileTree = Object.fromEntries(Object.entries(model.fileTree ?? {}).filter(([path]) => !removed.has(path))); + fileTree[entry.path] = { ...node, expanded: false }; + const next = { ...model, fileTree, entries: [...model.entries.slice(0, model.selectedIndex + FIRST_CHILD_OFFSET), ...model.entries.slice(end)], + fileHoveredIndex: undefined }; + const visible = fileSearchEntries(next); + return { ...next, selectedIndex: visible.some((row) => row.index === model.selectedIndex) ? model.selectedIndex : visible[0]?.index ?? NO_SELECTION }; +} + +function descendantEnd(model: WorkspaceModel, depth: number): number { + let end = model.selectedIndex + FIRST_CHILD_OFFSET; + while (end < model.entries.length && rowDepth(model, end) > depth) end += FIRST_CHILD_OFFSET; + return end; +} + +function rowDepth(model: WorkspaceModel, index: number): number { + const path = model.entries[index]?.path; + return path == null ? 0 : model.fileTree?.[path]?.depth ?? 0; +} diff --git a/src/app/workspace/file-tree.ts b/src/app/workspace/file-tree.ts index 139df40d..f5b06213 100644 --- a/src/app/workspace/file-tree.ts +++ b/src/app/workspace/file-tree.ts @@ -9,13 +9,14 @@ import { import type { EditorFilePort } from '../../ports/editor-file.js'; import type { GraftSessionPort } from '../../ports/graft-session.js'; import type { SourceHighlighter } from '../../ports/source-highlighter.js'; -import { createNotificationTickCmd, pushErrorToast } from '../../ui/feedback.js'; +import { directoryChangeFailure } from './directory-change-failure.js'; +import { updateInlineDirectoryKey } from './file-tree-expansion.js'; import { withFocusPane } from './focus.js'; import { isWorkspaceMarkdownFile } from './editor-session.js'; import { ViewModes } from './view-mode.js'; import { FocusPanes } from '../../ui/panel-focus.js'; import type { WorkspaceModel } from './model.js'; -import { WorkspaceMessageTypes, type WorkspaceMsg } from './msg.js'; +import type { WorkspaceMsg } from './msg.js'; import type { ProductionTextSession } from './production-text-session.js'; import { createWorkspaceTextOpenCmd, defaultWorkspaceTextAperture } from './workspace-text-commands.js'; import { pendingWorkspaceTextOpen } from './workspace-text-authority.js'; @@ -60,6 +61,8 @@ export function updateTreeFromKey( return [navigation, []]; } + const inline = updateInlineDirectoryKey(msg, model, { fileSystem: deps.fileSystem, nowMs }); + if (inline != null) return inline; if (isWorkspaceRefreshKey(msg)) { return changeDirectory(model, model.cwd, DIRECTORY_ACTION_REFRESH, nowMs, deps.fileSystem); } @@ -172,6 +175,8 @@ function openDirectory( ...model, cwd, entries: fileSystem.loadEntries(cwd), + fileTree: undefined, + fileHoveredIndex: undefined, selectedIndex: 0, }, cwd === model.cwd ? fileSearchState(model) : EMPTY_FILE_SEARCH); } @@ -186,17 +191,7 @@ function changeDirectory( try { return [openDirectory(model, cwd, fileSystem), []]; } catch (cause) { - const issue = fileSystem.describeDirectoryIssue(action, cwd, cause instanceof Error ? cause : String(cause)); - return pushErrorToast( - model, - issue.title, - issue.message, - nowMs(), - () => createNotificationTickCmd((atMs: number): WorkspaceMsg => ({ - type: WorkspaceMessageTypes.NotificationTick, - atMs, - })), - ); + return directoryChangeFailure(model, cwd, action, cause instanceof Error ? cause : String(cause), { fileSystem, nowMs }); } } diff --git a/src/app/workspace/model.ts b/src/app/workspace/model.ts index 871c44ed..a296e543 100644 --- a/src/app/workspace/model.ts +++ b/src/app/workspace/model.ts @@ -1,3 +1,4 @@ +import type { FileTreeNode } from './file-tree-expansion.js'; import type { FilepathStyle } from '../../ports/filepath-style.js'; import type { FooterLayout } from '../../ports/footer-preferences.js'; import type { NotificationState } from "@flyingrobots/bijou-tui"; @@ -35,6 +36,7 @@ export interface WorkspaceModel readonly cwd: string; readonly entries: readonly FileEntry[]; readonly selectedIndex: number; + readonly fileTree?: Readonly>; readonly fileSearch: FileSearchState; readonly fileSearchEditing: boolean; readonly fileHoveredIndex?: number; diff --git a/src/app/workspace/mouse.ts b/src/app/workspace/mouse.ts index 5dc5899e..86538305 100644 --- a/src/app/workspace/mouse.ts +++ b/src/app/workspace/mouse.ts @@ -1,5 +1,5 @@ -import { fileSearchCursorAtColumn } from '../../ui/file-search-input.js'; -import { fileSearchInputOptions, fileFilterPromptWidth, fileFilterPromptX } from '../../ui/workspace-file-filter-prompt.js'; +import { updateFileExplorerPointer } from './file-explorer-pointer.js'; +import type { DirectoryExpansionContext } from './directory-change-failure.js'; import type { Cmd, MouseMsg } from '@flyingrobots/bijou-tui'; import { mouseScrollDeltaRows, @@ -13,38 +13,19 @@ import { editorViewport } from './editor-session.js'; import { settingsRows } from './settings.js'; import type { SourceHighlighter } from '../../ports/source-highlighter.js'; import { ViewModes } from './view-mode.js'; -import { resolveWorkspaceLayout } from '../../ui/drawer-layout.js'; -import { - DRAWER_INNER_PAD, - listScrollOffset, - workspaceBodyHeight, - WORKSPACE_BODY_TOP_OFFSET, - FILE_SEARCH_ROW, - FILE_SEARCH_LIST_TOP, - fileSearchListHeight, - workspaceFooterRows, -} from './viewport.js'; import { FocusPanes } from '../../ui/panel-focus.js'; import { beginWorkspaceSourceHighlightRefresh } from './workspace-source-highlight.js'; -import { fileSearchEntries, fileSearchState, scrollFileSearchSelection } from './file-search.js'; +import { scrollFileSearchSelection } from './file-search.js'; -const MOUSE_PRESS = 'press'; -const MOUSE_MOVE = 'move'; -const MOUSE_BUTTON_LEFT = 'left'; export function updateFromMouse( msg: MouseMsg, model: WorkspaceModel, sourceHighlighter: SourceHighlighter, + directoryContext?: DirectoryExpansionContext, ): [WorkspaceModel, Cmd[]] { - const hover = updateFileDrawerHover(msg, model); - if (hover != null) return [hover, []]; - const input = updateFooterFilterFromClick(msg, model) ?? updateFileSearchFromClick(msg, model); - if (input != null) return [input, []]; - const clicked = updateFileDrawerFromClick(msg, model); - if (clicked != null) { - return [clicked, []]; - } + const pointer = updateFileExplorerPointer(msg, model, directoryContext); + if (pointer != null) return pointer; const deltaRows = mouseScrollDeltaRows(msg); if (deltaRows === 0) { return [model, []]; @@ -60,58 +41,6 @@ export function updateFromMouse( // (layout.fileDrawer.x, WORKSPACE_BODY_TOP_OFFSET) and its content is inset by // DRAWER_INNER_PAD. Filtered positions map through the scroll offset back to // original entry indexes. -function updateFileDrawerFromClick( - msg: MouseMsg, - model: WorkspaceModel, -): WorkspaceModel | undefined { - if (msg.action !== MOUSE_PRESS || msg.button !== MOUSE_BUTTON_LEFT) { - return undefined; - } - const index = fileDrawerEntryIndexAt(msg, model); - return index == null - ? undefined - : { ...model, focusPane: FocusPanes.Files, selectedIndex: index, fileSearchEditing: false }; -} - -function fileDrawerEntryIndexAt( - msg: MouseMsg, - model: WorkspaceModel, -): number | undefined { - if (!fileDrawerPointerEnabled(model)) { - return undefined; - } - const drawer = resolveWorkspaceLayout( - model.columns, - model.fileDrawerProgress, - model.graftDrawerProgress, - ).fileDrawer; - const withinDrawer = drawer.width > 0 - && msg.col >= drawer.x + DRAWER_INNER_PAD - && msg.col < (drawer.x + drawer.width) - DRAWER_INNER_PAD; - if (!withinDrawer) { - return undefined; - } - const row = msg.row - WORKSPACE_BODY_TOP_OFFSET - FILE_SEARCH_LIST_TOP; - const listHeight = fileSearchListHeight(workspaceBodyHeight(model)); - if (row < 0 || row >= listHeight) { - return undefined; - } - const entries = fileSearchEntries(model); - const position = entries.findIndex(({ index }) => index === model.selectedIndex); - const index = row + listScrollOffset( - position, - entries.length, - listHeight, - ); - return entries[index]?.index; -} - -function updateFileDrawerHover(msg: MouseMsg, model: WorkspaceModel): WorkspaceModel | undefined { - if (msg.action !== MOUSE_MOVE) return undefined; - const index = fileDrawerEntryIndexAt(msg, model); - return model.fileHoveredIndex === index ? model : { ...model, fileHoveredIndex: index }; -} - function updateScrollableDrawerFromMouse(model: WorkspaceModel, deltaRows: number): WorkspaceModel | undefined { if (model.settingsOpen) { return { @@ -131,20 +60,6 @@ function updateScrollableDrawerFromMouse(model: WorkspaceModel, deltaRows: numbe return undefined; } -function fileDrawerPointerEnabled(model: WorkspaceModel): boolean { - return model.fileDrawerOpen && !model.settingsOpen && !model.quitConfirmOpen && - !model.startupFileModalOpen && !model.commandLine?.active; -} - -function updateFileSearchFromClick(msg: MouseMsg, model: WorkspaceModel): WorkspaceModel | undefined { - if (msg.action !== MOUSE_PRESS || msg.button !== MOUSE_BUTTON_LEFT || !fileDrawerPointerEnabled(model)) return undefined; - if (msg.row !== WORKSPACE_BODY_TOP_OFFSET + FILE_SEARCH_ROW) return undefined; - if (fileSearchState(model).input.length === 0) return undefined; - const layout = resolveWorkspaceLayout(model.columns, model.fileDrawerProgress, model.graftDrawerProgress).fileDrawer; - if (msg.col <= layout.x || msg.col >= layout.x + layout.width - DRAWER_INNER_PAD) return undefined; - return { ...model, focusPane: FocusPanes.Files, fileSearchEditing: true }; -} - function updateEditorFromMouse( model: WorkspaceModel, deltaRows: number, @@ -164,13 +79,3 @@ function updateEditorFromMouse( function graftOutlineLength(model: WorkspaceModel): number { return model.graftInfo?.outlineItems.length ?? 0; } - -function updateFooterFilterFromClick(msg: MouseMsg, model: WorkspaceModel): WorkspaceModel | undefined { - if (!model.fileSearchEditing || !fileDrawerPointerEnabled(model)) return undefined; - if (msg.action !== MOUSE_PRESS || msg.button !== MOUSE_BUTTON_LEFT || msg.row !== model.rows - workspaceFooterRows(model)) return undefined; - const width = fileFilterPromptWidth(model); - const column = msg.col - fileFilterPromptX(model); - if (column < 0 || column >= width) return undefined; - return { ...model, fileSearch: { ...fileSearchState(model), - cursorIndex: fileSearchCursorAtColumn(fileSearchInputOptions(model, width), column) } }; -} diff --git a/src/app/workspace/runtime.ts b/src/app/workspace/runtime.ts index 62b7d907..02f84659 100644 --- a/src/app/workspace/runtime.ts +++ b/src/app/workspace/runtime.ts @@ -87,7 +87,7 @@ function updateWorkspaceRuntime( ): WorkspaceRuntimeResult { return synchronizeFileExplorerPreview(syncWorkspaceRuntimeResult( rebaseFrameClock(deps, model, updateWorkspaceRuntimeState(deps, msg, model)), - ), deps.filePreviewSource); + ), deps.filePreviewSource, deps.previewHighlighter); } // While the workspace is idle the tick handler returns the model untouched, so @@ -402,6 +402,7 @@ function updateWorkspaceInputMessage( msg, model, deps.sourceHighlighter, + { fileSystem: deps.fileSystem, nowMs: deps.nowMs }, ); } return msg.type === WorkspaceInputMessageTypes.Key diff --git a/src/app/workspace/workspace-runtime-dependencies.ts b/src/app/workspace/workspace-runtime-dependencies.ts index 02911fa0..22987d87 100644 --- a/src/app/workspace/workspace-runtime-dependencies.ts +++ b/src/app/workspace/workspace-runtime-dependencies.ts @@ -6,7 +6,7 @@ import type { EditorFilePort } from '../../ports/editor-file.js'; import type { FileSystemPort } from '../../ports/file-system.js'; import type { GraftDiagnosticsPort } from '../../ports/graft-diagnostics.js'; import type { GraftSessionPort } from '../../ports/graft-session.js'; -import type { SourceHighlighter } from '../../ports/source-highlighter.js'; +import type { SourceHighlighter, PreviewHighlighter } from '../../ports/source-highlighter.js'; import type { WorkspaceInitialModelSnapshot } from './init.js'; import type { CreateStartupFileDrawerAnimationCmd } from './key-binding-context.js'; import type { WorkspaceModel } from './model.js'; @@ -22,6 +22,7 @@ export type WorkspaceResizeMsg = ResizeMsg; export interface WorkspaceRuntimeDependencies { readonly footerPreferences?: FooterPreferencesPort; readonly filePreviewSource?: FilePreviewSource; + readonly previewHighlighter?: PreviewHighlighter; readonly initialColumns: number; readonly initialRows: number; readonly initialWorkingDirectory: string; diff --git a/src/generated/i18n.ts b/src/generated/i18n.ts index bb9ba803..49cc5140 100644 --- a/src/generated/i18n.ts +++ b/src/generated/i18n.ts @@ -214,47 +214,47 @@ export interface LocaleMetadata { readonly direction: LocaleDirection; } -export const en: TranslationSchema = {"footer":{"mode":{"browse":"browse","insert":"insert","normal":"normal","preview":"preview","settings":"settings","files":"files","graft":"graft","history":"history"},"context":{"settings":"settings","graft_empty":"open a file to inspect it","history_empty":"no Echo evidence yet","history_count":"Echo evidence: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k move","enter_change":"enter change","f2_close":"f2 close","esc_close":"esc close","j_k_scroll":"j/k scroll","f3_source":"f3 source","f3_preview":"f3 preview","text_input":"text input","esc_normal":"esc normal","ctrl_s_save":"ctrl+s save","ctrl_t_theme":"ctrl+t theme","tab_focus":"tab focus","tab_indent":"tab indent","ctrl_b_files":"ctrl+b files","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h history","enter_open":"enter open","backspace_up":"backspace up","ctrl_b_close":"ctrl+b close","enter_jump":"enter jump","r_refresh":"r refresh","ctrl_g_close":"ctrl+g close","ctrl_h_close":"ctrl+h close","i_insert":"i insert","o_open_line":"o open line","cc_line":"cc line","cw_word":"cw word","ce_word_end":"ce word-end","c0_start":"c0 start","c_end":"c$ end","dd_line":"dd line","dw_word":"dw word","de_word_end":"de word-end","d0_start":"d0 start","d_end":"d$ end","yy_line":"yy line","yw_word":"yw word","ye_word_end":"ye word-end","y0_start":"y0 start","y_end":"y$ end","gg_top":"gg top","esc_cancel":"esc cancel","type_filter":"type filter","arrows_select":"↑/↓ select","slash_filter":"/ filter"},"evidence":{"head":"head","tick":"tick","anchor":"anchor","coverage":"coverage","complete":"complete","partial":"partial","unavailable":"unavailable"},"status":{"nav":"nav","filter":"filter","read_only":"read-only","modified":"modified","modified_count":"{count} modified","pending_count":"{count} pending","buffer_count":"{count} buffers","loading":"loading"}},"history":{"title":"Echo History","empty":"No Echo evidence yet","header":"# tick kind status evidence summary"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Footer layout","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Filepaths","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Focused + workspace","footer_per_pane":"Per-pane + workspace","footer_compact":"Compact","paths_git_root":"Git root","paths_absolute":"Fully qualified"},"toast":{"changed_title":"Settings changed","save_failed_title":"Settings not saved","save_failed_message":"Could not save ~/.jimrc. Check its JSON and permissions. The setting is unchanged."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Search","placeholder":"Filter files…","empty":"No matches","preview_label":"Preview","preview_loading":"Loading preview…","preview_binary":"Binary file — preview unavailable","preview_unavailable":"Preview unavailable","preview_truncated":"Preview truncated"}}; +export const en: TranslationSchema = {"footer":{"mode":{"browse":"browse","insert":"insert","normal":"normal","preview":"preview","settings":"settings","files":"files","graft":"graft","history":"history"},"context":{"settings":"settings","graft_empty":"open a file to inspect it","history_empty":"no Echo evidence yet","history_count":"Echo evidence: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k move","enter_change":"enter change","f2_close":"f2 close","esc_close":"esc close","j_k_scroll":"j/k scroll","f3_source":"f3 source","f3_preview":"f3 preview","text_input":"text input","esc_normal":"esc normal","ctrl_s_save":"ctrl+s save","ctrl_t_theme":"ctrl+t theme","tab_focus":"tab focus","tab_indent":"tab indent","ctrl_b_files":"ctrl+b files","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h history","enter_open":"enter open / toggle","backspace_up":"backspace up","ctrl_b_close":"ctrl+b close","enter_jump":"enter jump","r_refresh":"r refresh","ctrl_g_close":"ctrl+g close","ctrl_h_close":"ctrl+h close","i_insert":"i insert","o_open_line":"o open line","cc_line":"cc line","cw_word":"cw word","ce_word_end":"ce word-end","c0_start":"c0 start","c_end":"c$ end","dd_line":"dd line","dw_word":"dw word","de_word_end":"de word-end","d0_start":"d0 start","d_end":"d$ end","yy_line":"yy line","yw_word":"yw word","ye_word_end":"ye word-end","y0_start":"y0 start","y_end":"y$ end","gg_top":"gg top","esc_cancel":"esc cancel","type_filter":"type filter","arrows_select":"↑/↓ select","slash_filter":"/ filter"},"evidence":{"head":"head","tick":"tick","anchor":"anchor","coverage":"coverage","complete":"complete","partial":"partial","unavailable":"unavailable"},"status":{"nav":"nav","filter":"filter","read_only":"read-only","modified":"modified","modified_count":"{count} modified","pending_count":"{count} pending","buffer_count":"{count} buffers","loading":"loading"}},"history":{"title":"Echo History","empty":"No Echo evidence yet","header":"# tick kind status evidence summary"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Footer layout","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Filepaths","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Focused + workspace","footer_per_pane":"Per-pane + workspace","footer_compact":"Compact","paths_git_root":"Git root","paths_absolute":"Fully qualified"},"toast":{"changed_title":"Settings changed","save_failed_title":"Settings not saved","save_failed_message":"Could not save ~/.jimrc. Check its JSON and permissions. The setting is unchanged."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Search","placeholder":"Filter files…","empty":"No matches","preview_label":"Preview","preview_loading":"Loading preview…","preview_binary":"Binary file — preview unavailable","preview_unavailable":"Preview unavailable","preview_truncated":"Preview truncated"}}; -export const fr: TranslationSchema = {"footer":{"mode":{"browse":"parcourir","insert":"insertion","normal":"normal","preview":"aperçu","settings":"paramètres","files":"fichiers","graft":"graft","history":"historique"},"context":{"settings":"paramètres","graft_empty":"ouvrez un fichier pour l'inspecter","history_empty":"pas encore de preuve Echo","history_count":"Preuves Echo : {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k déplacer","enter_change":"enter changer","f2_close":"f2 fermer","esc_close":"esc fermer","j_k_scroll":"j/k défiler","f3_source":"f3 source","f3_preview":"f3 aperçu","text_input":"saisie texte","esc_normal":"esc normal","ctrl_s_save":"ctrl+s enregistrer","ctrl_t_theme":"ctrl+t thème","tab_focus":"tab focus","tab_indent":"tab retrait","ctrl_b_files":"ctrl+b fichiers","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h historique","enter_open":"enter ouvrir","backspace_up":"backspace haut","ctrl_b_close":"ctrl+b fermer","enter_jump":"enter aller","r_refresh":"r actualiser","ctrl_g_close":"ctrl+g fermer","ctrl_h_close":"ctrl+h fermer","i_insert":"i insérer","o_open_line":"o ouvrir ligne","cc_line":"cc ligne","cw_word":"cw mot","ce_word_end":"ce fin mot","c0_start":"c0 début","c_end":"c$ fin","dd_line":"dd ligne","dw_word":"dw mot","de_word_end":"de fin mot","d0_start":"d0 début","d_end":"d$ fin","yy_line":"yy ligne","yw_word":"yw mot","ye_word_end":"ye fin mot","y0_start":"y0 début","y_end":"y$ fin","gg_top":"gg haut","esc_cancel":"esc annuler","type_filter":"saisir le filtre","arrows_select":"↑/↓ sélectionner","slash_filter":"/ filtrer"},"evidence":{"head":"tête","tick":"tick","anchor":"ancre","coverage":"couverture","complete":"complète","partial":"partielle","unavailable":"indisponible"},"status":{"nav":"navigation","filter":"filtre","read_only":"lecture seule","modified":"modifié","modified_count":"{count} modifiés","pending_count":"{count} en attente","buffer_count":"{count} tampons","loading":"chargement"}},"history":{"title":"Historique Echo","empty":"Pas encore de preuve Echo","header":"# tick type statut preuve résumé"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Disposition du pied","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Chemins","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Focus + espace","footer_per_pane":"Par panneau + espace","footer_compact":"Compact","paths_git_root":"Racine Git","paths_absolute":"Chemins absolus"},"toast":{"changed_title":"Settings changed","save_failed_title":"Réglages non enregistrés","save_failed_message":"Impossible d’enregistrer ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Recherche","placeholder":"Filtrer les fichiers…","empty":"Aucun résultat","preview_label":"Aperçu","preview_loading":"Chargement de l’aperçu…","preview_binary":"Fichier binaire — aperçu indisponible","preview_unavailable":"Aperçu indisponible","preview_truncated":"Aperçu tronqué"}}; +export const fr: TranslationSchema = {"footer":{"mode":{"browse":"parcourir","insert":"insertion","normal":"normal","preview":"aperçu","settings":"paramètres","files":"fichiers","graft":"graft","history":"historique"},"context":{"settings":"paramètres","graft_empty":"ouvrez un fichier pour l'inspecter","history_empty":"pas encore de preuve Echo","history_count":"Preuves Echo : {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k déplacer","enter_change":"enter changer","f2_close":"f2 fermer","esc_close":"esc fermer","j_k_scroll":"j/k défiler","f3_source":"f3 source","f3_preview":"f3 aperçu","text_input":"saisie texte","esc_normal":"esc normal","ctrl_s_save":"ctrl+s enregistrer","ctrl_t_theme":"ctrl+t thème","tab_focus":"tab focus","tab_indent":"tab retrait","ctrl_b_files":"ctrl+b fichiers","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h historique","enter_open":"entrée ouvrir / déplier","backspace_up":"backspace haut","ctrl_b_close":"ctrl+b fermer","enter_jump":"enter aller","r_refresh":"r actualiser","ctrl_g_close":"ctrl+g fermer","ctrl_h_close":"ctrl+h fermer","i_insert":"i insérer","o_open_line":"o ouvrir ligne","cc_line":"cc ligne","cw_word":"cw mot","ce_word_end":"ce fin mot","c0_start":"c0 début","c_end":"c$ fin","dd_line":"dd ligne","dw_word":"dw mot","de_word_end":"de fin mot","d0_start":"d0 début","d_end":"d$ fin","yy_line":"yy ligne","yw_word":"yw mot","ye_word_end":"ye fin mot","y0_start":"y0 début","y_end":"y$ fin","gg_top":"gg haut","esc_cancel":"esc annuler","type_filter":"saisir le filtre","arrows_select":"↑/↓ sélectionner","slash_filter":"/ filtrer"},"evidence":{"head":"tête","tick":"tick","anchor":"ancre","coverage":"couverture","complete":"complète","partial":"partielle","unavailable":"indisponible"},"status":{"nav":"navigation","filter":"filtre","read_only":"lecture seule","modified":"modifié","modified_count":"{count} modifiés","pending_count":"{count} en attente","buffer_count":"{count} tampons","loading":"chargement"}},"history":{"title":"Historique Echo","empty":"Pas encore de preuve Echo","header":"# tick type statut preuve résumé"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Disposition du pied","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Chemins","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Focus + espace","footer_per_pane":"Par panneau + espace","footer_compact":"Compact","paths_git_root":"Racine Git","paths_absolute":"Chemins absolus"},"toast":{"changed_title":"Settings changed","save_failed_title":"Réglages non enregistrés","save_failed_message":"Impossible d’enregistrer ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Recherche","placeholder":"Filtrer les fichiers…","empty":"Aucun résultat","preview_label":"Aperçu","preview_loading":"Chargement de l’aperçu…","preview_binary":"Fichier binaire — aperçu indisponible","preview_unavailable":"Aperçu indisponible","preview_truncated":"Aperçu tronqué"}}; -export const it: TranslationSchema = {"footer":{"mode":{"browse":"sfoglia","insert":"inserisci","normal":"normale","preview":"anteprima","settings":"impostazioni","files":"file","graft":"graft","history":"cronologia"},"context":{"settings":"impostazioni","graft_empty":"apri un file per ispezionarlo","history_empty":"nessuna prova Echo ancora","history_count":"Prove Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k muovi","enter_change":"enter cambia","f2_close":"f2 chiudi","esc_close":"esc chiudi","j_k_scroll":"j/k scorri","f3_source":"f3 sorgente","f3_preview":"f3 anteprima","text_input":"testo","esc_normal":"esc normale","ctrl_s_save":"ctrl+s salva","ctrl_t_theme":"ctrl+t tema","tab_focus":"tab focus","tab_indent":"tab rientra","ctrl_b_files":"ctrl+b file","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h cronologia","enter_open":"enter apri","backspace_up":"backspace su","ctrl_b_close":"ctrl+b chiudi","enter_jump":"enter vai","r_refresh":"r aggiorna","ctrl_g_close":"ctrl+g chiudi","ctrl_h_close":"ctrl+h chiudi","i_insert":"i inserisci","o_open_line":"o apri riga","cc_line":"cc riga","cw_word":"cw parola","ce_word_end":"ce fine parola","c0_start":"c0 inizio","c_end":"c$ fine","dd_line":"dd riga","dw_word":"dw parola","de_word_end":"de fine parola","d0_start":"d0 inizio","d_end":"d$ fine","yy_line":"yy riga","yw_word":"yw parola","ye_word_end":"ye fine parola","y0_start":"y0 inizio","y_end":"y$ fine","gg_top":"gg cima","esc_cancel":"esc annulla","type_filter":"digita filtro","arrows_select":"↑/↓ seleziona","slash_filter":"/ filtra"},"evidence":{"head":"testa","tick":"tick","anchor":"ancora","coverage":"copertura","complete":"completa","partial":"parziale","unavailable":"non disponibile"},"status":{"nav":"navigazione","filter":"filtro","read_only":"sola lettura","modified":"modificato","modified_count":"{count} modificati","pending_count":"{count} in attesa","buffer_count":"{count} buffer","loading":"caricamento"}},"history":{"title":"Cronologia Echo","empty":"Nessuna prova Echo ancora","header":"# tick tipo stato prova riepilogo"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Layout piè di pagina","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Percorsi","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Focus + area di lavoro","footer_per_pane":"Pannelli + area lavoro","footer_compact":"Compatto","paths_git_root":"Radice Git","paths_absolute":"Percorsi assoluti"},"toast":{"changed_title":"Settings changed","save_failed_title":"Impostazioni non salvate","save_failed_message":"Impossibile salvare ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Cerca","placeholder":"Filtra file…","empty":"Nessun risultato","preview_label":"Anteprima","preview_loading":"Caricamento anteprima…","preview_binary":"File binario — anteprima non disponibile","preview_unavailable":"Anteprima non disponibile","preview_truncated":"Anteprima troncata"}}; +export const it: TranslationSchema = {"footer":{"mode":{"browse":"sfoglia","insert":"inserisci","normal":"normale","preview":"anteprima","settings":"impostazioni","files":"file","graft":"graft","history":"cronologia"},"context":{"settings":"impostazioni","graft_empty":"apri un file per ispezionarlo","history_empty":"nessuna prova Echo ancora","history_count":"Prove Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k muovi","enter_change":"enter cambia","f2_close":"f2 chiudi","esc_close":"esc chiudi","j_k_scroll":"j/k scorri","f3_source":"f3 sorgente","f3_preview":"f3 anteprima","text_input":"testo","esc_normal":"esc normale","ctrl_s_save":"ctrl+s salva","ctrl_t_theme":"ctrl+t tema","tab_focus":"tab focus","tab_indent":"tab rientra","ctrl_b_files":"ctrl+b file","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h cronologia","enter_open":"invio apri / espandi","backspace_up":"backspace su","ctrl_b_close":"ctrl+b chiudi","enter_jump":"enter vai","r_refresh":"r aggiorna","ctrl_g_close":"ctrl+g chiudi","ctrl_h_close":"ctrl+h chiudi","i_insert":"i inserisci","o_open_line":"o apri riga","cc_line":"cc riga","cw_word":"cw parola","ce_word_end":"ce fine parola","c0_start":"c0 inizio","c_end":"c$ fine","dd_line":"dd riga","dw_word":"dw parola","de_word_end":"de fine parola","d0_start":"d0 inizio","d_end":"d$ fine","yy_line":"yy riga","yw_word":"yw parola","ye_word_end":"ye fine parola","y0_start":"y0 inizio","y_end":"y$ fine","gg_top":"gg cima","esc_cancel":"esc annulla","type_filter":"digita filtro","arrows_select":"↑/↓ seleziona","slash_filter":"/ filtra"},"evidence":{"head":"testa","tick":"tick","anchor":"ancora","coverage":"copertura","complete":"completa","partial":"parziale","unavailable":"non disponibile"},"status":{"nav":"navigazione","filter":"filtro","read_only":"sola lettura","modified":"modificato","modified_count":"{count} modificati","pending_count":"{count} in attesa","buffer_count":"{count} buffer","loading":"caricamento"}},"history":{"title":"Cronologia Echo","empty":"Nessuna prova Echo ancora","header":"# tick tipo stato prova riepilogo"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Layout piè di pagina","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Percorsi","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Focus + area di lavoro","footer_per_pane":"Pannelli + area lavoro","footer_compact":"Compatto","paths_git_root":"Radice Git","paths_absolute":"Percorsi assoluti"},"toast":{"changed_title":"Settings changed","save_failed_title":"Impostazioni non salvate","save_failed_message":"Impossibile salvare ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Cerca","placeholder":"Filtra file…","empty":"Nessun risultato","preview_label":"Anteprima","preview_loading":"Caricamento anteprima…","preview_binary":"File binario — anteprima non disponibile","preview_unavailable":"Anteprima non disponibile","preview_truncated":"Anteprima troncata"}}; -export const de: TranslationSchema = {"footer":{"mode":{"browse":"durchsuchen","insert":"einfügen","normal":"normal","preview":"vorschau","settings":"einstellungen","files":"dateien","graft":"graft","history":"verlauf"},"context":{"settings":"einstellungen","graft_empty":"datei öffnen zum prüfen","history_empty":"noch keine Echo-Nachweise","history_count":"Echo-Nachweise: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k bewegen","enter_change":"enter ändern","f2_close":"f2 schließen","esc_close":"esc schließen","j_k_scroll":"j/k scrollen","f3_source":"f3 quelltext","f3_preview":"f3 vorschau","text_input":"texteingabe","esc_normal":"esc normal","ctrl_s_save":"ctrl+s speichern","ctrl_t_theme":"ctrl+t theme","tab_focus":"tab fokus","tab_indent":"tab einrücken","ctrl_b_files":"ctrl+b dateien","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h verlauf","enter_open":"enter öffnen","backspace_up":"backspace hoch","ctrl_b_close":"ctrl+b schließen","enter_jump":"enter springen","r_refresh":"r aktualisieren","ctrl_g_close":"ctrl+g schließen","ctrl_h_close":"ctrl+h schließen","i_insert":"i einfügen","o_open_line":"o zeile öffnen","cc_line":"cc zeile","cw_word":"cw wort","ce_word_end":"ce wortende","c0_start":"c0 anfang","c_end":"c$ ende","dd_line":"dd zeile","dw_word":"dw wort","de_word_end":"de wortende","d0_start":"d0 anfang","d_end":"d$ ende","yy_line":"yy zeile","yw_word":"yw wort","ye_word_end":"ye wortende","y0_start":"y0 anfang","y_end":"y$ ende","gg_top":"gg oben","esc_cancel":"esc abbrechen","type_filter":"Filter eingeben","arrows_select":"↑/↓ auswählen","slash_filter":"/ filtern"},"evidence":{"head":"Kopf","tick":"Tick","anchor":"Anker","coverage":"Abdeckung","complete":"vollständig","partial":"teilweise","unavailable":"nicht verfügbar"},"status":{"nav":"Navigation","filter":"Filter","read_only":"schreibgeschützt","modified":"geändert","modified_count":"{count} geändert","pending_count":"{count} ausstehend","buffer_count":"{count} Puffer","loading":"wird geladen"}},"history":{"title":"Echo-Verlauf","empty":"Noch keine Echo-Nachweise","header":"# tick art status nachweis zusammenfassung"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Fußzeilenlayout","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Dateipfade","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Fokus + Arbeitsbereich","footer_per_pane":"Je Bereich + global","footer_compact":"Kompakt","paths_git_root":"Git-Wurzel","paths_absolute":"Vollständige Pfade"},"toast":{"changed_title":"Settings changed","save_failed_title":"Nicht gespeichert","save_failed_message":"~/.jimrc konnte nicht gespeichert werden."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Suche","placeholder":"Dateien filtern…","empty":"Keine Treffer","preview_label":"Vorschau","preview_loading":"Vorschau wird geladen…","preview_binary":"Binärdatei — keine Vorschau","preview_unavailable":"Vorschau nicht verfügbar","preview_truncated":"Vorschau gekürzt"}}; +export const de: TranslationSchema = {"footer":{"mode":{"browse":"durchsuchen","insert":"einfügen","normal":"normal","preview":"vorschau","settings":"einstellungen","files":"dateien","graft":"graft","history":"verlauf"},"context":{"settings":"einstellungen","graft_empty":"datei öffnen zum prüfen","history_empty":"noch keine Echo-Nachweise","history_count":"Echo-Nachweise: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k bewegen","enter_change":"enter ändern","f2_close":"f2 schließen","esc_close":"esc schließen","j_k_scroll":"j/k scrollen","f3_source":"f3 quelltext","f3_preview":"f3 vorschau","text_input":"texteingabe","esc_normal":"esc normal","ctrl_s_save":"ctrl+s speichern","ctrl_t_theme":"ctrl+t theme","tab_focus":"tab fokus","tab_indent":"tab einrücken","ctrl_b_files":"ctrl+b dateien","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h verlauf","enter_open":"eingabe öffnen / aufklappen","backspace_up":"backspace hoch","ctrl_b_close":"ctrl+b schließen","enter_jump":"enter springen","r_refresh":"r aktualisieren","ctrl_g_close":"ctrl+g schließen","ctrl_h_close":"ctrl+h schließen","i_insert":"i einfügen","o_open_line":"o zeile öffnen","cc_line":"cc zeile","cw_word":"cw wort","ce_word_end":"ce wortende","c0_start":"c0 anfang","c_end":"c$ ende","dd_line":"dd zeile","dw_word":"dw wort","de_word_end":"de wortende","d0_start":"d0 anfang","d_end":"d$ ende","yy_line":"yy zeile","yw_word":"yw wort","ye_word_end":"ye wortende","y0_start":"y0 anfang","y_end":"y$ ende","gg_top":"gg oben","esc_cancel":"esc abbrechen","type_filter":"Filter eingeben","arrows_select":"↑/↓ auswählen","slash_filter":"/ filtern"},"evidence":{"head":"Kopf","tick":"Tick","anchor":"Anker","coverage":"Abdeckung","complete":"vollständig","partial":"teilweise","unavailable":"nicht verfügbar"},"status":{"nav":"Navigation","filter":"Filter","read_only":"schreibgeschützt","modified":"geändert","modified_count":"{count} geändert","pending_count":"{count} ausstehend","buffer_count":"{count} Puffer","loading":"wird geladen"}},"history":{"title":"Echo-Verlauf","empty":"Noch keine Echo-Nachweise","header":"# tick art status nachweis zusammenfassung"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Fußzeilenlayout","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Dateipfade","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Fokus + Arbeitsbereich","footer_per_pane":"Je Bereich + global","footer_compact":"Kompakt","paths_git_root":"Git-Wurzel","paths_absolute":"Vollständige Pfade"},"toast":{"changed_title":"Settings changed","save_failed_title":"Nicht gespeichert","save_failed_message":"~/.jimrc konnte nicht gespeichert werden."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Suche","placeholder":"Dateien filtern…","empty":"Keine Treffer","preview_label":"Vorschau","preview_loading":"Vorschau wird geladen…","preview_binary":"Binärdatei — keine Vorschau","preview_unavailable":"Vorschau nicht verfügbar","preview_truncated":"Vorschau gekürzt"}}; -export const es: TranslationSchema = {"footer":{"mode":{"browse":"explorar","insert":"insertar","normal":"normal","preview":"vista previa","settings":"ajustes","files":"archivos","graft":"graft","history":"historial"},"context":{"settings":"ajustes","graft_empty":"abre un archivo para inspeccionarlo","history_empty":"sin evidencia Echo todavía","history_count":"Evidencia Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k mover","enter_change":"enter cambiar","f2_close":"f2 cerrar","esc_close":"esc cerrar","j_k_scroll":"j/k desplazar","f3_source":"f3 fuente","f3_preview":"f3 vista previa","text_input":"texto","esc_normal":"esc normal","ctrl_s_save":"ctrl+s guardar","ctrl_t_theme":"ctrl+t tema","tab_focus":"tab foco","tab_indent":"tab sangría","ctrl_b_files":"ctrl+b archivos","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h historial","enter_open":"enter abrir","backspace_up":"backspace arriba","ctrl_b_close":"ctrl+b cerrar","enter_jump":"enter saltar","r_refresh":"r actualizar","ctrl_g_close":"ctrl+g cerrar","ctrl_h_close":"ctrl+h cerrar","i_insert":"i insertar","o_open_line":"o abrir línea","cc_line":"cc línea","cw_word":"cw palabra","ce_word_end":"ce fin palabra","c0_start":"c0 inicio","c_end":"c$ fin","dd_line":"dd línea","dw_word":"dw palabra","de_word_end":"de fin palabra","d0_start":"d0 inicio","d_end":"d$ fin","yy_line":"yy línea","yw_word":"yw palabra","ye_word_end":"ye fin palabra","y0_start":"y0 inicio","y_end":"y$ fin","gg_top":"gg arriba","esc_cancel":"esc cancelar","type_filter":"escribir filtro","arrows_select":"↑/↓ seleccionar","slash_filter":"/ filtrar"},"evidence":{"head":"cabeza","tick":"tick","anchor":"ancla","coverage":"cobertura","complete":"completa","partial":"parcial","unavailable":"no disponible"},"status":{"nav":"navegación","filter":"filtro","read_only":"solo lectura","modified":"modificado","modified_count":"{count} modificados","pending_count":"{count} pendientes","buffer_count":"{count} búferes","loading":"cargando"}},"history":{"title":"Historial Echo","empty":"Sin evidencia Echo todavía","header":"# tick tipo estado evidencia resumen"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Diseño del pie","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Rutas","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Foco + espacio","footer_per_pane":"Por panel + espacio","footer_compact":"Compacto","paths_git_root":"Raíz de Git","paths_absolute":"Rutas absolutas"},"toast":{"changed_title":"Settings changed","save_failed_title":"Ajustes no guardados","save_failed_message":"No se pudo guardar ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Buscar","placeholder":"Filtrar archivos…","empty":"Sin resultados","preview_label":"Vista previa","preview_loading":"Cargando vista previa…","preview_binary":"Archivo binario — sin vista previa","preview_unavailable":"Vista previa no disponible","preview_truncated":"Vista previa truncada"}}; +export const es: TranslationSchema = {"footer":{"mode":{"browse":"explorar","insert":"insertar","normal":"normal","preview":"vista previa","settings":"ajustes","files":"archivos","graft":"graft","history":"historial"},"context":{"settings":"ajustes","graft_empty":"abre un archivo para inspeccionarlo","history_empty":"sin evidencia Echo todavía","history_count":"Evidencia Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k mover","enter_change":"enter cambiar","f2_close":"f2 cerrar","esc_close":"esc cerrar","j_k_scroll":"j/k desplazar","f3_source":"f3 fuente","f3_preview":"f3 vista previa","text_input":"texto","esc_normal":"esc normal","ctrl_s_save":"ctrl+s guardar","ctrl_t_theme":"ctrl+t tema","tab_focus":"tab foco","tab_indent":"tab sangría","ctrl_b_files":"ctrl+b archivos","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h historial","enter_open":"intro abrir / desplegar","backspace_up":"backspace arriba","ctrl_b_close":"ctrl+b cerrar","enter_jump":"enter saltar","r_refresh":"r actualizar","ctrl_g_close":"ctrl+g cerrar","ctrl_h_close":"ctrl+h cerrar","i_insert":"i insertar","o_open_line":"o abrir línea","cc_line":"cc línea","cw_word":"cw palabra","ce_word_end":"ce fin palabra","c0_start":"c0 inicio","c_end":"c$ fin","dd_line":"dd línea","dw_word":"dw palabra","de_word_end":"de fin palabra","d0_start":"d0 inicio","d_end":"d$ fin","yy_line":"yy línea","yw_word":"yw palabra","ye_word_end":"ye fin palabra","y0_start":"y0 inicio","y_end":"y$ fin","gg_top":"gg arriba","esc_cancel":"esc cancelar","type_filter":"escribir filtro","arrows_select":"↑/↓ seleccionar","slash_filter":"/ filtrar"},"evidence":{"head":"cabeza","tick":"tick","anchor":"ancla","coverage":"cobertura","complete":"completa","partial":"parcial","unavailable":"no disponible"},"status":{"nav":"navegación","filter":"filtro","read_only":"solo lectura","modified":"modificado","modified_count":"{count} modificados","pending_count":"{count} pendientes","buffer_count":"{count} búferes","loading":"cargando"}},"history":{"title":"Historial Echo","empty":"Sin evidencia Echo todavía","header":"# tick tipo estado evidencia resumen"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Diseño del pie","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Rutas","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Foco + espacio","footer_per_pane":"Por panel + espacio","footer_compact":"Compacto","paths_git_root":"Raíz de Git","paths_absolute":"Rutas absolutas"},"toast":{"changed_title":"Settings changed","save_failed_title":"Ajustes no guardados","save_failed_message":"No se pudo guardar ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Buscar","placeholder":"Filtrar archivos…","empty":"Sin resultados","preview_label":"Vista previa","preview_loading":"Cargando vista previa…","preview_binary":"Archivo binario — sin vista previa","preview_unavailable":"Vista previa no disponible","preview_truncated":"Vista previa truncada"}}; -export const ko: TranslationSchema = {"footer":{"mode":{"browse":"탐색","insert":"삽입","normal":"일반","preview":"미리보기","settings":"설정","files":"파일","graft":"Graft","history":"기록"},"context":{"settings":"설정","graft_empty":"검사할 파일을 여세요","history_empty":"아직 Echo 증거 없음","history_count":"Echo 증거: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k 이동","enter_change":"enter 변경","f2_close":"f2 닫기","esc_close":"esc 닫기","j_k_scroll":"j/k 스크롤","f3_source":"f3 소스","f3_preview":"f3 미리보기","text_input":"텍스트 입력","esc_normal":"esc 일반","ctrl_s_save":"ctrl+s 저장","ctrl_t_theme":"ctrl+t 테마","tab_focus":"tab 포커스","tab_indent":"tab 들여쓰기","ctrl_b_files":"ctrl+b 파일","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h 기록","enter_open":"enter 열기","backspace_up":"backspace 위로","ctrl_b_close":"ctrl+b 닫기","enter_jump":"enter 이동","r_refresh":"r 새로고침","ctrl_g_close":"ctrl+g 닫기","ctrl_h_close":"ctrl+h 닫기","i_insert":"i 삽입","o_open_line":"o 줄 열기","cc_line":"cc 줄","cw_word":"cw 단어","ce_word_end":"ce 단어 끝","c0_start":"c0 시작","c_end":"c$ 끝","dd_line":"dd 줄","dw_word":"dw 단어","de_word_end":"de 단어 끝","d0_start":"d0 시작","d_end":"d$ 끝","yy_line":"yy 줄","yw_word":"yw 단어","ye_word_end":"ye 단어 끝","y0_start":"y0 시작","y_end":"y$ 끝","gg_top":"gg 맨 위","esc_cancel":"esc 취소","type_filter":"필터 입력","arrows_select":"↑/↓ 선택","slash_filter":"/ 필터"},"evidence":{"head":"헤드","tick":"틱","anchor":"앵커","coverage":"범위","complete":"완전","partial":"부분","unavailable":"사용 불가"},"status":{"nav":"탐색","filter":"필터","read_only":"읽기 전용","modified":"수정됨","modified_count":"수정 {count}개","pending_count":"대기 {count}개","buffer_count":"버퍼 {count}개","loading":"로딩 중"}},"history":{"title":"Echo 기록","empty":"아직 Echo 증거 없음","header":"# tick 종류 상태 증거 요약"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"하단 표시 형식","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"파일 경로","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"포커스 + 작업 공간","footer_per_pane":"패널별 + 작업 공간","footer_compact":"간결하게","paths_git_root":"Git 루트 기준","paths_absolute":"절대 경로"},"toast":{"changed_title":"Settings changed","save_failed_title":"설정 저장 실패","save_failed_message":"~/.jimrc를 저장할 수 없습니다. JSON과 권한을 확인하세요."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"검색","placeholder":"파일 필터…","empty":"일치 항목 없음","preview_label":"미리 보기","preview_loading":"미리 보기 불러오는 중…","preview_binary":"바이너리 파일 — 미리 보기 불가","preview_unavailable":"미리 보기 불가","preview_truncated":"미리 보기 생략됨"}}; +export const ko: TranslationSchema = {"footer":{"mode":{"browse":"탐색","insert":"삽입","normal":"일반","preview":"미리보기","settings":"설정","files":"파일","graft":"Graft","history":"기록"},"context":{"settings":"설정","graft_empty":"검사할 파일을 여세요","history_empty":"아직 Echo 증거 없음","history_count":"Echo 증거: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k 이동","enter_change":"enter 변경","f2_close":"f2 닫기","esc_close":"esc 닫기","j_k_scroll":"j/k 스크롤","f3_source":"f3 소스","f3_preview":"f3 미리보기","text_input":"텍스트 입력","esc_normal":"esc 일반","ctrl_s_save":"ctrl+s 저장","ctrl_t_theme":"ctrl+t 테마","tab_focus":"tab 포커스","tab_indent":"tab 들여쓰기","ctrl_b_files":"ctrl+b 파일","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h 기록","enter_open":"enter 열기 / 펼치기","backspace_up":"backspace 위로","ctrl_b_close":"ctrl+b 닫기","enter_jump":"enter 이동","r_refresh":"r 새로고침","ctrl_g_close":"ctrl+g 닫기","ctrl_h_close":"ctrl+h 닫기","i_insert":"i 삽입","o_open_line":"o 줄 열기","cc_line":"cc 줄","cw_word":"cw 단어","ce_word_end":"ce 단어 끝","c0_start":"c0 시작","c_end":"c$ 끝","dd_line":"dd 줄","dw_word":"dw 단어","de_word_end":"de 단어 끝","d0_start":"d0 시작","d_end":"d$ 끝","yy_line":"yy 줄","yw_word":"yw 단어","ye_word_end":"ye 단어 끝","y0_start":"y0 시작","y_end":"y$ 끝","gg_top":"gg 맨 위","esc_cancel":"esc 취소","type_filter":"필터 입력","arrows_select":"↑/↓ 선택","slash_filter":"/ 필터"},"evidence":{"head":"헤드","tick":"틱","anchor":"앵커","coverage":"범위","complete":"완전","partial":"부분","unavailable":"사용 불가"},"status":{"nav":"탐색","filter":"필터","read_only":"읽기 전용","modified":"수정됨","modified_count":"수정 {count}개","pending_count":"대기 {count}개","buffer_count":"버퍼 {count}개","loading":"로딩 중"}},"history":{"title":"Echo 기록","empty":"아직 Echo 증거 없음","header":"# tick 종류 상태 증거 요약"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"하단 표시 형식","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"파일 경로","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"포커스 + 작업 공간","footer_per_pane":"패널별 + 작업 공간","footer_compact":"간결하게","paths_git_root":"Git 루트 기준","paths_absolute":"절대 경로"},"toast":{"changed_title":"Settings changed","save_failed_title":"설정 저장 실패","save_failed_message":"~/.jimrc를 저장할 수 없습니다. JSON과 권한을 확인하세요."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"검색","placeholder":"파일 필터…","empty":"일치 항목 없음","preview_label":"미리 보기","preview_loading":"미리 보기 불러오는 중…","preview_binary":"바이너리 파일 — 미리 보기 불가","preview_unavailable":"미리 보기 불가","preview_truncated":"미리 보기 생략됨"}}; -export const ja: TranslationSchema = {"footer":{"mode":{"browse":"参照","insert":"挿入","normal":"通常","preview":"プレビュー","settings":"設定","files":"ファイル","graft":"Graft","history":"履歴"},"context":{"settings":"設定","graft_empty":"検査するファイルを開く","history_empty":"Echo 証拠はまだありません","history_count":"Echo 証拠: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k 移動","enter_change":"enter 変更","f2_close":"f2 閉じる","esc_close":"esc 閉じる","j_k_scroll":"j/k スクロール","f3_source":"f3 ソース","f3_preview":"f3 プレビュー","text_input":"テキスト入力","esc_normal":"esc 通常","ctrl_s_save":"ctrl+s 保存","ctrl_t_theme":"ctrl+t テーマ","tab_focus":"tab フォーカス","tab_indent":"tab インデント","ctrl_b_files":"ctrl+b ファイル","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h 履歴","enter_open":"enter 開く","backspace_up":"backspace 上へ","ctrl_b_close":"ctrl+b 閉じる","enter_jump":"enter 移動","r_refresh":"r 更新","ctrl_g_close":"ctrl+g 閉じる","ctrl_h_close":"ctrl+h 閉じる","i_insert":"i 挿入","o_open_line":"o 行を開く","cc_line":"cc 行","cw_word":"cw 単語","ce_word_end":"ce 単語末","c0_start":"c0 先頭","c_end":"c$ 末尾","dd_line":"dd 行","dw_word":"dw 単語","de_word_end":"de 単語末","d0_start":"d0 先頭","d_end":"d$ 末尾","yy_line":"yy 行","yw_word":"yw 単語","ye_word_end":"ye 単語末","y0_start":"y0 先頭","y_end":"y$ 末尾","gg_top":"gg 先頭","esc_cancel":"esc 取消","type_filter":"絞り込み入力","arrows_select":"↑/↓ 選択","slash_filter":"/ 絞り込み"},"evidence":{"head":"ヘッド","tick":"ティック","anchor":"アンカー","coverage":"範囲","complete":"完全","partial":"部分","unavailable":"利用不可"},"status":{"nav":"移動","filter":"絞り込み","read_only":"読み取り専用","modified":"変更あり","modified_count":"変更 {count} 件","pending_count":"保留 {count} 件","buffer_count":"バッファ {count} 件","loading":"読み込み中"}},"history":{"title":"Echo 履歴","empty":"Echo 証拠はまだありません","header":"# tick 種類 状態 証拠 概要"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"フッターの配置","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"ファイルパス","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"フォーカス+作業領域","footer_per_pane":"ペイン別+作業領域","footer_compact":"コンパクト","paths_git_root":"Gitルート相対","paths_absolute":"絶対パス"},"toast":{"changed_title":"Settings changed","save_failed_title":"設定を保存できません","save_failed_message":"~/.jimrc を保存できません。JSON と権限を確認してください。"}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"検索","placeholder":"ファイルを絞り込む…","empty":"一致なし","preview_label":"プレビュー","preview_loading":"プレビューを読み込み中…","preview_binary":"バイナリファイル — プレビュー不可","preview_unavailable":"プレビュー不可","preview_truncated":"プレビューを省略"}}; +export const ja: TranslationSchema = {"footer":{"mode":{"browse":"参照","insert":"挿入","normal":"通常","preview":"プレビュー","settings":"設定","files":"ファイル","graft":"Graft","history":"履歴"},"context":{"settings":"設定","graft_empty":"検査するファイルを開く","history_empty":"Echo 証拠はまだありません","history_count":"Echo 証拠: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k 移動","enter_change":"enter 変更","f2_close":"f2 閉じる","esc_close":"esc 閉じる","j_k_scroll":"j/k スクロール","f3_source":"f3 ソース","f3_preview":"f3 プレビュー","text_input":"テキスト入力","esc_normal":"esc 通常","ctrl_s_save":"ctrl+s 保存","ctrl_t_theme":"ctrl+t テーマ","tab_focus":"tab フォーカス","tab_indent":"tab インデント","ctrl_b_files":"ctrl+b ファイル","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h 履歴","enter_open":"enter 開く / 展開","backspace_up":"backspace 上へ","ctrl_b_close":"ctrl+b 閉じる","enter_jump":"enter 移動","r_refresh":"r 更新","ctrl_g_close":"ctrl+g 閉じる","ctrl_h_close":"ctrl+h 閉じる","i_insert":"i 挿入","o_open_line":"o 行を開く","cc_line":"cc 行","cw_word":"cw 単語","ce_word_end":"ce 単語末","c0_start":"c0 先頭","c_end":"c$ 末尾","dd_line":"dd 行","dw_word":"dw 単語","de_word_end":"de 単語末","d0_start":"d0 先頭","d_end":"d$ 末尾","yy_line":"yy 行","yw_word":"yw 単語","ye_word_end":"ye 単語末","y0_start":"y0 先頭","y_end":"y$ 末尾","gg_top":"gg 先頭","esc_cancel":"esc 取消","type_filter":"絞り込み入力","arrows_select":"↑/↓ 選択","slash_filter":"/ 絞り込み"},"evidence":{"head":"ヘッド","tick":"ティック","anchor":"アンカー","coverage":"範囲","complete":"完全","partial":"部分","unavailable":"利用不可"},"status":{"nav":"移動","filter":"絞り込み","read_only":"読み取り専用","modified":"変更あり","modified_count":"変更 {count} 件","pending_count":"保留 {count} 件","buffer_count":"バッファ {count} 件","loading":"読み込み中"}},"history":{"title":"Echo 履歴","empty":"Echo 証拠はまだありません","header":"# tick 種類 状態 証拠 概要"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"フッターの配置","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"ファイルパス","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"フォーカス+作業領域","footer_per_pane":"ペイン別+作業領域","footer_compact":"コンパクト","paths_git_root":"Gitルート相対","paths_absolute":"絶対パス"},"toast":{"changed_title":"Settings changed","save_failed_title":"設定を保存できません","save_failed_message":"~/.jimrc を保存できません。JSON と権限を確認してください。"}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"検索","placeholder":"ファイルを絞り込む…","empty":"一致なし","preview_label":"プレビュー","preview_loading":"プレビューを読み込み中…","preview_binary":"バイナリファイル — プレビュー不可","preview_unavailable":"プレビュー不可","preview_truncated":"プレビューを省略"}}; -export const zhHans: TranslationSchema = {"footer":{"mode":{"browse":"浏览","insert":"插入","normal":"普通","preview":"预览","settings":"设置","files":"文件","graft":"Graft","history":"历史"},"context":{"settings":"设置","graft_empty":"打开文件以检查","history_empty":"还没有 Echo 证据","history_count":"Echo 证据: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k 移动","enter_change":"enter 更改","f2_close":"f2 关闭","esc_close":"esc 关闭","j_k_scroll":"j/k 滚动","f3_source":"f3 源码","f3_preview":"f3 预览","text_input":"文本输入","esc_normal":"esc 普通","ctrl_s_save":"ctrl+s 保存","ctrl_t_theme":"ctrl+t 主题","tab_focus":"tab 焦点","tab_indent":"tab 缩进","ctrl_b_files":"ctrl+b 文件","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h 历史","enter_open":"enter 打开","backspace_up":"backspace 上一级","ctrl_b_close":"ctrl+b 关闭","enter_jump":"enter 跳转","r_refresh":"r 刷新","ctrl_g_close":"ctrl+g 关闭","ctrl_h_close":"ctrl+h 关闭","i_insert":"i 插入","o_open_line":"o 打开行","cc_line":"cc 行","cw_word":"cw 词","ce_word_end":"ce 词尾","c0_start":"c0 开头","c_end":"c$ 结尾","dd_line":"dd 行","dw_word":"dw 词","de_word_end":"de 词尾","d0_start":"d0 开头","d_end":"d$ 结尾","yy_line":"yy 行","yw_word":"yw 词","ye_word_end":"ye 词尾","y0_start":"y0 开头","y_end":"y$ 结尾","gg_top":"gg 顶部","esc_cancel":"esc 取消","type_filter":"输入筛选","arrows_select":"↑/↓ 选择","slash_filter":"/ 筛选"},"evidence":{"head":"头","tick":"时刻","anchor":"锚点","coverage":"覆盖","complete":"完整","partial":"部分","unavailable":"不可用"},"status":{"nav":"导航","filter":"筛选","read_only":"只读","modified":"已修改","modified_count":"{count} 个已修改","pending_count":"{count} 个待处理","buffer_count":"{count} 个缓冲区","loading":"加载中"}},"history":{"title":"Echo 历史","empty":"还没有 Echo 证据","header":"# tick 类型 状态 证据 摘要"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"页脚布局","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"文件路径","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"焦点与工作区","footer_per_pane":"分面板与工作区","footer_compact":"紧凑","paths_git_root":"相对 Git 根目录","paths_absolute":"绝对路径"},"toast":{"changed_title":"Settings changed","save_failed_title":"设置未保存","save_failed_message":"无法保存 ~/.jimrc。请检查 JSON 和权限。"}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"搜索","placeholder":"筛选文件…","empty":"无匹配项","preview_label":"预览","preview_loading":"正在加载预览…","preview_binary":"二进制文件 — 无法预览","preview_unavailable":"无法预览","preview_truncated":"预览已截断"}}; +export const zhHans: TranslationSchema = {"footer":{"mode":{"browse":"浏览","insert":"插入","normal":"普通","preview":"预览","settings":"设置","files":"文件","graft":"Graft","history":"历史"},"context":{"settings":"设置","graft_empty":"打开文件以检查","history_empty":"还没有 Echo 证据","history_count":"Echo 证据: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k 移动","enter_change":"enter 更改","f2_close":"f2 关闭","esc_close":"esc 关闭","j_k_scroll":"j/k 滚动","f3_source":"f3 源码","f3_preview":"f3 预览","text_input":"文本输入","esc_normal":"esc 普通","ctrl_s_save":"ctrl+s 保存","ctrl_t_theme":"ctrl+t 主题","tab_focus":"tab 焦点","tab_indent":"tab 缩进","ctrl_b_files":"ctrl+b 文件","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h 历史","enter_open":"enter 打开 / 展开","backspace_up":"backspace 上一级","ctrl_b_close":"ctrl+b 关闭","enter_jump":"enter 跳转","r_refresh":"r 刷新","ctrl_g_close":"ctrl+g 关闭","ctrl_h_close":"ctrl+h 关闭","i_insert":"i 插入","o_open_line":"o 打开行","cc_line":"cc 行","cw_word":"cw 词","ce_word_end":"ce 词尾","c0_start":"c0 开头","c_end":"c$ 结尾","dd_line":"dd 行","dw_word":"dw 词","de_word_end":"de 词尾","d0_start":"d0 开头","d_end":"d$ 结尾","yy_line":"yy 行","yw_word":"yw 词","ye_word_end":"ye 词尾","y0_start":"y0 开头","y_end":"y$ 结尾","gg_top":"gg 顶部","esc_cancel":"esc 取消","type_filter":"输入筛选","arrows_select":"↑/↓ 选择","slash_filter":"/ 筛选"},"evidence":{"head":"头","tick":"时刻","anchor":"锚点","coverage":"覆盖","complete":"完整","partial":"部分","unavailable":"不可用"},"status":{"nav":"导航","filter":"筛选","read_only":"只读","modified":"已修改","modified_count":"{count} 个已修改","pending_count":"{count} 个待处理","buffer_count":"{count} 个缓冲区","loading":"加载中"}},"history":{"title":"Echo 历史","empty":"还没有 Echo 证据","header":"# tick 类型 状态 证据 摘要"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"页脚布局","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"文件路径","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"焦点与工作区","footer_per_pane":"分面板与工作区","footer_compact":"紧凑","paths_git_root":"相对 Git 根目录","paths_absolute":"绝对路径"},"toast":{"changed_title":"Settings changed","save_failed_title":"设置未保存","save_failed_message":"无法保存 ~/.jimrc。请检查 JSON 和权限。"}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"搜索","placeholder":"筛选文件…","empty":"无匹配项","preview_label":"预览","preview_loading":"正在加载预览…","preview_binary":"二进制文件 — 无法预览","preview_unavailable":"无法预览","preview_truncated":"预览已截断"}}; -export const ptBR: TranslationSchema = {"footer":{"mode":{"browse":"navegar","insert":"inserir","normal":"normal","preview":"prévia","settings":"configurações","files":"arquivos","graft":"graft","history":"histórico"},"context":{"settings":"configurações","graft_empty":"abra um arquivo para inspecionar","history_empty":"nenhuma evidência Echo ainda","history_count":"Evidências Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k mover","enter_change":"enter alterar","f2_close":"f2 fechar","esc_close":"esc fechar","j_k_scroll":"j/k rolar","f3_source":"f3 código","f3_preview":"f3 prévia","text_input":"entrada de texto","esc_normal":"esc normal","ctrl_s_save":"ctrl+s salvar","ctrl_t_theme":"ctrl+t tema","tab_focus":"tab foco","tab_indent":"tab recuo","ctrl_b_files":"ctrl+b arquivos","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h histórico","enter_open":"enter abrir","backspace_up":"backspace subir","ctrl_b_close":"ctrl+b fechar","enter_jump":"enter ir","r_refresh":"r atualizar","ctrl_g_close":"ctrl+g fechar","ctrl_h_close":"ctrl+h fechar","i_insert":"i inserir","o_open_line":"o abrir linha","cc_line":"cc linha","cw_word":"cw palavra","ce_word_end":"ce fim palavra","c0_start":"c0 início","c_end":"c$ fim","dd_line":"dd linha","dw_word":"dw palavra","de_word_end":"de fim palavra","d0_start":"d0 início","d_end":"d$ fim","yy_line":"yy linha","yw_word":"yw palavra","ye_word_end":"ye fim palavra","y0_start":"y0 início","y_end":"y$ fim","gg_top":"gg topo","esc_cancel":"esc cancelar","type_filter":"digitar filtro","arrows_select":"↑/↓ selecionar","slash_filter":"/ filtrar"},"evidence":{"head":"cabeça","tick":"tick","anchor":"âncora","coverage":"cobertura","complete":"completa","partial":"parcial","unavailable":"indisponível"},"status":{"nav":"navegação","filter":"filtro","read_only":"somente leitura","modified":"modificado","modified_count":"{count} modificados","pending_count":"{count} pendentes","buffer_count":"{count} buffers","loading":"carregando"}},"history":{"title":"Histórico Echo","empty":"Nenhuma evidência Echo ainda","header":"# tick tipo status evidência resumo"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Layout do rodapé","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Caminhos","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Foco + espaço","footer_per_pane":"Por painel + espaço","footer_compact":"Compacto","paths_git_root":"Raiz do Git","paths_absolute":"Caminhos absolutos"},"toast":{"changed_title":"Settings changed","save_failed_title":"Configurações não salvas","save_failed_message":"Não foi possível salvar ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Buscar","placeholder":"Filtrar arquivos…","empty":"Nenhum resultado","preview_label":"Prévia","preview_loading":"Carregando prévia…","preview_binary":"Arquivo binário — sem prévia","preview_unavailable":"Prévia indisponível","preview_truncated":"Prévia truncada"}}; +export const ptBR: TranslationSchema = {"footer":{"mode":{"browse":"navegar","insert":"inserir","normal":"normal","preview":"prévia","settings":"configurações","files":"arquivos","graft":"graft","history":"histórico"},"context":{"settings":"configurações","graft_empty":"abra um arquivo para inspecionar","history_empty":"nenhuma evidência Echo ainda","history_count":"Evidências Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k mover","enter_change":"enter alterar","f2_close":"f2 fechar","esc_close":"esc fechar","j_k_scroll":"j/k rolar","f3_source":"f3 código","f3_preview":"f3 prévia","text_input":"entrada de texto","esc_normal":"esc normal","ctrl_s_save":"ctrl+s salvar","ctrl_t_theme":"ctrl+t tema","tab_focus":"tab foco","tab_indent":"tab recuo","ctrl_b_files":"ctrl+b arquivos","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h histórico","enter_open":"enter abrir / expandir","backspace_up":"backspace subir","ctrl_b_close":"ctrl+b fechar","enter_jump":"enter ir","r_refresh":"r atualizar","ctrl_g_close":"ctrl+g fechar","ctrl_h_close":"ctrl+h fechar","i_insert":"i inserir","o_open_line":"o abrir linha","cc_line":"cc linha","cw_word":"cw palavra","ce_word_end":"ce fim palavra","c0_start":"c0 início","c_end":"c$ fim","dd_line":"dd linha","dw_word":"dw palavra","de_word_end":"de fim palavra","d0_start":"d0 início","d_end":"d$ fim","yy_line":"yy linha","yw_word":"yw palavra","ye_word_end":"ye fim palavra","y0_start":"y0 início","y_end":"y$ fim","gg_top":"gg topo","esc_cancel":"esc cancelar","type_filter":"digitar filtro","arrows_select":"↑/↓ selecionar","slash_filter":"/ filtrar"},"evidence":{"head":"cabeça","tick":"tick","anchor":"âncora","coverage":"cobertura","complete":"completa","partial":"parcial","unavailable":"indisponível"},"status":{"nav":"navegação","filter":"filtro","read_only":"somente leitura","modified":"modificado","modified_count":"{count} modificados","pending_count":"{count} pendentes","buffer_count":"{count} buffers","loading":"carregando"}},"history":{"title":"Histórico Echo","empty":"Nenhuma evidência Echo ainda","header":"# tick tipo status evidência resumo"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Layout do rodapé","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Caminhos","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Foco + espaço","footer_per_pane":"Por painel + espaço","footer_compact":"Compacto","paths_git_root":"Raiz do Git","paths_absolute":"Caminhos absolutos"},"toast":{"changed_title":"Settings changed","save_failed_title":"Configurações não salvas","save_failed_message":"Não foi possível salvar ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Buscar","placeholder":"Filtrar arquivos…","empty":"Nenhum resultado","preview_label":"Prévia","preview_loading":"Carregando prévia…","preview_binary":"Arquivo binário — sem prévia","preview_unavailable":"Prévia indisponível","preview_truncated":"Prévia truncada"}}; -export const ru: TranslationSchema = {"footer":{"mode":{"browse":"обзор","insert":"вставка","normal":"обычный","preview":"просмотр","settings":"настройки","files":"файлы","graft":"graft","history":"история"},"context":{"settings":"настройки","graft_empty":"откройте файл для проверки","history_empty":"пока нет доказательств Echo","history_count":"Доказательства Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k переместить","enter_change":"enter изменить","f2_close":"f2 закрыть","esc_close":"esc закрыть","j_k_scroll":"j/k прокрутка","f3_source":"f3 исходник","f3_preview":"f3 просмотр","text_input":"ввод текста","esc_normal":"esc обычный","ctrl_s_save":"ctrl+s сохранить","ctrl_t_theme":"ctrl+t тема","tab_focus":"tab фокус","tab_indent":"tab отступ","ctrl_b_files":"ctrl+b файлы","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h история","enter_open":"enter открыть","backspace_up":"backspace вверх","ctrl_b_close":"ctrl+b закрыть","enter_jump":"enter перейти","r_refresh":"r обновить","ctrl_g_close":"ctrl+g закрыть","ctrl_h_close":"ctrl+h закрыть","i_insert":"i вставка","o_open_line":"o открыть строку","cc_line":"cc строка","cw_word":"cw слово","ce_word_end":"ce конец слова","c0_start":"c0 начало","c_end":"c$ конец","dd_line":"dd строка","dw_word":"dw слово","de_word_end":"de конец слова","d0_start":"d0 начало","d_end":"d$ конец","yy_line":"yy строка","yw_word":"yw слово","ye_word_end":"ye конец слова","y0_start":"y0 начало","y_end":"y$ конец","gg_top":"gg верх","esc_cancel":"esc отмена","type_filter":"ввод фильтра","arrows_select":"↑/↓ выбор","slash_filter":"/ фильтр"},"evidence":{"head":"вершина","tick":"тик","anchor":"якорь","coverage":"покрытие","complete":"полное","partial":"частичное","unavailable":"недоступно"},"status":{"nav":"навигация","filter":"фильтр","read_only":"только чтение","modified":"изменён","modified_count":"изменено: {count}","pending_count":"ожидает: {count}","buffer_count":"буферов: {count}","loading":"загрузка"}},"history":{"title":"История Echo","empty":"Пока нет доказательств Echo","header":"# tick тип статус доказательство сводка"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Вид строки состояния","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Пути файлов","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Фокус + рабочая область","footer_per_pane":"По панелям + общее","footer_compact":"Компактный","paths_git_root":"От корня Git","paths_absolute":"Абсолютные пути"},"toast":{"changed_title":"Settings changed","save_failed_title":"Настройки не сохранены","save_failed_message":"Не удалось сохранить ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Поиск","placeholder":"Фильтр файлов…","empty":"Нет совпадений","preview_label":"Просмотр","preview_loading":"Загрузка просмотра…","preview_binary":"Двоичный файл — просмотр недоступен","preview_unavailable":"Просмотр недоступен","preview_truncated":"Просмотр сокращён"}}; +export const ru: TranslationSchema = {"footer":{"mode":{"browse":"обзор","insert":"вставка","normal":"обычный","preview":"просмотр","settings":"настройки","files":"файлы","graft":"graft","history":"история"},"context":{"settings":"настройки","graft_empty":"откройте файл для проверки","history_empty":"пока нет доказательств Echo","history_count":"Доказательства Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k переместить","enter_change":"enter изменить","f2_close":"f2 закрыть","esc_close":"esc закрыть","j_k_scroll":"j/k прокрутка","f3_source":"f3 исходник","f3_preview":"f3 просмотр","text_input":"ввод текста","esc_normal":"esc обычный","ctrl_s_save":"ctrl+s сохранить","ctrl_t_theme":"ctrl+t тема","tab_focus":"tab фокус","tab_indent":"tab отступ","ctrl_b_files":"ctrl+b файлы","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h история","enter_open":"enter открыть / развернуть","backspace_up":"backspace вверх","ctrl_b_close":"ctrl+b закрыть","enter_jump":"enter перейти","r_refresh":"r обновить","ctrl_g_close":"ctrl+g закрыть","ctrl_h_close":"ctrl+h закрыть","i_insert":"i вставка","o_open_line":"o открыть строку","cc_line":"cc строка","cw_word":"cw слово","ce_word_end":"ce конец слова","c0_start":"c0 начало","c_end":"c$ конец","dd_line":"dd строка","dw_word":"dw слово","de_word_end":"de конец слова","d0_start":"d0 начало","d_end":"d$ конец","yy_line":"yy строка","yw_word":"yw слово","ye_word_end":"ye конец слова","y0_start":"y0 начало","y_end":"y$ конец","gg_top":"gg верх","esc_cancel":"esc отмена","type_filter":"ввод фильтра","arrows_select":"↑/↓ выбор","slash_filter":"/ фильтр"},"evidence":{"head":"вершина","tick":"тик","anchor":"якорь","coverage":"покрытие","complete":"полное","partial":"частичное","unavailable":"недоступно"},"status":{"nav":"навигация","filter":"фильтр","read_only":"только чтение","modified":"изменён","modified_count":"изменено: {count}","pending_count":"ожидает: {count}","buffer_count":"буферов: {count}","loading":"загрузка"}},"history":{"title":"История Echo","empty":"Пока нет доказательств Echo","header":"# tick тип статус доказательство сводка"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Вид строки состояния","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Пути файлов","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Фокус + рабочая область","footer_per_pane":"По панелям + общее","footer_compact":"Компактный","paths_git_root":"От корня Git","paths_absolute":"Абсолютные пути"},"toast":{"changed_title":"Settings changed","save_failed_title":"Настройки не сохранены","save_failed_message":"Не удалось сохранить ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Поиск","placeholder":"Фильтр файлов…","empty":"Нет совпадений","preview_label":"Просмотр","preview_loading":"Загрузка просмотра…","preview_binary":"Двоичный файл — просмотр недоступен","preview_unavailable":"Просмотр недоступен","preview_truncated":"Просмотр сокращён"}}; -export const ar: TranslationSchema = {"footer":{"mode":{"browse":"تصفح","insert":"إدراج","normal":"عادي","preview":"معاينة","settings":"إعدادات","files":"ملفات","graft":"Graft","history":"السجل"},"context":{"settings":"إعدادات","graft_empty":"افتح ملفا لفحصه","history_empty":"لا توجد أدلة Echo بعد","history_count":"أدلة Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k تحريك","enter_change":"enter تغيير","f2_close":"f2 إغلاق","esc_close":"esc إغلاق","j_k_scroll":"j/k تمرير","f3_source":"f3 المصدر","f3_preview":"f3 معاينة","text_input":"إدخال نص","esc_normal":"esc عادي","ctrl_s_save":"ctrl+s حفظ","ctrl_t_theme":"ctrl+t سمة","tab_focus":"tab تركيز","tab_indent":"tab إزاحة","ctrl_b_files":"ctrl+b ملفات","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h سجل","enter_open":"enter فتح","backspace_up":"backspace أعلى","ctrl_b_close":"ctrl+b إغلاق","enter_jump":"enter انتقال","r_refresh":"r تحديث","ctrl_g_close":"ctrl+g إغلاق","ctrl_h_close":"ctrl+h إغلاق","i_insert":"i إدراج","o_open_line":"o فتح سطر","cc_line":"cc سطر","cw_word":"cw كلمة","ce_word_end":"ce نهاية كلمة","c0_start":"c0 بداية","c_end":"c$ نهاية","dd_line":"dd سطر","dw_word":"dw كلمة","de_word_end":"de نهاية كلمة","d0_start":"d0 بداية","d_end":"d$ نهاية","yy_line":"yy سطر","yw_word":"yw كلمة","ye_word_end":"ye نهاية كلمة","y0_start":"y0 بداية","y_end":"y$ نهاية","gg_top":"gg أعلى","esc_cancel":"esc إلغاء","type_filter":"اكتب للتصفية","arrows_select":"↑/↓ تحديد","slash_filter":"/ تصفية"},"evidence":{"head":"الرأس","tick":"النبضة","anchor":"المرساة","coverage":"التغطية","complete":"كاملة","partial":"جزئية","unavailable":"غير متاحة"},"status":{"nav":"تنقل","filter":"تصفية","read_only":"للقراءة فقط","modified":"معدّل","modified_count":"{count} معدّل","pending_count":"{count} معلّق","buffer_count":"{count} مخازن","loading":"جار التحميل"}},"history":{"title":"سجل Echo","empty":"لا توجد أدلة Echo بعد","header":"# tick النوع الحالة الدليل الملخص"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"تخطيط التذييل","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"مسارات الملفات","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"التركيز ومساحة العمل","footer_per_pane":"لكل لوحة ومساحة العمل","footer_compact":"مضغوط","paths_git_root":"جذر Git","paths_absolute":"مسارات كاملة"},"toast":{"changed_title":"Settings changed","save_failed_title":"لم تُحفظ الإعدادات","save_failed_message":"تعذر حفظ ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"بحث","placeholder":"تصفية الملفات…","empty":"لا نتائج","preview_label":"معاينة","preview_loading":"جارٍ تحميل المعاينة…","preview_binary":"ملف ثنائي — المعاينة غير متاحة","preview_unavailable":"المعاينة غير متاحة","preview_truncated":"المعاينة مختصرة"}}; +export const ar: TranslationSchema = {"footer":{"mode":{"browse":"تصفح","insert":"إدراج","normal":"عادي","preview":"معاينة","settings":"إعدادات","files":"ملفات","graft":"Graft","history":"السجل"},"context":{"settings":"إعدادات","graft_empty":"افتح ملفا لفحصه","history_empty":"لا توجد أدلة Echo بعد","history_count":"أدلة Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k تحريك","enter_change":"enter تغيير","f2_close":"f2 إغلاق","esc_close":"esc إغلاق","j_k_scroll":"j/k تمرير","f3_source":"f3 المصدر","f3_preview":"f3 معاينة","text_input":"إدخال نص","esc_normal":"esc عادي","ctrl_s_save":"ctrl+s حفظ","ctrl_t_theme":"ctrl+t سمة","tab_focus":"tab تركيز","tab_indent":"tab إزاحة","ctrl_b_files":"ctrl+b ملفات","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h سجل","enter_open":"enter فتح / توسيع","backspace_up":"backspace أعلى","ctrl_b_close":"ctrl+b إغلاق","enter_jump":"enter انتقال","r_refresh":"r تحديث","ctrl_g_close":"ctrl+g إغلاق","ctrl_h_close":"ctrl+h إغلاق","i_insert":"i إدراج","o_open_line":"o فتح سطر","cc_line":"cc سطر","cw_word":"cw كلمة","ce_word_end":"ce نهاية كلمة","c0_start":"c0 بداية","c_end":"c$ نهاية","dd_line":"dd سطر","dw_word":"dw كلمة","de_word_end":"de نهاية كلمة","d0_start":"d0 بداية","d_end":"d$ نهاية","yy_line":"yy سطر","yw_word":"yw كلمة","ye_word_end":"ye نهاية كلمة","y0_start":"y0 بداية","y_end":"y$ نهاية","gg_top":"gg أعلى","esc_cancel":"esc إلغاء","type_filter":"اكتب للتصفية","arrows_select":"↑/↓ تحديد","slash_filter":"/ تصفية"},"evidence":{"head":"الرأس","tick":"النبضة","anchor":"المرساة","coverage":"التغطية","complete":"كاملة","partial":"جزئية","unavailable":"غير متاحة"},"status":{"nav":"تنقل","filter":"تصفية","read_only":"للقراءة فقط","modified":"معدّل","modified_count":"{count} معدّل","pending_count":"{count} معلّق","buffer_count":"{count} مخازن","loading":"جار التحميل"}},"history":{"title":"سجل Echo","empty":"لا توجد أدلة Echo بعد","header":"# tick النوع الحالة الدليل الملخص"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"تخطيط التذييل","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"مسارات الملفات","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"التركيز ومساحة العمل","footer_per_pane":"لكل لوحة ومساحة العمل","footer_compact":"مضغوط","paths_git_root":"جذر Git","paths_absolute":"مسارات كاملة"},"toast":{"changed_title":"Settings changed","save_failed_title":"لم تُحفظ الإعدادات","save_failed_message":"تعذر حفظ ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"بحث","placeholder":"تصفية الملفات…","empty":"لا نتائج","preview_label":"معاينة","preview_loading":"جارٍ تحميل المعاينة…","preview_binary":"ملف ثنائي — المعاينة غير متاحة","preview_unavailable":"المعاينة غير متاحة","preview_truncated":"المعاينة مختصرة"}}; -export const id: TranslationSchema = {"footer":{"mode":{"browse":"jelajah","insert":"sisip","normal":"normal","preview":"pratinjau","settings":"pengaturan","files":"berkas","graft":"graft","history":"riwayat"},"context":{"settings":"pengaturan","graft_empty":"buka berkas untuk diperiksa","history_empty":"belum ada bukti Echo","history_count":"Bukti Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k pindah","enter_change":"enter ubah","f2_close":"f2 tutup","esc_close":"esc tutup","j_k_scroll":"j/k gulir","f3_source":"f3 sumber","f3_preview":"f3 pratinjau","text_input":"input teks","esc_normal":"esc normal","ctrl_s_save":"ctrl+s simpan","ctrl_t_theme":"ctrl+t tema","tab_focus":"tab fokus","tab_indent":"tab inden","ctrl_b_files":"ctrl+b berkas","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h riwayat","enter_open":"enter buka","backspace_up":"backspace naik","ctrl_b_close":"ctrl+b tutup","enter_jump":"enter lompat","r_refresh":"r segarkan","ctrl_g_close":"ctrl+g tutup","ctrl_h_close":"ctrl+h tutup","i_insert":"i sisip","o_open_line":"o buka baris","cc_line":"cc baris","cw_word":"cw kata","ce_word_end":"ce akhir kata","c0_start":"c0 awal","c_end":"c$ akhir","dd_line":"dd baris","dw_word":"dw kata","de_word_end":"de akhir kata","d0_start":"d0 awal","d_end":"d$ akhir","yy_line":"yy baris","yw_word":"yw kata","ye_word_end":"ye akhir kata","y0_start":"y0 awal","y_end":"y$ akhir","gg_top":"gg atas","esc_cancel":"esc batal","type_filter":"ketik filter","arrows_select":"↑/↓ pilih","slash_filter":"/ filter"},"evidence":{"head":"kepala","tick":"tick","anchor":"jangkar","coverage":"cakupan","complete":"lengkap","partial":"sebagian","unavailable":"tidak tersedia"},"status":{"nav":"navigasi","filter":"filter","read_only":"hanya baca","modified":"diubah","modified_count":"{count} diubah","pending_count":"{count} tertunda","buffer_count":"{count} buffer","loading":"memuat"}},"history":{"title":"Riwayat Echo","empty":"Belum ada bukti Echo","header":"# tick jenis status bukti ringkasan"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Tata letak footer","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Jalur berkas","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Fokus + ruang kerja","footer_per_pane":"Per panel + ruang kerja","footer_compact":"Ringkas","paths_git_root":"Akar Git","paths_absolute":"Jalur lengkap"},"toast":{"changed_title":"Settings changed","save_failed_title":"Pengaturan tidak disimpan","save_failed_message":"Tidak dapat menyimpan ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Cari","placeholder":"Filter berkas…","empty":"Tidak ada hasil","preview_label":"Pratinjau","preview_loading":"Memuat pratinjau…","preview_binary":"Berkas biner — pratinjau tidak tersedia","preview_unavailable":"Pratinjau tidak tersedia","preview_truncated":"Pratinjau dipotong"}}; +export const id: TranslationSchema = {"footer":{"mode":{"browse":"jelajah","insert":"sisip","normal":"normal","preview":"pratinjau","settings":"pengaturan","files":"berkas","graft":"graft","history":"riwayat"},"context":{"settings":"pengaturan","graft_empty":"buka berkas untuk diperiksa","history_empty":"belum ada bukti Echo","history_count":"Bukti Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k pindah","enter_change":"enter ubah","f2_close":"f2 tutup","esc_close":"esc tutup","j_k_scroll":"j/k gulir","f3_source":"f3 sumber","f3_preview":"f3 pratinjau","text_input":"input teks","esc_normal":"esc normal","ctrl_s_save":"ctrl+s simpan","ctrl_t_theme":"ctrl+t tema","tab_focus":"tab fokus","tab_indent":"tab inden","ctrl_b_files":"ctrl+b berkas","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h riwayat","enter_open":"enter buka / luaskan","backspace_up":"backspace naik","ctrl_b_close":"ctrl+b tutup","enter_jump":"enter lompat","r_refresh":"r segarkan","ctrl_g_close":"ctrl+g tutup","ctrl_h_close":"ctrl+h tutup","i_insert":"i sisip","o_open_line":"o buka baris","cc_line":"cc baris","cw_word":"cw kata","ce_word_end":"ce akhir kata","c0_start":"c0 awal","c_end":"c$ akhir","dd_line":"dd baris","dw_word":"dw kata","de_word_end":"de akhir kata","d0_start":"d0 awal","d_end":"d$ akhir","yy_line":"yy baris","yw_word":"yw kata","ye_word_end":"ye akhir kata","y0_start":"y0 awal","y_end":"y$ akhir","gg_top":"gg atas","esc_cancel":"esc batal","type_filter":"ketik filter","arrows_select":"↑/↓ pilih","slash_filter":"/ filter"},"evidence":{"head":"kepala","tick":"tick","anchor":"jangkar","coverage":"cakupan","complete":"lengkap","partial":"sebagian","unavailable":"tidak tersedia"},"status":{"nav":"navigasi","filter":"filter","read_only":"hanya baca","modified":"diubah","modified_count":"{count} diubah","pending_count":"{count} tertunda","buffer_count":"{count} buffer","loading":"memuat"}},"history":{"title":"Riwayat Echo","empty":"Belum ada bukti Echo","header":"# tick jenis status bukti ringkasan"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Tata letak footer","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Jalur berkas","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Fokus + ruang kerja","footer_per_pane":"Per panel + ruang kerja","footer_compact":"Ringkas","paths_git_root":"Akar Git","paths_absolute":"Jalur lengkap"},"toast":{"changed_title":"Settings changed","save_failed_title":"Pengaturan tidak disimpan","save_failed_message":"Tidak dapat menyimpan ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Cari","placeholder":"Filter berkas…","empty":"Tidak ada hasil","preview_label":"Pratinjau","preview_loading":"Memuat pratinjau…","preview_binary":"Berkas biner — pratinjau tidak tersedia","preview_unavailable":"Pratinjau tidak tersedia","preview_truncated":"Pratinjau dipotong"}}; -export const tr: TranslationSchema = {"footer":{"mode":{"browse":"gözat","insert":"ekle","normal":"normal","preview":"önizleme","settings":"ayarlar","files":"dosyalar","graft":"graft","history":"geçmiş"},"context":{"settings":"ayarlar","graft_empty":"incelemek için dosya aç","history_empty":"henüz Echo kanıtı yok","history_count":"Echo kanıtı: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k taşı","enter_change":"enter değiştir","f2_close":"f2 kapat","esc_close":"esc kapat","j_k_scroll":"j/k kaydır","f3_source":"f3 kaynak","f3_preview":"f3 önizleme","text_input":"metin girişi","esc_normal":"esc normal","ctrl_s_save":"ctrl+s kaydet","ctrl_t_theme":"ctrl+t tema","tab_focus":"tab odak","tab_indent":"tab girinti","ctrl_b_files":"ctrl+b dosyalar","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h geçmiş","enter_open":"enter aç","backspace_up":"backspace yukarı","ctrl_b_close":"ctrl+b kapat","enter_jump":"enter git","r_refresh":"r yenile","ctrl_g_close":"ctrl+g kapat","ctrl_h_close":"ctrl+h kapat","i_insert":"i ekle","o_open_line":"o satır aç","cc_line":"cc satır","cw_word":"cw kelime","ce_word_end":"ce kelime sonu","c0_start":"c0 başlangıç","c_end":"c$ son","dd_line":"dd satır","dw_word":"dw kelime","de_word_end":"de kelime sonu","d0_start":"d0 başlangıç","d_end":"d$ son","yy_line":"yy satır","yw_word":"yw kelime","ye_word_end":"ye kelime sonu","y0_start":"y0 başlangıç","y_end":"y$ son","gg_top":"gg üst","esc_cancel":"esc iptal","type_filter":"filtre yaz","arrows_select":"↑/↓ seç","slash_filter":"/ filtre"},"evidence":{"head":"baş","tick":"tik","anchor":"çapa","coverage":"kapsam","complete":"tam","partial":"kısmi","unavailable":"kullanılamıyor"},"status":{"nav":"gezinme","filter":"filtre","read_only":"salt okunur","modified":"değiştirildi","modified_count":"{count} değiştirildi","pending_count":"{count} bekliyor","buffer_count":"{count} arabellek","loading":"yükleniyor"}},"history":{"title":"Echo Geçmişi","empty":"Henüz Echo kanıtı yok","header":"# tick tür durum kanıt özet"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Alt çubuk düzeni","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Dosya yolları","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Odak + çalışma alanı","footer_per_pane":"Bölme + çalışma alanı","footer_compact":"Kompakt","paths_git_root":"Git kökü","paths_absolute":"Tam yollar"},"toast":{"changed_title":"Settings changed","save_failed_title":"Ayarlar kaydedilmedi","save_failed_message":"~/.jimrc kaydedilemedi."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Ara","placeholder":"Dosyaları filtrele…","empty":"Eşleşme yok","preview_label":"Önizleme","preview_loading":"Önizleme yükleniyor…","preview_binary":"İkili dosya — önizleme yok","preview_unavailable":"Önizleme kullanılamıyor","preview_truncated":"Önizleme kısaltıldı"}}; +export const tr: TranslationSchema = {"footer":{"mode":{"browse":"gözat","insert":"ekle","normal":"normal","preview":"önizleme","settings":"ayarlar","files":"dosyalar","graft":"graft","history":"geçmiş"},"context":{"settings":"ayarlar","graft_empty":"incelemek için dosya aç","history_empty":"henüz Echo kanıtı yok","history_count":"Echo kanıtı: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k taşı","enter_change":"enter değiştir","f2_close":"f2 kapat","esc_close":"esc kapat","j_k_scroll":"j/k kaydır","f3_source":"f3 kaynak","f3_preview":"f3 önizleme","text_input":"metin girişi","esc_normal":"esc normal","ctrl_s_save":"ctrl+s kaydet","ctrl_t_theme":"ctrl+t tema","tab_focus":"tab odak","tab_indent":"tab girinti","ctrl_b_files":"ctrl+b dosyalar","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h geçmiş","enter_open":"enter aç / genişlet","backspace_up":"backspace yukarı","ctrl_b_close":"ctrl+b kapat","enter_jump":"enter git","r_refresh":"r yenile","ctrl_g_close":"ctrl+g kapat","ctrl_h_close":"ctrl+h kapat","i_insert":"i ekle","o_open_line":"o satır aç","cc_line":"cc satır","cw_word":"cw kelime","ce_word_end":"ce kelime sonu","c0_start":"c0 başlangıç","c_end":"c$ son","dd_line":"dd satır","dw_word":"dw kelime","de_word_end":"de kelime sonu","d0_start":"d0 başlangıç","d_end":"d$ son","yy_line":"yy satır","yw_word":"yw kelime","ye_word_end":"ye kelime sonu","y0_start":"y0 başlangıç","y_end":"y$ son","gg_top":"gg üst","esc_cancel":"esc iptal","type_filter":"filtre yaz","arrows_select":"↑/↓ seç","slash_filter":"/ filtre"},"evidence":{"head":"baş","tick":"tik","anchor":"çapa","coverage":"kapsam","complete":"tam","partial":"kısmi","unavailable":"kullanılamıyor"},"status":{"nav":"gezinme","filter":"filtre","read_only":"salt okunur","modified":"değiştirildi","modified_count":"{count} değiştirildi","pending_count":"{count} bekliyor","buffer_count":"{count} arabellek","loading":"yükleniyor"}},"history":{"title":"Echo Geçmişi","empty":"Henüz Echo kanıtı yok","header":"# tick tür durum kanıt özet"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Alt çubuk düzeni","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Dosya yolları","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Odak + çalışma alanı","footer_per_pane":"Bölme + çalışma alanı","footer_compact":"Kompakt","paths_git_root":"Git kökü","paths_absolute":"Tam yollar"},"toast":{"changed_title":"Settings changed","save_failed_title":"Ayarlar kaydedilmedi","save_failed_message":"~/.jimrc kaydedilemedi."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Ara","placeholder":"Dosyaları filtrele…","empty":"Eşleşme yok","preview_label":"Önizleme","preview_loading":"Önizleme yükleniyor…","preview_binary":"İkili dosya — önizleme yok","preview_unavailable":"Önizleme kullanılamıyor","preview_truncated":"Önizleme kısaltıldı"}}; -export const hi: TranslationSchema = {"footer":{"mode":{"browse":"ब्राउज़","insert":"सम्मिलित","normal":"सामान्य","preview":"पूर्वावलोकन","settings":"सेटिंग","files":"फाइलें","graft":"Graft","history":"इतिहास"},"context":{"settings":"सेटिंग","graft_empty":"जांचने के लिए फाइल खोलें","history_empty":"अभी कोई Echo प्रमाण नहीं","history_count":"Echo प्रमाण: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k चलें","enter_change":"enter बदलें","f2_close":"f2 बंद","esc_close":"esc बंद","j_k_scroll":"j/k स्क्रोल","f3_source":"f3 स्रोत","f3_preview":"f3 पूर्वावलोकन","text_input":"पाठ इनपुट","esc_normal":"esc सामान्य","ctrl_s_save":"ctrl+s सहेजें","ctrl_t_theme":"ctrl+t थीम","tab_focus":"tab फोकस","tab_indent":"tab इंडेंट","ctrl_b_files":"ctrl+b फाइलें","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h इतिहास","enter_open":"enter खोलें","backspace_up":"backspace ऊपर","ctrl_b_close":"ctrl+b बंद","enter_jump":"enter जाएं","r_refresh":"r ताज़ा","ctrl_g_close":"ctrl+g बंद","ctrl_h_close":"ctrl+h बंद","i_insert":"i सम्मिलित","o_open_line":"o पंक्ति खोलें","cc_line":"cc पंक्ति","cw_word":"cw शब्द","ce_word_end":"ce शब्द अंत","c0_start":"c0 शुरुआत","c_end":"c$ अंत","dd_line":"dd पंक्ति","dw_word":"dw शब्द","de_word_end":"de शब्द अंत","d0_start":"d0 शुरुआत","d_end":"d$ अंत","yy_line":"yy पंक्ति","yw_word":"yw शब्द","ye_word_end":"ye शब्द अंत","y0_start":"y0 शुरुआत","y_end":"y$ अंत","gg_top":"gg ऊपर","esc_cancel":"esc रद्द","type_filter":"फ़िल्टर लिखें","arrows_select":"↑/↓ चुनें","slash_filter":"/ फ़िल्टर"},"evidence":{"head":"शीर्ष","tick":"टिक","anchor":"एंकर","coverage":"कवरेज","complete":"पूर्ण","partial":"आंशिक","unavailable":"अनुपलब्ध"},"status":{"nav":"नेविगेशन","filter":"फ़िल्टर","read_only":"केवल पढ़ने योग्य","modified":"बदला गया","modified_count":"{count} बदले गए","pending_count":"{count} लंबित","buffer_count":"{count} बफ़र","loading":"लोड हो रहा है"}},"history":{"title":"Echo इतिहास","empty":"अभी कोई Echo प्रमाण नहीं","header":"# tick प्रकार स्थिति प्रमाण सारांश"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"फ़ुटर लेआउट","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"फ़ाइल पथ","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"फ़ोकस + कार्यक्षेत्र","footer_per_pane":"प्रति पैनल + कार्यक्षेत्र","footer_compact":"संक्षिप्त","paths_git_root":"Git रूट","paths_absolute":"पूर्ण पथ"},"toast":{"changed_title":"Settings changed","save_failed_title":"सेटिंग सहेजी नहीं गई","save_failed_message":"~/.jimrc सहेजा नहीं जा सका। JSON और अनुमतियाँ जाँचें। फ़ुटर लेआउट नहीं बदला है।."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"खोज","placeholder":"फ़ाइलें छाँटें…","empty":"कोई मेल नहीं","preview_label":"पूर्वावलोकन","preview_loading":"पूर्वावलोकन लोड हो रहा है…","preview_binary":"बाइनरी फ़ाइल — पूर्वावलोकन उपलब्ध नहीं","preview_unavailable":"पूर्वावलोकन उपलब्ध नहीं","preview_truncated":"पूर्वावलोकन संक्षिप्त है"}}; +export const hi: TranslationSchema = {"footer":{"mode":{"browse":"ब्राउज़","insert":"सम्मिलित","normal":"सामान्य","preview":"पूर्वावलोकन","settings":"सेटिंग","files":"फाइलें","graft":"Graft","history":"इतिहास"},"context":{"settings":"सेटिंग","graft_empty":"जांचने के लिए फाइल खोलें","history_empty":"अभी कोई Echo प्रमाण नहीं","history_count":"Echo प्रमाण: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k चलें","enter_change":"enter बदलें","f2_close":"f2 बंद","esc_close":"esc बंद","j_k_scroll":"j/k स्क्रोल","f3_source":"f3 स्रोत","f3_preview":"f3 पूर्वावलोकन","text_input":"पाठ इनपुट","esc_normal":"esc सामान्य","ctrl_s_save":"ctrl+s सहेजें","ctrl_t_theme":"ctrl+t थीम","tab_focus":"tab फोकस","tab_indent":"tab इंडेंट","ctrl_b_files":"ctrl+b फाइलें","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h इतिहास","enter_open":"enter खोलें / फैलाएँ","backspace_up":"backspace ऊपर","ctrl_b_close":"ctrl+b बंद","enter_jump":"enter जाएं","r_refresh":"r ताज़ा","ctrl_g_close":"ctrl+g बंद","ctrl_h_close":"ctrl+h बंद","i_insert":"i सम्मिलित","o_open_line":"o पंक्ति खोलें","cc_line":"cc पंक्ति","cw_word":"cw शब्द","ce_word_end":"ce शब्द अंत","c0_start":"c0 शुरुआत","c_end":"c$ अंत","dd_line":"dd पंक्ति","dw_word":"dw शब्द","de_word_end":"de शब्द अंत","d0_start":"d0 शुरुआत","d_end":"d$ अंत","yy_line":"yy पंक्ति","yw_word":"yw शब्द","ye_word_end":"ye शब्द अंत","y0_start":"y0 शुरुआत","y_end":"y$ अंत","gg_top":"gg ऊपर","esc_cancel":"esc रद्द","type_filter":"फ़िल्टर लिखें","arrows_select":"↑/↓ चुनें","slash_filter":"/ फ़िल्टर"},"evidence":{"head":"शीर्ष","tick":"टिक","anchor":"एंकर","coverage":"कवरेज","complete":"पूर्ण","partial":"आंशिक","unavailable":"अनुपलब्ध"},"status":{"nav":"नेविगेशन","filter":"फ़िल्टर","read_only":"केवल पढ़ने योग्य","modified":"बदला गया","modified_count":"{count} बदले गए","pending_count":"{count} लंबित","buffer_count":"{count} बफ़र","loading":"लोड हो रहा है"}},"history":{"title":"Echo इतिहास","empty":"अभी कोई Echo प्रमाण नहीं","header":"# tick प्रकार स्थिति प्रमाण सारांश"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"फ़ुटर लेआउट","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"फ़ाइल पथ","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"फ़ोकस + कार्यक्षेत्र","footer_per_pane":"प्रति पैनल + कार्यक्षेत्र","footer_compact":"संक्षिप्त","paths_git_root":"Git रूट","paths_absolute":"पूर्ण पथ"},"toast":{"changed_title":"Settings changed","save_failed_title":"सेटिंग सहेजी नहीं गई","save_failed_message":"~/.jimrc सहेजा नहीं जा सका। JSON और अनुमतियाँ जाँचें। फ़ुटर लेआउट नहीं बदला है।."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"खोज","placeholder":"फ़ाइलें छाँटें…","empty":"कोई मेल नहीं","preview_label":"पूर्वावलोकन","preview_loading":"पूर्वावलोकन लोड हो रहा है…","preview_binary":"बाइनरी फ़ाइल — पूर्वावलोकन उपलब्ध नहीं","preview_unavailable":"पूर्वावलोकन उपलब्ध नहीं","preview_truncated":"पूर्वावलोकन संक्षिप्त है"}}; -export const nl: TranslationSchema = {"footer":{"mode":{"browse":"bladeren","insert":"invoegen","normal":"normaal","preview":"voorbeeld","settings":"instellingen","files":"bestanden","graft":"graft","history":"geschiedenis"},"context":{"settings":"instellingen","graft_empty":"open een bestand om te inspecteren","history_empty":"nog geen Echo-bewijs","history_count":"Echo-bewijs: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k bewegen","enter_change":"enter wijzigen","f2_close":"f2 sluiten","esc_close":"esc sluiten","j_k_scroll":"j/k scrollen","f3_source":"f3 bron","f3_preview":"f3 voorbeeld","text_input":"tekstinvoer","esc_normal":"esc normaal","ctrl_s_save":"ctrl+s opslaan","ctrl_t_theme":"ctrl+t thema","tab_focus":"tab focus","tab_indent":"tab inspringen","ctrl_b_files":"ctrl+b bestanden","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h geschiedenis","enter_open":"enter openen","backspace_up":"backspace omhoog","ctrl_b_close":"ctrl+b sluiten","enter_jump":"enter springen","r_refresh":"r vernieuwen","ctrl_g_close":"ctrl+g sluiten","ctrl_h_close":"ctrl+h sluiten","i_insert":"i invoegen","o_open_line":"o regel openen","cc_line":"cc regel","cw_word":"cw woord","ce_word_end":"ce woord-einde","c0_start":"c0 begin","c_end":"c$ einde","dd_line":"dd regel","dw_word":"dw woord","de_word_end":"de woord-einde","d0_start":"d0 begin","d_end":"d$ einde","yy_line":"yy regel","yw_word":"yw woord","ye_word_end":"ye woord-einde","y0_start":"y0 begin","y_end":"y$ einde","gg_top":"gg boven","esc_cancel":"esc annuleren","type_filter":"filter typen","arrows_select":"↑/↓ selecteren","slash_filter":"/ filter"},"evidence":{"head":"kop","tick":"tick","anchor":"anker","coverage":"dekking","complete":"volledig","partial":"gedeeltelijk","unavailable":"niet beschikbaar"},"status":{"nav":"navigatie","filter":"filter","read_only":"alleen-lezen","modified":"gewijzigd","modified_count":"{count} gewijzigd","pending_count":"{count} in behandeling","buffer_count":"{count} buffers","loading":"laden"}},"history":{"title":"Echo-geschiedenis","empty":"Nog geen Echo-bewijs","header":"# tick soort status bewijs samenvatting"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Voettekstindeling","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Bestandspaden","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Focus + werkruimte","footer_per_pane":"Per paneel + werkruimte","footer_compact":"Compact","paths_git_root":"Git-hoofdmap","paths_absolute":"Volledige paden"},"toast":{"changed_title":"Settings changed","save_failed_title":"Instellingen niet bewaard","save_failed_message":"Kan ~/.jimrc niet opslaan."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Zoeken","placeholder":"Bestanden filteren…","empty":"Geen resultaten","preview_label":"Voorbeeld","preview_loading":"Voorbeeld laden…","preview_binary":"Binair bestand — geen voorbeeld","preview_unavailable":"Voorbeeld niet beschikbaar","preview_truncated":"Voorbeeld ingekort"}}; +export const nl: TranslationSchema = {"footer":{"mode":{"browse":"bladeren","insert":"invoegen","normal":"normaal","preview":"voorbeeld","settings":"instellingen","files":"bestanden","graft":"graft","history":"geschiedenis"},"context":{"settings":"instellingen","graft_empty":"open een bestand om te inspecteren","history_empty":"nog geen Echo-bewijs","history_count":"Echo-bewijs: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k bewegen","enter_change":"enter wijzigen","f2_close":"f2 sluiten","esc_close":"esc sluiten","j_k_scroll":"j/k scrollen","f3_source":"f3 bron","f3_preview":"f3 voorbeeld","text_input":"tekstinvoer","esc_normal":"esc normaal","ctrl_s_save":"ctrl+s opslaan","ctrl_t_theme":"ctrl+t thema","tab_focus":"tab focus","tab_indent":"tab inspringen","ctrl_b_files":"ctrl+b bestanden","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h geschiedenis","enter_open":"enter openen / uitklappen","backspace_up":"backspace omhoog","ctrl_b_close":"ctrl+b sluiten","enter_jump":"enter springen","r_refresh":"r vernieuwen","ctrl_g_close":"ctrl+g sluiten","ctrl_h_close":"ctrl+h sluiten","i_insert":"i invoegen","o_open_line":"o regel openen","cc_line":"cc regel","cw_word":"cw woord","ce_word_end":"ce woord-einde","c0_start":"c0 begin","c_end":"c$ einde","dd_line":"dd regel","dw_word":"dw woord","de_word_end":"de woord-einde","d0_start":"d0 begin","d_end":"d$ einde","yy_line":"yy regel","yw_word":"yw woord","ye_word_end":"ye woord-einde","y0_start":"y0 begin","y_end":"y$ einde","gg_top":"gg boven","esc_cancel":"esc annuleren","type_filter":"filter typen","arrows_select":"↑/↓ selecteren","slash_filter":"/ filter"},"evidence":{"head":"kop","tick":"tick","anchor":"anker","coverage":"dekking","complete":"volledig","partial":"gedeeltelijk","unavailable":"niet beschikbaar"},"status":{"nav":"navigatie","filter":"filter","read_only":"alleen-lezen","modified":"gewijzigd","modified_count":"{count} gewijzigd","pending_count":"{count} in behandeling","buffer_count":"{count} buffers","loading":"laden"}},"history":{"title":"Echo-geschiedenis","empty":"Nog geen Echo-bewijs","header":"# tick soort status bewijs samenvatting"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Voettekstindeling","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Bestandspaden","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Focus + werkruimte","footer_per_pane":"Per paneel + werkruimte","footer_compact":"Compact","paths_git_root":"Git-hoofdmap","paths_absolute":"Volledige paden"},"toast":{"changed_title":"Settings changed","save_failed_title":"Instellingen niet bewaard","save_failed_message":"Kan ~/.jimrc niet opslaan."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Zoeken","placeholder":"Bestanden filteren…","empty":"Geen resultaten","preview_label":"Voorbeeld","preview_loading":"Voorbeeld laden…","preview_binary":"Binair bestand — geen voorbeeld","preview_unavailable":"Voorbeeld niet beschikbaar","preview_truncated":"Voorbeeld ingekort"}}; -export const pl: TranslationSchema = {"footer":{"mode":{"browse":"przeglądaj","insert":"wstaw","normal":"normalny","preview":"podgląd","settings":"ustawienia","files":"pliki","graft":"graft","history":"historia"},"context":{"settings":"ustawienia","graft_empty":"otwórz plik do sprawdzenia","history_empty":"brak jeszcze dowodów Echo","history_count":"Dowody Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k przesuń","enter_change":"enter zmień","f2_close":"f2 zamknij","esc_close":"esc zamknij","j_k_scroll":"j/k przewiń","f3_source":"f3 źródło","f3_preview":"f3 podgląd","text_input":"wpisywanie tekstu","esc_normal":"esc normalny","ctrl_s_save":"ctrl+s zapisz","ctrl_t_theme":"ctrl+t motyw","tab_focus":"tab fokus","tab_indent":"tab wcięcie","ctrl_b_files":"ctrl+b pliki","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h historia","enter_open":"enter otwórz","backspace_up":"backspace w górę","ctrl_b_close":"ctrl+b zamknij","enter_jump":"enter skocz","r_refresh":"r odśwież","ctrl_g_close":"ctrl+g zamknij","ctrl_h_close":"ctrl+h zamknij","i_insert":"i wstaw","o_open_line":"o otwórz linię","cc_line":"cc linia","cw_word":"cw słowo","ce_word_end":"ce koniec słowa","c0_start":"c0 początek","c_end":"c$ koniec","dd_line":"dd linia","dw_word":"dw słowo","de_word_end":"de koniec słowa","d0_start":"d0 początek","d_end":"d$ koniec","yy_line":"yy linia","yw_word":"yw słowo","ye_word_end":"ye koniec słowa","y0_start":"y0 początek","y_end":"y$ koniec","gg_top":"gg góra","esc_cancel":"esc anuluj","type_filter":"wpisz filtr","arrows_select":"↑/↓ wybierz","slash_filter":"/ filtr"},"evidence":{"head":"głowa","tick":"takt","anchor":"kotwica","coverage":"pokrycie","complete":"pełne","partial":"częściowe","unavailable":"niedostępne"},"status":{"nav":"nawigacja","filter":"filtr","read_only":"tylko odczyt","modified":"zmieniony","modified_count":"zmienione: {count}","pending_count":"oczekujące: {count}","buffer_count":"bufory: {count}","loading":"ładowanie"}},"history":{"title":"Historia Echo","empty":"Brak jeszcze dowodów Echo","header":"# tick typ status dowód podsumowanie"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Układ stopki","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Ścieżki plików","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Fokus + obszar pracy","footer_per_pane":"Panele + obszar pracy","footer_compact":"Kompaktowy","paths_git_root":"Katalog Git","paths_absolute":"Pełne ścieżki"},"toast":{"changed_title":"Settings changed","save_failed_title":"Ustawienia niezapisane","save_failed_message":"Nie można zapisać ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Szukaj","placeholder":"Filtruj pliki…","empty":"Brak wyników","preview_label":"Podgląd","preview_loading":"Wczytywanie podglądu…","preview_binary":"Plik binarny — brak podglądu","preview_unavailable":"Podgląd niedostępny","preview_truncated":"Podgląd skrócony"}}; +export const pl: TranslationSchema = {"footer":{"mode":{"browse":"przeglądaj","insert":"wstaw","normal":"normalny","preview":"podgląd","settings":"ustawienia","files":"pliki","graft":"graft","history":"historia"},"context":{"settings":"ustawienia","graft_empty":"otwórz plik do sprawdzenia","history_empty":"brak jeszcze dowodów Echo","history_count":"Dowody Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k przesuń","enter_change":"enter zmień","f2_close":"f2 zamknij","esc_close":"esc zamknij","j_k_scroll":"j/k przewiń","f3_source":"f3 źródło","f3_preview":"f3 podgląd","text_input":"wpisywanie tekstu","esc_normal":"esc normalny","ctrl_s_save":"ctrl+s zapisz","ctrl_t_theme":"ctrl+t motyw","tab_focus":"tab fokus","tab_indent":"tab wcięcie","ctrl_b_files":"ctrl+b pliki","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h historia","enter_open":"enter otwórz / rozwiń","backspace_up":"backspace w górę","ctrl_b_close":"ctrl+b zamknij","enter_jump":"enter skocz","r_refresh":"r odśwież","ctrl_g_close":"ctrl+g zamknij","ctrl_h_close":"ctrl+h zamknij","i_insert":"i wstaw","o_open_line":"o otwórz linię","cc_line":"cc linia","cw_word":"cw słowo","ce_word_end":"ce koniec słowa","c0_start":"c0 początek","c_end":"c$ koniec","dd_line":"dd linia","dw_word":"dw słowo","de_word_end":"de koniec słowa","d0_start":"d0 początek","d_end":"d$ koniec","yy_line":"yy linia","yw_word":"yw słowo","ye_word_end":"ye koniec słowa","y0_start":"y0 początek","y_end":"y$ koniec","gg_top":"gg góra","esc_cancel":"esc anuluj","type_filter":"wpisz filtr","arrows_select":"↑/↓ wybierz","slash_filter":"/ filtr"},"evidence":{"head":"głowa","tick":"takt","anchor":"kotwica","coverage":"pokrycie","complete":"pełne","partial":"częściowe","unavailable":"niedostępne"},"status":{"nav":"nawigacja","filter":"filtr","read_only":"tylko odczyt","modified":"zmieniony","modified_count":"zmienione: {count}","pending_count":"oczekujące: {count}","buffer_count":"bufory: {count}","loading":"ładowanie"}},"history":{"title":"Historia Echo","empty":"Brak jeszcze dowodów Echo","header":"# tick typ status dowód podsumowanie"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Układ stopki","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Ścieżki plików","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Fokus + obszar pracy","footer_per_pane":"Panele + obszar pracy","footer_compact":"Kompaktowy","paths_git_root":"Katalog Git","paths_absolute":"Pełne ścieżki"},"toast":{"changed_title":"Settings changed","save_failed_title":"Ustawienia niezapisane","save_failed_message":"Nie można zapisać ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Szukaj","placeholder":"Filtruj pliki…","empty":"Brak wyników","preview_label":"Podgląd","preview_loading":"Wczytywanie podglądu…","preview_binary":"Plik binarny — brak podglądu","preview_unavailable":"Podgląd niedostępny","preview_truncated":"Podgląd skrócony"}}; -export const vi: TranslationSchema = {"footer":{"mode":{"browse":"duyệt","insert":"chèn","normal":"thường","preview":"xem trước","settings":"cài đặt","files":"tệp","graft":"graft","history":"lịch sử"},"context":{"settings":"cài đặt","graft_empty":"mở tệp để kiểm tra","history_empty":"chưa có bằng chứng Echo","history_count":"Bằng chứng Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k di chuyển","enter_change":"enter đổi","f2_close":"f2 đóng","esc_close":"esc đóng","j_k_scroll":"j/k cuộn","f3_source":"f3 nguồn","f3_preview":"f3 xem trước","text_input":"nhập văn bản","esc_normal":"esc thường","ctrl_s_save":"ctrl+s lưu","ctrl_t_theme":"ctrl+t giao diện","tab_focus":"tab tiêu điểm","tab_indent":"tab thụt lề","ctrl_b_files":"ctrl+b tệp","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h lịch sử","enter_open":"enter mở","backspace_up":"backspace lên","ctrl_b_close":"ctrl+b đóng","enter_jump":"enter nhảy","r_refresh":"r làm mới","ctrl_g_close":"ctrl+g đóng","ctrl_h_close":"ctrl+h đóng","i_insert":"i chèn","o_open_line":"o mở dòng","cc_line":"cc dòng","cw_word":"cw từ","ce_word_end":"ce cuối từ","c0_start":"c0 đầu","c_end":"c$ cuối","dd_line":"dd dòng","dw_word":"dw từ","de_word_end":"de cuối từ","d0_start":"d0 đầu","d_end":"d$ cuối","yy_line":"yy dòng","yw_word":"yw từ","ye_word_end":"ye cuối từ","y0_start":"y0 đầu","y_end":"y$ cuối","gg_top":"gg đầu","esc_cancel":"esc hủy","type_filter":"nhập bộ lọc","arrows_select":"↑/↓ chọn","slash_filter":"/ lọc"},"evidence":{"head":"đầu","tick":"nhịp","anchor":"neo","coverage":"độ phủ","complete":"đầy đủ","partial":"một phần","unavailable":"không khả dụng"},"status":{"nav":"điều hướng","filter":"lọc","read_only":"chỉ đọc","modified":"đã sửa","modified_count":"{count} đã sửa","pending_count":"{count} đang chờ","buffer_count":"{count} bộ đệm","loading":"đang tải"}},"history":{"title":"Lịch sử Echo","empty":"Chưa có bằng chứng Echo","header":"# tick loại trạng thái bằng chứng tóm tắt"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Bố cục chân trang","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Đường dẫn","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Tiêu điểm + không gian","footer_per_pane":"Theo ngăn + không gian","footer_compact":"Gọn","paths_git_root":"Gốc Git","paths_absolute":"Đường dẫn đầy đủ"},"toast":{"changed_title":"Settings changed","save_failed_title":"Chưa lưu cài đặt","save_failed_message":"Không thể lưu ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Tìm","placeholder":"Lọc tệp…","empty":"Không khớp","preview_label":"Xem trước","preview_loading":"Đang tải bản xem trước…","preview_binary":"Tệp nhị phân — không thể xem trước","preview_unavailable":"Không thể xem trước","preview_truncated":"Bản xem trước bị cắt"}}; +export const vi: TranslationSchema = {"footer":{"mode":{"browse":"duyệt","insert":"chèn","normal":"thường","preview":"xem trước","settings":"cài đặt","files":"tệp","graft":"graft","history":"lịch sử"},"context":{"settings":"cài đặt","graft_empty":"mở tệp để kiểm tra","history_empty":"chưa có bằng chứng Echo","history_count":"Bằng chứng Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k di chuyển","enter_change":"enter đổi","f2_close":"f2 đóng","esc_close":"esc đóng","j_k_scroll":"j/k cuộn","f3_source":"f3 nguồn","f3_preview":"f3 xem trước","text_input":"nhập văn bản","esc_normal":"esc thường","ctrl_s_save":"ctrl+s lưu","ctrl_t_theme":"ctrl+t giao diện","tab_focus":"tab tiêu điểm","tab_indent":"tab thụt lề","ctrl_b_files":"ctrl+b tệp","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h lịch sử","enter_open":"enter mở / mở rộng","backspace_up":"backspace lên","ctrl_b_close":"ctrl+b đóng","enter_jump":"enter nhảy","r_refresh":"r làm mới","ctrl_g_close":"ctrl+g đóng","ctrl_h_close":"ctrl+h đóng","i_insert":"i chèn","o_open_line":"o mở dòng","cc_line":"cc dòng","cw_word":"cw từ","ce_word_end":"ce cuối từ","c0_start":"c0 đầu","c_end":"c$ cuối","dd_line":"dd dòng","dw_word":"dw từ","de_word_end":"de cuối từ","d0_start":"d0 đầu","d_end":"d$ cuối","yy_line":"yy dòng","yw_word":"yw từ","ye_word_end":"ye cuối từ","y0_start":"y0 đầu","y_end":"y$ cuối","gg_top":"gg đầu","esc_cancel":"esc hủy","type_filter":"nhập bộ lọc","arrows_select":"↑/↓ chọn","slash_filter":"/ lọc"},"evidence":{"head":"đầu","tick":"nhịp","anchor":"neo","coverage":"độ phủ","complete":"đầy đủ","partial":"một phần","unavailable":"không khả dụng"},"status":{"nav":"điều hướng","filter":"lọc","read_only":"chỉ đọc","modified":"đã sửa","modified_count":"{count} đã sửa","pending_count":"{count} đang chờ","buffer_count":"{count} bộ đệm","loading":"đang tải"}},"history":{"title":"Lịch sử Echo","empty":"Chưa có bằng chứng Echo","header":"# tick loại trạng thái bằng chứng tóm tắt"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"Bố cục chân trang","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"Đường dẫn","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"Tiêu điểm + không gian","footer_per_pane":"Theo ngăn + không gian","footer_compact":"Gọn","paths_git_root":"Gốc Git","paths_absolute":"Đường dẫn đầy đủ"},"toast":{"changed_title":"Settings changed","save_failed_title":"Chưa lưu cài đặt","save_failed_message":"Không thể lưu ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"Tìm","placeholder":"Lọc tệp…","empty":"Không khớp","preview_label":"Xem trước","preview_loading":"Đang tải bản xem trước…","preview_binary":"Tệp nhị phân — không thể xem trước","preview_unavailable":"Không thể xem trước","preview_truncated":"Bản xem trước bị cắt"}}; -export const th: TranslationSchema = {"footer":{"mode":{"browse":"เรียกดู","insert":"แทรก","normal":"ปกติ","preview":"ดูตัวอย่าง","settings":"ตั้งค่า","files":"ไฟล์","graft":"Graft","history":"ประวัติ"},"context":{"settings":"ตั้งค่า","graft_empty":"เปิดไฟล์เพื่อตรวจสอบ","history_empty":"ยังไม่มีหลักฐาน Echo","history_count":"หลักฐาน Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k ย้าย","enter_change":"enter เปลี่ยน","f2_close":"f2 ปิด","esc_close":"esc ปิด","j_k_scroll":"j/k เลื่อน","f3_source":"f3 ต้นฉบับ","f3_preview":"f3 ดูตัวอย่าง","text_input":"ป้อนข้อความ","esc_normal":"esc ปกติ","ctrl_s_save":"ctrl+s บันทึก","ctrl_t_theme":"ctrl+t ธีม","tab_focus":"tab โฟกัส","tab_indent":"tab เยื้อง","ctrl_b_files":"ctrl+b ไฟล์","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h ประวัติ","enter_open":"enter เปิด","backspace_up":"backspace ขึ้น","ctrl_b_close":"ctrl+b ปิด","enter_jump":"enter ไป","r_refresh":"r รีเฟรช","ctrl_g_close":"ctrl+g ปิด","ctrl_h_close":"ctrl+h ปิด","i_insert":"i แทรก","o_open_line":"o เปิดบรรทัด","cc_line":"cc บรรทัด","cw_word":"cw คำ","ce_word_end":"ce จบคำ","c0_start":"c0 เริ่ม","c_end":"c$ จบ","dd_line":"dd บรรทัด","dw_word":"dw คำ","de_word_end":"de จบคำ","d0_start":"d0 เริ่ม","d_end":"d$ จบ","yy_line":"yy บรรทัด","yw_word":"yw คำ","ye_word_end":"ye จบคำ","y0_start":"y0 เริ่ม","y_end":"y$ จบ","gg_top":"gg บน","esc_cancel":"esc ยกเลิก","type_filter":"พิมพ์ตัวกรอง","arrows_select":"↑/↓ เลือก","slash_filter":"/ กรอง"},"evidence":{"head":"เฮด","tick":"ทิก","anchor":"จุดยึด","coverage":"ความครอบคลุม","complete":"ครบถ้วน","partial":"บางส่วน","unavailable":"ไม่พร้อมใช้งาน"},"status":{"nav":"นำทาง","filter":"กรอง","read_only":"อ่านอย่างเดียว","modified":"แก้ไขแล้ว","modified_count":"แก้ไข {count}","pending_count":"รอดำเนินการ {count}","buffer_count":"บัฟเฟอร์ {count}","loading":"กำลังโหลด"}},"history":{"title":"ประวัติ Echo","empty":"ยังไม่มีหลักฐาน Echo","header":"# tick ชนิด สถานะ หลักฐาน สรุป"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"รูปแบบแถบล่าง","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"เส้นทางไฟล์","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"โฟกัส + พื้นที่ทำงาน","footer_per_pane":"แยกแผง + พื้นที่ทำงาน","footer_compact":"กะทัดรัด","paths_git_root":"ราก Git","paths_absolute":"เส้นทางเต็ม"},"toast":{"changed_title":"Settings changed","save_failed_title":"ไม่ได้บันทึกการตั้งค่า","save_failed_message":"บันทึก ~/.jimrc ไม่ได้ ตรวจสอบ JSON และสิทธิ์"}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"ค้นหา","placeholder":"กรองไฟล์…","empty":"ไม่พบผลลัพธ์","preview_label":"ตัวอย่าง","preview_loading":"กำลังโหลดตัวอย่าง…","preview_binary":"ไฟล์ไบนารี — ไม่สามารถแสดงตัวอย่าง","preview_unavailable":"ไม่สามารถแสดงตัวอย่าง","preview_truncated":"ตัวอย่างถูกตัด"}}; +export const th: TranslationSchema = {"footer":{"mode":{"browse":"เรียกดู","insert":"แทรก","normal":"ปกติ","preview":"ดูตัวอย่าง","settings":"ตั้งค่า","files":"ไฟล์","graft":"Graft","history":"ประวัติ"},"context":{"settings":"ตั้งค่า","graft_empty":"เปิดไฟล์เพื่อตรวจสอบ","history_empty":"ยังไม่มีหลักฐาน Echo","history_count":"หลักฐาน Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k ย้าย","enter_change":"enter เปลี่ยน","f2_close":"f2 ปิด","esc_close":"esc ปิด","j_k_scroll":"j/k เลื่อน","f3_source":"f3 ต้นฉบับ","f3_preview":"f3 ดูตัวอย่าง","text_input":"ป้อนข้อความ","esc_normal":"esc ปกติ","ctrl_s_save":"ctrl+s บันทึก","ctrl_t_theme":"ctrl+t ธีม","tab_focus":"tab โฟกัส","tab_indent":"tab เยื้อง","ctrl_b_files":"ctrl+b ไฟล์","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h ประวัติ","enter_open":"enter เปิด / ขยาย","backspace_up":"backspace ขึ้น","ctrl_b_close":"ctrl+b ปิด","enter_jump":"enter ไป","r_refresh":"r รีเฟรช","ctrl_g_close":"ctrl+g ปิด","ctrl_h_close":"ctrl+h ปิด","i_insert":"i แทรก","o_open_line":"o เปิดบรรทัด","cc_line":"cc บรรทัด","cw_word":"cw คำ","ce_word_end":"ce จบคำ","c0_start":"c0 เริ่ม","c_end":"c$ จบ","dd_line":"dd บรรทัด","dw_word":"dw คำ","de_word_end":"de จบคำ","d0_start":"d0 เริ่ม","d_end":"d$ จบ","yy_line":"yy บรรทัด","yw_word":"yw คำ","ye_word_end":"ye จบคำ","y0_start":"y0 เริ่ม","y_end":"y$ จบ","gg_top":"gg บน","esc_cancel":"esc ยกเลิก","type_filter":"พิมพ์ตัวกรอง","arrows_select":"↑/↓ เลือก","slash_filter":"/ กรอง"},"evidence":{"head":"เฮด","tick":"ทิก","anchor":"จุดยึด","coverage":"ความครอบคลุม","complete":"ครบถ้วน","partial":"บางส่วน","unavailable":"ไม่พร้อมใช้งาน"},"status":{"nav":"นำทาง","filter":"กรอง","read_only":"อ่านอย่างเดียว","modified":"แก้ไขแล้ว","modified_count":"แก้ไข {count}","pending_count":"รอดำเนินการ {count}","buffer_count":"บัฟเฟอร์ {count}","loading":"กำลังโหลด"}},"history":{"title":"ประวัติ Echo","empty":"ยังไม่มีหลักฐาน Echo","header":"# tick ชนิด สถานะ หลักฐาน สรุป"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"รูปแบบแถบล่าง","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"เส้นทางไฟล์","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"โฟกัส + พื้นที่ทำงาน","footer_per_pane":"แยกแผง + พื้นที่ทำงาน","footer_compact":"กะทัดรัด","paths_git_root":"ราก Git","paths_absolute":"เส้นทางเต็ม"},"toast":{"changed_title":"Settings changed","save_failed_title":"ไม่ได้บันทึกการตั้งค่า","save_failed_message":"บันทึก ~/.jimrc ไม่ได้ ตรวจสอบ JSON และสิทธิ์"}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"ค้นหา","placeholder":"กรองไฟล์…","empty":"ไม่พบผลลัพธ์","preview_label":"ตัวอย่าง","preview_loading":"กำลังโหลดตัวอย่าง…","preview_binary":"ไฟล์ไบนารี — ไม่สามารถแสดงตัวอย่าง","preview_unavailable":"ไม่สามารถแสดงตัวอย่าง","preview_truncated":"ตัวอย่างถูกตัด"}}; -export const fa: TranslationSchema = {"footer":{"mode":{"browse":"مرور","insert":"درج","normal":"عادی","preview":"پیش‌نمایش","settings":"تنظیمات","files":"فایل‌ها","graft":"Graft","history":"تاریخچه"},"context":{"settings":"تنظیمات","graft_empty":"برای بررسی یک فایل باز کنید","history_empty":"هنوز مدرک Echo وجود ندارد","history_count":"مدارک Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k حرکت","enter_change":"enter تغییر","f2_close":"f2 بستن","esc_close":"esc بستن","j_k_scroll":"j/k پیمایش","f3_source":"f3 منبع","f3_preview":"f3 پیش‌نمایش","text_input":"ورودی متن","esc_normal":"esc عادی","ctrl_s_save":"ctrl+s ذخیره","ctrl_t_theme":"ctrl+t پوسته","tab_focus":"tab تمرکز","tab_indent":"tab تورفتگی","ctrl_b_files":"ctrl+b فایل‌ها","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h تاریخچه","enter_open":"enter باز کردن","backspace_up":"backspace بالا","ctrl_b_close":"ctrl+b بستن","enter_jump":"enter پرش","r_refresh":"r تازه‌سازی","ctrl_g_close":"ctrl+g بستن","ctrl_h_close":"ctrl+h بستن","i_insert":"i درج","o_open_line":"o باز کردن خط","cc_line":"cc خط","cw_word":"cw واژه","ce_word_end":"ce پایان واژه","c0_start":"c0 آغاز","c_end":"c$ پایان","dd_line":"dd خط","dw_word":"dw واژه","de_word_end":"de پایان واژه","d0_start":"d0 آغاز","d_end":"d$ پایان","yy_line":"yy خط","yw_word":"yw واژه","ye_word_end":"ye پایان واژه","y0_start":"y0 آغاز","y_end":"y$ پایان","gg_top":"gg بالا","esc_cancel":"esc لغو","type_filter":"نوشتن فیلتر","arrows_select":"↑/↓ انتخاب","slash_filter":"/ فیلتر"},"evidence":{"head":"سر","tick":"تیک","anchor":"لنگر","coverage":"پوشش","complete":"کامل","partial":"جزئی","unavailable":"در دسترس نیست"},"status":{"nav":"پیمایش","filter":"پالایش","read_only":"فقط خواندنی","modified":"ویرایش‌شده","modified_count":"{count} ویرایش‌شده","pending_count":"{count} در انتظار","buffer_count":"{count} بافر","loading":"در حال بارگیری"}},"history":{"title":"تاریخچه Echo","empty":"هنوز مدرک Echo وجود ندارد","header":"# tick نوع وضعیت مدرک خلاصه"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"چیدمان پانوشت","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"مسیر پرونده‌ها","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"تمرکز و فضای کار","footer_per_pane":"هر بخش و فضای کار","footer_compact":"فشرده","paths_git_root":"ریشه Git","paths_absolute":"مسیر کامل"},"toast":{"changed_title":"Settings changed","save_failed_title":"تنظیمات ذخیره نشد","save_failed_message":"ذخیره ~/.jimrc ممکن نشد."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"جستجو","placeholder":"فیلتر پرونده‌ها…","empty":"بدون نتیجه","preview_label":"پیش‌نمایش","preview_loading":"در حال بارگذاری پیش‌نمایش…","preview_binary":"فایل دودویی — پیش‌نمایش در دسترس نیست","preview_unavailable":"پیش‌نمایش در دسترس نیست","preview_truncated":"پیش‌نمایش کوتاه شده"}}; +export const fa: TranslationSchema = {"footer":{"mode":{"browse":"مرور","insert":"درج","normal":"عادی","preview":"پیش‌نمایش","settings":"تنظیمات","files":"فایل‌ها","graft":"Graft","history":"تاریخچه"},"context":{"settings":"تنظیمات","graft_empty":"برای بررسی یک فایل باز کنید","history_empty":"هنوز مدرک Echo وجود ندارد","history_count":"مدارک Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k حرکت","enter_change":"enter تغییر","f2_close":"f2 بستن","esc_close":"esc بستن","j_k_scroll":"j/k پیمایش","f3_source":"f3 منبع","f3_preview":"f3 پیش‌نمایش","text_input":"ورودی متن","esc_normal":"esc عادی","ctrl_s_save":"ctrl+s ذخیره","ctrl_t_theme":"ctrl+t پوسته","tab_focus":"tab تمرکز","tab_indent":"tab تورفتگی","ctrl_b_files":"ctrl+b فایل‌ها","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h تاریخچه","enter_open":"enter باز کردن / گسترش","backspace_up":"backspace بالا","ctrl_b_close":"ctrl+b بستن","enter_jump":"enter پرش","r_refresh":"r تازه‌سازی","ctrl_g_close":"ctrl+g بستن","ctrl_h_close":"ctrl+h بستن","i_insert":"i درج","o_open_line":"o باز کردن خط","cc_line":"cc خط","cw_word":"cw واژه","ce_word_end":"ce پایان واژه","c0_start":"c0 آغاز","c_end":"c$ پایان","dd_line":"dd خط","dw_word":"dw واژه","de_word_end":"de پایان واژه","d0_start":"d0 آغاز","d_end":"d$ پایان","yy_line":"yy خط","yw_word":"yw واژه","ye_word_end":"ye پایان واژه","y0_start":"y0 آغاز","y_end":"y$ پایان","gg_top":"gg بالا","esc_cancel":"esc لغو","type_filter":"نوشتن فیلتر","arrows_select":"↑/↓ انتخاب","slash_filter":"/ فیلتر"},"evidence":{"head":"سر","tick":"تیک","anchor":"لنگر","coverage":"پوشش","complete":"کامل","partial":"جزئی","unavailable":"در دسترس نیست"},"status":{"nav":"پیمایش","filter":"پالایش","read_only":"فقط خواندنی","modified":"ویرایش‌شده","modified_count":"{count} ویرایش‌شده","pending_count":"{count} در انتظار","buffer_count":"{count} بافر","loading":"در حال بارگیری"}},"history":{"title":"تاریخچه Echo","empty":"هنوز مدرک Echo وجود ندارد","header":"# tick نوع وضعیت مدرک خلاصه"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"چیدمان پانوشت","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"مسیر پرونده‌ها","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"تمرکز و فضای کار","footer_per_pane":"هر بخش و فضای کار","footer_compact":"فشرده","paths_git_root":"ریشه Git","paths_absolute":"مسیر کامل"},"toast":{"changed_title":"Settings changed","save_failed_title":"تنظیمات ذخیره نشد","save_failed_message":"ذخیره ~/.jimrc ممکن نشد."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"جستجو","placeholder":"فیلتر پرونده‌ها…","empty":"بدون نتیجه","preview_label":"پیش‌نمایش","preview_loading":"در حال بارگذاری پیش‌نمایش…","preview_binary":"فایل دودویی — پیش‌نمایش در دسترس نیست","preview_unavailable":"پیش‌نمایش در دسترس نیست","preview_truncated":"پیش‌نمایش کوتاه شده"}}; -export const he: TranslationSchema = {"footer":{"mode":{"browse":"עיון","insert":"הוספה","normal":"רגיל","preview":"תצוגה","settings":"הגדרות","files":"קבצים","graft":"Graft","history":"היסטוריה"},"context":{"settings":"הגדרות","graft_empty":"פתח קובץ לבדיקה","history_empty":"עדיין אין ראיות Echo","history_count":"ראיות Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k הזז","enter_change":"enter שנה","f2_close":"f2 סגור","esc_close":"esc סגור","j_k_scroll":"j/k גלול","f3_source":"f3 מקור","f3_preview":"f3 תצוגה","text_input":"קלט טקסט","esc_normal":"esc רגיל","ctrl_s_save":"ctrl+s שמור","ctrl_t_theme":"ctrl+t ערכת נושא","tab_focus":"tab מיקוד","tab_indent":"tab הזחה","ctrl_b_files":"ctrl+b קבצים","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h היסטוריה","enter_open":"enter פתח","backspace_up":"backspace למעלה","ctrl_b_close":"ctrl+b סגור","enter_jump":"enter קפוץ","r_refresh":"r רענן","ctrl_g_close":"ctrl+g סגור","ctrl_h_close":"ctrl+h סגור","i_insert":"i הוסף","o_open_line":"o פתח שורה","cc_line":"cc שורה","cw_word":"cw מילה","ce_word_end":"ce סוף מילה","c0_start":"c0 התחלה","c_end":"c$ סוף","dd_line":"dd שורה","dw_word":"dw מילה","de_word_end":"de סוף מילה","d0_start":"d0 התחלה","d_end":"d$ סוף","yy_line":"yy שורה","yw_word":"yw מילה","ye_word_end":"ye סוף מילה","y0_start":"y0 התחלה","y_end":"y$ סוף","gg_top":"gg למעלה","esc_cancel":"esc בטל","type_filter":"הקלדת סינון","arrows_select":"↑/↓ בחירה","slash_filter":"/ סינון"},"evidence":{"head":"ראש","tick":"טיק","anchor":"עוגן","coverage":"כיסוי","complete":"מלא","partial":"חלקי","unavailable":"לא זמין"},"status":{"nav":"ניווט","filter":"סינון","read_only":"לקריאה בלבד","modified":"שונה","modified_count":"{count} שונו","pending_count":"{count} בהמתנה","buffer_count":"{count} מאגרים","loading":"בטעינה"}},"history":{"title":"היסטוריית Echo","empty":"עדיין אין ראיות Echo","header":"# tick סוג מצב ראיה סיכום"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"פריסת שורת מצב","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"נתיבי קבצים","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"מיקוד וסביבת עבודה","footer_per_pane":"לפי חלונית וסביבה","footer_compact":"קומפקטי","paths_git_root":"שורש Git","paths_absolute":"נתיבים מלאים"},"toast":{"changed_title":"Settings changed","save_failed_title":"ההגדרות לא נשמרו","save_failed_message":"לא ניתן לשמור את ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"חיפוש","placeholder":"סינון קבצים…","empty":"אין התאמות","preview_label":"תצוגה מקדימה","preview_loading":"טוען תצוגה מקדימה…","preview_binary":"קובץ בינארי — אין תצוגה מקדימה","preview_unavailable":"תצוגה מקדימה אינה זמינה","preview_truncated":"תצוגה מקדימה מקוצרת"}}; +export const he: TranslationSchema = {"footer":{"mode":{"browse":"עיון","insert":"הוספה","normal":"רגיל","preview":"תצוגה","settings":"הגדרות","files":"קבצים","graft":"Graft","history":"היסטוריה"},"context":{"settings":"הגדרות","graft_empty":"פתח קובץ לבדיקה","history_empty":"עדיין אין ראיות Echo","history_count":"ראיות Echo: {count}"},"command":{"invalid":"Command not recognized; type :help for help","hints":{"tab_accept":"tab accept","enter_run":"enter run","esc_cancel":"esc cancel"},"details":{"edit":"Open a file","write":"Write the current file","quit":"Quit jedit","wq":"Write and quit","ttd":"Observe a causal tick without moving canonical head","strand":"Create, switch, or list copy-on-write strands","braid":"View, preview, or admit braid candidates","why":"Explain the last meaningful command","help":"Show command help"}},"hints":{"j_k_move":"j/k הזז","enter_change":"enter שנה","f2_close":"f2 סגור","esc_close":"esc סגור","j_k_scroll":"j/k גלול","f3_source":"f3 מקור","f3_preview":"f3 תצוגה","text_input":"קלט טקסט","esc_normal":"esc רגיל","ctrl_s_save":"ctrl+s שמור","ctrl_t_theme":"ctrl+t ערכת נושא","tab_focus":"tab מיקוד","tab_indent":"tab הזחה","ctrl_b_files":"ctrl+b קבצים","ctrl_g_graft":"ctrl+g graft","ctrl_h_history":"ctrl+h היסטוריה","enter_open":"enter פתיחה / הרחבה","backspace_up":"backspace למעלה","ctrl_b_close":"ctrl+b סגור","enter_jump":"enter קפוץ","r_refresh":"r רענן","ctrl_g_close":"ctrl+g סגור","ctrl_h_close":"ctrl+h סגור","i_insert":"i הוסף","o_open_line":"o פתח שורה","cc_line":"cc שורה","cw_word":"cw מילה","ce_word_end":"ce סוף מילה","c0_start":"c0 התחלה","c_end":"c$ סוף","dd_line":"dd שורה","dw_word":"dw מילה","de_word_end":"de סוף מילה","d0_start":"d0 התחלה","d_end":"d$ סוף","yy_line":"yy שורה","yw_word":"yw מילה","ye_word_end":"ye סוף מילה","y0_start":"y0 התחלה","y_end":"y$ סוף","gg_top":"gg למעלה","esc_cancel":"esc בטל","type_filter":"הקלדת סינון","arrows_select":"↑/↓ בחירה","slash_filter":"/ סינון"},"evidence":{"head":"ראש","tick":"טיק","anchor":"עוגן","coverage":"כיסוי","complete":"מלא","partial":"חלקי","unavailable":"לא זמין"},"status":{"nav":"ניווט","filter":"סינון","read_only":"לקריאה בלבד","modified":"שונה","modified_count":"{count} שונו","pending_count":"{count} בהמתנה","buffer_count":"{count} מאגרים","loading":"בטעינה"}},"history":{"title":"היסטוריית Echo","empty":"עדיין אין ראיות Echo","header":"# tick סוג מצב ראיה סיכום"},"startupFileModal":{"title":"Open file","current_directory":"Current directory","empty":"No files in this directory"},"settings":{"sections":{"appearance":"Appearance","editor":"Editor","runtime":"Runtime"},"rows":{"theme":{"label":"Theme","description":"Switch between installed data-driven themes."},"theme_mode":{"label":"Light/dark","description":"Switch the current theme to its light or dark companion."},"footer":{"label":"Footer","description":"Show mode, focus, and command hints at the bottom edge."},"markdown_preview":{"label":"Markdown preview","description":"Switch the active Markdown buffer between source and preview."},"diagnostics":{"label":"Diagnostics","description":"Inspect Graft, parser, and Colorful runtime wiring."},"line_numbers":{"label":"Line numbers","description":"Switch between absolute and cursor-relative editor line numbers."},"gutter_dimmed":{"label":"Dim gutter","description":"Use the theme dimmed gutter token set."},"causal_gutter_basis":{"label":"Causal markers","description":"Choose the causal basis used by gutter change markers."},"footer_layout":{"label":"פריסת שורת מצב","description":"{layout} · ~/.jimrc"},"filepaths":{"label":"נתיבי קבצים","description":"{style} · ~/.jimrc"}},"values":{"on":"On","off":"Off","theme_mode_dark":"Dark","theme_mode_light":"Light","line_numbers_absolute":"Absolute","line_numbers_relative":"Relative","source":"Source","preview":"Preview","current":"Current","open":"Open","causal_gutter_last_save":"Last save","causal_gutter_import":"Import","causal_gutter_selected_checkpoint":"Selected checkpoint","causal_gutter_selected_tick":"Selected tick","footer_focused":"מיקוד וסביבת עבודה","footer_per_pane":"לפי חלונית וסביבה","footer_compact":"קומפקטי","paths_git_root":"שורש Git","paths_absolute":"נתיבים מלאים"},"toast":{"changed_title":"Settings changed","save_failed_title":"ההגדרות לא נשמרו","save_failed_message":"לא ניתן לשמור את ~/.jimrc."}},"worldline":{"title":"Worldlines","empty":"No worldlines yet","header":"kind name basis head delta conflict"},"why":{"range_obstructed_title":"Why range obstructed"},"fileExplorer":{"search_label":"חיפוש","placeholder":"סינון קבצים…","empty":"אין התאמות","preview_label":"תצוגה מקדימה","preview_loading":"טוען תצוגה מקדימה…","preview_binary":"קובץ בינארי — אין תצוגה מקדימה","preview_unavailable":"תצוגה מקדימה אינה זמינה","preview_truncated":"תצוגה מקדימה מקוצרת"}}; -export const me: TranslationSchema = {"footer":{"mode":{"browse":"esworb","insert":"tresni","normal":"lamron","preview":"weiverp","settings":"sgnittes","files":"selif","graft":"tfarg","history":"yrotsih"},"context":{"settings":"sgnittes","graft_empty":"ti tcepsni ot elif a nepo","history_empty":"tey ecnedive ohcE on","history_count":"{count} :ecnedive ohcE"},"command":{"invalid":"pleh rof pleh: epyt ;dezingocer ton dnammoC","hints":{"tab_accept":"tpecca bat","enter_run":"nur retne","esc_cancel":"lecnac cse"},"details":{"edit":"elif a nepO","write":"elif tnerruc eht etirW","quit":"tidej tiuQ","wq":"tiuq dna etirW","ttd":"daeh lacinonac gnivom tuohtiw kcit lasuac a evresbO","strand":"sdnarts etirw-no-ypoc tsil ro ,hctiws ,etaerC","braid":"setadidnac diarb timda ro ,weiverp ,weiV","why":"dnammoc lufgninaem tsal eht nialpxE","help":"pleh dnammoc wohS"}},"hints":{"j_k_move":"evom k/j","enter_change":"egnahc retne","f2_close":"esolc 2f","esc_close":"esolc cse","j_k_scroll":"llorcs k/j","f3_source":"ecruos 3f","f3_preview":"weiverp 3f","text_input":"tupni txet","esc_normal":"lamron cse","ctrl_s_save":"evas s+lrtc","ctrl_t_theme":"emeht t+lrtc","tab_focus":"sucof bat","tab_indent":"tnedni bat","ctrl_b_files":"selif b+lrtc","ctrl_g_graft":"tfarg g+lrtc","ctrl_h_history":"yrotsih h+lrtc","enter_open":"nepo retne","backspace_up":"pu ecapskcab","ctrl_b_close":"esolc b+lrtc","enter_jump":"pmuj retne","r_refresh":"hserfer r","ctrl_g_close":"esolc g+lrtc","ctrl_h_close":"esolc h+lrtc","i_insert":"tresni i","o_open_line":"enil nepo o","cc_line":"enil cc","cw_word":"drow wc","ce_word_end":"dne-drow ec","c0_start":"trats 0c","c_end":"dne $c","dd_line":"enil dd","dw_word":"drow wd","de_word_end":"dne-drow ed","d0_start":"trats 0d","d_end":"dne $d","yy_line":"enil yy","yw_word":"drow wy","ye_word_end":"dne-drow ey","y0_start":"trats 0y","y_end":"dne $y","gg_top":"pot gg","esc_cancel":"lecnac cse","type_filter":"retlif epyt","arrows_select":"tceles ↓/↑","slash_filter":"retlif /"},"evidence":{"head":"daeh","tick":"kcit","anchor":"rohcna","coverage":"egarevoc","complete":"etelpmoc","partial":"laitrap","unavailable":"elbaliavanu"},"status":{"nav":"van","filter":"retlif","read_only":"ylno-daer","modified":"deifidom","modified_count":"deifidom {count}","pending_count":"gnidnep {count}","buffer_count":"sreffub {count}","loading":"gnidaol"}},"history":{"title":"yrotsiH ohcE","empty":"tey ecnedive ohcE oN","header":"yrammus ecnedive sutats dnik kcit #"},"startupFileModal":{"title":"elif nepO","current_directory":"yrotcerid tnerruC","empty":"yrotcerid siht ni selif oN"},"settings":{"sections":{"appearance":"ecnaraeppA","editor":"rotidE","runtime":"emitnuR"},"rows":{"theme":{"label":"emehT","description":".semeht nevird-atad dellatsni neewteb hctiwS"},"theme_mode":{"label":"krad/thgiL","description":".noinapmoc krad ro thgil sti ot emeht tnerruc eht hctiwS"},"footer":{"label":"retooF","description":".egde mottob eht ta stnih dnammoc dna ,sucof ,edom wohS"},"markdown_preview":{"label":"weiverp nwodkraM","description":".weiverp dna ecruos neewteb reffub nwodkraM evitca eht hctiwS"},"diagnostics":{"label":"scitsongaiD","description":".gniriw emitnur lufroloC dna ,resrap ,tfarG tcepsnI"},"line_numbers":{"label":"srebmun eniL","description":".srebmun enil rotide evitaler-rosruc dna etulosba neewteb hctiwS"},"gutter_dimmed":{"label":"rettug miD","description":".tes nekot rettug demmid emeht eht esU"},"causal_gutter_basis":{"label":"srekram lasuaC","description":".srekram egnahc rettug yb desu sisab lasuac eht esoohC"},"footer_layout":{"label":"tuoyal retooF","description":"crmij./~ · {layout}"},"filepaths":{"label":"shtapeliF","description":"crmij./~ · {style}"}},"values":{"on":"nO","off":"ffO","theme_mode_dark":"kraD","theme_mode_light":"thgiL","line_numbers_absolute":"etulosbA","line_numbers_relative":"evitaleR","source":"ecruoS","preview":"weiverP","current":"tnerruC","open":"nepO","causal_gutter_last_save":"evas tsaL","causal_gutter_import":"tropmI","causal_gutter_selected_checkpoint":"tniopkcehc detceleS","causal_gutter_selected_tick":"kcit detceleS","footer_focused":"ecapskrow + desucoF","footer_per_pane":"ecapskrow + enap-reP","footer_compact":"tcapmoC","paths_git_root":"toor tiG","paths_absolute":"deifilauq ylluF"},"toast":{"changed_title":"degnahc sgnitteS","save_failed_title":"devas ton sgnitteS","save_failed_message":".degnahcnu si gnittes ehT .snoissimrep dna NOSJ sti kcehC .crmij./~ evas ton dluoC"}},"worldline":{"title":"senildlroW","empty":"tey senildlrow oN","header":"tcilfnoc atled daeh sisab eman dnik"},"why":{"range_obstructed_title":"detcurtsbo egnar yhW"},"fileExplorer":{"search_label":"hcraeS","placeholder":"…selif retliF","empty":"sehctam oN","preview_label":"weiverP","preview_loading":"…weiverp gnidaoL","preview_binary":"elbaliavanu weiverp — elif yraniB","preview_unavailable":"elbaliavanu weiverP","preview_truncated":"detacnurt weiverP"}}; +export const me: TranslationSchema = {"footer":{"mode":{"browse":"esworb","insert":"tresni","normal":"lamron","preview":"weiverp","settings":"sgnittes","files":"selif","graft":"tfarg","history":"yrotsih"},"context":{"settings":"sgnittes","graft_empty":"ti tcepsni ot elif a nepo","history_empty":"tey ecnedive ohcE on","history_count":"{count} :ecnedive ohcE"},"command":{"invalid":"pleh rof pleh: epyt ;dezingocer ton dnammoC","hints":{"tab_accept":"tpecca bat","enter_run":"nur retne","esc_cancel":"lecnac cse"},"details":{"edit":"elif a nepO","write":"elif tnerruc eht etirW","quit":"tidej tiuQ","wq":"tiuq dna etirW","ttd":"daeh lacinonac gnivom tuohtiw kcit lasuac a evresbO","strand":"sdnarts etirw-no-ypoc tsil ro ,hctiws ,etaerC","braid":"setadidnac diarb timda ro ,weiverp ,weiV","why":"dnammoc lufgninaem tsal eht nialpxE","help":"pleh dnammoc wohS"}},"hints":{"j_k_move":"evom k/j","enter_change":"egnahc retne","f2_close":"esolc 2f","esc_close":"esolc cse","j_k_scroll":"llorcs k/j","f3_source":"ecruos 3f","f3_preview":"weiverp 3f","text_input":"tupni txet","esc_normal":"lamron cse","ctrl_s_save":"evas s+lrtc","ctrl_t_theme":"emeht t+lrtc","tab_focus":"sucof bat","tab_indent":"tnedni bat","ctrl_b_files":"selif b+lrtc","ctrl_g_graft":"tfarg g+lrtc","ctrl_h_history":"yrotsih h+lrtc","enter_open":"elggot / nepo retne","backspace_up":"pu ecapskcab","ctrl_b_close":"esolc b+lrtc","enter_jump":"pmuj retne","r_refresh":"hserfer r","ctrl_g_close":"esolc g+lrtc","ctrl_h_close":"esolc h+lrtc","i_insert":"tresni i","o_open_line":"enil nepo o","cc_line":"enil cc","cw_word":"drow wc","ce_word_end":"dne-drow ec","c0_start":"trats 0c","c_end":"dne $c","dd_line":"enil dd","dw_word":"drow wd","de_word_end":"dne-drow ed","d0_start":"trats 0d","d_end":"dne $d","yy_line":"enil yy","yw_word":"drow wy","ye_word_end":"dne-drow ey","y0_start":"trats 0y","y_end":"dne $y","gg_top":"pot gg","esc_cancel":"lecnac cse","type_filter":"retlif epyt","arrows_select":"tceles ↓/↑","slash_filter":"retlif /"},"evidence":{"head":"daeh","tick":"kcit","anchor":"rohcna","coverage":"egarevoc","complete":"etelpmoc","partial":"laitrap","unavailable":"elbaliavanu"},"status":{"nav":"van","filter":"retlif","read_only":"ylno-daer","modified":"deifidom","modified_count":"deifidom {count}","pending_count":"gnidnep {count}","buffer_count":"sreffub {count}","loading":"gnidaol"}},"history":{"title":"yrotsiH ohcE","empty":"tey ecnedive ohcE oN","header":"yrammus ecnedive sutats dnik kcit #"},"startupFileModal":{"title":"elif nepO","current_directory":"yrotcerid tnerruC","empty":"yrotcerid siht ni selif oN"},"settings":{"sections":{"appearance":"ecnaraeppA","editor":"rotidE","runtime":"emitnuR"},"rows":{"theme":{"label":"emehT","description":".semeht nevird-atad dellatsni neewteb hctiwS"},"theme_mode":{"label":"krad/thgiL","description":".noinapmoc krad ro thgil sti ot emeht tnerruc eht hctiwS"},"footer":{"label":"retooF","description":".egde mottob eht ta stnih dnammoc dna ,sucof ,edom wohS"},"markdown_preview":{"label":"weiverp nwodkraM","description":".weiverp dna ecruos neewteb reffub nwodkraM evitca eht hctiwS"},"diagnostics":{"label":"scitsongaiD","description":".gniriw emitnur lufroloC dna ,resrap ,tfarG tcepsnI"},"line_numbers":{"label":"srebmun eniL","description":".srebmun enil rotide evitaler-rosruc dna etulosba neewteb hctiwS"},"gutter_dimmed":{"label":"rettug miD","description":".tes nekot rettug demmid emeht eht esU"},"causal_gutter_basis":{"label":"srekram lasuaC","description":".srekram egnahc rettug yb desu sisab lasuac eht esoohC"},"footer_layout":{"label":"tuoyal retooF","description":"crmij./~ · {layout}"},"filepaths":{"label":"shtapeliF","description":"crmij./~ · {style}"}},"values":{"on":"nO","off":"ffO","theme_mode_dark":"kraD","theme_mode_light":"thgiL","line_numbers_absolute":"etulosbA","line_numbers_relative":"evitaleR","source":"ecruoS","preview":"weiverP","current":"tnerruC","open":"nepO","causal_gutter_last_save":"evas tsaL","causal_gutter_import":"tropmI","causal_gutter_selected_checkpoint":"tniopkcehc detceleS","causal_gutter_selected_tick":"kcit detceleS","footer_focused":"ecapskrow + desucoF","footer_per_pane":"ecapskrow + enap-reP","footer_compact":"tcapmoC","paths_git_root":"toor tiG","paths_absolute":"deifilauq ylluF"},"toast":{"changed_title":"degnahc sgnitteS","save_failed_title":"devas ton sgnitteS","save_failed_message":".degnahcnu si gnittes ehT .snoissimrep dna NOSJ sti kcehC .crmij./~ evas ton dluoC"}},"worldline":{"title":"senildlroW","empty":"tey senildlrow oN","header":"tcilfnoc atled daeh sisab eman dnik"},"why":{"range_obstructed_title":"detcurtsbo egnar yhW"},"fileExplorer":{"search_label":"hcraeS","placeholder":"…selif retliF","empty":"sehctam oN","preview_label":"weiverP","preview_loading":"…weiverp gnidaoL","preview_binary":"elbaliavanu weiverp — elif yraniB","preview_unavailable":"elbaliavanu weiverP","preview_truncated":"detacnurt weiverP"}}; export const locales = ["en", "fr", "it", "de", "es", "ko", "ja", "zh-Hans", "pt-BR", "ru", "ar", "id", "tr", "hi", "nl", "pl", "vi", "th", "fa", "he", "me"] as const; diff --git a/src/ports/source-highlighter.ts b/src/ports/source-highlighter.ts index ab0b5b1d..5b6564dd 100644 --- a/src/ports/source-highlighter.ts +++ b/src/ports/source-highlighter.ts @@ -64,3 +64,9 @@ export interface SourceHighlightReading { export interface SourceHighlighter { highlight(input: SourceHighlightInput): Promise; } + +export type PreviewHighlightInput = Pick; + +export interface PreviewHighlighter { + highlightPreview(input: PreviewHighlightInput): Promise; +} diff --git a/src/ui/file-preview-syntax.ts b/src/ui/file-preview-syntax.ts new file mode 100644 index 00000000..2eb96b01 --- /dev/null +++ b/src/ui/file-preview-syntax.ts @@ -0,0 +1,45 @@ +import { segmentGraphemes, type Surface } from '@flyingrobots/bijou'; +import type { SourceHighlightReading } from '../ports/source-highlighter.js'; +import type { JeditTheme } from './jedit-theme.js'; +import { visibleLineLength } from './fit-line.js'; +import { sourceHighlightStyleAt } from './source-highlight.js'; + +export interface PreviewSyntaxPaintOptions { + readonly x: number; + readonly y: number; + readonly width: number; + readonly height: number; + readonly theme: JeditTheme; +} + +export function paintPreviewSyntax( + surface: Surface, + lines: readonly string[], + highlight: SourceHighlightReading | undefined, + options: PreviewSyntaxPaintOptions, +): void { + lines.slice(0, options.height).forEach((line, row) => paintSyntaxLine(surface, line, row, highlight, options)); +} + +function paintSyntaxLine( + surface: Surface, + line: string, + row: number, + highlight: SourceHighlightReading | undefined, + options: PreviewSyntaxPaintOptions, +): void { + let column = 0; + let sourceColumn = 0; + for (const grapheme of segmentGraphemes(line)) { + const width = visibleLineLength(grapheme); + const style = sourceHighlightStyleAt(highlight?.spans ?? [], row, sourceColumn, options.theme); + for (let cell = 0; cell < width && column + cell < options.width; cell += 1) { + const x = options.x + column + cell; + const y = options.y + row; + surface.set(x, y, { ...surface.get(x, y), ...style }); + } + sourceColumn += grapheme.length; + column += width; + if (column >= options.width) break; + } +} diff --git a/src/ui/file-search-results.ts b/src/ui/file-search-results.ts index 8a31a073..ffd747e2 100644 --- a/src/ui/file-search-results.ts +++ b/src/ui/file-search-results.ts @@ -1,3 +1,4 @@ +import { fileTreeNameColumn } from './workspace-render.js'; import type { Surface } from '@flyingrobots/bijou'; import type { FileSearchEntry } from '../app/workspace/file-search.js'; import { filledSelectionToken } from './filled-selection-token.js'; @@ -5,16 +6,15 @@ import type { JeditTheme } from './jedit-theme.js'; import { JEDIT_TEXT_MODIFIER } from './jedit-theme.js'; import { visibleLineLength } from './fit-line.js'; -const ENTRY_PREFIX_WIDTH = 2; const CHARACTER_STEP = 1; export function highlightFileSearchMatches(surface: Surface, entries: readonly FileSearchEntry[], theme: JeditTheme, selection: FileSearchSelection): void { - entries.forEach(({ entry, matchIndexes, index: sourceIndex }, row) => { + entries.forEach(({ entry, matchIndexes, index: sourceIndex, depth }, row) => { const selected = sourceIndex === selection.selectedIndex; paintFileSearchRow(surface, row, theme, { selected, hovered: sourceIndex === selection.hoveredIndex }); const characters = Array.from(entry.name); for (const index of matchIndexes) { - const column = ENTRY_PREFIX_WIDTH + visibleLineLength(characters.slice(0, index).join('')); + const column = fileTreeNameColumn(entry, depth) + visibleLineLength(characters.slice(0, index).join('')); const width = visibleLineLength(characters[index] ?? ''); for (let x = column; x < Math.min(surface.width, column + width); x += CHARACTER_STEP) { const cell = surface.get(x, row); diff --git a/src/ui/source-highlight.ts b/src/ui/source-highlight.ts index c710ee09..836e92ec 100644 --- a/src/ui/source-highlight.ts +++ b/src/ui/source-highlight.ts @@ -40,7 +40,7 @@ export function paintHighlightedSourceWindow( for (let col = ZERO_INDEX; col < safeWidth; col += 1) { const sourceCol = safeScrollCol + col; const char = sourceText[sourceCol] ?? SPACE_CHAR; - const style = styleAt( + const style = sourceHighlightStyleAt( highlight?.spans ?? [], sourceRow, sourceCol, @@ -55,7 +55,7 @@ export function paintHighlightedSourceWindow( } } -function styleAt( +export function sourceHighlightStyleAt( spans: readonly SourceHighlightSpan[], row: number, column: number, diff --git a/src/ui/workspace-render.ts b/src/ui/workspace-render.ts index 8aaccc75..86ec5350 100644 --- a/src/ui/workspace-render.ts +++ b/src/ui/workspace-render.ts @@ -30,15 +30,25 @@ export function formatGraftOutlineLine(item: GraftOutlineDisplayItem, options: S return `${prefix}${item.kind} ${item.name} · ${String(item.startLine)}`; } -export function formatTreeLine(entry: FileEntry, options: SelectableLineOptions): string { +export interface TreeLineOptions extends SelectableLineOptions { + readonly depth?: number; + readonly expanded?: boolean; +} + +export function fileTreeNameColumn(entry: FileEntry, depth = 0): number { + return 2 + depth * 2 + (entry.kind === FileEntryKinds.Directory ? 2 : 0); +} + +export function formatTreeLine(entry: FileEntry, options: TreeLineOptions): string { const prefix = options.selected ? '› ' : ' '; if (entry.kind === FileEntryKinds.Parent) { return `${prefix}../`; } if (entry.kind === FileEntryKinds.Directory) { - return `${prefix}${entry.name}/`; + const disclosure = options.expanded ? '▾' : '▸'; + return `${prefix}${' '.repeat(options.depth ?? 0)}${disclosure} ${entry.name}/`; } - return `${prefix}${entry.name}`; + return `${prefix}${' '.repeat(options.depth ?? 0)}${entry.name}`; } export function graftOutlineScroll(selectedIndex: number, total: number, visible: number): number { diff --git a/translations.json b/translations.json index b99122bd..540327e5 100644 --- a/translations.json +++ b/translations.json @@ -57,7 +57,7 @@ "ctrl_b_files": "ctrl+b files", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h history", - "enter_open": "enter open", + "enter_open": "enter open / toggle", "backspace_up": "backspace up", "ctrl_b_close": "ctrl+b close", "enter_jump": "enter jump", @@ -269,7 +269,7 @@ "ctrl_b_files": "ctrl+b fichiers", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h historique", - "enter_open": "enter ouvrir", + "enter_open": "entrée ouvrir / déplier", "backspace_up": "backspace haut", "ctrl_b_close": "ctrl+b fermer", "enter_jump": "enter aller", @@ -481,7 +481,7 @@ "ctrl_b_files": "ctrl+b file", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h cronologia", - "enter_open": "enter apri", + "enter_open": "invio apri / espandi", "backspace_up": "backspace su", "ctrl_b_close": "ctrl+b chiudi", "enter_jump": "enter vai", @@ -693,7 +693,7 @@ "ctrl_b_files": "ctrl+b dateien", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h verlauf", - "enter_open": "enter öffnen", + "enter_open": "eingabe öffnen / aufklappen", "backspace_up": "backspace hoch", "ctrl_b_close": "ctrl+b schließen", "enter_jump": "enter springen", @@ -905,7 +905,7 @@ "ctrl_b_files": "ctrl+b archivos", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h historial", - "enter_open": "enter abrir", + "enter_open": "intro abrir / desplegar", "backspace_up": "backspace arriba", "ctrl_b_close": "ctrl+b cerrar", "enter_jump": "enter saltar", @@ -1117,7 +1117,7 @@ "ctrl_b_files": "ctrl+b 파일", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h 기록", - "enter_open": "enter 열기", + "enter_open": "enter 열기 / 펼치기", "backspace_up": "backspace 위로", "ctrl_b_close": "ctrl+b 닫기", "enter_jump": "enter 이동", @@ -1329,7 +1329,7 @@ "ctrl_b_files": "ctrl+b ファイル", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h 履歴", - "enter_open": "enter 開く", + "enter_open": "enter 開く / 展開", "backspace_up": "backspace 上へ", "ctrl_b_close": "ctrl+b 閉じる", "enter_jump": "enter 移動", @@ -1541,7 +1541,7 @@ "ctrl_b_files": "ctrl+b 文件", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h 历史", - "enter_open": "enter 打开", + "enter_open": "enter 打开 / 展开", "backspace_up": "backspace 上一级", "ctrl_b_close": "ctrl+b 关闭", "enter_jump": "enter 跳转", @@ -1753,7 +1753,7 @@ "ctrl_b_files": "ctrl+b arquivos", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h histórico", - "enter_open": "enter abrir", + "enter_open": "enter abrir / expandir", "backspace_up": "backspace subir", "ctrl_b_close": "ctrl+b fechar", "enter_jump": "enter ir", @@ -1965,7 +1965,7 @@ "ctrl_b_files": "ctrl+b файлы", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h история", - "enter_open": "enter открыть", + "enter_open": "enter открыть / развернуть", "backspace_up": "backspace вверх", "ctrl_b_close": "ctrl+b закрыть", "enter_jump": "enter перейти", @@ -2177,7 +2177,7 @@ "ctrl_b_files": "ctrl+b ملفات", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h سجل", - "enter_open": "enter فتح", + "enter_open": "enter فتح / توسيع", "backspace_up": "backspace أعلى", "ctrl_b_close": "ctrl+b إغلاق", "enter_jump": "enter انتقال", @@ -2389,7 +2389,7 @@ "ctrl_b_files": "ctrl+b berkas", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h riwayat", - "enter_open": "enter buka", + "enter_open": "enter buka / luaskan", "backspace_up": "backspace naik", "ctrl_b_close": "ctrl+b tutup", "enter_jump": "enter lompat", @@ -2601,7 +2601,7 @@ "ctrl_b_files": "ctrl+b dosyalar", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h geçmiş", - "enter_open": "enter aç", + "enter_open": "enter aç / genişlet", "backspace_up": "backspace yukarı", "ctrl_b_close": "ctrl+b kapat", "enter_jump": "enter git", @@ -2813,7 +2813,7 @@ "ctrl_b_files": "ctrl+b फाइलें", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h इतिहास", - "enter_open": "enter खोलें", + "enter_open": "enter खोलें / फैलाएँ", "backspace_up": "backspace ऊपर", "ctrl_b_close": "ctrl+b बंद", "enter_jump": "enter जाएं", @@ -3025,7 +3025,7 @@ "ctrl_b_files": "ctrl+b bestanden", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h geschiedenis", - "enter_open": "enter openen", + "enter_open": "enter openen / uitklappen", "backspace_up": "backspace omhoog", "ctrl_b_close": "ctrl+b sluiten", "enter_jump": "enter springen", @@ -3237,7 +3237,7 @@ "ctrl_b_files": "ctrl+b pliki", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h historia", - "enter_open": "enter otwórz", + "enter_open": "enter otwórz / rozwiń", "backspace_up": "backspace w górę", "ctrl_b_close": "ctrl+b zamknij", "enter_jump": "enter skocz", @@ -3449,7 +3449,7 @@ "ctrl_b_files": "ctrl+b tệp", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h lịch sử", - "enter_open": "enter mở", + "enter_open": "enter mở / mở rộng", "backspace_up": "backspace lên", "ctrl_b_close": "ctrl+b đóng", "enter_jump": "enter nhảy", @@ -3661,7 +3661,7 @@ "ctrl_b_files": "ctrl+b ไฟล์", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h ประวัติ", - "enter_open": "enter เปิด", + "enter_open": "enter เปิด / ขยาย", "backspace_up": "backspace ขึ้น", "ctrl_b_close": "ctrl+b ปิด", "enter_jump": "enter ไป", @@ -3873,7 +3873,7 @@ "ctrl_b_files": "ctrl+b فایل‌ها", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h تاریخچه", - "enter_open": "enter باز کردن", + "enter_open": "enter باز کردن / گسترش", "backspace_up": "backspace بالا", "ctrl_b_close": "ctrl+b بستن", "enter_jump": "enter پرش", @@ -4085,7 +4085,7 @@ "ctrl_b_files": "ctrl+b קבצים", "ctrl_g_graft": "ctrl+g graft", "ctrl_h_history": "ctrl+h היסטוריה", - "enter_open": "enter פתח", + "enter_open": "enter פתיחה / הרחבה", "backspace_up": "backspace למעלה", "ctrl_b_close": "ctrl+b סגור", "enter_jump": "enter קפוץ",