diff --git a/.editorconfig b/.editorconfig index c965ea8c07..ff05c2e04e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,6 +1,6 @@ root = true -[*.{js,ts}] +[*.{js,cjs,ts,tsx,css}] charset = utf-8 end_of_line = lf indent_size = 4 diff --git a/.env b/.env deleted file mode 100644 index ff859e6225..0000000000 --- a/.env +++ /dev/null @@ -1 +0,0 @@ -NODE_OPTIONS=--max_old_space_size=4096 \ No newline at end of file diff --git a/.envrc b/.envrc new file mode 100644 index 0000000000..6deccfe3a5 --- /dev/null +++ b/.envrc @@ -0,0 +1,3 @@ +if has nix; then + use flake +fi diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml index 93772d7d92..58fa9743a5 100644 --- a/.github/actions/build-electron/action.yml +++ b/.github/actions/build-electron/action.yml @@ -21,7 +21,7 @@ runs: # Certificate setup - name: Import Apple certificates if: inputs.os == 'macos' - uses: apple-actions/import-codesign-certs@v5 + uses: apple-actions/import-codesign-certs@v6 with: p12-file-base64: ${{ env.APPLE_APP_CERTIFICATE_BASE64 }} p12-password: ${{ env.APPLE_APP_CERTIFICATE_PASSWORD }} @@ -30,7 +30,7 @@ runs: - name: Install Installer certificate if: inputs.os == 'macos' - uses: apple-actions/import-codesign-certs@v5 + uses: apple-actions/import-codesign-certs@v6 with: p12-file-base64: ${{ env.APPLE_INSTALLER_CERTIFICATE_BASE64 }} p12-password: ${{ env.APPLE_INSTALLER_CERTIFICATE_PASSWORD }} @@ -74,7 +74,7 @@ runs: - name: Update build info shell: ${{ inputs.shell }} - run: npm run chore:update-build-info + run: pnpm run chore:update-build-info # Critical debugging configuration - name: Run electron-forge build with enhanced logging @@ -85,8 +85,10 @@ runs: APPLE_ID: ${{ env.APPLE_ID }} APPLE_ID_PASSWORD: ${{ env.APPLE_ID_PASSWORD }} WINDOWS_SIGN_EXECUTABLE: ${{ env.WINDOWS_SIGN_EXECUTABLE }} + WINDOWS_SIGN_ERROR_LOG: ${{ env.WINDOWS_SIGN_ERROR_LOG }} TRILIUM_ARTIFACT_NAME_HINT: TriliumNotes-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }} - run: pnpm nx --project=desktop electron-forge:make -- --arch=${{ inputs.arch }} --platform=${{ inputs.forge_platform }} + TARGET_ARCH: ${{ inputs.arch }} + run: pnpm run --filter desktop electron-forge:make --arch=${{ inputs.arch }} --platform=${{ inputs.forge_platform }} # Add DMG signing step - name: Sign DMG @@ -162,3 +164,25 @@ runs: echo "Found ZIP: $zip_file" echo "Note: ZIP files are not code signed, but their contents should be" fi + + - name: Sign the RPM + if: inputs.os == 'linux' + shell: ${{ inputs.shell }} + run: | + echo -n "$GPG_SIGNING_KEY" | base64 --decode | gpg --import + + # Import the key into RPM for verification + gpg --export -a > pubkey + rpm --import pubkey + rm pubkey + + # Sign the RPM + rpm_file=$(find ./apps/desktop/upload -name "*.rpm" -print -quit) + rpmsign --define "_gpg_name Trilium Notes Signing Key " --addsign "$rpm_file" + rpm -Kv "$rpm_file" + + # Validate code signing + if ! rpm -K "$rpm_file" | grep -q "digests signatures OK"; then + echo .rpm file not signed + exit 1 + fi diff --git a/.github/actions/build-server/action.yml b/.github/actions/build-server/action.yml index b0ab05212c..8dbaafa5c3 100644 --- a/.github/actions/build-server/action.yml +++ b/.github/actions/build-server/action.yml @@ -8,11 +8,11 @@ inputs: runs: using: composite steps: - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v5 - name: Set up node & dependencies - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 24 cache: "pnpm" - name: Install dependencies shell: bash @@ -23,7 +23,7 @@ runs: shell: bash run: | pnpm run chore:update-build-info - pnpm nx --project=server package + pnpm run --filter server package - name: Prepare artifacts shell: bash run: | diff --git a/.github/actions/deploy-to-cloudflare-pages/action.yml b/.github/actions/deploy-to-cloudflare-pages/action.yml new file mode 100644 index 0000000000..4f7a4a177a --- /dev/null +++ b/.github/actions/deploy-to-cloudflare-pages/action.yml @@ -0,0 +1,103 @@ +name: "Deploy to Cloudflare Pages" +description: "Deploys to Cloudflare Pages on either a temporary branch with preview comment, or on the production version if on the main branch." +inputs: + project_name: + description: "CloudFlare Pages project name" + comment_body: + description: "The message to display when deployment is ready" + default: "Deployment is ready." + required: false + production_url: + description: "The URL to mention as the production URL." + required: true + deploy_dir: + description: "The directory from which to deploy." + required: true + cloudflare_api_token: + description: "The Cloudflare API token to use for deployment." + required: true + cloudflare_account_id: + description: "The Cloudflare account ID to use for deployment." + required: true + github_token: + description: "The GitHub token to use for posting PR comments." + required: true +runs: + using: composite + steps: + # Install wrangler globally to avoid workspace issues + - name: Install Wrangler + shell: bash + run: npm install -g wrangler + + # Deploy using Wrangler (use pre-installed wrangler) + - name: Deploy to Cloudflare Pages + id: deploy + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ inputs.cloudflare_api_token }} + accountId: ${{ inputs.cloudflare_account_id }} + command: pages deploy ${{ inputs.deploy_dir }} --project-name=${{ inputs.project_name}} --branch=${{ github.ref_name }} + wranglerVersion: '' # Use pre-installed version + + # Deploy preview for PRs + - name: Deploy Preview to Cloudflare Pages + id: preview-deployment + if: github.event_name == 'pull_request' + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ inputs.cloudflare_api_token }} + accountId: ${{ inputs.cloudflare_account_id }} + command: pages deploy ${{ inputs.deploy_dir }} --project-name=${{ inputs.project_name}} --branch=pr-${{ github.event.pull_request.number }} + wranglerVersion: '' # Use pre-installed version + + # Post deployment URL as PR comment + - name: Comment PR with Preview URL + if: github.event_name == 'pull_request' + uses: actions/github-script@v8 + env: + COMMENT_BODY: ${{ inputs.comment_body }} + PRODUCTION_URL: ${{ inputs.production_url }} + PROJECT_NAME: ${{ inputs.project_name }} + with: + github-token: ${{ inputs.github_token }} + script: | + const prNumber = context.issue.number; + // Construct preview URL based on Cloudflare Pages pattern + const projectName = process.env.PROJECT_NAME; + const previewUrl = `https://pr-${prNumber}.${projectName}.pages.dev`; + + // Check if we already commented + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber + }); + + const customMessage = process.env.COMMENT_BODY; + const botComment = comments.data.find(comment => + comment.user.type === 'Bot' && + comment.body.includes(customMessage) + ); + + const mainUrl = process.env.PRODUCTION_URL; + const commentBody = `${customMessage}!\n\nšŸ”— Preview URL: ${previewUrl}\nšŸ“– Production URL: ${mainUrl}\n\nāœ… All checks passed\n\n_This preview will be updated automatically with new commits._`; + + if (botComment) { + // Update existing comment + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body: commentBody + }); + } else { + // Create new comment + await github.rest.issues.createComment({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + } diff --git a/.github/actions/report-size/action.yml b/.github/actions/report-size/action.yml index e6bc477ca4..372a6b9ec3 100644 --- a/.github/actions/report-size/action.yml +++ b/.github/actions/report-size/action.yml @@ -44,7 +44,7 @@ runs: steps: # Checkout branch to compare to [required] - name: Checkout base branch - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ inputs.branch }} path: br-base @@ -69,7 +69,7 @@ runs: # Post github action comment - name: Post comment - uses: marocchino/sticky-pull-request-comment@v2 + uses: marocchino/sticky-pull-request-comment@v3 if: ${{ steps.bundleSize.outputs.hasDifferences == 'true' }} # post only in case of changes with: number: ${{ github.event.pull_request.number }} diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000000..b4dfb29f7f --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,334 @@ +# Trilium Notes - AI Coding Agent Instructions + +## Project Overview + +Trilium Notes is a hierarchical note-taking application with advanced features like synchronization, scripting, and rich text editing. Built as a TypeScript monorepo using pnpm, it implements a three-layer caching architecture (Becca/Froca/Shaca) with a widget-based UI system and supports extensive user scripting capabilities. + +## Essential Architecture Patterns + +### Three-Layer Cache System (Critical to Understand) +- **Becca** (`apps/server/src/becca/`): Server-side entity cache, primary data source +- **Froca** (`apps/client/src/services/froca.ts`): Client-side mirror synchronized via WebSocket +- **Shaca** (`apps/server/src/share/`): Optimized cache for public/shared notes + +**Key insight**: Never bypass these caches with direct DB queries. Always use `becca.notes[noteId]`, `froca.getNote()`, or equivalent cache methods. + +### Entity Relationship Model +Notes use a **multi-parent tree** via branches: +- `BNote` - The note content and metadata +- `BBranch` - Tree relationships (one note can have multiple parents via cloning) +- `BAttribute` - Key-value metadata attached to notes (labels and relations) + +### Entity Change System & Sync +Every entity modification (notes, branches, attributes) creates an `EntityChange` record that drives synchronization: + +```typescript +// Entity changes are automatically tracked +note.title = "New Title"; +note.save(); // Creates EntityChange record with changeId + +// Sync protocol via WebSocket +ws.sendMessage({ type: 'sync-pull-in-progress', ... }); +``` + +**Critical**: This is why you must use Becca/Froca methods instead of direct DB writes - they create the change tracking records needed for sync. + +### Entity Lifecycle & Events +The event system (`apps/server/src/services/events.ts`) broadcasts entity lifecycle events: + +```typescript +// Subscribe to events in widgets or services +eventService.subscribe('noteChanged', ({ noteId }) => { + // React to note changes +}); + +// Common events: noteChanged, branchChanged, attributeChanged, noteDeleted +// Widget method: entitiesReloadedEvent({loadResults}) for handling reloads +``` + +**Becca loader priorities**: Events are emitted in order (notes → branches → attributes) during initial load to ensure referential integrity. + +### TaskContext for Long Operations +Use `TaskContext` for operations with progress reporting (imports, exports, bulk operations): + +```typescript +const taskContext = new TaskContext("task-id", "import", "Import Notes"); +taskContext.increaseProgressCount(); + +// WebSocket messages: { type: 'taskProgressCount', taskId, taskType, data, progressCount } + +**Pattern**: All long-running operations (delete note trees, export, import) use TaskContext to send WebSocket updates to the frontend. + +### Protected Session Handling +Protected notes require an active encryption session: + +```typescript +// Always check before accessing protected content +if (note.isContentAvailable()) { + const content = note.getContent(); // Safe +} else { + const title = note.getTitleOrProtected(); // Returns "[protected]" +} + +// Protected session management +protectedSessionService.isProtectedSessionAvailable() // Check session +protectedSessionService.startProtectedSession() // After password entry +``` + +**Session timeout**: Protected sessions expire after inactivity. The encryption key is kept in memory only. + +### Attribute Inheritance Patterns +Attributes can be inherited through three mechanisms: + +```typescript +// 1. Standard inheritance (#hidePromotedAttributes ~hidePromotedAttributes) +note.getInheritableAttributes() // Walks up parent tree + +// 2. Child prefix inheritance (child:label copies to children) +parentNote.setLabel("child:icon", "book") // All children inherit this + +// 3. Template relation inheritance (#template=templateNoteId) +note.setRelation("template", templateNoteId) +note.getInheritedAttributes() // Includes template's inheritable attributes +``` + +**Cycle prevention**: Inheritance tracking prevents infinite loops when notes reference each other. + +### Widget-Based UI Architecture +All UI components extend from widget base classes (`apps/client/src/widgets/`): + +```typescript +// Right panel widget (sidebar) +class MyWidget extends RightPanelWidget { + get position() { return 100; } // Order in panel + get parentWidget() { return 'right-pane'; } + isEnabled() { return this.note && this.note.hasLabel('myLabel'); } + async refreshWithNote(note) { /* Update UI */ } +} + +// Note-aware widget (responds to note changes) +class MyNoteWidget extends NoteContextAwareWidget { + async refreshWithNote(note) { /* Refresh when note changes */ } + async entitiesReloadedEvent({loadResults}) { /* Handle entity updates */ } +} +``` + +**Important**: Widgets use jQuery (`this.$widget`) for DOM manipulation. Don't mix React patterns here. + +## Development Workflow + +### Running & Testing +```bash +# From root directory +pnpm install # Install dependencies +corepack enable # Enable pnpm if not available +pnpm server:start # Dev server (http://localhost:8080) +pnpm server:start-prod # Production mode server +pnpm desktop:start # Desktop app development +pnpm server:test spec/etapi/search.spec.ts # Run specific test +pnpm test:parallel # Client tests (can run parallel) +pnpm test:sequential # Server tests (sequential due to shared DB) +pnpm test:all # All tests (parallel + sequential) +pnpm coverage # Generate coverage reports +pnpm typecheck # Type check all projects +``` + +### Building +```bash +pnpm client:build # Build client application +pnpm server:build # Build server application +pnpm desktop:build # Build desktop application +``` + +### Test Organization +- **Server tests** (`apps/server/spec/`): Must run sequentially (shared database state) +- **Client tests** (`apps/client/src/`): Can run in parallel +- **E2E tests** (`apps/server-e2e/`): Use Playwright for integration testing +- **ETAPI tests** (`apps/server/spec/etapi/`): External API contract tests + +**Pattern**: When adding new API endpoints, add tests in `spec/etapi/` following existing patterns (see `search.spec.ts`). + +### Monorepo Navigation +``` +apps/ + client/ # Frontend (shared by server & desktop) + server/ # Node.js backend with REST API + desktop/ # Electron wrapper + web-clipper/ # Browser extension for saving web content + db-compare/ # Database comparison tool + dump-db/ # Database export utility + edit-docs/ # Documentation editing tools +packages/ + commons/ # Shared types and utilities + ckeditor5/ # Custom rich text editor with Trilium-specific plugins + codemirror/ # Code editor integration + highlightjs/ # Syntax highlighting + share-theme/ # Theme for shared/published notes + ckeditor5-admonition/ # Admonition blocks plugin + ckeditor5-footnotes/ # Footnotes plugin + ckeditor5-math/ # Math equations plugin + ckeditor5-mermaid/ # Mermaid diagrams plugin +``` + +**Filter commands**: Use `pnpm --filter server test` to run commands in specific packages. + +## Critical Code Patterns + +### ETAPI Backwards Compatibility +When adding query parameters to ETAPI endpoints (`apps/server/src/etapi/`), maintain backwards compatibility by checking if new params exist before changing response format. + +**Pattern**: ETAPI consumers expect specific response shapes. Always check for breaking changes. + +### Frontend-Backend Communication +- **REST API**: `apps/server/src/routes/api/` - Internal endpoints (no auth required when `noAuthentication=true`) +- **ETAPI**: `apps/server/src/etapi/` - External API with authentication +- **WebSocket**: Real-time sync via `apps/server/src/services/ws.ts` + +**Auth note**: ETAPI uses basic auth with tokens. Internal API endpoints trust the frontend. + +### Database Migrations +- Add scripts in `apps/server/src/migrations/YYMMDD_HHMM__description.sql` +- Update schema in `apps/server/src/assets/db/schema.sql` +- Never bypass Becca cache after migrations + +## Common Pitfalls + +1. **Never bypass the cache layers** - Always use `becca.notes[noteId]`, `froca.getNote()`, or equivalent cache methods. Direct database queries will cause sync issues between Becca/Froca/Shaca and won't create EntityChange records needed for synchronization. + +2. **Protected notes require session check** - Before accessing `note.title` or `note.getContent()` on protected notes, check `note.isContentAvailable()` or use `note.getTitleOrProtected()` which handles this automatically. + +3. **Widget lifecycle matters** - Override `refreshWithNote()` for note changes, `doRenderBody()` for initial render, `entitiesReloadedEvent()` for entity updates. Widgets use jQuery (`this.$widget`) - don't mix React patterns. + +4. **Tests run differently** - Server tests must run sequentially (shared database state), client tests can run in parallel. Use `pnpm test:sequential` for backend, `pnpm test:parallel` for frontend. + +5. **ETAPI requires authentication** - ETAPI endpoints use basic auth with tokens. Internal API endpoints (`apps/server/src/routes/api/`) trust the frontend when `noAuthentication=true`. + +6. **Search expressions are evaluated in memory** - The search service loads all matching notes, scores them in JavaScript, then sorts. You cannot add SQL-level LIMIT/OFFSET without losing scoring functionality. + +7. **Documentation edits have rules** - `docs/Script API/` is auto-generated (never edit directly). `docs/User Guide/` should be edited via `pnpm edit-docs:edit-docs`, not manually. Only `docs/Developer Guide/` and `docs/Release Notes/` are safe for direct Markdown editing. + +8. **pnpm workspace filtering** - Use `pnpm --filter server ` or shorthand `pnpm server:test` defined in root `package.json`. Note the `--filter` syntax, not `-F` or other shortcuts. + +9. **Event subscription cleanup** - When subscribing to events in widgets, unsubscribe in `cleanup()` or `doDestroy()` to prevent memory leaks. + +10. **Attribute inheritance can be complex** - When checking for labels/relations, use `note.getOwnedAttribute()` for direct attributes or `note.getAttribute()` for inherited ones. Don't assume attributes are directly on the note. + +## TypeScript Configuration + +- **Project references**: Monorepo uses TypeScript project references (`tsconfig.json`) +- **Path mapping**: Use relative imports, not path aliases +- **Build order**: `pnpm typecheck` builds all projects in dependency order +- **Build system**: Uses Vite for fast development, ESBuild for production optimization +- **Patches**: Custom patches in `patches/` directory for CKEditor and other dependencies + +## Key Files for Context + +- `apps/server/src/becca/entities/bnote.ts` - Note entity methods +- `apps/client/src/services/froca.ts` - Frontend cache API +- `apps/server/src/services/search/services/search.ts` - Search implementation +- `apps/server/src/routes/routes.ts` - API route registration +- `apps/client/src/widgets/basic_widget.ts` - Widget base class +- `apps/server/src/main.ts` - Server startup entry point +- `apps/client/src/desktop.ts` - Client initialization +- `apps/server/src/services/backend_script_api.ts` - Scripting API +- `apps/server/src/assets/db/schema.sql` - Database schema + +## Note Types and Features + +Trilium supports multiple note types with specialized widgets in `apps/client/src/widgets/type_widgets/`: +- **Text**: Rich text with CKEditor5 (markdown import/export) +- **Code**: Syntax-highlighted code editing with CodeMirror +- **File**: Binary file attachments +- **Image**: Image display with editing capabilities +- **Canvas**: Drawing/diagramming with Excalidraw +- **Mermaid**: Diagram generation +- **Relation Map**: Visual note relationship mapping +- **Web View**: Embedded web pages +- **Doc/Book**: Hierarchical documentation structure + +### Collections +Notes can be marked with the `#collection` label to enable collection view modes. Collections support multiple view types: +- **List**: Standard list view +- **Grid**: Card/grid layout +- **Calendar**: Calendar-based view +- **Table**: Tabular data view +- **GeoMap**: Geographic map view +- **Board**: Kanban-style board +- **Presentation**: Slideshow presentation mode + +View types are configured via `#viewType` label (e.g., `#viewType=table`). Each view mode stores its configuration in a separate attachment (e.g., `table.json`). Collections are organized separately from regular note type templates in the note creation menu. + +## Common Development Tasks + +### Adding New Note Types +1. Create widget in `apps/client/src/widgets/type_widgets/` +2. Register in `apps/client/src/services/note_types.ts` +3. Add backend handling in `apps/server/src/services/notes.ts` + +### Extending Search +- Search expressions handled in `apps/server/src/services/search/` +- Add new search operators in search context files +- Remember: scoring happens in-memory, not at database level + +### Custom CKEditor Plugins +- Create new package in `packages/` following existing plugin structure +- Register in `packages/ckeditor5/src/plugins.ts` +- See `ckeditor5-admonition`, `ckeditor5-footnotes`, `ckeditor5-math`, `ckeditor5-mermaid` for examples + +### Database Migrations +- Add migration scripts in `apps/server/src/migrations/YYMMDD_HHMM__description.sql` +- Update schema in `apps/server/src/assets/db/schema.sql` +- Never bypass Becca cache after migrations + +## Security & Features + +### Security Considerations +- Per-note encryption with granular protected sessions +- CSRF protection for API endpoints +- OpenID and TOTP authentication support +- Sanitization of user-generated content + +### Scripting System +Trilium provides powerful user scripting capabilities: +- **Frontend scripts**: Run in browser context with UI access +- **Backend scripts**: Run in Node.js context with full API access +- Script API documentation in `docs/Script API/` +- Backend API available via `api` object in script context + +### Internationalization +- Translation files in `apps/client/src/translations/` +- Use translation system via `t()` function +- Automatic pluralization: Add `_other` suffix to translation keys (e.g., `item` and `item_other` for singular/plural) + +## Testing Conventions + +```typescript +// ETAPI test pattern +describe("etapi/feature", () => { + beforeAll(async () => { + config.General.noAuthentication = false; + app = await buildApp(); + token = await login(app); + }); + + it("should test feature", async () => { + const response = await supertest(app) + .get("/etapi/notes?search=test") + .auth(USER, token, { type: "basic" }) + .expect(200); + + expect(response.body.results).toBeDefined(); + }); +}); +``` + +## Questions to Verify Understanding + +Before implementing significant changes, confirm: +- Is this touching the cache layer? (Becca/Froca/Shaca must stay in sync via EntityChange records) +- Does this change API response shape? (Check backwards compatibility for ETAPI) +- Are you adding search features? (Understand expression-based architecture and in-memory scoring first) +- Is this a new widget? (Know which base class and lifecycle methods to use) +- Does this involve protected notes? (Check `isContentAvailable()` before accessing content) +- Is this a long-running operation? (Use TaskContext for progress reporting) +- Are you working with attributes? (Understand inheritance patterns: direct, child-prefix, template) diff --git a/.github/instructions/nx.instructions.md b/.github/instructions/nx.instructions.md deleted file mode 100644 index c6d01270fd..0000000000 --- a/.github/instructions/nx.instructions.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -applyTo: '**' ---- - -// This file is automatically generated by Nx Console - -You are in an nx workspace using Nx 21.3.7 and pnpm as the package manager. - -You have access to the Nx MCP server and the tools it provides. Use them. Follow these guidelines in order to best help the user: - -# General Guidelines -- When answering questions, use the nx_workspace tool first to gain an understanding of the workspace architecture -- For questions around nx configuration, best practices or if you're unsure, use the nx_docs tool to get relevant, up-to-date docs!! Always use this instead of assuming things about nx configuration -- If the user needs help with an Nx configuration or project graph error, use the 'nx_workspace' tool to get any errors -- To help answer questions about the workspace structure or simply help with demonstrating how tasks depend on each other, use the 'nx_visualize_graph' tool - -# Generation Guidelines -If the user wants to generate something, use the following flow: - -- learn about the nx workspace and any specifics the user needs by using the 'nx_workspace' tool and the 'nx_project_details' tool if applicable -- get the available generators using the 'nx_generators' tool -- decide which generator to use. If no generators seem relevant, check the 'nx_available_plugins' tool to see if the user could install a plugin to help them -- get generator details using the 'nx_generator_schema' tool -- you may use the 'nx_docs' tool to learn more about a specific generator or technology if you're unsure -- decide which options to provide in order to best complete the user's request. Don't make any assumptions and keep the options minimalistic -- open the generator UI using the 'nx_open_generate_ui' tool -- wait for the user to finish the generator -- read the generator log file using the 'nx_read_generator_log' tool -- use the information provided in the log file to answer the user's question or continue with what they were doing - -# Running Tasks Guidelines -If the user wants help with tasks or commands (which include keywords like "test", "build", "lint", or other similar actions), use the following flow: -- Use the 'nx_current_running_tasks_details' tool to get the list of tasks (this can include tasks that were completed, stopped or failed). -- If there are any tasks, ask the user if they would like help with a specific task then use the 'nx_current_running_task_output' tool to get the terminal output for that task/command -- Use the terminal output from 'nx_current_running_task_output' to see what's wrong and help the user fix their problem. Use the appropriate tools if necessary -- If the user would like to rerun the task or command, always use `nx run ` to rerun in the terminal. This will ensure that the task will run in the nx context and will be run the same way it originally executed -- If the task was marked as "continuous" do not offer to rerun the task. This task is already running and the user can see the output in the terminal. You can use 'nx_current_running_task_output' to get the output of the task to verify the output. - - - diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 90751b906e..5597f58b39 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -12,6 +12,7 @@ jobs: steps: - name: Check if PRs have conflicts uses: eps1lon/actions-label-merge-conflict@v3 + if: ${{ github.repository == vars.REPO_MAIN }} with: dirtyLabel: "merge-conflicts" repoToken: "${{ secrets.MERGE_CONFLICT_LABEL_PAT }}" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3a241d807a..aff87f3494 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -57,7 +57,7 @@ jobs: # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 # Add any setup steps before running the `github/codeql-action/init` action. # This includes steps like installing compilers or runtimes (`actions/setup-node` @@ -67,7 +67,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -95,6 +95,6 @@ jobs: exit 1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000000..899060a2df --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,78 @@ +name: Deploy Documentation + +on: + # Trigger on push to main branch + push: + branches: + - main + - master # Also support master branch + # Only run when docs files change + paths: + - 'docs/**' + - 'apps/edit-docs/**' + - 'apps/build-docs/**' + - 'packages/share-theme/**' + + # Allow manual triggering from Actions tab + workflow_dispatch: + + # Run on pull requests for preview deployments + pull_request: + branches: + - main + - master + paths: + - 'docs/**' + - 'apps/edit-docs/**' + - 'apps/build-docs/**' + - 'packages/share-theme/**' + +jobs: + build-and-deploy: + name: Build and Deploy Documentation + runs-on: ubuntu-latest + timeout-minutes: 10 + + # Required permissions for deployment + permissions: + contents: read + deployments: write + pull-requests: write # For PR preview comments + id-token: write # For OIDC authentication (if needed) + + steps: + - name: Checkout Repository + uses: actions/checkout@v6 + + - name: Setup pnpm + uses: pnpm/action-setup@v5 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: '24' + cache: 'pnpm' + + - name: Install Dependencies + run: pnpm install --frozen-lockfile + + - name: Trigger build of documentation + run: pnpm docs:build + + - name: Validate Built Site + run: | + test -f site/index.html || (echo "ERROR: site/index.html not found" && exit 1) + test -f site/developer-guide/index.html || (echo "ERROR: site/developer-guide/index.html not found" && exit 1) + echo "āœ“ User Guide and Developer Guide built successfully" + + - name: Deploy + uses: ./.github/actions/deploy-to-cloudflare-pages + if: ${{ github.repository == vars.REPO_MAIN }} + with: + project_name: "trilium-docs" + comment_body: "šŸ“š Documentation preview is ready" + production_url: "https://docs.triliumnotes.org" + deploy_dir: "site" + cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index e9d3964c6f..38d170903a 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -19,63 +19,68 @@ permissions: pull-requests: write # for PR comments jobs: - check-affected: - name: Check affected jobs (NX) - runs-on: ubuntu-latest - steps: - - name: Checkout the repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # needed for https://github.com/marketplace/actions/nx-set-shas - - - uses: pnpm/action-setup@v4 - - name: Set up node & dependencies - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: 'pnpm' - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - uses: nrwl/nx-set-shas@v4 - - name: Check affected - run: pnpm nx affected --verbose -t typecheck build rebuild-deps test-build - test_dev: name: Test development runs-on: ubuntu-latest - needs: - - check-affected steps: - name: Checkout the repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v5 - name: Set up node & dependencies - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 24 cache: "pnpm" - run: pnpm install --frozen-lockfile - - name: Run the unit tests - run: pnpm run test:all + - name: Typecheck + run: pnpm typecheck + + - name: Run the client-side tests + run: pnpm run --filter=client test + + - name: Upload client test report + uses: actions/upload-artifact@v7 + if: always() + with: + name: client-test-report + path: apps/client/test-output/vitest/html/ + retention-days: 30 + + - name: Run the server-side tests + run: pnpm run --filter=server test + + - name: Upload server test report + uses: actions/upload-artifact@v7 + if: always() + with: + name: server-test-report + path: apps/server/test-output/vitest/html/ + retention-days: 30 + + - name: Run CKEditor e2e tests + run: | + pnpm run --filter=ckeditor5-mermaid test + pnpm run --filter=ckeditor5-math test + + - name: Run the rest of the tests + run: pnpm run --filter=\!client --filter=\!server --filter=\!ckeditor5-mermaid --filter=\!ckeditor5-math test build_docker: name: Build Docker image runs-on: ubuntu-latest needs: - test_dev - - check-affected steps: - - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v5 - name: Install dependencies run: pnpm install --frozen-lockfile - name: Update build info run: pnpm run chore:update-build-info - name: Trigger client build - run: pnpm nx run client:build + run: pnpm client:build - name: Send client bundle stats to RelativeCI if: false uses: relative-ci/agent-action@v3 @@ -83,9 +88,9 @@ jobs: webpackStatsFile: ./apps/client/dist/webpack-stats.json key: ${{ secrets.RELATIVE_CI_CLIENT_KEY }} - name: Trigger server build - run: pnpm nx run server:build - - uses: docker/setup-buildx-action@v3 - - uses: docker/build-push-action@v6 + run: pnpm run server:build + - uses: docker/setup-buildx-action@v4 + - uses: docker/build-push-action@v7 with: context: apps/server cache-from: type=gha @@ -95,7 +100,6 @@ jobs: runs-on: ubuntu-latest needs: - build_docker - - check-affected strategy: matrix: include: @@ -103,16 +107,16 @@ jobs: - dockerfile: Dockerfile steps: - name: Checkout the repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v5 - name: Install dependencies run: pnpm install --frozen-lockfile - name: Update build info run: pnpm run chore:update-build-info - name: Trigger build - run: pnpm nx run server:build + run: pnpm server:build - name: Set IMAGE_NAME to lowercase run: echo "IMAGE_NAME=${IMAGE_NAME,,}" >> $GITHUB_ENV @@ -120,10 +124,10 @@ jobs: run: echo "TEST_TAG=${TEST_TAG,,}" >> $GITHUB_ENV - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Build and export to Docker - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: apps/server file: apps/server/${{ matrix.dockerfile }} diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml new file mode 100644 index 0000000000..00bf2982e3 --- /dev/null +++ b/.github/workflows/i18n.yml @@ -0,0 +1,30 @@ +name: Internationalization +on: + push: + branches: + - "weblate:*" + workflow_dispatch: + pull_request: + paths: + - "apps/client/src/translations/**" + - ".github/workflows/i18n.yml" + +permissions: + contents: read + +jobs: + i18n-check: + name: Check i18n translations + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v5 + - name: Set up node & dependencies + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: 'pnpm' + - name: Install dependencies + run: pnpm install --frozen-lockfile + - name: Check translations + run: pnpm tsx scripts/translation/check-translation-coverage.ts diff --git a/.github/workflows/main-docker.yml b/.github/workflows/main-docker.yml index 40c5149c74..eecda5ec1a 100644 --- a/.github/workflows/main-docker.yml +++ b/.github/workflows/main-docker.yml @@ -32,7 +32,7 @@ jobs: - dockerfile: Dockerfile steps: - name: Checkout the repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set IMAGE_NAME to lowercase run: echo "IMAGE_NAME=${IMAGE_NAME,,}" >> $GITHUB_ENV @@ -40,13 +40,13 @@ jobs: run: echo "TEST_TAG=${TEST_TAG,,}" >> $GITHUB_ENV - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v5 - name: Set up node & dependencies - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 24 cache: "pnpm" - name: Install npm dependencies @@ -59,7 +59,7 @@ jobs: run: pnpm run server:build - name: Build and export to Docker - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: apps/server file: apps/server/${{ matrix.dockerfile }} @@ -82,16 +82,16 @@ jobs: require-healthy: true - name: Run Playwright tests - run: TRILIUM_DOCKER=1 TRILIUM_PORT=8082 pnpm exec nx run server-e2e:e2e + run: TRILIUM_DOCKER=1 TRILIUM_PORT=8082 pnpm --filter=server-e2e e2e - name: Upload Playwright trace if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: Playwright trace (${{ matrix.dockerfile }}) path: test-output/playwright/output - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: ${{ !cancelled() }} with: name: Playwright report (${{ matrix.dockerfile }}) @@ -116,10 +116,10 @@ jobs: - dockerfile: Dockerfile platform: linux/arm64 image: ubuntu-24.04-arm - - dockerfile: Dockerfile + - dockerfile: Dockerfile.legacy platform: linux/arm/v7 image: ubuntu-24.04-arm - - dockerfile: Dockerfile + - dockerfile: Dockerfile.legacy platform: linux/arm/v8 image: ubuntu-24.04-arm runs-on: ${{ matrix.image }} @@ -141,30 +141,32 @@ jobs: run: echo "TEST_TAG=${TEST_TAG,,}" >> $GITHUB_ENV - name: Checkout repository - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 + uses: actions/checkout@v6 + - uses: pnpm/action-setup@v5 - name: Set up node & dependencies - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 24 cache: 'pnpm' - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Run the TypeScript build - run: pnpm run server:build - - name: Update build info run: pnpm run chore:update-build-info + - name: Update nightly version + if: ${{ !startsWith(github.ref, 'refs/tags/v') }} + run: pnpm run chore:ci-update-nightly-version + + - name: Run the TypeScript build + run: pnpm run server:build + - name: Docker meta id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: - images: | - ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }} - ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }} + images: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=tag @@ -173,28 +175,21 @@ jobs: latest=false - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Login to GHCR - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ${{ env.GHCR_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - registry: ${{ env.DOCKERHUB_REGISTRY }} - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push by digest id: build - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: apps/server file: apps/server/${{ matrix.dockerfile }} @@ -209,9 +204,9 @@ jobs: touch "/tmp/digests/${digest#sha256:}" - name: Upload digest - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: - name: digests-${{ env.PLATFORM_PAIR }} + name: digests-${{ env.PLATFORM_PAIR }}-${{ matrix.dockerfile }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 @@ -223,7 +218,7 @@ jobs: - build steps: - name: Download digests - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: path: /tmp/digests pattern: digests-* @@ -233,75 +228,86 @@ jobs: - name: Set TEST_TAG to lowercase run: echo "TEST_TAG=${TEST_TAG,,}" >> $GITHUB_ENV - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: | - ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }} - ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }} - flavor: | - latest=false + - name: Set up crane + uses: imjasonh/setup-crane@v0.5 - name: Login to GHCR - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ${{ env.GHCR_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ${{ env.DOCKERHUB_REGISTRY }} username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Create manifest list and push + - name: Docker meta + id: meta + uses: docker/metadata-action@v6 + with: + images: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=tag + type=sha + flavor: | + latest=false + + - name: Verify digests exist on GHCR working-directory: /tmp/digests run: | - # Extract the branch or tag name from the ref - REF_NAME=$(echo "${GITHUB_REF}" | sed 's/refs\/heads\///' | sed 's/refs\/tags\///') + echo "Verifying all digests are available on GHCR..." + for DIGEST_FILE in *; do + DIGEST="sha256:${DIGEST_FILE}" + echo -n " ${DIGEST}: " + crane manifest "${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}@${DIGEST}" > /dev/null + echo "OK" + done - # Create and push the manifest list with both the branch/tag name and the commit SHA - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - -t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:${REF_NAME} \ - $(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) + - name: Create and push multi-arch manifest + working-directory: /tmp/digests + run: | + GHCR_IMAGE="${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}" + DOCKERHUB_IMAGE="${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}" - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - -t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${REF_NAME} \ - $(printf '${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) + # Build -m flags for crane index append from digest files + MANIFEST_ARGS="" + for d in *; do + MANIFEST_ARGS="${MANIFEST_ARGS} -m ${GHCR_IMAGE}@sha256:${d}" + done - # If the ref is a tag, also tag the image as stable as this is part of a 'release' - # and only go in the `if` if there is NOT a `-` in the tag's name, due to tagging of `-alpha`, `-beta`, etc... + # Create multi-arch manifest for each tag from metadata, plus copy to DockerHub + while IFS= read -r TAG; do + echo "Creating manifest: ${TAG}" + crane index append ${MANIFEST_ARGS} -t "${TAG}" + + SUFFIX="${TAG#*:}" + echo "Copying to DockerHub: ${DOCKERHUB_IMAGE}:${SUFFIX}" + crane copy "${TAG}" "${DOCKERHUB_IMAGE}:${SUFFIX}" + done <<< "${{ steps.meta.outputs.tags }}" + + # For stable releases (tags without hyphens), also create stable + latest + REF_NAME="${GITHUB_REF#refs/tags/}" if [[ "${GITHUB_REF}" == refs/tags/* && ! "${REF_NAME}" =~ - ]]; then - # First create stable tags - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - -t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:stable \ - $(printf '${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) - - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - -t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:stable \ - $(printf '${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) - - # Small delay to ensure stable tag is fully propagated - sleep 5 - - # Now update latest tags - docker buildx imagetools create \ - -t ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:latest \ - ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:stable - - docker buildx imagetools create \ - -t ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest \ - ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:stable + echo "Creating stable tags..." + crane index append ${MANIFEST_ARGS} -t "${GHCR_IMAGE}:stable" + crane copy "${GHCR_IMAGE}:stable" "${DOCKERHUB_IMAGE}:stable" + echo "Creating latest tags..." + crane copy "${GHCR_IMAGE}:stable" "${GHCR_IMAGE}:latest" + crane copy "${GHCR_IMAGE}:latest" "${DOCKERHUB_IMAGE}:latest" fi - - name: Inspect image + - name: Inspect manifests run: | - docker buildx imagetools inspect ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} - docker buildx imagetools inspect ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} + REF_NAME="${GITHUB_REF#refs/heads/}" + REF_NAME="${REF_NAME#refs/tags/}" + echo "=== GHCR ===" + crane manifest "${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}:${REF_NAME}" + echo "" + echo "=== DockerHub ===" + crane manifest "${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${REF_NAME}" diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 990c8dfb94..b3998e8365 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -19,7 +19,6 @@ concurrency: cancel-in-progress: true env: - GITHUB_UPLOAD_URL: https://uploads.github.com/repos/TriliumNext/Notes/releases/179589950/assets{?name,label} GITHUB_RELEASE_ID: 179589950 permissions: @@ -27,6 +26,7 @@ permissions: jobs: nightly-electron: + if: ${{ github.repository == vars.REPO_MAIN }} name: Deploy nightly strategy: fail-fast: false @@ -45,20 +45,32 @@ jobs: image: win-signing shell: cmd forge_platform: win32 + # Exclude ARM64 Linux from default matrix to use native runner + exclude: + - arch: arm64 + os: + name: linux + # Add ARM64 Linux with native ubuntu-24.04-arm runner for better-sqlite3 compatibility + include: + - arch: arm64 + os: + name: linux + image: ubuntu-24.04-arm + shell: bash + forge_platform: linux runs-on: ${{ matrix.os.image }} steps: - - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v5 - name: Set up node & dependencies - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 24 cache: 'pnpm' - name: Install dependencies run: pnpm install --frozen-lockfile - - uses: nrwl/nx-set-shas@v4 - name: Update nightly version - run: npm run chore:ci-update-nightly-version + run: pnpm run chore:ci-update-nightly-version - name: Run the build uses: ./.github/actions/build-electron with: @@ -75,9 +87,11 @@ jobs: APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} WINDOWS_SIGN_EXECUTABLE: ${{ vars.WINDOWS_SIGN_EXECUTABLE }} + WINDOWS_SIGN_ERROR_LOG: ${{ vars.WINDOWS_SIGN_ERROR_LOG }} + GPG_SIGNING_KEY: ${{ secrets.GPG_SIGN_KEY }} - name: Publish release - uses: softprops/action-gh-release@v2.3.2 + uses: softprops/action-gh-release@v2.6.1 if: ${{ github.event_name != 'pull_request' }} with: make_latest: false @@ -89,13 +103,14 @@ jobs: name: Nightly Build - name: Publish artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 if: ${{ github.event_name == 'pull_request' }} with: name: TriliumNotes ${{ matrix.os.name }} ${{ matrix.arch }} path: apps/desktop/upload nightly-server: + if: ${{ github.repository == vars.REPO_MAIN }} name: Deploy server nightly strategy: fail-fast: false @@ -108,7 +123,7 @@ jobs: runs-on: ubuntu-24.04-arm runs-on: ${{ matrix.runs-on }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Run the build uses: ./.github/actions/build-server @@ -117,7 +132,7 @@ jobs: arch: ${{ matrix.arch }} - name: Publish release - uses: softprops/action-gh-release@v2.3.2 + uses: softprops/action-gh-release@v2.6.1 if: ${{ github.event_name != 'pull_request' }} with: make_latest: false diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 247eb9618a..a51d29e652 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -4,6 +4,9 @@ on: push: branches: - main + - hotfix + paths-ignore: + - "apps/website/**" pull_request: permissions: @@ -11,32 +14,74 @@ permissions: contents: read jobs: - main: - runs-on: ubuntu-latest + e2e: + strategy: + fail-fast: false + matrix: + include: + - name: linux-x64 + os: ubuntu-22.04 + arch: x64 + - name: linux-arm64 + os: ubuntu-24.04-arm + arch: arm64 + runs-on: ${{ matrix.os }} + name: E2E tests on ${{ matrix.name }} + env: + TRILIUM_DOCKER: 1 + TRILIUM_PORT: 8082 + TRILIUM_DATA_DIR: "${{ github.workspace }}/apps/server/spec/db" + TRILIUM_INTEGRATION_TEST: memory steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: filter: tree:0 fetch-depth: 0 - # This enables task distribution via Nx Cloud - # Run this command as early as possible, before dependencies are installed - # Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun - # Connect your workspace by running "nx connect" and uncomment this line to enable task distribution - # - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="e2e-ci" - - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v5 + - uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 24 cache: 'pnpm' - name: Install dependencies run: pnpm install --frozen-lockfile - - run: pnpm exec playwright install --with-deps - - uses: nrwl/nx-set-shas@v4 - # Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud - # - run: npx nx-cloud record -- echo Hello World - # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected - # When you enable task distribution, run the e2e-ci task instead of e2e - - run: pnpm exec nx affected -t e2e --exclude desktop-e2e + + - name: Install Playwright browsers + run: pnpm exec playwright install --with-deps + + - name: Build the server + uses: ./.github/actions/build-server + with: + os: linux + arch: ${{ matrix.arch }} + + - name: Unpack and start the server + run: | + version=$(node --eval "console.log(require('./package.json').version)") + file=$(find ./upload -name '*.tar.xz' -print -quit) + name=$(basename "$file" .tar.xz) + mkdir -p ./server-dist + tar -xvf "$file" -C ./server-dist + server_dir="./server-dist/TriliumNotes-Server-$version-linux-${{ matrix.arch }}" + if [ ! -d "$server_dir" ]; then + echo Missing dir. + exit 1 + fi + cd "$server_dir" + "./trilium.sh" & + sleep 10 + + - name: Server end-to-end tests + run: pnpm --filter server-e2e e2e + + - name: Upload test report + if: failure() + uses: actions/upload-artifact@v7 + with: + name: e2e report ${{ matrix.arch }} + path: apps/server-e2e/test-output + + - name: Kill the server + if: always() + run: pkill -f trilium || true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b05cb4939a..2943a122ca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,8 +11,28 @@ concurrency: cancel-in-progress: true jobs: + sanity-check: + name: Sanity Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - uses: pnpm/action-setup@v5 + - name: Set up node & dependencies + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --filter source --frozen-lockfile --ignore-scripts + + - name: Check version consistency + run: pnpm tsx ${{ github.workspace }}/scripts/check-version-consistency.ts ${{ github.ref_name }} make-electron: name: Make Electron + needs: + - sanity-check strategy: fail-fast: false matrix: @@ -30,18 +50,30 @@ jobs: image: win-signing shell: cmd forge_platform: win32 + # Exclude ARM64 Linux from default matrix to use native runner + exclude: + - arch: arm64 + os: + name: linux + # Add ARM64 Linux with native ubuntu-24.04-arm runner for better-sqlite3 compatibility + include: + - arch: arm64 + os: + name: linux + image: ubuntu-24.04-arm + shell: bash + forge_platform: linux runs-on: ${{ matrix.os.image }} steps: - - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v5 - name: Set up node & dependencies - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 22 + node-version: 24 cache: 'pnpm' - name: Install dependencies run: pnpm install --frozen-lockfile - - uses: nrwl/nx-set-shas@v4 - name: Run the build uses: ./.github/actions/build-electron with: @@ -58,15 +90,19 @@ jobs: APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} WINDOWS_SIGN_EXECUTABLE: ${{ vars.WINDOWS_SIGN_EXECUTABLE }} + WINDOWS_SIGN_ERROR_LOG: ${{ vars.WINDOWS_SIGN_ERROR_LOG }} + GPG_SIGNING_KEY: ${{ secrets.GPG_SIGN_KEY }} - name: Upload the artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: release-desktop-${{ matrix.os.name }}-${{ matrix.arch }} path: apps/desktop/upload/*.* build_server: name: Build Linux Server + needs: + - sanity-check strategy: fail-fast: false matrix: @@ -78,7 +114,7 @@ jobs: runs-on: ubuntu-24.04-arm runs-on: ${{ matrix.runs-on }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Run the build uses: ./.github/actions/build-server @@ -87,7 +123,7 @@ jobs: arch: ${{ matrix.arch }} - name: Upload the artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: release-server-linux-${{ matrix.arch }} path: upload/*.* @@ -101,20 +137,20 @@ jobs: steps: - run: mkdir upload - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: sparse-checkout: | docs/Release Notes - name: Download all artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: merge-multiple: true pattern: release-* path: upload - name: Publish stable release - uses: softprops/action-gh-release@v2.3.2 + uses: softprops/action-gh-release@v2.6.1 with: draft: false body_path: docs/Release Notes/Release Notes/${{ github.ref_name }}.md diff --git a/.github/workflows/unblock_signing.yml b/.github/workflows/unblock_signing.yml new file mode 100644 index 0000000000..0860f89daa --- /dev/null +++ b/.github/workflows/unblock_signing.yml @@ -0,0 +1,11 @@ +name: Unblock signing +on: + workflow_dispatch: + +jobs: + unblock-win-signing: + runs-on: win-signing + steps: + - run: | + cat ${{ vars.WINDOWS_SIGN_ERROR_LOG }} + rm ${{ vars.WINDOWS_SIGN_ERROR_LOG }} diff --git a/.github/workflows/web-clipper.yml b/.github/workflows/web-clipper.yml new file mode 100644 index 0000000000..41d2f56839 --- /dev/null +++ b/.github/workflows/web-clipper.yml @@ -0,0 +1,69 @@ +name: Deploy web clipper extension + +on: + push: + branches: + - main + paths: + - "apps/web-clipper/**" + tags: + - "web-clipper-v*" + + pull_request: + paths: + - "apps/web-clipper/**" + +permissions: + contents: write + discussions: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + name: Build web clipper extension + + permissions: + contents: read + deployments: write + + steps: + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v5 + - name: Set up node & dependencies + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --filter web-clipper --frozen-lockfile --ignore-scripts + + - name: Build the web clipper extension + run: | + pnpm --filter web-clipper zip + pnpm --filter web-clipper zip:firefox + + - name: Upload build artifacts + uses: actions/upload-artifact@v7 + if: ${{ !startsWith(github.ref, 'refs/tags/web-clipper-v') }} + with: + name: web-clipper-extension + path: apps/web-clipper/.output/*.zip + include-hidden-files: true + if-no-files-found: error + compression-level: 0 + + - name: Release web clipper extension + uses: softprops/action-gh-release@v2.6.1 + if: ${{ startsWith(github.ref, 'refs/tags/web-clipper-v') }} + with: + draft: false + fail_on_unmatched_files: true + files: apps/web-clipper/.output/*.zip + discussion_category_name: Releases + make_latest: false + token: ${{ secrets.RELEASE_PAT }} diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml new file mode 100644 index 0000000000..e255837959 --- /dev/null +++ b/.github/workflows/website.yml @@ -0,0 +1,51 @@ +name: Deploy website + +on: + push: + branches: + - main + paths: + - "apps/website/**" + + pull_request: + paths: + - "apps/website/**" + + release: + types: [ released ] + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + name: Build & deploy website + + permissions: + contents: read + deployments: write + pull-requests: write # For PR preview comments + + steps: + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v5 + - name: Set up node & dependencies + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --filter website --frozen-lockfile --ignore-scripts + + - name: Build the website + run: pnpm website:build + + - name: Deploy + uses: ./.github/actions/deploy-to-cloudflare-pages + with: + project_name: "trilium-homepage" + comment_body: "šŸ“š Website preview is ready" + production_url: "https://triliumnotes.org" + deploy_dir: "apps/website/dist" + cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index d7694258d9..994679ebe5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ # See https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files for more about ignoring files. +/.cache # compiled output dist @@ -10,6 +11,7 @@ node_modules # IDEs and editors /.idea +.idea .project .classpath .c9/ @@ -31,19 +33,21 @@ testem.log .DS_Store Thumbs.db -.nx/cache -.nx/workspace-data - vite.config.*.timestamp* vitest.config.*.timestamp* test-output -apps/*/data +apps/*/data* apps/*/out upload .rollup.cache *.tsbuildinfo +/.direnv /result -.svelte-kit \ No newline at end of file + +# docs +site/ +apps/*/coverage +scripts/translation/.language*.json diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 2102c8715d..0000000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# Default ignored files -/workspace.xml - -# Datasource local storage ignored files -/dataSources.local.xml -/dataSources/ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index d499350272..0000000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123c2b..0000000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml deleted file mode 100644 index 88634a3244..0000000000 --- a/.idea/dataSources.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - sqlite.xerial - true - org.sqlite.JDBC - jdbc:sqlite:$PROJECT_DIR$/data/document.db - $ProjectFileDir$ - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 15a15b218a..0000000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/git_toolbox_prj.xml b/.idea/git_toolbox_prj.xml deleted file mode 100644 index 02b915b85f..0000000000 --- a/.idea/git_toolbox_prj.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 22cdf9bd9e..0000000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml deleted file mode 100644 index d23208fbb7..0000000000 --- a/.idea/jsLibraryMappings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/jsLinters/jslint.xml b/.idea/jsLinters/jslint.xml deleted file mode 100644 index 742a5fe034..0000000000 --- a/.idea/jsLinters/jslint.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 44ee38edea..0000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 09c4a5cbf8..0000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml deleted file mode 100644 index dd88c0a28a..0000000000 --- a/.idea/sqldialects.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index dcb6b8c4cc..0000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/.nvmrc b/.nvmrc index 818ab238a5..045200741c 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.17.1 \ No newline at end of file +24.14.1 \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e64c42352f..c3af7fffbc 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,12 +5,10 @@ "lokalise.i18n-ally", "ms-azuretools.vscode-docker", "ms-playwright.playwright", - "nrwl.angular-console", "redhat.vscode-yaml", "tobermory.es6-string-html", "vitest.explorer", "yzhang.markdown-all-in-one", - "svelte.svelte-vscode", - "bradlc.vscode-tailwindcss" + "usernamehw.errorlens" ] } diff --git a/.vscode/i18n-ally-custom-framework.yml b/.vscode/i18n-ally-custom-framework.yml index 32ec786aa5..eed692a431 100644 --- a/.vscode/i18n-ally-custom-framework.yml +++ b/.vscode/i18n-ally-custom-framework.yml @@ -3,6 +3,7 @@ languageIds: - javascript - typescript + - typescriptreact - html # An array of RegExes to find the key usage. **The key should be captured in the first match group**. @@ -13,6 +14,7 @@ usageMatchRegex: # the `{key}` will be placed by a proper keypath matching regex, # you can ignore it and use your own matching rules as well - "[^\\w\\d]t\\(['\"`]({key})['\"`]" + - ]*> # A RegEx to set a custom scope range. This scope will be used as a prefix when detecting keys # and works like how the i18next framework identifies the namespace scope from the @@ -25,9 +27,10 @@ scopeRangeRegex: "useTranslation\\(\\s*\\[?\\s*['\"`](.*?)['\"`]" # The "$1" will be replaced by the keypath specified. refactorTemplates: - t("$1") + - {t("$1")} - ${t("$1")} - <%= t("$1") %> # If set to true, only enables this custom framework (will disable all built-in frameworks) -monopoly: true \ No newline at end of file +monopoly: true diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..c58bd439d9 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,57 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch client (Chrome)", + "request": "launch", + "type": "chrome", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}/apps/client" + }, + { + "name": "Launch server", + "type": "node", + "request": "launch", + "program": "${workspaceFolder}/apps/server/src/main.ts", + "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/tsx", + "env": { + "NODE_ENV": "development", + "TRILIUM_ENV": "dev", + "TRILIUM_DATA_DIR": "${input:trilium_data_dir}", + "TRILIUM_RESOURCE_DIR": "${workspaceFolder}/apps/server/src" + }, + "autoAttachChildProcesses": true, + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "skipFiles": ["/**", "${workspaceFolder}/node_modules/**"] + }, + { + "name": "Launch Vitest with current test file", + "type": "node", + "request": "launch", + "autoAttachChildProcesses": true, + "program": "${workspaceFolder}/node_modules/vitest/vitest.mjs", + "args": ["run", "${relativeFile}"], + "smartStep": true, + "console": "integratedTerminal", + "skipFiles": ["/**", "**/node_modules/**"], + "cwd": "${workspaceFolder}" + } + ], + "compounds": [ + { + "name": "Launch client (Chrome) and server", + "configurations": ["Launch server","Launch client (Chrome)"], + "stopAll": true + } + ], + "inputs": [ + { + "id": "trilium_data_dir", + "type": "promptString", + "description": "Select Trilum Notes data directory", + "default": "${workspaceFolder}/apps/server/data" + } + ] +} diff --git a/.vscode/mcp.json b/.vscode/mcp.json deleted file mode 100644 index 28994bb29e..0000000000 --- a/.vscode/mcp.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "servers": { - "nx-mcp": { - "type": "http", - "url": "http://localhost:9461/mcp" - } - } -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 4ee21bb3ce..974a4ff64e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,7 +5,8 @@ "i18n-ally.keystyle": "nested", "i18n-ally.localesPaths": [ "apps/server/src/assets/translations", - "apps/client/src/translations" + "apps/client/src/translations", + "apps/website/public/translations" ], "npm.exclude": [ "**/dist", @@ -36,5 +37,13 @@ "apps/server/src/assets/doc_notes/**": true, "apps/edit-docs/demo/**": true }, - "nxConsole.generateAiAgentRules": true -} \ No newline at end of file + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "eslint.rules.customizations": [ + { "rule": "*", "severity": "warn" } + ], + "cSpell.words": [ + "Trilium" + ] +} diff --git a/.vscode/snippets.code-snippets b/.vscode/snippets.code-snippets index 77b251a4ad..c7255af76d 100644 --- a/.vscode/snippets.code-snippets +++ b/.vscode/snippets.code-snippets @@ -20,5 +20,10 @@ "scope": "typescript", "prefix": "jqf", "body": ["private $${1:name}!: JQuery;"] + }, + "region": { + "scope": "css", + "prefix": "region", + "body": ["/* #region ${1:name} */\n$0\n/* #endregion */"] } } diff --git a/CLAUDE.md b/CLAUDE.md index 942ad06e3f..a818b18929 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Overview -Trilium Notes is a hierarchical note-taking application with advanced features like synchronization, scripting, and rich text editing. It's built as a TypeScript monorepo using NX, with multiple applications and shared packages. +Trilium Notes is a hierarchical note-taking application with advanced features like synchronization, scripting, and rich text editing. It's built as a TypeScript monorepo using pnpm, with multiple applications and shared packages. ## Development Commands @@ -14,12 +14,9 @@ Trilium Notes is a hierarchical note-taking application with advanced features l ### Running Applications - `pnpm run server:start` - Start development server (http://localhost:8080) -- `pnpm nx run server:serve` - Alternative server start command -- `pnpm nx run desktop:serve` - Run desktop Electron app - `pnpm run server:start-prod` - Run server in production mode ### Building -- `pnpm nx build ` - Build specific project (server, client, desktop, etc.) - `pnpm run client:build` - Build client application - `pnpm run server:build` - Build server application - `pnpm run electron:build` - Build desktop application @@ -28,13 +25,8 @@ Trilium Notes is a hierarchical note-taking application with advanced features l - `pnpm test:all` - Run all tests (parallel + sequential) - `pnpm test:parallel` - Run tests that can run in parallel - `pnpm test:sequential` - Run tests that must run sequentially (server, ckeditor5-mermaid, ckeditor5-math) -- `pnpm nx test ` - Run tests for specific project - `pnpm coverage` - Generate coverage reports -### Linting & Type Checking -- `pnpm nx run :lint` - Lint specific project -- `pnpm nx run :typecheck` - Type check specific project - ## Architecture Overview ### Monorepo Structure @@ -94,7 +86,6 @@ Frontend uses a widget system (`apps/client/src/widgets/`): - `apps/server/src/assets/db/schema.sql` - Core database structure 4. **Configuration**: - - `nx.json` - NX workspace configuration - `package.json` - Project dependencies and scripts ## Note Types and Features @@ -127,6 +118,8 @@ Trilium provides powerful user scripting capabilities: ### Internationalization - Translation files in `apps/client/src/translations/` - Supported languages: English, German, Spanish, French, Romanian, Chinese +- **Only add new translation keys to `en/translation.json`** — translations for other languages are managed via Weblate and will be contributed by the community +- Third-party components (e.g., mind-map context menu) should use i18next `t()` for their labels, with the English strings added to `en/translation.json` under a dedicated namespace (e.g., `"mind-map"`) ### Security Considerations - Per-note encryption with granular protected sessions @@ -134,6 +127,15 @@ Trilium provides powerful user scripting capabilities: - OpenID and TOTP authentication support - Sanitization of user-generated content +### Client-Side API Restrictions +- **Do not use `crypto.randomUUID()`** or other Web Crypto APIs that require secure contexts - Trilium can run over HTTP, not just HTTPS +- Use `randomString()` from `apps/client/src/services/utils.ts` for generating IDs instead + +### Shared Types Policy +- Types shared between client and server belong in `@triliumnext/commons` (`packages/commons/src/lib/`) +- Import shared types directly from `@triliumnext/commons` - do not re-export them from app-specific modules +- Keep app-specific types (e.g., `LlmProvider` for server, `StreamCallbacks` for client) in their respective apps + ## Common Development Tasks ### Adding New Note Types @@ -153,8 +155,14 @@ Trilium provides powerful user scripting capabilities: - Add migration scripts in `apps/server/src/migrations/` - Update schema in `apps/server/src/assets/db/schema.sql` +### Server-Side Static Assets +- Static assets (templates, SQL, translations, etc.) go in `apps/server/src/assets/` +- Access them at runtime via `RESOURCE_DIR` from `apps/server/src/services/resource_dir.ts` (e.g. `path.join(RESOURCE_DIR, "llm", "skills", "file.md")`) +- **Do not use `import.meta.url`/`fileURLToPath`** to resolve file paths — the server is bundled into CJS for production, so `import.meta.url` will not point to the source directory +- **Do not use `__dirname` with relative paths** from source files — after bundling, `__dirname` points to the bundle output, not the original source tree + ## Build System Notes -- Uses NX for monorepo management with build caching +- Uses pnpm for monorepo management - Vite for fast development builds - ESBuild for production optimization - pnpm workspaces for dependency management diff --git a/README.md b/README.md index 540d5f226c..0fc8e562b3 100644 --- a/README.md +++ b/README.md @@ -1,74 +1,93 @@ +
+ Special thanks to:
+ + Warp sponsorship
+ Warp, built for coding with multiple AI agents
+
+ Available for macOS, Linux and Windows +
+ +
+ # Trilium Notes -Donate: ![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran?style=flat-square) ![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran?style=flat-square) +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) ![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran) +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total) +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) [![Translation status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) -![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/notes?style=flat-square) -![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/triliumnext/notes/total?style=flat-square) -[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop&style=flat-square)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) - -[English](./README.md) | [Chinese](./docs/README-ZH_CN.md) | [Russian](./docs/README.ru.md) | [Japanese](./docs/README.ja.md) | [Italian](./docs/README.it.md) | [Spanish](./docs/README.es.md) + + +[Chinese (Simplified Han script)](./docs/README-ZH_CN.md) | [Chinese (Traditional Han script)](./docs/README-ZH_TW.md) | [English](./docs/README.md) | [French](./docs/README-fr.md) | [German](./docs/README-de.md) | [Greek](./docs/README-el.md) | [Italian](./docs/README-it.md) | [Japanese](./docs/README-ja.md) | [Romanian](./docs/README-ro.md) | [Spanish](./docs/README-es.md) + Trilium Notes is a free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases. -See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for quick overview: +Trilium Screenshot -Trilium Screenshot +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – unstable development version, updated daily with the latest features and fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at [docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation directly in the application +- **GitHub**: Navigate through the [User Guide](./docs/User%20Guide/User%20Guide/) in this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) ## šŸŽ Features -* Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) -* Rich WYSIWYG note editor including e.g. tables, images and [math](https://triliumnext.github.io/Docs/Wiki/text-notes) with markdown [autoformat](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) -* Support for editing [notes with source code](https://triliumnext.github.io/Docs/Wiki/code-notes), including syntax highlighting -* Fast and easy [navigation between notes](https://triliumnext.github.io/Docs/Wiki/note-navigation), full text search and [note hoisting](https://triliumnext.github.io/Docs/Wiki/note-hoisting) -* Seamless [note versioning](https://triliumnext.github.io/Docs/Wiki/note-revisions) -* Note [attributes](https://triliumnext.github.io/Docs/Wiki/attributes) can be used for note organization, querying and advanced [scripting](https://triliumnext.github.io/Docs/Wiki/scripts) +* Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source code](https://docs.triliumnotes.org/user-guide/note-types/code), including syntax highlighting +* Fast and easy [navigation between notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), full text search and [note hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) can be used for note organization, querying and advanced [scripting](https://docs.triliumnotes.org/user-guide/scripts) * UI available in English, German, Spanish, French, Romanian, and Chinese (simplified and traditional) -* Direct [OpenID and TOTP integration](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/Multi-Factor%20Authentication.md) for more secure login -* [Synchronization](https://triliumnext.github.io/Docs/Wiki/synchronization) with self-hosted sync server - * there's a [3rd party service for hosting synchronisation server](https://trilium.cc/paid-hosting) -* [Sharing](https://triliumnext.github.io/Docs/Wiki/sharing) (publishing) notes to public internet -* Strong [note encryption](https://triliumnext.github.io/Docs/Wiki/protected-notes) with per-note granularity +* Direct [OpenID and TOTP integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) with self-hosted sync server + * there are [3rd party services for hosting synchronisation server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) (publishing) notes to public internet +* Strong [note encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) with per-note granularity * Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type "canvas") -* [Relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map) and [link maps](https://triliumnext.github.io/Docs/Wiki/link-map) for visualizing notes and their relations +* [Relation maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) for visualizing notes and their relations * Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) -* [Geo maps](./docs/User%20Guide/User%20Guide/Note%20Types/Geo%20Map.md) with location pins and GPX tracks -* [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - see [Advanced showcases](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) -* [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) for automation +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for automation * Scales well in both usability and performance upwards of 100 000 notes -* Touch optimized [mobile frontend](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) for smartphones and tablets -* Built-in [dark theme](https://triliumnext.github.io/Docs/Wiki/themes), support for user themes -* [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) and [Markdown import & export](https://triliumnext.github.io/Docs/Wiki/markdown) -* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) for easy saving of web content +* Touch optimized [mobile frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for smartphones and tablets +* Built-in [dark theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) and [Markdown import & export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for easy saving of web content * Customizable UI (sidebar buttons, user-defined widgets, ...) -* [Metrics](./docs/User%20Guide/User%20Guide/Advanced%20Usage/Metrics.md), along with a [Grafana Dashboard](./docs/User%20Guide/User%20Guide/Advanced%20Usage/Metrics/grafana-dashboard.json) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), along with a Grafana Dashboard. ✨ Check out the following third-party resources/communities for more TriliumNext related goodies: - [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party themes, scripts, plugins and more. - [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. -## āš ļø Why TriliumNext? +## ā“Why TriliumNext? -[The original Trilium project is in maintenance mode](https://github.com/zadam/trilium/issues/4620). +The original Trilium developer ([Zadam](https://github.com/zadam)) has graciously given the Trilium repository to the community project which resides at https://github.com/TriliumNext -### Migrating from Trilium? +### ā¬†ļøMigrating from Zadam/Trilium? -There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Notes instance. Simply [install TriliumNext/Notes](#-installation) as usual and it will use your existing database. +There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Trilium instance. Simply [install TriliumNext/Trilium](#-installation) as usual and it will use your existing database. -Versions up to and including [v0.90.4](https://github.com/TriliumNext/Notes/releases/tag/v0.90.4) are compatible with the latest zadam/trilium version of [v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later versions of TriliumNext have their sync versions incremented. - -## šŸ“– Documentation - -We're currently in the progress of moving the documentation to in-app (hit the `F1` key within Trilium). As a result, there may be some missing parts until we've completed the migration. If you'd prefer to navigate through the documentation within GitHub, you can navigate the [User Guide](./docs/User%20Guide/User%20Guide/) documentation. - -Below are some quick links for your convenience to navigate the documentation: -- [Server installation](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation.md) - - [Docker installation](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.md) -- [Upgrading TriliumNext](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Upgrading%20TriliumNext.md) -- [Concepts and Features - Note](./docs/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes.md) -- [Patterns of personal knowledge base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) - -Until we finish reorganizing the documentation, you may also want to [browse the old documentation](https://triliumnext.github.io/Docs). +Versions up to and including [v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are compatible with the latest zadam/trilium version of [v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later versions of TriliumNext/Trilium have their sync versions incremented which prevents direct migration. ## šŸ’¬ Discuss with us @@ -76,14 +95,14 @@ Feel free to join our official conversations. We would love to hear what feature - [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous discussions.) - The `General` Matrix room is also bridged to [XMPP](xmpp:discuss@trilium.thisgreat.party?join) -- [Github Discussions](https://github.com/TriliumNext/Notes/discussions) (For asynchronous discussions.) -- [Github Issues](https://github.com/TriliumNext/Notes/issues) (For bug reports and feature requests.) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug reports and feature requests.) ## šŸ— Installation ### Windows / MacOS -Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Notes/releases/latest), unzip the package and run the `trilium` executable. +Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package and run the `trilium` executable. ### Linux @@ -91,7 +110,7 @@ If your distribution is listed in the table below, use your distribution's packa [![Packaging status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) -You may also download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Notes/releases/latest), unzip the package and run the `trilium` executable. +You may also download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package and run the `trilium` executable. TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. @@ -105,17 +124,27 @@ Currently only the latest versions of Chrome & Firefox are supported (and tested To use TriliumNext on a mobile device, you can use a mobile web browser to access the mobile interface of a server installation (see below). -If you prefer a native Android app, you can use [TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). Report bugs and missing features at [their repository](https://github.com/FliegendeWurst/TriliumDroid). +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more information on mobile app support. -See issue https://github.com/TriliumNext/Notes/issues/72 for more information on mobile app support. +If you prefer a native Android app, you can use [TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their repository](https://github.com/FliegendeWurst/TriliumDroid). +Note: It is best to disable automatic updates on your server installation (see below) when using TriliumDroid since the sync version must match between Trilium and TriliumDroid. ### Server -To install TriliumNext on your own server (including via Docker from [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) follow [the server installation docs](https://triliumnext.github.io/Docs/Wiki/server-installation). +To install TriliumNext on your own server (including via Docker from [Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server installation docs](https://docs.triliumnotes.org/user-guide/setup/server). ## šŸ’» Contribute +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our [Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + ### Code Download the repository, install dependencies using `pnpm` and then run the server (available at http://localhost:8080): @@ -133,36 +162,65 @@ Download the repository, install dependencies using `pnpm` and then run the envi git clone https://github.com/TriliumNext/Trilium.git cd Trilium pnpm install -pnpm nx run edit-docs:edit-docs +pnpm edit-docs:edit-docs ``` +Alternatively, if you have Nix installed: +```shell +# Run directly +nix run .#edit-docs + +# Or install to your profile +nix profile install .#edit-docs +trilium-edit-docs +``` + + ### Building the Executable Download the repository, install dependencies using `pnpm` and then build the desktop app for Windows: ```shell git clone https://github.com/TriliumNext/Trilium.git cd Trilium pnpm install -pnpm nx --project=desktop electron-forge:make -- --arch=x64 --platform=win32 +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 ``` -For more details, see the [development docs](https://github.com/TriliumNext/Notes/blob/develop/docs/Developer%20Guide/Developer%20Guide/Building%20and%20deployment/Running%20a%20development%20build.md). +For more details, see the [development docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). ### Developer Documentation -Please view the [documentation guide](./docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) for details. If you have more questions, feel free to reach out via the links described in the "Discuss with us" section above. +Please view the [documentation guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) for details. If you have more questions, feel free to reach out via the links described in the "Discuss with us" section above. ## šŸ‘ Shoutouts -* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - best WYSIWYG editor on the market, very interactive and listening team -* [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. Trilium Notes would not be the same without it. -* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages -* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map) +* [zadam](https://github.com/zadam) for the original concept and implementation of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. Used in [relation maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and [link maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) ## šŸ¤ Support -Support for the TriliumNext organization will be possible in the near future. For now, you can: -- Support continued development on TriliumNext by supporting our developers: [eliandoran](https://github.com/sponsors/eliandoran) (See the [repository insights]([developers]([url](https://github.com/TriliumNext/Notes/graphs/contributors))) for a full list) -- Show a token of gratitude to the original Trilium developer ([zadam](https://github.com/sponsors/zadam)) via [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). +Trilium is built and maintained with [hundreds of hours of work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your support keeps it open-source, improves features, and covers costs such as hosting. + +Consider supporting the main developer ([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) ## šŸ”‘ License diff --git a/SECURITY.md b/SECURITY.md index 0c7e17bd6e..20c58fca16 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -10,4 +10,5 @@ Description above is a general rule and may be altered on case by case basis. ## Reporting a Vulnerability -You can report low severity vulnerabilities as GitHub issues, more severe vulnerabilities should be reported to the email [contact@eliandoran.me](mailto:contact@eliandoran.me) +* For low severity vulnerabilities, they can be reported as GitHub issues. +* For severe vulnerabilities, please report it using [GitHub Security Advisories](https://github.com/TriliumNext/Trilium/security/advisories). diff --git a/_regroup/bin/create-anonymization-script.ts b/_regroup/bin/create-anonymization-script.ts deleted file mode 100644 index ff462ec5e2..0000000000 --- a/_regroup/bin/create-anonymization-script.ts +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node - -import anonymizationService from "../src/services/anonymization.js"; -import fs from "fs"; -import path from "path"; - -fs.writeFileSync(path.resolve(__dirname, "tpl", "anonymize-database.sql"), anonymizationService.getFullAnonymizationScript()); diff --git a/_regroup/bin/create-icons.sh b/_regroup/bin/create-icons.sh deleted file mode 100644 index 16ace4c2c3..0000000000 --- a/_regroup/bin/create-icons.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash - -if ! command -v magick &> /dev/null; then - echo "This tool requires ImageMagick to be installed in order to create the icons." - exit 1 -fi - -if ! command -v inkscape &> /dev/null; then - echo "This tool requires Inkscape to be render sharper SVGs than ImageMagick." - exit 1 -fi - -if ! command -v icnsutil &> /dev/null; then - echo "This tool requires icnsutil to be installed in order to generate macOS icons." - exit 1 -fi - -script_dir=$(realpath $(dirname $0)) -cd "${script_dir}/../images/app-icons" -inkscape -w 180 -h 180 "../icon-color.svg" -o "./ios/apple-touch-icon.png" - -# Build PNGs -inkscape -w 128 -h 128 "../icon-color.svg" -o "./png/128x128.png" -inkscape -w 256 -h 256 "../icon-color.svg" -o "./png/256x256.png" - -# Build dev icons (including tray) -inkscape -w 16 -h 16 "../icon-purple.svg" -o "./png/16x16-dev.png" -inkscape -w 32 -h 32 "../icon-purple.svg" -o "./png/32x32-dev.png" -inkscape -w 256 -h 256 "../icon-purple.svg" -o "./png/256x256-dev.png" - -# Build Mac .icns -declare -a sizes=("16" "32" "512" "1024") -for size in "${sizes[@]}"; do - inkscape -w $size -h $size "../icon-color.svg" -o "./png/${size}x${size}.png" -done - -mkdir -p fakeapp.app -npx iconsur set fakeapp.app -l -i "png/1024x1024.png" -o "mac/1024x1024.png" -s 0.8 -declare -a sizes=("16x16" "32x32" "128x128" "512x512") -for size in "${sizes[@]}"; do - magick "mac/1024x1024.png" -resize "${size}" "mac/${size}.png" -done -icnsutil compose -f "mac/icon.icns" ./mac/*.png - -# Build Windows icon -magick -background none "../icon-color.svg" -define icon:auto-resize=16,32,48,64,128,256 "./icon.ico" - -# Build Windows setup icon -magick -background none "../icon-installer.svg" -define icon:auto-resize=16,32,48,64,128,256 "./win/setup.ico" - -# Build Squirrel splash image -magick "./png/256x256.png" -background "#ffffff" -gravity center -extent 640x480 "./win/setup-banner.gif" \ No newline at end of file diff --git a/_regroup/bin/export-schema.sh b/_regroup/bin/export-schema.sh deleted file mode 100644 index ab5de1a815..0000000000 --- a/_regroup/bin/export-schema.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -SCHEMA_FILE_PATH=db/schema.sql - -sqlite3 ./data/document.db .schema | grep -v "sqlite_sequence" > "$SCHEMA_FILE_PATH" - -echo "DB schema exported to $SCHEMA_FILE_PATH" \ No newline at end of file diff --git a/_regroup/bin/push-docker-image.sh b/_regroup/bin/push-docker-image.sh deleted file mode 100644 index 0372143cf1..0000000000 --- a/_regroup/bin/push-docker-image.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -if [[ $# -eq 0 ]] ; then - echo "Missing argument of new version" - exit 1 -fi - -VERSION=$1 -SERIES=${VERSION:0:4}-latest - -docker push zadam/trilium:$VERSION -docker push zadam/trilium:$SERIES - -if [[ $1 != *"beta"* ]]; then - docker push zadam/trilium:latest -fi diff --git a/_regroup/bin/release-flatpack.sh b/_regroup/bin/release-flatpack.sh deleted file mode 100644 index 31e42881b7..0000000000 --- a/_regroup/bin/release-flatpack.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash - -if [[ $# -eq 0 ]] ; then - echo "Missing argument of new version" - exit 1 -fi - -VERSION=$1 - -if ! [[ ${VERSION} =~ ^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}(-.+)?$ ]] ; -then - echo "Version ${VERSION} isn't in format X.Y.Z" - exit 1 -fi - -VERSION_DATE=$(git log -1 --format=%aI "v${VERSION}" | cut -c -10) -VERSION_COMMIT=$(git rev-list -n 1 "v${VERSION}") - -# expecting the directory at a specific path -cd ~/trilium-flathub || exit - -if ! git diff-index --quiet HEAD --; then - echo "There are uncommitted changes" - exit 1 -fi - -BASE_BRANCH=main - -if [[ "$VERSION" == *"beta"* ]]; then - BASE_BRANCH=beta -fi - -git switch "${BASE_BRANCH}" -git pull - -BRANCH=b${VERSION} - -git branch "${BRANCH}" -git switch "${BRANCH}" - -echo "Updating files with version ${VERSION}, date ${VERSION_DATE} and commit ${VERSION_COMMIT}" - -flatpak-node-generator npm ../trilium/package-lock.json - -xmlstarlet ed --inplace --update "/component/releases/release/@version" --value "${VERSION}" --update "/component/releases/release/@date" --value "${VERSION_DATE}" ./com.github.zadam.trilium.metainfo.xml - -yq --inplace "(.modules[0].sources[0].tag = \"v${VERSION}\") | (.modules[0].sources[0].commit = \"${VERSION_COMMIT}\")" ./com.github.zadam.trilium.yml - -git add ./generated-sources.json -git add ./com.github.zadam.trilium.metainfo.xml -git add ./com.github.zadam.trilium.yml - -git commit -m "release $VERSION" -git push --set-upstream origin "${BRANCH}" - -gh pr create --fill -B "${BASE_BRANCH}" -gh pr merge --auto --merge --delete-branch diff --git a/_regroup/bin/release.sh b/_regroup/bin/release.sh deleted file mode 100644 index fe9a65a36a..0000000000 --- a/_regroup/bin/release.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash - -set -e - -if [[ $# -eq 0 ]] ; then - echo "Missing argument of new version" - exit 1 -fi - -if ! command -v jq &> /dev/null; then - echo "Missing command: jq" - exit 1 -fi - -VERSION=$1 - -if ! [[ ${VERSION} =~ ^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}(-.+)?$ ]] ; -then - echo "Version ${VERSION} isn't in format X.Y.Z" - exit 1 -fi - -if ! git diff-index --quiet HEAD --; then - echo "There are uncommitted changes" - exit 1 -fi - -echo "Releasing Trilium $VERSION" - -jq '.version = "'$VERSION'"' package.json > package.json.tmp -mv package.json.tmp package.json - -git add package.json - -npm run chore:update-build-info - -git add src/services/build.ts - -TAG=v$VERSION - -echo "Committing package.json version change" - -git commit -m "chore(release): $VERSION" -git push - -echo "Tagging commit with $TAG" - -git tag $TAG -git push origin $TAG diff --git a/_regroup/entitlements.plist b/_regroup/entitlements.plist deleted file mode 100644 index 040a4c1cb8..0000000000 --- a/_regroup/entitlements.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.cs.allow-jit - - com.apple.security.files.user-selected.read-write - - - \ No newline at end of file diff --git a/_regroup/eslint.config.js b/_regroup/eslint.config.js deleted file mode 100644 index 7c906beb2b..0000000000 --- a/_regroup/eslint.config.js +++ /dev/null @@ -1,51 +0,0 @@ -import eslint from "@eslint/js"; -import tseslint from "typescript-eslint"; -import simpleImportSort from "eslint-plugin-simple-import-sort"; - -export default tseslint.config( - eslint.configs.recommended, - tseslint.configs.recommended, - // consider using rules below, once we have a full TS codebase and can be more strict - // tseslint.configs.strictTypeChecked, - // tseslint.configs.stylisticTypeChecked, - // tseslint.configs.recommendedTypeChecked, - { - languageOptions: { - parserOptions: { - projectService: true, - tsconfigRootDir: import.meta.dirname - } - } - }, - { - plugins: { - "simple-import-sort": simpleImportSort - } - }, - { - rules: { - // add rule overrides here - "no-undef": "off", - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": [ - "error", - { - argsIgnorePattern: "^_", - varsIgnorePattern: "^_" - } - ], - "simple-import-sort/imports": "error", - "simple-import-sort/exports": "error" - } - }, - { - ignores: [ - "build/*", - "dist/*", - "docs/*", - "demo/*", - "src/public/app-dist/*", - "src/public/app/doc_notes/*" - ] - } -); diff --git a/_regroup/eslint.format.config.js b/_regroup/eslint.format.config.js deleted file mode 100644 index 9dbfd78b2e..0000000000 --- a/_regroup/eslint.format.config.js +++ /dev/null @@ -1,47 +0,0 @@ -import stylistic from "@stylistic/eslint-plugin"; -import tsParser from "@typescript-eslint/parser"; - -// eslint config just for formatting rules -// potentially to be merged with the linting rules into one single config, -// once we have fixed the majority of lint errors - -// Go to https://eslint.style/rules/default/${rule_without_prefix} to check the rule details -export const stylisticRules = { - "@stylistic/indent": [ "error", 4 ], - "@stylistic/quotes": [ "error", "double", { avoidEscape: true, allowTemplateLiterals: "always" } ], - "@stylistic/semi": [ "error", "always" ], - "@stylistic/quote-props": [ "error", "consistent-as-needed" ], - "@stylistic/max-len": [ "error", { code: 100 } ], - "@stylistic/comma-dangle": [ "error", "never" ], - "@stylistic/linebreak-style": [ "error", "unix" ], - "@stylistic/array-bracket-spacing": [ "error", "always" ], - "@stylistic/object-curly-spacing": [ "error", "always" ], - "@stylistic/padded-blocks": [ "error", { classes: "always" } ] -}; - -export default [ - { - files: [ "**/*.{js,ts,mjs,cjs}" ], - languageOptions: { - parser: tsParser - }, - plugins: { - "@stylistic": stylistic - }, - rules: { - ...stylisticRules - } - }, - { - ignores: [ - "build/*", - "dist/*", - "docs/*", - "demo/*", - // TriliumNextTODO: check if we want to format packages here as well - for now skipping it - "packages/*", - "src/public/app-dist/*", - "src/public/app/doc_notes/*" - ] - } -]; diff --git a/_regroup/integration-tests/auth.setup.ts b/_regroup/integration-tests/auth.setup.ts deleted file mode 100644 index 9b31eec499..0000000000 --- a/_regroup/integration-tests/auth.setup.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { test as setup, expect } from "@playwright/test"; - -const authFile = "playwright/.auth/user.json"; - -const ROOT_URL = "http://localhost:8082"; -const LOGIN_PASSWORD = "demo1234"; - -// Reference: https://playwright.dev/docs/auth#basic-shared-account-in-all-tests - -setup("authenticate", async ({ page }) => { - await page.goto(ROOT_URL); - await expect(page).toHaveURL(`${ROOT_URL}/login`); - - await page.getByRole("textbox", { name: "Password" }).fill(LOGIN_PASSWORD); - await page.getByRole("button", { name: "Login" }).click(); - await page.context().storageState({ path: authFile }); -}); diff --git a/_regroup/integration-tests/duplicate.spec.ts b/_regroup/integration-tests/duplicate.spec.ts deleted file mode 100644 index fe079952bd..0000000000 --- a/_regroup/integration-tests/duplicate.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { test, expect } from "@playwright/test"; - -test("Can duplicate note with broken links", async ({ page }) => { - await page.goto(`http://localhost:8082/#2VammGGdG6Ie`); - await page.locator(".tree-wrapper .fancytree-active").getByText("Note map").click({ button: "right" }); - await page.getByText("Duplicate subtree").click(); - await expect(page.locator(".toast-body")).toBeHidden(); - await expect(page.locator(".tree-wrapper").getByText("Note map (dup)")).toBeVisible(); -}); diff --git a/_regroup/integration-tests/example.disabled.ts b/_regroup/integration-tests/example.disabled.ts deleted file mode 100644 index a149fe3286..0000000000 --- a/_regroup/integration-tests/example.disabled.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { test, expect } from "@playwright/test"; - -test("has title", async ({ page }) => { - await page.goto("https://playwright.dev/"); - - // Expect a title "to contain" a substring. - await expect(page).toHaveTitle(/Playwright/); -}); - -test("get started link", async ({ page }) => { - await page.goto("https://playwright.dev/"); - - // Click the get started link. - await page.getByRole("link", { name: "Get started" }).click(); - - // Expects page to have a heading with the name of Installation. - await expect(page.getByRole("heading", { name: "Installation" })).toBeVisible(); -}); diff --git a/_regroup/integration-tests/settings.spec.ts b/_regroup/integration-tests/settings.spec.ts deleted file mode 100644 index b3fe16fda3..0000000000 --- a/_regroup/integration-tests/settings.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import test, { expect } from "@playwright/test"; - -test("Native Title Bar not displayed on web", async ({ page }) => { - await page.goto("http://localhost:8082/#root/_hidden/_options/_optionsAppearance"); - await expect(page.getByRole("heading", { name: "Theme" })).toBeVisible(); - await expect(page.getByRole("heading", { name: "Native Title Bar (requires" })).toBeHidden(); -}); - -test("Tray settings not displayed on web", async ({ page }) => { - await page.goto("http://localhost:8082/#root/_hidden/_options/_optionsOther"); - await expect(page.getByRole("heading", { name: "Note Erasure Timeout" })).toBeVisible(); - await expect(page.getByRole("heading", { name: "Tray" })).toBeHidden(); -}); - -test("Spellcheck settings not displayed on web", async ({ page }) => { - await page.goto("http://localhost:8082/#root/_hidden/_options/_optionsSpellcheck"); - await expect(page.getByRole("heading", { name: "Spell Check" })).toBeVisible(); - await expect(page.getByRole("heading", { name: "Tray" })).toBeHidden(); - await expect(page.getByText("These options apply only for desktop builds")).toBeVisible(); - await expect(page.getByText("Enable spellcheck")).toBeHidden(); -}); diff --git a/_regroup/integration-tests/tree.spec.ts b/_regroup/integration-tests/tree.spec.ts deleted file mode 100644 index 257375fa81..0000000000 --- a/_regroup/integration-tests/tree.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import test, { expect } from "@playwright/test"; - -test("Renders on desktop", async ({ page, context }) => { - await page.goto("http://localhost:8082"); - await expect(page.locator(".tree")).toContainText("Trilium Integration Test"); -}); - -test("Renders on mobile", async ({ page, context }) => { - await context.addCookies([ - { - url: "http://localhost:8082", - name: "trilium-device", - value: "mobile" - } - ]); - await page.goto("http://localhost:8082"); - await expect(page.locator(".tree")).toContainText("Trilium Integration Test"); -}); diff --git a/_regroup/integration-tests/update_check.spec.ts b/_regroup/integration-tests/update_check.spec.ts deleted file mode 100644 index 38e28bf229..0000000000 --- a/_regroup/integration-tests/update_check.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { test, expect } from "@playwright/test"; - -const expectedVersion = "0.90.3"; - -test("Displays update badge when there is a version available", async ({ page }) => { - await page.goto("http://localhost:8080"); - await page.getByRole("button", { name: "ī°·" }).click(); - await page.getByText(`Version ${expectedVersion} is available,`).click(); - - const page1 = await page.waitForEvent("popup"); - expect(page1.url()).toBe(`https://github.com/TriliumNext/Trilium/releases/tag/v${expectedVersion}`); -}); diff --git a/_regroup/package.json b/_regroup/package.json deleted file mode 100644 index 5b00715eb8..0000000000 --- a/_regroup/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "main": "./electron-main.js", - "bin": { - "trilium": "src/main.js" - }, - "type": "module", - "scripts": { - "server:start-safe": "cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev nodemon src/main.ts", - "server:start-no-dir": "cross-env TRILIUM_ENV=dev nodemon src/main.ts", - "server:start-test": "npm run server:switch && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts", - "server:qstart": "npm run server:switch && npm run server:start", - "server:switch": "rimraf ./node_modules/better-sqlite3 && npm install", - "electron:start-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev TRILIUM_PORT=37742 electron --inspect=5858 .", - "electron:start-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"", - "electron:start-nix-no-dir": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev TRILIUM_PORT=37742 nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"", - "electron:start-prod-no-dir": "npm run build:prepare-dist && cross-env TRILIUM_ENV=prod electron --inspect=5858 .", - "electron:start-prod-nix": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"", - "electron:start-prod-nix-no-dir": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"", - "electron:qstart": "npm run electron:switch && npm run electron:start", - "electron:switch": "electron-rebuild", - "docs:build": "typedoc", - "test": "npm run client:test && npm run server:test", - "client:test": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app", - "client:coverage": "cross-env TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest --root src/public/app --coverage", - "test:playwright": "playwright test --workers 1", - "test:integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts", - "test:integration-mem-db": "cross-env nodemon src/main.ts", - "test:integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts", - "dev:watch-dist": "tsx ./bin/watch-dist.ts", - "dev:format-check": "eslint -c eslint.format.config.js .", - "dev:format-fix": "eslint -c eslint.format.config.js . --fix", - "dev:linter-check": "eslint .", - "dev:linter-fix": "eslint . --fix", - "chore:generate-document": "cross-env nodemon ./bin/generate_document.ts 1000", - "chore:generate-openapi": "tsx bin/generate-openapi.js" - }, - "devDependencies": { - "@playwright/test": "1.54.1", - "@stylistic/eslint-plugin": "5.2.2", - "@types/express": "5.0.3", - "@types/node": "22.17.0", - "@types/yargs": "17.0.33", - "@vitest/coverage-v8": "3.2.4", - "eslint": "9.32.0", - "eslint-plugin-simple-import-sort": "12.1.1", - "esm": "3.2.25", - "jsdoc": "4.0.4", - "lorem-ipsum": "2.0.8", - "rcedit": "4.0.1", - "rimraf": "6.0.1", - "tslib": "2.8.1", - "typedoc": "0.28.8", - "typedoc-plugin-missing-exports": "4.0.0" - }, - "optionalDependencies": { - "appdmg": "0.6.6" - } -} diff --git a/_regroup/spec/etapi/app_info.ts b/_regroup/spec/etapi/app_info.ts deleted file mode 100644 index 9c510d99b2..0000000000 --- a/_regroup/spec/etapi/app_info.ts +++ /dev/null @@ -1,9 +0,0 @@ -import etapi from "../support/etapi.js"; -/* TriliumNextTODO: port to Vitest -etapi.describeEtapi("app_info", () => { - it("get", async () => { - const appInfo = await etapi.getEtapi("app-info"); - expect(appInfo.clipperProtocolVersion).toEqual("1.0"); - }); -}); -*/ diff --git a/_regroup/spec/etapi/backup.ts b/_regroup/spec/etapi/backup.ts deleted file mode 100644 index 924213f0e3..0000000000 --- a/_regroup/spec/etapi/backup.ts +++ /dev/null @@ -1,10 +0,0 @@ -import etapi from "../support/etapi.js"; - -/* TriliumNextTODO: port to Vitest -etapi.describeEtapi("backup", () => { - it("create", async () => { - const response = await etapi.putEtapiContent("backup/etapi_test"); - expect(response.status).toEqual(204); - }); -}); -*/ diff --git a/_regroup/spec/etapi/import.ts b/_regroup/spec/etapi/import.ts deleted file mode 100644 index 36782a26ab..0000000000 --- a/_regroup/spec/etapi/import.ts +++ /dev/null @@ -1,26 +0,0 @@ -import etapi from "../support/etapi.js"; -import fs from "fs"; -import path from "path"; -import { fileURLToPath } from "url"; - -/* TriliumNextTODO: port to Vitest -etapi.describeEtapi("import", () => { - // temporarily skip this test since test-export.zip is missing - xit("import", async () => { - const scriptDir = path.dirname(fileURLToPath(import.meta.url)); - - const zipFileBuffer = fs.readFileSync(path.resolve(scriptDir, "test-export.zip")); - - const response = await etapi.postEtapiContent("notes/root/import", zipFileBuffer); - expect(response.status).toEqual(201); - - const { note, branch } = await response.json(); - - expect(note.title).toEqual("test-export"); - expect(branch.parentNoteId).toEqual("root"); - - const content = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).text(); - expect(content).toContain("test export content"); - }); -}); -*/ diff --git a/_regroup/spec/etapi/notes.ts b/_regroup/spec/etapi/notes.ts deleted file mode 100644 index d5c9b680cd..0000000000 --- a/_regroup/spec/etapi/notes.ts +++ /dev/null @@ -1,103 +0,0 @@ -import crypto from "crypto"; -import etapi from "../support/etapi.js"; - -/* TriliumNextTODO: port to Vitest -etapi.describeEtapi("notes", () => { - it("create", async () => { - const { note, branch } = await etapi.postEtapi("create-note", { - parentNoteId: "root", - type: "text", - title: "Hello World!", - content: "Content", - prefix: "Custom prefix" - }); - - expect(note.title).toEqual("Hello World!"); - expect(branch.parentNoteId).toEqual("root"); - expect(branch.prefix).toEqual("Custom prefix"); - - const rNote = await etapi.getEtapi(`notes/${note.noteId}`); - expect(rNote.title).toEqual("Hello World!"); - - const rContent = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).text(); - expect(rContent).toEqual("Content"); - - const rBranch = await etapi.getEtapi(`branches/${branch.branchId}`); - expect(rBranch.parentNoteId).toEqual("root"); - expect(rBranch.prefix).toEqual("Custom prefix"); - }); - - it("patch", async () => { - const { note } = await etapi.postEtapi("create-note", { - parentNoteId: "root", - type: "text", - title: "Hello World!", - content: "Content" - }); - - await etapi.patchEtapi(`notes/${note.noteId}`, { - title: "new title", - type: "code", - mime: "text/apl", - dateCreated: "2000-01-01 12:34:56.999+0200", - utcDateCreated: "2000-01-01 10:34:56.999Z" - }); - - const rNote = await etapi.getEtapi(`notes/${note.noteId}`); - expect(rNote.title).toEqual("new title"); - expect(rNote.type).toEqual("code"); - expect(rNote.mime).toEqual("text/apl"); - expect(rNote.dateCreated).toEqual("2000-01-01 12:34:56.999+0200"); - expect(rNote.utcDateCreated).toEqual("2000-01-01 10:34:56.999Z"); - }); - - it("update content", async () => { - const { note } = await etapi.postEtapi("create-note", { - parentNoteId: "root", - type: "text", - title: "Hello World!", - content: "Content" - }); - - await etapi.putEtapiContent(`notes/${note.noteId}/content`, "new content"); - - const rContent = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).text(); - expect(rContent).toEqual("new content"); - }); - - it("create / update binary content", async () => { - const { note } = await etapi.postEtapi("create-note", { - parentNoteId: "root", - type: "file", - title: "Hello World!", - content: "ZZZ" - }); - - const updatedContent = crypto.randomBytes(16); - - await etapi.putEtapiContent(`notes/${note.noteId}/content`, updatedContent); - - const rContent = await (await etapi.getEtapiContent(`notes/${note.noteId}/content`)).arrayBuffer(); - expect(Buffer.from(new Uint8Array(rContent))).toEqual(updatedContent); - }); - - it("delete note", async () => { - const { note } = await etapi.postEtapi("create-note", { - parentNoteId: "root", - type: "text", - title: "Hello World!", - content: "Content" - }); - - await etapi.deleteEtapi(`notes/${note.noteId}`); - - const resp = await etapi.getEtapiResponse(`notes/${note.noteId}`); - expect(resp.status).toEqual(404); - - const error = await resp.json(); - expect(error.status).toEqual(404); - expect(error.code).toEqual("NOTE_NOT_FOUND"); - expect(error.message).toEqual(`Note '${note.noteId}' not found.`); - }); -}); -*/ diff --git a/_regroup/spec/support/etapi.ts b/_regroup/spec/support/etapi.ts deleted file mode 100644 index 307868d7d9..0000000000 --- a/_regroup/spec/support/etapi.ts +++ /dev/null @@ -1,155 +0,0 @@ -import type child_process from "child_process"; -import { describe, beforeAll, afterAll } from "vitest"; - -let etapiAuthToken: string | undefined; - -const getEtapiAuthorizationHeader = (): string => "Basic " + Buffer.from(`etapi:${etapiAuthToken}`).toString("base64"); - -const PORT: string = "9999"; -const HOST: string = "http://localhost:" + PORT; - -type SpecDefinitionsFunc = () => void; - -function describeEtapi(description: string, specDefinitions: SpecDefinitionsFunc): void { - describe(description, () => { - let appProcess: ReturnType; - - beforeAll(async () => {}); - - afterAll(() => {}); - - specDefinitions(); - }); -} - -async function getEtapiResponse(url: string): Promise { - return await fetch(`${HOST}/etapi/${url}`, { - method: "GET", - headers: { - Authorization: getEtapiAuthorizationHeader() - } - }); -} - -async function getEtapi(url: string): Promise { - const response = await getEtapiResponse(url); - return await processEtapiResponse(response); -} - -async function getEtapiContent(url: string): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "GET", - headers: { - Authorization: getEtapiAuthorizationHeader() - } - }); - - checkStatus(response); - - return response; -} - -async function postEtapi(url: string, data: Record = {}): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: getEtapiAuthorizationHeader() - }, - body: JSON.stringify(data) - }); - return await processEtapiResponse(response); -} - -async function postEtapiContent(url: string, data: BodyInit): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "POST", - headers: { - "Content-Type": "application/octet-stream", - Authorization: getEtapiAuthorizationHeader() - }, - body: data - }); - - checkStatus(response); - - return response; -} - -async function putEtapi(url: string, data: Record = {}): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "PUT", - headers: { - "Content-Type": "application/json", - Authorization: getEtapiAuthorizationHeader() - }, - body: JSON.stringify(data) - }); - return await processEtapiResponse(response); -} - -async function putEtapiContent(url: string, data?: BodyInit): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "PUT", - headers: { - "Content-Type": "application/octet-stream", - Authorization: getEtapiAuthorizationHeader() - }, - body: data - }); - - checkStatus(response); - - return response; -} - -async function patchEtapi(url: string, data: Record = {}): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "PATCH", - headers: { - "Content-Type": "application/json", - Authorization: getEtapiAuthorizationHeader() - }, - body: JSON.stringify(data) - }); - return await processEtapiResponse(response); -} - -async function deleteEtapi(url: string): Promise { - const response = await fetch(`${HOST}/etapi/${url}`, { - method: "DELETE", - headers: { - Authorization: getEtapiAuthorizationHeader() - } - }); - return await processEtapiResponse(response); -} - -async function processEtapiResponse(response: Response): Promise { - const text = await response.text(); - - if (response.status < 200 || response.status >= 300) { - throw new Error(`ETAPI error ${response.status}: ${text}`); - } - - return text?.trim() ? JSON.parse(text) : null; -} - -function checkStatus(response: Response): void { - if (response.status < 200 || response.status >= 300) { - throw new Error(`ETAPI error ${response.status}`); - } -} - -export default { - describeEtapi, - getEtapi, - getEtapiResponse, - getEtapiContent, - postEtapi, - postEtapiContent, - putEtapi, - putEtapiContent, - patchEtapi, - deleteEtapi -}; diff --git a/_regroup/tsconfig.webpack.json b/_regroup/tsconfig.webpack.json deleted file mode 100644 index ed622818b3..0000000000 --- a/_regroup/tsconfig.webpack.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "module": "NodeNext", - "declaration": false, - "sourceMap": true, - "outDir": "./build", - "strict": true, - "noImplicitAny": true, - "resolveJsonModule": true, - "lib": ["ES2023"], - "downlevelIteration": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowJs": true - }, - "include": ["./src/public/app/**/*"], - "files": [ - "./src/public/app/types.d.ts", - "./src/public/app/types-lib.d.ts", - "./src/types.d.ts" - ] -} diff --git a/_regroup/typedoc.json b/_regroup/typedoc.json deleted file mode 100644 index 30771621ca..0000000000 --- a/_regroup/typedoc.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "entryPoints": [ - "src/services/backend_script_entrypoint.ts", - "src/public/app/services/frontend_script_entrypoint.ts" - ], - "plugin": [ - "typedoc-plugin-missing-exports" - ], - "outputs": [ - { - "name": "html", - "path": "./docs/Script API" - } - ] -} diff --git a/apps/build-docs/package.json b/apps/build-docs/package.json new file mode 100644 index 0000000000..98a346e05f --- /dev/null +++ b/apps/build-docs/package.json @@ -0,0 +1,28 @@ +{ + "name": "build-docs", + "version": "1.0.0", + "description": "Build documentation from Trilium notes", + "main": "src/main.ts", + "bin": { + "trilium-build-docs": "dist/cli.js" + }, + "scripts": { + "start": "tsx .", + "cli": "tsx src/cli.ts", + "build": "tsx scripts/build.ts" + }, + "keywords": [], + "author": "Elian Doran ", + "license": "AGPL-3.0-only", + "packageManager": "pnpm@10.33.0", + "devDependencies": { + "@redocly/cli": "2.25.3", + "archiver": "7.0.1", + "fs-extra": "11.3.4", + "js-yaml": "4.1.1", + "react": "19.2.4", + "react-dom": "19.2.4", + "typedoc": "0.28.18", + "typedoc-plugin-missing-exports": "4.1.2" + } +} diff --git a/apps/build-docs/scripts/build.ts b/apps/build-docs/scripts/build.ts new file mode 100644 index 0000000000..79fa01f3f6 --- /dev/null +++ b/apps/build-docs/scripts/build.ts @@ -0,0 +1,23 @@ +import BuildHelper from "../../../scripts/build-utils"; + +const build = new BuildHelper("apps/build-docs"); + +async function main() { + // Build the CLI and other TypeScript files + await build.buildBackend([ + "src/cli.ts", + "src/main.ts", + "src/build-docs.ts", + "src/swagger.ts", + "src/script-api.ts", + "src/context.ts" + ]); + + // Copy HTML template + build.copy("src/index.html", "index.html"); + + // Copy node modules dependencies if needed + build.copyNodeModules([ "better-sqlite3", "bindings", "file-uri-to-path" ]); +} + +main(); diff --git a/apps/build-docs/src/backend_script_entrypoint.ts b/apps/build-docs/src/backend_script_entrypoint.ts new file mode 100644 index 0000000000..0447900b6b --- /dev/null +++ b/apps/build-docs/src/backend_script_entrypoint.ts @@ -0,0 +1,41 @@ +/** + * The backend script API is accessible to code notes with the "JS (backend)" language. + * + * The entire API is exposed as a single global: {@link api} + * + * @module Backend Script API + */ + +/** + * This file creates the entrypoint for TypeDoc that simulates the context from within a + * script note on the server side. + * + * Make sure to keep in line with backend's `script_context.ts`. + */ + +export type { + default as AbstractBeccaEntity +} from "../../server/src/becca/entities/abstract_becca_entity.js"; +export type { + default as BAttachment +} from "../../server/src/becca/entities/battachment.js"; +export type { default as BAttribute } from "../../server/src/becca/entities/battribute.js"; +export type { default as BBranch } from "../../server/src/becca/entities/bbranch.js"; +export type { default as BEtapiToken } from "../../server/src/becca/entities/betapi_token.js"; +export type { BNote }; +export type { default as BOption } from "../../server/src/becca/entities/boption.js"; +export type { default as BRecentNote } from "../../server/src/becca/entities/brecent_note.js"; +export type { default as BRevision } from "../../server/src/becca/entities/brevision.js"; + +import BNote from "../../server/src/becca/entities/bnote.js"; +import BackendScriptApi, { type Api } from "../../server/src/services/backend_script_api.js"; + +export type { Api }; + +const fakeNote = new BNote(); + +/** + * The `api` global variable allows access to the backend script API, + * which is documented in {@link Api}. + */ +export const api: Api = new BackendScriptApi(fakeNote, {}); diff --git a/apps/build-docs/src/build-docs.ts b/apps/build-docs/src/build-docs.ts new file mode 100644 index 0000000000..357ecb1d41 --- /dev/null +++ b/apps/build-docs/src/build-docs.ts @@ -0,0 +1,274 @@ +process.env.TRILIUM_INTEGRATION_TEST = "memory-no-store"; +// Only set TRILIUM_RESOURCE_DIR if not already set (e.g., by Nix wrapper) +if (!process.env.TRILIUM_RESOURCE_DIR) { + process.env.TRILIUM_RESOURCE_DIR = "../server/src"; +} +process.env.NODE_ENV = "development"; + +import cls from "@triliumnext/server/src/services/cls.js"; +import archiver from "archiver"; +import { execSync } from "child_process"; +import { WriteStream } from "fs"; +import * as fs from "fs/promises"; +import * as fsExtra from "fs-extra"; +import yaml from "js-yaml"; +import { dirname, join, resolve } from "path"; + +import BuildContext from "./context.js"; + +interface NoteMapping { + rootNoteId: string; + path: string; + format: "markdown" | "html" | "share"; + ignoredFiles?: string[]; + exportOnly?: boolean; +} + +interface Config { + baseUrl: string; + noteMappings: NoteMapping[]; +} + +const DOCS_ROOT = "../../../docs"; +const OUTPUT_DIR = "../../site"; + +// Load configuration from edit-docs-config.yaml +async function loadConfig(configPath?: string): Promise { + const pathsToTry = configPath + ? [resolve(configPath)] + : [ + join(process.cwd(), "edit-docs-config.yaml"), + join(__dirname, "../../../edit-docs-config.yaml") + ]; + + for (const path of pathsToTry) { + try { + const configContent = await fs.readFile(path, "utf-8"); + const config = yaml.load(configContent) as Config; + + // Resolve all paths relative to the config file's directory + const CONFIG_DIR = dirname(path); + config.noteMappings = config.noteMappings.map((mapping) => ({ + ...mapping, + path: resolve(CONFIG_DIR, mapping.path) + })); + + return config; + } catch (error) { + if (error.code !== "ENOENT") { + throw error; // rethrow unexpected errors + } + } + } + + return null; // No config file found +} + +async function exportDocs( + noteId: string, + format: "markdown" | "html" | "share", + outputPath: string, + ignoredFiles?: string[] +) { + const zipFilePath = `output-${noteId}.zip`; + try { + const { exportToZipFile } = (await import("@triliumnext/server/src/services/export/zip.js")) + .default; + await exportToZipFile(noteId, format, zipFilePath, {}); + + const ignoredSet = ignoredFiles ? new Set(ignoredFiles) : undefined; + await extractZip(zipFilePath, outputPath, ignoredSet); + } finally { + if (await fsExtra.exists(zipFilePath)) { + await fsExtra.rm(zipFilePath); + } + } +} + +async function importAndExportDocs(sourcePath: string, outputSubDir: string) { + const note = await importData(sourcePath); + + // Use a meaningful name for the temporary zip file + const zipName = outputSubDir || "user-guide"; + const zipFilePath = `output-${zipName}.zip`; + try { + const { exportToZip } = (await import("@triliumnext/server/src/services/export/zip.js")) + .default; + const branch = note.getParentBranches()[0]; + const taskContext = new (await import("@triliumnext/server/src/services/task_context.js")) + .default( + "no-progress-reporting", + "export", + null + ); + const fileOutputStream = fsExtra.createWriteStream(zipFilePath); + await exportToZip(taskContext, branch, "share", fileOutputStream); + const { waitForStreamToFinish } = await import("@triliumnext/server/src/services/utils.js"); + await waitForStreamToFinish(fileOutputStream); + + // Output to root directory if outputSubDir is empty, otherwise to subdirectory + const outputPath = outputSubDir ? join(OUTPUT_DIR, outputSubDir) : OUTPUT_DIR; + await extractZip(zipFilePath, outputPath); + } finally { + if (await fsExtra.exists(zipFilePath)) { + await fsExtra.rm(zipFilePath); + } + } +} + +async function buildDocsInner(config?: Config) { + const i18n = await import("@triliumnext/server/src/services/i18n.js"); + await i18n.initializeTranslations(); + + const sqlInit = (await import("../../server/src/services/sql_init.js")).default; + await sqlInit.createInitialDatabase(true); + + // Wait for becca to be loaded before importing data + const beccaLoader = await import("../../server/src/becca/becca_loader.js"); + await beccaLoader.beccaLoaded; + + if (config) { + // Config-based build (reads from edit-docs-config.yaml) + console.log("Building documentation from config file..."); + + // Import all non-export-only mappings + for (const mapping of config.noteMappings) { + if (!mapping.exportOnly) { + console.log(`Importing from ${mapping.path}...`); + await importData(mapping.path); + } + } + + // Export all mappings + for (const mapping of config.noteMappings) { + if (mapping.exportOnly) { + console.log(`Exporting ${mapping.format} to ${mapping.path}...`); + await exportDocs( + mapping.rootNoteId, + mapping.format, + mapping.path, + mapping.ignoredFiles + ); + } + } + } else { + // Legacy hardcoded build (for backward compatibility) + console.log("Building User Guide..."); + await importAndExportDocs(join(__dirname, DOCS_ROOT, "User Guide"), "user-guide"); + + console.log("Building Developer Guide..."); + await importAndExportDocs( + join(__dirname, DOCS_ROOT, "Developer Guide"), + "developer-guide" + ); + + // Copy favicon. + await fs.copyFile("../../apps/website/src/assets/favicon.ico", + join(OUTPUT_DIR, "favicon.ico")); + await fs.copyFile("../../apps/website/src/assets/favicon.ico", + join(OUTPUT_DIR, "user-guide", "favicon.ico")); + await fs.copyFile("../../apps/website/src/assets/favicon.ico", + join(OUTPUT_DIR, "developer-guide", "favicon.ico")); + } + + console.log("Documentation built successfully!"); +} + +export async function importData(path: string) { + const buffer = await createImportZip(path); + const importService = (await import("../../server/src/services/import/zip.js")).default; + const TaskContext = (await import("../../server/src/services/task_context.js")).default; + const context = new TaskContext("no-progress-reporting", "importNotes", null); + const becca = (await import("../../server/src/becca/becca.js")).default; + + const rootNote = becca.getRoot(); + if (!rootNote) { + throw new Error("Missing root note for import."); + } + return await importService.importZip(context, buffer, rootNote, { + preserveIds: true + }); +} + +async function createImportZip(path: string) { + const inputFile = "input.zip"; + const archive = archiver("zip", { + zlib: { level: 0 } + }); + + console.log("Archive path is ", resolve(path)); + archive.directory(path, "/"); + + const outputStream = fsExtra.createWriteStream(inputFile); + archive.pipe(outputStream); + archive.finalize(); + const { waitForStreamToFinish } = await import("@triliumnext/server/src/services/utils.js"); + await waitForStreamToFinish(outputStream); + + try { + return await fsExtra.readFile(inputFile); + } finally { + await fsExtra.rm(inputFile); + } +} + + +export async function extractZip( + zipFilePath: string, + outputPath: string, + ignoredFiles?: Set +) { + const { readZipFile, readContent } = (await import( + "@triliumnext/server/src/services/import/zip.js" + )); + await readZipFile(await fs.readFile(zipFilePath), async (zip, entry) => { + // We ignore directories since they can appear out of order anyway. + if (!entry.fileName.endsWith("/") && !ignoredFiles?.has(entry.fileName)) { + const destPath = join(outputPath, entry.fileName); + const fileContent = await readContent(zip, entry); + + await fsExtra.mkdirs(dirname(destPath)); + await fs.writeFile(destPath, fileContent); + } + + zip.readEntry(); + }); +} + +export async function buildDocsFromConfig(configPath?: string, gitRootDir?: string) { + const config = await loadConfig(configPath); + + if (gitRootDir) { + // Build the share theme if we have a gitRootDir (for Trilium project) + execSync(`pnpm run --filter share-theme build`, { + stdio: "inherit", + cwd: gitRootDir + }); + } + + // Trigger the actual build. + await new Promise((res, rej) => { + cls.init(() => { + buildDocsInner(config ?? undefined) + .catch(rej) + .then(res); + }); + }); +} + +export default async function buildDocs({ gitRootDir }: BuildContext) { + // Build the share theme. + execSync(`pnpm run --filter share-theme build`, { + stdio: "inherit", + cwd: gitRootDir + }); + + // Trigger the actual build. + await new Promise((res, rej) => { + cls.init(() => { + buildDocsInner() + .catch(rej) + .then(res); + }); + }); +} diff --git a/apps/build-docs/src/cli.ts b/apps/build-docs/src/cli.ts new file mode 100644 index 0000000000..8aee089701 --- /dev/null +++ b/apps/build-docs/src/cli.ts @@ -0,0 +1,89 @@ +#!/usr/bin/env node + +import packageJson from "../package.json" with { type: "json" }; +import { buildDocsFromConfig } from "./build-docs.js"; + +// Parse command-line arguments +function parseArgs() { + const args = process.argv.slice(2); + let configPath: string | undefined; + let showHelp = false; + let showVersion = false; + + for (let i = 0; i < args.length; i++) { + if (args[i] === "--config" || args[i] === "-c") { + configPath = args[i + 1]; + if (!configPath) { + console.error("Error: --config/-c requires a path argument"); + process.exit(1); + } + i++; // Skip the next argument as it's the value + } else if (args[i] === "--help" || args[i] === "-h") { + showHelp = true; + } else if (args[i] === "--version" || args[i] === "-v") { + showVersion = true; + } + } + + return { configPath, showHelp, showVersion }; +} + +function getVersion(): string { + return packageJson.version; +} + +function printHelp() { + const version = getVersion(); + console.log(` +Usage: trilium-build-docs [options] + +Options: + -c, --config Path to the configuration file + (default: edit-docs-config.yaml in current directory) + -h, --help Display this help message + -v, --version Display version information + +Description: + Builds documentation from Trilium note structure and exports to various formats. + Configuration file should be in YAML format with the following structure: + + baseUrl: "https://example.com" + noteMappings: + - rootNoteId: "noteId123" + path: "docs" + format: "markdown" + - rootNoteId: "noteId456" + path: "public/docs" + format: "share" + exportOnly: true + +Version: ${version} +`); +} + +function printVersion() { + const version = getVersion(); + console.log(version); +} + +async function main() { + const { configPath, showHelp, showVersion } = parseArgs(); + + if (showHelp) { + printHelp(); + process.exit(0); + } else if (showVersion) { + printVersion(); + process.exit(0); + } + + try { + await buildDocsFromConfig(configPath); + process.exit(0); + } catch (error) { + console.error("Error building documentation:", error); + process.exit(1); + } +} + +main(); diff --git a/apps/build-docs/src/context.ts b/apps/build-docs/src/context.ts new file mode 100644 index 0000000000..ab2289e506 --- /dev/null +++ b/apps/build-docs/src/context.ts @@ -0,0 +1,4 @@ +export default interface BuildContext { + gitRootDir: string; + baseDir: string; +} diff --git a/apps/build-docs/src/frontend_script_entrypoint.ts b/apps/build-docs/src/frontend_script_entrypoint.ts new file mode 100644 index 0000000000..7aba11b2a4 --- /dev/null +++ b/apps/build-docs/src/frontend_script_entrypoint.ts @@ -0,0 +1,31 @@ +/** + * The front script API is accessible to code notes with the "JS (frontend)" language. + * + * The entire API is exposed as a single global: {@link api} + * + * @module Frontend Script API + */ + +/** + * This file creates the entrypoint for TypeDoc that simulates the context from within a + * script note. + * + * Make sure to keep in line with frontend's `script_context.ts`. + */ + +export type { default as FAttachment } from "../../client/src/entities/fattachment.js"; +export type { default as FAttribute } from "../../client/src/entities/fattribute.js"; +export type { default as FBranch } from "../../client/src/entities/fbranch.js"; +export type { default as FNote } from "../../client/src/entities/fnote.js"; +export type { Api } from "../../client/src/services/frontend_script_api.js"; +export type { default as BasicWidget } from "../../client/src/widgets/basic_widget.js"; +export type { + default as NoteContextAwareWidget +} from "../../client/src/widgets/note_context_aware_widget.js"; +export type { default as RightPanelWidget } from "../../client/src/widgets/right_panel_widget.js"; + +import FrontendScriptApi, { type Api } from "../../client/src/services/frontend_script_api.js"; + + +// @ts-expect-error - FrontendScriptApi is not directly exportable as Api without this simulation. +export const api: Api = new FrontendScriptApi(); diff --git a/apps/build-docs/src/index.html b/apps/build-docs/src/index.html new file mode 100644 index 0000000000..47a0bfb34e --- /dev/null +++ b/apps/build-docs/src/index.html @@ -0,0 +1,10 @@ + + + + + Redirecting... + + +

If you are not redirected automatically, click here.

+ + \ No newline at end of file diff --git a/apps/build-docs/src/main.ts b/apps/build-docs/src/main.ts new file mode 100644 index 0000000000..cca17125d8 --- /dev/null +++ b/apps/build-docs/src/main.ts @@ -0,0 +1,31 @@ +import { cpSync, existsSync, mkdirSync, rmSync } from "fs"; +import { join } from "path"; + +import buildDocs from "./build-docs"; +import BuildContext from "./context"; +import buildScriptApi from "./script-api"; +import buildSwagger from "./swagger"; + +const context: BuildContext = { + gitRootDir: join(__dirname, "../../../"), + baseDir: join(__dirname, "../../../site") +}; + +async function main() { + // Clean input dir. + if (existsSync(context.baseDir)) { + rmSync(context.baseDir, { recursive: true }); + } + mkdirSync(context.baseDir); + + // Start building. + await buildDocs(context); + buildSwagger(context); + buildScriptApi(context); + + // Copy index and 404 files. + cpSync(join(__dirname, "index.html"), join(context.baseDir, "index.html")); + cpSync(join(context.baseDir, "user-guide/404.html"), join(context.baseDir, "404.html")); +} + +main(); diff --git a/apps/build-docs/src/script-api.ts b/apps/build-docs/src/script-api.ts new file mode 100644 index 0000000000..2c62477474 --- /dev/null +++ b/apps/build-docs/src/script-api.ts @@ -0,0 +1,16 @@ +import { execSync } from "child_process"; +import { join } from "path"; + +import BuildContext from "./context"; + +export default function buildScriptApi({ baseDir, gitRootDir }: BuildContext) { + // Generate types + execSync(`pnpm typecheck`, { stdio: "inherit", cwd: gitRootDir }); + + for (const config of [ "backend", "frontend" ]) { + const outDir = join(baseDir, "script-api", config); + execSync(`pnpm typedoc --options typedoc.${config}.json --html "${outDir}"`, { + stdio: "inherit" + }); + } +} diff --git a/apps/build-docs/src/swagger.ts b/apps/build-docs/src/swagger.ts new file mode 100644 index 0000000000..2af458ec47 --- /dev/null +++ b/apps/build-docs/src/swagger.ts @@ -0,0 +1,36 @@ +import { execSync } from "child_process"; +import { mkdirSync } from "fs"; +import { join } from "path"; + +import BuildContext from "./context"; + +interface BuildInfo { + specPath: string; + outDir: string; +} + +const DIR_PREFIX = "rest-api"; + +const buildInfos: BuildInfo[] = [ + { + // Paths are relative to Git root. + specPath: "apps/server/internal.openapi.yaml", + outDir: `${DIR_PREFIX}/internal` + }, + { + specPath: "apps/server/etapi.openapi.yaml", + outDir: `${DIR_PREFIX}/etapi` + } +]; + +export default function buildSwagger({ baseDir, gitRootDir }: BuildContext) { + for (const { specPath, outDir } of buildInfos) { + const absSpecPath = join(gitRootDir, specPath); + const targetDir = join(baseDir, outDir); + mkdirSync(targetDir, { recursive: true }); + execSync( + `pnpm redocly build-docs ${absSpecPath} -o ${targetDir}/index.html`, + { stdio: "inherit" } + ); + } +} diff --git a/apps/build-docs/tsconfig.app.json b/apps/build-docs/tsconfig.app.json new file mode 100644 index 0000000000..b9e17115a0 --- /dev/null +++ b/apps/build-docs/tsconfig.app.json @@ -0,0 +1,36 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "bundler", + "target": "ES2020", + "outDir": "dist", + "strict": false, + "types": [ + "node", + "express" + ], + "rootDir": "src", + "tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo" + }, + "include": [ + "src/**/*.ts", + "../server/src/*.d.ts" + ], + "exclude": [ + "eslint.config.js", + "eslint.config.cjs", + "eslint.config.mjs" + ], + "references": [ + { + "path": "../server/tsconfig.app.json" + }, + { + "path": "../desktop/tsconfig.app.json" + }, + { + "path": "../client/tsconfig.app.json" + } + ] +} diff --git a/apps/build-docs/tsconfig.json b/apps/build-docs/tsconfig.json new file mode 100644 index 0000000000..99c9b71b37 --- /dev/null +++ b/apps/build-docs/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.base.json", + "include": [ + "scripts/**/*.ts" + ], + "references": [ + { + "path": "../server" + }, + { + "path": "../client" + }, + { + "path": "./tsconfig.app.json" + } + ] +} diff --git a/apps/build-docs/typedoc.backend.json b/apps/build-docs/typedoc.backend.json new file mode 100644 index 0000000000..a7f91c42e4 --- /dev/null +++ b/apps/build-docs/typedoc.backend.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "name": "Trilium Backend API", + "entryPoints": [ + "src/backend_script_entrypoint.ts" + ], + "tsconfig": "tsconfig.app.json", + "plugin": [ + "typedoc-plugin-missing-exports" + ] +} diff --git a/apps/build-docs/typedoc.frontend.json b/apps/build-docs/typedoc.frontend.json new file mode 100644 index 0000000000..c462004712 --- /dev/null +++ b/apps/build-docs/typedoc.frontend.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "name": "Trilium Frontend API", + "entryPoints": [ + "src/frontend_script_entrypoint.ts" + ], + "tsconfig": "tsconfig.app.json", + "plugin": [ + "typedoc-plugin-missing-exports" + ] +} diff --git a/apps/client/.env b/apps/client/.env index 78b4a229b0..18a7bcf954 100644 --- a/apps/client/.env +++ b/apps/client/.env @@ -1,5 +1,4 @@ # The development license key for premium CKEditor features. # Note: This key must only be used for the Trilium Notes project. -# Expires on: 2025-09-13 -VITE_CKEDITOR_KEY=eyJhbGciOiJFUzI1NiJ9.eyJleHAiOjE3NTc3MjE1OTksImp0aSI6ImFiN2E0NjZmLWJlZGMtNDNiYy1iMzU4LTk0NGQ0YWJhY2I3ZiIsImRpc3RyaWJ1dGlvbkNoYW5uZWwiOlsic2giLCJkcnVwYWwiXSwid2hpdGVMYWJlbCI6dHJ1ZSwiZmVhdHVyZXMiOlsiRFJVUCIsIkNNVCIsIkRPIiwiRlAiLCJTQyIsIlRPQyIsIlRQTCIsIlBPRSIsIkNDIiwiTUYiLCJTRUUiLCJFQ0giLCJFSVMiXSwidmMiOiI1MzlkOWY5YyJ9.2rvKPql4hmukyXhEtWPZ8MLxKvzPIwzCdykO653g7IxRRZy2QJpeRszElZx9DakKYZKXekVRAwQKgHxwkgbE_w +VITE_CKEDITOR_KEY=eyJhbGciOiJFUzI1NiJ9.eyJleHAiOjE3ODcyNzA0MDAsImp0aSI6IjkyMWE1MWNlLTliNDMtNGRlMC1iOTQwLTc5ZjM2MDBkYjg1NyIsImRpc3RyaWJ1dGlvbkNoYW5uZWwiOiJ0cmlsaXVtIiwiZmVhdHVyZXMiOlsiVFJJTElVTSJdLCJ2YyI6ImU4YzRhMjBkIn0.hny77p-U4-jTkoqbwPytrEar5ylGCWBN7Ez3SlB8i6_mJCBIeCSTOlVQk_JMiOEq3AGykUMHzWXzjdMFwgniOw VITE_CKEDITOR_ENABLE_INSPECTOR=false \ No newline at end of file diff --git a/apps/client/eslint.config.mjs b/apps/client/eslint.config.mjs deleted file mode 100644 index 724052a2e2..0000000000 --- a/apps/client/eslint.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import baseConfig from "../../eslint.config.mjs"; - -export default [ - ...baseConfig -]; diff --git a/apps/client/index.html b/apps/client/index.html new file mode 100644 index 0000000000..12f653666f --- /dev/null +++ b/apps/client/index.html @@ -0,0 +1,30 @@ + + + + + + + + + + Trilium Notes + + + + + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/apps/client/package.json b/apps/client/package.json index 6e5c0d17fb..e24ba042a2 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -1,87 +1,95 @@ { "name": "@triliumnext/client", - "version": "0.97.1", + "version": "0.102.1", "description": "JQuery-based client for TriliumNext, used for both web and desktop (via Electron)", "private": true, "license": "AGPL-3.0-only", "author": { "name": "Trilium Notes Team", "email": "contact@eliandoran.me", - "url": "https://github.com/TriliumNext/Notes" + "url": "https://github.com/TriliumNext/Trilium" + }, + "scripts": { + "build": "cross-env NODE_OPTIONS=--max-old-space-size=4096 vite build", + "test": "vitest", + "coverage": "vitest --coverage", + "circular-deps": "dpdm -T src/**/*.ts --tree=false --warning=false --skip-dynamic-imports=circular" }, "dependencies": { - "@eslint/js": "9.32.0", "@excalidraw/excalidraw": "0.18.0", - "@fullcalendar/core": "6.1.18", - "@fullcalendar/daygrid": "6.1.18", - "@fullcalendar/interaction": "6.1.18", - "@fullcalendar/list": "6.1.18", - "@fullcalendar/multimonth": "6.1.18", - "@fullcalendar/timegrid": "6.1.18", + "@fullcalendar/core": "6.1.20", + "@fullcalendar/daygrid": "6.1.20", + "@fullcalendar/interaction": "6.1.20", + "@fullcalendar/list": "6.1.20", + "@fullcalendar/multimonth": "6.1.20", + "@fullcalendar/rrule": "6.1.20", + "@fullcalendar/timegrid": "6.1.20", "@maplibre/maplibre-gl-leaflet": "0.1.3", - "@mermaid-js/layout-elk": "0.1.8", - "@mind-elixir/node-menu": "5.0.0", + "@mermaid-js/layout-elk": "0.2.1", + "@mind-elixir/node-menu": "5.0.1", "@popperjs/core": "2.11.8", + "@preact/signals": "2.9.0", "@triliumnext/ckeditor5": "workspace:*", "@triliumnext/codemirror": "workspace:*", "@triliumnext/commons": "workspace:*", "@triliumnext/highlightjs": "workspace:*", "@triliumnext/share-theme": "workspace:*", + "@triliumnext/split.js": "workspace:*", + "@univerjs/preset-sheets-conditional-formatting": "0.19.0", + "@univerjs/preset-sheets-core": "0.19.0", + "@univerjs/preset-sheets-data-validation": "0.19.0", + "@univerjs/preset-sheets-filter": "0.19.0", + "@univerjs/preset-sheets-find-replace": "0.19.0", + "@univerjs/preset-sheets-note": "0.19.0", + "@univerjs/preset-sheets-sort": "0.19.0", + "@univerjs/presets": "0.19.0", + "@zumer/snapdom": "2.7.0", "autocomplete.js": "0.38.1", - "bootstrap": "5.3.7", + "bootstrap": "5.3.8", "boxicons": "2.1.4", - "dayjs": "1.11.13", - "dayjs-plugin-utc": "0.1.2", - "debounce": "2.2.0", + "clsx": "2.1.1", + "color": "5.0.3", + "debounce": "3.0.0", + "dompurify": "3.3.3", "draggabilly": "3.0.0", - "force-graph": "1.50.1", - "globals": "16.3.0", - "i18next": "25.3.2", + "force-graph": "1.51.2", + "globals": "17.4.0", + "i18next": "26.0.1", "i18next-http-backend": "3.0.2", - "jquery": "3.7.1", - "jquery-hotkeys": "0.2.2", + "jquery": "4.0.0", "jquery.fancytree": "2.38.5", "jsplumb": "2.15.6", - "katex": "0.16.22", - "knockout": "3.5.1", + "katex": "0.16.44", "leaflet": "1.9.4", "leaflet-gpx": "2.2.0", "mark.js": "8.11.1", - "marked": "16.1.1", - "mermaid": "11.9.0", - "mind-elixir": "5.0.4", + "marked": "17.0.5", + "mermaid": "11.13.0", + "mind-elixir": "5.10.0", "normalize.css": "8.0.1", - "panzoom": "9.4.3", - "preact": "10.27.0", - "split.js": "1.6.5", + "panzoom": "9.4.4", + "preact": "10.29.0", + "react-i18next": "17.0.1", + "react-window": "2.2.7", + "reveal.js": "6.0.0", + "rrule": "2.8.1", "svg-pan-zoom": "3.6.2", - "tabulator-tables": "6.3.1", + "tabulator-tables": "6.4.0", "vanilla-js-wheel-zoom": "9.0.4" }, "devDependencies": { "@ckeditor/ckeditor5-inspector": "5.0.0", + "@prefresh/vite": "2.4.12", "@types/bootstrap": "5.2.10", - "@types/jquery": "3.5.32", - "@types/leaflet": "1.9.20", - "@types/leaflet-gpx": "1.3.7", + "@types/jquery": "4.0.0", + "@types/leaflet": "1.9.21", + "@types/leaflet-gpx": "1.3.8", "@types/mark.js": "8.11.12", - "@types/tabulator-tables": "6.2.8", - "copy-webpack-plugin": "13.0.0", - "happy-dom": "18.0.1", + "@types/tabulator-tables": "6.3.1", + "copy-webpack-plugin": "14.0.0", + "happy-dom": "20.8.9", + "lightningcss": "1.32.0", "script-loader": "0.7.2", - "vite-plugin-static-copy": "3.1.1" - }, - "nx": { - "name": "client", - "targets": { - "serve": { - "dependsOn": [ - "^build" - ] - }, - "circular-deps": { - "command": "pnpx dpdm -T {projectRoot}/src/**/*.ts --tree=false --warning=false --skip-dynamic-imports=circular" - } - } + "vite-plugin-static-copy": "4.0.0" } -} \ No newline at end of file +} diff --git a/apps/client/src/assets/manifest.webmanifest b/apps/client/src/assets/manifest.webmanifest index b2cbca184c..1f8cb3b69a 100644 --- a/apps/client/src/assets/manifest.webmanifest +++ b/apps/client/src/assets/manifest.webmanifest @@ -7,6 +7,9 @@ "display": "standalone", "scope": "/", "start_url": "/", + "display_override": [ + "window-controls-overlay" + ], "icons": [ { "src": "icon.png", diff --git a/apps/client/src/components/app_context.ts b/apps/client/src/components/app_context.ts index 2944005bd2..d731f03382 100644 --- a/apps/client/src/components/app_context.ts +++ b/apps/client/src/components/app_context.ts @@ -1,45 +1,47 @@ -import froca from "../services/froca.js"; -import RootCommandExecutor from "./root_command_executor.js"; -import Entrypoints, { type SqlExecuteResults } from "./entrypoints.js"; -import options from "../services/options.js"; -import utils, { hasTouchBar } from "../services/utils.js"; -import zoomComponent from "./zoom.js"; -import TabManager from "./tab_manager.js"; -import Component from "./component.js"; -import keyboardActionsService from "../services/keyboard_actions.js"; -import linkService, { type ViewScope } from "../services/link.js"; -import MobileScreenSwitcherExecutor, { type Screen } from "./mobile_screen_switcher.js"; -import MainTreeExecutors from "./main_tree_executors.js"; -import toast from "../services/toast.js"; -import ShortcutComponent from "./shortcut_component.js"; -import { t, initLocale } from "../services/i18n.js"; -import type NoteDetailWidget from "../widgets/note_detail.js"; -import type { ResolveOptions } from "../widgets/dialogs/delete_notes.js"; -import type { PromptDialogOptions } from "../widgets/dialogs/prompt.js"; -import type { ConfirmWithMessageOptions, ConfirmWithTitleOptions } from "../widgets/dialogs/confirm.js"; -import type LoadResults from "../services/load_results.js"; -import type { Attribute } from "../services/attribute_parser.js"; -import type NoteTreeWidget from "../widgets/note_tree.js"; -import type { default as NoteContext, GetTextEditorCallback } from "./note_context.js"; -import type TypeWidget from "../widgets/type_widgets/type_widget.js"; -import type EditableTextTypeWidget from "../widgets/type_widgets/editable_text.js"; -import type { NativeImage, TouchBar } from "electron"; -import TouchBarComponent from "./touch_bar.js"; import type { CKTextEditor } from "@triliumnext/ckeditor5"; import type CodeMirror from "@triliumnext/codemirror"; -import { StartupChecks } from "./startup_checks.js"; -import type { CreateNoteOpts } from "../services/note_create.js"; +import { SqlExecuteResponse } from "@triliumnext/commons"; +import type { NativeImage, TouchBar } from "electron"; import { ColumnComponent } from "tabulator-tables"; +import type { Attribute } from "../services/attribute_parser.js"; +import froca from "../services/froca.js"; +import { initLocale, t } from "../services/i18n.js"; +import keyboardActionsService from "../services/keyboard_actions.js"; +import linkService, { type ViewScope } from "../services/link.js"; +import type LoadResults from "../services/load_results.js"; +import type { CreateNoteOpts } from "../services/note_create.js"; +import options from "../services/options.js"; +import toast from "../services/toast.js"; +import utils, { hasTouchBar } from "../services/utils.js"; +import { ReactWrappedWidget } from "../widgets/basic_widget.js"; +import type RootContainer from "../widgets/containers/root_container.js"; +import { AddLinkOpts } from "../widgets/dialogs/add_link.jsx"; +import type { ConfirmWithMessageOptions, ConfirmWithTitleOptions } from "../widgets/dialogs/confirm.js"; +import type { ResolveOptions } from "../widgets/dialogs/delete_notes.js"; +import { IncludeNoteOpts } from "../widgets/dialogs/include_note.jsx"; +import type { InfoProps } from "../widgets/dialogs/info.jsx"; +import type { MarkdownImportOpts } from "../widgets/dialogs/markdown_import.jsx"; +import { ChooseNoteTypeCallback } from "../widgets/dialogs/note_type_chooser.jsx"; +import type { PromptDialogOptions } from "../widgets/dialogs/prompt.js"; +import type NoteTreeWidget from "../widgets/note_tree.js"; +import Component from "./component.js"; +import Entrypoints from "./entrypoints.js"; +import MainTreeExecutors from "./main_tree_executors.js"; +import MobileScreenSwitcherExecutor, { type Screen } from "./mobile_screen_switcher.js"; +import type { default as NoteContext, GetTextEditorCallback } from "./note_context.js"; +import RootCommandExecutor from "./root_command_executor.js"; +import ShortcutComponent from "./shortcut_component.js"; +import { StartupChecks } from "./startup_checks.js"; +import TabManager from "./tab_manager.js"; +import TouchBarComponent from "./touch_bar.js"; +import zoomComponent from "./zoom.js"; + interface Layout { - getRootWidget: (appContext: AppContext) => RootWidget; + getRootWidget: (appContext: AppContext) => RootContainer; } -interface RootWidget extends Component { - render: () => JQuery; -} - -interface BeforeUploadListener extends Component { +export interface BeforeUploadListener extends Component { beforeUnloadEvent(): boolean; } @@ -84,7 +86,6 @@ export type CommandMappings = { focusTree: CommandData; focusOnTitle: CommandData; focusOnDetail: CommandData; - focusOnSearchDefinition: Required; searchNotes: CommandData & { searchString?: string; ancestorNoteId?: string | null; @@ -92,9 +93,14 @@ export type CommandMappings = { closeTocCommand: CommandData; closeHlt: CommandData; showLaunchBarSubtree: CommandData; - showRevisions: CommandData; - showLlmChat: CommandData; - createAiChat: CommandData; + showHiddenSubtree: CommandData; + showSQLConsoleHistory: CommandData; + logout: CommandData; + switchToMobileVersion: CommandData; + switchToDesktopVersion: CommandData; + showRevisions: CommandData & { + noteId?: string | null; + }; showOptions: CommandData & { section: string; }; @@ -111,14 +117,14 @@ export type CommandMappings = { openedFileUpdated: CommandData & { entityType: string; entityId: string; - lastModifiedMs: number; + lastModifiedMs?: number; filePath: string; }; focusAndSelectTitle: CommandData & { isNewNote?: boolean; }; showPromptDialog: PromptDialogOptions; - showInfoDialog: ConfirmWithMessageOptions; + showInfoDialog: InfoProps; showConfirmDialog: ConfirmWithMessageOptions; showRecentChanges: CommandData & { ancestorNoteId: string }; showImportDialog: CommandData & { noteId: string }; @@ -135,6 +141,7 @@ export type CommandMappings = { showLeftPane: CommandData; showAttachments: CommandData; showSearchHistory: CommandData; + showShareSubtree: CommandData; hoistNote: CommandData & { noteId: string }; leaveProtectedSession: CommandData; enterProtectedSession: CommandData; @@ -145,6 +152,7 @@ export type CommandMappings = { }; openInTab: ContextMenuCommandData; openNoteInSplit: ContextMenuCommandData; + openNoteInWindow: ContextMenuCommandData; openNoteInPopup: ContextMenuCommandData; toggleNoteHoisting: ContextMenuCommandData; insertNoteAfter: ContextMenuCommandData; @@ -193,7 +201,7 @@ export type CommandMappings = { resetLauncher: ContextMenuCommandData; executeInActiveNoteDetailWidget: CommandData & { - callback: (value: NoteDetailWidget | PromiseLike) => void; + callback: (value: ReactWrappedWidget) => void; }; executeWithTextEditor: CommandData & ExecuteCommandData & { @@ -205,19 +213,19 @@ export type CommandMappings = { * Generally should not be invoked manually, as it is used by {@link NoteContext.getContentElement}. */ executeWithContentElement: CommandData & ExecuteCommandData>; - executeWithTypeWidget: CommandData & ExecuteCommandData; + executeWithTypeWidget: CommandData & ExecuteCommandData; addTextToActiveEditor: CommandData & { text: string; }; /** Works only in the electron context menu. */ replaceMisspelling: CommandData; - importMarkdownInline: CommandData; showPasswordNotSet: CommandData; showProtectedSessionPasswordDialog: CommandData; showUploadAttachmentsDialog: CommandData & { noteId: string }; - showIncludeNoteDialog: CommandData & { textTypeWidget: EditableTextTypeWidget }; - showAddLinkDialog: CommandData & { textTypeWidget: EditableTextTypeWidget, text: string }; + showIncludeNoteDialog: CommandData & IncludeNoteOpts; + showAddLinkDialog: CommandData & AddLinkOpts; + showPasteMarkdownDialog: CommandData & MarkdownImportOpts; closeProtectedSessionPasswordDialog: CommandData; copyImageReferenceToClipboard: CommandData; copyImageToClipboard: CommandData; @@ -257,15 +265,85 @@ export type CommandMappings = { reEvaluateRightPaneVisibility: CommandData; runActiveNote: CommandData; - scrollContainerToCommand: CommandData & { + scrollContainerTo: CommandData & { position: number; }; scrollToEnd: CommandData; closeThisNoteSplit: CommandData; moveThisNoteSplit: CommandData & { isMovingLeft: boolean }; jumpToNote: CommandData; + openTodayNote: CommandData; commandPalette: CommandData; + // Keyboard shortcuts + backInNoteHistory: CommandData; + forwardInNoteHistory: CommandData; + forceSaveRevision: CommandData; + scrollToActiveNote: CommandData; + quickSearch: CommandData; + collapseTree: CommandData; + createNoteAfter: CommandData; + createNoteInto: CommandData; + addNoteAboveToSelection: CommandData; + addNoteBelowToSelection: CommandData; + openNewTab: CommandData; + activateNextTab: CommandData; + activatePreviousTab: CommandData; + openNewWindow: CommandData; + toggleTray: CommandData; + firstTab: CommandData; + secondTab: CommandData; + thirdTab: CommandData; + fourthTab: CommandData; + fifthTab: CommandData; + sixthTab: CommandData; + seventhTab: CommandData; + eigthTab: CommandData; + ninthTab: CommandData; + lastTab: CommandData; + showNoteSource: CommandData; + showNoteOCRText: CommandData; + showSQLConsole: CommandData; + showBackendLog: CommandData; + showCheatsheet: CommandData; + showHelp: CommandData; + addLinkToText: CommandData; + followLinkUnderCursor: CommandData; + insertDateTimeToText: CommandData; + pasteMarkdownIntoText: CommandData; + cutIntoNote: CommandData; + addIncludeNoteToText: CommandData; + editReadOnlyNote: CommandData; + toggleRibbonTabClassicEditor: CommandData; + toggleRibbonTabBasicProperties: CommandData; + toggleRibbonTabBookProperties: CommandData; + toggleRibbonTabFileProperties: CommandData; + toggleRibbonTabImageProperties: CommandData; + toggleRibbonTabOwnedAttributes: CommandData; + toggleRibbonTabInheritedAttributes: CommandData; + toggleRibbonTabPromotedAttributes: CommandData; + toggleRibbonTabNoteMap: CommandData; + toggleRibbonTabNoteInfo: CommandData; + toggleRibbonTabNotePaths: CommandData; + toggleRibbonTabSimilarNotes: CommandData; + toggleRightPane: CommandData; + printActiveNote: CommandData; + exportAsPdf: CommandData; + openNoteExternally: CommandData; + openNoteCustom: CommandData; + openNoteOnServer: CommandData; + renderActiveNote: CommandData; + unhoist: CommandData; + reloadFrontendApp: CommandData; + openDevTools: CommandData; + findInText: CommandData; + toggleLeftPane: CommandData; + toggleFullscreen: CommandData; + zoomOut: CommandData; + zoomIn: CommandData; + zoomReset: CommandData; + copyWithoutFormatting: CommandData; + // Geomap deleteFromMap: { noteId: string }; @@ -302,6 +380,10 @@ export type CommandMappings = { }; refreshTouchBar: CommandData; reloadTextEditor: CommandData; + chooseNoteType: CommandData & { + callback: ChooseNoteTypeCallback + }; + customDownload: CommandData; }; type EventMappings = { @@ -327,7 +409,7 @@ type EventMappings = { addNewLabel: CommandData; addNewRelation: CommandData; sqlQueryResults: CommandData & { - results: SqlExecuteResults; + response: SqlExecuteResponse; }; readOnlyTemporarilyDisabled: { noteContext: NoteContext; @@ -366,6 +448,8 @@ type EventMappings = { error: string; }; searchRefreshed: { ntxId?: string | null }; + textEditorRefreshed: { ntxId?: string | null, editor: CKTextEditor }; + contentElRefreshed: { ntxId?: string | null, contentEl: HTMLElement }; hoistedNoteChanged: { noteId: string; ntxId: string | null; @@ -390,6 +474,11 @@ type EventMappings = { noteContextRemoved: { ntxIds: string[]; }; + contextDataChanged: { + noteContext: NoteContext; + key: string; + value: unknown; + }; exportSvg: { ntxId: string | null | undefined; }; exportPng: { ntxId: string | null | undefined; }; geoMapCreateChildNote: { @@ -407,14 +496,9 @@ type EventMappings = { relationMapResetPanZoom: { ntxId: string | null | undefined }; relationMapResetZoomIn: { ntxId: string | null | undefined }; relationMapResetZoomOut: { ntxId: string | null | undefined }; - activeNoteChanged: {}; - showAddLinkDialog: { - textTypeWidget: EditableTextTypeWidget; - text: string; - }; - showIncludeDialog: { - textTypeWidget: EditableTextTypeWidget; - }; + activeNoteChanged: {ntxId: string | null | undefined}; + showAddLinkDialog: AddLinkOpts; + showIncludeDialog: IncludeNoteOpts; openBulkActionsDialog: { selectedOrActiveNoteIds: string[]; }; @@ -422,6 +506,10 @@ type EventMappings = { noteIds: string[]; }; refreshData: { ntxId: string | null | undefined }; + contentSafeMarginChanged: { + top: number; + noteContext: NoteContext; + }; }; export type EventListener = { @@ -454,7 +542,7 @@ export type FilteredCommandNames = keyof Pick[]; + beforeUnloadListeners: (WeakRef | (() => boolean))[]; tabManager!: TabManager; layout?: Layout; noteTreeWidget?: NoteTreeWidget; @@ -547,7 +635,7 @@ export class AppContext extends Component { component.triggerCommand(commandName, { $el: $(this) }); }); - this.child(rootWidget); + this.child(rootWidget as Component); this.triggerEvent("initialRenderComplete", {}); } @@ -574,16 +662,24 @@ export class AppContext extends Component { } getComponentByEl(el: HTMLElement) { - return $(el).closest(".component").prop("component"); + return $(el).closest("[data-component-id]").prop("component"); } - addBeforeUnloadListener(obj: BeforeUploadListener) { + addBeforeUnloadListener(obj: BeforeUploadListener | (() => boolean)) { if (typeof WeakRef !== "function") { // older browsers don't support WeakRef return; } - this.beforeUnloadListeners.push(new WeakRef(obj)); + if (typeof obj === "object") { + this.beforeUnloadListeners.push(new WeakRef(obj)); + } else { + this.beforeUnloadListeners.push(obj); + } + } + + removeBeforeUnloadListener(listener: (() => boolean)) { + this.beforeUnloadListeners = this.beforeUnloadListeners.filter(l => l !== listener); } } @@ -593,30 +689,32 @@ const appContext = new AppContext(window.glob.isMainWindow); $(window).on("beforeunload", () => { let allSaved = true; - appContext.beforeUnloadListeners = appContext.beforeUnloadListeners.filter((wr) => !!wr.deref()); + appContext.beforeUnloadListeners = appContext.beforeUnloadListeners.filter((wr) => typeof wr === "function" || !!wr.deref()); - for (const weakRef of appContext.beforeUnloadListeners) { - const component = weakRef.deref(); + for (const listener of appContext.beforeUnloadListeners) { + if (typeof listener === "object") { + const component = listener.deref(); - if (!component) { - continue; - } - - if (!component.beforeUnloadEvent()) { - console.log(`Component ${component.componentId} is not finished saving its state.`); - - toast.showMessage(t("app_context.please_wait_for_save"), 10000); + if (!component) { + continue; + } + if (!component.beforeUnloadEvent()) { + console.log(`Component ${component.componentId} is not finished saving its state.`); + allSaved = false; + } + } else if (!listener()) { allSaved = false; } } if (!allSaved) { + toast.showMessage(t("app_context.please_wait_for_save"), 10000); return "some string"; } }); -$(window).on("hashchange", function () { +$(window).on("hashchange", () => { const { notePath, ntxId, viewScope, searchString } = linkService.parseNavigationStateFromUrl(window.location.href); if (notePath || ntxId) { diff --git a/apps/client/src/components/component.ts b/apps/client/src/components/component.ts index 8686a7bb96..1538aff76d 100644 --- a/apps/client/src/components/component.ts +++ b/apps/client/src/components/component.ts @@ -1,6 +1,8 @@ import utils from "../services/utils.js"; import type { CommandMappings, CommandNames, EventData, EventNames } from "./app_context.js"; +type EventHandler = ((data: any) => void); + /** * Abstract class for all components in the Trilium's frontend. * @@ -19,6 +21,7 @@ export class TypedComponent> { initialized: Promise | null; parent?: TypedComponent; _position!: number; + private listeners: Record | null = {}; constructor() { this.componentId = `${this.sanitizedClassName}-${utils.randomString(8)}`; @@ -54,6 +57,18 @@ export class TypedComponent> { return this; } + /** + * Removes a child component from this component's children array. + * This is used for cleanup when a widget is unmounted to prevent event listener accumulation. + */ + removeChild(component: ChildT) { + const index = this.children.indexOf(component); + if (index !== -1) { + this.children.splice(index, 1); + component.parent = undefined; + } + } + handleEvent(name: T, data: EventData): Promise | null | undefined { try { const callMethodPromise = this.initialized ? this.initialized.then(() => this.callMethod((this as any)[`${name}Event`], data)) : this.callMethod((this as any)[`${name}Event`], data); @@ -62,8 +77,8 @@ export class TypedComponent> { // don't create promises if not needed (optimization) return callMethodPromise && childrenPromise ? Promise.all([callMethodPromise, childrenPromise]) : callMethodPromise || childrenPromise; - } catch (e: any) { - console.error(`Handling of event '${name}' failed in ${this.constructor.name} with error ${e.message} ${e.stack}`); + } catch (e: unknown) { + console.error(`Handling of event '${name}' failed in ${this.constructor.name} with error`, e); return null; } @@ -76,6 +91,14 @@ export class TypedComponent> { handleEventInChildren(name: T, data: EventData): Promise | null { const promises: Promise[] = []; + // Handle React children. + if (this.listeners?.[name]) { + for (const listener of this.listeners[name]) { + listener(data); + } + } + + // Handle legacy children. for (const child of this.children) { const ret = child.handleEvent(name, data) as Promise; @@ -120,6 +143,35 @@ export class TypedComponent> { return promise; } + + registerHandler(name: T, handler: EventHandler) { + if (!this.listeners) { + this.listeners = {}; + } + + if (!this.listeners[name]) { + this.listeners[name] = []; + } + + if (this.listeners[name].includes(handler)) { + return; + } + + this.listeners[name].push(handler); + } + + removeHandler(name: T, handler: EventHandler) { + if (!this.listeners?.[name]?.includes(handler)) { + return; + } + + this.listeners[name] = this.listeners[name] + .filter(listener => listener !== handler); + + if (!this.listeners[name].length) { + delete this.listeners[name]; + } + } } export default class Component extends TypedComponent {} diff --git a/apps/client/src/components/entrypoints.ts b/apps/client/src/components/entrypoints.ts index fd81879a72..8fc4e1b3d5 100644 --- a/apps/client/src/components/entrypoints.ts +++ b/apps/client/src/components/entrypoints.ts @@ -1,47 +1,26 @@ -import utils from "../services/utils.js"; +import { CreateChildrenResponse, SqlExecuteResponse } from "@triliumnext/commons"; + +import bundleService from "../services/bundle.js"; import dateNoteService from "../services/date_notes.js"; +import froca from "../services/froca.js"; +import { t } from "../services/i18n.js"; +import linkService from "../services/link.js"; import protectedSessionHolder from "../services/protected_session_holder.js"; import server from "../services/server.js"; +import toastService from "../services/toast.js"; +import utils from "../services/utils.js"; +import ws from "../services/ws.js"; import appContext, { type NoteCommandData } from "./app_context.js"; import Component from "./component.js"; -import toastService from "../services/toast.js"; -import ws from "../services/ws.js"; -import bundleService from "../services/bundle.js"; -import froca from "../services/froca.js"; -import linkService from "../services/link.js"; -import { t } from "../services/i18n.js"; -import type FNote from "../entities/fnote.js"; - -// TODO: Move somewhere else nicer. -export type SqlExecuteResults = string[][][]; - -// TODO: Deduplicate with server. -interface SqlExecuteResponse { - success: boolean; - error?: string; - results: SqlExecuteResults; -} - -// TODO: Deduplicate with server. -interface CreateChildrenResponse { - note: FNote; -} export default class Entrypoints extends Component { constructor() { super(); - - if (jQuery.hotkeys) { - // hot keys are active also inside inputs and content editables - jQuery.hotkeys.options.filterInputAcceptingElements = false; - jQuery.hotkeys.options.filterContentEditable = false; - jQuery.hotkeys.options.filterTextInputs = false; - } } openDevToolsCommand() { if (utils.isElectron()) { - utils.dynamicRequire("@electron/remote").getCurrentWindow().toggleDevTools(); + utils.dynamicRequire("@electron/remote").getCurrentWindow().webContents.toggleDevTools(); } } @@ -131,7 +110,7 @@ export default class Entrypoints extends Component { if (utils.isElectron()) { // standard JS version does not work completely correctly in electron const webContents = utils.dynamicRequire("@electron/remote").getCurrentWebContents(); - const activeIndex = parseInt(webContents.navigationHistory.getActiveIndex()); + const activeIndex = webContents.navigationHistory.getActiveIndex(); webContents.goToIndex(activeIndex - 1); } else { @@ -143,7 +122,7 @@ export default class Entrypoints extends Component { if (utils.isElectron()) { // standard JS version does not work completely correctly in electron const webContents = utils.dynamicRequire("@electron/remote").getCurrentWebContents(); - const activeIndex = parseInt(webContents.navigationHistory.getActiveIndex()); + const activeIndex = webContents.navigationHistory.getActiveIndex(); webContents.goToIndex(activeIndex + 1); } else { @@ -181,6 +160,16 @@ export default class Entrypoints extends Component { this.openInWindowCommand({ notePath: "", hoistedNoteId: "root" }); } + async openTodayNoteCommand() { + const todayNote = await dateNoteService.getTodayNote(); + if (!todayNote) { + console.warn("Missing today note."); + return; + } + + await appContext.tabManager.openInSameTab(todayNote.noteId); + } + async runActiveNoteCommand() { const noteContext = appContext.tabManager.getActiveContext(); if (!noteContext) { @@ -199,13 +188,8 @@ export default class Entrypoints extends Component { } else if (note.mime.endsWith("env=backend")) { await server.post(`script/run/${note.noteId}`); } else if (note.mime === "text/x-sqlite;schema=trilium") { - const resp = await server.post(`sql/execute/${note.noteId}`); - - if (!resp.success) { - toastService.showError(t("entrypoints.sql-error", { message: resp.error })); - } - - await appContext.triggerEvent("sqlQueryResults", { ntxId: ntxId, results: resp.results }); + const response = await server.post(`sql/execute/${note.noteId}`); + await appContext.triggerEvent("sqlQueryResults", { ntxId, response }); } toastService.showMessage(t("entrypoints.note-executed")); diff --git a/apps/client/src/components/note_context.ts b/apps/client/src/components/note_context.ts index 1bc4e5498e..3ca6a2a792 100644 --- a/apps/client/src/components/note_context.ts +++ b/apps/client/src/components/note_context.ts @@ -1,18 +1,20 @@ -import protectedSessionHolder from "../services/protected_session_holder.js"; -import server from "../services/server.js"; -import utils from "../services/utils.js"; -import appContext, { type EventData, type EventListener } from "./app_context.js"; -import treeService from "../services/tree.js"; -import Component from "./component.js"; -import froca from "../services/froca.js"; -import hoistedNoteService from "../services/hoisted_note.js"; -import options from "../services/options.js"; -import type { ViewScope } from "../services/link.js"; -import type FNote from "../entities/fnote.js"; -import type TypeWidget from "../widgets/type_widgets/type_widget.js"; import type { CKTextEditor } from "@triliumnext/ckeditor5"; import type CodeMirror from "@triliumnext/codemirror"; + +import type FNote from "../entities/fnote.js"; import { closeActiveDialog } from "../services/dialog.js"; +import froca from "../services/froca.js"; +import hoistedNoteService from "../services/hoisted_note.js"; +import type { ViewScope } from "../services/link.js"; +import options from "../services/options.js"; +import protectedSessionHolder from "../services/protected_session_holder.js"; +import server from "../services/server.js"; +import treeService from "../services/tree.js"; +import utils from "../services/utils.js"; +import { ReactWrappedWidget } from "../widgets/basic_widget.js"; +import type { HeadingContext } from "../widgets/sidebar/TableOfContents.js"; +import appContext, { type EventData, type EventListener } from "./app_context.js"; +import Component from "./component.js"; export interface SetNoteOpts { triggerSwitchEvent?: unknown; @@ -21,6 +23,31 @@ export interface SetNoteOpts { export type GetTextEditorCallback = (editor: CKTextEditor) => void; +export type SaveState = "saved" | "saving" | "unsaved" | "error"; + +export interface NoteContextDataMap { + toc: HeadingContext; + pdfPages: { + totalPages: number; + currentPage: number; + scrollToPage(page: number): void; + requestThumbnail(page: number): void; + }; + pdfAttachments: { + attachments: PdfAttachment[]; + downloadAttachment(filename: string): void; + }; + pdfLayers: { + layers: PdfLayer[]; + toggleLayer(layerId: string, visible: boolean): void; + }; + saveState: { + state: SaveState; + }; +} + +type ContextDataKey = keyof NoteContextDataMap; + class NoteContext extends Component implements EventListener<"entitiesReloaded"> { ntxId: string | null; hoistedNoteId: string; @@ -31,6 +58,13 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded"> parentNoteId?: string | null; viewScope?: ViewScope; + /** + * Metadata storage for UI components (e.g., table of contents, PDF page list, code outline). + * This allows type widgets to publish data that sidebar/toolbar components can consume. + * Data is automatically cleared when navigating to a different note. + */ + private contextData: Map = new Map(); + constructor(ntxId: string | null = null, hoistedNoteId: string = "root", mainNtxId: string | null = null) { super(); @@ -90,6 +124,22 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded"> this.viewScope = opts.viewScope; ({ noteId: this.noteId, parentNoteId: this.parentNoteId } = treeService.getNoteIdAndParentIdFromUrl(resolvedNotePath)); + // Clear context data when switching notes and notify subscribers + const oldKeys = Array.from(this.contextData.keys()); + this.contextData.clear(); + if (oldKeys.length > 0) { + // Notify subscribers asynchronously to avoid blocking navigation + window.setTimeout(() => { + for (const key of oldKeys) { + this.triggerEvent("contextDataChanged", { + noteContext: this, + key, + value: undefined + }); + } + }, 0); + } + this.saveToRecentNotes(resolvedNotePath); protectedSessionHolder.touchProtectedSessionIfNecessary(this.note); @@ -321,14 +371,24 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded"> return false; } + if (note.type === "search") { + return false; + } + if (!["default", "contextual-help"].includes(this.viewScope?.viewMode ?? "")) { return false; } // Collections must always display a note list, even if no children. - const viewType = note.getLabelValue("viewType") ?? "grid"; - if (!["list", "grid"].includes(viewType)) { - return true; + if (note.type === "book") { + if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) { + return false; + } + + const viewType = note.getLabelValue("viewType") ?? "grid"; + if (!["list", "grid"].includes(viewType)) { + return true; + } } if (!note.hasChildren()) { @@ -383,7 +443,7 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded"> * If no content could be determined `null` is returned instead. */ async getContentElement() { - return this.timeout>( + return this.timeout | null>( new Promise((resolve) => appContext.triggerCommand("executeWithContentElement", { resolve, @@ -395,7 +455,7 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded"> async getTypeWidget() { return this.timeout( - new Promise((resolve) => + new Promise((resolve) => appContext.triggerCommand("executeWithTypeWidget", { resolve, ntxId: this.ntxId @@ -436,6 +496,70 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded"> return title; } + + /** + * Set metadata for this note context (e.g., table of contents, PDF pages, code outline). + * This data can be consumed by sidebar/toolbar components. + * + * @param key - Unique identifier for the data type (e.g., "toc", "pdfPages", "codeOutline") + * @param value - The data to store (will be cleared when switching notes) + */ + setContextData(key: K, value: NoteContextDataMap[K]): void { + this.contextData.set(key, value); + // Trigger event so subscribers can react + this.triggerEvent("contextDataChanged", { + noteContext: this, + key, + value + }); + } + + /** + * Get metadata for this note context. + * + * @param key - The data key to retrieve + * @returns The stored data, or undefined if not found + */ + getContextData(key: K): NoteContextDataMap[K] | undefined { + return this.contextData.get(key) as NoteContextDataMap[K] | undefined; + } + + /** + * Check if context data exists for a given key. + */ + hasContextData(key: ContextDataKey): boolean { + return this.contextData.has(key); + } + + /** + * Clear specific context data. + */ + clearContextData(key: ContextDataKey): void { + this.contextData.delete(key); + this.triggerEvent("contextDataChanged", { + noteContext: this, + key, + value: undefined + }); + } +} + +export function openInCurrentNoteContext(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent | React.PointerEvent | null, notePath: string, viewScope?: ViewScope) { + const ntxId = $(evt?.target as Element) + .closest("[data-ntx-id]") + .attr("data-ntx-id"); + + const noteContext = ntxId ? appContext.tabManager.getNoteContextById(ntxId) : appContext.tabManager.getActiveContext(); + + if (noteContext) { + noteContext.setNote(notePath, { viewScope }).then(() => { + if (noteContext !== appContext.tabManager.getActiveContext()) { + appContext.tabManager.activateNoteContext(noteContext.ntxId); + } + }); + } else { + appContext.tabManager.openContextWithNote(notePath, { viewScope, activate: true }); + } } export default NoteContext; diff --git a/apps/client/src/components/root_command_executor.ts b/apps/client/src/components/root_command_executor.ts index 70d875563d..4560eafce6 100644 --- a/apps/client/src/components/root_command_executor.ts +++ b/apps/client/src/components/root_command_executor.ts @@ -1,15 +1,12 @@ -import Component from "./component.js"; -import appContext, { type CommandData, type CommandListenerData } from "./app_context.js"; import dateNoteService from "../services/date_notes.js"; -import treeService from "../services/tree.js"; -import openService from "../services/open.js"; -import protectedSessionService from "../services/protected_session.js"; -import options from "../services/options.js"; import froca from "../services/froca.js"; -import utils from "../services/utils.js"; -import LlmChatPanel from "../widgets/llm_chat_panel.js"; -import toastService from "../services/toast.js"; -import noteCreateService from "../services/note_create.js"; +import openService from "../services/open.js"; +import options from "../services/options.js"; +import protectedSessionService from "../services/protected_session.js"; +import treeService from "../services/tree.js"; +import utils, { openInReusableSplit } from "../services/utils.js"; +import appContext, { type CommandListenerData } from "./app_context.js"; +import Component from "./component.js"; export default class RootCommandExecutor extends Component { editReadOnlyNoteCommand() { @@ -43,8 +40,6 @@ export default class RootCommandExecutor extends Component { const noteContext = await appContext.tabManager.openTabWithNoteWithHoisting(searchNote.noteId, { activate: true }); - - appContext.triggerCommand("focusOnSearchDefinition", { ntxId: noteContext.ntxId }); } async searchInSubtreeCommand({ notePath }: CommandListenerData<"searchInSubtree">) { @@ -69,6 +64,13 @@ export default class RootCommandExecutor extends Component { } } + openNoteOnServerCommand() { + const noteId = appContext.tabManager.getActiveContextNoteId(); + if (noteId) { + openService.openNoteOnServer(noteId); + } + } + enterProtectedSessionCommand() { protectedSessionService.enterProtectedSession(); } @@ -186,7 +188,8 @@ export default class RootCommandExecutor extends Component { } toggleTrayCommand() { - if (!utils.isElectron()) return; + if (!utils.isElectron() || options.is("disableTray")) return; + const { BrowserWindow } = utils.dynamicRequire("@electron/remote"); const windows = BrowserWindow.getAllWindows() as Electron.BaseWindow[]; const isVisible = windows.every((w) => w.isVisible()); @@ -201,6 +204,19 @@ export default class RootCommandExecutor extends Component { appContext.triggerEvent("zenModeChanged", { isEnabled }); } + async toggleRibbonTabNoteMapCommand(data: CommandListenerData<"toggleRibbonTabNoteMap">) { + const { isExperimentalFeatureEnabled } = await import("../services/experimental_features.js"); + const isNewLayout = isExperimentalFeatureEnabled("new-layout"); + if (!isNewLayout) { + this.triggerEvent("toggleRibbonTabNoteMap", data); + return; + } + + const activeContext = appContext.tabManager.getActiveContext(); + if (!activeContext?.notePath) return; + openInReusableSplit(activeContext.notePath, "note-map"); + } + firstTabCommand() { this.#goToTab(1); } @@ -243,34 +259,4 @@ export default class RootCommandExecutor extends Component { } } - async createAiChatCommand() { - try { - // Create a new AI Chat note at the root level - const rootNoteId = "root"; - - const result = await noteCreateService.createNote(rootNoteId, { - title: "New AI Chat", - type: "aiChat", - content: JSON.stringify({ - messages: [], - title: "New AI Chat" - }) - }); - - if (!result.note) { - toastService.showError("Failed to create AI Chat note"); - return; - } - - await appContext.tabManager.openTabWithNoteWithHoisting(result.note.noteId, { - activate: true - }); - - toastService.showMessage("Created new AI Chat note"); - } - catch (e) { - console.error("Error creating AI Chat note:", e); - toastService.showError("Failed to create AI Chat note: " + (e as Error).message); - } - } } diff --git a/apps/client/src/components/tab_manager.ts b/apps/client/src/components/tab_manager.ts index 0416071c6a..3cf06a7793 100644 --- a/apps/client/src/components/tab_manager.ts +++ b/apps/client/src/components/tab_manager.ts @@ -165,7 +165,7 @@ export default class TabManager extends Component { const activeNoteContext = this.getActiveContext(); this.updateDocumentTitle(activeNoteContext); - this.triggerEvent("activeNoteChanged", {}); // trigger this even in on popstate event + this.triggerEvent("activeNoteChanged", {ntxId:activeNoteContext?.ntxId}); // trigger this even in on popstate event } calculateHash(): string { @@ -265,6 +265,7 @@ export default class TabManager extends Component { mainNtxId: string | null = null ): Promise { const noteContext = new NoteContext(ntxId, hoistedNoteId, mainNtxId); + noteContext.setEmpty(); const existingNoteContext = this.children.find((nc) => nc.ntxId === noteContext.ntxId); @@ -433,6 +434,9 @@ export default class TabManager extends Component { $autocompleteEl.autocomplete("close"); } + // close dangling tooltips + $("body > div.tooltip").remove(); + const noteContextsToRemove = noteContextToRemove.getSubContexts(); const ntxIdsToRemove = noteContextsToRemove.map((nc) => nc.ntxId); @@ -600,18 +604,18 @@ export default class TabManager extends Component { } async moveTabToNewWindowCommand({ ntxId }: { ntxId: string }) { - const { notePath, hoistedNoteId } = this.getNoteContextById(ntxId); + const { notePath, hoistedNoteId, viewScope } = this.getNoteContextById(ntxId); const removed = await this.removeNoteContext(ntxId); if (removed) { - this.triggerCommand("openInWindow", { notePath, hoistedNoteId }); + this.triggerCommand("openInWindow", { notePath, hoistedNoteId, viewScope }); } } async copyTabToNewWindowCommand({ ntxId }: { ntxId: string }) { - const { notePath, hoistedNoteId } = this.getNoteContextById(ntxId); - this.triggerCommand("openInWindow", { notePath, hoistedNoteId }); + const { notePath, hoistedNoteId, viewScope } = this.getNoteContextById(ntxId); + this.triggerCommand("openInWindow", { notePath, hoistedNoteId, viewScope }); } async reopenLastTabCommand() { @@ -643,7 +647,32 @@ export default class TabManager extends Component { ...this.noteContexts.slice(-noteContexts.length), ...this.noteContexts.slice(lastClosedTab.position, -noteContexts.length) ]; - this.noteContextReorderEvent({ ntxIdsInOrder: ntxsInOrder.map((nc) => nc.ntxId).filter((id) => id !== null) }); + + // Update mainNtxId if the restored pane is the main pane in the split pane + const { oldMainNtxId, newMainNtxId } = (() => { + if (noteContexts.length !== 1) { + return { oldMainNtxId: undefined, newMainNtxId: undefined }; + } + + const mainNtxId = noteContexts[0]?.mainNtxId; + const index = this.noteContexts.findIndex(c => c.ntxId === mainNtxId); + + // No need to update if the restored position is after mainNtxId + if (index === -1 || lastClosedTab.position > index) { + return { oldMainNtxId: undefined, newMainNtxId: undefined }; + } + + return { + oldMainNtxId: this.noteContexts[index].ntxId ?? undefined, + newMainNtxId: noteContexts[0]?.ntxId ?? undefined + }; + })(); + + this.triggerCommand("noteContextReorder", { + ntxIdsInOrder: ntxsInOrder.map((nc) => nc.ntxId).filter((id) => id !== null), + oldMainNtxId, + newMainNtxId + }); let mainNtx = noteContexts.find((nc) => nc.isMainContext()); if (mainNtx) { diff --git a/apps/client/src/components/touch_bar.ts b/apps/client/src/components/touch_bar.ts index 7bf10d7f12..226318a927 100644 --- a/apps/client/src/components/touch_bar.ts +++ b/apps/client/src/components/touch_bar.ts @@ -23,11 +23,11 @@ export default class TouchBarComponent extends Component { this.$widget = $("
"); $(window).on("focusin", async (e) => { - const $target = $(e.target); + const focusedEl = e.target as unknown as HTMLElement; + const $target = $(focusedEl); this.$activeModal = $target.closest(".modal-dialog"); - const parentComponentEl = $target.closest(".component"); - this.lastFocusedComponent = appContext.getComponentByEl(parentComponentEl[0]); + this.lastFocusedComponent = appContext.getComponentByEl(focusedEl); this.#refreshTouchBar(); }); } diff --git a/apps/client/src/desktop.ts b/apps/client/src/desktop.ts index 65e2e285a4..6f22d3fc7b 100644 --- a/apps/client/src/desktop.ts +++ b/apps/client/src/desktop.ts @@ -1,20 +1,18 @@ -import appContext from "./components/app_context.js"; -import utils from "./services/utils.js"; -import noteTooltipService from "./services/note_tooltip.js"; -import bundleService from "./services/bundle.js"; -import toastService from "./services/toast.js"; -import noteAutocompleteService from "./services/note_autocomplete.js"; -import electronContextMenu from "./menus/electron_context_menu.js"; -import glob from "./services/glob.js"; -import { t } from "./services/i18n.js"; -import options from "./services/options.js"; -import server from "./services/server.js"; +import "autocomplete.js/index_jquery.js"; + import type ElectronRemote from "@electron/remote"; import type Electron from "electron"; -import "./stylesheets/bootstrap.scss"; -import "boxicons/css/boxicons.min.css"; -import "jquery-hotkeys"; -import "autocomplete.js/index_jquery.js"; + +import appContext from "./components/app_context.js"; +import electronContextMenu from "./menus/electron_context_menu.js"; +import bundleService from "./services/bundle.js"; +import glob from "./services/glob.js"; +import { t } from "./services/i18n.js"; +import noteAutocompleteService from "./services/note_autocomplete.js"; +import noteTooltipService from "./services/note_tooltip.js"; +import options from "./services/options.js"; +import toastService from "./services/toast.js"; +import utils from "./services/utils.js"; await appContext.earlyInit(); @@ -25,6 +23,7 @@ bundleService.getWidgetBundlesByParent().then(async (widgetBundles) => { appContext.setLayout(new DesktopLayout(widgetBundles)); appContext.start().catch((e) => { toastService.showPersistent({ + id: "critical-error", title: t("toast.critical-error.title"), icon: "alert", message: t("toast.critical-error.message", { message: e.message }) @@ -57,10 +56,14 @@ function initOnElectron() { initDarkOrLightMode(style); initTransparencyEffects(style, currentWindow); + initFullScreenDetection(currentWindow); if (options.get("nativeTitleBarVisible") !== "true") { initTitleBarButtons(style, currentWindow); } + + // Clear navigation history on frontend refresh. + currentWindow.webContents.navigationHistory.clear(); } function initTitleBarButtons(style: CSSStyleDeclaration, currentWindow: Electron.BrowserWindow) { @@ -86,16 +89,28 @@ function initTitleBarButtons(style: CSSStyleDeclaration, currentWindow: Electron } } +function initFullScreenDetection(currentWindow: Electron.BrowserWindow) { + currentWindow.on("enter-full-screen", () => document.body.classList.add("full-screen")); + currentWindow.on("leave-full-screen", () => document.body.classList.remove("full-screen")); +} + function initTransparencyEffects(style: CSSStyleDeclaration, currentWindow: Electron.BrowserWindow) { + const material = style.getPropertyValue("--background-material").trim(); if (window.glob.platform === "win32") { - const material = style.getPropertyValue("--background-material"); - // TriliumNextTODO: find a nicer way to make TypeScript happy – unfortunately TS did not like Array.includes here const bgMaterialOptions = ["auto", "none", "mica", "acrylic", "tabbed"] as const; const foundBgMaterialOption = bgMaterialOptions.find((bgMaterialOption) => material === bgMaterialOption); if (foundBgMaterialOption) { currentWindow.setBackgroundMaterial(foundBgMaterialOption); } } + + if (window.glob.platform === "darwin") { + const bgMaterialOptions = [ "popover", "tooltip", "titlebar", "selection", "menu", "sidebar", "header", "sheet", "window", "hud", "fullscreen-ui", "content", "under-window", "under-page" ] as const; + const foundBgMaterialOption = bgMaterialOptions.find((bgMaterialOption) => material === bgMaterialOption); + if (foundBgMaterialOption) { + currentWindow.setVibrancy(foundBgMaterialOption); + } + } } /** diff --git a/apps/client/src/entities/fnote.ts b/apps/client/src/entities/fnote.ts index 6099cba35a..12fd311bec 100644 --- a/apps/client/src/entities/fnote.ts +++ b/apps/client/src/entities/fnote.ts @@ -1,41 +1,24 @@ -import server from "../services/server.js"; -import noteAttributeCache from "../services/note_attribute_cache.js"; -import ws from "../services/ws.js"; -import protectedSessionHolder from "../services/protected_session_holder.js"; +import { getNoteIcon } from "@triliumnext/commons"; + import cssClassManager from "../services/css_class_manager.js"; import type { Froca } from "../services/froca-interface.js"; -import type FAttachment from "./fattachment.js"; -import type { default as FAttribute, AttributeType } from "./fattribute.js"; +import noteAttributeCache from "../services/note_attribute_cache.js"; +import protectedSessionHolder from "../services/protected_session_holder.js"; +import search from "../services/search.js"; +import server from "../services/server.js"; import utils from "../services/utils.js"; +import type FAttachment from "./fattachment.js"; +import type { AttributeType, default as FAttribute } from "./fattribute.js"; const LABEL = "label"; const RELATION = "relation"; -const NOTE_TYPE_ICONS = { - file: "bx bx-file", - image: "bx bx-image", - code: "bx bx-code", - render: "bx bx-extension", - search: "bx bx-file-find", - relationMap: "bx bxs-network-chart", - book: "bx bx-book", - noteMap: "bx bxs-network-chart", - mermaid: "bx bx-selection", - canvas: "bx bx-pen", - webView: "bx bx-globe-alt", - launcher: "bx bx-link", - doc: "bx bxs-file-doc", - contentWidget: "bx bxs-widget", - mindMap: "bx bx-sitemap", - aiChat: "bx bx-bot" -}; - /** * There are many different Note types, some of which are entirely opaque to the * end user. Those types should be used only for checking against, they are * not for direct use. */ -export type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap" | "aiChat"; +export type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap" | "spreadsheet" | "llmChat"; export interface NotePathRecord { isArchived: boolean; @@ -64,7 +47,7 @@ export interface NoteMetaData { /** * Note is the main node and concept in Trilium. */ -class FNote { +export default class FNote { private froca: Froca; noteId!: string; @@ -240,7 +223,7 @@ class FNote { const aNote = this.froca.getNoteFromCache(aNoteId); - if (aNote.isArchived || aNote.isHiddenCompletely()) { + if (!aNote || aNote.isArchived || aNote.isHiddenCompletely()) { return 1; } @@ -256,18 +239,36 @@ class FNote { return this.children; } - async getSubtreeNoteIds() { - let noteIds: (string | string[])[] = []; + async getChildNoteIdsWithArchiveFiltering(includeArchived = false) { + const isHiddenNote = this.noteId.startsWith("_"); + const isSearchNote = this.type === "search"; + if (!includeArchived && !isHiddenNote && !isSearchNote) { + const unorderedIds = new Set(await search.searchForNoteIds(`note.parents.noteId="${this.noteId}" #!archived`)); + const results: string[] = []; + for (const id of this.children) { + if (unorderedIds.has(id)) { + results.push(id); + } + } + return results; + } + return this.children; + } + + async getSubtreeNoteIds(includeArchived = false) { + const noteIds: (string | string[])[] = []; for (const child of await this.getChildNotes()) { + if (child.isArchived && !includeArchived) continue; + noteIds.push(child.noteId); - noteIds.push(await child.getSubtreeNoteIds()); + noteIds.push(await child.getSubtreeNoteIds(includeArchived)); } return noteIds.flat(); } async getSubtreeNotes() { const noteIds = await this.getSubtreeNoteIds(); - return this.froca.getNotes(noteIds); + return (await this.froca.getNotes(noteIds)); } async getChildNotes() { @@ -416,7 +417,7 @@ class FNote { return notePaths; } - getSortedNotePathRecords(hoistedNoteId = "root"): NotePathRecord[] { + getSortedNotePathRecords(hoistedNoteId = "root", activeNotePath: string | null = null): NotePathRecord[] { const isHoistedRoot = hoistedNoteId === "root"; const notePaths: NotePathRecord[] = this.getAllNotePaths().map((path) => ({ @@ -427,7 +428,23 @@ class FNote { isHidden: path.includes("_hidden") })); + // Calculate the length of the prefix match between two arrays + const prefixMatchLength = (path: string[], target: string[]) => { + const diffIndex = path.findIndex((seg, i) => seg !== target[i]); + return diffIndex === -1 ? Math.min(path.length, target.length) : diffIndex; + }; + notePaths.sort((a, b) => { + if (activeNotePath) { + const activeSegments = activeNotePath.split('/'); + const aOverlap = prefixMatchLength(a.notePath, activeSegments); + const bOverlap = prefixMatchLength(b.notePath, activeSegments); + // Paths with more matching prefix segments are prioritized + // when the match count is equal, other criteria are used for sorting + if (bOverlap !== aOverlap) { + return bOverlap - aOverlap; + } + } if (a.isInHoistedSubTree !== b.isInHoistedSubTree) { return a.isInHoistedSubTree ? -1 : 1; } else if (a.isArchived !== b.isArchived) { @@ -436,9 +453,8 @@ class FNote { return a.isHidden ? 1 : -1; } else if (a.isSearch !== b.isSearch) { return a.isSearch ? 1 : -1; - } else { - return a.notePath.length - b.notePath.length; } + return a.notePath.length - b.notePath.length; }); return notePaths; @@ -448,10 +464,11 @@ class FNote { * Returns the note path considered to be the "best" * * @param {string} [hoistedNoteId='root'] + * @param {string|null} [activeNotePath=null] * @return {string[]} array of noteIds constituting the particular note path */ - getBestNotePath(hoistedNoteId = "root") { - return this.getSortedNotePathRecords(hoistedNoteId)[0]?.notePath; + getBestNotePath(hoistedNoteId = "root", activeNotePath: string | null = null) { + return this.getSortedNotePathRecords(hoistedNoteId, activeNotePath)[0]?.notePath; } /** @@ -549,26 +566,15 @@ class FNote { const iconClassLabels = this.getLabels("iconClass"); const workspaceIconClass = this.getWorkspaceIconClass(); - if (iconClassLabels && iconClassLabels.length > 0) { - return iconClassLabels[0].value; - } else if (workspaceIconClass) { - return workspaceIconClass; - } else if (this.noteId === "root") { - return "bx bx-home-alt-2"; - } - if (this.noteId === "_share") { - return "bx bx-share-alt"; - } else if (this.type === "text") { - if (this.isFolder()) { - return "bx bx-folder"; - } else { - return "bx bx-note"; - } - } else if (this.type === "code" && this.mime.startsWith("text/x-sql")) { - return "bx bx-data"; - } else { - return NOTE_TYPE_ICONS[this.type]; - } + const icon = getNoteIcon({ + noteId: this.noteId, + type: this.type, + mime: this.mime, + iconClass: iconClassLabels.length > 0 ? iconClassLabels[0].value : undefined, + workspaceIconClass, + isFolder: this.isFolder.bind(this) + }); + return `tn-icon ${icon}`; } getColorClass() { @@ -577,14 +583,16 @@ class FNote { } isFolder() { - return this.type === "search" || this.getFilteredChildBranches().length > 0; + if (this.isLabelTruthy("subtreeHidden")) return false; + if (this.type === "search") return true; + return this.getFilteredChildBranches().length > 0; } getFilteredChildBranches() { - let childBranches = this.getChildBranches(); + const childBranches = this.getChildBranches(); if (!childBranches) { - ws.logError(`No children for '${this.noteId}'. This shouldn't happen.`); + console.error(`No children for '${this.noteId}'. This shouldn't happen.`); return []; } @@ -692,6 +700,15 @@ class FNote { return this.hasAttribute(LABEL, name); } + /** + * Returns `true` if the note has a label with the given name (same as {@link hasOwnedLabel}), or it has a label with the `disabled:` prefix (for example due to a safe import). + * @param name the name of the label to look for. + * @returns `true` if the label exists, or its version with the `disabled:` prefix. + */ + hasLabelOrDisabled(name: string) { + return this.hasLabel(name) || this.hasLabel(`disabled:${name}`); + } + /** * @param name - label name * @returns true if label exists (including inherited) and does not have "false" value. @@ -770,6 +787,16 @@ class FNote { return this.getAttributeValue(LABEL, name); } + getLabelOrRelation(nameWithPrefix: string) { + if (nameWithPrefix.startsWith("#")) { + return this.getLabelValue(nameWithPrefix.substring(1)); + } else if (nameWithPrefix.startsWith("~")) { + return this.getRelationValue(nameWithPrefix.substring(1)); + } + return this.getLabelValue(nameWithPrefix); + + } + /** * @param name - relation name * @returns relation value if relation exists, null otherwise @@ -821,8 +848,7 @@ class FNote { return []; } - const promotedAttrs = this.getAttributes() - .filter((attr) => attr.isDefinition()) + const promotedAttrs = this.getAttributeDefinitions() .filter((attr) => { const def = attr.getDefinition(); @@ -833,15 +859,20 @@ class FNote { promotedAttrs.sort((a, b) => { if (a.noteId === b.noteId) { return a.position < b.position ? -1 : 1; - } else { - // inherited promoted attributes should stay grouped: https://github.com/zadam/trilium/issues/3761 - return a.noteId < b.noteId ? -1 : 1; } + // inherited promoted attributes should stay grouped: https://github.com/zadam/trilium/issues/3761 + return a.noteId < b.noteId ? -1 : 1; + }); return promotedAttrs; } + getAttributeDefinitions() { + return this.getAttributes() + .filter((attr) => attr.isDefinition()); + } + hasAncestor(ancestorNoteId: string, followTemplates = false, visitedNoteIds: Set | null = null) { if (this.noteId === ancestorNoteId) { return true; @@ -905,8 +936,8 @@ class FNote { return this.getBlob(); } - async getBlob() { - return await this.froca.getBlob("notes", this.noteId); + getBlob() { + return this.froca.getBlob("notes", this.noteId); } toString() { @@ -943,6 +974,10 @@ class FNote { ); } + isJsx() { + return (this.type === "code" && this.mime === "text/jsx"); + } + /** @returns true if this note is HTML */ isHtml() { return (this.type === "code" || this.type === "file" || this.type === "render") && this.mime === "text/html"; @@ -950,7 +985,7 @@ class FNote { /** @returns JS script environment - either "frontend" or "backend" */ getScriptEnv() { - if (this.isHtml() || (this.isJavaScript() && this.mime.endsWith("env=frontend"))) { + if (this.isHtml() || (this.isJavaScript() && this.mime.endsWith("env=frontend")) || this.isJsx()) { return "frontend"; } @@ -972,7 +1007,7 @@ class FNote { * @returns a promise that resolves when the script has been run. Additionally, for front-end notes, the promise will contain the value that is returned by the script. */ async executeScript() { - if (!this.isJavaScript()) { + if (!(this.isJavaScript() || this.isJsx())) { throw new Error(`Note ${this.noteId} is of type ${this.type} and mime ${this.mime} and thus cannot be executed`); } @@ -1020,6 +1055,14 @@ class FNote { return this.noteId.startsWith("_options"); } + isTriliumSqlite() { + return this.mime === "text/x-sqlite;schema=trilium"; + } + + isTriliumScript() { + return this.mime.startsWith("application/javascript"); + } + /** * Provides note's date metadata. */ @@ -1027,5 +1070,3 @@ class FNote { return await server.get(`notes/${this.noteId}/metadata`); } } - -export default FNote; diff --git a/apps/client/src/fonts/boxicons.woff2 b/apps/client/src/fonts/boxicons.woff2 new file mode 100644 index 0000000000..79c35e4c9c Binary files /dev/null and b/apps/client/src/fonts/boxicons.woff2 differ diff --git a/apps/client/src/index.ts b/apps/client/src/index.ts index e69de29bb2..fba6e17d7e 100644 --- a/apps/client/src/index.ts +++ b/apps/client/src/index.ts @@ -0,0 +1,131 @@ +async function bootstrap() { + showSplash(); + await setupGlob(); + await Promise.all([ + initJQuery(), + loadBootstrapCss() + ]); + loadStylesheets(); + loadIcons(); + setBodyAttributes(); + await loadScripts(); + hideSplash(); +} + +async function initJQuery() { + const $ = (await import("jquery")).default; + window.$ = $; + window.jQuery = $; + + // Polyfill removed jQuery methods for autocomplete.js compatibility + ($ as any).isArray = Array.isArray; + ($ as any).isFunction = function(obj: any) { return typeof obj === 'function'; }; + ($ as any).isPlainObject = function(obj: any) { + if (obj == null || typeof obj !== 'object') { return false; } + const proto = Object.getPrototypeOf(obj); + if (proto === null) { return true; } + const Ctor = Object.prototype.hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor === 'function' && Ctor === Object; + }; +} + +async function setupGlob() { + const response = await fetch(`./bootstrap${window.location.search}`); + const json = await response.json(); + + window.global = globalThis; /* fixes https://github.com/webpack/webpack/issues/10035 */ + window.glob = { + ...json, + activeDialog: null + }; +} + +async function loadBootstrapCss() { + // We have to selectively import Bootstrap CSS based on text direction. + if (glob.isRtl) { + await import("bootstrap/dist/css/bootstrap.rtl.min.css"); + } else { + await import("bootstrap/dist/css/bootstrap.min.css"); + } +} + +function loadStylesheets() { + const { device, assetPath, themeCssUrl, themeUseNextAsBase } = window.glob; + + const cssToLoad: string[] = []; + if (device !== "print") { + cssToLoad.push(`${assetPath}/stylesheets/ckeditor-theme.css`); + cssToLoad.push(`api/fonts`); + cssToLoad.push(`${assetPath}/stylesheets/theme-light.css`); + if (themeCssUrl) { + cssToLoad.push(themeCssUrl); + } + if (themeUseNextAsBase === "next") { + cssToLoad.push(`${assetPath}/stylesheets/theme-next.css`); + } else if (themeUseNextAsBase === "next-dark") { + cssToLoad.push(`${assetPath}/stylesheets/theme-next-dark.css`); + } else if (themeUseNextAsBase === "next-light") { + cssToLoad.push(`${assetPath}/stylesheets/theme-next-light.css`); + } + cssToLoad.push(`${assetPath}/stylesheets/style.css`); + } + + for (const href of cssToLoad) { + const linkEl = document.createElement("link"); + linkEl.href = href; + linkEl.rel = "stylesheet"; + document.head.appendChild(linkEl); + } +} + +function loadIcons() { + const styleEl = document.createElement("style"); + styleEl.innerText = window.glob.iconPackCss; + document.head.appendChild(styleEl); +} + +function setBodyAttributes() { + const { device, headingStyle, layoutOrientation, platform, isElectron, hasNativeTitleBar, hasBackgroundEffects, currentLocale } = window.glob; + const classesToSet = [ + device, + `heading-style-${headingStyle}`, + `layout-${layoutOrientation}`, + `platform-${platform}`, + isElectron && "electron", + hasNativeTitleBar && "native-titlebar", + hasBackgroundEffects && "background-effects" + ].filter(Boolean) as string[]; + + for (const classToSet of classesToSet) { + document.body.classList.add(classToSet); + } + + document.body.lang = currentLocale.id; + document.body.dir = currentLocale.rtl ? "rtl" : "ltr"; +} + +async function loadScripts() { + switch (glob.device) { + case "mobile": + await import("./mobile.js"); + break; + case "print": + await import("./print.js"); + break; + case "desktop": + default: + await import("./desktop.js"); + break; + } +} + +function showSplash() { + // hide body to reduce flickering on the startup. This is done through JS and not CSS to not hide
-`; - -export default class HelpDialog extends BasicWidget { - doRender() { - this.$widget = $(TPL); - } - - showCheatsheetEvent() { - openDialog(this.$widget); - } -} diff --git a/apps/client/src/widgets/dialogs/help.tsx b/apps/client/src/widgets/dialogs/help.tsx new file mode 100644 index 0000000000..f6c0c96d60 --- /dev/null +++ b/apps/client/src/widgets/dialogs/help.tsx @@ -0,0 +1,167 @@ +import Modal from "../react/Modal.jsx"; +import { t } from "../../services/i18n.js"; +import { ComponentChildren } from "preact"; +import appContext, { CommandNames } from "../../components/app_context.js"; +import RawHtml from "../react/RawHtml.jsx"; +import { useEffect, useState } from "preact/hooks"; +import keyboard_actions from "../../services/keyboard_actions.js"; +import { useTriliumEvent } from "../react/hooks.jsx"; + +export default function HelpDialog() { + const [ shown, setShown ] = useState(false); + useTriliumEvent("showCheatsheet", () => setShown(true)); + + return ( + setShown(false)} + show={shown} + > +
+ +
    + + + + + + + + +
+
+ + +
    + + +
+ +
{t("help.onlyInDesktop")}
+
    + + + + +
+
+ + +
    + + + +
+
+ + +
    + + + + + + + + + +
+
+ + +
    + + + + + + +
+
+ + +
    +
  • +
  • +
  • +
  • +
+
+ + +
    + + + +
+
+ + +
    + + +
+
+
+
+ ); +} + +function KeyboardShortcut({ commands, description }: { commands: CommandNames | CommandNames[], description: string }) { + const [ shortcuts, setShortcuts ] = useState([]); + + useEffect(() => { + (async () => { + const shortcuts: string[] = []; + for (const command of Array.isArray(commands) ? commands : [commands]) { + const action = await keyboard_actions.getAction(command); + if (action) { + shortcuts.push(...(action.effectiveShortcuts ?? [])); + } + } + + if (shortcuts.length === 0) { + shortcuts.push(t("help.notSet")); + } + + setShortcuts(shortcuts); + })(); + }, [commands]); + + return FixedKeyboardShortcut({ + keys: shortcuts, + description + }); +} + +function FixedKeyboardShortcut({ keys, description }: { keys?: string[], description: string }) { + return ( +
  • + {keys && keys.map((key, index) => + <> + {key} + {index < keys.length - 1 ? ", " : "" } + + )} - +
  • + ); +} + +function Card({ title, children }: { title: string, children: ComponentChildren }) { + return ( +
    +
    +
    {title}
    + +

    + {children} +

    +
    +
    + ) +} + +function editShortcuts() { + appContext.tabManager.openContextWithNote("_optionsShortcuts", { activate: true }); +} \ No newline at end of file diff --git a/apps/client/src/widgets/dialogs/import.ts b/apps/client/src/widgets/dialogs/import.ts deleted file mode 100644 index c8cd66a273..0000000000 --- a/apps/client/src/widgets/dialogs/import.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { escapeQuotes } from "../../services/utils.js"; -import treeService from "../../services/tree.js"; -import importService, { type UploadFilesOptions } from "../../services/import.js"; -import options from "../../services/options.js"; -import BasicWidget from "../basic_widget.js"; -import { t } from "../../services/i18n.js"; -import { Modal, Tooltip } from "bootstrap"; -import type { EventData } from "../../components/app_context.js"; -import { openDialog } from "../../services/dialog.js"; - -const TPL = /*html*/` -`; - -export default class ImportDialog extends BasicWidget { - - private parentNoteId: string | null; - - private $form!: JQuery; - private $noteTitle!: JQuery; - private $fileUploadInput!: JQuery; - private $importButton!: JQuery; - private $safeImportCheckbox!: JQuery; - private $shrinkImagesCheckbox!: JQuery; - private $textImportedAsTextCheckbox!: JQuery; - private $codeImportedAsCodeCheckbox!: JQuery; - private $explodeArchivesCheckbox!: JQuery; - private $replaceUnderscoresWithSpacesCheckbox!: JQuery; - - constructor() { - super(); - - this.parentNoteId = null; - } - - doRender() { - this.$widget = $(TPL); - Modal.getOrCreateInstance(this.$widget[0]); - - this.$form = this.$widget.find(".import-form"); - this.$noteTitle = this.$widget.find(".import-note-title"); - this.$fileUploadInput = this.$widget.find(".import-file-upload-input"); - this.$importButton = this.$widget.find(".import-button"); - this.$safeImportCheckbox = this.$widget.find(".safe-import-checkbox"); - this.$shrinkImagesCheckbox = this.$widget.find(".shrink-images-checkbox"); - this.$textImportedAsTextCheckbox = this.$widget.find(".text-imported-as-text-checkbox"); - this.$codeImportedAsCodeCheckbox = this.$widget.find(".code-imported-as-code-checkbox"); - this.$explodeArchivesCheckbox = this.$widget.find(".explode-archives-checkbox"); - this.$replaceUnderscoresWithSpacesCheckbox = this.$widget.find(".replace-underscores-with-spaces-checkbox"); - - this.$form.on("submit", () => { - // disabling so that import is not triggered again. - this.$importButton.attr("disabled", "disabled"); - - if (this.parentNoteId) { - this.importIntoNote(this.parentNoteId); - } - - return false; - }); - - this.$fileUploadInput.on("change", () => { - if (this.$fileUploadInput.val()) { - this.$importButton.removeAttr("disabled"); - } else { - this.$importButton.attr("disabled", "disabled"); - } - }); - - let _ = [...this.$widget.find('[data-bs-toggle="tooltip"]')].forEach((element) => { - Tooltip.getOrCreateInstance(element, { - html: true - }); - }); - } - - async showImportDialogEvent({ noteId }: EventData<"showImportDialog">) { - this.parentNoteId = noteId; - - this.$fileUploadInput.val("").trigger("change"); // to trigger Import button disabling listener below - - this.$safeImportCheckbox.prop("checked", true); - this.$shrinkImagesCheckbox.prop("checked", options.is("compressImages")); - this.$textImportedAsTextCheckbox.prop("checked", true); - this.$codeImportedAsCodeCheckbox.prop("checked", true); - this.$explodeArchivesCheckbox.prop("checked", true); - this.$replaceUnderscoresWithSpacesCheckbox.prop("checked", true); - - this.$noteTitle.text(await treeService.getNoteTitle(this.parentNoteId)); - - openDialog(this.$widget); - } - - async importIntoNote(parentNoteId: string) { - const files = Array.from(this.$fileUploadInput[0].files ?? []); // shallow copy since we're resetting the upload button below - - const boolToString = ($el: JQuery) => ($el.is(":checked") ? "true" : "false"); - - const options: UploadFilesOptions = { - safeImport: boolToString(this.$safeImportCheckbox), - shrinkImages: boolToString(this.$shrinkImagesCheckbox), - textImportedAsText: boolToString(this.$textImportedAsTextCheckbox), - codeImportedAsCode: boolToString(this.$codeImportedAsCodeCheckbox), - explodeArchives: boolToString(this.$explodeArchivesCheckbox), - replaceUnderscoresWithSpaces: boolToString(this.$replaceUnderscoresWithSpacesCheckbox) - }; - - this.$widget.modal("hide"); - - await importService.uploadFiles("notes", parentNoteId, files, options); - } -} diff --git a/apps/client/src/widgets/dialogs/import.tsx b/apps/client/src/widgets/dialogs/import.tsx new file mode 100644 index 0000000000..0c37466d59 --- /dev/null +++ b/apps/client/src/widgets/dialogs/import.tsx @@ -0,0 +1,103 @@ +import { useState } from "preact/hooks"; +import { t } from "../../services/i18n"; +import tree from "../../services/tree"; +import Button from "../react/Button"; +import FormCheckbox from "../react/FormCheckbox"; +import FormFileUpload from "../react/FormFileUpload"; +import FormGroup, { FormMultiGroup } from "../react/FormGroup"; +import Modal from "../react/Modal"; +import RawHtml from "../react/RawHtml"; +import importService, { UploadFilesOptions } from "../../services/import"; +import { useTriliumEvent, useTriliumOptionBool } from "../react/hooks"; + +export default function ImportDialog() { + const [ compressImages ] = useTriliumOptionBool("compressImages"); + const [ parentNoteId, setParentNoteId ] = useState(); + const [ noteTitle, setNoteTitle ] = useState(); + const [ files, setFiles ] = useState(null); + const [ safeImport, setSafeImport ] = useState(true); + const [ explodeArchives, setExplodeArchives ] = useState(true); + const [ shrinkImages, setShrinkImages ] = useState(compressImages); + const [ textImportedAsText, setTextImportedAsText ] = useState(true); + const [ codeImportedAsCode, setCodeImportedAsCode ] = useState(true); + const [ replaceUnderscoresWithSpaces, setReplaceUnderscoresWithSpaces ] = useState(true); + const [ shown, setShown ] = useState(false); + + useTriliumEvent("showImportDialog", ({ noteId }) => { + setParentNoteId(noteId); + tree.getNoteTitle(noteId).then(setNoteTitle); + setShown(true); + }); + + return ( + { + if (!files || !parentNoteId) { + return; + } + + const options: UploadFilesOptions = { + safeImport: boolToString(safeImport), + shrinkImages: boolToString(shrinkImages), + textImportedAsText: boolToString(textImportedAsText), + codeImportedAsCode: boolToString(codeImportedAsCode), + explodeArchives: boolToString(explodeArchives), + replaceUnderscoresWithSpaces: boolToString(replaceUnderscoresWithSpaces) + }; + + setShown(false); + await importService.uploadFiles("notes", parentNoteId, Array.from(files), options); + }} + onHidden={() => { + setShown(false); + setFiles(null); + }} + footer={ - -
    - - -
    - - -`; - -export default class IncludeNoteDialog extends BasicWidget { - - private modal!: bootstrap.Modal; - private $form!: JQuery; - private $autoComplete!: JQuery; - private textTypeWidget?: EditableTextTypeWidget; - - doRender() { - this.$widget = $(TPL); - this.modal = Modal.getOrCreateInstance(this.$widget[0]); - this.$form = this.$widget.find(".include-note-form"); - this.$autoComplete = this.$widget.find(".include-note-autocomplete"); - this.$form.on("submit", () => { - const notePath = this.$autoComplete.getSelectedNotePath(); - - if (notePath) { - this.modal.hide(); - this.includeNote(notePath); - } else { - logError("No noteId to include."); - } - - return false; - }); - } - - async showIncludeNoteDialogEvent({ textTypeWidget }: EventData<"showIncludeDialog">) { - this.textTypeWidget = textTypeWidget; - await this.refresh(); - openDialog(this.$widget); - - this.$autoComplete.trigger("focus").trigger("select"); // to be able to quickly remove entered text - } - - async refresh() { - this.$autoComplete.val(""); - noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, { - hideGoToSelectedNoteButton: true, - allowCreatingNotes: true - }); - noteAutocompleteService.showRecentNotes(this.$autoComplete); - } - - async includeNote(notePath: string) { - const noteId = treeService.getNoteIdFromUrl(notePath); - if (!noteId) { - return; - } - const note = await froca.getNote(noteId); - const boxSize = $("input[name='include-note-box-size']:checked").val() as string; - - if (["image", "canvas", "mermaid"].includes(note?.type ?? "")) { - // there's no benefit to use insert note functionlity for images, - // so we'll just add an IMG tag - this.textTypeWidget?.addImage(noteId); - } else { - this.textTypeWidget?.addIncludeNote(noteId, boxSize); - } - } -} diff --git a/apps/client/src/widgets/dialogs/include_note.tsx b/apps/client/src/widgets/dialogs/include_note.tsx new file mode 100644 index 0000000000..aabd64bab7 --- /dev/null +++ b/apps/client/src/widgets/dialogs/include_note.tsx @@ -0,0 +1,87 @@ +import { useRef, useState } from "preact/hooks"; +import { t } from "../../services/i18n"; +import FormGroup from "../react/FormGroup"; +import FormRadioGroup from "../react/FormRadioGroup"; +import Modal from "../react/Modal"; +import NoteAutocomplete from "../react/NoteAutocomplete"; +import Button from "../react/Button"; +import { Suggestion, triggerRecentNotes } from "../../services/note_autocomplete"; +import tree from "../../services/tree"; +import froca from "../../services/froca"; +import { useTriliumEvent } from "../react/hooks"; +import { type BoxSize, CKEditorApi } from "../type_widgets/text/CKEditorWithWatchdog"; + +export interface IncludeNoteOpts { + editorApi: CKEditorApi; +} + +export default function IncludeNoteDialog() { + const editorApiRef = useRef(null); + const [suggestion, setSuggestion] = useState(null); + const [boxSize, setBoxSize] = useState("medium"); + const [shown, setShown] = useState(false); + + useTriliumEvent("showIncludeNoteDialog", ({ editorApi }) => { + editorApiRef.current = editorApi; + setShown(true); + }); + + const autoCompleteRef = useRef(null); + + return ( + triggerRecentNotes(autoCompleteRef.current)} + onHidden={() => setShown(false)} + onSubmit={() => { + if (!suggestion?.notePath || !editorApiRef.current) return; + setShown(false); + includeNote(suggestion.notePath, editorApiRef.current, boxSize as BoxSize); + }} + footer={ - - - - - -`; - -export default class IncorrectCpuArchDialog extends BasicWidget { - private modal!: Modal; - private $downloadButton!: JQuery; - - doRender() { - this.$widget = $(TPL); - this.modal = Modal.getOrCreateInstance(this.$widget[0]); - this.$downloadButton = this.$widget.find(".download-correct-version-button"); - - this.$downloadButton.on("click", () => { - // Open the releases page where users can download the correct version - if (utils.isElectron()) { - const { shell } = utils.dynamicRequire("electron"); - shell.openExternal("https://github.com/TriliumNext/Trilium/releases/latest"); - } else { - window.open("https://github.com/TriliumNext/Trilium/releases/latest", "_blank"); - } - }); - - // Auto-focus the download button when shown - this.$widget.on("shown.bs.modal", () => { - this.$downloadButton.trigger("focus"); - }); - } - - showCpuArchWarningEvent() { - this.modal.show(); - } -} diff --git a/apps/client/src/widgets/dialogs/incorrect_cpu_arch.tsx b/apps/client/src/widgets/dialogs/incorrect_cpu_arch.tsx new file mode 100644 index 0000000000..438cff1f3b --- /dev/null +++ b/apps/client/src/widgets/dialogs/incorrect_cpu_arch.tsx @@ -0,0 +1,45 @@ +import { useRef } from "preact/hooks"; +import { t } from "../../services/i18n.js"; +import utils from "../../services/utils.js"; +import Button from "../react/Button.js"; +import Modal from "../react/Modal.js"; +import { useState } from "preact/hooks"; +import { useTriliumEvent } from "../react/hooks.jsx"; + +export default function IncorrectCpuArchDialogComponent() { + const [ shown, setShown ] = useState(false); + const downloadButtonRef = useRef(null); + useTriliumEvent("showCpuArchWarning", () => setShown(true)); + + return ( + downloadButtonRef.current?.focus()} + footerAlignment="between" + footer={<> + - - - - - -`; - -export default class InfoDialog extends BasicWidget { - - private resolve: ConfirmDialogCallback | null; - private modal!: bootstrap.Modal; - private $originallyFocused!: JQuery | null; - private $infoContent!: JQuery; - private $okButton!: JQuery; - - constructor() { - super(); - - this.resolve = null; - this.$originallyFocused = null; // element focused before the dialog was opened, so we can return to it afterward - } - - doRender() { - this.$widget = $(TPL); - this.modal = Modal.getOrCreateInstance(this.$widget[0]); - this.$infoContent = this.$widget.find(".info-dialog-content"); - this.$okButton = this.$widget.find(".info-dialog-ok-button"); - - this.$widget.on("shown.bs.modal", () => this.$okButton.trigger("focus")); - - this.$widget.on("hidden.bs.modal", () => { - if (this.resolve) { - this.resolve(); - } - - if (this.$originallyFocused) { - this.$originallyFocused.trigger("focus"); - this.$originallyFocused = null; - } - }); - - this.$okButton.on("click", () => this.modal.hide()); - } - - showInfoDialogEvent({ message, callback }: EventData<"showInfoDialog">) { - this.$originallyFocused = $(":focus"); - - if (typeof message === "string") { - this.$infoContent.text(message); - } else if (Array.isArray(message)) { - this.$infoContent.html(message[0]); - } else { - this.$infoContent.html(message as HTMLElement); - } - - - openDialog(this.$widget); - - this.resolve = callback; - } -} diff --git a/apps/client/src/widgets/dialogs/info.tsx b/apps/client/src/widgets/dialogs/info.tsx new file mode 100644 index 0000000000..e53faa8bdb --- /dev/null +++ b/apps/client/src/widgets/dialogs/info.tsx @@ -0,0 +1,73 @@ +import { EventData } from "../../components/app_context"; +import Modal, { type ModalProps } from "../react/Modal"; +import { t } from "../../services/i18n"; +import Button from "../react/Button"; +import { useRef, useState } from "preact/hooks"; +import { RawHtmlBlock } from "../react/RawHtml"; +import { useTriliumEvent } from "../react/hooks"; +import { isValidElement } from "preact"; +import { ConfirmWithMessageOptions } from "./confirm"; +import "./info.css"; +import server from "../../services/server"; +import { ToMarkdownResponse } from "@triliumnext/commons"; +import { copyTextWithToast } from "../../services/clipboard_ext"; + +export interface InfoExtraProps extends Partial> { + /** Adds a button in the footer that allows easily copying the content of the infobox to clipboard. */ + copyToClipboardButton?: boolean; +} + +export type InfoProps = ConfirmWithMessageOptions & InfoExtraProps; + +export default function InfoDialog() { + const modalRef = useRef(null); + const [ opts, setOpts ] = useState>(); + const [ shown, setShown ] = useState(false); + const okButtonRef = useRef(null); + + useTriliumEvent("showInfoDialog", (opts) => { + setOpts(opts); + setShown(true); + }); + + return ( { + opts?.callback?.(); + setShown(false); + }} + onShown={() => okButtonRef.current?.focus?.()} + modalRef={modalRef} + footer={<> + {opts?.copyToClipboardButton && ( + - - - - - -`; - -const KEEP_LAST_SEARCH_FOR_X_SECONDS = 120; - -export default class JumpToNoteDialog extends BasicWidget { - - private lastOpenedTs: number; - private modal!: bootstrap.Modal; - private $autoComplete!: JQuery; - private $results!: JQuery; - private $modalFooter!: JQuery; - private isCommandMode: boolean = false; - - constructor() { - super(); - - this.lastOpenedTs = 0; - } - - doRender() { - this.$widget = $(TPL); - this.modal = Modal.getOrCreateInstance(this.$widget[0]); - - this.$autoComplete = this.$widget.find(".jump-to-note-autocomplete"); - this.$results = this.$widget.find(".jump-to-note-results"); - this.$modalFooter = this.$widget.find(".modal-footer"); - this.$modalFooter.find(".show-in-full-text-button").on("click", (e) => this.showInFullText(e)); - - shortcutService.bindElShortcut(this.$widget, "ctrl+return", (e) => this.showInFullText(e)); - - // Monitor input changes to detect command mode switches - this.$autoComplete.on("input", () => { - this.updateCommandModeState(); - }); - } - - private updateCommandModeState() { - const currentValue = String(this.$autoComplete.val() || ""); - const newCommandMode = currentValue.startsWith(">"); - - if (newCommandMode !== this.isCommandMode) { - this.isCommandMode = newCommandMode; - this.updateButtonVisibility(); - } - } - - private updateButtonVisibility() { - if (this.isCommandMode) { - this.$modalFooter.hide(); - } else { - this.$modalFooter.show(); - } - } - - async jumpToNoteEvent() { - await this.openDialog(); - } - - async commandPaletteEvent() { - await this.openDialog(true); - } - - private async openDialog(commandMode = false) { - const dialogPromise = openDialog(this.$widget); - if (utils.isMobile()) { - dialogPromise.then(($dialog) => { - const el = $dialog.find(">.modal-dialog")[0]; - - function reposition() { - const offset = 100; - const modalHeight = (window.visualViewport?.height ?? 0) - offset; - const safeAreaInsetBottom = (window.visualViewport?.height ?? 0) - window.innerHeight; - el.style.height = `${modalHeight}px`; - el.style.bottom = `${(window.visualViewport?.height ?? 0) - modalHeight - safeAreaInsetBottom - offset}px`; - } - - this.$autoComplete.on("focus", () => { - reposition(); - }); - - window.visualViewport?.addEventListener("resize", () => { - reposition(); - }); - - reposition(); - }); - } - - // first open dialog, then refresh since refresh is doing focus which should be visible - this.refresh(commandMode); - - this.lastOpenedTs = Date.now(); - } - - async refresh(commandMode = false) { - noteAutocompleteService - .initNoteAutocomplete(this.$autoComplete, { - allowCreatingNotes: true, - hideGoToSelectedNoteButton: true, - allowJumpToSearchNotes: true, - container: this.$results[0], - isCommandPalette: true - }) - // clear any event listener added in previous invocation of this function - .off("autocomplete:noteselected") - .off("autocomplete:commandselected") - .on("autocomplete:noteselected", function (event, suggestion, dataset) { - if (!suggestion.notePath) { - return false; - } - - appContext.tabManager.getActiveContext()?.setNote(suggestion.notePath); - }) - .on("autocomplete:commandselected", async (event, suggestion, dataset) => { - if (!suggestion.commandId) { - return false; - } - - this.modal.hide(); - await commandRegistry.executeCommand(suggestion.commandId); - }); - - if (commandMode) { - // Start in command mode - manually trigger command search - this.$autoComplete.autocomplete("val", ">"); - this.isCommandMode = true; - this.updateButtonVisibility(); - - // Manually populate with all commands immediately - noteAutocompleteService.showAllCommands(this.$autoComplete); - - this.$autoComplete.trigger("focus"); - } else { - // if you open the Jump To dialog soon after using it previously, it can often mean that you - // actually want to search for the same thing (e.g., you opened the wrong note at first try) - // so we'll keep the content. - // if it's outside of this time limit, then we assume it's a completely new search and show recent notes instead. - if (Date.now() - this.lastOpenedTs > KEEP_LAST_SEARCH_FOR_X_SECONDS * 1000) { - this.isCommandMode = false; - this.updateButtonVisibility(); - noteAutocompleteService.showRecentNotes(this.$autoComplete); - } else { - this.$autoComplete - // hack, the actual search value is stored in
     element next to the search input
    -                    // this is important because the search input value is replaced with the suggestion note's title
    -                    .autocomplete("val", this.$autoComplete.next().text())
    -                    .trigger("focus")
    -                    .trigger("select");
    -
    -                // Update command mode state based on the restored value
    -                this.updateCommandModeState();
    -
    -                // If we restored a command mode value, manually trigger command display
    -                if (this.isCommandMode) {
    -                    // Clear the value first, then set it to ">" to trigger a proper change
    -                    this.$autoComplete.autocomplete("val", "");
    -                    noteAutocompleteService.showAllCommands(this.$autoComplete);
    -                }
    -            }
    -        }
    -    }
    -
    -    showInFullText(e: JQuery.TriggeredEvent) {
    -        // stop from propagating upwards (dangerous, especially with ctrl+enter executable javascript notes)
    -        e.preventDefault();
    -        e.stopPropagation();
    -
    -        // Don't perform full text search in command mode
    -        if (this.isCommandMode) {
    -            return;
    -        }
    -
    -        const searchString = String(this.$autoComplete.val());
    -
    -        this.triggerCommand("searchNotes", { searchString });
    -        this.modal.hide();
    -    }
    -}
    diff --git a/apps/client/src/widgets/dialogs/jump_to_note.tsx b/apps/client/src/widgets/dialogs/jump_to_note.tsx
    new file mode 100644
    index 0000000000..89c4388039
    --- /dev/null
    +++ b/apps/client/src/widgets/dialogs/jump_to_note.tsx
    @@ -0,0 +1,143 @@
    +import Modal from "../react/Modal";
    +import Button from "../react/Button";
    +import NoteAutocomplete from "../react/NoteAutocomplete";
    +import { t } from "../../services/i18n";
    +import { useRef, useState } from "preact/hooks";
    +import note_autocomplete, { Suggestion } from "../../services/note_autocomplete";
    +import appContext from "../../components/app_context";
    +import commandRegistry from "../../services/command_registry";
    +import { refToJQuerySelector } from "../react/react_utils";
    +import { useTriliumEvent } from "../react/hooks";
    +import shortcutService from "../../services/shortcuts";
    +
    +const KEEP_LAST_SEARCH_FOR_X_SECONDS = 120;
    +
    +type Mode = "last-search" | "recent-notes" | "commands";
    +
    +export default function JumpToNoteDialogComponent() {
    +    const [ mode, setMode ] = useState();
    +    const [ lastOpenedTs, setLastOpenedTs ] = useState(0);
    +    const containerRef = useRef(null);
    +    const autocompleteRef = useRef(null);
    +    const [ isCommandMode, setIsCommandMode ] = useState(mode === "commands");
    +    const [ initialText, setInitialText ] = useState(isCommandMode ? "> " : "");
    +    const actualText = useRef(initialText);
    +    const [ shown, setShown ] = useState(false);
    +    
    +    async function openDialog(commandMode: boolean) {        
    +        let newMode: Mode;
    +        let initialText = "";
    +
    +        if (commandMode) {
    +            newMode = "commands";
    +            initialText = ">";            
    +        } else if (Date.now() - lastOpenedTs <= KEEP_LAST_SEARCH_FOR_X_SECONDS * 1000 && actualText.current) {
    +            // if you open the Jump To dialog soon after using it previously, it can often mean that you
    +            // actually want to search for the same thing (e.g., you opened the wrong note at first try)
    +            // so we'll keep the content.
    +            // if it's outside of this time limit, then we assume it's a completely new search and show recent notes instead.
    +            newMode = "last-search";
    +            initialText = actualText.current;
    +        } else {
    +            newMode = "recent-notes";
    +        }
    +
    +        if (mode !== newMode) {
    +            setMode(newMode);
    +        }
    +
    +        setInitialText(initialText);
    +        setShown(true);
    +        setLastOpenedTs(Date.now());
    +    }
    +
    +    useTriliumEvent("jumpToNote", () => openDialog(false));
    +    useTriliumEvent("commandPalette", () => openDialog(true));
    +
    +    async function onItemSelected(suggestion?: Suggestion | null) {
    +        if (!suggestion) {
    +            return;
    +        }
    +        
    +        setShown(false);
    +        if (suggestion.notePath) {
    +            appContext.tabManager.getActiveContext()?.setNote(suggestion.notePath);
    +        } else if (suggestion.commandId) {
    +            await commandRegistry.executeCommand(suggestion.commandId);
    +        }
    +    }
    +
    +    function onShown() {
    +        const $autoComplete = refToJQuerySelector(autocompleteRef);
    +        switch (mode) {
    +            case "last-search":
    +                break;
    +            case "recent-notes":
    +                note_autocomplete.showRecentNotes($autoComplete);
    +                break;
    +            case "commands":
    +                note_autocomplete.showAllCommands($autoComplete);
    +                break;
    +        }
    +
    +        $autoComplete
    +            .trigger("focus")
    +            .trigger("select");
    +            
    +        // Add keyboard shortcut for full search
    +        shortcutService.bindElShortcut($autoComplete, "ctrl+return", () => {
    +            if (!isCommandMode) {
    +                showInFullSearch();
    +            }
    +        });
    +    }
    +    
    +    async function showInFullSearch() {
    +        try {
    +            setShown(false);
    +            const searchString = actualText.current?.trim();
    +            if (searchString && !searchString.startsWith(">")) {
    +                await appContext.triggerCommand("searchNotes", {
    +                    searchString
    +                });
    +            }
    +        } catch (error) {
    +            console.error("Failed to trigger full search:", error);
    +        }
    +    }
    +
    +    return (
    +         {
    +                    actualText.current = text;
    +                    setIsCommandMode(text.startsWith(">"));
    +                }}
    +                onChange={onItemSelected}
    +                />}
    +            onShown={onShown}
    +            onHidden={() => setShown(false)}
    +            footer={!isCommandMode && 
    -            
    -            
    -            
    -        
    -    
    -`;
    -
    -interface RenderMarkdownResponse {
    -    htmlContent: string;
    -}
    -
    -export default class MarkdownImportDialog extends BasicWidget {
    -
    -    private lastOpenedTs: number;
    -    private modal!: bootstrap.Modal;
    -    private $importTextarea!: JQuery;
    -    private $importButton!: JQuery;
    -
    -    constructor() {
    -        super();
    -
    -        this.lastOpenedTs = 0;
    -    }
    -
    -    doRender() {
    -        this.$widget = $(TPL);
    -        this.modal = Modal.getOrCreateInstance(this.$widget[0]);
    -        this.$importTextarea = this.$widget.find(".markdown-import-textarea");
    -        this.$importButton = this.$widget.find(".markdown-import-button");
    -
    -        this.$importButton.on("click", () => this.sendForm());
    -
    -        this.$widget.on("shown.bs.modal", () => this.$importTextarea.trigger("focus"));
    -
    -        shortcutService.bindElShortcut(this.$widget, "ctrl+return", () => this.sendForm());
    -    }
    -
    -    async convertMarkdownToHtml(markdownContent: string) {
    -        const { htmlContent } = await server.post("other/render-markdown", { markdownContent });
    -
    -        const textEditor = await appContext.tabManager.getActiveContext()?.getTextEditor();
    -        if (!textEditor) {
    -            return;
    -        }
    -
    -        const viewFragment = textEditor.data.processor.toView(htmlContent);
    -        const modelFragment = textEditor.data.toModel(viewFragment);
    -
    -        textEditor.model.insertContent(modelFragment, textEditor.model.document.selection);
    -        textEditor.editing.view.focus();
    -
    -        toastService.showMessage(t("markdown_import.import_success"));
    -    }
    -
    -    async pasteMarkdownIntoTextEvent() {
    -        await this.importMarkdownInlineEvent(); // BC with keyboard shortcuts command
    -    }
    -
    -    async importMarkdownInlineEvent() {
    -        if (appContext.tabManager.getActiveContextNoteType() !== "text") {
    -            return;
    -        }
    -
    -        if (utils.isElectron()) {
    -            const { clipboard } = utils.dynamicRequire("electron");
    -            const text = clipboard.readText();
    -
    -            this.convertMarkdownToHtml(text);
    -        } else {
    -            openDialog(this.$widget);
    -        }
    -    }
    -
    -    async sendForm() {
    -        const text = String(this.$importTextarea.val());
    -
    -        this.modal.hide();
    -
    -        await this.convertMarkdownToHtml(text);
    -
    -        this.$importTextarea.val("");
    -    }
    -}
    diff --git a/apps/client/src/widgets/dialogs/markdown_import.tsx b/apps/client/src/widgets/dialogs/markdown_import.tsx
    new file mode 100644
    index 0000000000..ee968e3df9
    --- /dev/null
    +++ b/apps/client/src/widgets/dialogs/markdown_import.tsx
    @@ -0,0 +1,77 @@
    +import { useRef, useState } from "preact/hooks";
    +import { t } from "../../services/i18n";
    +import server from "../../services/server";
    +import toast from "../../services/toast";
    +import utils from "../../services/utils";
    +import Modal from "../react/Modal";
    +import Button from "../react/Button";
    +import { useTriliumEvent } from "../react/hooks";
    +import { CKEditorApi } from "../type_widgets/text/CKEditorWithWatchdog";
    +import { RenderMarkdownResponse } from "@triliumnext/commons";
    +
    +export interface MarkdownImportOpts {
    +    editorApi: CKEditorApi;
    +}
    +
    +export default function MarkdownImportDialog() {
    +    const markdownImportTextArea = useRef(null);
    +    const editorApiRef = useRef(null);
    +    const [ text, setText ] = useState("");
    +    const [ shown, setShown ] = useState(false);
    +
    +    useTriliumEvent("showPasteMarkdownDialog", ({ editorApi }) => {
    +        if (utils.isElectron()) {
    +            const { clipboard } = utils.dynamicRequire("electron");
    +            const text = clipboard.readText();
    +
    +            convertMarkdownToHtml(text, editorApi);
    +        } else {
    +            editorApiRef.current = editorApi;
    +            setShown(true);
    +        }
    +    });
    +
    +    function submit() {
    +        setShown(false);
    +        if (editorApiRef.current && text) {
    +            convertMarkdownToHtml(text, editorApiRef.current);
    +        }
    +    }
    +
    +    return (
    +        
    +            }
    +            onShown={() => markdownImportTextArea.current?.focus()}
    +            onHidden={() => {
    +                setShown(false);
    +                setText("");
    +            }}
    +            show={shown}
    +        >
    +            

    {t("markdown_import.modal_body_text")}

    + +
    + ) +} + +async function convertMarkdownToHtml(markdownContent: string, textTypeWidget: CKEditorApi) { + const { htmlContent } = await server.post("other/render-markdown", { markdownContent }); + textTypeWidget.addHtmlToEditor(htmlContent); + toast.showMessage(t("markdown_import.import_success")); +} diff --git a/apps/client/src/widgets/dialogs/move_to.ts b/apps/client/src/widgets/dialogs/move_to.ts deleted file mode 100644 index 49e016f155..0000000000 --- a/apps/client/src/widgets/dialogs/move_to.ts +++ /dev/null @@ -1,120 +0,0 @@ -import noteAutocompleteService from "../../services/note_autocomplete.js"; -import toastService from "../../services/toast.js"; -import froca from "../../services/froca.js"; -import branchService from "../../services/branches.js"; -import treeService from "../../services/tree.js"; -import BasicWidget from "../basic_widget.js"; -import { t } from "../../services/i18n.js"; -import type { EventData } from "../../components/app_context.js"; -import { openDialog } from "../../services/dialog.js"; - -const TPL = /*html*/` -`; - -export default class MoveToDialog extends BasicWidget { - - private movedBranchIds: string[] | null; - private $form!: JQuery; - private $noteAutoComplete!: JQuery; - private $noteList!: JQuery; - - constructor() { - super(); - - this.movedBranchIds = null; - } - - doRender() { - this.$widget = $(TPL); - this.$form = this.$widget.find(".move-to-form"); - this.$noteAutoComplete = this.$widget.find(".move-to-note-autocomplete"); - this.$noteList = this.$widget.find(".move-to-note-list"); - - this.$form.on("submit", () => { - const notePath = this.$noteAutoComplete.getSelectedNotePath(); - - if (notePath) { - this.$widget.modal("hide"); - - const { noteId, parentNoteId } = treeService.getNoteIdAndParentIdFromUrl(notePath); - if (parentNoteId) { - froca.getBranchId(parentNoteId, noteId).then((branchId) => { - if (branchId) { - this.moveNotesTo(branchId); - } - }); - } - } else { - logError(t("move_to.error_no_path")); - } - - return false; - }); - } - - async moveBranchIdsToEvent({ branchIds }: EventData<"moveBranchIdsTo">) { - this.movedBranchIds = branchIds; - - openDialog(this.$widget); - - this.$noteAutoComplete.val("").trigger("focus"); - - this.$noteList.empty(); - - for (const branchId of this.movedBranchIds) { - const branch = froca.getBranch(branchId); - if (!branch) { - continue; - } - - const note = await froca.getNote(branch.noteId); - if (!note) { - continue; - } - - this.$noteList.append($("
  • ").text(note.title)); - } - - noteAutocompleteService.initNoteAutocomplete(this.$noteAutoComplete); - noteAutocompleteService.showRecentNotes(this.$noteAutoComplete); - } - - async moveNotesTo(parentBranchId: string) { - if (this.movedBranchIds) { - await branchService.moveToParentNote(this.movedBranchIds, parentBranchId); - } - - const parentBranch = froca.getBranch(parentBranchId); - const parentNote = await parentBranch?.getNote(); - - toastService.showMessage(`${t("move_to.move_success_message")} ${parentNote?.title}`); - } -} diff --git a/apps/client/src/widgets/dialogs/move_to.tsx b/apps/client/src/widgets/dialogs/move_to.tsx new file mode 100644 index 0000000000..985934cdfe --- /dev/null +++ b/apps/client/src/widgets/dialogs/move_to.tsx @@ -0,0 +1,78 @@ +import Modal from "../react/Modal"; +import { t } from "../../services/i18n"; +import NoteList from "../react/NoteList"; +import FormGroup from "../react/FormGroup"; +import NoteAutocomplete from "../react/NoteAutocomplete"; +import Button from "../react/Button"; +import { useRef, useState } from "preact/hooks"; +import { Suggestion, triggerRecentNotes } from "../../services/note_autocomplete"; +import tree from "../../services/tree"; +import froca from "../../services/froca"; +import branches from "../../services/branches"; +import toast from "../../services/toast"; +import { useTriliumEvent } from "../react/hooks"; + +export default function MoveToDialog() { + const [ movedBranchIds, setMovedBranchIds ] = useState(); + const [ suggestion, setSuggestion ] = useState(null); + const [ shown, setShown ] = useState(false); + const autoCompleteRef = useRef(null); + + useTriliumEvent("moveBranchIdsTo", ({ branchIds }) => { + setMovedBranchIds(branchIds); + setShown(true); + }); + + async function onSubmit() { + const notePath = suggestion?.notePath; + if (!notePath) { + logError(t("move_to.error_no_path")); + return; + } + + setShown(false); + const { noteId, parentNoteId } = tree.getNoteIdAndParentIdFromUrl(notePath); + if (!parentNoteId) { + return; + } + + const branchId = await froca.getBranchId(parentNoteId, noteId); + if (branchId) { + moveNotesTo(movedBranchIds, branchId); + } + } + + return ( + } + onSubmit={onSubmit} + onShown={() => triggerRecentNotes(autoCompleteRef.current)} + onHidden={() => setShown(false)} + show={shown} + > +
    {t("move_to.notes_to_move")}
    + + + + + +
    + ) +} + +async function moveNotesTo(movedBranchIds: string[] | undefined, parentBranchId: string) { + if (movedBranchIds) { + await branches.moveToParentNote(movedBranchIds, parentBranchId); + } + + const parentBranch = froca.getBranch(parentBranchId); + const parentNote = await parentBranch?.getNote(); + + toast.showMessage(`${t("move_to.move_success_message")} ${parentNote?.title}`); +} \ No newline at end of file diff --git a/apps/client/src/widgets/dialogs/note_type_chooser.ts b/apps/client/src/widgets/dialogs/note_type_chooser.ts deleted file mode 100644 index 34a89aff60..0000000000 --- a/apps/client/src/widgets/dialogs/note_type_chooser.ts +++ /dev/null @@ -1,204 +0,0 @@ -import type { CommandNames } from "../../components/app_context.js"; -import type { MenuCommandItem } from "../../menus/context_menu.js"; -import { t } from "../../services/i18n.js"; -import noteTypesService from "../../services/note_types.js"; -import noteAutocompleteService from "../../services/note_autocomplete.js"; -import BasicWidget from "../basic_widget.js"; -import { Dropdown, Modal } from "bootstrap"; - -const TPL = /*html*/` -`; - -export interface ChooseNoteTypeResponse { - success: boolean; - noteType?: string; - templateNoteId?: string; - notePath?: string; -} - -type Callback = (data: ChooseNoteTypeResponse) => void; - -export default class NoteTypeChooserDialog extends BasicWidget { - private resolve: Callback | null; - private dropdown!: Dropdown; - private modal!: Modal; - private $noteTypeDropdown!: JQuery; - private $autoComplete!: JQuery; - private $originalFocused: JQuery | null; - private $originalDialog: JQuery | null; - - constructor() { - super(); - - this.resolve = null; - this.$originalFocused = null; // element focused before the dialog was opened, so we can return to it afterward - this.$originalDialog = null; - } - - doRender() { - this.$widget = $(TPL); - this.modal = Modal.getOrCreateInstance(this.$widget[0]); - - this.$autoComplete = this.$widget.find(".choose-note-path"); - this.$noteTypeDropdown = this.$widget.find(".note-type-dropdown"); - this.dropdown = Dropdown.getOrCreateInstance(this.$widget.find(".note-type-dropdown-trigger")[0]); - - this.$widget.on("hidden.bs.modal", () => { - if (this.resolve) { - this.resolve({ success: false }); - } - - if (this.$originalFocused) { - this.$originalFocused.trigger("focus"); - this.$originalFocused = null; - } - - glob.activeDialog = this.$originalDialog; - }); - - this.$noteTypeDropdown.on("click", ".dropdown-item", (e) => this.doResolve(e)); - - this.$noteTypeDropdown.on("focus", ".dropdown-item", (e) => { - this.$noteTypeDropdown.find(".dropdown-item").each((i, el) => { - $(el).toggleClass("active", el === e.target); - }); - }); - - this.$noteTypeDropdown.on("keydown", ".dropdown-item", (e) => { - if (e.key === "Enter") { - this.doResolve(e); - e.preventDefault(); - return false; - } - }); - - this.$noteTypeDropdown.parent().on("hide.bs.dropdown", (e) => { - // prevent closing dropdown by clicking outside - // TODO: Check if this actually works. - //@ts-ignore - if (e.clickEvent) { - e.preventDefault(); - } else { - this.modal.hide(); - } - }); - } - - async refresh() { - noteAutocompleteService - .initNoteAutocomplete(this.$autoComplete, { - allowCreatingNotes: false, - hideGoToSelectedNoteButton: true, - allowJumpToSearchNotes: false, - }) - } - - async chooseNoteTypeEvent({ callback }: { callback: Callback }) { - this.$originalFocused = $(":focus"); - - await this.refresh(); - - const noteTypes = await noteTypesService.getNoteTypeItems(); - - this.$noteTypeDropdown.empty(); - - for (const noteType of noteTypes) { - if (noteType.title === "----") { - this.$noteTypeDropdown.append($('
  • Script Launcher
    An advanced launcher which will run a script upon pressing. See  Scripts for more information.

    + class="reference-link" href="#root/_help_CdNpE2pqjmI6">Scripting for more information.

      -
    1. Set script to point to the desired script to run.
    2. -
    3. Optionally, set a keyboardShortcut to trigger the launcher.
    4. +
    5. Set script to point to the desired script + to run.
    6. +
    7. Optionally, set a keyboardShortcut to trigger + the launcher.
  • @@ -80,7 +99,7 @@

    Allows defining a custom widget to be rendered inside the launcher. See  Widget Basics for more information.

    + class="reference-link" href="#root/_help_SynTBQiBsdYJ">Widget Basics for more information.

  • Spacers @@ -88,4 +107,5 @@ visual distinction.

  • -

    Launchers are configured via predefined Promoted Attributes.

    \ No newline at end of file +

    Launchers are configured via predefined Promoted Attributes.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout.html new file mode 100644 index 0000000000..8b4b1739d8 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout.html @@ -0,0 +1,244 @@ +

    The New layout is a series of UI/UX changes that were introduced + in v0.101.0 that heavily change both existing UI elements, as well as adding + some new ones. The goal of this new layout is to modernize the application + and to make it more intuitive but at the same time to reduce clutter.

    +

    Newly introduced features

    +

    Status bar

    +

    At the bottom of the window there is a new bar called the Status bar. + This bar houses multiple items such as the Breadcrumb navigation and information + and settings about the current note, such as the content language and  + Attributes.

    +

    For more information, consult the dedicated page.

    +
    + +
    + +

    Inline title

    +

    In previous versions of Trilium, the title bar was fixed at all times. + In the new layout, there is both a fixed title bar and one that scrolls + with the text. The newly introduced title is called the Inline title and + it displays the title in a larger font, while also displaying additional + information such as the creation and the modification date.

    +

    Whenever the title is scrolled past, the fixed title is shown instead.

    +

    This only affects Text and  + Code notes. Note types that take the entirety of the screen such + as Canvas will + always have only the fixed title bar.

    +

    Depending on the note type, the inline title will also present some more + interactive options such as being able to switch the note type (see below).

    +
    + +
    The Inline title, which is displayed at the top of the note and + can be scrolled past.
    +
    +
    + +
    The fixed title bar. The title only appears after scrolling past the Inline title.
    +
    + +

    New note type switcher

    +

    When a new Text or  + Code note is created, a note type switcher will appear below + the Inline title. Apart from changing the note type, it's also + possible to apply a template.

    +

    The switcher will disappear as soon as a text is entered.

    + + +

    Note badges

    +

    Note badges appear near the fixed note title and indicate important information + about the note such as whether it is read-only. Some of the badges are + also interactive.

    +
    + +
    +

    The following badges are available:

    +
      +
    • Read-only badge, which will be shown if the note is not + editable due to either automatic read-only or manual read-only. Clicking + on the badge will temporarily edit the note (similar to the Edit floating button).
    • +
    • Share badge, which will indicate that the current note + is shared. The badge will also indicate if the share is on the local network + (for the desktop application without Synchronization set + up) or publicly accessible (for the server).
    • +
    • Web clip badge, which will indicate if the note was clipped + using the Web Clipper. + The badge acts as a link, so it can be clicked on to navigate to the page + or right clicked for more options.
    • +
    • Execute badge, for scripts or + saved SQL querieswhich have an execute button or a description.
    • +
    +

    Some of these badges replace the dedicated panels at the top of the note.

    +

    Collapsible sections

    +
    + +
    +

    The following sections have been made collapsible:

    +
      +
    • Promoted Attributes +
        +
      • For full-height notes such as Canvas, + the promoted attributes are collapsed by default to make room.
      • +
      • The keyboard shortcut previously used to trigger the promoted attributes + ribbon tab (which was no longer working) has been repurposed to toggle + the promoted attributes instead.
      • +
      +
    • +
    • Edited Notes, which appears for Day Notes is now shown underneath the + title. +
        +
      • Whether the section is collapsed or not depends on the choice in  + Options ā†’ Appearance.
      • +
      +
    • +
    • Search Properties, which appears for the full Search and Saved Search.
    • +
    +

    Save status indicator

    +

    + To the right of the note title, a temporary indicators appears after making + a change to the document that indicates whether the document has been saved.

    +

    It indicates the following states:

    +
      +
    • Unsaved, if the changes will be saved soon.
    • +
    • Saving, if the changes are being saved.
    • +
    • Saved, if all the changes were successfully saved to the server.
    • +
    • Error, if the changes could not be saved, for example due to + a communication server with the server.
    • +
    +

    After all changes have been saved, the indicator will hide automatically + after a few seconds.

    +

    Changing to the existing layout

    +

    Removal of the ribbon

    +

    The most significant change is the removal of the ribbon. All the actions + and options from the ribbon were integrated in other places in the application.

    +

    Here's how all the different tabs that were once part of the ribbon are + now available in the new layout:

    +
      +
    • ā€œFormatting toolbarā€ was relocated to the top of the page. +
        +
      • Instead of having one per split, now there is a single formatting toolbar + per tab. This allows more space for the toolbar items.
      • +
      +
    • +
    • ā€œOwned attributesā€ and ā€œInherited attributesā€ were merged and moved to + the status bar region (displayed one above the other).
    • +
    • ā€œBasic Propertiesā€ were integrated in the Note buttons menu. +
        +
      • The only exception here is the Language combo box which can now be found + in the status bar (top-right of the screen).
      • +
      +
    • +
    • ā€œFileā€ and ā€œImageā€ tabs +
        +
      • The buttons were moved to the right of the note title, as dedicated entries + in Note buttons.
      • +
      • The info section has been merged into the Note info section of + the status bar.
      • +
      +
    • +
    • Edited notes +
        +
      • Moved underneath the title, displayed under a collapsible area and the + notes are represented as badges/chips.
      • +
      • Whether the section is expanded or collapsed depends on the ā€œEdited Notes + ribbon tab will automatically open on day notesā€ setting from Options → + Appearance.
      • +
      +
    • +
    • Search definition tab +
        +
      • Moved underneath the title under a collapsible area.
      • +
      • Expanded by default for new searches, collapsed for saved searches.
      • +
      +
    • +
    • The Note map is now available in the Note actions menu. +
        +
      • Instead of opening into a panel in the ribbon, the note map now opens + in a side split (similar to the in-app help).
      • +
      +
    • +
    • ā€œNote infoā€ tab was moved to a small (i) icon in the status bar.
    • +
    • ā€œSimilar notesā€ tab +
        +
      • Moved to the status bar, by going to the ā€œNote infoā€ section and pressing + the button to show similar notes.
      • +
      • Displayed as a fixed panel, similar to the attributes.
      • +
      +
    • +
    • The Collection properties tab were relocated under the note title and + grouped into: +
        +
      • A combo box to quickly switch between views.
      • +
      • Individual settings for the current view in a submenu.
      • +
      +
    • +
    • Some smaller ribbon tabs were converted to badges that appear near the + note title in the breadcrumb section: +
        +
      • Original URL indicator for clipped web pages (#pageUrl).
      • +
      • SQL and script execute buttons.
      • +
      +
    • +
    + +

    Removal of the floating buttons

    +

    Most of the buttons were relocated to the right of the note title, in + the Note buttons area, + with the exception of:

    +
      +
    • The Edit button is displayed near the note title, as a badge.
    • +
    • Backlinks is displayed in the status bar. When clicked, the same + list of backlinks is displayed.
    • +
    • Relation map zoom buttons are now part of the relation map itself.
    • +
    • Export image to PNG/SVG are now in the Note actions menu, in the Export as image option.
    • +
    +

    Changes to the sidebar

    +

    The sidebar (also known as the right pane) also received some important + changes.

    +

    The previous iteration of the sidebar would appear contextually, depending + on whether there are any items to be displayed. This caused occasional + content shifts when moving between two panes in a split view. In the new + layout, the sidebar acts more like the Note Tree pane, + remaining visible even if there is nothing to display.

    +

    In order to toggle the sidebar, there is a new button on the top-right + side of the screen, near the window buttons (on Windows and Linux).

    +

    Now each section of the sidebar (e.g. ā€œTable of Contentsā€, ā€œHighlights + listā€) is individually collapsible and will remember whether it was collapsed.

    +

    Some sidebar items also have a contextual menu, indicated by the three + dots on the title. For example, the highlights filter can be adjusted directly + from that menu. 

    +

    Custom widgets are still supported. For custom scripts, the three dots + menu allows quick navigation to the corresponding script note.

    +

    How to toggle the new layout

    +

    Starting with v0.101.0, this new layout is enabled by default. It is possible + to fall back to the old layout by going to Options ā†’ Appearance and selecting Old layout.

    + \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb.html new file mode 100644 index 0000000000..02b2082a24 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb.html @@ -0,0 +1,55 @@ +
    + +
    +

    The breadcrumb allows quickly viewing the note hierarchy of the current + note and navigating through it.

    +

    It is part of the Status bar, + displayed in the bottom-left of the screen.

    +

    Layout and Interaction

    +
      +
    • If a note or workspace is hoisted, a badge will appear on the left-most + side. +
        +
      • Clicking on the badge will un-hoist the note/workspace.
      • +
      +
    • +
    • The left-most icon represents the root note, or the hoisted note or workspace. +
        +
      • Clicking the icon will jump to the root note.
      • +
      • Right clicking the icon will display a menu that allows opening the note + in a new tab, split, etc.
      • +
      +
    • +
    • Each segment shows the title of a note in the current note hierarchy. +
        +
      • Clicking the icon will jump to that note.
      • +
      • Right clicking will open a menu with multiple options such as opening + the note in a different tab/split/window, hoisting, moving/cloning the + note, duplicating as well as changing the color of the note.
      • +
      +
    • +
    • Clicking the arrow next to each segment will reveal the child notes of + the segment on the left. +
        +
      • Clicking on an icon will navigate to that particular note.
      • +
      • It's also possible to create a new child note from here.
      • +
      • The menu can optionally hide the archived notes.
      • +
      +
    • +
    • If the current note is deep within a hierarchy, the segments will collapse + into a […] button in order not to occupy too much space. +
        +
      • Clicking this button will display each collapsed entry as a menu item. + Clicking on it will navigate to that particular note.
      • +
      +
    • +
    • Right clicking on an empty space to the right of the breadcrumb (before + the other status bar items) will reveal another menu that allows: +
        +
      • Toggling whether archived notes are displayed in the breadcrumb and in + the note tree.
      • +
      • Copying the current note path to clipboard.
      • +
      +
    • +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb_image.png new file mode 100644 index 0000000000..4a2f36ae2e Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Status bar.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Status bar.html new file mode 100644 index 0000000000..120fe309c0 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Status bar.html @@ -0,0 +1,51 @@ +

    The status bar displays information about the current note and allows + changing settings related to it such as configuring the language or attributes.

    +

    Layout and interaction

    +

    On the left side, the Breadcrumb is + displayed which indicates the current note as well as its parent notes + and allows for quick navigation throughout the hierarchy.

    +

    On the right side, specific sections will show depending on the type of + the current note.

    +
      +
    1. For code notes, the language mode of the note is indicated (e.g. JavaScript, + plain text), as well as allowing easy switching to another mode.
    2. +
    3. For text notes, the content language is displayed and can be changed, + thus configuring the spell-check and the right-to-left support. +
        +
      1. Note that this applies to the entire note and not the selection, unlike + some text editors.
      2. +
      +
    4. +
    5. If a note is placed in multiple places in the tree (cloned), the number + of the note paths will be displayed. +
        +
      1. Clicking it will reveal the full list of note paths and a button to place + it somewhere else.
      2. +
      +
    6. +
    7. If a note has attachments, their number will be displayed. +
        +
      1. Clicking on it will reveal the list of attachments in a new tab.
      2. +
      +
    8. +
    9. If a note is linked from other text notes (backlinks), the number of backlinks + will be displayed. +
        +
      1. Clicking on it will show the list of notes that link to this note, as + well as an excerpt of where the note is referenced.
      2. +
      +
    10. +
    +

    Regardless of note type, the following items will always be displayed + if there is a note:

    +
      +
    1. Note info, which displays: +
        +
      1. The creation/modification date of the note.
      2. +
      3. The type and MIME of the note.
      4. +
      5. The note ID.
      6. +
      7. An estimation of the note size of the note itself and its children.
      8. +
      9. A button to show Similar notes.
      10. +
      +
    2. +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout_image.png new file mode 100644 index 0000000000..12f5e0d5f0 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tooltip.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tooltip.html index 3500d61342..387a6de341 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tooltip.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tooltip.html @@ -1,10 +1,10 @@
    - +

    The note tooltip is a convenience feature which displays a popup when - hovering over an internal link to - another note.

    + hovering over an internal link to another + note.

    The following information is displayed:

    • The note path, at the top of the popup.
    • @@ -16,8 +16,8 @@
  • A snippet of the content will be displayed as well.
  • -
  • A button to quickly edit the note - in a popup.
  • +
  • A button to quickly edit the note in a + popup.
  • The tooltip can be found in multiple places, including:

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree.html index 32b54240fa..99eed49fd0 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree.html @@ -5,13 +5,15 @@

    Drag and Drop

    - Drag and drop example + Drag and drop example

    You can easily rearrange the note tree by dragging and dropping notes, as demonstrated in the example above.

    Keyboard Manipulation

    - Example of using keyboard keys to move a noteTrilium offers efficient keyboard-based manipulation using the following + Example of using keyboard keys to move a noteTrilium offers efficient keyboard-based manipulation using the following shortcuts:

      @@ -27,9 +29,10 @@

    Context Menu

    You can also move notes using the familiar cut and paste functions available - in the context menu, or with the associated keyboard shortcuts: CTRL-C ( - copy), Ctrl + X (cut) and Ctrl + V (paste).

    + in the context menu, or with the associated keyboard shortcuts: + CTRL-C( copy), Ctrl + X (cut) + and Ctrl + V (paste).

    See Note tree contextual menu for more information.

    Keyboard shortcuts

    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/1_Hiding the subtree_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/1_Hiding the subtree_image.png new file mode 100644 index 0000000000..44f0bbe515 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/1_Hiding the subtree_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree.html new file mode 100644 index 0000000000..36294949ad --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree.html @@ -0,0 +1,80 @@ +
    + +
    An example of a collection with a relatively large number of children + that are hidden from the tree.
    +
    +

    The tree works well when the notes are structured in a hierarchy so that + the number of items stays small. When a note has a large number of notes + (in the order of thousands or tens of thousands), two problems arise:

    +
      +
    • Navigating between notes becomes cumbersome and the tree itself gets cluttered + with a large amount of notes.
    • +
    • The large amount of notes can slow down the application considerably.
    • +
    +

    Since v0.102.0, Trilium allows the tree to hide the child notes of particular + notes. This works for both Collections and + normal notes.

    +

    Interaction

    +

    When the subtree of a note is hidden, there are a few subtle changes:

    +
      +
    • To indicate that the subtree is hidden, the note will not have an expand + button and it will display the number of children to the right.
    • +
    • It's not possible to add a new note directly from the tree. +
        +
      • For Collections, + it's best to use the built-in mechanism to create notes (for example by + creating a new point on a geo-map, or by adding a new row in a table).
      • +
      • For normal notes, it's still possible to create children via other means + such as using the Internal (reference) links system.
      • +
      +
    • +
    • Notes can be dragged from outside the note, case in which they will be + cloned into it. +
        +
      • Instead of switching to the child notes that were copied, the parent note + is highlighted instead.
      • +
      • A notification will indicate this behavior.
      • +
      +
    • +
    • Similarly, features such as cut/copy and then paste into the note will + also work.
    • +
    +

    Spotlighting

    +
    + +
    +

    Even if the subtree of a note is hidden, if a child note manages to become + active, it will still appear inside the tree in a special state called spotlighted.

    +

    During this state, the note remains under its normal hierarchy, so that + its easy to tell its location. In addition, this means that:

    +
      +
    • The note position is clearly visible when using the Search.
    • +
    • The note can still be operated on from the tree, such as adding a  + Branch prefix or moving it outside the collection.
    • +
    +

    The note appears in italics to indicate its temporary display. When switching + to another note, the spotlighted note will disappear.

    + +

    Working with collections

    +

    For large collections, it can be helpful to hide their child notes for + performance reasons or de-cluttering the tree.

    +

    To toggle this behavior:

    +
      +
    • Open the collection and in Collection Properties, + look for Hide child notes in tree.
    • +
    • Right click the collection note in the Note Tree and select Advanced → Show subtree.
    • +
    +

    Working with normal notes

    +

    It's possible to hide the subtree for normal notes as well, not just collections. + To do so, right click the note in the Note Tree and + select Advanced → Hide subtree. +

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree_image.png new file mode 100644 index 0000000000..7b75834e96 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Keyboard shortcuts.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Keyboard shortcuts.html index befdaae03a..2d17206499 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Keyboard shortcuts.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Keyboard shortcuts.html @@ -1,33 +1,48 @@

    The Note Tree comes with multiple keyboard shortcuts to make editing faster:

    +

    Navigation within the tree

      -
    • Opening notes: -
        -
      • Click to open the note in the current tab.
      • -
      • Ctrl+Click or Middle click to open the note - in a new tab.
      • -
      • Ctrl+Right click to open the note in Quick edit.
      • -
      -
    • -
    • Navigation within the tree: -
        -
      • Up and Down to navigate between notes.
      • -
      • Left to collapse a note, or Right to expand it.
      • -
      -
    • -
    • Clipboard management: -
        -
      • Ctrl+C to copy a note.
      • -
      • Ctrl+X to cut a note.
      • -
      • Ctrl+V to paste it somewhere.
      • -
      -
    • -
    • For Multiple selection: -
        -
      • Alt+Clickto add a single note to the current selection.
      • -
      • Shift+Clickto select a range of notes, starting - from the current note (the highlighted one) to the one that is being clicked.
      • -
      -
    • +
    • ↑ and ↑ to navigate between + notes.
    • +
    • ← to collapse a note with children, or → to + expand it.
    • +
    • ← on a note with no children to navigate to its + parent.
    • +
    +

    Opening notes

    +
      +
    • Click to open the note in the current tab.
    • +
    • Ctrl+Click or Middle click to open the note + in a new tab.
    • +
    • Ctrl+Right click to open the note in Quick edit.
    • +
    +

    Clipboard management

    +
      +
    • Ctrl+C to copy one or more notes based on selection + (see Cloning Notes).
    • +
    • Ctrl+X to cut one or more notes (for moving them).
    • +
    • Ctrl+V to paste them somewhere (which results in + a copy or move based on the shortcut used).
    • +
    +

    Moving notes

    +
      +
    • Ctrl + ↑ , Ctrl + ↓ - + move note up/down in the note list.
    • +
    • Ctrl + ← - move note up in the note tree.
    • +
    • Ctrl+→ - move note down in the note + tree.
    • +
    • Del - deletes note and optionally its subtree (asked in the + dialog).
    • +
    +

    Multiple selection

    +

    See Multiple selection for + more information about how selection works.

    +
      +
    • Alt+Click – add a single note to the current selection.
    • +
    • Shift+Click – select a range of notes, starting from + the current note (the highlighted one) to the one that is being clicked.
    • +
    • Shift+↑, Shift+↓ – + multi-select not above/below.
    • +
    • Ctrl+A – select all notes in the current level
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu.html index c8dc3a86b2..93e56632b7 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu.html @@ -10,8 +10,7 @@
    • On a single note, by right clicking it in the note tree.
    • On multiple notes, by selecting them first. See Multiple selection on how to do - so. + href="#root/_help_yTjUdsOi4CIE">Multiple selection on how to do so.
      • When right clicking, do note that usually the note being right clicked is also included in the affected notes, regardless of whether it was selected @@ -81,9 +80,9 @@
      • Use one of the two paste functions (or the keyboard shortcuts) to copy them to the desired location.
      • Note that the copy function here works according to the Cloning Notes functionality (i.e. - the note itself will be present in two locations at once, and editing it - in one place will edit it everywhere).
      • + href="#root/_help_IakOLONlIfGI">Cloning Notes functionality (i.e. the + note itself will be present in two locations at once, and editing it in + one place will edit it everywhere).
      • To simply create a duplicate note that can be modified independently, look for Duplicate subtree.
      @@ -120,6 +119,15 @@ href="#root/_help_KC1HB96bqqHX">Templates.
    +
  • Archive/Unarchive +
      +
    • Marks a note as archived.
    • +
    • If the note is already archived, it will be unarchived instead.
    • +
    • Multiple notes can be selected as well. However, all the selected notes + must be in the same state (archived or not), otherwise the option will + be disabled.
    • +
    +
  • Delete
    • Will delete the given notes, asking for confirmation first.
    • @@ -136,8 +144,8 @@
    • Import into note
        -
      • Opens the import dialog and places - the imported notes as child notes of the selected one.
      • +
      • Opens the import dialog and places the + imported notes as child notes of the selected one.
    • Export @@ -182,8 +190,8 @@
    • Converts the selected notes to Attachments of their parent notes.
    • This functional is most useful when dealing with image File notes that were imported - from an external source or an older version of Trilium.
    • + href="#root/_help_W8vYD3Q1zjCR">File notes that were imported from an + external source or an older version of Trilium.
  • Expand subtree @@ -208,7 +216,7 @@
  • Copy note path to clipboard
    • Copies a URL fragment representing the full path to this branch for a - note, such as #root/Hb2E70L7HPuf/4sRFgMZhYFts/2IVuShedRJ3U/LJVMvKXOFv7n.
    • + note, such as #root/Hb2E70L7HPuf/4sRFgMZhYFts/2IVuShedRJ3U/LJVMvKXOFv7n.
    • The URL to manually create Links within notes, or for note Navigation.
    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons.html index 0f3209d34c..fc33f8aed0 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons.html @@ -9,4 +9,9 @@ as import, export, viewing the Note source code or  Attachments.
  • - \ No newline at end of file + +

    On the New Layout, + the button area is populated by some more buttons that are specific to + the current note. For example, for Image and File notes, the download and copy buttons + were relocated there.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Options.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Options.html index a45f1009c8..8c49439ec8 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Options.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Options.html @@ -1,14 +1,13 @@
    - +

    The Options section allows the configuration of the TriliumNext client and server.

    Entering options

    The Options can be accessed via:

      -
    • The Global menu, by selecting - the Options item.
    • +
    • The Global menu, by selecting the Options item.
    • The button in the Launch Bar which can optionally be hidden if not desirable.
    • diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Recent Changes.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Recent Changes.html index c0ee07abe5..bac90c3d0e 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Recent Changes.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Recent Changes.html @@ -1,6 +1,6 @@
      - +

      Accessing the recent changes

      @@ -9,10 +9,9 @@ button in the Launch Bar.
        -
      • If there is a hoisted note or a - workspace, the list of recent changes will be limited to the descendents - of the hoisted note, or the workspace.
      • +
      • If there is a hoisted note or a workspace, + the list of recent changes will be limited to the descendents of the hoisted + note, or the workspace.
    • To limit the list of recent changes to a note and its descendants, look diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon.html index 31b5908d94..e23f83d729 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon.html @@ -24,28 +24,27 @@
    • Protect the note toggles whether the current note is encrypted and accessible only by entering the protected session. - See Protected Notes for - more information.
    • + See Protected Notes for more + information.
    • Editable changes whether the current note:
        -
      • Enters read-only mode automatically - if the note is too big (default behaviour).
      • +
      • Enters read-only mode automatically if + the note is too big (default behavior).
      • Is always in read-only mode (however it can still be edited temporarily).
      • Is always editable, regardless of its size.
    • Bookmark toggles the display of the current note - into the Launch Bar for - easy access. See Bookmarks for - more information.
    • + into the Launch Bar for easy + access. See Bookmarks for more + information.
    • Shared toggles whether the current note is publicly accessible if you have a server instance set - up. See Sharing for more - information.
    • + up. See Sharing for more information.
    • Template toggles whether the current note is considered a template and can be used to easily create notes with the same - content. See Template for - more information.
    • + content. See Template for more + information.
    • Language changes the main language of the current note, mostly useful for spell checking or right-to-left support. See  Note Paths

      This section displays all the places where the current note has been cloned to. Here the current note can also be cloned to a new location (similar - to the Note Tree) See  - Cloning Notes for more information.

      + to the Note Tree) See Cloning Notes for + more information.

      Note Map

      The note map displays all the relations of the current note to other notes, as well as the subtree structure. See Note Tree for more information.

      Similar Notes

      This section lists all the notes that are similar to the current one. - See Similar Notes for - more information.

      + See Similar Notes for more information.

      Note Info

      This section displays information about the current note:

      • The internal ID of the note.
      • -
      • The type of the note, as well as - its MIME type (used mostly for exporting notes).
      • +
      • The type of the note, as well as its MIME + type (used mostly for exporting notes).
      • The created and modification dates.
      • The estimated size of the note in the Database, as well as its children count and size.
      • diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Right Sidebar.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Right Sidebar.html index f3e1b9aee8..4f12210786 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Right Sidebar.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Right Sidebar.html @@ -1,6 +1,6 @@
        - +

        The right sidebar displays specific content for the current note. Currently it includes:

        @@ -13,7 +13,7 @@

        Note that the sidebar is not displayed if it would otherwise be empty, for example if there are too few headings and there are no highlights.

        Toggling the right sidebar

        -

        The sidebar can be hidden or shown by using the toggleRightPane keyboard +

        The sidebar can be hidden or shown by using the toggleRightPane keyboard shortcut, which is not assigned by default.

        Relation with splits

        When using Split View, diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View.html index b73d3bcefc..6549132937 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View.html @@ -43,4 +43,41 @@ class="image image-style-align-center">

        This is generally quite useful for reorganizing notes from one place to the other, by hoisting the old place in the first split and hoisting the new place to the second one. This will allow easy cut and paste without - the tree jumping around from switching between notes.

        \ No newline at end of file + the tree jumping around from switching between notes.

        +

        Mobile support

        +

        Since v0.100.0, it's possible to have a split view on the mobile view + as well, with the following differences from the desktop version of the + split:

        +
          +
        • On smartphones, the split views are laid out vertically (one on the top + and one on the bottom), instead of horizontally as on the desktop.
        • +
        • There can be only one split open per tab.
        • +
        • It's not possible to resize the two split panes.
        • +
        • When the keyboard is opened, the active note will be ā€œmaximizedā€, thus + allowing for more space even when a split is open. When the keyboard is + closed, the splits become equal in size again.
        • +
        +

        Interaction:

        +
          +
        • To create a new split, click the three dots button on the right of the + note title and select Create new split. +
            +
          • This option will only be available if there is no split already open in + the current tab.
          • +
          +
        • +
        • To close a split, click the three dots button on the right of the note + title and select Close this pane. +
            +
          • Note that this option will only be available on the second note in the + split (the one at the bottom on smartphones, the one on the right on tablets).
          • +
          +
        • +
        • When long-pressing a link, a contextual menu will show up with an option + to Open note in a new split. +
            +
          • If there's already a split, the option will replace the existing split + instead.
          • +
          +
        • +
        \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs.html index 45eac88576..536a2068d7 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs.html @@ -1,6 +1,6 @@
        - +

        In Trilium, tabs allow easy switching between notes.

        Layout

        @@ -9,8 +9,8 @@
      • For the vertical layout, the tabs will be placed at the top but to the right of the Note Tree.
      • For the horizontal layout, the tabs will be placed at the top in full-width, - above the note tree, allowing - for more tabs to be comfortably displayed.
      • + above the note tree, allowing for + more tabs to be comfortably displayed.

      Interaction

        @@ -19,8 +19,8 @@
      • To close a tab, press the corresponding button.
      • For multitasking, tabs can be used alongside Split View. Each tab can have one or - more notes, displayed horizontally.
      • + href="#root/_help_luNhaphA37EO">Split View. Each tab can have one or more + notes, displayed horizontally.
      • Tabs can be reordered by drag-and-dropping it into a new position.
      • An existing tab can be displayed in a new window by dragging the tab upwards or downwards. It is not possible to combine tabs back into another window.
      • @@ -36,7 +36,29 @@
      • Ctrl+Tab and Ctrl+Shift+Tab to go to the next or previous tab.
      • Ctrl+1, Ctrl+2, up to Ctrl+9 to - activate the first, second and up til ninth tab.
      • + activate the first, second and up to ninth tab.
      • There is also a shortcut to go to the last tab, but it is not assigned a key by default.
      • -
      \ No newline at end of file +
    +

    Mobile

    +
    + +
    +

    Tabs are also supported on the Mobile Frontend.

    +

    Since v0.102.0, the tabs are displayed by pressing the dedicated tab switcher + button in the Launch Bar. + In this view the tabs are laid out on a grid with a preview of the note + content.

    +

    The context menu button at the top-right of the popup allows creating + a new tab, reopening the last closed tab and closing all the tabs.

    +

    Split Views are + also indicated in the tab switcher, with two titles displayed in a tab.

    + \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs_IMG_1767.PNG b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs_IMG_1767.PNG new file mode 100644 index 0000000000..dd5a7ab1e5 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs_IMG_1767.PNG differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom.html index e69de29bb2..b056e6fda0 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom.html @@ -0,0 +1,8 @@ +

    Zoom applies to the entire UI, including text.

    +

    On the desktop application, use the Global menu to + zoom in/out.

    +

    On both web browser and the desktop, the keyboard shortcuts Ctrl+Shift++ and Ctrl+Shift+- can + be used.

    +

    Adjusting the text size instead

    +

    As an alternative to the zoom, the text size can be individually adjusted + by going to Options ā†’ Appearance.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Zen mode.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Zen mode.html index 7d10cb7861..94aecbad7a 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Zen mode.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Zen mode.html @@ -15,7 +15,7 @@ the ā€œZen Modeā€ option:

    Aside from the global menu, it's also possible to activate this mode by using a keyboard shortcut (which is F9 since TriliumNext 0.92.5 - and Alt+Z for older versions). Look for toggleZenMode in + and Alt+Z for older versions). Look for toggleZenMode in the shortcut configuration.

    Once Zen Mode is activated, all the UI elements of the application will be hidden away, including the global menu. In that case, the Zen Mode can @@ -37,9 +37,10 @@ 11 with background effects off.

    Split windows and tabs

    Tabs are completely hidden, however it's still possible to use keyboard - shortcuts such as firstTab (Ctrl+1 by default), secondTab (Ctrl+2 by - default). There are also some newer shortcuts such as activateNextTab (Ctrl+Tab) - or activatePreviousTab (Ctrl+Shift+Tab) + shortcuts such as firstTab (Ctrl+1 by + default), secondTab (Ctrl+2 by + default). There are also some newer shortcuts such as activateNextTab (Ctrl+Tab) + or activatePreviousTab (Ctrl+Shift+Tab) that allow easy navigation, however make sure that they are configured properly in the settings.

    For the split view of notes, there are no keyboard shortcuts at the time diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections.html new file mode 100644 index 0000000000..03caa4ce64 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections.html @@ -0,0 +1,160 @@ +

    Collections are a unique type of note that don't have content, but instead + display their child notes in various presentation methods.

    +

    Main collections

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    Calendar  +
    which displays a week, month or year calendar with the notes being shown + as events. New events can be added easily by dragging across the calendar.
    +
    + +
    +
    Table  +
    displays each note as a row in a table, with Promoted Attributes being shown as well. + This makes it easy to visualize attributes of notes, as well as making + them easily editable.
    +
    + +
    +
    Kanban Board  +
    displays notes in columns, grouped by the value of a label. Items and + columns can easily be created or dragged around to change their status.
    +
    + +
    +
    Geo Map  +
    which displays a geographical map in which the notes are represented as + markers/pins on the map. New events can be easily added by pointing on + the map.
    +
    + +
    +
    Presentation  +
    which shows each note as a slide and can be presented full-screen with + smooth transitions or exported to PDF for sharing.
    + +

    Classic collections

    +

    Classic collections are read-only mode and compiles the contents of all + child notes into one continuous view. This makes it ideal for reading extensive + information broken into smaller, manageable segments.

    +
      +
    • Grid View which + is the default presentation method for child notes (see Note List), where the notes are displayed + as tiles with their title and content being visible.
    • +
    • List View is + similar to Grid View, + but it displays the notes one under the other with the content being expandable/collapsible, + but also works recursively.
    • +
    +

    Creating a new collection

    +

    To create a new collections, right click in the Note Tree and look for the Collections entry + and select the desired type.

    +

    By default, collections come with a default configuration and sometimes + even sample notes. To create a collection completely from scratch:

    +
      +
    1. Create a new note of type Text (or any type).
    2. +
    3. Change the note type to Collection.
    4. +
    5. In Collection Properties, + select the desired view type.
    6. +
    7. Consult the help page of the corresponding view type in order to understand + how to configure them.
    8. +
    +

    Configuration

    +

    To change the configuration of a collection or even switch to a different + collection (e.g. from Kanban Board to a Calendar), see the Collection Properties bar at the top + of the note.

    +

    Archived notes

    +

    By default, archived notes will not be + shown in collections. This behavior can be changed by going to  + Collection Properties and checking Show archived notes.

    +

    Archived notes will be generally indicated by being greyed out as opposed + to the normal ones.

    +

    Hiding the child notes from the note tree

    +

    For collections with a large number of items, it can be helpful to hide + the items from the note tree for performance reasons and to reduce clutter. + This is especially useful for standalone collections, such as a geomap + or a task board.

    +

    To do so, go to Collection Properties and + select Hide child notes in tree.

    +

    Advanced use cases

    +

    Adding a description to a collection

    +

    To add a text before the collection, for example to describe it:

    +
      +
    1. Create a new collection.
    2. +
    3. Change the note type from Collection to Text.
    4. +
    +

    Now the text will be displayed above while still maintaining the collection + view.

    +

    The only downside to this method is that Collection Properties will not be shown + anymore. In this case, modify the attributes manually or switch back temporarily + to the Collection type for configuration purposes.

    +

    Using saved search

    +

    Collections, by default, only display the child notes. However, it is + possible to use the Search functionality + to display notes all across the tree, with advanced querying functionality.

    +

    To do so, simply start a Search and + go to the Collection Properties tab in the Ribbon and select a desired type of + collection. To keep the search-based collection, use a Saved Search.

    + +

    Under the hood

    +

    Collections by themselves are simply notes with no content that rely on + the Note List mechanism + (the one that lists the children notes at the bottom of a note) to display + information.

    +

    By default, new collections use predefined Templates that are stored safely in + the Hidden Notes to + define some basic configuration such as the type of view, but also some  + Promoted Attributes to make editing easier.

    +

    Collections don't store their configuration (e.g. the position on the + map, the hidden columns in a table) in the content of the note itself, + but as attachments.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/11_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/10_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/11_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/10_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/12_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/11_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/12_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/11_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/13_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/12_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/13_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/12_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/14_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/13_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/14_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/13_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/16_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/14_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/16_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/14_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/17_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/15_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/17_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/15_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/18_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/16_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/18_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/16_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/1_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/1_Calendar_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/1_Calendar View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/1_Calendar_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/1_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/1_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/1_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/1_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/1_Kanban Board_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/1_Kanban Board_image.png new file mode 100644 index 0000000000..1ccb0a3ccf Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/1_Kanban Board_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/1_Presentation_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/1_Presentation_image.png new file mode 100644 index 0000000000..83b0c01af7 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/1_Presentation_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/4_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/2_Calendar_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/4_Calendar View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/2_Calendar_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/2_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/2_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/2_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/2_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Board View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/2_Kanban Board_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Board View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/2_Kanban Board_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/5_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/3_Calendar_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/5_Calendar View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/3_Calendar_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/3_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/3_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/3_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/3_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/6_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/4_Calendar_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/6_Calendar View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/4_Calendar_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/4_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/4_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/4_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/4_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/7_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/5_Calendar_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/7_Calendar View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/5_Calendar_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/5_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/5_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/5_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/5_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/8_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/6_Calendar_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/8_Calendar View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/6_Calendar_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/6_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/6_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/6_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/6_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/9_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/7_Calendar_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/9_Calendar View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/7_Calendar_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/7_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/7_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/7_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/7_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/10_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/8_Calendar_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/10_Calendar View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/8_Calendar_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/9_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/8_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/9_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/8_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/11_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/9_Calendar_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/11_Calendar View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/9_Calendar_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/10_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/9_Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/10_Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/9_Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Calendar.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Calendar.html new file mode 100644 index 0000000000..45d8ace3d7 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Calendar.html @@ -0,0 +1,441 @@ +
    + +
    +

    The Calendar view will display each child note in a calendar that has + a start date and optionally an end date, as an event.

    +

    The Calendar view has multiple display modes:

    +
      +
    • Week view, where all the 7 days of the week (or 5 if the weekends are + hidden) are displayed in columns. This mode allows entering and displaying + time-specific events, not just all-day events.
    • +
    • Month view, where the entire month is displayed and all-day events can + be inserted. Both time-specific events and all-day events are listed.
    • +
    • Year view, which displays the entire year for quick reference.
    • +
    • List view, which displays all the events of a given month in sequence.
    • +
    +

    Unlike other Collection view types, the Calendar view also allows some + kind of interaction, such as moving events around as well as creating new + ones.

    +

    Creating a calendar

    +

    Right click on an existing note in the Note Tree and select Insert child note and + look for Calendar.

    +

    Creating a new event/note

    +
      +
    • Clicking on a day will create a new child note and assign it to that particular + day. +
        +
      • You will be asked for the name of the new note. If the popup is dismissed + by pressing the close button or escape, then the note will not be created.
      • +
      +
    • +
    • It's possible to drag across multiple days to set both the start and end + date of a particular note. +
      + +
    • +
    • Creating new notes from the calendar will respect the ~child:template relation + if set on the Collection note.
    • +
    +

    Interacting with events

    +
      +
    • Hovering the mouse over an event will display information about the note. +
      + +
    • +
    • Left clicking the event will open a Quick edit to + edit the note in a popup while allowing easy return to the calendar by + just dismissing the popup. +
        +
      • Middle clicking will open the note in a new tab.
      • +
      • Right click will offer more options including opening the note in a new + split or window.
      • +
      +
    • +
    • Drag and drop an event on the calendar to move it to another day.
    • +
    • The length of an event can be changed by placing the mouse to the right + edge of the event and dragging the mouse around.
    • +
    +

    Interaction on mobile

    +

    When Trilium is on mobile, the interaction with the calendar is slightly + different:

    +
      +
    • Clicking on an event triggers the contextual menu, including the option + to open in Quick edit.
    • +
    • To insert a new event, touch and hold the empty space. When successful, + the empty space will become colored to indicate the selection. +
        +
      • Before releasing, drag across multiple spaces to create multi-day events.
      • +
      • When released, a prompt will appear to enter the note title.
      • +
      +
    • +
    • To move an existing event, touch and hold the event until the empty space + near it will become colored. +
        +
      • At this point the event can be dragged across other days on the calendar.
      • +
      • Or the event can be resized by tapping on the small circle to the right + end of the event.
      • +
      • To exit out of editing mode, simply tap the empty space anywhere on the + calendar.
      • +
      +
    • +
    +

    Configuring the calendar view

    +

    In the Collections tab in the Ribbon, + it's possible to adjust the following:

    +
      +
    • Hide weekends from the week view.
    • +
    • Display week numbers on the calendar.
    • +
    +

    Configuring the calendar using attributes

    +

    The following attributes can be added to the Collection type:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDescription
    #calendar:hideWeekends + When present (regardless of value), it will hide Saturday and Sundays + from the calendar.
    #calendar:weekNumbers + When present (regardless of value), it will show the number of the week + on the calendar.
    #calendar:initialDate + Change the date the calendar opens on. When not present, the calendar + opens on the current date.
    #calendar:view + +

    Which view to display in the calendar:

    +
      +
    • timeGridWeek for the week view;
    • +
    • dayGridMonth for the month view;
    • +
    • multiMonthYear for the year view;
    • +
    • listMonth for the list view.
    • +
    +

    Any other value will be dismissed and the default view (month) will be + used instead.

    +

    The value of this label is automatically updated when changing the view + using the UI buttons.

    +
    ~child:template + Defines the template for newly created notes in the calendar (via dragging + or clicking).
    +

    In addition, the first day of the week can be either Sunday or Monday + and can be adjusted from the application settings.

    +

    Configuring the calendar events using attributes

    +

    For each note of the calendar, the following attributes can be used:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDescription
    #startDate + The date the event starts, which will display it in the calendar. The + format is YYYY-MM-DD (year, month and day + separated by a minus sign).
    #endDate + Similar to startDate, mentions the end + date if the event spans across multiple days. The date is inclusive, so + the end day is also considered. The attribute can be missing for single-day + events.
    #startTime + The time the event starts at. If this value is missing, then the event + is considered a full-day event. The format is HH:MM (hours + in 24-hour format and minutes).
    #endTime + Similar to startTime, it mentions the time + at which the event ends (in relation with endDate if + present, or startDate).
    #recurrence + This is an optional CalDAV RRULE string + that if present, determines whether a task should repeat or not. Note that + it does not include the DTSTART attribute, + which is derived from the #startDate and + #startTimedirectly. For examples of valid RRULE strings + see https://icalendar.org/rrule-tool.html +
    #color + Displays the event with a specified color (named such as red, + grayor hex such as #FF0000). This + will also change the color of the note in other places such as the note + tree.
    #calendar:color + āŒļø Removed since v0.100.0. Use **#color** instead.   +
    +
    Similar to #color, but applies the color + only for the event in the calendar and not for other places such as the + note tree.
    #iconClass + If present, the icon of the note will be displayed to the left of the + event title.
    #calendar:title + Changes the title of an event to point to an attribute of the note other + than the title, can either a label or a relation (without the # or + ~symbol). See Use-cases for more information.
    #calendar:displayedAttributes + Allows displaying the value of one or more attributes in the calendar + like this:        +
    +
    +       +
    +
    #weight="70" #Mood="Good" #calendar:displayedAttributes="weight,Mood"      +
    +
    It can also be used with relations, case in which it will display the + title of the target note:       +
    +
    ~assignee=@My assignee #calendar:displayedAttributes="assignee" +
    #calendar:startDate + Allows using a different label to represent the start date, other than + startDate(e.g. expiryDate). The + label name must not be prefixed with #. + If the label is not defined for a note, the default will be used instead.
    #calendar:endDate + Similar to #calendar:startDate, allows + changing the attribute which is being used to read the end date.
    #calendar:startTime + Similar to #calendar:startDate, allows + changing the attribute which is being used to read the start time.
    #calendar:endTime + Similar to #calendar:startDate, allows + changing the attribute which is being used to read the end time.
    + +

    How the calendar works

    +

    + +

    +

    The calendar displays all the child notes of the Collection that have + a #startDate. An #endDate can + optionally be added.

    +

    If editing the start date and end date from the note itself is desirable, + the following attributes can be added to the Collection note:

    #viewType=calendar #label:startDate(inheritable)="promoted,alias=Start Date,single,date"
    +#label:endDate(inheritable)="promoted,alias=End Date,single,date"
    +#hidePromotedAttributes 
    +

    This will result in:

    +

    + +

    +

    When not used in a Journal, the calendar is recursive. That is, it will + look for events not just in its child notes but also in the children of + these child notes.

    +

    Recurrence

    +

    The built in calendar view also supports repeating tasks. If a child note + of the calendar has a #recurrence label with a valid recurrence, that event + will repeat on the calendar according to the recurrence string. 

    +

    For example, to make a note repeat on the calendar:

    +
      +
    • Every Day - #recurrence="FREQ=DAILY;INTERVAL=1" +
    • +
    • Every 3 days - #recurrence="FREQ=DAILY;INTERVAL=3" +
    • +
    • Every week - #recurrence="FREQ=WEEKLY;INTERVAL=1" +
    • +
    • Every 2 weeks on Monday, Wednesday and Friday - #recurrence="FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FR" +
    • +
    • Every 3 months - #recurrence="FREQ=MONTHLY;INTERVAL=3" +
    • +
    • Every 2 months on the First Sunday - #recurrence="FREQ=MONTHLY;INTERVAL=2;BYDAY=1SU" +
    • +
    • Every month on the Last Friday - #recurrence="FREQ=MONTHLY;INTERVAL=1;BYDAY=-1FR" +
    • +
    • And so on.
    • +
    +

    For other examples of valid RRULE strings + see https://icalendar.org/rrule-tool.html +

    +

    Note that the recurrence string does not include the DTSTART attribute + as defined in the iCAL specifications. This is derived directly from the + startDateand startTime attributes

    +

    If you want to override the label the calendar uses to fetch the recurrence + string, you can use the #calendar:recurrence attribute. + For example, you can set #calendar:recurrence=taskRepeats. + Then you can set your recurrence string like #taskRepeats="FREQ=DAILY;INTERVAL=1" +

    +

    Also note that the recurrence label can be made promoted as with the start + and end dates. 

    + +

    Use-cases

    +

    Using with the Journal / calendar

    +

    It is possible to integrate the calendar view into the Journal with day + notes. In order to do so change the note type of the Journal note (calendar + root) to Collection and then select the Calendar View.

    +

    Based on the #calendarRoot (or #workspaceCalendarRoot) + attribute, the calendar will know that it's in a calendar and apply the + following:

    +
      +
    • The calendar events are now rendered based on their dateNote attribute + rather than startDate.
    • +
    • Interactive editing such as dragging over an empty era or resizing an + event is no longer possible.
    • +
    • Clicking on the empty space on a date will automatically open that day's + note or create it if it does not exist.
    • +
    • Direct children of a day note will be displayed on the calendar despite + not having a dateNote attribute. Children + of the child notes will not be displayed.
    • +
    + + +

    Using a different attribute as event title

    +

    By default, events are displayed on the calendar by their note title. + However, it is possible to configure a different attribute to be displayed + instead.

    +

    To do so, assign #calendar:title to the + child note (not the calendar/Collection note), with the value being + namewhere name can be any label (make + not to add the # prefix). The attribute can + also come through inheritance such as a template attribute. If the note + does not have the requested label, the title of the note will be used instead.

    + + + + + + + + + + + + + +
      
    #startDate=2025-02-11 #endDate=2025-02-13 #name="My vacation" #calendar:title="name"
    +
    +

     

    +
    + +
    +
    + +

    Using a relation attribute as event title

    +

    Similarly to using an attribute, use #calendar:title and + set it to name where name is + the name of the relation to use.

    +

    Moreover, if there are more relations of the same name, they will be displayed + as multiple events coming from the same note.

    + + + + + + + + + + + + + +
      
    #startDate=2025-02-14 #endDate=2025-02-15 ~for=@John Smith ~for=@Jane Doe #calendar:title="for"
    +
    + +
    +

    Note that it's even possible to have a #calendar:title on + the target note (e.g. ā€œJohn Smithā€) which will try to render an attribute + of it. Note that it's not possible to use a relation here as well for safety + reasons (an accidental recursion  of attributes could cause the application + to loop infinitely).

    + + + + + + + + + + + + + +
      
    #calendar:title="shortName" #shortName="John S."
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Calendar_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Calendar View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Calendar_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Collection Properties.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Collection Properties.html new file mode 100644 index 0000000000..8b4c62bcef --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Collection Properties.html @@ -0,0 +1,25 @@ +
    + +
    +

    The Collection Properties is a toolbar that is displayed at the + top of every collection note.

    +

    For versions prior to v0.102.0, this feature was only available for the  + New Layout. Starting with this version, the collection properties + are enabled for the Old layout as well, and Ribbon no longer contains a dedicated + tab for collection properties.

    +

    The collection properties has:

    +
      +
    • A quick selector for the view type (e.g. grid, calendar, board).
    • +
    • A settings button with: +
        +
      • Settings for the current view, for example hiding the weekends in a calendar.
      • +
      • Generic settings for the collection, such as hiding the child notes or + showing archived notes.
      • +
      +
    • +
    • Specific interactions for the current view, for example month selector + and view switcher for the calendar.
    • +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Collection Properties_imag.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Collection Properties_imag.png new file mode 100644 index 0000000000..c1955ce8b1 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Collection Properties_imag.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Geo Map View.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Geo Map.html similarity index 69% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Geo Map View.html rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Geo Map.html index cbda5b9773..dd2d5a8f3a 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Geo Map View.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Geo Map.html @@ -5,45 +5,16 @@ href="#root/_help_0ESUbbAxVnoK">Note List. 

    - +

    This note type displays the children notes on a geographical map, based on an attribute. It is also possible to add new notes at a specific location using the built-in interface.

    Creating a new geo map

    - - - - - - - - - - - - - - - - - - - - -
    1 -
    - -
    -
    Right click on any note on the note tree and select Insert child note → Geo Map (beta).
    2 -
    - -
    -
    By default the map will be empty and will show the entire world.
    - +

    Right click on an existing note in the Note Tree and select Geo Map.

    +

    By default the map will be empty and will show the entire world.

    Repositioning the map

    • Click and drag the map in order to move across the map.
    • @@ -67,22 +38,22 @@ 1 To create a marker, first navigate to the desired point on the map. Then press the - button in the Floating buttons (top-right) - area.   + button in the Floating buttons (top-right) + area.      

      If the button is not visible, make sure the button section is visible by pressing the chevron button ( - ) in the top-right of the map. + ) in the top-right of the map. 2 - Once pressed, the map will enter in the insert mode, as illustrated by - the notification.      + the notification.         

      Simply click the point on the map where to place the marker, or the Escape key to cancel. @@ -90,7 +61,7 @@ 3 - Enter the name of the marker/note to be created. @@ -98,7 +69,7 @@ 4 - Once confirmed, the marker will show up on the map and it will also be @@ -112,7 +83,8 @@
    • Right click anywhere on the map, where to place the newly created marker (and corresponding note).
    • Select Add a marker at this location.
    • -
    • Enter the name of the newly created note.
    • +
    • Enter the name of the neNote Treewly + created note.
    • The map should be updated with the new marker.
    • Adding an existing note on note from the note tree

      @@ -129,11 +101,15 @@
    • Notes that are a child of the geo map and also positioned, case in which the marker will be relocated to the new position.
    +

    How the location of the markers is stored

    -

    The location of a marker is stored in the #geolocation attribute +

    The location of a marker is stored in the #geolocation attribute of the child notes:

    - +

    This value can be added manually if needed. The value of the attribute is made up of the latitude and longitude separated by a comma.

    Repositioning markers

    @@ -179,7 +155,7 @@ height="278">
  • Open the location using an external application (if the operating system supports it).
  • Open the note in a new tab, split or window.
  • -
  • Remove the marker from the map, which will remove the #geolocation attribute +
  • Remove the marker from the map, which will remove the #geolocation attribute of the note. To add it back again, the coordinates have to be manually added back in.
  • @@ -187,14 +163,15 @@ height="278">

    Icon and color of the markers

    - image + image

    The markers will have the same icon as the note.

    -

    It's possible to add a custom color to a marker by assigning them a #color attribute - such as #color=green.

    +

    It's possible to add a custom color to a marker by assigning them a + #colorattribute such as #color=green.

    Adding the coordinates manually

    -

    In a nutshell, create a child note and set the #geolocation attribute +

    In a nutshell, create a child note and set the #geolocation attribute to the coordinates.

    The value of the attribute is made up of the latitude and longitude separated by a comma.

    @@ -212,25 +189,27 @@ height="278"> 1
    - +
    Go to Google Maps on the web and look for a desired location, right click - on it and a context menu will show up.      + on it and a context menu will show up.         

    Simply click on the first item displaying the coordinates and they will - be copied to clipboard.      + be copied to clipboard.         
    -
    Then paste the value inside the text box into the #geolocation attribute - of a child note of the map (don't forget to surround the value with a " character). +
    Then paste the value inside the text box into the #geolocation attribute + of a child note of the map (don't forget to surround the value with a + "character). 2
    - +
    In Trilium, create a child note under the map. @@ -239,12 +218,12 @@ height="278"> 3
    - +
    - And then go to Owned Attributes and type #geolocation=", then - paste from the clipboard as-is and then add the ending " character. + And then go to Owned Attributes and type #geolocation=", + then paste from the clipboard as-is and then add the ending " character. Press Enter to confirm and the map should now be updated to contain the new note. @@ -265,7 +244,7 @@ height="278"> 1 - Go to any location on openstreetmap.org and right click to bring up the @@ -274,21 +253,21 @@ height="278"> 2 - The address will be visible in the top-left of the screen, in the place - of the search bar.      + of the search bar.         

    Select the coordinates and copy them into the clipboard. 3 - - Simply paste the value inside the text box into the #geolocation attribute + Simply paste the value inside the text box into the #geolocation attribute of a child note of the map and then it should be displayed on the map. @@ -309,8 +288,8 @@ height="278"> 1
    - +
    To add a track, simply drag & drop a .gpx file inside the geo map @@ -320,22 +299,22 @@ height="278"> 2
    - +
    In order for the file to be recognized as a GPS track, it needs to show - up as application/gpx+xml in the File type field. + up as application/gpx+xml in the File type field. 3
    - +
    - When going back to the map, the track should now be visible.      + When going back to the map, the track should now be visible.         

    The start and end points of the track are indicated by the two blue markers. @@ -344,8 +323,8 @@ height="278"> @@ -362,9 +341,9 @@ height="278"> class="reference-link" href="#root/_help_XpOYSgsLkTJy">Floating buttons. To disable it, press the button again.

    Configuration

    Map Style

    -

    The styling of the map can be adjusted in the Collection Properties tab - in the Ribbon or - manually via the #map:style attribute.

    +

    The styling of the map can be adjusted in the Collection Properties or manually via + the #map:style attribute.

    The geo map comes with two different types of styles:

    • Raster styles @@ -387,17 +366,36 @@ height="278">
    +

    Custom map style / tiles

    +

    Starting with v0.102.0 it is possible to use custom tile sets, but only + in raster format.

    +

    To do so, manually set the #map:style + labelto the URL of the tile set. For example, to use Esri.NatGeoWorldMap, + set the value to https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}. +

    -

    Scale

    -

    Activating this option via the Ribbon or - manually via #map:scale will display an indicator in the bottom-left - of the scale of the map.

    +

    Custom vector map support is planned, but not yet implemented.

    +

    Other options

    +

    The following options can be configured either via the Collection Properties, by clicking on the + settings (Gear icon). Alternatively, each of these options also have a + corresponding label that can be set manually.

    +
      +
    • Scale, which illustrates the scale of the map in kilometers and miles + in the bottom-left of the map.
    • +
    • The name of the markers is displayed by default underneath the pin on + the map. Since v0.102.0, it is possible to hide these labels which increases + the performance and decreases clutter when there are many markers on the + map.
    • +

    Troubleshooting

    - +

    Grid-like artifacts on the map

    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Geo Map View_image.jpg b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Geo Map_image.jpg similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Geo Map View_image.jpg rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Geo Map_image.jpg diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Geo Map_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Geo Map View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Geo Map_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Grid View.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Grid View.html similarity index 76% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Grid View.html rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Grid View.html index 1633c01e74..ddbc230b0e 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Grid View.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Grid View.html @@ -1,6 +1,6 @@
    - +

    This view presents the child notes in a grid format, allowing for a more visual navigation experience.

    @@ -24,7 +24,11 @@ displayed instead.

    The grid view is also used by default in the Note List of every note, making - it easy to navigate to children notes.

    + href="#root/_help_0ESUbbAxVnoK">Note List of every note, making it easy + to navigate to children notes.

    +

    Creating a new table

    +

    Right click on an existing note in the Note Tree and select Insert child note and + look for Grid View.

    Configuration

    Unlike most other view types, the grid view is not actually configurable.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Grid View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Grid View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Grid View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Grid View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Kanban Board.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Kanban Board.html new file mode 100644 index 0000000000..e7c6ac0f2e --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Kanban Board.html @@ -0,0 +1,185 @@ +
    + +
    +

    The Board view presents sub-notes in columns for a Kanban-like experience. + Each column represents a possible value for a status label, which can be + adjusted.

    +

    Creating a Kanban board

    +

    Right click on an existing note in the Note Tree and select Insert child note and + look for Kanban Board.

    +

    How it works

    +

    When first creating a collection of Board type, a few subnotes + will be created, each having a #status label + set. The board then groups each note by the value of the status attribute.

    +

    Notes are displayed recursively, so even the child notes of the child + notes will be displayed. However, unlike the Table, the notes are not displayed in a hierarchy.

    +

    Interaction

    +

    Working with columns

    +
      +
    • Create a new column by pressing Add Column near the last column. +
        +
      • Once pressed, a text box will be displayed to set the name of the column. + Press Enter to confirm, or Escape to dismiss.
      • +
      +
    • +
    • To reorder a column, simply hold the mouse over the title and drag it + to the desired position.
    • +
    • To delete a column, right click on its title and select Delete column.
    • +
    • To rename a column, click on the note title. +
        +
      • Press Enter to confirm.
      • +
      • Upon renaming a column, the corresponding status attribute of all its + notes will be changed in bulk.
      • +
      +
    • +
    • If there are many columns, use the mouse wheel to scroll.
    • +
    +

    Working with notes

    +
      +
    • Create a new note in any column by pressing New item +
        +
      • Enter the name of the note and press Enter or click away. To + dismiss the creation of a new note, simply press Escape or leave + the name empty.
      • +
      • Once created, the new note will have an attribute (status label + by default) set to the name of the column.
      • +
      +
    • +
    • To open the note, simply click on it.
    • +
    • To change the title of the note directly from the board, hover the mouse + over its card and press the edit button on the right.
    • +
    • To change the state of a note, simply drag a note from one column to the + other to change its state.
    • +
    • The order of the notes in each column corresponds to their position in + the tree. +
        +
      • It's possible to reorder notes simply by dragging them to the desired + position within the same columns.
      • +
      • It's also possible to drag notes across columns, at the desired position.
      • +
      +
    • +
    • For more options, right click on a note to display a context menu with + the following options: +
        +
      • Open the note in a new tab/split/window or quick edit.
      • +
      • Move the note to any column.
      • +
      • Insert a new note above/below the current one.
      • +
      • Archive/unarchive the current note.
      • +
      • Delete the current note.
      • +
      +
    • +
    • If there are many notes within the column, move the mouse over the column + and use the mouse wheel to scroll.
    • +
    +

    Working with the note tree

    +

    It's also possible to add items on the board using the Note Tree.

    +
      +
    1. Select the desired note in the Note Tree.
    2. +
    3. Hold the mouse on the note and drag it to the to the desired column.
    4. +
    +

    This works for:

    +
      +
    • Notes that are not children of the board, case in which a clone will + be created.
    • +
    • Notes that are children of the board, but not yet assigned on the board.
    • +
    • Notes that are children of the board, case in which they will be moved + to the new column.
    • +
    +

    Keyboard interaction

    +

    The board view has mild support for keyboard-based navigation:

    +
      +
    • Use Tab and Shift+Tab to navigate between + column titles, notes and the ā€œNew itemā€ button for each of the columns, + in sequential order.
    • +
    • To rename a column or a note, press F2 while it is focused.
    • +
    • To open a specific note or create a new item, press Enter while + it is focused.
    • +
    • To dismiss a rename of a note or a column, press Escape.
    • +
    +

    Configuration

    +

    Displaying custom attributes

    +
    + +
    +

    Since v0.100.0, note attributes can be displayed on the board to enhance + it with custom information such as adding a Due date for your tasks.

    +

    This feature works exclusively via attribute definitions (Promoted Attributes). The easiest way to + add these is:

    +
      +
    1. Go to board note.
    2. +
    3. In the ribbon select Owned Attributes → plus button → Add new label/relation definition.
    4. +
    5. Configure the attribute as desired.
    6. +
    7. Check Inheritable to make it applicable to child notes automatically.
    8. +
    +

    After creating the attribute, click on a note and fill in the promoted + attributes which should then reflect inside the board.

    +

    Of note:

    +
      +
    • Both promoted and non-promoted attribute definitions are supported. The + only difference is that non-promoted attributes don't have an ā€œAliasā€ for + assigning a custom name.
    • +
    • Both ā€œSingle valueā€ and ā€œMulti valueā€ attributes are supported. In case + of multi-value, a badge is displayed for every instance of the attribute.
    • +
    • All label types are supported, including dates, booleans and URLs.
    • +
    • Relation attributes are also supported as well, showing a link with the + target note title and icon.
    • +
    • Currently, it's not possible to adjust which promoted attributes are displayed, + since all promoted attributes will be displayed (except the board:groupBy one). + There are plans to improve upon this being able to hide promoted attributes + individually.
    • +
    +

    Grouping by another label

    +

    By default, the label used to group the notes is #status. + It is possible to use a different label if needed by defining a label named + #board:groupBywith the value being the attribute to use (with or + without # attribute prefix).

    +

    Grouping by relations

    +
    + +
    +

    A more advanced use-case is grouping by Relations.

    +

    During this mode:

    +
      +
    • The columns represent the target notes of a relation.
    • +
    • When creating a new column, a note is selected instead of a column name.
    • +
    • The column icon will match the target note.
    • +
    • Moving notes between columns will change its relation.
    • +
    • Renaming an existing column will change the target note of all the notes + in that column.
    • +
    +

    Using relations instead of labels has some benefits:

    +
      +
    • The status/grouping of the notes is visible outside the Kanban board, + for example on the Note Map.
    • +
    • Columns can have icons.
    • +
    • Renaming columns is less intensive since it simply involves changing the + note title of the target note instead of having to do a bulk rename.
    • +
    +

    To do so:

    +
      +
    1. +

      First, create a Kanban board from scratch and not a template:

      +
    2. +
    3. +

      Assign #viewType=board #hidePromotedAttributes to + emulate the default template.

      +
    4. +
    5. +

      Set #board:groupBy to the name of a relation + to group by, including the ~ prefix (e.g. + ~status).

      +
    6. +
    7. +

      Optionally, use Promoted Attributes for + easy status change within the note:

      #relation:status(inheritable)="promoted,alias=Status,single"
      +
    8. +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Kanban Board_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Kanban Board_image.png new file mode 100644 index 0000000000..d2160e6b22 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Kanban Board_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html new file mode 100644 index 0000000000..aedd1637df --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html @@ -0,0 +1,59 @@ +
    + +
    +

    List view is similar to Grid View, + but in the list view mode, each note is displayed in a single row with + only the title and the icon of the note being visible by the default. By + pressing the expand button it's possible to view the content of the note, + as well as the children of the note (recursively).

    +

    In the example above, the "Node.js" note on the left panel contains several + child notes. The right panel displays the content of these child notes + as a single continuous document.

    +

    Creating a new table

    +

    Right click on an existing note in the Note Tree and select Insert child note and + look for List View.

    +

    Interaction

    +
      +
    • Each note can be expanded or collapsed by clicking on the arrow to the + left of the title.
    • +
    • In the Ribbon, + in the Collection tab there are options to expand and to collapse + all notes easily.
    • +
    +

    Printing and exporting to PDF

    +

    Since v0.100.0, list collections can be printed or exported to PDF.

    +

    A printed list collection will print all the notes in the collection, + in the right order and preserving the full hierarchy.

    +

    If exported to PDF within the desktop application, there is additional + functionality:

    +
      +
    • The table of contents of the PDF will reflect the structure of the notes.
    • +
    • Reference and inline links to other notes within the same hierarchy will + be functional (will jump to the corresponding page). If a link refers to + a note that is not in the printed hierarchy, it will be unlinked.
    • +
    +

    Expanding and collapsing multiple notes at once

    +

    Apart from individually expanding or collapsing notes, it's also possible + to expand or collapse them all at once. To do so, go to the Collection Properties and look for the + corresponding button.

    +

    By default, the Expand button will only expand the direct children + (first level) of the collection. Starting with v0.100.0, it's possible + to expand multiple levels of notes using the arrow button next to the button.

    +

    Manually expanded notes will reset if the application/tab is closed and + then the collection is visited again. Automatically expanded notes, using + the ribbon configuration will persist.

    + + \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/List View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/List View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Presentation.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Presentation.html new file mode 100644 index 0000000000..c2376a8c3c --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Presentation.html @@ -0,0 +1,140 @@ +
    + +
    +

    The Presentation view allows the creation of slideshows directly from + within Trilium.

    +

    Creating a new presentation

    +

    Right click on an existing note in the Note Tree and select Insert child note and + look for Presentation.

    +

    How it works

    +
      +
    • Each slide is a child note of the collection.
    • +
    • The order of the child notes determines the order of the slides.
    • +
    • Unlike traditional presentation software, slides can be laid out both + horizontally and vertically (see belwo for more information).
    • +
    • Direct children will be laid out horizontally and the children of those + will be laid out vertically. Children deeper than two levels of nesting + are ignored.
    • +
    +

    Interaction and navigation

    +

    In the floating buttons section (top-right):

    +
      +
    • Edit button to go to the corresponding note of the current slide.
    • +
    • Press Overview button (or the O key) to show a birds-eye view + of the slides. Press the button again to disable it.
    • +
    • Press the ā€œStart presentationā€ button to show the presentation in full-screen.
    • +
    +

    The following keyboard shortcuts are supported:

    +
      +
    • Press ← and → (or H and L) to go + to the slide on the left or on the right (horizontal).
    • +
    • Press ↑ and ↓  (or K and J) + to go to the upward or downward slide (vertical).
    • +
    • Press Space and Shift + Space or  to go + to the next/previous slide in order.
    • +
    • And a few more, press ? to display a popup with all the supported + keyboard combinations.
    • +
    +

    Vertical slides and nesting

    +

    Unlike traditional presentation software such as Microsoft PowerPoint, + the slides in Trilium can be laid out horizontally or vertically in order + to create depth or better organize the slides by topic.

    +

    This horizontal/vertical organization affects transitions (especially + on the ā€œslideā€ transition), however it is most noticeable in navigation.

    +
      +
    • Pressing ← and → will navigate through slides horizontally, + thus skipping vertical notes under the current slide. This is useful to + skip entire chapters/related slides.
    • +
    • Pressing ↑ and ↓ will navigate through the vertical + slides at the current level.
    • +
    • Pressing Space and Shift + Space will go to + the next/previous slide in order, regardless of the direction. This is + generally the key combination to use when presenting.
    • +
    • The arrows on the bottom-right of the slide will also reflect this navigation + scheme.
    • +
    +
    + +
    +

    All direct children of the collection will be laid out horizontally. If + a direct child also has children, those children will be placed as vertical + slides.

    +

    In the following example, the note structure is as follows:

    +
      +
    • Presentation collection +
        +
      • Trilium Notes (demo page)
      • +
      • ā€œIntroductionā€ slide +
          +
        • ā€œThe challenge of personal knowledge managementā€
        • +
        • ā€œNote-taking structuresā€
        • +
        +
      • +
      • ā€œDemo & Feature highlightsā€ slide +
          +
        • ā€œReally fast installation processā€
        • +
        • Video slide
        • +
        +
      • +
      +
    • +
    +

    Customization

    +

    At collection level, it's possible to adjust:

    +
      +
    • The theme of the entire presentation to one of the predefined themes by + going to the Collection Properties and + looking for the Theme option.
    • +
    • It's currently not possible to create custom themes, although it is planned.
    • +
    • Note that it is note possible to alter the CSS via Custom app-wide CSS because the slides + are rendered isolated (in a shadow DOM).
    • +
    +

    At slide level:

    +
      +
    • It's possible to adjust the background color of a slide by using the + predefined promoted attributefor the color or manually setting + #slide:backgroundto a hex color.
    • +
    • More complex backgrounds can be achieved via gradients. There's no UI + for it; it has to be set via #slide:background to + a CSS gradient definition such as: linear-gradient(to bottom, #283b95, #17b2c3).
    • +
    +

    Tips and tricks

    +
      +
    • Text notes generally respect the formatting (bold, italic, foreground + and background colors) and font size. Code blocks and tables also work.
    • +
    • Try using more than just text notes, the presentation uses the same mechanism + as shared notes and Note List so it should be able to display  + Mermaid DiagramsCanvas and  + Mind Map in full-screen (without the interactivity). +
        +
      • +

        Consider using a transparent background for Canvas, if the slides have a custom background + (go to the hamburger menu in the Canvas, press the button select a custom + color and write transparent).

        +
      • +
      • +

        For Mermaid Diagrams, + some of them have a predefined background which can be changed via the + frontmatter. For example, for XY-charts:

        ---
        +config:
        +    themeVariables:
        +        xyChart:
        +            backgroundColor: transparent
        +---
        +
      • +
      +
    • +
    +

    Under the hood

    +

    The Presentation view uses Reveal.js to + handle the navigation and layout of the slides.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Presentation_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Presentation_image.png new file mode 100644 index 0000000000..b87b47a4b5 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Presentation_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Table View.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Table.html similarity index 84% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Table View.html rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Table.html index 3c6e3fc9b6..34001c638e 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Table View.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Table.html @@ -1,6 +1,6 @@
    - +

    The table view displays information in a grid, where the rows are individual notes and the columns are Promoted Attributes. @@ -20,24 +20,25 @@ show up in the child notes, but it's not a requirement. -

  • If there are multiple attribute definitions with the same name, +
  • If there are multiple attribute definitions with the same name, only one will be displayed.
  • There are also a few predefined columns:

      -
    • The current item number, identified by the # symbol. +
    • The current item number, identified by the # symbol.
      • This simply counts the note and is affected by sorting.
    • -
    • Note ID, - representing the unique ID used internally by Trilium
    • +
    • Note ID, representing + the unique ID used internally by Trilium
    • The title of the note.

    Interaction

    Creating a new table

    -

    Right click the Note Tree and - select Insert child note and look for the Table item.

    +

    Right click on an existing note in the Note Tree and select Insert child note and + look for Table.

    Adding columns

    Each column is a promoted or unpromoted attribute that is defined on the Collection note.

    @@ -80,7 +81,9 @@
    • Opening the corresponding note of the row in a new tab, split, window or quick editing it.
    • -
    • Inserting rows above, below or as a child note.
    • +
    • Inserting a new note above or below the selected row. These options are + only enabled if the table is not sorted.
    • +
    • Inserting a new child note for the selected row.
    • Deleting the row.
    @@ -111,8 +114,8 @@

    Working with the data

    Sorting by column

    By default, the order of the notes matches the order in the Note Tree. However, it is possible - to sort the data by the values of a column:

    + href="#root/_help_oPVyFC7WL2Lp">Note Tree. However, it is possible to sort + the data by the values of a column:

    • To do so, simply click on a column.
    • To switch between ascending or descending sort, simply click again on @@ -136,7 +139,8 @@ href="#root/_help_oPVyFC7WL2Lp">Note Tree.

      Reordering does have some limitations:

        -
      • If the parent note has #sorted, reordering will be disabled.
      • +
      • If the parent note has #sorted, reordering + will be disabled.
      • If using nested tables, then reordering will also be disabled.
      • Currently, it's possible to reorder notes even if column sorting is used, but the result might be inconsistent.
      • @@ -150,8 +154,8 @@ to a certain number of levels or even disable it completely. To do so, either:

          -
        • Go to Collection Properties in the Ribbon and look for the Max nesting depth section. +
        • Go to Collection Properties and + look for the Max nesting depth section.
          • To disable nesting, type 0 and press Enter.
          • To limit to a certain depth, type in the desired number (e.g. 2 to only @@ -159,7 +163,8 @@
          • To re-enable unlimited nesting, remove the number and press Enter.
        • -
        • Manually set maxNestingDepth to the desired value.
        • +
        • Manually set maxNestingDepth to the desired + value.

        Limitations:

          @@ -168,14 +173,14 @@

          Limitations

          • Multi-value labels and relations are not supported. If a Promoted Attributes is defined - with a Multi value specificity, they will be ignored.
          • + href="#root/_help_OFXdgB2nNk1F">Promoted Attributes is defined with + a Multi value specificity, they will be ignored.
          • There is no support to filter the rows by a certain criteria. Consider using the table view in search for that use case.

          Use in search

          The table view can be used in a Saved Search by - adding the #viewType=table attribute.

          + adding the #viewType=table attribute.

          Unlike when used in a Collection, saved searches are not limited to the sub-hierarchy of a note and allows for advanced queries thanks to the power of the Search.

          @@ -185,7 +190,6 @@
        • It's not possible to add a new row.

        Columns are supported, by being defined as Promoted Attributes to the  - Saved Search note.

        + href="#root/_help_OFXdgB2nNk1F">Promoted Attributes to the Saved Search note.

        Editing is also supported.

        \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Table View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Table_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Table View_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/Table_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_bo.webp b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_bo.webp new file mode 100644 index 0000000000..6ed49dd449 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_bo.webp differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_ca.webp b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_ca.webp new file mode 100644 index 0000000000..34b7961e0f Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_ca.webp differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_ge.webp b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_ge.webp new file mode 100644 index 0000000000..e564fbfc6f Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_ge.webp differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_pr.webp b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_pr.webp new file mode 100644 index 0000000000..f7ae75cc3a Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_pr.webp differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_ta.webp b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_ta.webp new file mode 100644 index 0000000000..2113caf65f Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections_collection_ta.webp differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/FAQ.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/FAQ.html index 24dfa9332c..290fb0c6c9 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/FAQ.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/FAQ.html @@ -1,3 +1,17 @@ +

        Inspiration for the name ā€œTriliumā€

        +
        +

        Naming software is hard. I lived in Ontario when I first started the project + and Trillium (the flower) is sort of a provincial logo, many institutions + in Ontario are named "Trillium [something]". So I kept hearing/reading + it almost everyday, I liked the sound of it and its nature motif, so I + just reused it.

        +

        – Zadam (original Trilium maintainer) +

        +
        +

        macOS support

        Originally, Trilium Notes considered the macOS build unsupported. TriliumNext commits to make the experience on macOS as good as possible.

        @@ -26,16 +40,17 @@

      How to open multiple documents in one Trilium instance

      This is normally not supported - one Trilium process can open only a single - instance of a database. However, - you can run two Trilium processes (from one installation), each connected - to a separate document. To achieve this, you need to set a location for - the data directory in the TRILIUM_DATA_DIR environment - variable and separate port on TRILIUM_PORT environment variable. - How to do that depends on the platform, in Unix-based systems you can achieve - that by running command such as this:

      TRILIUM_DATA_DIR=/home/me/path/to/data/dir TRILIUM_PORT=12345 trilium 
      -

      You can save this command into a .sh script file or make an - alias. Do this similarly for a second instance with different data directory - and port.

      + instance of a database. However, you can + run two Trilium processes (from one installation), each connected to a + separate document. To achieve this, you need to set a location for the + data directoryin the TRILIUM_DATA_DIR environment + variable and separate port on TRILIUM_PORT environment + variable. How to do that depends on the platform, in Unix-based systems + you can achieve that by running command such as this:

      TRILIUM_DATA_DIR=/home/me/path/to/data/dir TRILIUM_PORT=12345 trilium 
      +

      You can save this command into a .sh script + file or make an alias. Do this similarly for a second instance with different + data directory and port.

      Can I use Dropbox / Google Drive / OneDrive to sync data across multiple computers.

      No.

      These general purpose sync apps are not suitable to sync database files @@ -54,9 +69,8 @@ with probably more problems.

      More detailed answer:

        -
      • clones are what you might call "hard - directory link" in filesystem lingo, but this concept is not implemented - in any filesystem
      • +
      • clones are what you might call "hard directory + link" in filesystem lingo, but this concept is not implemented in any filesystem
      • filesystems make a distinction between directory and file while there's intentionally no such difference in Trilium
      • files are stored in no particular order and user can't change this
      • @@ -70,4 +84,34 @@
      • Filesystems are generally not transactional. While this is not completely required for a note-taking application, having transactions make it way easier to keep notes and their metadata in predictable and consistent state.
      • -
      \ No newline at end of file +
    +

    Search-related Questions

    +

    Why does search sometimes find results with typos?

    +

    Trilium uses a progressive search strategy that includes fuzzy matching + when exact matches return fewer than 5 results. This finds notes despite + minor typos in your search query. You can use fuzzy search operators ( + ~=for fuzzy exact match and ~* for + fuzzy contains). See the Search documentation + for details.

    +

    How can I search for notes when I'm not sure of the exact spelling?

    +

    Use the fuzzy search operators:

    +
      +
    • #title ~= "projct" - finds notes with titles + like "project" despite the typo
    • +
    • note.content ~* "algoritm" - finds content + containing "algorithm" or similar words
    • +
    +

    Why do some search results appear before others with lower scores?

    +

    Trilium places exact matches before fuzzy matches. When you search for + "project", notes containing exactly "project" appear before notes with + variations like "projects" or "projection", regardless of other scoring + factors.

    +

    How can I make my searches faster?

    +
      +
    1. Use the "Fast search" option to search only titles and attributes (not + content)
    2. +
    3. Limit search scope using the "Ancestor" field
    4. +
    5. Set a result limit to prevent loading too many results
    6. +
    7. For large databases, consider archiving old notes to reduce search scope
    8. +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Feature Highlights.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Feature Highlights.html index 826c8b9e08..c4af42f289 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Feature Highlights.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Feature Highlights.html @@ -3,10 +3,19 @@ of brevity, beta versions are skipped and the features gathered to the nearest stable version.

      +
    • v0.101.0: +
        +
      • New Layout has + been introduced, making significant modifications to the UI/UX such as + integrating the ribbon and the floating buttons into other UI elements + and introducing new functionality such as the Breadcrumb.
      • +
      +
    • v0.97.0:
      • Books are now Collections.
      • -
      • Table View is +
      • Table is a new collection type displaying notes and attributes in an editable grid.
      • Quick edit is introduced, adding a new way to edit notes in a popup instead of opening @@ -30,13 +39,13 @@
      • v0.95.0:
        • A more friendly theme was introduced for Sharing, with search, expandable tree, - night mode and more.
        • + href="#root/_help_R9pX4DGra2Vt">Sharing, with search, expandable tree, night + mode and more.
      • v0.94.0:
          -
        • Added integration with AI (using +
        • Added integration with [missing note] (using self-hosted LLMs such as Ollama or industry standards such as ChatGPT).
      • @@ -52,13 +61,12 @@
      • macOS binaries are now signed.
      • Text notes can now have adjustable Content language & Right-to-left support.
      • -
      • Export as PDF +
      • Printing & Exporting as PDF
      • Zen mode
      • -
      • Calendar View, - allowing notes to be displayed in a monthly grid based on start and end - dates.
      • +
      • Calendar, allowing + notes to be displayed in a monthly grid based on start and end dates.
    • v0.91.5: @@ -70,8 +78,8 @@ href="#root/_help_iPIMuisry3hd">Text notes.
    • The TriliumNext theme is introduced, bringing a more modern design to the application.
    • -
    • Geo Map View, - displaying notes as markers on a geographical map for easy trip planning.
    • +
    • Geo Map, displaying + notes as markers on a geographical map for easy trip planning.
  • v0.90.8: diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Backup.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Backup.html index 754946d1c4..c4677663ce 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Backup.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Backup.html @@ -9,33 +9,38 @@

    So in total you'll have at most 4 backups from different points in time which should protect you from various problems. These backups are stored - by default in backup directory placed in the data directory.

    + by default in backup directory placed in + the data directory.

    This is only very basic backup solution, and you're encouraged to add some better backup solution - e.g. backing up the Database to cloud / different - computer etc.

    + href="#root/_help_wX4HbRucYSDD">Database to cloud / different computer + etc.

    Note that Synchronization provides also some backup capabilities by its nature of distributing the data to other computers.

    Restoring backup

    Let's assume you want to restore the weekly backup, here's how to do it:

      -
    • find data directory Trilium uses - - easy way is to open "About Trilium Notes" from "Menu" in upper left corner - and looking at "data directory" +
    • find data directory Trilium uses - easy + way is to open "About Trilium Notes" from "Menu" in upper left corner and + looking at "data directory"
        -
      • I'll refer to ~/trilium-data as data directory from now on
      • +
      • I'll refer to ~/trilium-data as data directory + from now on
    • -
    • find ~/trilium-data/backup/backup-weekly.db - this is the  - Database backup
    • +
    • find ~/trilium-data/backup/backup-weekly.db - + this is the Database backup
    • at this point stop/kill Trilium
    • -
    • delete ~/trilium-data/document.db, ~/trilium-data/document.db-wal and ~/trilium-data/document.db-shm (latter - two files are auto generated)
    • -
    • copy and rename this ~/trilium-data/backup/backup-weekly.db to ~/trilium-data/document.db +
    • delete ~/trilium-data/document.db, + ~/trilium-data/document.db-waland ~/trilium-data/document.db-shm (latter + two files are auto generated)
    • +
    • copy and rename this ~/trilium-data/backup/backup-weekly.db to + ~/trilium-data/document.db
    • -
    • make sure that the file is writable, e.g. with chmod 600 document.db +
    • make sure that the file is writable, e.g. with chmod 600 document.db
    • start Trilium again
    @@ -43,11 +48,13 @@ of the sync cluster, otherwise older version (restored backup) of the document will be detected and synced to the newer version.

    Disabling backup

    -

    Although this is not recommended, it is possible to disable backup in config.ini in - the data directory:

    [General]
    +

    Although this is not recommended, it is possible to disable backup in + config.iniin the data directory:

    [General]
     ... some other configs
     # set to true to disable backups (e.g. because of limited space on server)
     noBackup=true

    You can also review the configuration file - to provide all config.ini values as environment variables instead.

    -

    See sample config.

    \ No newline at end of file + to provide all config.ini values as environment + variables instead.

    +

    See sample config.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Data directory.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Data directory.html index 60589b51ee..fbd042717a 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Data directory.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Data directory.html @@ -1,26 +1,28 @@

    Data directory contains:

      -
    • document.db - database +
    • document.db - database
    • -
    • config.ini - instance level settings like port on which the - Trilium application runs
    • -
    • backup - contains automatically backup of +
    • config.ini - instance level settings like + port on which the Trilium application runs
    • +
    • backup - contains automatically backup of documents
    • -
    • log - contains application log files
    • +
    • log - contains application log files
    -

    Location

    +

    Location of the data directory

    Easy way how to find out which data directory Trilium uses is to look at the "About Trilium Notes" dialog (from "Menu" in upper left corner):

    Here's how the location is decided:

    -

    Data directory is normally named trilium-data and it is stored - in:

    +

    Data directory is normally named trilium-data and + it is stored in:

      -
    • /home/[user]/.local/share for Linux
    • -
    • C:\Users\[user]\AppData\Roaming for Windows Vista and up
    • -
    • /Users/[user]/Library/Application Support for Mac OS
    • +
    • /home/[user]/.local/share for Linux
    • +
    • C:\Users\[user]\AppData\Roaming for Windows + Vista and up
    • +
    • /Users/[user]/Library/Application Support for + Mac OS
    • user's home is a fallback if some of the paths above don't exist
    • user's home is also a default setup for [[docker|Docker server installation]]
    @@ -28,20 +30,28 @@ - it contains everything you need.

    Changing the location of data directory

    If you want to use some other location for the data directory than the - default one, you may change it via TRILIUM_DATA_DIR environment variable - to some other location:

    + default one, you may change it via TRILIUM_DATA_DIR environment + variable to some other location:

    +

    Windows

    +
      +
    1. Press the Windows key on your keyboard.
    2. +
    3. Search and select ā€œEdit the system variablesā€.
    4. +
    5. Press the ā€œEnvironment Variablesā€¦ā€ button in the bottom-right of the newly + opened screen.
    6. +
    7. On the top section ("User variables for [user]"), press the ā€œNewā€¦ā€ button.
    8. +
    9. In the Variable name field insert TRILIUM_DATA_DIR.
    10. +
    11. Press the Browse Directory… button and select the new directory + where to store the database.
    12. +
    13. Close all the windows by pressing the OK button for each of them.
    14. +

    Linux

    export TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data

    Mac OS X

    -

    You need to create a .plist file under ~/Library/LaunchAgents to - load it properly each login.

    -

    To load it manually, you need to use launchctl setenv TRILIUM_DATA_DIR <yourpath> +

    You need to create a .plist file under + ~/Library/LaunchAgentsto load it properly each login.

    +

    To load it manually, you need to use launchctl setenv TRILIUM_DATA_DIR <yourpath>

    -

    Here is a pre-defined template, where you just need to add your path to:

    
    -
    -
    -
    -    
    -        Label
    +

    Here is a pre-defined template, where you just need to add your path to:

            Label
             set.trilium.env
             RunAtLoad
             
    @@ -50,32 +60,74 @@
                 launchctl
                 setenv
                 TRILIUM_DATA_DIR
    -            /Users/YourUserName/Library/Application Support/trilium-data
    -        
    -    
    -
    + /Users/YourUserName/Library/Application Support/trilium-data

    Create a script to run with specific data directory

    An alternative to globally setting environment variable is to run only the Trilium Notes with this environment variable. This then allows for different setup styles like two database instances or "portable" installation.

    -

    To do this in unix based systems simply run trilium like this:

    TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data trilium
    +

    To do this in Unix-based systems simply run trilium like + this:

    TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data trilium

    You can then save the above command as a shell script on your path for convenience.

    -

    Fine-grained directory/path location

    -

    It's possible to configure e.g. backup and log directories separately, - with following environment variables:

    -
      -
    • TRILIUM_DOCUMENT_PATH -
    • -
    • TRILIUM_BACKUP_DIR -
    • -
    • TRILIUM_LOG_DIR -
    • -
    • TRILIUM_ANONYMIZED_DB_DIR -
    • -
    • TRILIUM_CONFIG_INI_PATH -
    • -
    -

    If these are not set, default paths within the data directory will be - used.

    \ No newline at end of file +

    Fine-grained directory/path location

    +

    Apart from the data directory, some of the subdirectories of it can be + moved elsewhere by changing an environment variable:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Environment variableDefault valueDescription
    TRILIUM_DOCUMENT_PATH + ${TRILIUM_DATA_DIR}/document.db + Path to the Database (storing + all notes and metadata).
    TRILIUM_BACKUP_DIR + ${TRILIUM_DATA_DIR}/backup + Directory where automated Backup databases + are stored.
    TRILIUM_LOG_DIR + ${TRILIUM_DATA_DIR}/log + Directory where daily Backend (server) logs are + stored.
    TRILIUM_TMP_DIR + ${TRILIUM_DATA_DIR}/tmp + Directory where temporary files are stored (for example when opening in + an external app).
    TRILIUM_ANONYMIZED_DB_DIR + ${TRILIUM_DATA_DIR}/anonymized-db + Directory where a Anonymized Database is + stored.
    TRILIUM_CONFIG_INI_PATH + ${TRILIUM_DATA_DIR}/config.ini + Path to Configuration (config.ini or environment variables) file.
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation.html index 6057d513f1..40d7ddd89c 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation.html @@ -1,32 +1,34 @@

    To install Trilium on your desktop, follow these steps:

    1. Download the Latest Release: Obtain the appropriate binary - release for your operating system from the latest release page on + release for your operating system from the latest release page on GitHub.
    2. Extract the Package: Unzip the downloaded package to a location of your choice.
    3. -
    4. Run the Application: Launch Trilium by executing the trilium executable - found within the unzipped folder.
    5. +
    6. Run the Application: Launch Trilium by executing the + triliumexecutable found within the unzipped folder.

    Startup Scripts

    Trilium offers various startup scripts to customize your experience:

      -
    • trilium-no-cert-check: Starts Trilium without validating - TLS certificates, useful if connecting to a server with a self-signed - certificate. -
        -
      • Alternatively, set the NODE_TLS_REJECT_UNAUTHORIZED=0 environment - variable before starting Trilium.
      • -
      +
    • trilium-no-cert-check: Starts Trilium + without validating TLS certificates, useful + if connecting to a server with a self-signed certificate. +
        +
      • Alternatively, set the NODE_TLS_REJECT_UNAUTHORIZED=0 environment + variable before starting Trilium.
      • +
    • -
    • trilium-portable: Launches Trilium in portable mode, where - the data directory is created within - the application's directory, making it easy to move the entire setup.
    • -
    • trilium-safe-mode: Boots Trilium in "safe mode," disabling - any startup scripts that might cause the application to crash.
    • +
    • trilium-portable: Launches Trilium in + portable mode, where the data directory is + created within the application's directory, making it easy to move the + entire setup.
    • +
    • trilium-safe-mode: Boots Trilium in "safe + mode," disabling any startup scripts that might cause the application to + crash.

    Synchronization

    -

    For Trilium desktp users who wish to synchronize their data with a server +

    For Trilium desktop users who wish to synchronize their data with a server instance, refer to the Synchronization guide for detailed instructions.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation/Nix flake.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation/Nix flake.html new file mode 100644 index 0000000000..5d72c46e82 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation/Nix flake.html @@ -0,0 +1,66 @@ +

    Since TriliumNext 0.94.1, the desktop and server applications can be built + using Nix.

    +

    System requirements

    +

    Installation of Nix on Mac or Linux (download page). + About 3-4 gigabytes of additional storage space, for build artifacts.

    +

    Run directly

    +

    Using nix run, + the desktop app can be started as: nix run github:TriliumNext/Trilium/v0.95.0 +

    +

    Running the server requires explicitly specifying the desired package: + nix run github:TriliumNext/Trilium/v0.95.0#server +

    +

    Instead of a version (v0.95.0 above), you + can also specify a commit hash (or a branch name). This makes it easy to + test development builds.

    +

    Install on NixOS

    +

    Add to your flake.nix:

    {
    +  inputs = {
    +    nixpkgs.url = # ...;
    +    trilium-notes = {
    +      url = "github:TriliumNext/Trilium/v0.95.0";
    +      inputs.nixpkgs.follows = "nixpkgs";
    +    };
    +  };
    +
    +  outputs =
    +    {
    +      self,
    +      # ...
    +      trilium-notes,
    +      ...
    +    }:
    +    {
    +      nixosConfigurations = {
    +        "nixos" = nixpkgs.lib.nixosSystem {
    +          system = "x86_64-linux";
    +          modules = [
    +            ./configuration.nix
    +          ];
    +          specialArgs = {
    +            inherit
    +              trilium-notes
    +              ;
    +          };
    +        };
    +      };
    +    };
    +}
    +
    +

    Add to your configuration.nix:

    {
    +  # ...
    +  trilium-notes,
    +  ...
    +}:
    +
    +{
    +  # ...
    +
    +  services.trilium-server.package = trilium-notes.packages.x86_64-linux.server;
    +
    +  environment.systemPackages = [
    +    trilium-notes.packages.x86_64-linux.desktop
    +  ];
    +}
    +

    The flake aims to be compatible with the latest NixOS stable and unstable.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation/System Requirements.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation/System Requirements.html new file mode 100644 index 0000000000..dccd6c556f --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation/System Requirements.html @@ -0,0 +1,21 @@ +

    The desktop version of Trilium supports all three main operating systems:

    +
      +
    • Windows +
        +
      • Windows 11 is officially supported.
      • +
      • Windows on ARM is also supported
      • +
      +
    • +
    • Linux: +
        +
      • Most modern distributions are supported, including NixOS.
      • +
      • ARM is supported in aarch64 (no ARM v7 support).
      • +
      +
    • +
    • macOS +
        +
      • Minimum supported operating system: macOS Monterey
      • +
      • Both Intel and Apple Silicon devices are supported.
      • +
      +
    • +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation/Using the desktop application .html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation/Using the desktop application .html new file mode 100644 index 0000000000..66d4c23810 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation/Using the desktop application .html @@ -0,0 +1,35 @@ +

    Sometimes, setting up a dedicated server installation is + not feasible. The desktop application ships with a fully functional server + instance by default.

    +

    You can access this web interface locally by navigating to http://localhost:37840/login.

    + +

    Mobile interface

    +

    By default, this will display the desktop user interface, even on mobile. + To switch to the mobile version, simply go to the Global menu and select ā€œSwitch to the + mobile versionā€.

    +

    Allowing the port externally on Windows with Windows Defender Firewall

    +

    First, find out the IP of your desktop server by running ipconfig in + your local terminal. Then try accessing http://<ip>:37840/login on + another device. If it doesn't work, then most likely the port is blocked + by your operating system's firewall.

    +

    If you use Windows Defender Firewall:

    +
      +
    1. Go to Windows's start menu and look for ā€œWindows Defender Firewall with + Advanced Securityā€.
    2. +
    3. Go to ā€œInbound Rulesā€ on the left tree, and select ā€œNew Ruleā€ in the ā€œActionsā€ + sidebar on the right.
    4. +
    5. Select ā€œPortā€ and press ā€œNextā€.
    6. +
    7. Type in 37840 in the ā€œSpecific local portsā€ + section and then press ā€œNextā€.
    8. +
    9. Leave ā€œAllow the connectionā€ checked and press ā€œNextā€.
    10. +
    11. Configure the networks to apply to (check all if unsure) and then press + ā€œNextā€.
    12. +
    13. Add an appropriate name to the rule (e.g. ā€œTrilium Notesā€) and press ā€œFinishā€.
    14. +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend.html index 6446279a9e..d67f4cb73e 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend.html @@ -1,37 +1,135 @@ -

    Trilium (server edition) has a - mobile web frontend which is optimized for touch based devices - smartphones - and tablets. It is activated automatically during login process based on - browser detection.

    -

    Mobile frontend is limited in features compared to full desktop frontend. +

    + +
    +

    Trilium has a mobile web frontend which is optimized for touch based devices + - smartphones and tablets. It is activated automatically during login process + based on browser detection.

    +

    Mobile frontend is limited in features compared to the full desktop version. See below for more details on this.

    -

    Note that this is not an Android/iOS app, this is just mobile friendly - web page served on the server edition.

    -

    Screenshots

    -

    Mobile phone

    -

    - -

    -

    Tablet

    -

    - -

    -

    Limitations

    -

    Mobile frontend provides only some of the features of the full desktop - frontend:

    +

    Layout basics

    +

    Unlike the desktop version, the mobile version has a slightly different + UI meant to better fit the constrained screens of a mobile phone.

    +

    Here is a non-exhaustive list of differences between the desktop version + and the mobile one:

      -
    • it is possible to browse the whole note tree, read and edit all types - of notes, but you can create only text notes
    • -
    • reading and editing protected notes is - possible, but creating them is not supported
    • -
    • editing options is not supported
    • -
    • cloning notes is not supported
    • -
    • uploading file attachments is not supported
    • +
    • +

      The Note Tree is + displayed as a sidebar. To display the sidebar, press the button in the + top-left of the screen.

      +
        +
      • There is also a swipe gesture that can be done from the left of the screen, + but the browser's navigation gesture interferes with it most of the time + (depending on the platform).
      • +
      • Press and hold a note to display the Note tree contextual menu.
      • +
      +
    • +
    • +

      The Quick search bar + is also displayed at the top of the note tree.

      +
    • +
    • +

      The full Search function + can be triggered either from either the Global menu or from the Launch Bar, if configured.

      +
    • +
    • +

      The Launch Bar is + displayed at the bottom of the screen.

      +
        +
      • The launch bar uses a different configuration for icons than the desktop + version. See the dedicated page for more information on how to configure + it.
      • +
      +
    • +
    • +

      Most of the note-related actions are grouped in the horizontal dots icon + on the top-right of the note.

      +
    • +
    • +

      The Tabs are + grouped under a tab switcher in the Launch Bar, + where the tabs are displayed in a full-screen grid with preview for easy + switching, as well as additional options such as reopening closed tabs.

      +
    • +
    • +

      Since v0.100.0, Split View can + also be used in mobile view, but with a maximum of two panes at once. The + splits are displayed vertically instead of horizontally.

      +
    • +
    • +

      Starting with v0.102.0, the New Layout is + enforced on mobile. This brings features such as the note badges, note + type switcher or collection properties which would otherwise not be available.

      +
    +

    Installing as a PWA

    +

    The mobile view can be set up as a PWA. While this does not offer any + offline capabilities, it will display the application in full-screen and + makes it easy to access via your mobile phone's home screen.

    +

    On iOS with Safari

    +
      +
    1. Open your default web browser and access your Trilium instance.
    2. +
    3. Login.
    4. +
    5. Press the […] button in the bottom-right of the screen and select Share.
    6. +
    7. Scroll down to reveal the full list of items and choose ā€œAdd to Home Screenā€.
    8. +
    9. Press ā€œAddā€ and the web app will be available.
    10. +
    +

    On Android with Google Chrome

    + +
      +
    1. Open your default web browser and access your Trilium instance.
    2. +
    3. Login.
    4. +
    5. Press the three vertical dots icon in the top-right of the screen and + select Add to Home screen. +
    6. +
    7. Select the Install option.
    8. +
    9. Select an appropriate name.
    10. +
    11. The web app will appear as an application, not on the home screen.
    12. +
    +

    On Android with Brave

    + +
      +
    1. Open your default web browser and access your Trilium instance.
    2. +
    3. Login.
    4. +
    5. Press the three vertical dots icon in the bottom-right of the screen and + select Add to Home screen.
    6. +
    7. Press the Install option.
    8. +
    9. The web app will appear as an application, not on the home screen.
    10. +
    +

    On Samsung Browser

    +
      +
    1. Open your default web browser and access your Trilium instance.
    2. +
    3. Login.
    4. +
    5. Press the hamburger menu in the bottom-right of the screen.
    6. +
    7. Select Add to, followed by Home screen.
    8. +
    9. Press Add and the web app will appear on the home page.
    10. +
    +

    Testing via the desktop application

    +

    If you are running Trilium without a dedicated server installation, + you can still test the mobile application using the desktop application. + For more information, see Using the desktop application as a server. + To access it go to http://<ip>:37840/login?mobile .

    Forcing mobile/desktop frontend

    -

    Trilium decides automatically whether to use mobile or desktop frontend. - If this is not appropriate, you can use ?mobile or ?desktop query - param on login page (Note: you might need to log out).

    +

    Trilium decides automatically whether to use mobile or desktop front-end. + If this is not appropriate, you can use ?mobile or + ?desktopquery param on login page (Note: you might + need to log out).

    +

    Alternatively, simply select Switch to Mobile/Desktop Version in + the Global menu.

    Scripting

    -

    You can alter the behavior with scripts just - like for normal frontend. For script notes to be executed, they need to - have labeled #run=mobileStartup.

    \ No newline at end of file +

    You can alter the behavior with Scripting, + just like for normal frontend. For script notes to be executed, they need + to have labeled #run=mobileStartup.

    +

    Custom Launch Bar widgets + are also supported.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend_IMG_1765.PNG b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend_IMG_1765.PNG new file mode 100644 index 0000000000..5536b5ffbd Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend_IMG_1765.PNG differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-sma.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-sma.png deleted file mode 100644 index cd839420dd..0000000000 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-sma.png and /dev/null differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-tab.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-tab.png deleted file mode 100644 index 6d890f90db..0000000000 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-tab.png and /dev/null differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation.html index c1fcde150c..7b3a54250e 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation.html @@ -26,33 +26,36 @@

    Configuration

    After setting up your server installation, you may want to configure settings such as the port or enable TLS. Configuration - is managed via the Trilium config.ini file, which is located - in the data directory by default. - To begin customizing your setup, copy the provided config-sample.ini file - with default values to config.ini.

    + is managed via the Trilium config.ini file, + which is located in the data directory by + default. To begin customizing your setup, copy the provided config-sample.ini file + with default values to config.ini.

    You can also review the configuration file - to provide all config.ini values as environment variables instead.

    + to provide all config.ini values as environment + variables instead.

    Config Location

    -

    By default, config.ini, the database, +

    By default, config.ini, the database, and other important Trilium data files are stored in the data directory. - If you prefer a different location, you can change it by setting the TRILIUM_DATA_DIR environment - variable:

    export TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data
    + If you prefer a different location, you can change it by setting the + TRILIUM_DATA_DIRenvironment variable:

    export TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data

    Disabling / Modifying the Upload Limit

    If you're running into the 250MB limit imposed on the server by default, - and you'd like to increase the upload limit, you can set the TRILIUM_NO_UPLOAD_LIMIT environment - variable to true disable it completely:

    export TRILIUM_NO_UPLOAD_LIMIT=true 
    + and you'd like to increase the upload limit, you can set the TRILIUM_NO_UPLOAD_LIMIT environment + variable to true to disable it completely:

    export TRILIUM_NO_UPLOAD_LIMIT=true 

    Or, if you'd simply like to increase the upload limit size to something - beyond 250MB, you can set the MAX_ALLOWED_FILE_SIZE_MB environment - variable to something larger than the integer 250 (e.g. 450 in - the following example):

    export MAX_ALLOWED_FILE_SIZE_MB=450
    + beyond 250MB, you can set the MAX_ALLOWED_FILE_SIZE_MB environment + variable to something larger than the integer 250 (e.g. + 450in the following example):

    export MAX_ALLOWED_FILE_SIZE_MB=450

    Disabling Authentication

    See Authentication.

    Reverse Proxy Setup

    To configure a reverse proxy for Trilium, you can use either nginx or Apache. You can also check out the documentation stored in the Reverse proxy folder.

    nginx

    -

    Add the following configuration to your nginx setup to proxy - requests to Trilium:

    location /trilium/ {
    +

    Add the following configuration to your nginx setup + to proxy requests to Trilium:

    location /trilium/ {
         proxy_pass http://127.0.0.1:8080/;
         proxy_http_version 1.1;
         proxy_set_header Upgrade $http_upgrade;
    @@ -60,7 +63,7 @@
         proxy_set_header Host $host;
         proxy_cache_bypass $http_upgrade;
     }
    -

    To avoid limiting the size of payloads, include this in the server {} block:

    # Set to 0 for unlimited. Default is 1M.
    +

    To avoid limiting the size of payloads, include this in the server {} block:

    # Set to 0 for unlimited. Default is 1M.
     client_max_body_size 0;

    Apache

    For an Apache setup, refer to the Apache proxy setup guide.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually.html index f7138444da..d61946a18c 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually.html @@ -19,8 +19,10 @@ its derivatives (like Ubuntu) below:

    sudo apt install libpng16-16 libpng-dev pkg-config autoconf libtool build-essential nasm libx11-dev libxkbfile-dev

    Installation

    Download

    -

    You can either download source code zip/tar from https://github.com/TriliumNext/Notes/releases/latest.

    -

    For the latest version including betas, clone Git repository from main branch with:

    git clone -b main https://github.com/triliumnext/notes.git
    +

    You can either download source code zip/tar from https://github.com/TriliumNext/Trilium/releases/latest.

    +

    For the latest version including betas, clone Git repository from + main branch with:

    git clone -b main https://github.com/triliumnext/trilium.git

    Installation

    cd trilium
     
     # download all node dependencies
    @@ -39,5 +41,5 @@ nohup TRILIUM_ENV=dev node src/www &
    browser and navigate to http://localhost:8080 to access Trilium (replace "localhost" with your hostname).

    TLS

    -

    Don't forget to configure TLS which - is required for secure usage!

    \ No newline at end of file +

    Don't forget to configure TLS which is + required for secure usage!

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Multiple server instances.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Multiple server instances.html index 91a0d2241a..40be44230c 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Multiple server instances.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Multiple server instances.html @@ -9,7 +9,7 @@ class="reference-link" href="#root/_help_J1Bb6lVlwU5T">Manually, if starting the server manually just specify a different port and data directory per instance:

    TRILIUM_NETWORK_PORT=8080 TRILIUM_DATA_DIR=/path/to/your/data-dir-A /opt/trilium/trilium.sh

    For a second instance:

    TRILIUM_NETWORK_PORT=8081 TRILIUM_DATA_DIR=/path/to/your/data-dir-B /opt/trilium/trilium.sh
    -

    If using systemd, then set the environment variables in the service configuration.

    +

    If using systemd, then set the environment variables in the service configuration.

  • For Using Docker, diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/On NixOS.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/On NixOS.html index b965f62fc6..4955dda602 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/On NixOS.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/On NixOS.html @@ -2,7 +2,7 @@

    Requirements

    NixOS installation.

    Configuration

    -

    Add this to your configuration.nix:

    services.trilium-server.enable = true;
    +

    Add this to your configuration.nix:

    services.trilium-server.enable = true;
     
     # default data directory: /var/lib/trilium
     #services.trilium-server.dataDir = "/var/lib/trilium-sync-server";
    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux.html
    index 8cff3851b0..b0ca40607d 100644
    --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux.html	
    +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux.html	
    @@ -3,14 +3,15 @@
     

    Steps

    • SSH into your server
    • -
    • use wget (or curl) to download latest TriliumNotes-Server-[VERSION]-linux-x64.tar.xz (copy - link from release page, - notice -Server suffix) on your server.
    • -
    • unpack the archive, e.g. using tar -xf -d TriliumNotes-Server-[VERSION]-linux-x64.tar.xz +
    • use wget (or curl) + to download latest TriliumNotes-Server-[VERSION]-linux-x64.tar.xz (copy + link from release page, + notice -Server suffix) on your server.
    • +
    • unpack the archive, e.g. using tar -xf -d TriliumNotes-Server-[VERSION]-linux-x64.tar.xz
    • -
    • cd trilium-linux-x64-server +
    • cd trilium-linux-x64-server
    • -
    • ./trilium.sh +
    • ./trilium.sh
    • you can open the browser and open http://[your-server-hostname]:8080 and you should see Trilium initialization page
    • @@ -18,9 +19,10 @@

      The problem with above steps is that once you close the SSH connection, the Trilium process is terminated. To avoid that, you have two options:

        -
      • Kill it (with e.g. Ctrl + C) and run again like this: nohup ./trilium.sh &. - (nohup keeps the process running in the background, & runs - it in the background)
      • +
      • Kill it (with e.g. Ctrl + C) and run again like this: + nohup ./trilium.sh &. (nohup keeps the process running in the + background, & runs it in the background)
      • Configure systemd to automatically run Trilium in the background on every boot
      @@ -59,6 +61,102 @@ WantedBy=multi-user.target
  • You can now open a browser to http://[your-server-hostname]:8080 and you should see the Trilium initialization page.
  • +

    Simple Autoupdate for Server

    +

    Run as the same User Trilium runs

    +

    if you run as root please remove 'sudo' from the commands

    +

    requires "jq" apt install jq +

    +

    It will stop the service above, overwrite everything (i expect no config.ini), + and start service It also creates a version file in the Trilium directory + so it updates only with a newer Version

    #!/bin/bash
    +
    +# Configuration
    +REPO="TriliumNext/Trilium"
    +PATTERN="TriliumNotes-Server-.*-linux-x64.tar.xz"
    +DOWNLOAD_DIR="/var/tmp/trilium_download"
    +OUTPUT_DIR="/opt/trilium"
    +SERVICE_NAME="trilium"
    +VERSION_FILE="$OUTPUT_DIR/version.txt"
    +
    +# Ensure dependencies are installed
    +command -v curl >/dev/null 2>&1 || { echo "Error: curl is required"; exit 1; }
    +command -v jq >/dev/null 2>&1 || { echo "Error: jq is required"; exit 1; }
    +command -v tar >/dev/null 2>&1 || { echo "Error: tar is required"; exit 1; }
    +
    +# Create download directory
    +mkdir -p "$DOWNLOAD_DIR" || { echo "Error: Cannot create $DOWNLOAD_DIR"; exit 1; }
    +
    +# Get the latest release version
    +LATEST_VERSION=$(curl -sL https://api.github.com/repos/$REPO/releases/latest | jq -r '.tag_name')
    +if [ -z "$LATEST_VERSION" ]; then
    +  echo "Error: Could not fetch latest release version"
    +  exit 1
    +fi
    +
    +# Check current installed version (from version.txt or existing tarball)
    +CURRENT_VERSION=""
    +if [ -f "$VERSION_FILE" ]; then
    +  CURRENT_VERSION=$(cat "$VERSION_FILE")
    +elif [ -f "$DOWNLOAD_DIR/TriliumNotes-Server-$LATEST_VERSION-linux-x64.tar.xz" ]; then
    +  CURRENT_VERSION="$LATEST_VERSION"
    +fi
    +
    +# Compare versions
    +if [ "$CURRENT_VERSION" = "$LATEST_VERSION" ]; then
    +  echo "Latest version ($LATEST_VERSION) is already installed"
    +  exit 0
    +fi
    +
    +# Download the latest release
    +LATEST_URL=$(curl -sL https://api.github.com/repos/$REPO/releases/latest | jq -r ".assets[] | select(.name | test(\"$PATTERN\")) | .browser_download_url")
    +if [ -z "$LATEST_URL" ]; then
    +  echo "Error: No asset found matching pattern '$PATTERN'"
    +  exit 1
    +fi
    +
    +FILE_NAME=$(basename "$LATEST_URL")
    +FILE_PATH="$DOWNLOAD_DIR/$FILE_NAME"
    +
    +# Download if not already present
    +if [ -f "$FILE_PATH" ]; then
    +  echo "Latest release $FILE_NAME already downloaded"
    +else
    +  curl -LO --output-dir "$DOWNLOAD_DIR" "$LATEST_URL" || { echo "Error: Download failed"; exit 1; }
    +  echo "Downloaded $FILE_NAME to $DOWNLOAD_DIR"
    +fi
    +
    +# Extract the tarball
    +EXTRACT_DIR="$DOWNLOAD_DIR/extracted"
    +mkdir -p "$EXTRACT_DIR"
    +tar -xJf "$FILE_PATH" -C "$EXTRACT_DIR" || { echo "Error: Extraction failed"; exit 1; }
    +
    +# Find the extracted directory (e.g., TriliumNotes-Server-0.97.2-linux-x64)
    +INNER_DIR=$(find "$EXTRACT_DIR" -maxdepth 1 -type d -name "TriliumNotes-Server-*-linux-x64" | head -n 1)
    +if [ -z "$INNER_DIR" ]; then
    +  echo "Error: Could not find extracted directory matching TriliumNotes-Server-*-linux-x64"
    +  exit 1
    +fi
    +
    +# Stop the trilium-server service
    +if systemctl is-active --quiet "$SERVICE_NAME"; then
    +  echo "Stopping $SERVICE_NAME service..."
    +  sudo systemctl stop "$SERVICE_NAME" || { echo "Error: Failed to stop $SERVICE_NAME"; exit 1; }
    +fi
    +
    +# Copy contents to /opt/trilium, overwriting existing files
    +echo "Copying contents from $INNER_DIR to $OUTPUT_DIR..."
    +sudo mkdir -p "$OUTPUT_DIR"
    +sudo cp -r "$INNER_DIR"/* "$OUTPUT_DIR"/ || { echo "Error: Copy failed"; exit 1; }
    +echo "$LATEST_VERSION" | sudo tee "$VERSION_FILE" >/dev/null
    +echo "Files copied to $OUTPUT_DIR"
    +
    +# Start the trilium-server service
    +echo "Starting $SERVICE_NAME service..."
    +sudo systemctl start "$SERVICE_NAME" || { echo "Error: Failed to start $SERVICE_NAME"; exit 1; }
    +
    +# Clean up
    +rm -rf "$EXTRACT_DIR"
    +echo "Cleanup complete. Trilium updated to $LATEST_VERSION."

    Common issues

    Outdated glibc

    Error: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /var/www/virtual/.../node_modules/@mlink/scrypt/build/Release/scrypt.node)
         at Object.Module._extensions..node (module.js:681:18)
    @@ -67,5 +165,5 @@ WantedBy=multi-user.target

    If you get an error like this, you need to either upgrade your glibc (typically by upgrading to up-to-date distribution version) or use some other server installation method.

    TLS

    -

    Don't forget to configure TLS, which - is required for secure usage!

    \ No newline at end of file +

    Don't forget to configure TLS, which is + required for secure usage!

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.html index 60e5d049e6..016662b751 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.html @@ -1,6 +1,6 @@

    Official docker images are published on docker hub for AMD64, ARMv7 and ARM64/v8: https://hub.docker.com/r/triliumnext/notes/ + href="https://hub.docker.com/r/triliumnext/trilium/">https://hub.docker.com/r/triliumnext/trilium/

    Prerequisites

    Ensure Docker is installed on your system.

    @@ -11,22 +11,25 @@

    Running with Docker Compose

    -

    Grab the latest docker-compose.yml:

    wget https://raw.githubusercontent.com/TriliumNext/Notes/master/docker-compose.yml
    -

    Optionally, edit the docker-compose.yml file to configure the - container settings prior to starting it. Unless configured otherwise, the - data directory will be ~/trilium-data and the container will - be accessible at port 8080.

    +

    Grab the latest docker-compose.yml:

    wget https://raw.githubusercontent.com/TriliumNext/Trilium/master/docker-compose.yml
    +

    Optionally, edit the docker-compose.yml file + to configure the container settings prior to starting it. Unless configured + otherwise, the data directory will be ~/trilium-data and + the container will be accessible at port 8080.

    Start the container:

    Run the following command to start the container in the background:

    docker compose up -d

    Running without Docker Compose / Further Configuration

    Pulling the Docker Image

    -

    To pull the image, use the following command, replacing [VERSION] with - the desired version or tag, such as v0.91.6 or just latest. - (See published tag names at https://hub.docker.com/r/triliumnext/notes/tags.):

    docker pull triliumnext/notes:v0.91.6
    +

    To pull the image, use the following command, replacing [VERSION] with + the desired version or tag, such as v0.91.6 or + just latest. (See published tag names at + https://hub.docker.com/r/triliumnext/trilium/tags.):

    docker pull triliumnext/trilium:v0.91.6

    Warning: Avoid using the "latest" tag, as it may automatically upgrade your instance to a new minor version, potentially disrupting sync setups or causing other issues.

    @@ -37,28 +40,29 @@

    Local Access Only

    Run the container to make it accessible only from the localhost. This setup is suitable for testing or when using a proxy server like Nginx or - Apache.

    sudo docker run -t -i -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:[VERSION]
    + Apache.

    sudo docker run -t -i -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/trilium:[VERSION]
      -
    1. Verify the container is running using docker ps.
    2. -
    3. Access Trilium via a web browser at 127.0.0.1:8080.
    4. +
    5. Verify the container is running using docker ps.
    6. +
    7. Access Trilium via a web browser at 127.0.0.1:8080.

    Local Network Access

    To make the container accessible only on your local network, first create a new Docker network:

    docker network create -d macvlan -o parent=eth0 --subnet 192.168.2.0/24 --gateway 192.168.2.254 --ip-range 192.168.2.252/27 mynet
    -

    Then, run the container with the network settings:

    docker run --net=mynet -d -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:-latest
    +

    Then, run the container with the network settings:

    docker run --net=mynet -d -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/trilium:-latest

    To set a different user ID (UID) and group ID (GID) for the saved data, - use the USER_UID and USER_GID environment variables:

    docker run --net=mynet -d -p 127.0.0.1:8080:8080 -e "USER_UID=1001" -e "USER_GID=1001" -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:-latest
    -

    Find the local IP address using docker inspect [container_name] and + use the USER_UID and USER_GID environment + variables:

    docker run --net=mynet -d -p 127.0.0.1:8080:8080 -e "USER_UID=1001" -e "USER_GID=1001" -v ~/trilium-data:/home/node/trilium-data triliumnext/trilium:-latest
    +

    Find the local IP address using docker inspect [container_name] and access the service from devices on the local network.

    docker ps
     docker inspect [container_name]

    Global Access

    -

    To allow access from any IP address, run the container as follows:

    docker run -d -p 0.0.0.0:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:[VERSION]
    -

    Stop the container with docker stop <CONTAINER ID>, - where the container ID is obtained from docker ps.

    +

    To allow access from any IP address, run the container as follows:

    docker run -d -p 0.0.0.0:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/trilium:[VERSION]
    +

    Stop the container with docker stop <CONTAINER ID>, + where the container ID is obtained from docker ps.

    Custom Data Directory

    -

    For a custom data directory, use:

    -v ~/YourOwnDirectory:/home/node/trilium-data triliumnext/notes:[VERSION]
    +

    For a custom data directory, use:

    -v ~/YourOwnDirectory:/home/node/trilium-data triliumnext/trilium:[VERSION]

    If you want to run your instance in a non-default way, please use the - volume switch as follows: -v ~/YourOwnDirectory:/home/node/trilium-data triliumnext/notes:<VERSION>. + volume switch as follows: -v ~/YourOwnDirectory:/home/node/trilium-data triliumnext/trilium:<VERSION>. It is important to be aware of how Docker works for volumes, with the first path being your own and the second the one to virtually bind to. https://docs.docker.com/storage/volumes/ The path before the colon is the host directory, and the path after the colon @@ -71,28 +75,31 @@ docker inspect [container_name]

  • Note on --user Directive

    -

    The --user directive is unsupported. Instead, use the USER_UID and USER_GID environment +

    The --user directive is unsupported. Instead, + use the USER_UID and USER_GID environment variables to set the appropriate user and group IDs.

    Note on timezones

    If you are having timezone issues and you are not using docker-compose, - you may need to add a TZ environment variable with the TZ identifier of + you may need to add a TZ environment variable + with the TZ identifier of your local timezone.

    Rootless Docker Image

    If you would prefer to run Trilium without having to run the Docker container - as root, you can use either of the provided Debian (default) - and Alpine-based images with the rootless tag. 

    + as root, you can use either of the provided + Debian (default) and Alpine-based images with the rootless tag. 

    If you're unsure, stick to the ā€œrootfulā€ Docker image referenced above.

    Below are some commands to pull the rootless images:

    # For Debian-based image
    -docker pull triliumnext/notes:rootless
    +docker pull triliumnext/trilium:rootless
     
     # For Alpine-based image
    -docker pull triliumnext/notes:rootless-alpine
    +docker pull triliumnext/trilium:rootless-alpine

    Why Rootless?

    Running containers as non-root is a security best practice that reduces the potential impact of container breakouts. If an attacker manages to @@ -101,10 +108,11 @@ docker pull triliumnext/notes:rootless-alpine

    How It Works

    The rootless Trilium image:

      -
    1. Creates a non-root user (trilium) during build time
    2. +
    3. Creates a non-root user (trilium) during + build time
    4. Configures the application to run as this non-root user
    5. -
    6. Allows runtime customization of the user's UID/GID via Docker's --user flag
    7. -
    8. Does not require a separate Docker entrypoint script
    9. +
    10. Allows runtime customization of the user's UID/GID via Docker's --user flag
    11. +
    12. Does not require a separate Docker entrypoint script

    Usage

    Using docker-compose (Recommended)

    # Run with default UID/GID (1000:1000)
    @@ -117,30 +125,33 @@ TRILIUM_UID=$(id -u) TRILIUM_GID=$(id -g) docker-compose -f docker-compose.rootl
     TRILIUM_DATA_DIR=/path/to/your/data TRILIUM_UID=$(id -u) TRILIUM_GID=$(id -g) docker-compose -f docker-compose.rootless.yml up -d
     

    Using Docker CLI

    # Build the image
    -docker build -t triliumnext/notes:rootless -f apps/server/Dockerfile.rootless .
    +docker build -t triliumnext/trilium:rootless -f apps/server/Dockerfile.rootless .
     
     # Run with default UID/GID (1000:1000)
    -docker run -d --name trilium -p 8080:8080 -v ~/trilium-data:/home/trilium/trilium-data triliumnext/notes:rootless
    +docker run -d --name trilium -p 8080:8080 -v ~/trilium-data:/home/trilium/trilium-data triliumnext/trilium:rootless
     
     # Run with custom UID/GID
    -docker run -d --name trilium -p 8080:8080 --user $(id -u):$(id -g) -v ~/trilium-data:/home/trilium/trilium-data triliumnext/notes:rootless
    +docker run -d --name trilium -p 8080:8080 --user $(id -u):$(id -g) -v ~/trilium-data:/home/trilium/trilium-data triliumnext/trilium:rootless
     

    Environment Variables

      -
    • TRILIUM_UID: UID to use for the container process (passed - to Docker's --user flag)
    • -
    • TRILIUM_GID: GID to use for the container process (passed - to Docker's --user flag)
    • -
    • TRILIUM_DATA_DIR: Path to the data directory inside the container - (default: /home/node/trilium-data)
    • +
    • TRILIUM_UID: UID to use for the container + process (passed to Docker's --user flag)
    • +
    • TRILIUM_GID: GID to use for the container + process (passed to Docker's --user flag)
    • +
    • TRILIUM_DATA_DIR: Path to the data directory + inside the container (default: /home/node/trilium-data)
    +

    For a complete list of configuration environment variables (network settings, + authentication, sync, etc.), see Configuration (config.ini or environment variables).

    Volume Permissions

    If you encounter permission issues with the data volume, ensure that:

    1. The host directory has appropriate permissions for the UID/GID you're using
    2. -
    3. You're setting both TRILIUM_UID and TRILIUM_GID to - match the owner of the host directory
    4. +
    5. You're setting both TRILIUM_UID and + TRILIUM_GIDto match the owner of the host directory
    # For example, if your data directory is owned by UID 1001 and GID 1001:
     TRILIUM_UID=1001 TRILIUM_GID=1001 docker-compose -f docker-compose.rootless.yml up -d
     
    @@ -149,7 +160,7 @@ TRILIUM_UID=1001 TRILIUM_GID=1001 docker-compose -f docker-compose.rootless.yml
  • The container starts with a specific UID/GID which can be customized at runtime
  • Unlike the traditional setup, this approach does not use a separate entrypoint - script with usermod/groupmod commands
  • + script with usermod/groupmod commands
  • The container cannot modify its own UID/GID at runtime, which is a security feature of rootless containers
  • @@ -159,7 +170,7 @@ TRILIUM_UID=1001 TRILIUM_GID=1001 docker-compose -f docker-compose.rootless.yml
  • Debian-based (default): Uses the Debian Bullseye Slim base image
      -
    • Dockerfile: apps/server/Dockerfile.rootless +
    • Dockerfile: apps/server/Dockerfile.rootless
    • Recommended for most users
    @@ -167,7 +178,7 @@ TRILIUM_UID=1001 TRILIUM_GID=1001 docker-compose -f docker-compose.rootless.yml
  • Alpine-based: Uses the Alpine base image for smaller size
      -
    • Dockerfile: apps/server/Dockerfile.alpine.rootless +
    • Dockerfile: apps/server/Dockerfile.alpine.rootless
    • Smaller image size, but may have compatibility issues with some systems
    @@ -176,15 +187,18 @@ TRILIUM_UID=1001 TRILIUM_GID=1001 docker-compose -f docker-compose.rootless.yml

    Building Custom Rootless Images

    If you would prefer, you can also customize the UID/GID at build time:

    # For Debian-based image with custom UID/GID
     docker build --build-arg USER=myuser --build-arg UID=1001 --build-arg GID=1001 \
    -  -t triliumnext/notes:rootless-custom -f apps/server/Dockerfile.rootless .
    +  -t triliumnext/trilium:rootless-custom -f apps/server/Dockerfile.rootless .
     
     # For Alpine-based image with custom UID/GID
     docker build --build-arg USER=myuser --build-arg UID=1001 --build-arg GID=1001 \
    -  -t triliumnext/notes:alpine-rootless-custom -f apps/server/Dockerfile.alpine.rootless .
    +  -t triliumnext/trilium:alpine-rootless-custom -f apps/server/Dockerfile.alpine.rootless .
     

    Available build arguments:

      -
    • USER: Username for the non-root user (default: trilium)
    • -
    • UID: User ID for the non-root user (default: 1000)
    • -
    • GID: Group ID for the non-root user (default: 1000)
    • +
    • USER: Username for the non-root user (default: + trilium)
    • +
    • UID: User ID for the non-root user (default: + 1000)
    • +
    • GID: Group ID for the non-root user (default: + 1000)
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Kubernetes.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Kubernetes.html index 0fb29eb7ed..efcae48860 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Kubernetes.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Kubernetes.html @@ -5,17 +5,18 @@

    Root privileges

    The Trilium docker container needs to be run with root privileges. The node process inside the container will be started with reduced privileges (uid:gid 1000:1000) after some initialization logic. Please make sure that you don't use a security context (PodSecurityContext) which changes the user ID. To use a different uid:gid for file storage and the application, - please use the USER_UID & USER_GID environment + please use the USER_UID & USER_GID environment variables.

    -

    The docker image will also fix the permissions of /home/node so +

    The docker image will also fix the permissions of /home/node so you don't have to use an init container.

    Helm Charts

    Official Helm chart from @@ -27,7 +28,7 @@

    Below is an example of how

    helm repo add trilium https://triliumnext.github.io/helm-charts
     "trilium" has been added to your repositories

    How to install a chart

    -

    After reviewing the values.yaml from +

    After reviewing the values.yaml from the Helm chart, modifying as required and then creating your own:

    helm install --create-namespace --namespace trilium trilium trilium/trilium -f values.yaml

    For more information on using Helm, please refer to the Helm documentation, or create a Discussion in the TriliumNext GitHub Organization.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache using Docker.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache using Docker.html new file mode 100644 index 0000000000..58f5f67550 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache using Docker.html @@ -0,0 +1,76 @@ +

    This tutorial assumes that you have created a DNS A record for trilium.yourdomain.com that + you want to use for your Trilium server.

    +

    Docker setup

    +

    Download docker image and create container

     docker pull triliumnext/trilium:[VERSION]
    + docker create --name trilium -t -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/trilium:[VERSION]
    +

    Configuring the Apache proxy

    +
      +
    1. +

      Enable apache proxy modules

       a2enmod ssl
      + a2enmod proxy
      + a2enmod proxy_http
      + a2enmod proxy_wstunnel
      +
    2. +
    3. +

      Create a new let's encrypt certificate

       sudo certbot certonly -d trilium.mydomain.com
      +

      Choose standalone (2) and note the location of the created certificates + (typically /etc/letsencrypt/live/...)

      +
    4. +
    5. +

      Create a new virtual host file for apache (you may want to use apachectl -S to + determine the server root location, mine is /etc/apache2)

       sudo nano /etc/apache2/sites-available/trilium.yourdomain.com.conf
      +

      Paste (and customize) the following text into the configuration file

       
      +     ServerName http://trilium.yourdomain.com
      +     RewriteEngine on
      +         RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
      + 
      + 
      +     ServerName https://trilium.yourdomain.com
      +     RewriteEngine On
      +     RewriteCond %{HTTP:Connection} Upgrade [NC]
      +     RewriteCond %{HTTP:Upgrade} websocket [NC]
      +     RewriteRule /(.*) ws://localhost:8080/$1 [P,L]
      +     AllowEncodedSlashes NoDecode
      +     ProxyPass / http://localhost:8080/ nocanon
      +     ProxyPassReverse / http://localhost:8080/
      +     SSLCertificateFile /etc/letsencrypt/live/trilium.yourdomain.com/fullchain.pem
      +     SSLCertificateKeyFile /etc/letsencrypt/live/trilium.yourdomain.com/privkey.pem
      +     Include /etc/letsencrypt/options-ssl-apache.conf
      + 
      +
    6. +
    7. +

      Enable the virtual host with sudo a2ensite trilium.yourdomain.com.conf +

      +
    8. +
    9. +

      Reload apache2 with sudo systemctl reload apache2 +

      +
    10. +
    +

    Configuring the trusted proxy

    +

    After setting up a reverse proxy, make sure to configure the Trusted proxy.

    +

    Setup the systemd service to start up the server

    +

    Create and enable a systemd service to start the docker container on boot

    +
      +
    1. +

      Create a new empty file called /lib/systemd/system/trilium.service with + the contents

       [Unit]
      + Description=Trilium Server
      + Requires=docker.service
      + After=docker.service
      +
      + [Service]
      + Restart=always
      + ExecStart=/usr/bin/docker start -a trilium
      + ExecStop=/usr/bin/docker stop -t 2 trilium
      +
      + [Install]
      + WantedBy=local.target
      +
    2. +
    3. +

      Install, enable and start service

       sudo systemctl daemon-reload
      + sudo systemctl enable trilium.service
      + sudo systemctl start trilium.service
      +
    4. +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache.html deleted file mode 100644 index ffb2f921dc..0000000000 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache.html +++ /dev/null @@ -1,79 +0,0 @@ -

    I've assumed you have created a DNS A record for trilium.yourdomain.com that - you want to use for your Trilium server.

    -
      -
    1. -

      Download docker image and create container

       docker pull triliumnext/notes:[VERSION]
      - docker create --name trilium -t -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:[VERSION]
      -
    2. -
    3. -

      Configure Apache proxy and websocket proxy

      -
        -
      1. -

        Enable apache proxy modules

         a2enmod ssl
        - a2enmod proxy
        - a2enmod proxy_http
        - a2enmod proxy_wstunnel
        -
      2. -
      3. -

        Create a new let's encrypt certificate

         sudo certbot certonly -d trilium.mydomain.com
        -

        Choose standalone (2) and note the location of the created certificates - (typically /etc/letsencrypt/live/...)

        -
      4. -
      5. -

        Create a new virtual host file for apache (you may want to use apachectl -S to - determine the server root location, mine is /etc/apache2)

         sudo nano /etc/apache2/sites-available/trilium.yourdomain.com.conf
        -

        Paste (and customize) the following text into the configuration file

         
        -     ServerName http://trilium.yourdomain.com
        -     RewriteEngine on
        -         RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
        - 
        - 
        -     ServerName https://trilium.yourdomain.com
        -     RewriteEngine On
        -     RewriteCond %{HTTP:Connection} Upgrade [NC]
        -     RewriteCond %{HTTP:Upgrade} websocket [NC]
        -     RewriteRule /(.*) ws://localhost:8080/$1 [P,L]
        -     AllowEncodedSlashes NoDecode
        -     ProxyPass / http://localhost:8080/ nocanon
        -     ProxyPassReverse / http://localhost:8080/
        -     SSLCertificateFile /etc/letsencrypt/live/trilium.yourdomain.com/fullchain.pem
        -     SSLCertificateKeyFile /etc/letsencrypt/live/trilium.yourdomain.com/privkey.pem
        -     Include /etc/letsencrypt/options-ssl-apache.conf
        - 
        -
      6. -
      7. -

        Enable the virtual host with sudo a2ensite trilium.yourdomain.com.conf -

        -
      8. -
      9. -

        Reload apache2 with sudo systemctl reload apache2 -

        -
      10. -
      -
    4. -
    5. -

      Create and enable a systemd service to start the docker container on boot

      -
        -
      1. -

        Create a new empty file called /lib/systemd/system/trilium.service with - the contents

         [Unit]
        - Description=Trilium Server
        - Requires=docker.service
        - After=docker.service
        -
        - [Service]
        - Restart=always
        - ExecStart=/usr/bin/docker start -a trilium
        - ExecStop=/usr/bin/docker stop -t 2 trilium
        -
        - [Install]
        - WantedBy=local.target
        -
      2. -
      3. -

        Install, enable and start service

         sudo systemctl daemon-reload
        - sudo systemctl enable trilium.service
        - sudo systemctl start trilium.service
        -
      4. -
      -
    6. -
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx.html index 7b7e958a0d..c8a4cee60d 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx.html @@ -1,11 +1,11 @@ -

    Configure Nginx proxy and HTTPS. The operating system here is Ubuntu 18.04.

    +

    Configure Nginx proxy and HTTPS. The operating system here is Ubuntu.

    +

    Installing Nginx

    +

    Download Nginx and remove Apache2

    sudo apt-get install nginx
    +sudo apt-get remove apache2
    +

    Build the configuration file

    1. -

      Download Nginx and remove Apache2

      sudo apt-get install nginx
      -sudo apt-get remove apache2
      -
    2. -
    3. -

      Create configure file

      cd /etc/nginx/conf.d
      +    

      First, create the configuration file:

      cd /etc/nginx/conf.d
       vim default.conf
    4. @@ -48,16 +48,19 @@ server { return 301 https://$server_name$request_uri; }
    5. -
    6. -

      Alternatively if you want to serve the instance under a different path - (useful e.g. if you want to serve multiple instances), update the location - block like so:

      -
        -
      • update the location with your desired path (make sure to not leave a trailing - slash "/", if your proxy_pass does not end on a slash as well)
      • -
      • add the proxy_cookie_path directive with the same path: this - allows you to stay logged in at multiple instances at the same time.
      • -
          location /trilium/instance-one {
      +
    +

    Serving under a different path

    +

    Alternatively if you want to serve the instance under a different path + (useful e.g. if you want to serve multiple instances), update the location + block like so:

    +
      +
    • update the location with your desired path (make sure to not leave a trailing + slash "/", if your proxy_pass does not end + on a slash as well)
    • +
    • add the proxy_cookie_path directive with + the same path: this allows you to stay logged in at multiple instances + at the same time.
    • +
        location /trilium/instance-one {
             rewrite /trilium/instance-one/(.*) /$1  break;
             proxy_set_header Host $host;
             proxy_set_header X-Real-IP $remote_addr;
    @@ -68,7 +71,7 @@ server {
             proxy_pass http://trilium;
             proxy_cookie_path / /trilium/instance-one
             proxy_read_timeout 90;
    -    }
    -
    -
  • - \ No newline at end of file + } +

    Configuring the trusted proxy

    +

    After setting up a reverse proxy, make sure to configure the Trusted proxy.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik.html new file mode 100644 index 0000000000..b2aea2650c --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik.html @@ -0,0 +1,67 @@ +

    The goal of this article is to configure Traefik proxy and HTTPS. See + #7768for reference.

    +

    Breaking change in Traefik 3.6.4

    +

    Traefik 3.6.4 introduced a breaking change regarding + how percent-encoded characters are handled in URLs. More specifically some + URLs used by Trilium (such as search/%23workspace%20%23!template) + are automatically rejected by Traefik, resulting in HTTP 400 errors.

    +

    To solve this, the Traefik static configuration must + be modified in order to allow those characters:

    entryPoints:
    +  web:
    +    http:
    +      encodedCharacters:
    +        allowEncodedSlash: true
    +        allowEncodedHash: true
    + +

    Build the docker-compose file

    +

    Setting up Traefik as reverse proxy requires setting the following labels:

        labels:
    +      - traefik.enable=true
    +      - traefik.http.routers.trilium.entrypoints=https
    +      - traefik.http.routers.trilium.rule=Host(`trilium.mydomain.tld`)
    +      - traefik.http.routers.trilium.tls=true
    +      - traefik.http.routers.trilium.service=trilium
    +      - traefik.http.services.trilium.loadbalancer.server.port=8080
    +      # scheme must be HTTP instead of the usual HTTPS because Trilium listens on HTTP internally
    +      - traefik.http.services.trilium.loadbalancer.server.scheme=http
    +      - traefik.docker.network=proxy
    +      # forward HTTP to HTTPS
    +      - traefik.http.routers.trilium.middlewares=trilium-headers@docker
    +      - traefik.http.middlewares.trilium-headers.headers.customrequestheaders.X-Forwarded-Proto=https
    +

    Setup needed environment variables

    +

    After setting up a reverse proxy, make sure to configure the Trusted proxy.

    +

    Example docker-compose.yaml

    services:
    +  trilium:
    +    image: triliumnext/trilium
    +    container_name: trilium
    +    networks:
    +      - traefik-proxy
    +    environment:
    +      - TRILIUM_NETWORK_TRUSTEDREVERSEPROXY=my-traefik-host-ip # e.g., 172.18.0.0/16
    +    volumes:
    +      - /path/to/data:/home/node/trilium-data
    +      - /etc/timezone:/etc/timezone:ro
    +      - /etc/localtime:/etc/localtime:ro
    +    labels:
    +      - traefik.enable=true
    +      - traefik.http.routers.trilium.entrypoints=https
    +      - traefik.http.routers.trilium.rule=Host(`trilium.mydomain.tld`)
    +      - traefik.http.routers.trilium.tls=true
    +      - traefik.http.routers.trilium.service=trilium
    +      - traefik.http.services.trilium.loadbalancer.server.port=8080
    +      # scheme must be HTTP instead of the usual HTTPS because of how trilium works
    +      - traefik.http.services.trilium.loadbalancer.server.scheme=http
    +      - traefik.docker.network=traefik-proxy
    +      # Tell Trilium the original request was HTTPS
    +      - traefik.http.routers.trilium.middlewares=trilium-headers@docker
    +      - traefik.http.middlewares.trilium-headers.headers.customrequestheaders.X-Forwarded-Proto=https
    +
    +networks:
    +  traefik-proxy:
    +    external: true
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Trusted proxy.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Trusted proxy.html new file mode 100644 index 0000000000..d18e9fadcb --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Trusted proxy.html @@ -0,0 +1,11 @@ +

    If you are running the Trilium server under a reverse proxy, + it's important to configure it as a trusted proxy so that the application + can correctly identify the real IP address of the clients (for authentication + and rate limiting purposes).

    +

    To do so, simply modify Configuration (config.ini or environment variables) and + set:

    [Network]
    +trustedReverseProxy=true
    +

    This will use the left-most IP in the X-Forwarded-For header. + Alternatively, instead of true use the IP + address of the reverse proxy or Express.js shortcuts such as:

    loopback(127.0.0.1/8, ::1/128), linklocal(169.254.0.0/16, fe80::/10), uniquelocal(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7)
    +

    For more information, consult Express behind proxies.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Authentication.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Authentication.html index 55a085b4bb..4c7331c82a 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Authentication.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Authentication.html @@ -1,19 +1,18 @@

    Disabling authentication

    -

    If you are running Trilium on localhost only or if authentication - is handled by another component, you can disable Trilium’s authentication - by adding the following to config.ini:

    [General]
    +

    If you are running Trilium on localhost only + or if authentication is handled by another component, you can disable Trilium’s + authentication by adding the following to config.ini:

    [General]
     noAuthentication=true

    Disabling authentication will bypass even the Multi-Factor Authentication since - v0.94.1.

    + href="#root/_help_7DAiwaf8Z7Rz">Multi-Factor Authentication since v0.94.1.

    Understanding how the session works

    Once logged into Trilium, the application will store this information about the login into a cookie on the browser, but also as a session on the server.

    If ā€œRemember meā€ is checked, then the login will expire in 21 days. This - period can be adjusted by modifying the Session.cookieMaxAge value - in config.ini. For example, to have the session expire in one - day:

    [Session]
    +  period can be adjusted by modifying the Session.cookieMaxAge value
    +  in config.ini. For example, to have the
    +  session expire in one day:

    [Session]
     cookieMaxAge=86400

    When ā€œRemember meā€ is unchecked, the behavior is different. At client/browser level the authentication does not have any expiration date, but it will @@ -22,10 +21,9 @@ cookieMaxAge=86400

    the last interaction with the application.

    Viewing active sessions

    The login sessions are now stored in the same Database as the user data. In - order to view which sessions are active, open the SQL Console and run the following - query:

    SELECT * FROM sessions
    + href="#root/_help_wX4HbRucYSDD">Database as the user data. In order + to view which sessions are active, open the SQL Console and run the following query:

    SELECT * FROM sessions

    Expired sessions are periodically cleaned by the server, generally an hourly interval.

    See also

    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/HTTPS (TLS).html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/HTTPS (TLS).html new file mode 100644 index 0000000000..296149a010 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/HTTPS (TLS).html @@ -0,0 +1,53 @@ +

    Configuring TLS is essential for server installation in + Trilium. This guide details the steps to set up TLS within Trilium itself.

    + +

    Obtaining a TLS Certificate

    +

    You have two options for obtaining a TLS certificate:

    +
      +
    • Recommended: Obtain a TLS certificate signed by a root + certificate authority. For personal use, Let's Encrypt is + an excellent choice. It is free, automated, and straightforward. Certbot + can facilitate automatic TLS setup.
    • +
    • Generate a self-signed certificate. This option is not recommended due + to the additional complexity of importing the certificate into all machines + connecting to the server.
    • +
    +

    Modifying config.ini

    +

    Once you have your certificate, modify the config.ini file + in the data directory to configure Trilium + to use it:

    [Network]
    +port=8080
    +# Set to true for TLS/SSL/HTTPS (secure), false for HTTP (insecure).
    +https=true
    +# Path to the certificate (run "bash bin/generate-cert.sh" to generate a self-signed certificate).
    +# Relevant only if https=true
    +certPath=/[username]/.acme.sh/[hostname]/fullchain.cer
    +keyPath=/[username]/.acme.sh/[hostname]/example.com.key
    +

    You can also review the configuration file + to provide all config.ini values as environment + variables instead. For example, you can configure TLS using environment + variables:

    export TRILIUM_NETWORK_HTTPS=true
    +export TRILIUM_NETWORK_CERTPATH=/path/to/cert.pem
    +export TRILIUM_NETWORK_KEYPATH=/path/to/key.pem
    +

    The above example shows how this is set up in an environment where the + certificate was generated using Let's Encrypt's ACME utility. Your paths + may differ. For Docker installations, ensure these paths are within a volume + or another directory accessible by the Docker container, such as /home/node/trilium-data/[DIR IN DATA DIRECTORY].

    +

    After configuring config.ini, restart Trilium + and access the hostname using "https".

    +

    Self-Signed Certificate

    +

    If you opt to use a self-signed certificate for your server instance, + note that the desktop instance will not trust it by default.

    +

    To bypass this, disable certificate validation by setting the following + environment variable (for Linux):

    export NODE_TLS_REJECT_UNAUTHORIZED=0
    +trilium
    +

    Trilium provides scripts to start in this mode, such as trilium-no-cert-check.bat for + Windows.

    +

    Warning: Disabling TLS certificate validation is insecure. + Proceed only if you fully understand the implications.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication.html index 63a6e2edfd..4ba1a51cb1 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication.html @@ -43,14 +43,31 @@ class="admonition warning">

    OpenID

    In order to setup OpenID, you will need to setup a authentication provider. This requires a bit of extra setup. Follow these instructions to - setup an OpenID service through google.

    + setup an OpenID service through google. The Redirect URL of Trilium is + https://<your-trilium-domain>/callback.

      -
    1. Set the oauthBaseUrl, oauthClientId and oauthClientSecret in - the config.ini file (check Configuration (config.ini or environment variables) for - more information). -
        -
      1. You can also setup through environment variables (TRILIUM_OAUTH_BASE_URL, TRILIUM_OAUTH_CLIENT_ID and TRILIUM_OAUTH_CLIENT_SECRET).
      2. -
      +
    2. Set the oauthBaseUrl, oauthClientId and + oauthClientSecretin the config.ini file + (check Configuration (config.ini or environment variables) for + more information). +
        +
      1. You can also setup through environment variables: +
          +
        • Standard: TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHBASEURL, + TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHCLIENTID, TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHCLIENTSECRET +
        • +
        • Legacy (still supported): TRILIUM_OAUTH_BASE_URL, + TRILIUM_OAUTH_CLIENT_ID, TRILIUM_OAUTH_CLIENT_SECRET +
        • +
        +
      2. +
      3. oauthBaseUrl should be the link of your + Trilium instance server, for example, https://<your-trilium-domain>.
      4. +
    3. Restart the server
    4. Go to "Menu" -> "Options" -> "MFA"
    5. @@ -60,9 +77,41 @@ class="admonition warning">
    \ No newline at end of file + +

    Authentik

    +

    If you don’t already have a running Authentik instance, please follow + these instructionsto set one up.

    +
      +
    1. In the Authentik admin dashboard, create a new OAuth2 application by following + these steps. Make sure to set the Redirect URL to: https://<your-trilium-domain>/callback.
    2. +
    3. In your config.ini file, set the relevant OAuth variables: +
        +
      1. oauthIssuerBaseUrl → Use the OpenID Configuration Issuer URL + from your application's overview page.
      2. +
      3. oauthIssuerName and oauthIssuerIcon → + Set these to customize the name and icon displayed on the login page. If + omitted, Google’s name and icon will be shown by default.
      4. +
      +
    4. +
    5. Apply the changes by restarting your server.
    6. +
    7. Proceed with the remaining steps starting from Step 3 in the OpenID section.
    8. +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Nix flake.clone.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Nix flake.clone.html new file mode 100644 index 0000000000..e9944f59e8 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Nix flake.clone.html @@ -0,0 +1 @@ +

    This is a clone of a note. Go to its primary location.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/System Requirements.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/System Requirements.html new file mode 100644 index 0000000000..5ecef02bd8 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/System Requirements.html @@ -0,0 +1,18 @@ +
      +
    • Using Docker, the server can be run on Windows, Linux and macOS devices.
    • +
    • Native binaries are provided for Linux x64 and ARM (aarch64).
    • +
    +

    Legacy ARM support

    +

    The Docker builds also provide linux/arm/v7 and + linux/arm/v8platforms. These platforms are considered legacy since + Trilium uses Node.js version 24 which have officially downgraded support for + these platforms to ā€œexperimentalā€.

    +

    As a result, Trilium needs to use Node.js 22 for these versions. As soon + as soon Node.js 22 will no longer be compatible, support for armv7 and + armv8will be dropped entirely.

    +

    Regardless of upstream support, these platforms are supported on a best-effort + basis and are not officially supported by the Trilium development team. + Bug reports are accepted but they will not be treated with priority; contributions + are welcome.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/TLS Configuration.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/TLS Configuration.html deleted file mode 100644 index ead34359c4..0000000000 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/TLS Configuration.html +++ /dev/null @@ -1,45 +0,0 @@ -

    Configuring TLS is essential for server installation in - Trilium. This guide details the steps to set up TLS within Trilium itself.

    -

    For a more robust solution, consider using TLS termination with a reverse - proxy (recommended, e.g., Nginx). You can follow a guide like this for - such setups.

    -

    Obtaining a TLS Certificate

    -

    You have two options for obtaining a TLS certificate:

    -
      -
    • Recommended: Obtain a TLS certificate signed by a root - certificate authority. For personal use, Let's Encrypt is - an excellent choice. It is free, automated, and straightforward. Certbot - can facilitate automatic TLS setup.
    • -
    • Generate a self-signed certificate. This option is not recommended due - to the additional complexity of importing the certificate into all machines - connecting to the server.
    • -
    -

    Modifying config.ini

    -

    Once you have your certificate, modify the config.ini file - in the data directory to configure - Trilium to use it:

    [Network]
    -port=8080
    -# Set to true for TLS/SSL/HTTPS (secure), false for HTTP (insecure).
    -https=true
    -# Path to the certificate (run "bash bin/generate-cert.sh" to generate a self-signed certificate).
    -# Relevant only if https=true
    -certPath=/[username]/.acme.sh/[hostname]/fullchain.cer
    -keyPath=/[username]/.acme.sh/[hostname]/example.com.key
    -

    You can also review the configuration file - to provide all config.ini values as environment variables instead.

    -

    The above example shows how this is set up in an environment where the - certificate was generated using Let's Encrypt's ACME utility. Your paths - may differ. For Docker installations, ensure these paths are within a volume - or another directory accessible by the Docker container, such as /home/node/trilium-data/[DIR IN DATA DIRECTORY].

    -

    After configuring config.ini, restart Trilium and access the - hostname using "https".

    -

    Self-Signed Certificate

    -

    If you opt to use a self-signed certificate for your server instance, - note that the desktop instance will not trust it by default.

    -

    To bypass this, disable certificate validation by setting the following - environment variable (for Linux):

    export NODE_TLS_REJECT_UNAUTHORIZED=0
    -trilium
    -

    Trilium provides scripts to start in this mode, such as trilium-no-cert-check.bat for - Windows.

    -

    Warning: Disabling TLS certificate validation is insecure. - Proceed only if you fully understand the implications.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Third-party cloud hosting.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Third-party cloud hosting.html new file mode 100644 index 0000000000..63c7458f10 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Server Installation/Third-party cloud hosting.html @@ -0,0 +1,37 @@ +

    As an alternative to hosting your own Trilium instance, + there are two services out there that provide out of the box support for + Trilium.

    + +

    Cloud instance providers

    +

    PikaPods

    +
      +
    1. Go to pikapods.com  and sign + up.
    2. +
    3. In the ā€œAvailable Appsā€ section, look for "TriliumNext +
       and select ā€œRun your ownā€.
    4. +
    5. Follow the on-screen instructions to set up your own cloud hosted instance.
    6. +
    +

    PikaPods generally updates their Trilium instances to the latest version + within a two-week interval after a new version is released.

    +

    trilium.cc

    +

    Trilium.cc is a cloud service dedicated + to hosting a Trilium instance.

    + +

    Matching your version with the cloud instance

    +

    Please note that once you set up Synchronization between + a cloud instance and desktop clients, it's + important that the version of the desktop application and the server match + up.

    +

    When setting up a cloud instance, it's best to check the version of the + server by accessing it via a web browser and going to the About section. + It's best that both the desktop and the server have the same App version; + however it's generally OK to update the desktop to a newer version than + the server if it has the same Sync version.

    +

    If the Sync version between the server and the desktop application + doesn't match, synchronization will not work.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Synchronization.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Synchronization.html index d277c52e8e..1b6f89a2c0 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Synchronization.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Synchronization.html @@ -12,9 +12,9 @@

    Setting Up Synchronization

    Security Considerations

    Setting up the server securely is critical and can be complex. It is crucial - to use a valid TLS certificate (HTTPS) - rather than an unencrypted HTTP connection to ensure security and avoid - potential vulnerabilities.

    + to use a valid TLS certificate (HTTPS) rather + than an unencrypted HTTP connection to ensure security and avoid potential + vulnerabilities.

    Synchronizing a Desktop Instance with a Sync Server

    This method is used when you already have a desktop instance of Trilium and want to set up a sync server on your web host.

    @@ -26,7 +26,8 @@ instance address" to your sync server's address. Click Save.

    - screenshot of the sync settings options modal + screenshot of the sync settings options modal

    1. Testing Sync: Click the "Test sync" button to verify @@ -45,7 +46,8 @@ to set up sync with a sync server.

    - screenshot of the sync from server setup page + screenshot of the sync from server setup page

    1. Server Details: Configure the Trilium server address @@ -54,7 +56,8 @@ you will see the following screen:

    - screenshot of the sync page + screenshot of the sync page

    Once synchronization is complete, you will be automatically redirected to the Trilium application.

    @@ -73,12 +76,13 @@

    Certificate Issues

    When using TLS, Trilium will verify the server certificate. If verification fails (e.g., due to self-signed certificates or certain corporate proxies), - you can run the Trilium client with the NODE_TLS_REJECT_UNAUTHORIZED environment - variable set to 0:

    export NODE_TLS_REJECT_UNAUTHORIZED=0
    + you can run the Trilium client with the NODE_TLS_REJECT_UNAUTHORIZED environment + variable set to 0:

    export NODE_TLS_REJECT_UNAUTHORIZED=0

    This will disable TLS certificate verification, significantly reducing security and exposing the setup to MITM attacks. It is strongly recommended to use a valid signed server certificate. Newer Trilium versions include - a script called trilium-no-cert-check.sh for this purpose.

    + a script called trilium-no-cert-check.sh for + this purpose.

    Conflict Resolution

    If you edit the same note on multiple instances before synchronization, Trilium resolves conflicts by retaining the newer change and discarding diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Upgrading TriliumNext.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Upgrading TriliumNext.html index 2248850345..f8836997fc 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Upgrading TriliumNext.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Upgrading TriliumNext.html @@ -8,7 +8,7 @@

  • Docker Server Installation: Pull the new image and restart the container.
  • Other Installations: Download the latest version from - the release page and + the release page and replace the existing application files.
  • Database Compatibility and Migration

    @@ -18,8 +18,8 @@ of Trilium and its database, you can restore the backup that is created prior to migration.

    Sync Compatibility

    -

    The synchronization protocol used - by Trilium is versioned, requiring all members of the sync cluster to use - the same protocol version. Therefore, when upgrading to a new version, - you may need to upgrade all instances in the sync cluster. Changes to the - sync protocol version are typically indicated on the release page.

    \ No newline at end of file +

    The synchronization protocol used by Trilium + is versioned, requiring all members of the sync cluster to use the same + protocol version. Therefore, when upgrading to a new version, you may need + to upgrade all instances in the sync cluster. Changes to the sync protocol + version are typically indicated on the release page.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Web Clipper.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Web Clipper.html index 64c7b080a8..daed786e9c 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Web Clipper.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Web Clipper.html @@ -4,9 +4,20 @@

    Trilium Web Clipper is a web browser extension which allows user to clip text, screenshots, whole pages and short notes and save them directly to Trilium Notes.

    -

    Project is hosted here.

    -

    Firefox and Chrome are supported browsers, but the chrome build should - work on other chromium based browsers as well.

    +

    Supported browsers

    +

    Trilium Web Clipper officially supports the following web browsers:

    +
      +
    • Mozilla Firefox, using Manifest v2.
    • +
    • Google Chrome, using Manifest v3. Theoretically the extension should work + on other Chromium-based browsers as well, but they are not officially supported.
    • +
    +

    Obtaining the extension

    +

    Functionality

    • select text and clip it with the right-click context menu
    • @@ -15,28 +26,80 @@
    • save screenshot (with crop tool) from either popup or context menu
    • create short text note from popup
    +

    Location of clippings

    Trilium will save these clippings as a new child note under a "clipper inbox" note.

    -

    By default, that's the day note but - you can override that by setting the label clipperInbox, - on any other note.

    +

    By default, that's the day note but you + can override that by setting the label + clipperInbox, on any other note.

    If there's multiple clippings from the same page (and on the same day), then they will be added to the same note.

    -

    Extension is available from: -

    +

    Keyboard shortcuts

    +

    Keyboard shortcuts are available for most functions:

      -
    • Project release page - - .xpi for Firefox and .zip for Chromium based browsers.
    • -
    • Chrome Web Store +
    • Save selected text: Ctrl+Shift+S (Mac: ⌘+⇧+S)
    • +
    • Save whole page: Alt+Shift+S (Mac: ⌄+⇧+S)
    • +
    • Save screenshot: Ctrl+Shift+E (Mac: ⌘+⇧+E)
    • +
    +

    To set custom shortcuts, follow the directions for your browser.

    +
      +
    • Firefox: about:addons → + Gear icon āš™ļø → Manage extension shortcuts
    • +
    • Chrome: chrome://extensions/shortcuts
    +

    Configuration

    The extension needs to connect to a running Trilium instance. By default, it scans a port range on the local computer to find a desktop Trilium instance.

    It's also possible to configure the server address if you don't run the desktop application, or want it to work without the desktop application running.

    -

    Username

    -

    Older versions of Trilium (before 0.50) required username & password - to authenticate, but this is no longer the case. You may enter anything - in that field, it will not have any effect.

    \ No newline at end of file +

    Testing development versions

    +

    Development versions are version pre-release versions, generally meant + for testing purposes. These are not available in the Google or Firefox + web stores, but can be downloaded from either:

    +
      +
    • GitHub Releases by + looking for releases starting with Web Clipper. +
    • +
    • Artifacts in GitHub Actions, by looking for the Deploy web clipper extension workflow. + Once a workflow run is selected, the ZIP files are available in the Artifacts section, + under the name web-clipper-extension.
    • +
    +

    For Chrome

    +
      +
    1. Download trilium-web-clipper-[x.y.z]-chrome.zip.
    2. +
    3. Extract the archive.
    4. +
    5. In Chrome, navigate to chrome://extensions/ +
    6. +
    7. Toggle Developer Mode in top-right of the page.
    8. +
    9. Press the Load unpacked button near the header.
    10. +
    11. Point to the extracted directory from step (2).
    12. +
    +

    For Firefox

    + +
      +
    1. Navigate to about:addons.
    2. +
    3. Select Extensions in the left-side navigation.
    4. +
    5. Press the Gear icon on the right of the Manage Your Extensions title.
    6. +
    7. Select Install Add-on From File… +
    8. +
    9. Point it to trilium-web-clipper-[x.y.z]-firefox.zip.
    10. +
    11. Press the Add button to confirm.
    12. +
    +

    Credits

    +

    Some parts of the code are based on the Joplin Notes browser extension.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Miscellaneous/Patterns of personal knowl.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Miscellaneous/Patterns of personal knowl.png new file mode 100644 index 0000000000..39788216a7 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Miscellaneous/Patterns of personal knowl.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Miscellaneous/Patterns of personal knowledge.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Miscellaneous/Patterns of personal knowledge.html new file mode 100644 index 0000000000..ea0ddcbb38 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Miscellaneous/Patterns of personal knowledge.html @@ -0,0 +1,304 @@ + +

    This page contains description of some of the patterns I use to organize + information in my knowledge base. This is meant to give some inspiration + of how one might create and structure their knowledge base in general and + also specifically in Trilium Notes. It also gives some background and justification + for some of the design decisions.

    +

    Meta patterns

    +

    Just to be clear, meta patterns are "patterns of patterns", i.e. patterns + appearing in other patterns.

    +

    Hierarchical organization of information

    +

    Basic meta pattern is that I sort notes (units of information) into a + hierarchy - I have some "top level" notes which represent coarse grained + organization, these then split into sub-notes defining finer grained organization + and so on. I consider this hierarchical (tree) organization very efficient + for organization of large amounts of information. A lot of note taking + software (such as Evernote) are frustratingly limited in this regard which + limits scalability of the software to large amounts of notes.

    +

    Scalability

    +

    It's important to frame the following (meta) patterns with some idea of + how large amount of data are we talking about.

    +

    My rule of thumb for estimation of size of personal knowledge base is + that you can reasonably produce around 10 notes a day, which is 3650 in + a year. I plan to use my knowledge base long term (with or without Trilium + Notes), probably decades so you can easily get to number 100 000 or even + more. Right now, my personal knowledge base has around 10 000 notes.

    +

    100 000 is a number to which most note taking software doesn't scale well + (in both performance and UI). Yet I don't think it's really very much considering + a lifetime of knowledge.

    +

    Lazy hierarchy

    +

    My approach to creating the hierarchy is being lazy - I don't create the + structure first and then fill it with notes, instead I create single note + for some specific topic and start using this one note. Once the content + starts to grow, and I see how some parts could be split out, I move + them out into separate sub notes. As an example I have a book review for The Fellowship of the Ring:

    +
      +
    • Book reviews +
        +
      • The Fellowship of the Ring
      • +
      +
    • +
    +

    The note contains basic book info (author, publisher etc.), book highlights + with the comments and then overall review. Now it turns out there's far + too many book highlights and overall review is also rather long, so I want + to change the structure to the following:

    +
      +
    • Book reviews +
        +
      • The Fellowship of the Ring       (still contains basic info) +
          +
        • Highlights
        • +
        • Review
        • +
        +
      • +
      +
    • +
    +

    If I used standard text file stored in a filesystem I would soon run into + an annoying problem that in order to split out the Highlights and Review + into sub-notes I would also have to convert The Fellowship of the Ring from + text file into directory and split out all sections of the note into sub-notes. + Instead, Trilium treats all notes as equal - both leaf notes and inner + notes can have both text content which allows me to sub-structure only + content which needs it.

    +

    Sorting notes into multiple places in the hierarchy

    +

    While organizing the notes into the hierarchy, you very quickly run into + a dilemma - your note seem to belong to two places in the hierarchy equally. + As an example - you want to make a note about bash - + does it belong to "OS / Linux" or "Programming / Scripting languages"? + This is actually a false dichotomy forced down by the limits of the basic + tree hierarchy - the answer is of course it belongs to both. This + is the reason why Trilium doesn't use standard tree structure (which requires + every note to have exactly one parent), but an extension which allows every + note to have several parents, thus effectively allowing it to appear in + multiple places in the hierarchy. For lack of better term I call this "cloning". + The main problem with this term is that it suggests that each clone must + have an original, but here all clones are completely equal - effectively + there's no original.

    +

    In tech lingo, it might be better to describe it as a hard link with + an important difference that it is possible to hard link (clone) a directory + (inner note).

    +

    Protected notes

    +

    I have Trilium Notes opened non-stop. Sometimes I forget to lock my computer + when going to the bathroom. Sometimes I let a friend or family member to + use my computer for a minute without supervision. They might click on (running) + Trilium and inadvertently see a note I really don't want anybody to see + (personal diary, credentials). To cover this, Trilium has a concept of + "protected notes" + - protected note is encrypted and on top of that requires the user to enter + the password every 5 minutes which guarantees that such note can be in + a readable state only for small amount of time. Working with ordinary (not + protected) notes don't require password so you're not bothered by extra + security when it's not needed.

    +

    Archiving notes

    +

    Notes can lose relevancy with time - let's say I switch jobs - all the + notes specific to the former employer immediately lose most of its import. + This doesn't mean I want to delete these notes though - typically I just + want them to somehow deprioritize - in Trilium I would do that by assigning + an inherited + label archived to the company root note. + The main effect of this label is that all the notes from this sub-tree + are filtered out from search results (fast search via note autocomplete + is my main navigation approach). + Apart from this, I also typically move such outdated notes to some less + prominent place in the hierarchy.

    +

    I use archivation also for notes which are not very relevant from their + creation - an example might be automatically imported reddit comments.

    +

    Sometimes there's no clear category split between relevant and + non-relevant notes, in that case I just create "OLD" note with + archivedlabel and move all irrelevant notes there. So my credentials + note might look something like this:

    +
      +
    • Credentials +
        +
      • Personal +
          +
        • OLD       (contains a bunch of notes with credentials for services I don't use anymore) +
        • +
        • Gmail
        • +
        • Github
        • +
        • ...
        • +
        +
      • +
      +
    • +
    +

    Patterns

    +

    Day note

    +

    Every day has its note which contains or references everything related + to the given day. Structure looks like this:

    +
      +
    • 2018 +
        +
      • 11 - November +
          +
        • 26 - Monday
        • +
        • 27 - Tuesday +
            +
          • subnote 1
          • +
          +
        • +
        +
      • +
      +
    • +
    +

    Day note serves as a workspace and note inbox at the same time - it's + the default location to create a note when I don't have time to think about + proper placement. At the end of the day I typically review my day note + and clone the notes into suitable locations in the hierarchy.

    +

    Trilium has this pattern partly built-in - Trilium understands and can + create this Year / Month / Day structure semi-automatically (on API call). + There's also global keyboard shortcut CTRL-ALT-P which + will create new note in the day note.

    +

    What notes do I keep under this day note?

    +
      +
    • TODO list for given day (this can be automated - see Task Manager)
    • +
    • Personal diary
    • +
    • clones of notes I created during this + day (which kind of represents what I've been working on).
    • +
    • I often clone notes (or sub-trees) of e.g. projects I'm working on at + given day so they are at hand
    • +
    • I have some scripts which allow me to track + certain daily metrics (like weight). These are saved into one daily "data + note" (actually JSON code note). +
        +
      • I have other scripts which then help me to visualize these data (see a  + Weight Tracker example)
      • +
      • I have a script which automatically imports all my comments from reddit + into the day note. +
          +
        • People are sometimes wondering why. The answer is that I usually put some + effort and thought into a comment and that's why I feel it's worth preserving, + especially if it can be done automatically.
        • +
        +
      • +
      +
    • +
    +

    For most notes, this day note placement is secondary and their + primary location is somewhere else (e.g. for a book review I've been working + on it's Book / Reviews, not the day note). So for this pattern + to work, ability to clone notes into multiple + places is pretty fundamental.

    +

    Projects

    +

    Project is pretty self-explanatory, for me specifically it also + means being long term (years) - an example of a project might be Trilium + Notes or university studies. Given their longevity, projects can be large + and deep, but their structure is very domain specific, and I don't see + any common patterns. What's pretty clear is they are often widely interconnected + with other parts of the knowledge base - e.g. university credentials are + cloned from "Credentials / University" top level notes and Trilium related + blog posts are in "Blog / [Name of the blog] / Trilium".

    +

    Epics are the same thing as projects, but differ in scope - they + are typically several months long and as such are usually placed into a + year note (e.g. 2018 / Epics). Epics are often of work nature (also + cloned into work note) and personal (e.g. currently I have large epic for + moving to a different city).

    +

    I don't have a term for short term projects (typically several days long), + but continuing the scrum analogy I might call them story. These + are often placed directly into day notes and manually moved from one day + to another (or place into a month note, e.g. 2018 / 11 - November).

    +

    Credentials

    +

    I keep all my credentials in the knowledge base, they are sorted into + categories - work related, project related, personal per country etc. These + notes are of course protected and are often + cloned into other places (e.g. project credentials are cloned into the + project itself). This is a pretty important advantage compared to traditional + tools like KeePass - all the relevant information is centralized into one + place without compromising security.

    +

    People profiles

    +

    This might seem creepy to some, but I keep a profile on most people. It + contains pretty standard things like date of birth, contacts, address, + but also current and previous employments, their hobbies and worldviews + and sometimes even important (IM/mail/meatspace) conversations. Just about + everything I find notable. It helps to refresh some basic info before meeting + people, especially if you haven't been in touch in a while. It gets pretty + awkward to ask for the tenth time where do they work for example, because + you keep forgetting it.

    +

    Naturally I have a lot of (extended) family members, friends, acquaintances + etc. so I need some way to sort them. My main method is to sort them by + social circle (work, high school, sports club etc.), sometimes also by + their town of residence. Family circle is still too large so the + further organization is by clan (as in "Smiths"). Some people are + members of several such circles, so they are just cloned into multiple + places.

    +

    For family specifically it's pretty useful to create relation map to + visualize relationships:

    +
    + +
    +

    [missing note] +

    +

    Books

    +

    Of course, I keep standard "To read" list. I also keep a record on the + books I've read - typically one book has one subtree where the root has + some basic info like author, page count, publication date, date started, + date finished (in the form of Promoted Attributes). + I also write a (private) review and keep list of highlights from Kindle, + optionally with some commentary, these are usually stored in sub notes + (unless they are pretty short).

    +

    To keep the list of books manageable, I sort them per year (of reading + them), this also gives me some basic overview of "reading performance" + for given year. I plan to create a script which + would show some timeline chart visualizing book attributes dateStarted - + dateFinishedto have nicer view of my reading sprints and trends.

    +

    Some specific authors also have their own note which contains cloned book + reviews, links to interviews and other related resources.

    +

    I have similar system for movies and TV shows, but not as sophisticated.

    +

    Personal diary

    +

    This is a place to reflect on events, experiences, new findings etc. This + can help you get deeper understanding of your inner self, clarify your + thinking and make better decisions as a result.

    +

    I sort personal diary notes directly under day note (explained + above), but it can be cloned also to e.g. "trip note" (if the diary note + is about given trip) or to person's profile (if the person plays a role + in the diary note). All my diary notes are protected since + they are usually pretty sensitive.

    +

    Documents

    +

    I keep all my personal documents (ID, passport, education certificates + ...) scanned in the knowledge base. They are synchronized across + every PC which provides decent backup and makes them available everywhere.

    +

    Advantage compared to e.g. keeping them in Dropbox or Google Drive is + that they are not stored on some 3rd party server and they can be encrypted + (protected).

    +

    Inventory

    +

    Inventory contains documents and other relevant importation for my important + belongings - e.g. for car you can keep the registration card, maintenance + record, related costs etc. I also keep inventory for some items personally + important to me - mainly computers, phones, cameras and similar electronics. + This can be practical at times but also provides sentimental value.

    +

    Topic knowledge base

    +

    This where I store hard "knowledge" - summarized topics and findings from + different domains. Topics can range from traditional sciences - physics, + history, economy to philosophy, mental models, apps (notes about specific + apps I use) etc. Of course this is very subjective - given what I do, my + Physics sub-tree is pretty sparse compared to my Programming subtree.

    +

    Work knowledge base

    +

    I usually keep top level note for the company I currently work at (past + jobs are moved elsewhere). I track basic organization of the company (divisions, + business units), who is who (relation maps) + are again useful for visualization), projects I work at etc.

    +

    There's a number of credentials to various company services I need to + use. Companies usually have a bunch of complex processes and tools. I record + meeting minutes, link to the company wiki (which is usually difficult to + find relevant info). In general there's a lot of company specific information + I need to know or need have them at hand in a nice structure I can understand. + Often it's just copy pasting and reshuffling of existing information into + something more understandable for me.

    +

    From my experience, keeping this makes me more productive and even more + importantly dramatically reduces frustration and stress.

    +

    Conclusion

    +

    I could probably go on with more patterns (e.g. study notes, travelling), + but I think you get the idea. Whatever is important in your life, it probably + makes sense to document and track it.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Miscellaneous/Privacy Policy.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Miscellaneous/Privacy Policy.html new file mode 100644 index 0000000000..8f81ba26e7 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Miscellaneous/Privacy Policy.html @@ -0,0 +1,20 @@ +

    Trilium Notes

    +

    Trilium Notes does not collect/send any data from the user's installation, + i.e. no analytics, no telemetry etc. The data flows only between user controlled + / installed applications, without any intermediary.

    +

    Automatic network activity consists of:

    +
      +
    • Trilium periodically queries URL https://github.com/TriliumNext/Trilium/releases to + see if there's a new stable version released. (check only, there's no automatic + download and/or installation).
    • +
    • Trilium will download spelling dictionaries automatically as needed based + on language settings
    • +
    +

    Trilium Web Clipper

    +

    Trilium Web Clipper does not collect/send any data from the user's installation, + i.e. no analytics, no telemetry etc. The data flows only between user controlled + / installed applications, without any intermediary.

    +

    Trilium Sender for Android

    +

    Trilium Sender for Android does not collect/send any data from the user's + installation, i.e. no analytics, no telemetry etc. The data flows only + between user controlled / installed applications, without any intermediary.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types.html index 0d1b2c0fd5..e1c453eb6b 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types.html @@ -1,5 +1,5 @@ -

    One core features of Trilium is that it supports multiple types of notes, - depending on the need.

    +

    One of the core features of Trilium is that it supports multiple types + of notes, depending on the need.

    Creating a new note with a different type via the note tree

    The default note type in Trilium (e.g. when creating a new note) is  Creating a new note of a different type via add link or new tab

    • When adding a link in a Text note, type the desired title - of the new note and press Enter. Afterwards the type of the note will be - asked.
    • + href="#root/_help_iPIMuisry3hd">Text note, type the desired title of + the new note and press Enter. Afterwards the type of the note will be asked.
    • Similarly, when creating a new tab, type the desired title and press Enter.

    Changing the type of a note

    It is possible to change the type of a note after it has been created via the Basic Properties tab in the Ribbon. Note that it's generally a - good idea to change the note type only if the note is empty. Can also be - used to edit the source of a note.

    + href="#root/_help_BlN9DFI679QC">Ribbon. Note that it's generally a good idea + to change the note type only if the note is empty. Can also be used to + edit the source of a note.

    Supported note types

    The following note types are supported by Trilium:

    @@ -81,7 +80,7 @@ @@ -109,7 +108,7 @@ - @@ -175,8 +179,8 @@ to use the mouse. For a reference of all the key combinations, see  Keyboard Shortcuts. In addition, see Markdown-like formatting as an - alternative to the keyboard shortcuts.

    + href="#root/_help_QrtTYPmdd1qq">Markdown-like formatting as an alternative + to the keyboard shortcuts.

    Technical details

    For the text editing functionality, Trilium uses a commercial product (with an open-source base) called CKEditor. diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/10_Lists_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/10_Lists_image.png index 1282f27ec0..fba0cc85c9 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/10_Lists_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/10_Lists_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/10_Tables_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/10_Tables_image.png index 5cf2cc519c..099b253570 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/10_Tables_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/10_Tables_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/11_Tables_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/11_Tables_image.png index cde63c9ac3..5cf2cc519c 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/11_Tables_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/11_Tables_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/12_Tables_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/12_Tables_image.png index 9c512ee533..cde63c9ac3 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/12_Tables_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/12_Tables_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/13_Tables_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/13_Tables_image.png new file mode 100644 index 0000000000..9c512ee533 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/13_Tables_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/14_Tables_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/14_Tables_image.png new file mode 100644 index 0000000000..dd4becc162 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/14_Tables_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/1_Lists_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/1_Lists_image.png index fba0cc85c9..4a17f481cc 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/1_Lists_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/1_Lists_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/2_Lists_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/2_Lists_image.png index ee7a6bdead..2473cd3102 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/2_Lists_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/2_Lists_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/4_Lists_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/4_Lists_image.png index 8369a03c61..3caf2d880c 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/4_Lists_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/4_Lists_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/7_Lists_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/7_Lists_image.png index 3caf2d880c..ee7a6bdead 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/7_Lists_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/7_Lists_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/8_Lists_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/8_Lists_image.png index 4a17f481cc..30a9511b08 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/8_Lists_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/8_Lists_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/9_Lists_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/9_Lists_image.png index 2473cd3102..8369a03c61 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/9_Lists_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/9_Lists_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/9_Tables_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/9_Tables_image.png index 099b253570..e802154768 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/9_Tables_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/9_Tables_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Block quotes & admonitions.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Block quotes & admonitions.html index 6f16fc2141..179f435506 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Block quotes & admonitions.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Block quotes & admonitions.html @@ -25,18 +25,18 @@ class="image image-style-align-center">

    It's possible to insert an admonition simply by typing:

      -
    • !!! note +
    • !!! note
    • -
    • !!! tip +
    • !!! tip
    • -
    • !!! important +
    • !!! important
    • -
    • !!! caution +
    • !!! caution
    • -
    • !!! warning +
    • !!! warning
    -

    In addition to that, it's also possible to type !!!  +

    In addition to that, it's also possible to type !!!  followed by any text, case in which a default admonition type will appear (note) with the entered text inside it.

    Interaction

    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Bookmarks.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Bookmarks.html index 8e1e9979f3..bc7b346e33 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Bookmarks.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Bookmarks.html @@ -1,5 +1,5 @@ -

    Bookmarks allows creating links to - a certain part of a note, such as referencing a particular heading.

    +

    Bookmarks allows creating links to a certain + part of a note, such as referencing a particular heading.

    Technically, bookmarks are HTML anchors.

    This feature was introduced in TriliumNext 0.94.0.

    Interaction

    @@ -8,9 +8,11 @@
    • Place the cursor at the desired position where to place the bookmark.
    • Look for the - button in the Formatting toolbar, + button in the Formatting toolbar, and then press the - button.
    • + button.
  • To place a link to a bookmark: diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Developer-specific formatting.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Developer-specific formatting.html index be60556c4a..31efbe6f7a 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Developer-specific formatting.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Developer-specific formatting.html @@ -5,14 +5,14 @@

    Example of inline code being used to illustrate file system paths as well - as shell commands (git in this case).

    + as shell commands (git in this case).

    To insert an inline code:

      -
    • Via the Formatting toolbar, - look for the +
    • Via the Formatting toolbar, look + for the button.
    • -
    • Type `code` where code is the desired text to be automatically - formatted as inline code.
    • +
    • Type `code` where code is the desired text + to be automatically formatted as inline code.

    Code blocks

    Code blocks display a snippet of code as a dedicated block:

    @@ -21,8 +21,7 @@

    A code block with JavaScript syntax highlight enabled.

    Note that these are not meant for very large portions of code. Use the - dedicated Code note type - instead.

    + dedicated Code note type instead.

    See the dedicated documentation for more information: Code blocks

    Keyboard shortcuts

    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks.html index 87ce90c0a1..d45dd8218c 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks.html @@ -18,13 +18,26 @@ available languages.
  • -
  • Type ``` (as in Markdown). +
  • Type ``` (as in Markdown).
    • Note that it's not possible to specify the language, as it will default to the last selected language.
  • +

    Exiting out of the code block

    +
      +
    • To exit out of a code block and enter a normal paragraph, move the cursor + at the end of the code block and press Enter twice.
    • +
    • Similarly, to insert a paragraph above the note block, move the cursor + at the beginning of the code block and press Enter twice.
    • +
    +

    Syntax highlighting & color schemes

    Since TriliumNext v0.90.12, Trilium will try to offer syntax highlighting to the code block. Note that the syntax highlighting mechanism is slightly @@ -42,8 +55,7 @@

    Note that when editing a text note, syntax highlighting is automatically disabled if the code block is too big (somewhere around 500 lines). This value is currently not configurable. For Read-Only Notes, this limitation is - not applied.

    + href="#root/_help_CoFPLs3dRlXc">Read-Only Notes, this limitation is not applied.

    In order to configure this new feature, a section has been added in Options → Appearance to control the syntax highlighting. There the color scheme can be chosen, from a builtin selection of themes from Highlight.js.

    @@ -84,9 +96,9 @@ Code note type.

    The supported languages can be adjusted by going to Options, then Code Notes and - looking for the Available MIME types in the dropdown section. Simply - check any of the items to add them to the list, or uncheck them to remove - them from the list.

    + href="#root/_help_4TIF1oA4VQRO">Options, then Code Notes and looking + for the Available MIME types in the dropdown section. Simply check + any of the items to add them to the list, or uncheck them to remove them + from the list.

    Note that the list of languages is not immediately refreshed, you'd have to manually refresh the application.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Footnotes.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Footnotes.html index dc63ed5119..04c4a73639 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Footnotes.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Footnotes.html @@ -1,21 +1,21 @@
    - +

    Footnotes are a good place to insert references to a paragraph or details that are displayed at the bottom of the note.

    Interaction

    • To insert a new footnote, press - (or press the right arrow and select New footnote).
    • + (or press the right arrow and select New footnote).
    • To insert a reference to an existing footnote, press the right arrow and select Insert footnote, followed by the number of the footnote to insert.
    • -
    • Hovering over a reference (e.g. [1]) will display the content - of the footnote in a tooltip for easy reference.
    • -
    • Clicking on a reference in the text (e.g. [1]) will navigate - to the corresponding footnote.
    • -
    • Similarly, clicking on the ^ button of a footnote will navigate - to the corresponding reference in the text.
    • +
    • Hovering over a reference (e.g. [1]) will + display the content of the footnote in a tooltip for easy reference.
    • +
    • Clicking on a reference in the text (e.g. [1]) + will navigate to the corresponding footnote.
    • +
    • Similarly, clicking on the ^ button of a + footnote will navigate to the corresponding reference in the text.
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/General formatting.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/General formatting.html index 8ee8f69896..3cbdbbf441 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/General formatting.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/General formatting.html @@ -12,11 +12,11 @@

    Apart from using the UI, it is also possible to quickly insert headings using the Markdown-like shortcuts:

      -
    • ## for Heading 2
    • -
    • ### for Heading 3
    • -
    • #### for Heading 4
    • -
    • ##### for Heading 5
    • -
    • ###### for Heading 6
    • +
    • ## for Heading 2
    • +
    • ### for Heading 3
    • +
    • #### for Heading 4
    • +
    • ##### for Heading 5
    • +
    • ###### for Heading 6

    Font size

    @@ -50,11 +50,13 @@

    Alternatively, Markdown-like formatting can be used:

      -
    • Bold: Type **text** or __text__ +
    • Bold: Type **text** or + __text__
    • -
    • Italic: Type *text* or _text_ +
    • Italic: Type *text* or _text_
    • -
    • Strikethrough: Type ~~text~~ +
    • Strikethrough: Type ~~text~~

    Superscript, subscript

    @@ -79,7 +81,8 @@ the Remove formatting toolbar item.

    Remove formatting

    The - Remove formatting button is a quick way to eliminate the general + Remove formatting button is a quick way to eliminate the general formatting styling of a particular text.

    Simply select the text and press the button to remove the formatting (bold, italic, colors, sizes, etc.). If the text does not have any removable formatting, @@ -88,6 +91,11 @@ be manually changed back to a paragraph according to the Headings section.

    When pasting content that comes with undesired formatting, an alternative to pasting and then removing formatting is pasting as plain text via Ctrl+Shift+V.

    +

    Format painter

    +

    The Format Painter allows + users to copy the formatting of text (such as bold, italic, Strikethrough, + etc.) and apply it to other parts of the document. It helps maintain consistent + formatting and accelerates the creation of rich content.

    Support for Markdown

    When exported to Markdown, most of the general formatting is maintained such as headings, bold, italic, diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Highlights list.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Highlights list.html index b492c7cc0d..24b3789cba 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Highlights list.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Highlights list.html @@ -1,6 +1,6 @@

    - +

    Similar to the Table of contents, but instead of headings this feature will list highlighted text from a @@ -29,4 +29,4 @@

    Per-note configuration

    To suppress the display of highlighted text for one specific note, use  Attributes to add the #hideHighlightWidget label.

    \ No newline at end of file + class="reference-link" href="#root/_help_zEY4DaJG4YT5">Attributes to add the #hideHighlightWidget label.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Images.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Images.html index d5badf0f93..c38380185a 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Images.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Images.html @@ -1,10 +1,9 @@

    Trilium supports storing and displaying images. Supported formats are JPEG, PNG and GIF.

    An image can be uploaded in the form of note's attachment or - as a standalone note placed into the - note tree. Its reference can be copied into a text note, in order - to display it in the text itself.

    + as a standalone note placed into the note tree. + Its reference can be copied into a text note, in order to display it in + the text itself.

    Uploading images

    To add an image to the note, simply drag it from file explorer onto the note editor inside Trilium and the image will be uploaded.

    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Images/Image references.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Images/Image references.html index c9b26fc849..3d5430ecc9 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Images/Image references.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Images/Image references.html @@ -1,6 +1,6 @@
    - +

    Image references are an easy way to embed the preview of another note type into a Text note.

    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Include Note.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Include Note.html index 84adc92de7..f674e9ea89 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Include Note.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Include Note.html @@ -5,4 +5,11 @@

    In the Formatting toolbar, look for the button. There is also a keyboard shortcut defined for it but it is not - allocated by default.

    \ No newline at end of file + allocated by default.

    +

    Included notes in the share functionality

    +

    If a shared note contains one or more included + notes, they will be displayed in the content of the note as if they were + part of the note itself.

    +

    For this to work, the included notes must also be shared, otherwise they + will not be shown. However, the included notes can still be hidden from + the note tree via #shareHiddenFromTree.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Insert buttons.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Insert buttons.html index d74b7f43bb..8b176dfad7 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Insert buttons.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Insert buttons.html @@ -1,77 +1,85 @@

    Press the - button in the Formatting toolbar to + button in the Formatting toolbar to reveal special inserable items and blocks such as symbols, Math expressions and separators.

    Bookmarks

    See the dedicated Bookmarks section.

    Emoji

    - +

    This feature allows inserting Unicode emoji characters. Simply select a category and a desired emoji to insert it.

    Emojis can also be searched by their English name and the skin tone can be selected via a combo box to the right.

    -

    There is also the possibility of inserting emojis directly by typing : followed - by a name of an emoji, triggering the display of a list of emojis. Simply - use the arrow keys to select one and press Enter to insert it.

    - - +

    There is also the possibility of inserting emojis directly by typing + :followed by a name of an emoji, triggering the display of a list + of emojis. Simply use the arrow keys to select one and press Enter to + insert it.

    + +

    Symbols

    -
    - -
    -

    Pressing the - button will reveal a popup window displaying a list of characters that - are generally more difficult to insert directly from the keyboard, such - as a subset of emojis, quotation characters, etc.

    -

    Interaction:

    -
      -
    • Click on a character to insert it at the current cursor position.
    • -
    • The window can be dragged around by the top bar where the title is, to - avoid it getting in the way of the text.
    • -
    • Click on the Category selector to filter the characters.
    • -
    -

    Math equations

    -

    See the dedicated Math Equations page.

    -

    Mermaid diagram

    -

    Press the - button to create an inline Mermaid diagram.

    -

    This feature is quite similar to the Mermaid Diagrams note - types and is meant as an alternative to it for simple diagrams. For more - complex diagrams, use the Include Note feature - for a dedicated Mermaid note.

    -
    - -
    - +
    + +
    +

    Pressing the + button will reveal a popup window displaying a list of characters that + are generally more difficult to insert directly from the keyboard, such + as a subset of emojis, quotation characters, etc.

    +

    Interaction:

    +
      +
    • Click on a character to insert it at the current cursor position.
    • +
    • The window can be dragged around by the top bar where the title is, to + avoid it getting in the way of the text.
    • +
    • Click on the Category selector to filter the characters.
    • +
    +

    Math equations

    +

    See the dedicated Math Equations page.

    +

    Mermaid diagram

    +

    Press the + button to create an inline Mermaid diagram.

    +

    This feature is quite similar to the Mermaid Diagrams note + types and is meant as an alternative to it for simple diagrams. For more + complex diagrams, use the Include Note feature + for a dedicated Mermaid note.

    +
    + +
    +

    Horizontal ruler

    -

    This feature will display a horizontal line, generally useful to separate - different sections of the text. To do so, press the - button in the Formatting toolbar.

    - -

    Alternatively, it's possible to insert a horizontal ruler by typing ---.

    -

    Page break

    -
    - -
    -

    Page breaks provide a way to force the next paragraph or block (table, - image, etc.) to be displayed onto the next page when printing (either to - a real printer to when exporting to PDF).

    -

    Page breaks are marked in the editor with the words Page break, - but they will not actually be shown when printed.

    -
      -
    • To insert a page break, press the - in the formatting toolbar.
    • -
    • To insert many page breaks at once, insert a page break first, click on - it and press Ctrl+C. Then use Ctrl+V, - to paste as many times as needed.
    • -
    \ No newline at end of file +

    This feature will display a horizontal line, generally useful to separate + different sections of the text. To do so, press the + button in the Formatting toolbar.

    + +

    Alternatively, it's possible to insert a horizontal ruler by typing + ---.

    +

    Page break

    +
    + +
    +

    Page breaks provide a way to force the next paragraph or block (table, + image, etc.) to be displayed onto the next page when printing (either to + a real printer to when exporting to PDF).

    +

    Page breaks are marked in the editor with the words Page break, + but they will not actually be shown when printed.

    +
      +
    • To insert a page break, press the + in the formatting toolbar.
    • +
    • To insert many page breaks at once, insert a page break first, click on + it and press Ctrl+C. Then use Ctrl+V, + to paste as many times as needed.
    • +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Keyboard shortcuts.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Keyboard shortcuts.html index b21042ae68..e85e10f952 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Keyboard shortcuts.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Keyboard shortcuts.html @@ -111,10 +111,10 @@

    Content editing

    Collections Displays the children of the note either as a grid, a list, or for a more - specialized case: a calendar. + specialized case: a calendar. 

    Generally useful for easy reading of short notes.
    Easy for brainstorming ideas, by placing them in a hierarchical layout.
    Geo Map View + Geo Map Displays the children of the note as a geographical map, one use-case would be to plan vacations. It even has basic support for tracks. Notes diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/1_File_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/1_File_image.png index 18ce5beff2..498813236b 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/1_File_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/1_File_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/2_File_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/2_File_image.png index 04478a3ada..3dd5cebb82 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/2_File_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/2_File_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/3_File_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/3_File_image.png index 498813236b..af5bdfd5b2 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/3_File_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/3_File_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/4_File_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/4_File_image.png index 3dd5cebb82..14044ba955 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/4_File_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/4_File_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/5_File_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/5_File_image.png deleted file mode 100644 index af5bdfd5b2..0000000000 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/5_File_image.png and /dev/null differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/6_File_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/6_File_image.png deleted file mode 100644 index 14044ba955..0000000000 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/6_File_image.png and /dev/null differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Canvas.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Canvas.html index 430c7ed663..5be4d8ca0a 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Canvas.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Canvas.html @@ -1,7 +1,13 @@ +
    + grafik +

    Available since Trilium v0.52.

    Canvas notes use the Excalidraw library to allow handwritten notes with mouse, pen or touch on an infinite canvas. It also supports basic diagramming, text and graphics input.

    -

    - grafik -

    \ No newline at end of file +

    Interaction

    + \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections.html deleted file mode 100644 index 7b255c8803..0000000000 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections.html +++ /dev/null @@ -1,83 +0,0 @@ -

    Collections are a unique type of notes that don't have a content, but - instead display its child notes in various presentation methods.

    -

    Classic collections are read-only mode and compiles the contents of all - child notes into one continuous view. This makes it ideal for reading extensive - information broken into smaller, manageable segments.

    -
      -
    • Grid View which - is the default presentation method for child notes (see Note List), where the notes are displayed - as tiles with their title and content being visible.
    • -
    • List View is - similar to Grid View, - but it displays the notes one under the other with the content being expandable/collapsible, - but also works recursively.
    • -
    -

    More specialized collections were introduced, such as the:

    -
      -
    • Calendar View which - displays a week, month or year calendar with the notes being shown as events. - New events can be added easily by dragging across the calendar.
    • -
    • Geo Map View which - displays a geographical map in which the notes are represented as markers/pins - on the map. New events can be easily added by pointing on the map.
    • -
    • Table View displays - each note as a row in a table, with Promoted Attributes being - shown as well. This makes it easy to visualize attributes of notes, as - well as making them easily editable.
    • -
    • Board View (Kanban) - displays notes in columns, grouped by the value of a label.
    • -
    -

    For a quick presentation of all the supported view types, see the child - notes of this help page, including screenshots.

    -

    Configuration

    -

    To adjust the view type, see the dedicated Collections tab in the  - Ribbon.

    -

    Use cases

    -

    Creating a new collection

    -

    To create a new collections, right click in the Note Tree and look for the Collections entry - and select the desired type.

    -

    Adding a description to a collection

    -

    To add a text before the collection, for example to describe it:

    -
      -
    1. Create a new collection.
    2. -
    3. In the Ribbon, - go to Basic Properties and change the note type from Collection to Text.
    4. -
    -

    Now the text will be displayed above while still maintaining the collection - view.

    -

    Using saved search

    -

    Since collections are based on the Note List mechanism, - it's possible to apply the same configuration to Saved Search to do advanced querying - and presenting the result in an adequate matter such as a calendar, a table - or even a map.

    -

    Creating a collection from scratch

    -

    By default, collections come with a default configuration and sometimes - even sample notes. To create a collection completely from scratch:

    -
      -
    1. Create a new note of type Text (or any type).
    2. -
    3. In the Ribbon, - go to Basic Properties and select Collection as the note - type.
    4. -
    5. Still in the ribbon, go to Collection Properties and select the - desired view type.
    6. -
    7. Consult the help page of the corresponding view type in order to understand - how to configure them.
    8. -
    -

    Under the hood

    -

    Collections by themselves are simply notes with no content that rely on - the Note List mechanism - (the one that lists the children notes at the bottom of a note) to display - information.

    -

    By default, new collections use predefined Templates that are stored safely - in the Hidden Notes to - define some basic configuration such as the type of view, but also some  - Promoted Attributes to make editing easier.

    -

    Collections don't store their configuration (e.g. the position on the - map, the hidden columns in a table) in the content of the note itself, - but as attachments.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/15_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/15_Geo Map View_image.png deleted file mode 100644 index 72dbb98617..0000000000 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/15_Geo Map View_image.png and /dev/null differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/2_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/2_Calendar View_image.png deleted file mode 100644 index 2c17bb45a7..0000000000 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/2_Calendar View_image.png and /dev/null differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/3_Calendar View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/3_Calendar View_image.png deleted file mode 100644 index 3bf94720fe..0000000000 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/3_Calendar View_image.png and /dev/null differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/8_Geo Map View_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/8_Geo Map View_image.png deleted file mode 100644 index c2317a878c..0000000000 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/8_Geo Map View_image.png and /dev/null differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Board View.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Board View.html deleted file mode 100644 index 3c13a81d8a..0000000000 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Board View.html +++ /dev/null @@ -1,81 +0,0 @@ -
    - -
    -

    The Board view presents sub-notes in columns for a Kanban-like experience. - Each column represents a possible value for a status label, which can be - adjusted.

    -

    How it works

    -

    When first creating a collection of Board type, a few subnotes - will be created, each having a #status label set. The board - then groups each note by the value of the status attribute.

    -

    Notes are displayed recursively, so even the child notes of the child - notes will be displayed. However, unlike the Table View, the notes are not displayed - in a hierarchy.

    -

    Interaction with columns

    -
      -
    • Create a new column by pressing Add Column near the last column. -
        -
      • Once pressed, a text box will be displayed to set the name of the column. - Press Enter to confirm.
      • -
      -
    • -
    • To reorder a column, simply hold the mouse over the title and drag it - to the desired position.
    • -
    • To delete a column, right click on its title and select Delete column.
    • -
    • To rename a column, click on the note title. -
        -
      • Press Enter to confirm.
      • -
      • Upon renaming a column, the corresponding status attribute of all its - notes will be changed in bulk.
      • -
      -
    • -
    • If there are many columns, use the mouse wheel to scroll.
    • -
    -

    Interaction with notes

    -
      -
    • Create a new note in any column by pressing New item -
        -
      • Enter the name of the note and press Enter.
      • -
      • Doing so will create a new note. The new note will have an attribute (status label - by default) set to the name of the column.
      • -
      -
    • -
    • To change the state of a note, simply drag a note from one column to the - other to change its state.
    • -
    • The order of the notes in each column corresponds to their position in - the tree. -
        -
      • It's possible to reorder notes simply by dragging them to the desired - position within the same columns.
      • -
      • It's also possible to drag notes across columns, at the desired position.
      • -
      -
    • -
    • For more options, right click on a note to display a context menu with - the following options: -
        -
      • Open the note in a new tab/split/window or quick edit.
      • -
      • Move the note to any column.
      • -
      • Insert a new note above/below the current one.
      • -
      • Delete the current note.
      • -
      -
    • -
    • If there are many notes within the column, move the mouse over the column - and use the mouse wheel to scroll.
    • -
    -

    Configuration

    -

    Grouping by another attribute

    -

    By default, the label used to group the notes is #status. - It is possible to use a different label if needed by defining a label named #board:groupBy with - the value being the attribute to use (without # attribute prefix).

    - -

    Interaction

    -

    Limitations

    -
      -
    • It is not possible yet to use group by a relation, only by label.
    • -
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Calendar View.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Calendar View.html deleted file mode 100644 index eaefc470db..0000000000 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/Calendar View.html +++ /dev/null @@ -1,366 +0,0 @@ -
    - -
    -

    The Calendar view will display each child note in a calendar that has - a start date and optionally an end date, as an event.

    -

    The Calendar view has multiple display modes:

    -
      -
    • Week view, where all the 7 days of the week (or 5 if the weekends are - hidden) are displayed in columns. This mode allows entering and displaying - time-specific events, not just all-day events.
    • -
    • Month view, where the entire month is displayed and all-day events can - be inserted. Both time-specific events and all-day events are listed.
    • -
    • Year view, which displays the entire year for quick reference.
    • -
    • List view, which displays all the events of a given month in sequence.
    • -
    -

    Unlike other Collection view types, the Calendar view also allows some - kind of interaction, such as moving events around as well as creating new - ones.

    -

    Creating a calendar

    - - - - - - - - - - - - - - - - - - - - -
    1 - - The Calendar View works only for Collection note types. To create a new - note, right click on the note tree on the left and select Insert note after, - or Insert child note and then select Collection.
    2 - - Once created, the ā€œView typeā€ of the Collection needs changed to ā€œCalendarā€, - by selecting the ā€œCollection Propertiesā€ tab in the ribbon.
    - -

    Creating a new event/note

    -
      -
    • Clicking on a day will create a new child note and assign it to that particular - day. -
        -
      • You will be asked for the name of the new note. If the popup is dismissed - by pressing the close button or escape, then the note will not be created.
      • -
      -
    • -
    • It's possible to drag across multiple days to set both the start and end - date of a particular note. -
      - -
    • -
    • Creating new notes from the calendar will respect the ~child:template relation - if set on the Collection note.
    • -
    -

    Interacting with events

    -
      -
    • Hovering the mouse over an event will display information about the note. -
      - -
    • -
    • Left clicking the event will open a Quick edit to - edit the note in a popup while allowing easy return to the calendar by - just dismissing the popup. -
        -
      • Middle clicking will open the note in a new tab.
      • -
      • Right click will offer more options including opening the note in a new - split or window.
      • -
      -
    • -
    • Drag and drop an event on the calendar to move it to another day.
    • -
    • The length of an event can be changed by placing the mouse to the right - edge of the event and dragging the mouse around.
    • -
    -

    Configuring the calendar view

    -

    In the Collections tab in the Ribbon, - it's possible to adjust the following:

    -
      -
    • Hide weekends from the week view.
    • -
    • Display week numbers on the calendar.
    • -
    -

    Configuring the calendar using attributes

    -

    The following attributes can be added to the Collection type:

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescription
    #calendar:hideWeekends - When present (regardless of value), it will hide Saturday and Sundays - from the calendar.
    #calendar:weekNumbers - When present (regardless of value), it will show the number of the week - on the calendar.
    #calendar:view - -

    Which view to display in the calendar:

    -
      -
    • timeGridWeek for the week view;
    • -
    • dayGridMonth for the month view;
    • -
    • multiMonthYear for the year view;
    • -
    • listMonth for the list view.
    • -
    -

    Any other value will be dismissed and the default view (month) will be - used instead.

    -

    The value of this label is automatically updated when changing the view - using the UI buttons.

    -
    ~child:template - Defines the template for newly created notes in the calendar (via dragging - or clicking).
    -

    In addition, the first day of the week can be either Sunday or Monday - and can be adjusted from the application settings.

    -

    Configuring the calendar events using attributes

    -

    For each note of the calendar, the following attributes can be used:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescription
    #startDate - The date the event starts, which will display it in the calendar. The - format is YYYY-MM-DD (year, month and day separated by a minus - sign).
    #endDate - Similar to startDate, mentions the end date if the event spans - across multiple days. The date is inclusive, so the end day is also considered. - The attribute can be missing for single-day events.
    #startTime - The time the event starts at. If this value is missing, then the event - is considered a full-day event. The format is HH:MM (hours in - 24-hour format and minutes).
    #endTime - Similar to startTime, it mentions the time at which the event - ends (in relation with endDate if present, or startDate).
    #color - Displays the event with a specified color (named such as red, gray or - hex such as #FF0000). This will also change the color of the - note in other places such as the note tree.
    #calendar:color - Similar to #color, but applies the color only for the event - in the calendar and not for other places such as the note tree.
    #iconClass - If present, the icon of the note will be displayed to the left of the - event title.
    #calendar:title - Changes the title of an event to point to an attribute of the note other - than the title, can either a label or a relation (without the # or ~ symbol). - See Use-cases for more information.
    #calendar:displayedAttributes - Allows displaying the value of one or more attributes in the calendar - like this:     -
    -
    -    -
    -
    #weight="70" #Mood="Good" #calendar:displayedAttributes="weight,Mood"   -
    -
    It can also be used with relations, case in which it will display the - title of the target note:    -
    -
    ~assignee=@My assignee #calendar:displayedAttributes="assignee" -
    #calendar:startDate - Allows using a different label to represent the start date, other than startDate (e.g. expiryDate). - The label name must not be prefixed with #. - If the label is not defined for a note, the default will be used instead.
    #calendar:endDate - Similar to #calendar:startDate, allows changing the attribute - which is being used to read the end date.
    #calendar:startTime - Similar to #calendar:startDate, allows changing the attribute - which is being used to read the start time.
    #calendar:endTime - Similar to #calendar:startDate, allows changing the attribute - which is being used to read the end time.
    - -

    How the calendar works

    -

    - -

    -

    The calendar displays all the child notes of the Collection that have - a #startDate. An #endDate can optionally be added.

    -

    If editing the start date and end date from the note itself is desirable, - the following attributes can be added to the Collection note:

    #viewType=calendar #label:startDate(inheritable)="promoted,alias=Start Date,single,date"
    -#label:endDate(inheritable)="promoted,alias=End Date,single,date"
    -#hidePromotedAttributes 
    -

    This will result in:

    -

    - -

    -

    When not used in a Journal, the calendar is recursive. That is, it will - look for events not just in its child notes but also in the children of - these child notes.

    -

    Use-cases

    -

    Using with the Journal / calendar

    -

    It is possible to integrate the calendar view into the Journal with day - notes. In order to do so change the note type of the Journal note (calendar - root) to Collection and then select the Calendar View.

    -

    Based on the #calendarRoot (or #workspaceCalendarRoot) - attribute, the calendar will know that it's in a calendar and apply the - following:

    -
      -
    • The calendar events are now rendered based on their dateNote attribute - rather than startDate.
    • -
    • Interactive editing such as dragging over an empty era or resizing an - event is no longer possible.
    • -
    • Clicking on the empty space on a date will automatically open that day's - note or create it if it does not exist.
    • -
    • Direct children of a day note will be displayed on the calendar despite - not having a dateNote attribute. Children of the child notes - will not be displayed.
    • -
    - - -

    Using a different attribute as event title

    -

    By default, events are displayed on the calendar by their note title. - However, it is possible to configure a different attribute to be displayed - instead.

    -

    To do so, assign #calendar:title to the child note (not the - calendar/Collection note), with the value being name where name can - be any label (make not to add the # prefix). The attribute can - also come through inheritance such as a template attribute. If the note - does not have the requested label, the title of the note will be used instead.

    - - - - - - - - - - - - - -
      
    #startDate=2025-02-11 #endDate=2025-02-13 #name="My vacation" #calendar:title="name"
    -
    -

     

    -
    - -
    -
    - -

    Using a relation attribute as event title

    -

    Similarly to using an attribute, use #calendar:title and set - it to name where name is the name of the relation - to use.

    -

    Moreover, if there are more relations of the same name, they will be displayed - as multiple events coming from the same note.

    - - - - - - - - - - - - - -
      
    #startDate=2025-02-14 #endDate=2025-02-15 ~for=@John Smith ~for=@Jane Doe #calendar:title="for"
    -
    - -
    -

    Note that it's even possible to have a #calendar:title on the - target note (e.g. ā€œJohn Smithā€) which will try to render an attribute of - it. Note that it's not possible to use a relation here as well for safety - reasons (an accidental recursion  of attributes could cause the application - to loop infinitely).

    - - - - - - - - - - - - - -
      
    #calendar:title="shortName" #shortName="John S."
    -
    -
    - -
    -
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/List View.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/List View.html deleted file mode 100644 index 68bac777e4..0000000000 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Collections/List View.html +++ /dev/null @@ -1,20 +0,0 @@ -
    - -
    -

    List view is similar to Grid View, - but in the list view mode, each note is displayed in a single row with - only the title and the icon of the note being visible by the default. By - pressing the expand button it's possible to view the content of the note, - as well as the children of the note (recursively).

    -

    In the example above, the "Node.js" note on the left panel contains several - child notes. The right panel displays the content of these child notes - as a single continuous document.

    -

    Interaction

    -
      -
    • Each note can be expanded or collapsed by clicking on the arrow to the - left of the title.
    • -
    • In the Ribbon, - in the Collection tab there are options to expand and to collapse - all notes easily.
    • -
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File.html index 104d8dd6ac..f64ba7eade 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File.html @@ -10,58 +10,31 @@

    Supported file types

    PDFs

    -
    - -
    -

    PDFs can be browsed directly from Trilium.

    -

    Interaction:

    -
      -
    • Press the menu icon at the top-left to see a preview (thumbnail) of all - the pages, as well as a table of contents (if the PDF has this information).
    • -
    • See or edit the page number at the top.
    • -
    • Adjust the zoom using the buttons at the top or manually editing the value.
    • -
    • Rotate the document if it's in the wrong orientation.
    • -
    • In the contextual menu: -
        -
      • View two pages at once (great for books).
      • -
      • Toggle annotations (if present in the document).
      • -
      • View document properties.
      • -
      -
    • -
    +

    See PDFs.

    Images

    - +

    Interaction:

    • Copy reference to clipboard, for embedding the image within  Text notes. See Image references for - more information.
    • + class="reference-link" href="#root/_help_iPIMuisry3hd">Text notes. + +

    Videos

    -
    - -
    -

    Video files can be added in as well. The file is streamed directly, so - when accessing the note from a server it doesn't have to download the entire - video to start playing it.

    - +

    See Videos.

    Audio

    -
    - +
    +

    Adding a supported audio file will reveal a basic audio player that can be used to play it.

    @@ -76,8 +49,8 @@

    Text files

    - +

    Files that are identified as containing text will show a preview of their content. One common use case for this type of file is to embed text files @@ -94,9 +67,9 @@ of characters. To view the full file, consider opening it in an external application.

    Unknown file types

    -
    - +
    +

    If the file could not be identified as any of the supported file types from above, it will be treated as an unknown file. In this case, all the @@ -114,9 +87,7 @@

  • It is not possible to change the note type of a File note.
  • -
  • Convert into an attachment from the - note menu.
  • +
  • Convert into an attachment from the note menu.
  • Relation with other notes

      @@ -124,7 +95,7 @@

      Files are also displayed in the Note List based on their type:

      + src="4_File_image.png" width="853" height="315">
    • Non-image files can be embedded into text notes as read-only widgets via diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/1_PDFs_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/1_PDFs_image.png new file mode 100644 index 0000000000..36e4fd6d82 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/1_PDFs_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/PDFs.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/PDFs.html new file mode 100644 index 0000000000..d502c2c243 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/PDFs.html @@ -0,0 +1,119 @@ +

      + +
      +

      PDFs file can be uploaded in Trilium, where they will be displayed without + the need to download them first.

      +

      Since v0.102.0, PDFs will be rendered using Trilium's built-in PDF viewer, + which is a customization of Mozilla's PDF.js viewer (also + built-in in the Mozilla Firefox browser). Versions prior to that render + PDFs using the browser's default PDF viewer.

      +

      Storing last position and settings

      +

      For every PDF, Trilium will remember the following information:

      +
        +
      • The current page.
      • +
      • The scroll position, within the current page.
      • +
      • The rotation of the page.
      • +
      +

      This makes it useful when reading large documents since the position is + remembered automatically. This happens in the background, however it's + recorded only a few seconds after stopping any scroll actions.

      + +

      Annotations

      +

      Since v0.102.0 it's possible to annotate PDFs. To do so, look for the + annotation buttons on the right side of the PDF toolbar ( + ).

      +

      Supported annotations

      +

      The following annotation methods are supported:

      +
        +
      • Highlight +
        Allows highlighting text with one of the predefined colors. +
          +
        • The thickness is also adjustable.
        • +
        • It's also possible to highlight the blank space, turning the feature more + into a thicker pen.
        • +
        +
      • +
      • Text +
        Allows adding arbitrary text, with a custom color and size.
      • +
      • Pen +
        Allows free drawing on the document, with variable color, thickness and + opacity.
      • +
      • Image +
        Allows inserting images from outside Trilium directly into the document.
      • +
      +

      Editing existing annotations

      +

      Although annotations are stored in the PDF itself, they can be edited. + To edit an annotation, press one of the annotation buttons from the previous + section to enter edit mode and click on an existing annotation. This will + reveal a toolbar with options to customize the annotation (e.g. to change + a color), as well as the possibility to remove it.

      +

      How are annotations stored

      +

      Annotations are stored directly in the PDF. When modifications are made, + Trilium will replace the PDF with the new one.

      +

      Since modifications are automatically saved, there's no need to manually + save the document after making modifications to the annotations.

      +

      The benefit of ā€œbaked-in annotationsā€ is that they are also accessible + if downloading (for external use outside Trilium) or sharing the note.

      +

      The downside is that the entire PDF needs to be sent back to the server, + which can slow down performance for larger documents. If you encounter + any issues from this system, feel free to report it.

      +

      Filling out forms

      +

      Similar to annotations, forms are also supported by Trilium since v0.102.0. + If the document has fields that can be filled-in, they will be indicated + with a colored background.

      +

      Simply type text in the forms and they will be automatically saved.

      +

      Sidebar navigation

      + +

      When a PDF file is opened in Trilium the Right Sidebar is augmented with PDF-specific + navigation, with the following features:

      +
        +
      • Table of contents/outline +
          +
        • All the headings and ā€œbookmarksā€ will be displayed hierarchially.
        • +
        • The heading on the current page is also highlighted (note that it can + be slightly offset depending on how many headings are on the same page).
        • +
        • Clicking on a heading will jump to the corresponding position in the PDF.
        • +
        +
      • +
      • Pages +
          +
        • A preview of all the pages with a small thumbnail.
        • +
        • Clicking on a page will automatically navigate to that page.
        • +
        +
      • +
      • Attachments +
          +
        • If the PDF has its own attachments (not to be confused with Trilium's  + Attachments), they will be displayed in a list.
        • +
        • Some information such as the name and size of the attachment are displayed.
        • +
        • It's possible to download the attachment by clicking on the download button.
        • +
        +
      • +
      • Layers +
          +
        • A less common feature, if the PDF has toggle-able layers, these layers + will be displayed in a list here.
        • +
        • It's possible to toggle the visibility for each individual layer.
        • +
        +
      • +
      +

      Share functionality

      +

      PDFs can also be shared using the Sharing feature. + This will also use Trilium's customized PDF viewer.

      +

      If you are using a reverse proxy on your server with strict access limitations + for the share functionality, make sure that [host].com/pdfjs directory + is accessible. Note that this directory is outside the /share route + as it's common with the rest of the application.

      \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/PDFs_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/PDFs_image.png new file mode 100644 index 0000000000..cf8d2c109b Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/PDFs_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/Videos.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/Videos.html new file mode 100644 index 0000000000..d331bfcb49 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/Videos.html @@ -0,0 +1,131 @@ +
      + +
      +

      Starting with v0.103.0, Trilium has a custom video player which offers + more features than the built-in video player.

      +

      Versions prior to v0.103.0 also support videos, but using the built-in + player.

      +

      The file is streamed directly, so when accessing the note from a server + it doesn't have to download the entire video to start playing it.

      +

      Note on large video files

      +

      Although Trilium offers support for videos, it is generally not meant + to be used with very large files. Uploading large videos will cause the  + Database to balloon as well as the any Backup of it. In addition to that, there + might be slowdowns when first uploading the files. Otherwise, a large database + should not impact the general performance of Trilium significantly.

      +

      Supported formats

      +

      Trilium uses the built-in video decoding mechanism of the browser (or + Electron/Chromium when running on the desktop). Starting with v0.103.0, + a message will be displayed instead when a video format is not supported.

      +

      Interactions

      +

      To play/pause the video, simply click anywhere on the video.

      +

      The controls at the bottom will hide automatically after playing, simply + move the mouse to show them again.

      +

      The bottom bar has the following features:

      +
        +
      • +

        A track bar to seek across the video.

        +
      • +
      • +

        On the left of the track bar, the current time is indicated.

        +
      • +
      • +

        On the right of the track bar, the remaining time is indicated.

        +
      • +
      • +

        On the left side there are buttons to:

        +
          +
        • Adjust the playback speed (e.g. 0.5x, 1x).
        • +
        • Rotate the video by 90 degrees.
        • +
        +
      • +
      • +

        In the center:

        +
          +
        • Go back by 10s
        • +
        • Play/pause
        • +
        • Go forward by 30s
        • +
        • Loop, which when enabled will restart the video once it reaches the end.
        • +
        +
      • +
      • +

        On the right side:

        +
          +
        • Mute button
        • +
        • Volume adjustment
        • +
        • Full screen
        • +
        • Zoom to fill, which will crop the video so that it fills the entire window.
        • +
        • Picture-in-picture (if the browser supports it).
        • +
        +
      • +
      +

      Keyboard shortcuts

      +

      The following keyboard shortcuts are supported by the video player:

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Space + Play/pause
      Left arrow key + Go back by 10s
      Right arrow key + Go forward by 10s
      Ctrl + Left arrow key + Go back by 1 min
      Ctrl + Right arrow key + Go right by 1 min
      F + Toggle full-screen
      M + Mute/unmute
      Home + Go to the beginning of the video
      End + Go to the end of the video
      Up + Increase volume by 5%
      Down + Decrease volume by 5%
      \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/Videos_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/Videos_image.png new file mode 100644 index 0000000000..29cfb5da79 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File/Videos_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File_image.png index 0f01d19d96..04478a3ada 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagrams.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagrams.html index 44850ab531..eef00ae659 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagrams.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagrams.html @@ -1,12 +1,25 @@ +
      +

      Types of diagrams

      Trilium supports Mermaid, which adds support for various diagrams such as flowchart, sequence diagram, class diagram, state diagram, pie charts, etc., all using a text description of the chart instead of manually drawing the diagram.

      -

      For the official documentation of Mermaid.js see mermaid.js.org/intro/.

      +

      Starting with v0.103.0, Mermaid diagrams no longer start with a sample + flowchart, but instead a pane at the bottom will show all the supported + diagrams with sample code for each:

      +
        +
      • Simply click on any of the samples to apply it.
      • +
      • The pane will disappear as soon as something is typed in the code editor + or a sample is selected. To make it appear again, simply remove the content + of the note.
      • +

      Layouts

      Depending on the chart being edited and user preference, there are two layouts supported by the Mermaid note type:

      @@ -35,30 +48,34 @@
    • The preview can be moved around by holding the left mouse button and dragging.
    • -
    • Zooming can also be done by using the scroll wheel.
    • -
    • The zoom and position on the preview will remain fixed as the diagram - changes, to be able to work more easily with large diagrams.
    • -
    +
  • Zooming can also be done by using the scroll wheel.
  • +
  • The zoom and position on the preview will remain fixed as the diagram + changes, to be able to work more easily with large diagrams.
  • +
  • The size of the source/preview panes can be adjusted by hovering over the border between them and dragging it with the mouse.
  • In the Floating buttons area:
    • The source/preview can be laid out left-right or bottom-top via the Move editing pane to the left / bottom option.
    • -
    • Press Lock editing to automatically mark the note as read-only. +
    • Press Lock editing to automatically mark the note as read-only. In this mode, the code pane is hidden and the diagram is displayed full-size. Similarly, press Unlock editing to mark a read-only note as editable.
    • -
    • Press the Copy image reference to the clipboard to be able to insert - the image representation of the diagram into a text note. See Image references for more information.
    • -
    • Press the Export diagram as SVG to download a scalable/vector rendering - of the diagram. Can be used to present the diagram without degrading when - zooming.
    • +
    • Press the Copy image reference to the clipboard to be able to insert + the image representation of the diagram into a text note. See Image references for more information.
    • +
    • Press the Export diagram as SVG to download a scalable/vector rendering + of the diagram. Can be used to present the diagram without degrading when + zooming.
    • Press the Export diagram as PNG to download a normal image (at 1x scale, raster) of the diagram. Can be used to send the diagram in more traditional channels such as e-mail.
    • -
    -
  • + +

    Errors in the diagram

    If there is an error in the source code, the error will be displayed in diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/AI/AI Provider Information/Anthropic.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagrams/Syntax reference.dat similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/AI/AI Provider Information/Anthropic.html rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagrams/Syntax reference.dat diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mind Map.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mind Map.html index 48766db0cd..988f1bcacd 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mind Map.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mind Map.html @@ -1,6 +1,6 @@

    - +

    The mindmap allows for easy jotting down of ideas and storing them in a hierarchical fashion.

    @@ -31,9 +31,10 @@ relative to the root node (to the left, to the right, or to both sides).
  • In the Floating buttons area:
      -
    • An image reference can be copied, - to paste the mind map in a text note.
    • +
    • An image reference can be copied, to paste + the mind map in a text note.
    • The diagram can be exported either as SVG (vectorial) or PNG (raster).
    • +
    • The note can be togged read-only.
  • \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Note Map.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Note Map.html index 9c567f6700..77fabe9ed3 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Note Map.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Note Map.html @@ -1,12 +1,12 @@
    - +

    A Note map is a note type which displays a standalone version of the feature of the same name: Note Map (Link map, Tree map).

    Once created, the note map will display the relations between notes. Only the notes that are part of the parent of the note map will be displayed (including their children).

    -

    The labels mapIncludeRelation and mapExcludeRelation, +

    The labels mapIncludeRelation and mapExcludeRelation, if set, filter the note map to include only the specified relations or to exclude the specified relations, respectively.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Relation Map.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Relation Map.html index 957acc574a..11f4eaaba8 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Relation Map.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Relation Map.html @@ -1,16 +1,52 @@ -

    Relation map is a type of Note which - visualizes notes and their relations. - See an example:

    +

    Relation map is a type of note which visualizes notes and their + relations.

    +

    Interaction

    +
      +
    • To create a new note and add it to the board, press the plus button in + the Floating buttons. +
        +
      • Afterwards, click anywhere on the map to place it there.
      • +
      • The note will be placed as a sub-child of the map.
      • +
      +
    • +
    • An existing note can also be dragged from the Note Tree. It will be placed at the position + it's dragged on. +
        +
      • Multiple notes can also be dragged via Multiple selection. The notes will be positioned + near the dragged position without overlapping.
      • +
      • The dragged note can be a sub-child of the map, or it can be at any arbitrary + position.
      • +
      +
    • +
    • To create a relationship, hold the mouse on the box on the right of a + note and then: +
        +
      • Drag it over another note to create a relationship pointing from the first + note to the second one.
      • +
      • Drag over the same note to create a self-referencing relationship (represented + as a loop).
      • +
      • Once dragged, enter the name of the relationship to create. To cancel, + simply dismiss the dialog or press Esc.
      • +
      +
    • +
    • To open a note, either click on the note (opening it in the current view) + or use the right click menu to open in a new tab.
    • +
    • To edit the title of a note or to delete it (either from the map, or delete + it completely), right click the note.
    • +
    • To delete a relationship, right click it and select the corresponding + option.
    • +

    Development process demo

    This is a basic example how you can create simple diagram using relation maps:

    -

    - -

    +

    And this is how you can create it:

    -

    - -

    +

    We start completely from scratch by first creating new note called "Development process" and changing its type to "Relation map". After that we create new notes one by one and place them by clicking into the map. We also drag @@ -23,17 +59,15 @@

    Family demo

    This is more complicated demo using some advanced concepts. Resulting diagram is here:

    -

    - -

    +

    This is how you get to it:

    -

    - -

    +

    There are several steps here:

    • we start with empty relation map and two existing notes representing Prince - Philip and Queen Elizabeth II. These two notes already have "isPartnerOf" + Philip and Queen Elizabeth II. These two notes already have isPartnerOf relationsdefined.
        @@ -42,22 +76,28 @@
    • we drag both notes to relation map and place to suitable position. Notice - how the existing "isPartnerOf" relations are displayed.
    • + how the existing isPartnerOf relations are + displayed.
    • now we create new note - we name it "Prince Charles" and place it on the relation map by clicking on the desired position. The note is by default created under the relation map note (visible in the note tree on the left).
    • -
    • we create two new relations "isChildOf" targeting both Philip and Elizabeth +
    • we create two new relations isChildOf targeting + both Philip and Elizabeth
      • now there's something unexpected - we can also see the relation to display - another "hasChild" relation. This is because there's a relation definition which - puts "isChildOf" as an "inverse" - relation of "hasChildOf" (and vice versa) and thus it is created automatically.
      • + another hasChild relation. This is because + there's a relation definition which puts + isChildOfas an "inverse" relation + of hasChildOf (and vice versa) and thus it + is created automatically.
    • -
    • we create another note for Princess Diana and create "isPartnerOf" relation +
    • we create another note for Princess Diana and create isPartnerOf relation from Charles. Again notice how the relation has arrows both ways - this - is because "isPartnerOf" definition specifies its inverse relation as again - "isPartnerOf" so the opposite relation is created automatically.
    • + is because isPartnerOf definition specifies + its inverse relation as again "isPartnerOf" so the opposite relation is + created automatically.
    • as the last step we pan & zoom the map to fit better to window dimensions.

    Relation definitions mentioned above come from "Person template" note @@ -65,11 +105,12 @@ play with the whole thing in the demo notes.

    Details

    You can specify which relations should be displayed with comma delimited - names of relations in displayRelations label.

    + names of relations in displayRelations label.

    Alternatively, you can specify comma delimited list of relation names - in hideRelations which will display all relations, except for - the ones defined in the label.

    + in hideRelations which will display all relations, + except for the ones defined in the label.

    See also

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Render Note.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Render Note.html index 0d8f4200a3..7e6b8cddbe 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Render Note.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Render Note.html @@ -1,38 +1,80 @@
    - +
    -

    Render Note is used in Scripting. - It works by displaying the HTML of a Code note, - via an attribute.

    +

    Render Note is a special case of front-end scripting which + allows rendering custom content inside a note. This makes it possible to + create custom dashboards, or to use a custom note editor.

    +

    The content can either be a vanilla HTML, or Preact JSX.

    Creating a render note

    1. Create a Code note - with the HTML language, with what needs to be displayed (for example <p>Hello world.</p>).
    2. + with the: +
        +
      1. HTML language for the legacy/vanilla method, with what needs to be displayed + (for example <p>Hello world.</p>).
      2. +
      3. JSX for the Preact-based approach (see below).
      4. +
      +
    3. Create a Render Note.
    4. -
    5. Assign the renderNote relation to +
    6. Assign the renderNote relation to point at the previously created code note.
    -

    Dynamic content

    +

    Legacy scripting using jQuery

    A static HTML is generally not enough for Scripting. The next step is to automatically change parts of the note using JavaScript.

    For a simple example, we are going to create a render note that displays the current date in a field.

    -

    To do so, first create an HTML code note with the following content:

    <h1>Current date & time</h1>
    +

    To do so, first create an HTML code note with the following content:

    <h1>Current date & time</h1>
     The current date & time is <span class="date"></span>

    Now we need to add the script. Create another Code, but this time of JavaScript (frontend) language. Make sure the newly created note is a direct child of the HTML - note created previously; with the following content:

    const $dateEl = api.$container.find(".date");
    +  note created previously; with the following content:

    const $dateEl = api.$container.find(".date");
     $dateEl.text(new Date());
    -

    Now create a render note at any place and set its ~renderNote relation +

    Now create a render note at any place and set its ~renderNote relation to point to the HTML note. When the render note is accessed it will display:

    Current date & time
    The current date & time is Sun Apr 06 2025 15:26:29 GMT+0300 (Eastern European Summer Time)

    +

    Dynamic content using Preact & JSX

    +

    As a more modern alternative to jQuery, it's possible to use Preact & + JSX to render pages. Since JSX is a superset of JavaScript, there's no + need to provide a HTML anymore.

    +

    Here are the steps to creating a simple render note:

    +
      +
    1. +

      Create a note of type Render Note.

      +
    2. +
    3. +

      Create a child Code note + with JSX as the language. +
      As an example, use the following content:

      export default function() {
      +    return (
      +        <>
      +            <p>Hello world.</p>
      +        </>
      +    );
      +}
      +
    4. +
    5. +

      In the parent render note, define a ~renderNote relation + pointing to the newly created child.

      +
    6. +
    7. +

      Refresh the render note and it should display a ā€œHello worldā€ message.

      +
    8. +
    +

    Refreshing the note

    +

    It's possible to refresh the note via:

    +

    Examples

    • Weight Tracker which diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Saved Search.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Saved Search.html index 6d67947432..35c8567a68 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Saved Search.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Saved Search.html @@ -9,7 +9,8 @@ style="width:50%;">

      Location

      By default, saved searches are stored in the day note. However, you can - designate a different note to store saved searches by marking it with the #searchHome label. - Additionally, for workspaces, you - can use the #workspaceSearchHome label to specify a storage - location for saved searches within that workspace.

      \ No newline at end of file + designate a different note to store saved searches by marking it with the + #searchHomelabel. Additionally, for workspaces, + you can use the #workspaceSearchHome label + to specify a storage location for saved searches within that workspace.

      \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Spreadsheets.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Spreadsheets.html new file mode 100644 index 0000000000..010b594aa6 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Spreadsheets.html @@ -0,0 +1,91 @@ +
      + +
      + +

      Spreadsheets provide a familiar experience to Microsoft Excel or LibreOffice + Calc, with support for formulas, data validation and text formatting.

      +

      Spreadsheets vs. collections

      +

      There is a slight overlap between spreadsheets and the Table collection. In general the table + collection is useful to track meta-information about notes (for example + a collection of people and their birthdays), whereas spreadsheets are quite + useful for calculations since they support formulas.

      +

      Spreadsheets also benefit from a wider range of features such as data + validation, formatting and can work on a relatively large dataset.

      +

      Important statement regarding data format

      +

      For Trilium as a knowledge database, it is important that data is stored + in a format that is easy to convert to something else. For example,  + Text notes can be exported to either HTML or Markdown, making + it relatively easy to migrate to another software or simply to stand the + test of time.

      +

      For spreadsheets, Trilium uses a technology called Univer Sheets, + developed by DreamNum Co., Ltd. Although this software library is quite + powerful and has a good track record (starting with Luckysheet from 2020, + becoming Univer somewhere in 2023), it uses its own JSON format to store + the sheets.

      +

      As such, if Univer were to become unmaintained or incompatible for some + reason, your data might become vendor locked-in.

      +

      With that in mind, spreadsheets can be really useful for quick calculations, + but it's important not to have critical information on it that you might + not want to need in a few years time.

      +

      Regarding data export

      +

      Currently, in Trilium there is no way to export the spreadsheets to CSV + or Excel formats. We might manage to add support for it at some point, + but currently this is not the case.

      +

      Supported features

      +

      The spreadsheet has support for the following features:

      +
        +
      • Filtering
      • +
      • Sorting
      • +
      • Data validation
      • +
      • Conditional formatting
      • +
      • Notes / annotations
      • +
      • Find / replace
      • +
      +

      We might consider adding other features from + Univer at some point. If there is a particular feature that can be added + easily, it can be discussed over GitHub Issues.

      +

      Features not supported yet

      +

      Regarding Pro features

      +

      Univer spreadsheets also feature a Pro plan which + adds quite a lot of functionality such as charts, printing, pivot tables, + export, etc.

      +

      As the Pro plan needs a license, Trilium does not support any of the premium + features. Theoretically, pro features can be used in trial mode with some + limitations, we might explore this direction at some point.

      +

      Planned features

      +

      There are a few features that are already planned but are not supported + yet:

      +
        +
      • Trilium-specific formulas (e.g. to obtain the title of a note).
      • +
      • User-defined formulas
      • +
      • Cross-workbook calculation
      • +
      +

      If you would like us to work on these features, consider supporting us.

      +

      Known limitations

      +
        +
      • +

        It is possible to share a spreadsheet, case in which a best-effort HTML + rendering of the spreadsheet is done.

        +
          +
        • For more advanced use cases, this will most likely not work as intended. + Feel free to report issues, but keep in + mind that we might not be able to have a complete feature parity with all + the features of Univer.
        • +
        +
      • +
      • +

        There is currently no export functionality, as stated previously.

        +
      • +
      • +

        There is no dedicated mobile support. Mobile support is currently experimental + in Univer and when it becomes stable, we could potentially integrate it + into Trilium as well.

        +
      • +
      \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Spreadsheets_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Spreadsheets_image.png new file mode 100644 index 0000000000..6b957c220b Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Spreadsheets_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text.html index e6bfdc6967..bdb79fc490 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text.html @@ -7,8 +7,10 @@
    • The Floating toolbar is hidden by default and only appears when needed. In this mode there are actually two different toolbars:
      - - + +
    • A toolbar that appears when text is selected. This provides text-level formatting such as bold, italic, text colors, inline code, etc. @@ -159,6 +161,8 @@
    • Templates
    • +
    • Format Painter +
    @@ -133,7 +133,7 @@ - + @@ -71,7 +76,8 @@ @@ -79,7 +85,8 @@ @@ -95,4 +102,12 @@
    Insert a soft break (a <br> element)Insert a soft break (a <br> element) Shift+Enter ⇧Enter diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links.html index fa5d3dcef3..bde71988f3 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links.html @@ -5,31 +5,6 @@
  • Internal (reference) links for links to other notes within Trilium.
  • -

    Pasting links

    -
      -
    • For internal links (links to notes in Trilium), press Ctrl+C in the  - Note Tree: -
        -
      • Pasting directly in a text note will create a reference link (with an - icon to the note and the actual note title).
      • -
      • Pasting over an existing text will create a traditional link.
      • -
      -
    • -
    • For external links: -
        -
      • Paste the raw URL directly and press space to turn it into a link.
      • -
      • Select a text and paste the URL over it to turn that text into a link.
      • -
      • If you are pasting a formatted link (e.g. from the a webpage in a browser), - simply paste it and it will keep the original text and URL.
      • -
      -
    • -
    -

    In-place linking

    -

    Trilium also provides "inline" linking - type @ and you'll - see an autocomplete, just type few characters from the desired note title, - press enter and you have a link.

    Note map

    -

    Trilium provides a visualisation of incoming and outgoing links for a - particular note. See note map for - details.

    \ No newline at end of file +

    Trilium provides a visualization of incoming and outgoing links for a + particular note. See note map for details.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/1_Internal (reference) links.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/1_Internal (reference) links.png new file mode 100644 index 0000000000..614c755b29 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/1_Internal (reference) links.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/External links.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/External links.html index e296eef5a2..4bb65ae951 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/External links.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/External links.html @@ -4,7 +4,8 @@

    To create a link without a custom text:

    • Press - in the Formatting toolbar: + in the Formatting toolbar:
      • A popup will appear, type or paste the URL in the box.
      • Press Enter or the check mark icon to confirm.
      • @@ -29,7 +30,8 @@ will remain.
      • To modify the link, click on the link to display the popup and press the Edit link button.
      • + src="External links_image.png" width="18" + height="18"> Edit link button.
      • To remove a link, click on it and press the Unlink button.
      • diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/Internal (reference) links.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/Internal (reference) links.html index f4070a1b5a..404730ae3d 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/Internal (reference) links.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Links/Internal (reference) links.html @@ -1,33 +1,50 @@ -

        Unlike external notes, internal links (links to other notes) can be created - at the current position by :

        +

        Internal links are links to other notes within Trilium.

        +

        You can open an internal link by clicking it. You can also see a read-only + preview of an internal link's contents by hovering over it.

        +

        Inserting internal links

        +

        Internal links can be created at the current position in a text note by:

        1. Pressing Ctrl + L or the button from the Formatting toolbar.
        2. -
        3. Filling in the desired note to link. It's also possible to create notes - from this dialog by typing a non-existing note title and selecting Create and link child note.
        4. + width="20" height="17">button underneath the + menu in the Formatting toolbar. +
        5. Searching for the title of the desired note to link. It's also possible + to create new notes from this dialog by typing a non-existing note title + and selecting Create and link child note.
        -

        There are two link types, adjustable when creating the link to the note:

        +

        There are two link types which you can select when creating the link to + the note:

          -
        1. link title mirrors the note's current title +
        2. Link title mirrors the note's current title
          1. This is sometimes also called "reference link".
          2. -
          3. Title of such links cannot be changed, instead it is always mirroring - the title of linked note.
          4. -
          5. The icon of the note is also displayed.
          6. -
          7. The link title will automatically update if the title of the note is changed.
          8. +
          9. The title of this link cannot be changed. Instead, it will always show + the current title of the linked note.
          10. +
          11. The icon of the linked note will also be displayed.
        3. -
        4. link title can be changed arbitrarily +
        5. Link title can be changed arbitrarily
            -
          1. This is the traditional hyperlink, where the text of the link can be different - to the note title.
          2. +
          3. This will create a traditional hyperlink, where the text of the link can + be different from the note title.
        -

        Once an internal link is created:

        -
          -
        • You can follow the note link by double clicking it.
        • -
        • Alternatively if you only wish to quickly preview the content, you can - hover over the link and will see read only preview.
        • -
        \ No newline at end of file +

        In-place linking

        +

        You can also insert internal links ā€œinlineā€ by using the @ symbol:

        +
          +
        1. Type @ in a text note, which will open the + note search menu.
        2. +
        3. Search for the desired note's title by typing a few characters. Use Up and Down to + select the correct note, and press Enter or Tab to create + the link. It's also possible to create new notes with this method by typing + a non-existing note title and selecting Create and link child note.
        4. +
        +

        Pasting internal links

        +

        You can also insert internal links by copying a note from the note tree.

        +
          +
        1. In the Note Tree, + select a note and press Ctrl + C.
        2. +
        3. In a text note, paste the link by pressing Ctrl + V.
        4. +
        \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Lists.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Lists.html index 97ddf62380..1ba6f9008e 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Lists.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Lists.html @@ -1,27 +1,32 @@

        There are three types of lists supported by text notes:

        • - Bulleted lists (also known as unordered lists).
        • + Bulleted lists (also known as unordered lists).
        • - Numbered lists (or ordered lists).
        • + Numbered lists (or ordered lists).
        • - To-do lists
        • + To-do lists

        For bulleted and numbered lists, it's possible to configure an alternative marker such as squares or Roman numbering by pressing the - icon. For numbered lists, it's also possible to specify the number to start at or whether to count in reverse order.

        Keyboard interaction

        • To create a new list:
            -
          • Bulleted list: Start a line with * or - followed - by a space;
          • -
          • Numbered list: Start a line with 1. or 1) followed - by a space;
          • -
          • To-do list: Start a line with [ ] for an unchecked item or [x] for - a checked item.
          • +
          • Bulleted list: Start a line with * or + -followed by a space;
          • +
          • Numbered list: Start a line with 1. or + 1)followed by a space;
          • +
          • To-do list: Start a line with - [ ] for + an unchecked item or [x] for a checked item.
        • To create a new item in the list, press Enter.
        • @@ -29,8 +34,8 @@
        • To exit out of the list, press Enter twice.
        • To merge two lists, simply delete the gap between them.
        • To create nested lists, simply use the - button (see Indentation in Other features) + button (see Indentation in Other features) or the Tab key. To decrease the nesting level for the current element, press Shift+Tab.
        @@ -56,7 +61,7 @@
    2 - + Press Enter to create a new list item.
    4 + src="10_Lists_image.png" width="676" + height="112"> At this point, insert any desired block-level item such as a code block.
    5 + src="8_Lists_image.png" width="675" + height="129"> To continue with a new bullet point, press Enter until the cursor moves to a new blank position.

    The same principle applies to all three list types (bullet, numbered and - to-do).

    \ No newline at end of file + to-do).

    +

    To-do lists

    +
      +
    • To insert a to-do list from the keyboard, type - [ ] for + an unchecked item or [x] for a checked item + while on an empty paragraph.
    • +
    • To reorder the item under the cursor, press Alt+Up or Alt+Down. + To reorder multiple items, select them first.
    • +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Lists_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Lists_image.png index 30a9511b08..1282f27ec0 100644 Binary files a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Lists_image.png and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Lists_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Markdown-like formatting.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Markdown-like formatting.html index 165093de09..2397bef689 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Markdown-like formatting.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Markdown-like formatting.html @@ -1,7 +1,7 @@

    Markdown-like formatting allows inserting some basic formatting by typing the Markdown equivalent. Note that this does not mean that Text notes supports Markdown, - these are just some convenience shortcuts.

    + href="#root/_help_iPIMuisry3hd">Text notes supports Markdown, these + are just some convenience shortcuts.

    To import more complex formatting into text notes, consider using the Import from Markdown @@ -10,56 +10,60 @@

    • For headings:
        -
      • ## for Heading 2 (the first-level heading is reserved for - the note title).
      • -
      • ### for Heading 3
      • -
      • #### for Heading 4
      • -
      • ##### for Heading 5
      • -
      • ###### for Heading 6
      • +
      • ## for Heading 2 (the first-level heading + is reserved for the note title).
      • +
      • ### for Heading 3
      • +
      • #### for Heading 4
      • +
      • ##### for Heading 5
      • +
      • ###### for Heading 6
    • For General formatting:
        -
      • Bold: Type **text** or __text__ +
      • Bold: Type **text** or + __text__
      • -
      • Italic: Type *text* or _text_ +
      • Italic: Type *text* or _text_
      • -
      • Strikethrough: Type ~~text~~ +
      • Strikethrough: Type ~~text~~
    • For Lists:
        -
      • Bulleted list: Start a line with * or - followed - by a space;
      • -
      • Numbered list: Start a line with 1. or 1) followed - by a space;
      • -
      • To-do list: Start a line with [ ] for an unchecked item or [x] for - a checked item.
      • +
      • Bulleted list: Start a line with * or + -followed by a space;
      • +
      • Numbered list: Start a line with 1. or + 1)followed by a space;
      • +
      • To-do list: Start a line with [ ] for an + unchecked item or [x] for a checked item.
    • -
    • For block quotes, press >, +
    • For block quotes, press >, followed by a space.
    • For Code blocks, - type ```.
    • -
    • For a horizontal line, type ---.
    • + type ```. +
    • For a horizontal line, type ---.
    • For admonitions:
        -
      • !!! note +
      • !!! note
      • -
      • !!! tip +
      • !!! tip
      • -
      • !!! important +
      • !!! important
      • -
      • !!! caution +
      • !!! caution
      • -
      • !!! warning +
      • !!! warning
      • -
      • Starting any other text with !!! will insert a note admonition - with the text inside of it.
      • +
      • Starting any other text with !!! will insert + a note admonition with the text inside of it.
    • -
    • For emojis, type : followed +
    • For emojis, type : followed by an emoji name to trigger an auto-completion.

    If auto-formatting is not desirable, press Ctrl + Z to diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Math Equations.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Math Equations.html index dd41d19ab2..d8a4ef4eba 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Math Equations.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Math Equations.html @@ -1,17 +1,12 @@

    - +

    Within text notes, it's possible to enter mathematical equations using the - button from the Formatting toolbar (generally + button from the Formatting toolbar (generally found under the Insert buttons).

    -

    If inserting equations frequently, using the Ctrl+M keyboard - shortcut can be more comfortable. Alternatively, type $$ or \[ to - trigger the popup directly.

    -

    There is currently no quick way to insert an equation, such as surrounding - it with $ or pressing Ctrl+M on an already - typed-out equation.

    The mathematical expression must be written in the TeX format. There is no visual editor for the math equations, only a preview. 

    Enabling Display mode will render the equation slightly bigger @@ -19,6 +14,13 @@ center it. Display mode equations will act as blocks (i.e. like paragraphs, or tables) and can be inserted for example in lists. Non-display equations can be part of the text.

    +

    Keyboard shortcuts

    +

    If inserting equations frequently, using the Ctrl+M keyboard + shortcut can be more comfortable. Alternatively, type $$ or + \[to trigger the popup directly.

    +

    There is currently no quick way to turn an already typed-out equation, + such as surrounding it with $ or pressing Ctrl+M.

    Supported math features

    Technically we are using the KaTeX library which allows for a subset of the TeX format. To see the full list of supported features, consult the @@ -27,8 +29,12 @@ the official documentation.

    Markdown support

    Math equations will be preserved when exporting to or importing from Markdown, - surrounded by \( characters for inline math expressions, and $\) for - display mode.

    + surrounded by $ characters for inline math + expressions, and $$ for display mode.

    If you notice any issue with the Markdown import/export for equations, - feel free to report it while providing - the equation that causes issues.

    \ No newline at end of file + feel free to report it while providing the + equation that causes issues.

    +

    Formatting the equation

    +

    It is possible to customize the font size and foreground color for both + inline and display-mode equations, just like any other text. For inline + equations, the background color/highlight can also be adjusted.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Other features.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Other features.html index fe16dc6038..7ff30b1da6 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Other features.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Other features.html @@ -1,32 +1,34 @@

    Indentation

    - +

    Paragraphs can be indented to the right using the  button from the  Formatting toolbar.

    • Press - to increase the indentation of the current paragraph by one. Can be pressed + to increase the indentation of the current paragraph by one. Can be pressed multiple times if needed.
    • Press - to decrease the indentation of a current paragraph. The button will be + to decrease the indentation of a current paragraph. The button will be disabled if it is already at the minimum indentation level.
    • For convenience, keyboard shortcuts are also available. Press Tab to indent or Shift+Tab to decrease the indentation. These shortcuts work even if the cursor is not at the beginning of a paragraph or a list.
    • Apart from paragraphs, the indent button is also enabled in Lists, where it can be used to create - nested lists.
    • + href="#root/_help_S6Xx8QIWTV66">Lists, where it can be used to create nested + lists.

    Markdown import

    If the clipboard contains Markdown text, it can be easily imported into text notes. Simply copy a Markdown-formatted text and press the to insert its visual representation.

    -

    Note that this only works with raw Markdown (e.g. # Heading 1 to +

    Note that this only works with raw Markdown (e.g. # Heading 1 to generate a heading) and not the visual representation of the Markdown (e.g. as in the preview pane of an application). In that case, simply use the paste function which already accepts HTML-formatted content.

    @@ -38,14 +40,16 @@ not have access to the clipboard.

    Cut to subnote

    The - button will create a child note with the selected text. For more information, + button will create a child note with the selected text. For more information, see Cut to subnote.

    Find and replace

    - +

    The - button will open the editor's dedicated search and replace functionality.

    + button will open the editor's dedicated search and replace functionality.

    Alternatively, the Ctrl+F combination can be pressed to show the dialog.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features.html index 8b3a9e8acb..7da7ce5db1 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features.html @@ -14,5 +14,6 @@

    At this moment there is no way to disable these features, apart from manually modifying the source code. If this is a problem, let us know.

    If you have the possibility of rebuilding the source code (e.g. if a package - maintainer), then modify VITE_CKEDITOR_KEY in apps/client/.env to - be GPL.

    \ No newline at end of file + maintainer), then modify VITE_CKEDITOR_KEY in + apps/client/.envto be GPL.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter.html new file mode 100644 index 0000000000..3271503068 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter.html @@ -0,0 +1,48 @@ +
    + +
    + +

    The Format Painter is a feature in text notes that allows users to copy + the formatting of text (such as bold, italic, Strikethrough, + etc.) and apply it to other parts of the document. It helps maintain consistent + formatting and accelerates the creation of rich content.

    +

    Usage Instructions

    +

    Click the text that you want to copy the formatting from and use the paint + formatting toolbar button ( + Format painter) to copy the style. Then select the target text with your mouse to apply + the formatting.

    +
      +
    • To copy the formatting: Place the cursor inside a text + with some formatting and click the paint formatting toolbar button. Notice + that the mouse cursor changes to the + Format painter text cursor.
    • +
    • To paint with the copied formatting: Click any word in + the document and the new formatting will be applied. Alternatively, instead + of clicking a single word, you can select a text fragment (like an entire + paragraph). Notice that the cursor will go back to the default one after + the formatting is applied.
    • +
    • To keep painting using the same formatting: Open the + toolbar dropdown and enable the continuous painting mode. Once copied, + the same formatting can be applied multiple times in different places until + the paint formatting button is clicked (the cursor will then revert to + the regular one).
    • +
    +

    Limitations

    +
      +
    1. Painting with block-level formatting (like headings or image styles) is + not supported yet. This is because, in CKEditor, + they are considered a part of the content rather than text formatting.
    2. +
    3. When applying formatting to words, spaces or other Western punctuation + are used as word boundaries, which prevents proper handling of languages + that do not use space-based word segmentation.
    4. +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_746436a2e1.svg b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_746436a2e1.svg new file mode 100644 index 0000000000..77ad84f56b --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_746436a2e1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_e144e96df9.svg b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_e144e96df9.svg new file mode 100644 index 0000000000..06342b7c73 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_e144e96df9.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_image.png new file mode 100644 index 0000000000..db5cbbbd11 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Slash Commands.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Slash Commands.html index ca453511af..bcd8f95565 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Slash Commands.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Premium features/Slash Commands.html @@ -1,6 +1,6 @@
    - +

    To implement this widget:

      -
    1. Create a new JS Frontend note in Trilium and paste in the code - above.
    2. -
    3. Assign the #widget attribute to +
    4. Create a new JS Frontend note in Trilium + and paste in the code above.
    5. +
    6. Assign the #widget attribute to the note.
    7. Restart Trilium or reload the window.
    -

    To verify that the widget is working, open the developer tools (Cmd + Shift + I) - and run document.querySelector("#my-widget"). If the element - is found, the widget is functioning correctly. If undefined is +

    To verify that the widget is working, open the developer tools (Ctrl + Shift + I) + and run document.querySelector("#my-widget"). + If the element is found, the widget is functioning correctly. If undefined is returned, double-check that the note has - the #widget attribute.

    + the #widget attribute.

    Step 2: Adding an UI Element

    -

    Next, let's improve the widget by adding a button to it.

    const template = ``;
    +

    Next, let's improve the widget by adding a button to it.

    const template = `<div id="my-widget"><button>Click Me!</button></div>`;
     
     class MyWidget extends api.BasicWidget {
         get position() {return 1;}
    @@ -46,8 +46,10 @@ module.exports = new MyWidget();

    Step 3: Styling the Widget

    To make the button more visually appealing and position it correctly, we'll apply some custom styling. Trilium includes Box Icons, - which we'll use to replace the button text with an icon. For example the bx bxs-magic-wand icon.

    -

    Here's the updated template:

    const template = ``;
    + which we'll use to replace the button text with an icon. For example the + bx bxs-magic-wandicon.

    +

    Here's the updated template:

    const template = `<div id="my-widget"><button class="tree-floating-button bx bxs-magic-wand tree-settings-button"></button></div>`;

    Next, we'll adjust the button's position using CSS:

    class MyWidget extends api.BasicWidget {
         get position() { return 1; }
         get parentWidget() { return "left-pane"; }
    @@ -69,7 +71,8 @@ module.exports = new MyWidget();
    of the left pane, alongside other action buttons.

    Step 4: Adding User Interaction

    Let’s make the button interactive by showing a message when it’s clicked. - We'll use the api.showMessage method from the Script API.

    class MyWidget extends api.BasicWidget {
    +  We'll use the api.showMessage method from
    +  the Script API.

    class MyWidget extends api.BasicWidget {
         get position() { return 1; }
         get parentWidget() { return "left-pane"; }
         
    @@ -87,5 +90,8 @@ module.exports = new MyWidget();
    } module.exports = new MyWidget();
    -

    Reload the application one last time. When you click the button, a "Hello - World!" message should appear, confirming that your widget is fully functional.

    \ No newline at end of file +

    For the list of possible values for parentWidget(), + see Custom Widgets

    +

    Reload the application one last time. + When you click the button, a "Hello World!" message should appear, confirming + that your widget is fully functional.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Custom Widgets/Word count widget.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget.html similarity index 93% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Custom Widgets/Word count widget.html rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget.html index c627056c85..52a8a2d30d 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Custom Widgets/Word count widget.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget.html @@ -3,7 +3,7 @@ href="#root/_help_6tZeKvSHEUiB">Demo Notes.

    Create a Code note - of type JS frontend and give it a #widget label.

    /*
    +  of type JS frontend and give it a  #widget  label.

    /*
      * This defines a custom widget which displays number of words and characters in a current text note.
      * To be activated for a given note, add label 'wordCount' to the note, you can also make it inheritable and thus activate it for the whole subtree.
      * 
    @@ -83,6 +83,6 @@ module.exports = new WordCountWidget();

    At the bottom of the note you can see the resulting widget:

    - +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Custom Widgets/Word count widget_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget_image.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Custom Widgets/Word count widget_image.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget_image.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/Downloading responses from Goo.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/Downloading responses from Goo.html similarity index 88% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/Downloading responses from Goo.html rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/Downloading responses from Goo.html index c6911fb883..05d13383b5 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/Downloading responses from Goo.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/Downloading responses from Goo.html @@ -2,7 +2,7 @@ are able to download the responses of a form using the ā€œLink to Sheets" functionality.

    Note that the link will be publicly accessible to everyone (however the - link is in a hard-to-guess format such as https://docs.google.com/spreadsheets/d/e/2PACX-1vTA8NU2_eZFhc8TFadCZPreBfvP7un8IHd6J0SchrLLw3ueGmntNZjwRmsH2ZRcp1pJYDAzMz1FmFaj/pub?output=csv). + link is in a hard-to-guess format such as https://docs.google.com/spreadsheets/d/e/2PACX-1vTA8NU2_eZFhc8TFadCZPreBfvP7un8IHd6J0SchrLLw3ueGmntNZjwRmsH2ZRcp1pJYDAzMz1FmFaj/pub?output=csv). Make sure you are not accidentally publishing sensitive information.

    Obtaining the CSV link

      diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/New Task launcher button.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button.html similarity index 90% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/New Task launcher button.html rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button.html index aae9e6f6f4..346b57093b 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/New Task launcher button.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button.html @@ -1,14 +1,15 @@

      In this example we are going to extend the functionality of Task Manager showcase (which comes - by default with Trilium) by adding a button in the Task Manager showcase (which comes by + default with Trilium) by adding a button in the Launch Bar  ( ) to create a new task automatically and open it.

      Creating the note

      1. First, create a new Code note type with the JS frontend language.
      2. -
      3. Define the #run=frontendStartup label in Attributes.
      4. +
      5. Define the #run=frontendStartup label in  + Attributes.

      Content of the script

      Copy-paste the following script:

      api.addButtonToToolbar({
      @@ -48,8 +49,8 @@
       });
      -

      This uses the Front-end API to create - a icon in the Launch Bar, +

      This uses the Front-end API to create a + icon in the Launch Bar, by specifying:

      • A title
      • @@ -117,8 +118,8 @@
          -
        • Since we know the ID of the newly - created note, all we have to do now is to show this note to the user.
        • +
        • Since we know the ID of the newly created + note, all we have to do now is to show this note to the user.
        diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/New Task launcher button_i.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button_i.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/New Task launcher button_i.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button_i.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/Using promoted attributes .png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes .png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/Using promoted attributes .png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes .png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/Using promoted attributes to c.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes to c.html similarity index 87% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/Using promoted attributes to c.html rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes to c.html index c76d5d93aa..08ea0c0d25 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Examples/Using promoted attributes to c.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes to c.html @@ -30,9 +30,10 @@ if (!outputNoteId) { api.showError("Missing output."); return; }
    -

    Note that here we are using api.showError which is only available - for frontend notes. If you are writing a backend note, simply remove api.showError but - the user will no feedback on why the script did not execute properly.

    +

    Note that here we are using api.showError which + is only available for frontend notes. If you are writing a backend note, + simply remove api.showError but the user + will no feedback on why the script did not execute properly.

    Afterwards we can simply read the note and do something with it:

    const note = api.getNote(inputNoteId);
     if (!note) {
     	return;
    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets.html
    new file mode 100644
    index 0000000000..acf5a50e35
    --- /dev/null
    +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets.html	
    @@ -0,0 +1,30 @@
    +

    Launch bar widgets are a subset of Custom Widgets that + can be used to render custom buttons and widgets inside the Launch Bar.

    +

    Creating a launch bar widget

    +

    Unlike Custom Widgets, + the process of setting up a launch bar widget is slightly different:

    +
      +
    1. Create a Code note of type JavaScript (front-end) or JSX (for Preact-based + widgets). +
        +
      • The script itself uses the same concepts as Custom Widgets, including the use of a + NoteContextAwareWidgetor a BasicWidget (according + to needs).
      • +
      • As examples in both legacy and Preact format, see Note Title Widget and Analog Watch.
      • +
      +
    2. +
    3. Don't set #widget, as that attribute is + reserved for Custom Widgets.
    4. +
    5. In the Global menu, + select Configure launchbar.
    6. +
    7. In the Visible Launchers section, select Add a custom widget.
    8. +
    9. Give the newly created launcher a name (and optionally a name).
    10. +
    11. In the Promoted Attributes section, + modify the widget field to point to the newly created note.
    12. +
    13. Refresh the UI.
    14. +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch.html new file mode 100644 index 0000000000..e9625e39b7 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch.html @@ -0,0 +1,84 @@ +
    + +
    +

    This is a more intricate example of a basic widget, which displays an + analog watch in the launch bar. Unlike note-context aware widgets, basic + widgets don't react to note navigation.

    const TPL = `
    +<div class="analog-watch" style="
    +    position: relative;
    +    height: 38px;
    +    width: 38px;
    +    border-radius: 50%;
    +    background: white;
    +    border: 2px solid #444;
    +    flex-shrink: 0;
    +">
    +    <!-- hour hand -->
    +    <div class="hand hour" style="
    +        position: absolute;
    +        left: 50%;
    +        top: 50%;
    +        width: 3px;
    +        height: 10px;
    +        background: #333;
    +        transform-origin: bottom center;
    +    "></div>
    +
    +    <!-- minute hand -->
    +    <div class="hand minute" style="
    +        position: absolute;
    +        left: 50%;
    +        top: 50%;
    +        width: 2px;
    +        height: 13px;
    +        background: #111;
    +        transform-origin: bottom center;
    +    "></div>
    +
    +    <!-- second hand -->
    +    <div class="hand second" style="
    +        position: absolute;
    +        left: 50%;
    +        top: 50%;
    +        width: 1px;
    +        height: 15px;
    +        background: red;
    +        transform-origin: bottom center;
    +    "></div>
    +</div>
    +`;
    +
    +class AnalogWatchWidget extends api.BasicWidget {
    +    doRender() {        
    +        this.$widget = $(TPL);
    +
    +        const hourHand   = this.$widget.find('.hand.hour')[0];
    +        const minuteHand = this.$widget.find('.hand.minute')[0];
    +        const secondHand = this.$widget.find('.hand.second')[0];
    +
    +        const update = () => {
    +            const now = new Date();
    +            const sec  = now.getSeconds();
    +            const min  = now.getMinutes();
    +            const hour = now.getHours();
    +
    +            const secDeg  = sec * 6;
    +            const minDeg  = min * 6 + sec * 0.1;
    +            const hourDeg = (hour % 12) * 30 + min * 0.5;
    +
    +            secondHand.style.transform = `translate(-50%, -100%) rotate(${secDeg}deg)`;
    +            minuteHand.style.transform = `translate(-50%, -100%) rotate(${minDeg}deg)`;
    +            hourHand.style.transform   = `translate(-50%, -100%) rotate(${hourDeg}deg)`;
    +        };
    +
    +        update();
    +        this._interval = setInterval(update, 1000);
    +    }
    +
    +    cleanup() {
    +        if (this._interval) clearInterval(this._interval);
    +    }
    +}
    +
    +module.exports = new AnalogWatchWidget();
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch_image.png new file mode 100644 index 0000000000..809488185c Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget.html new file mode 100644 index 0000000000..5386d00521 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget.html @@ -0,0 +1,47 @@ +
    + +
    +

    This is an example of a note context-aware widget, which reacts to the + currently opened note and refreshes automatically as the user navigates + through the notes.

    +

    Legacy widget

    +

    In this example, the title of the note is displayed. It works best on + the horizontal layout.

    const TPL = `\
    +<div style="
    +    display: flex;
    +    height: 53px;
    +    width: fit-content;
    +    font-size: 0.75em;
    +    contain: none;
    +    align-items: center;
    +    flex-shrink: 0;
    +    padding: 0 1em;
    +"></div>`;
    +
    +class NoteTitleWidget extends api.NoteContextAwareWidget {
    +    doRender() {
    +        this.$widget = $(TPL);
    +    }
    +
    +    async refreshWithNote(note) {
    +        this.$widget.text(note.title);
    +    }
    +}
    +
    +module.exports = new NoteTitleWidget();
    +

    Preact widget (v0.101.0+)

    import { defineLauncherWidget, useActiveNoteContext } from "trilium:preact";
    +
    +export default defineLauncherWidget({
    +    render: () => {
    +        const { note } = useActiveNoteContext();
    +        return <div style={{
    +            display: "flex",
    +            height: "53px",
    +            width: "fit-content",
    +            fontSize: "0.75em",
    +            alignItems: "center",
    +            flexShrink: 0            
    +        }}>{note?.title}</div>;
    +    }
    +});
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget_image.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget_image.png new file mode 100644 index 0000000000..6320bd8f17 Binary files /dev/null and b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget_image.png differ diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact.html new file mode 100644 index 0000000000..6834652270 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact.html @@ -0,0 +1,63 @@ +

    Since v0.101.0, Trilium integrates Preact for front-end scripting, including + support for JSX.

    +

    Preact can be used for:

    +
      +
    • Render Note, where + a JSX code note is used instead of a HTML one.
    • +
    • Custom Widgets, + where JSX can be used to replace the old, jQuery-based mechanism.
    • +
    +

    To get started, the first step is to enable JSX in the list of Code languages. + Go to Options → Code Notes and check the ā€œJSXā€ language. Afterwards, proceed + with the documentation in either Render Note or  + Custom Widgets, which will both have a section on how to use the new + Preact integration.

    + +

    Import/exports

    +

    When using Preact with JSX, there is a special syntax which provides ES-like + imports. This import syntax makes way for + a more intuitive that doesn't make use of global objects and paves the + way for better auto-completion support that might be introduced in the + future. 

    +

    API imports

    +

    Instead of:

    api.showMessage("Hello");
    +

    the JSX version looks like this:

    import { showMessage } from "trilium:api";
    +showMessage("hello");
    +

    Preact API imports (hooks, components)

    +

    There's a new Script API dedicated + to Preact, which provides shared components that are also used by Trilium + internally as well as hooks, for example.

    import { useState } from "trilium:preact";
    +const [ myState, setMyState ] = useState("Hi");
    +

    Exporting

    +

    JSX notes can export a component for use in Render Note or for Component libraries: 

    export default function() {
    +    return (
    +        <>
    +            <p>Hello world.</p>
    +        </>
    +    );
    +}
    +

    Import/export are not required

    +

    These imports are syntactic sugar meant to replace the usage for the + apiglobal object (see Script API). 

    + +

    Under the hood

    +

    Unlike JavaScript, JSX requires pre-processing to turn it into JavaScript + (just like TypeScript). To do so, Trilium uses Sucrase, + a JavaScript library which processes the JSX to pure JavaScript. The processing + is done each time a script is run (for widgets this happens at every program + startup). If you notice any performance degradation due to long compilation, + consider reporting the issue to us.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components.html new file mode 100644 index 0000000000..73243df78d --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components.html @@ -0,0 +1,44 @@ +
    + +
    A partial screenshot from the Widget showcase example (see below).
    +
    +

    Trilium comes with its own set of Preact components, some of which are + also available to Custom Widgets and  + Render Note.

    +

    To use these components, simply import them from trilium:preact:

    import { ActionButton, Button, LinkButton } from "trilium:preact";
    +

    and then use them:

    export default function MyRenderNote() {
    +    const onClick = () => showMessage("A button was pressed");
    +    
    +    return (
    +        <>
    +            <h2>Buttons</h2>
    +            <div style={{ display: "flex", gap: "1em", alignItems: "center" }}>
    +                <ActionButton icon="bx bx-rocket" text="Action button" onClick={onClick} />
    +                <Button icon="bx bx-rocket" text="Simple button" onClick={onClick} />
    +                <LinkButton text="Link button" onClick={onClick} />                
    +            </div>
    +        </>
    +    )
    +}
    +

    Widget showcase

    + +

    This is a Render Note example + with JSX that shows most of the built-in components that are accessible + to custom widgets and JSX render notes.

    +

    To use it, simply:

    +
      +
    1. Create a render note.
    2. +
    3. Create a child code note of JSX type with the content of this file:  + Widget showcase +
    4. +
    5. Set the ~renderNote relation of the parent + note to the child note.
    6. +
    7. Refresh the render note to see the results.
    8. +
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components/Widget showcase.jsx b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components/Widget showcase.jsx new file mode 100644 index 0000000000..6da0b9a5b4 --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components/Widget showcase.jsx @@ -0,0 +1,189 @@ +import { + ActionButton, Button, LinkButton, + Admonition, Collapsible, + FormCheckbox, FormDropdownList, FormFileUploadButton, FormGroup, FormRadioGroup, FormTextArea, + FormTextBox, FormToggle, Slider, RawHtml, LoadingSpinner, Icon, + Dropdown, FormListItem, FormDropdownDivider, FormDropdownSubmenu, + NoteAutocomplete, NoteLink, Modal, + CKEditor, + useEffect, useState +} from "trilium:preact"; +import { showMessage } from "trilium:api"; + +export default function() { + const [ time, setTime ] = useState(); + const lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam accumsan eu odio non gravida. Pellentesque ornare, arcu condimentum molestie dignissim, nibh turpis ultrices elit, eget elementum nunc erat at erat. Maecenas vehicula consectetur elit, nec fermentum elit venenatis eu."; + useEffect(() => { + const interval = setInterval(() => setTime(new Date().toLocaleString()), 1000); + return () => clearInterval(interval); + }, []); + + return ( +
    +

    Widget showcase

    + + + + Admonition
    + {lorem} +
    + + + {lorem} + + + + + + +
    + ); +} + +function Buttons() { + const onClick = () => showMessage("A button was pressed"); + + return ( + <> +

    Buttons

    +
    + +
    + + ) +} + +function FormElements() { + const [ checkboxChecked, setCheckboxChecked ] = useState(false); + const [ dropdownValue, setDropdownValue ] = useState("key-1"); + const [ radioGroupValue, setRadioGroupValue ] = useState("key-1"); + const [ sliderValue, setSliderValue ] = useState(50); + + return ( + <> +

    Form elements

    +
    + + + + + + + + + + + + + + {}} + /> + + + {}} + /> + + + + + + { + const file = files?.[0]; + if (!file) return; + showMessage(`Got file "${file.name}" of size ${file.size} B and type ${file.type}.`); + }} + /> + + + + + + + + + + +
    + + ) +} + +function NoteElements() { + const [ noteId, setNoteId ] = useState(""); + + return ( +
    +

    Note elements

    + + + + + + + {noteId + ? + : Select a note first} + +
    + ); +} + +function ModalSample() { + const [ shown, setShown ] = useState(false); + + return ( + <> +

    Modal

    + -

    -If you use VSCode, install the Sherlock i18n extension for a better i18n experience. -

    diff --git a/apps/website/src/routes/download-now.svelte b/apps/website/src/routes/download-now.svelte deleted file mode 100644 index 20abe9c55f..0000000000 --- a/apps/website/src/routes/download-now.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - -{#if url} - - Download now - - ({platform} {architecture}) - - -{/if} \ No newline at end of file diff --git a/apps/website/src/routes/download/+page.svelte b/apps/website/src/routes/download/+page.svelte deleted file mode 100644 index b09c684f98..0000000000 --- a/apps/website/src/routes/download/+page.svelte +++ /dev/null @@ -1,65 +0,0 @@ - - - - Trilium Notes: Download - - - -
    -
    -

    Download the desktop application

    - - -
    - Architecture: -
    - {#each architectures as arch} - - {/each} -
    -
    - -
    - {#each Object.entries(downloadMatrix.desktop) as [platformId, platform]} - {@const textColor = (platformId === "windows" ? "text-blue-600" : platformId === "linux" ? "text-violet-600" : "text-gray-800 dark:text-gray-100")} - {@const bgColor = (platformId === "windows" ? "bg-blue-600" : platformId === "linux" ? "bg-violet-600" : "bg-gray-800")} - {@const hoverColor = (platformId === "windows" ? "hover:bg-blue-700" : platformId === "linux" ? "hover:bg-violet-700" : "hover:bg-gray-900")} - - {/each} -
    -
    - -
    -

    Set up a server for access on multiple devices

    - -
    - {#each Object.entries(downloadMatrix.server) as [platformId, platform]} - {@const textColor = (platformId === "linux" ? "text-violet-600" : "text-gray-800 dark:text-gray-100")} - {@const bgColor = (platformId === "linux" ? "bg-violet-600" : "bg-gray-800")} - {@const hoverColor = (platformId === "linux" ? "hover:bg-violet-700" : "hover:bg-gray-900")} - - {/each} -
    -
    - - - -
    diff --git a/apps/website/src/routes/download/download-card.svelte b/apps/website/src/routes/download/download-card.svelte deleted file mode 100644 index 9fd89c20fc..0000000000 --- a/apps/website/src/routes/download/download-card.svelte +++ /dev/null @@ -1,31 +0,0 @@ - - -
    -

    {typeof platform.title === "object" ? platform.title[architecture] : platform.title}

    -

    {typeof platform.title === "object" ? platform.description[architecture] : platform.description}

    -
    - {#if recommended} - - {recommended[1].name} - - {/if} -
    - {#each Object.entries(platform.downloads).filter((e) => !e[1].recommended) as [format, download]} - - {download.name} - - {/each} -
    -
    -
    \ No newline at end of file diff --git a/apps/website/src/routes/feature-block.svelte b/apps/website/src/routes/feature-block.svelte deleted file mode 100644 index 982eea437c..0000000000 --- a/apps/website/src/routes/feature-block.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - -
    - {imgAlt} -
    -

    {title}

    -

    {text}

    -
    -
    \ No newline at end of file diff --git a/apps/website/src/routes/header.svelte b/apps/website/src/routes/header.svelte deleted file mode 100644 index af1a7f057d..0000000000 --- a/apps/website/src/routes/header.svelte +++ /dev/null @@ -1,23 +0,0 @@ - -
    - -
    \ No newline at end of file diff --git a/apps/website/src/style.css b/apps/website/src/style.css new file mode 100644 index 0000000000..39f15c4035 --- /dev/null +++ b/apps/website/src/style.css @@ -0,0 +1,195 @@ +@font-face { + font-family: "Inter"; + src: url(./assets/fonts/Inter/Inter-VariableFont_opsz,wght.ttf); +} + +:root { + --background-color: #fff; + --foreground-color: black; + --muted-color: #606060; + --card-background-color: white; + --card-box-shadow: 0 0 3px rgba(0, 0, 0, 0.25); + --header-background-color: rgba(255, 255, 255, 0.75); + --brand-1: #e47b19; + --brand-2: #4fa52b; + --brand-3: #e33f3b; + --brand-foreground-color: white; +} + +@media (prefers-color-scheme: dark) { + :root { + --foreground-color: #fff; + --background-color: #0a0e14; + --muted-color: #c5c5c5; + --header-background-color: rgba(0, 0, 0, 0.75); + --card-background-color: #ffffff12; + --card-box-shadow: 0 0 12px rgba(0, 0, 0, 0.15); + } +} + +html, +body { + margin: 0; + line-height: 1.5; + font-family: Inter, + system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, + "Noto Sans", "Noto Sans CJK SC", + "Hiragino Sans", "Hiragino Kaku Gothic ProN", + "Microsoft YaHei", "Meiryo", "Malgun Gothic", + "PingFang SC", "Source Han Sans SC", + "Source Han Sans JP", "Source Han Sans KR"; + min-height: 100vh; +} + +main { + min-height: calc(100vh - 80px - 136px); + display: flex; + flex-direction: column; +} + +body { + background: var(--background-color); + color: var(--foreground-color); +} + +a { + color: var(--brand-3); + text-decoration: none; + + &:not(.button):hover { + text-decoration: underline; + } +} + +.content-wrapper { + max-width: 1200px; + width: 90%; + margin: auto; + box-sizing: border-box; +} + +section { + padding: 1em 0; + justify-content: center; + align-items: stretch; + + &.fill { + flex-grow: 1; + display: flex; + } + + h2 { + text-align: center; + font-weight: 300; + margin-top: 0; + margin-bottom: 1em; + } +} + +img { + width: 100%; + height: auto; +} + +.card { + border: 0; + box-shadow: var(--card-box-shadow); + background-color: var(--card-background-color); + border-radius: 16px; + overflow: hidden; + display: flex; + flex-direction: column; + + h3 { + font-size: 1.1rem; + font-weight: 300; + margin: 0; + color: var(--brand-1); + margin-bottom: 0.5em; + + &> span { + vertical-align: middle; + } + } + + &> .image { + height: 200px; + object-fit: cover; + } + + .card-content { + margin: 0; + padding: 1em; + color: var(--muted-color); + display: flex; + flex-direction: column; + flex-grow: 1; + + .more-info-container { + margin-top: 0.5em; + flex-grow: 1; + display: flex; + flex-direction: column; + justify-content: flex-end; + + .more-info { + font-size: 0.9em; + } + } + } +} + +.bx { + display: inline-block; + width: 24px; + height: 24px; + vertical-align: middle; + + svg { + fill: currentColor; + } +} + +@media (max-width: 719.99px) { + .grid-4-cols > *, + .grid-3-cols > *, + .grid-2-cols > * { + margin-bottom: 1em; + } + + .desktop-only { + display: none !important; + } +} + +@media (min-width: 720px) { + section { + padding: 3em 0; + + h2 { + margin-bottom: 2em; + } + } + + .grid-4-cols { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + gap: 1em; + } + + .grid-3-cols { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 1em; + } + + .grid-2-cols { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1em; + } + + .mobile-only { + display: none !important; + } +} diff --git a/apps/website/src/translations/ar/translation.json b/apps/website/src/translations/ar/translation.json new file mode 100644 index 0000000000..6760c21d57 --- /dev/null +++ b/apps/website/src/translations/ar/translation.json @@ -0,0 +1,145 @@ +{ + "download_helper_server_linux": { + "download_tar_arm64": "بصيغة ARM (.tar.xz)", + "download_nixos": "Ł…ŁƒŁˆŁ† NixOS", + "download_tar_x64": "x64 (.tar.xz)", + "title": "الاستضافة Ų§Ł„Ų°Ų§ŲŖŁŠŲ© على نظام Ł„ŁŠŁ†ŁƒŲ³" + }, + "download_helper_server_hosted": { + "title": "استضافة Ł…ŲÆŁŁˆŲ¹Ų©", + "download_triliumcc": "بدلا من Ų°Ł„ŁƒŲŒ Ų±Ų§Ų¬Ų¹ trillum. cc", + "download_pikapod": "اعدلد على PikaPods" + }, + "get-started": { + "architecture": "Ų§Ł„Ł…Ų¹Ł…Ų§Ų±ŁŠŲ©:", + "older_releases": "انظر الى الاصدارات Ų§Ł„Ł‚ŲÆŁŠŁ…Ų©", + "title": "Ų§ŲØŲÆŲ£ الان", + "desktop_title": "قم ŲØŲŖŲ­Ł…ŁŠŁ„ ŲŖŲ·ŲØŁŠŁ‚ Ų³Ų·Ų­ Ų§Ł„Ł…ŁƒŲŖŲØ (v{{version}})", + "server_title": "Ų„Ų¹ŲÆŲ§ŲÆ Ų®Ų§ŲÆŁ… Ł„Ł„ŲÆŲ®ŁˆŁ„ من أكثر من جهاز" + }, + "hero_section": { + "github": "GitHub", + "get_started": "Ų§ŲØŲÆŲ£ الان", + "dockerhub": "Ł…Ų³ŲŖŁˆŲÆŲ¹ Docker", + "title": "Ų±ŲŖŲØ أفكارك. ابنِ قاعدة Ł…Ų¹Ų±ŁŲŖŁƒ Ų§Ł„Ų“Ų®ŲµŁŠŲ©.", + "subtitle": "ŲŖŲ±ŁŠŁ„ŁŠŁˆŁ… Ł‡Łˆ Ų­Ł„ Ł…ŁŲŖŁˆŲ­ المصدر Ł„ŲŖŲÆŁˆŁŠŁ† الملاحظات ŁˆŲŖŁ†ŲøŁŠŁ… قاعدة المعرفة Ų§Ł„Ų“Ų®ŲµŁŠŲ©. استخدمه Ł…Ų­Ł„ŁŠŁ‹Ų§ على جهاز Ų§Ł„ŁƒŁ…ŲØŁŠŁˆŲŖŲ± الخاص بك، أو قم بمزامنته Ł…Ų¹ Ų®Ų§ŲÆŁ…Łƒ المستضاف Ų°Ų§ŲŖŁŠŁ‹Ų§ للاحتفاظ ŲØŁ…Ł„Ų§Ų­ŲøŲ§ŲŖŁƒ Ų£ŁŠŁ†Ł…Ų§ ŁƒŁ†ŲŖ.", + "screenshot_alt": "لقطة Ų“Ų§Ų“Ų© Ł„ŲŖŲ·ŲØŁŠŁ‚ Trilium Notes لسطح Ų§Ł„Ł…ŁƒŲŖŲØ" + }, + "organization_benefits": { + "title": "ŲŖŁ†ŲøŁŠŁ…", + "note_structure_title": "Ł‡ŁŠŁƒŁŠŁ„ŁŠŲ© الملاحظة", + "hoisting_title": "Ł…Ų³Ų§Ų­Ų§ŲŖ العمل ŁˆŲ§Ł„ŲŖŲ±ŁƒŁŠŲ² على الملاحظة", + "attributes_title": "العلاقات ŁˆŲ¬ŲÆŲ§ŁˆŁ„ الملاحظة", + "note_structure_description": "ŁŠŁ…ŁƒŁ† ŲŖŁ†ŲøŁŠŁ… الملاحظات ŲØŲ“ŁƒŁ„ Ł‡Ų±Ł…ŁŠ. لا Ų­Ų§Ų¬Ų© Ł„Ł„Ł…Ų¬Ł„ŲÆŲ§ŲŖŲŒ Ų„Ų° ŁŠŁ…ŁƒŁ† أن تحتوي ŁƒŁ„ ملاحظة على ملاحظات فرعية. ŁˆŁŠŁ…ŁƒŁ† ؄ضافة الملاحظة Ų§Ł„ŁˆŲ§Ų­ŲÆŲ© في Ų¹ŲÆŲ© Ł…ŁˆŲ§Ų¶Ų¹ ضمن التسلسل Ų§Ł„Ł‡Ų±Ł…ŁŠ.", + "attributes_description": "Ų§Ų³ŲŖŲ®ŲÆŁ… العلاقات ŲØŁŠŁ† الملاحظات أو أضف ŲŖŲµŁ†ŁŠŁŲ§ŲŖ Ł„ŲŖŲ³Ł‡ŁŠŁ„ Ų¹Ł…Ł„ŁŠŲ© Ų§Ł„ŲŖŲµŁ†ŁŠŁ. Ų§Ų³ŲŖŲ®ŲÆŁ… السمات Ų§Ł„Ł…ŁŲ±ŁˆŁŽŁ‘Ų¬Ų© ل؄دخال Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ Ł…ŁŁ‡ŁŠŁƒŁ„Ų© ŁŠŁ…ŁƒŁ† استخدامها في Ų§Ł„Ų¬ŲÆŲ§ŁˆŁ„ ŁˆŲ§Ł„Ł„ŁˆŲ­Ų§ŲŖ.", + "hoisting_description": "ŁŠŁ…ŁƒŁ†Łƒ ŲØŲ³Ł‡ŁˆŁ„Ų© فصل Ł…Ł„Ų§Ų­ŲøŲ§ŲŖŁƒ Ų§Ł„Ų“Ų®ŲµŁŠŲ© ŁˆŁ…Ł„Ų§Ų­ŲøŲ§ŲŖ العمل عن Ų·Ų±ŁŠŁ‚ ŲŖŲ¬Ł…ŁŠŲ¹Ł‡Ų§ ضمن Ł…Ų³Ų§Ų­Ų© Ų¹Ł…Ł„ŲŒ Ł…Ł…Ų§ يركز Ų“Ų¬Ų±Ų© الملاحظات الخاصة بك لعرض Ł…Ų¬Ł…ŁˆŲ¹Ų© Ł…Ų­ŲÆŲÆŲ© من الملاحظات فقط." + }, + "productivity_benefits": { + "sync_title": "ā€ŽŲ§Ł„Ł…Ų²Ų§Ł…Ł†Ų©", + "revisions_title": "Ł…Ų±Ų§Ų¬Ų¹Ų§ŲŖ الملاحظة", + "protected_notes_title": "الملاحظات Ų§Ł„Ł…Ų­Ł…ŁŠŲ©", + "search_title": "البحث Ų§Ł„Ł‚ŁˆŁŠ", + "web_clipper_title": "Ų§ŲÆŲ§Ų© قص Ų§Ł„ŁˆŁŠŲØ", + "title": "Ų§Ł„Ų§Ł†ŲŖŲ§Ų¬ŁŠŲ© ŁˆŲ§Ł„Ų³Ł„Ų§Ł…Ų©", + "jump_to_title": "Ų§Ł„Ų§ŁˆŲ§Ł…Ų± ŁˆŲ§Ł„ŲØŲ­Ų« Ų§Ł„Ų³Ų±ŁŠŲ¹", + "revisions_content": "ŲŖŁŲ­ŁŲø الملاحظات ŲÆŁˆŲ±ŁŠŁ‹Ų§ في Ų§Ł„Ų®Ł„ŁŁŠŲ©ŲŒ ŁˆŁŠŁ…ŁƒŁ† Ų§Ų³ŲŖŲ®ŲÆŲ§Ł… Ų§Ł„ŲŖŲ¹ŲÆŁŠŁ„Ų§ŲŖ للمراجعة أو للتراجع عن Ų§Ł„ŲŖŲŗŁŠŁŠŲ±Ų§ŲŖ غير Ų§Ł„Ł…Ł‚ŲµŁˆŲÆŲ©. ŁƒŁ…Ų§ ŁŠŁ…ŁƒŁ† ؄نؓاؔ Ų§Ł„ŲŖŲ¹ŲÆŁŠŁ„Ų§ŲŖ عند الطلب.", + "sync_content": "Ų§Ų³ŲŖŲ®ŲÆŁ… نسخة مستضافة Ų°Ų§ŲŖŁŠŁ‹Ų§ أو نسخة سحابية لمزامنة Ł…Ł„Ų§Ų­ŲøŲ§ŲŖŁƒ ŲØŲ³Ł‡ŁˆŁ„Ų© Ų¹ŲØŲ± أجهزة Ł…ŲŖŲ¹ŲÆŲÆŲ©ŲŒ ŁˆŁ„Ł„ŁˆŲµŁˆŁ„ Ų„Ł„ŁŠŁ‡Ų§ من Ł‡Ų§ŲŖŁŁƒ Ų§Ł„Ł…Ų­Ł…ŁˆŁ„ ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… ŲŖŲ·ŲØŁŠŁ‚ ويب ŲŖŁ‚ŲÆŁ…ŁŠ (PWA).", + "protected_notes_content": "احمِ Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖŁƒ Ų§Ł„Ų“Ų®ŲµŁŠŲ© الحساسة Ų¹ŲØŲ± تؓفير الملاحظات ŁˆŁ‚ŁŁ„Ł‡Ų§ خلف جلسة Ł…Ų­Ł…ŁŠŲ© ŲØŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ±.", + "jump_to_content": "انتقل ŲØŲ³Ų±Ų¹Ų© ؄لى الملاحظات أو Ų£ŁˆŲ§Ł…Ų± ŁˆŲ§Ų¬Ł‡Ų© المستخدم Ų¹ŲØŲ± التسلسل Ų§Ł„Ł‡Ų±Ł…ŁŠ من خلال البحث عن Ų¹Ł†Ų§ŁˆŁŠŁ†Ł‡Ų§ŲŒ Ł…Ų¹ Ł…ŁŠŲ²Ų© المطابقة Ų§Ł„ŲŖŁ‚Ų±ŁŠŲØŁŠŲ© Ł„ŲŖŲ¬Ų§ŁˆŲ² الأخطاؔ Ų§Ł„Ų„Ł…Ł„Ų§Ų¦ŁŠŲ© أو الاختلافات Ų§Ł„ŲØŲ³ŁŠŲ·Ų©.", + "search_content": "أو Ų§ŲØŲ­Ų« عن نص داخل الملاحظات ŁˆŲ¶ŁŠŁ‘Ł‚ نطاق البحث Ų¹ŲØŲ± Ų§Ł„ŲŖŲµŁŁŠŲ© Ų­Ų³ŲØ الملاحظة Ų§Ł„Ų±Ų¦ŁŠŲ³ŁŠŲ©ŲŒ أو Ų­Ų³ŲØ Ł…Ų³ŲŖŁˆŁ‰ التفرع.", + "web_clipper_content": "اقتبس صفحات Ų§Ł„ŁˆŁŠŲØ (أو لقطات الؓاؓة) ŁˆŲ¶Ų¹Ł‡Ų§ Ł…ŲØŲ§Ų“Ų±Ų© في Trilium ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… ؄ضافة المتصفح مقص Ų§Ł„Ų“ŲØŁƒŲ© (Web Clipper)." + }, + "note_types": { + "canvas_title": "Ł…Ų³Ų§Ų­Ų© العمل", + "mindmap_title": "خريطة Ų°Ł‡Ł†ŁŠŲ©", + "text_title": "ملاحظات النص", + "code_title": "ملاحظات Ų§Ł„ŁƒŁˆŲÆ", + "file_title": "ملاحظات الملف", + "mermaid_title": "Ł…Ų®Ų·Ų·Ų§ŲŖ Mermaid", + "title": "طرق Ł…ŲŖŲ¹ŲÆŲÆŲ© لعرض Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖŁƒ", + "text_description": "ŁŠŲŖŁ… تحرير الملاحظات ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… Ł…Ų­Ų±Ų± Ł…Ų±Ų¦ŁŠ (WYSIWYG)، Ł…Ų¹ دعم Ł„Ł„Ų¬ŲÆŲ§ŁˆŁ„ŲŒ ŁˆŲ§Ł„ŲµŁˆŲ±ŲŒ ŁˆŲ§Ł„Ų¹ŲØŲ§Ų±Ų§ŲŖ Ų§Ł„Ų±ŁŠŲ§Ų¶ŁŠŲ©ŲŒ ŁˆŁƒŲŖŁ„ Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ…Ų§ŲŖ Ų§Ł„ŲØŲ±Ł…Ų¬ŁŠŲ© Ł…Ų¹ ŲŖŁ…ŁŠŁŠŲ² بناؔ الجملة. ŁŠŁ…ŁƒŁ†Łƒ ŲŖŁ†Ų³ŁŠŁ‚ النص ŲØŲ³Ų±Ų¹Ų© ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… Ł‚ŁˆŲ§Ų¹ŲÆ \"Markdown\" أو Ų¹ŲØŲ± Ų£ŁˆŲ§Ł…Ų± الؓرطة المائلة (slash commands).", + "code_description": "ŲŖŲ³ŲŖŲ®ŲÆŁ… Ų§Ł„Ų¹ŁŠŁ†Ų§ŲŖ Ų§Ł„ŁƒŲØŁŠŲ±Ų© من Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ…Ų§ŲŖ Ų§Ł„ŲØŲ±Ł…Ų¬ŁŠŲ© أو Ų§Ł„Ł†ŲµŁˆŲµ Ų§Ł„ŲØŲ±Ł…Ų¬ŁŠŲ© (Scripts) محررًا Ł…Ų®ŲµŲµŁ‹Ų§ŲŒ Ł…Ų¹ ŲŖŁ…ŁŠŁŠŲ² Ų§Ł„ŲµŁŠŲŗŲ© Ł„Ł„Ų¹ŲÆŁŠŲÆ من لغات البرمجة ŁˆŲØŲ³Ł…Ų§ŲŖ Ų£Ł„ŁˆŲ§Ł† Ł…ŲŖŁ†ŁˆŲ¹Ų©.", + "file_description": "ŲŖŲ¶Ł…ŁŠŁ† ملفات Ų§Ł„ŁˆŲ³Ų§Ų¦Ų· المتعددة Ł…Ų«Ł„ ملفات PDF ŁˆŲ§Ł„ŲµŁˆŲ± ŁˆŁ…Ł‚Ų§Ų·Ų¹ Ų§Ł„ŁŁŠŲÆŁŠŁˆ Ł…Ų¹ Ł…ŁŠŲ²Ų© Ų§Ł„Ł…Ų¹Ų§ŁŠŁ†Ų© داخل Ų§Ł„ŲŖŲ·ŲØŁŠŁ‚." + }, + "extensibility_benefits": { + "import_export_title": "استيراد/تصدير", + "title": "Ų§Ł„Ł…Ų“Ų§Ų±ŁƒŲ© ŁˆŁ‚Ų§ŲØŁ„ŁŠŲ© Ų§Ł„ŲŖŁˆŲ³ŁŠŲ¹", + "scripting_title": "البرمجة Ų§Ł„Ł†ŲµŁŠŲ© المتقدمة", + "api_title": "ŁˆŲ§Ų¬Ł‡Ų© برمجة REST" + }, + "collections": { + "calendar_title": "Ų§Ł„ŲŖŁ‚ŁˆŁŠŁ…", + "table_title": "Ų¬ŲÆŁˆŁ„", + "board_title": "Ł„ŁˆŲ­Ų©", + "geomap_title": "خريطة جغرافية" + }, + "footer": { + "copyright_community": "المجتمع", + "copyright_and_the": " و Ų§Ł„ " + }, + "social_buttons": { + "github": "GitHub", + "matrix": "ā€Ł…ŲµŁŁˆŁŲ©", + "reddit": "Reddit", + "github_discussions": "مناقؓات GitHub" + }, + "support_us": { + "paypal": "PayPal", + "title": "ادعمنا", + "financial_donations_title": "التبرعات Ų§Ł„Ł…Ų§Ł„ŁŠŲ©", + "github_sponsors": "الرعاة على GitHub", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "download_helper_desktop_windows": { + "download_scoop": "Scoop", + "download_exe": "ŲŖŲ­Ł…ŁŠŁ„ ملف Ų§Ł„ŲŖŲ«ŲØŁŠŲŖ (exe.)", + "title_x64": "ŁˆŁŠŁ†ŲÆŁˆŲ² 64 ŲØŲŖ", + "download_zip": "النسخة Ų§Ł„Ł…Ų­Ł…ŁˆŁ„Ų© بصيغة zip", + "title_arm64": "نظام ŁˆŁŠŁ†ŲÆŁˆŲ² عاى ARM", + "quick_start": "Ł„Ł„ŲŖŲ«ŲØŁŠŲŖ ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… Winget:" + }, + "download_helper_desktop_linux": { + "download_deb": ".deb", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR", + "download_rpm": "rpm.", + "download_flatpak": "flatpak.", + "title_x64": "Ł„ŁŠŁ†ŁŠŁƒŲ³ 64 ŲØŲŖ", + "download_zip": "النسخة Ų§Ł„Ł…Ų­Ł…ŁˆŁ„Ų© بصيغة zip", + "title_arm64": "نظام Ł„ŁŠŁ†ŁƒŲ³ على ARM" + }, + "download_helper_server_docker": { + "download_ghcr": "ghcr.io", + "download_dockerhub": "Ł…Ų³ŲŖŁˆŲÆŲ¹ Docker", + "title": "الاستضافة Ų§Ł„Ų°Ų§ŲŖŁŠŲ© ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… Ų§Ł„Docker" + }, + "final_cta": { + "get_started": "Ų§ŲØŲÆŲ£ الان" + }, + "components": { + "link_learn_more": "تعلم Ų§Ł„Ł…Ų²ŁŠŲÆ..." + }, + "download_now": { + "text": "ŲŖŁ†Ų²ŁŠŁ„ الان ", + "platform_small": "لاجل{{platform}}", + "linux_small": "Ł„Linux", + "linux_big": "Ų§ŲµŲÆŲ§Ų± v {{version}} لنظام Ł„ŁŠŁ†ŁƒŲ³" + }, + "faq": { + "title": "الاسئلة Ų§Ł„Ł…ŲŖŁƒŲ±Ų±Ų©" + }, + "404": { + "title": "404: غير Ł…ŁˆŲ¬ŁˆŲÆ" + }, + "download_helper_desktop_macos": { + "download_dmg": "ŲŖŲ­Ł…ŁŠŁ„ ملف Ų§Ł„ŲŖŲ«ŲØŁŠŲŖ (dmg.)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "النسخة Ų§Ł„Ł…Ų­Ł…ŁˆŁ„Ų© بصيغة zip", + "title_x64": "نظام macOS لاصدار intel", + "title_arm64": "نظام macOS لمعالجة اجهزة Apple Silicon", + "quick_start": "Ł„Ł„ŲŖŲ«ŲØŁŠŲŖ بواسطة Homebrew:" + }, + "contribute": { + "title": "طرق اخرى للمساهمة" + } +} diff --git a/apps/website/src/translations/bg/translation.json b/apps/website/src/translations/bg/translation.json new file mode 100644 index 0000000000..e61d418209 --- /dev/null +++ b/apps/website/src/translations/bg/translation.json @@ -0,0 +1,35 @@ +{ + "get-started": { + "title": "Започнете Ń‚ŃƒŠŗ", + "desktop_title": "Двалете Гесктоп Š°ŠæŠ»ŠøŠŗŠ°Ń†ŠøŃŃ‚а (v{{version}})", + "architecture": "ŠŃ€Ń…ŠøŃ‚ŠµŠŗŃ‚ŃƒŃ€Š°:", + "older_releases": "Вижте по-стари версии", + "server_title": "ŠšŠ¾Š½Ń„ŠøŠ³ŃƒŃ€ŠøŃ€Š°Š¹Ń‚Šµ ŃŃŠŃ€Š²ŃŠŃ€ за Š“Š¾ŃŃ‚ŃŠŠæ от различни ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š°" + }, + "hero_section": { + "title": "ŠžŃ€Š³Š°Š½ŠøŠ·ŠøŃ€Š°Š¹Ń‚Šµ Š’Š°ŃˆŠøŃ‚Šµ иГеи. Š”ŃŠŠ·Š“Š°Š¹Ń‚Šµ Š’Š°ŃˆŠ°Ń‚Š° лична база от Š·Š½Š°Š½ŠøŃ.", + "subtitle": "Trilium е Ń€ŠµŃˆŠµŠ½ŠøŠµ с отворен коГ за съзГаване на бележки Šø Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ на лична база от Š·Š½Š°Š½ŠøŃ. Š˜Š·ŠæŠ¾Š»Š²Š°Š¹Ń‚Šµ приложението на Š’Š°ŃˆŠøŃ Гесктоп, или го синхоранизирайте чрез ŃŃŠŃ€Š²Š°Ń€ хостнат от Вас за Га имате Š“Š¾Ń‚ŃŠŠæ Го бележките си Š½Š°Š²ŃŃŠŗŃŠŠ“е.", + "get_started": "Започнете Ń‚ŃƒŠŗ", + "github": "GitHub", + "screenshot_alt": "Š”ŠŗŃ€ŠøŠ½ŃˆŠ¾Ń‚ от Trilium Notes Гесктоп програмата" + }, + "organization_benefits": { + "title": "ŠžŃ€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ", + "note_structure_title": "Š”Ń‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š° на бележката", + "note_structure_description": "Бележките може Га Š±ŃŠŠ“ат поГреГени йерархично. ŠŃŠ¼Š° нужа от папки, понеже Š²ŃŃŠŗŠ° бележка може Га ŃŃŠŠ“ŃŠŃ€Š¶Š° поГ-бележка. ЕГна бележка може Га бъГе Гобавена на Š½ŃŠŗŠ¾Š»ŠŗŠ¾ места в Š¹ŠµŃ€Š°Ń€Ń…ŠøŃŃ‚Š°.", + "attributes_title": "Етикети Šø Š²Ń€ŃŠŠ·ŠŗŠø на бележката", + "attributes_description": "Š˜Š·ŠæŠ¾Š»Š·Š²Š°Š¹Ń‚Šµ Š²Ń€ŃŠŠ·ŠŗŠø межГу бележките или Гобавете етикети за по-лесна ŠŗŠµŃ‚ŠµŠ³Š¾Ń€ŠøŠ·Š°Ń†ŠøŃ. Š˜Š·ŠæŠ»Š¾Š·Š²Š°Š¹Ń‚Šµ избрани Š°Ń‚Ń€ŠøŠ±ŃƒŃ‚Šµ за Га Š²ŃŠŠ²ŠµŠ“ете ŃŃ‚ŃƒŠŗŃ‚ŃƒŃ€ŠøŃ€Š°Š½Š° ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ, ŠŗŠ¾ŃŃ‚Š¾ може Га бъГе използвана в таблици, табла.", + "hoisting_title": "Работни плотове", + "hoisting_description": "Лесно Ń€Š°Š·Š“ŠµŠ»ŃŠ¹Ń‚Šµ лични от работни бележки като ги Š³Ń€ŃƒŠæŠøŃ€Š°Ń‚е в работен плот, който ще накара Š“ŃŠŃ€Š²Š¾Ń‚Š¾ от бележки Га показва само специфичен сет от бележки." + }, + "productivity_benefits": { + "title": "ŠŸŃ€Š¾Š“ŃƒŠŗŃ‚ŠøŠ²Š½Š¾ŃŃ‚ Šø безопасност", + "revisions_title": "Ревизии на бележката", + "revisions_content": "Бележките периоГично се запазват Šø ревизиите може Га се ползват за Ń€ŠµŠ²ŃŽ или за Га се отмени нежелана ŠæŃ€Š¾Š¼ŃŠ½Š°. Ревизиите ŃŃŠŃ‰Š¾ могат Га Š±ŃŠŠ“ат съзГавани Ń€ŃŠŃ‡Š½Š¾.", + "sync_title": "Š”ŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·Š°Ń†ŠøŃ", + "sync_content": "Š˜Š·ŠæŠ¾Š»Š·Š²Š°Š¹Ń‚Šµ лично хостната или качена в клауГа ŠøŠ½ŃŃ‚Š°Š½Ń†ŠøŃ за Га синхронизирате Š’Š°ŃˆŠøŃ‚Šµ бележки на Š½ŃŠŗŠ¾Š»ŠŗŠ¾ ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š°, Šø за Га ги Š“Š¾ŃŃ‚ŃŠŠæŠøŃ‚Šµ от мобилно ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾ използвайки ПУА(ŠŸŃ€Š¾Š³Ń€ŠµŃŠøŠ²ŠµŠ½ Уеб Апп).", + "protected_notes_title": "Защитени бележки", + "protected_notes_content": "Защитете Ń‡ŃƒŃŃ‚Š²ŠøŃ‚ŠµŠ»Š½Š° лична ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ като криптирате ŃŃŠŠ¾Š±Ń‰ŠµŠ½ŠøŃŃ‚Š° Šø ги Š·Š°ŠŗŠ»ŃŽŃ‡ŠøŃ‚е с парола.", + "jump_to_title": "Š‘ŃŠŃ€Š·Š¾ Ń‚ŃŠŃ€ŃŠµŠ½Šµ Šø команГи" + } +} diff --git a/apps/website/src/translations/ca/translation.json b/apps/website/src/translations/ca/translation.json new file mode 100644 index 0000000000..af24b1b86e --- /dev/null +++ b/apps/website/src/translations/ca/translation.json @@ -0,0 +1,8 @@ +{ + "get-started": { + "title": "ComenƧa", + "desktop_title": "Descarrega l'aplicació d'escriptori (v{{version}})", + "architecture": "Arquitectura:", + "older_releases": "Veure versions anteriors" + } +} diff --git a/apps/website/src/translations/cs/translation.json b/apps/website/src/translations/cs/translation.json new file mode 100644 index 0000000000..86b34534d2 --- /dev/null +++ b/apps/website/src/translations/cs/translation.json @@ -0,0 +1,139 @@ +{ + "get-started": { + "title": "ZačƭnĆ”me", + "desktop_title": "StaženĆ­ aplikace pro osobnĆ­ počƭtače (v{{version}})", + "architecture": "Architektura:", + "older_releases": "StarŔí vydĆ”nĆ­", + "server_title": "Nastavte server pro přístup z vĆ­ce zařízenĆ­" + }, + "hero_section": { + "get_started": "Start", + "github": "GitHub", + "title": "UspořÔdejte si myÅ”lenky. Vytvořte si osobnĆ­ znalostnĆ­ bĆ”zi.", + "subtitle": "Trilium je open-source řeÅ”enĆ­ pro pořizovĆ”nĆ­ poznĆ”mek a organizaci osobnĆ­ znalostnĆ­ bĆ”ze. Používejte jej lokĆ”lně na svĆ©m počƭtači nebo jej synchronizujte se svým vlastnĆ­m serverem, abyste měli svĆ© poznĆ”mky vždy po ruce, aÅ„ jste kdekoli.", + "dockerhub": "Docker Hub", + "screenshot_alt": "SnĆ­mek obrazovky desktopovĆ© aplikace Trilium Notes" + }, + "organization_benefits": { + "title": "Organizace", + "note_structure_title": "Struktura poznĆ”mek", + "note_structure_description": "PoznĆ”mky lze uspořÔdat hierarchicky. NenĆ­ třeba používat složky, protože každĆ” poznĆ”mka může obsahovat podpoznĆ”mky. Jednu poznĆ”mku lze přidat na vĆ­ce mĆ­st v hierarchii.", + "attributes_title": "PoznĆ”mky k Å”tĆ­tkÅÆm a vazbĆ”m", + "attributes_description": "Využijte vazby mezi poznĆ”mkami nebo přidejte Å”tĆ­tky pro snadnou kategorizaci. PomocĆ­ propagovaných atributÅÆ zadejte strukturovanĆ© informace, kterĆ© lze použít v rÅÆzných tabulkĆ”ch.", + "hoisting_title": "PracovnĆ­ prostředĆ­ a hoisting", + "hoisting_description": "Snadno oddělte svĆ© osobnĆ­ a pracovnĆ­ poznĆ”mky tĆ­m, že je seskupĆ­te do pracovnĆ­ho prostoru, který zaměří strom poznĆ”mek tak, aby zobrazoval pouze konkrĆ©tnĆ­ sadu poznĆ”mek." + }, + "productivity_benefits": { + "title": "Produktivita a bezpečnost", + "revisions_title": "Revize poznĆ”mek", + "revisions_content": "PoznĆ”mky se pravidelně uklĆ”dajĆ­ na pozadĆ­ a revize lze použít k přezkoumĆ”nĆ­ nebo ke zruÅ”enĆ­ nĆ”hodných změn. Revize lze takĆ© vytvÔřet na požÔdĆ”nĆ­.", + "search_content": "Nebo vyhledĆ”vejte text uvnitř poznĆ”mek a zúžte vyhledĆ”vĆ”nĆ­ filtrovĆ”nĆ­m podle nadřazenĆ© poznĆ”mky nebo podle hloubky.", + "web_clipper_title": "Webový výstřižek", + "web_clipper_content": "ZachyÅ„te webovĆ© strĆ”nky (nebo snĆ­mky obrazovky) a vložte je přímo do Trilium pomocĆ­ rozŔířenĆ­ prohlížeče WebovĆ©ho výstřižku.", + "sync_title": "Synchoronizace", + "sync_content": "PomocĆ­ vlastnĆ­ nebo cloudovĆ© instance můžete snadno synchronizovat svĆ© poznĆ”mky mezi vĆ­ce zařízenĆ­mi a přistupovat k nim ze svĆ©ho mobilnĆ­ho telefonu pomocĆ­ PWA.", + "protected_notes_title": "ChrĆ”něnĆ© poznĆ”mky", + "protected_notes_content": "Chraňte citlivĆ© osobnĆ­ Ćŗdaje Å”ifrovĆ”nĆ­m poznĆ”mek a jejich uzamčenĆ­m za heslem chrĆ”něnou relacĆ­.", + "jump_to_title": "RychlĆ© hledĆ”nĆ­ a příkazy", + "jump_to_content": "Rychle přejděte k poznĆ”mkĆ”m nebo příkazÅÆm uživatelskĆ©ho rozhranĆ­ v celĆ© hierarchii pomocĆ­ vyhledĆ”vĆ”nĆ­ podle nĆ”zvu, přičemž fuzzy vyhledĆ”vĆ”nĆ­ zohledňuje překlepy nebo drobnĆ© rozdĆ­ly.", + "search_title": "VýkonnĆ© vyhledĆ”vĆ”nĆ­" + }, + "note_types": { + "title": "Několik zpÅÆsobÅÆ, jak prezentovat vaÅ”e informace", + "text_title": "TextovĆ” poznĆ”mka", + "text_description": "PoznĆ”mky se upravujĆ­ pomocĆ­ vizuĆ”lnĆ­ho editoru (WYSIWYG) s podporou tabulek, obrĆ”zkÅÆ, matematických výrazÅÆ a blokÅÆ kódu se zvýrazněnĆ­m syntaxe. Text lze rychle formĆ”tovat pomocĆ­ syntaxe podobnĆ© Markdownu nebo pomocĆ­ příkazÅÆ s lomĆ­tkem.", + "code_title": "PoznĆ”mka kódu", + "code_description": "VelkĆ© vzorky zdrojovĆ©ho kódu nebo skriptÅÆ používajĆ­ speciĆ”lnĆ­ editor s barevným zvýrazněnĆ­m syntaxe pro mnoho programovacĆ­ch jazykÅÆ a s rÅÆznými barevnými motivy.", + "file_title": "SouborovĆ© poznĆ”mky", + "file_description": "Vložte multimediĆ”lnĆ­ soubory, jako jsou PDF, obrĆ”zky, videa, s nĆ”hledem v aplikaci.", + "canvas_title": "PlĆ”tno", + "canvas_description": "UspořÔdejte tvary, obrĆ”zky a text na nekonečnĆ©m plĆ”tně pomocĆ­ stejnĆ© technologie, jakĆ” se používĆ” na webu excalidraw.com. IdeĆ”lnĆ­ pro diagramy, nĆ”Ärtky a vizuĆ”lnĆ­ plĆ”novĆ”nĆ­.", + "mermaid_title": "Mermaid diagramy", + "mermaid_description": "VytvÔřejte diagramy, jako jsou vývojovĆ© diagramy, diagramy tříd a sekvencĆ­, Ganttovy diagramy a mnoho dalŔích, pomocĆ­ syntaxe Mermaid.", + "mindmap_title": "MyÅ”lenkovĆ” mapa", + "mindmap_description": "Zorganizujte si myÅ”lenky vizuĆ”lně nebo uspořÔdejte brainstorming.", + "others_list": "a dalŔí: <0>mapa poznĆ”mek, <1>mapa vztahÅÆ, <2>uloženĆ” vyhledĆ”vĆ”nĆ­, <3>zobrazenĆ­ poznĆ”mky a <4>webovĆ© zobrazenĆ­." + }, + "extensibility_benefits": { + "title": "SdĆ­lenĆ­ a rozÅ”iřitelnost", + "import_export_title": "Import/export", + "import_export_description": "SnadnĆ” interakce s jinými aplikacemi pomocĆ­ formĆ”tÅÆ Markdown, ENEX a OML.", + "share_title": "SdĆ­let poznĆ”mky na webu", + "share_description": "Pokud mĆ”te server, můžete jej použít ke sdĆ­lenĆ­ ÄĆ”sti svých poznĆ”mek s ostatnĆ­mi lidmi.", + "scripting_title": "PokročilĆ© skriptovĆ”nĆ­", + "scripting_description": "Vytvořte si vlastnĆ­ integrace v rĆ”mci Trilium pomocĆ­ přizpÅÆsobených widgetÅÆ nebo logiky na straně serveru.", + "api_title": "REST API", + "api_description": "Komunikujte s Trilium programově pomocĆ­ jeho vestavěnĆ©ho REST API." + }, + "collections": { + "title": "Kolekce", + "calendar_title": "KalendÔř", + "calendar_description": "Organizujte svĆ© osobnĆ­ nebo pracovnĆ­ udĆ”losti pomocĆ­ kalendÔře, který podporuje celodennĆ­ i vĆ­cedennĆ­ udĆ”losti. Zobrazte si svĆ© udĆ”losti na prvnĆ­ pohled v týdennĆ­m, měsƭčnĆ­m a ročnĆ­m přehledu. SnadnĆ” interakce pro přidĆ”vĆ”nĆ­ nebo přetahovĆ”nĆ­ udĆ”lostĆ­.", + "table_title": "Tabulka", + "table_description": "Zobrazujte a upravujte informace o poznĆ”mkĆ”ch v tabulkovĆ© struktuře s rÅÆznými typy sloupcÅÆ, jako jsou text, čƭsla, zaÅ”krtĆ”vacĆ­ polƭčka, datum a čas, odkazy a barvy, a podporou vztahÅÆ. Volitelně můžete poznĆ”mky zobrazit v hierarchickĆ© struktuře stromu uvnitř tabulky.", + "board_title": "KanbanovĆ” tabule", + "board_description": "UspořÔdejte si Ćŗkoly nebo stav projektu do tabule Kanban, kde můžete snadno vytvÔřet novĆ© položky a sloupce a jednoduÅ”e měnit jejich stav přetahovĆ”nĆ­m po tabuli.", + "geomap_title": "Geomapa", + "geomap_description": "NaplĆ”nujte si dovolenou nebo si označte mĆ­sta, kterĆ” vĆ”s zajĆ­majĆ­, přímo na geografickĆ© mapě pomocĆ­ přizpÅÆsobitelných značek. Zobrazte zaznamenanĆ© trasy GPX a sledujte itinerÔře.", + "presentation_title": "Prezentace", + "presentation_description": "UspořÔdejte informace do snĆ­mkÅÆ a prezentujte je na celĆ© obrazovce s plynulými přechody. SnĆ­mky lze takĆ© exportovat do formĆ”tu PDF pro snadnĆ© sdĆ­lenĆ­." + }, + "faq": { + "title": "Často kladenĆ© otĆ”zky", + "mobile_question": "Existuje mobilnĆ­ aplikace?", + "mobile_answer": "V současnĆ© době neexistuje žÔdnĆ” oficiĆ”lnĆ­ mobilnĆ­ aplikace. Pokud vÅ”ak mĆ”te instanci serveru, můžete k nĆ­ přistupovat pomocĆ­ webovĆ©ho prohlížeče a dokonce ji nainstalovat jako PWA. Pro Android existuje neoficiĆ”lnĆ­ aplikace s nĆ”zvem TriliumDroid, kterĆ” funguje i offline (stejně jako desktopový klient).", + "database_question": "Kde jsou mĆ” data uložena?", + "database_answer": "VÅ”echny vaÅ”e poznĆ”mky budou uloženy v databĆ”zi SQLite ve složce aplikace. DÅÆvodem, proč Trilium používĆ” databĆ”zi namĆ­sto prostých textových souborÅÆ, je jak výkon, tak i skutečnost, že některĆ© funkce by byly mnohem obtížnějŔí implementovat, například klony (stejnĆ” poznĆ”mka na vĆ­ce mĆ­stech ve stromu). Chcete-li najĆ­t složku aplikace, stačƭ přejĆ­t do okna O aplikaci.", + "server_question": "Potřebuju server pro používĆ”nĆ­ Trilium?", + "server_answer": "Ne, server umožňuje přístup přes webový prohlížeč a spravuje synchronizaci, pokud mĆ”te vĆ­ce zařízenĆ­. Chcete-li začƭt, stačƭ si stĆ”hnout desktopovou aplikaci a začƭt ji používat.", + "scaling_question": "Jak dobře se aplikace přizpÅÆsobuje velkĆ©mu množstvĆ­ poznĆ”mek?", + "scaling_answer": "V zĆ”vislosti na použitĆ­ by aplikace měla být schopna bez problĆ©mÅÆ zpracovat alespoň 100 000 poznĆ”mek. Upozorňujeme, že proces synchronizace může někdy selhat, pokud nahrĆ”vĆ”te mnoho velkých souborÅÆ (1 GB na soubor), protože Trilium je spĆ­Å”e aplikacĆ­ pro sprĆ”vu znalostĆ­ než ĆŗložiÅ”těm souborÅÆ (jako například NextCloud).", + "network_share_question": "Mohu sdĆ­let svou databĆ”zi přes sĆ­Å„ový disk?", + "network_share_answer": "Ne, sdĆ­lenĆ­ databĆ”ze SQLite přes sĆ­Å„ový disk obecně nenĆ­ dobrý nĆ”pad. I když to někdy může fungovat, existuje riziko, že se databĆ”ze poÅ”kodĆ­ kvÅÆli nedokonalĆ©mu zamykĆ”nĆ­ souborÅÆ v sĆ­ti.", + "security_question": "Jak jsou mĆ” data chrĆ”něna?", + "security_answer": "Ve výchozĆ­m nastavenĆ­ nejsou poznĆ”mky Å”ifrovĆ”ny a lze je čƭst přímo z databĆ”ze. Jakmile je poznĆ”mka označena jako Å”ifrovanĆ”, je zaÅ”ifrovĆ”na pomocĆ­ AES-128-CBC." + }, + "final_cta": { + "title": "Jste připraveni začƭt používat Trilium Notes?", + "description": "Vytvořte si svou osobnĆ­ znalostnĆ­ bĆ”zi s výkonnými funkcemi a plným soukromĆ­m.", + "get_started": "Začƭt" + }, + "components": { + "link_learn_more": "Zjistit vĆ­ce..." + }, + "download_now": { + "text": "StĆ”hnout nynĆ­ ", + "platform_big": "v{{version}} pro{{platform}}", + "platform_small": "pro {{platform}}", + "linux_big": "v{{version}} pro Linux", + "linux_small": "pro Linux", + "more_platforms": "DalŔí platformy a nastavenĆ­ serveru" + }, + "header": { + "get-started": "Začƭt", + "documentation": "Dokumentace", + "support-us": "Podpořte nĆ”s" + }, + "footer": { + "copyright_and_the": " a ", + "copyright_community": "komunita" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "GitHub diskuze", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "support_us": { + "title": "Podpořte nĆ”s", + "financial_donations_title": "FinančnĆ­ dary", + "financial_donations_description": "Trilium je vyvĆ­jeno a udržovĆ”no dĆ­ky stovkĆ”m hodin prĆ”ce. VaÅ”e podpora zajiŔńuje, že zÅÆstane open-source, vylepÅ”uje jeho funkce a pokrývĆ” nĆ”klady, jako je hosting.", + "financial_donations_cta": "Zvažte podporu hlavnĆ­ho vývojÔře (eliandoran) aplikace prostřednictvĆ­m:", + "github_sponsors": "Sponzoři GitHubu", + "paypal": "PayPal", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "contribute": { + "title": "DalŔí zpÅÆsoby, jak přispět" + } +} diff --git a/apps/website/src/translations/de/translation.json b/apps/website/src/translations/de/translation.json new file mode 100644 index 0000000000..f61186fd38 --- /dev/null +++ b/apps/website/src/translations/de/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "title": "Loslegen", + "desktop_title": "Die Desktop-App herunterladen (v{{version}})", + "architecture": "Architektur:", + "older_releases": "Ƅltere Releases anzeigen", + "server_title": "Richte einen Server für den Zugriff auf mehreren GerƤten ein" + }, + "hero_section": { + "github": "GitHub", + "get_started": "Loslegen", + "dockerhub": "Docker Hub", + "title": "Organisieren Sie Ihre Gedanken. Bauen Sie Ihre persƶnliche Wissensdatenbank auf.", + "subtitle": "Trilium ist eine Open-Source-Lƶsung zum Erstellen von Notizen und Organisieren einer persƶnlichen Wissensdatenbank. Sie kann lokal auf dem Desktop verwendet oder mit einem selbst gehosteten Server synchronisieren werden, um erstellte Notizen überall verfügbar zu haben.", + "screenshot_alt": "Screenshot der Desktop-Anwendung Trilium Notes" + }, + "organization_benefits": { + "title": "Organisation", + "note_structure_title": "Notizstruktur", + "attributes_title": "Notiz Labels und Beziehungen", + "note_structure_description": "Notizen lassen sich hierarchisch anordnen. Ordner sind nicht nƶtig, da jede Notiz Unternotizen enthalten kann. Eine einzelne Notiz kann an mehreren Stellen in der Hierarchie hinzugefügt werden.", + "hoisting_description": "Trennen Sie Ihre persƶnlichen und beruflichen Notizen ganz einfach, indem Sie sie in einem Arbeitsbereich gruppieren. Dadurch wird Ihre Notizstruktur so fokussiert, dass nur ein bestimmter Satz von Notizen angezeigt wird.", + "hoisting_title": "Arbeitsbereiche und Fokusansicht", + "attributes_description": "Nutze Beziehungen zwischen Notizen oder füge Label hinzu um diese einfach zu kategorisieren. Verwende hervorgehobene Attribute um strukturierte Informationen zu hinterlegen die in Tabellen oder Boards verwendet werden." + }, + "productivity_benefits": { + "revisions_title": "Notizrevisionen", + "title": "ProduktivitƤt und Sicherheit", + "sync_title": "Synchronisation", + "protected_notes_title": "Geschützte Notizen", + "jump_to_title": "Schnellsuche und Kommandos", + "search_title": "Leistungsstarke Suche", + "web_clipper_title": "Webschnipsel", + "revisions_content": "Notizen werden regelmäßig im Hintergrund gespeichert und Revisionen kƶnnen zur Überprüfung oder zum RückgƤngigmachen versehentlicher Ƅnderungen verwendet werden. Revisionen kƶnnen auch bei Bedarf erstellt werden.", + "sync_content": "Verwenden Sie eine selbst gehostete oder Cloud-Instanz, um Ihre Notizen ganz einfach auf mehreren GerƤten zu synchronisieren und über eine WebApp von Ihrem mobilen GerƤt aus darauf zuzugreifen.", + "protected_notes_content": "Halten Sie vertrauliche Informationen sicher, indem Sie Notizen verschlüsseln und mit einem Passwort schützen.", + "jump_to_content": "Springen Sie schnell zu Notizen oder UI-Befehlen in der gesamten Hierarchie, indem Sie nach ihrem Titel suchen. Dank Fuzzy-Matching finden Sie auch Treffer bei Tippfehlern oder leicht abweichenden Schreibweisen.", + "search_content": "Oder durchsuchen Sie den Inhalt von Notizen und grenzen Sie die Suche ein, indem Sie nach übergeordneten Notizen oder der Hierarchieebene filtern.", + "web_clipper_content": "Webseiten oder Screenshots direkt in Trilium speichern – mit der Web Clipper Browser-Erweiterung." + }, + "note_types": { + "text_title": "Text Notizen", + "code_title": "Code Notizen", + "canvas_title": "Leinwand", + "mermaid_title": "Mermaid Diagramm", + "mindmap_title": "Mindmap", + "text_description": "Die Notizen werden mit einem visuellen Editor (WYSIWYG) bearbeitet, der Tabellen, Bilder, mathematische Ausdrücke und Code-Blƶcke mit Syntaxhervorhebung unterstützt. Formatieren Sie den Text schnell mit einer Markdown-Ƥhnlichen Syntax oder mit Slash-Befehlen.", + "code_description": "Große Quellcode- oder Skriptdateien werden mit einem speziellen Editor bearbeitet, der Syntaxhervorhebung für viele Programmiersprachen und diverse Farbschemata bietet.", + "title": "Verschiedene Darstellungsformen für Ihre Informationen", + "file_title": "Datei Notizen", + "file_description": "Betten Sie Multimedia-Dateien wie PDFs, Bilder und Videos mit einer Vorschau innerhalb der Anwendung ein.", + "canvas_description": "Ordnen Sie Formen, Bilder und Text auf einer unendlichen Leinwand an, indem Sie dieselbe Technologie verwenden, die auch hinter excalidraw.com steckt. Ideal für Diagramme, Skizzen und visuelle Planung.", + "mermaid_description": "Erstellen Sie Fluss-, Klassen-, Sequenz- sowie Gantt-Diagramme und vieles mehr mit der Mermaid-Syntax.", + "mindmap_description": "Strukturieren Sie Ihre Gedanken visuell oder nutzen Sie eine Brainstorming-Sitzung.", + "others_list": "und andere: <0>note map, <1>relation map, <2>saved searches, <3>render note, and <4>web views." + }, + "extensibility_benefits": { + "import_export_title": "Import/Export", + "scripting_title": "Erweitertes Scripting", + "api_title": "REST API", + "title": "Freigabe & Erweiterung", + "import_export_description": "Einfache Interaktion mit anderen Anwendungen mithilfe von Markdown, ENEX und OML Formaten.", + "share_title": "Notizen im Web teilen", + "share_description": "Wenn Sie über einen Server verfügen, kƶnnen Sie diesen nutzen, um einen Teil Ihrer Notizen mit anderen zu teilen.", + "scripting_description": "Erstellen Sie Ihre eigenen Integrationen innerhalb von Trilium mit benutzerdefinierten Widgets oder serverseitiger Logik.", + "api_description": "Nutzen Sie die integrierte REST-API, um flexibel und automatisiert mit Trilium zu interagieren." + }, + "collections": { + "calendar_title": "Kalender", + "title": "Sammlungen", + "calendar_description": "Organisieren Sie Ihre privaten oder beruflichen Termine mithilfe eines Kalenders, der ganztƤgige und mehrtƤgige Termine unterstützt. Verschaffen Sie sich mit der Wochen-, Monats- und Jahresansicht einen Überblick über Ihre Termine. Einfaches Hinzufügen oder Verschieben von Terminen.", + "table_title": "Tabelle", + "table_description": "Zeigen Sie Informationen zu Notizen in einer tabellarischen Ansicht an und bearbeiten Sie diese. Dabei stehen verschiedene Spaltentypen wie Text, Zahlen, KontrollkƤstchen, Datum sowie Uhrzeit, Links und Farben zur Verfügung, auch Beziehungen werden unterstützt. Optional kƶnnen Sie die Notizen innerhalb einer Baumhierarchie in der Tabelle anzeigen.", + "board_title": "Kanban-Board", + "board_description": "Organisieren Sie Aufgaben und Projektstatus in einem Kanban-Board und Ƥndern Sie den Status ganz einfach per Drag & Drop.", + "geomap_title": "Geokarte", + "geomap_description": "Planen Sie Ihren Urlaub oder markieren Sie Ihre Sehenswürdigkeiten direkt auf einer geografischen Karte mit individuellen Markierungen. Zeigen Sie aufgezeichnete GPX-Tracks an, um Reiserouten zu verfolgen.", + "presentation_title": "PrƤsentation", + "presentation_description": "Organisieren Sie Informationen in Folien und prƤsentieren Sie diese im Vollbildmodus mit flüssigen ÜbergƤngen. Die Folien kƶnnen als PDF gespeichert und einfach geteilt werden." + }, + "download_helper_desktop_macos": { + "quick_start": "Installieren mit Homebrew:", + "download_dmg": "Installer (.dmg) herunterladen", + "download_zip": "Portable (.zip)", + "download_homebrew_cask": "Die Homebrew Cask", + "description_arm64": "Für Apple Silicon Macs, beispielsweise mit M1-, M2-, M3- oder M4-Chips.", + "description_x64": "Für Intel-Macs ab macOS Monterey und neuer.", + "title_x64": "macOS für Intel", + "title_arm64": "macOS für Apple Silicon" + }, + "download_helper_server_docker": { + "title": "Self-hosted mit Docker", + "description": "Schnelle Installation auf Windows, Linux oder macOS mit einem Docker-Container.", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_desktop_linux": { + "download_aur": "AUR", + "download_nixpkgs": "nixpkgs", + "download_zip": "Portable (.zip)", + "download_flatpak": ".flatpak", + "download_rpm": ".rpm", + "title_x64": "Linux 64-bit", + "title_arm64": "Linux on ARM", + "description_x64": "Für die meisten Linux-Distributionen, kompatibel mit der x86_64-Architektur.", + "description_arm64": "Für ARM-basierte Linux-Distributionen, kompatibel mit der aarch64-Architektur.", + "quick_start": "WƤhlen Sie je nach Ihrer Distribution ein geeignetes Paketformat aus:", + "download_deb": ".deb" + }, + "download_helper_server_linux": { + "title": "Self-hosted auf Linux", + "description": "Trilium Notes auf Ihrem eigenen Server oder VPS bereitstellen – kompatibel mit den meisten Linux-Distributionen.", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "NixOS Module" + }, + "download_helper_server_hosted": { + "title": "Kostenpflichtiges Hosting", + "description": "Trilium Notes wird auf PikaPods gehostet, einem kostenpflichtigen Dienst für einfachen Zugriff und Verwaltung. Es besteht keine direkte Verbindung zum Trilium-Team.", + "download_pikapod": "Auf PikaPods installieren", + "download_triliumcc": "Alternativ siehe trilium.cc" + }, + "faq": { + "title": "HƤufig gestellte Fragen", + "mobile_question": "Gibt es eine mobile Applikation?", + "mobile_answer": "Derzeit gibt es keine offizielle mobile Anwendung. Wenn Sie jedoch über eine Serverinstanz verfügen, kƶnnen Sie über einen Webbrowser darauf zugreifen und sie sogar als PWA installieren. Für Android gibt es eine inoffizielle Anwendung namens TriliumDroid, die sogar offline funktioniert (genau wie ein Desktop-Client).", + "database_question": "Wo werden die Daten gespeichert?", + "database_answer": "Alle Ihre Notizen werden in einer SQLite-Datenbank in einem Anwendungsordner gespeichert. Der Grund, warum Trilium eine Datenbank anstelle von einfachen Textdateien verwendet, liegt sowohl in der Leistung als auch darin, dass einige Funktionen, wie z. B. Klone (gleiche Notiz an mehreren Stellen im Baum), viel schwieriger zu implementieren wƤren. Um den Anwendungsordner zu finden, gehen Sie einfach zum Fenster ā€žĆœberā€œ.", + "server_question": "Benƶtige ich einen Server um Trilium zu nutzen?", + "server_answer": "Nein, der Server ermƶglicht den Zugriff über einen Webbrowser und verwaltet die Synchronisierung, wenn Sie mehrere GerƤte haben. Um loszulegen, reicht es aus, die Desktop-Anwendung herunterzuladen und zu verwenden.", + "scaling_question": "Wie gut skaliert die Anwendung bei einer großen Anzahl von Notizen?", + "scaling_answer": "Je nach Nutzung sollte die Anwendung min. 100.000 Notizen problemlos verarbeiten kƶnnen. Beachten Sie, dass der Synchronisierungsvorgang manchmal fehlschlagen kann, wenn viele große Dateien (1 GB pro Datei) hochgeladen werden, da Trilium eher als Wissensdatenbank-Anwendung und nicht als Dateispeicher (wie beispielsweise NextCloud) konzipiert ist.", + "network_share_question": "Kann ich meine Datenbank über ein Netzlaufwerk freigeben?", + "network_share_answer": "Nein, es ist im Allgemeinen keine gute Idee, eine SQLite-Datenbank über ein Netzlaufwerk freizugeben. Auch wenn dies manchmal funktionieren mag, besteht die Gefahr, dass die Datenbank aufgrund unvollstƤndiger Dateisperren über ein Netzwerk beschƤdigt wird.", + "security_question": "Wie werden meine Daten geschützt?", + "security_answer": "Standardmäßig sind Notizen nicht verschlüsselt und kƶnnen direkt aus der Datenbank gelesen werden. Sobald eine Notiz als verschlüsselt markiert ist, wird diese mit AES-128-CBC verschlüsselt." + }, + "final_cta": { + "title": "Sind Sie bereit, um mit Trilium Notes zu starten?", + "description": "Baue dein persƶnliches Wissensarchiv mit leistungsstarken Funktionen und vollstƤndigem Datenschutz auf.", + "get_started": "Loslegen" + }, + "components": { + "link_learn_more": "Mehr erfahren..." + }, + "download_now": { + "text": "Herunterladen ", + "platform_big": "v{{version}} für {{platform}}", + "platform_small": "für {{platform}}", + "linux_big": "v{{version}} für Linux", + "linux_small": "für Linux", + "more_platforms": "Weitere Plattformen & Server-Einrichtung" + }, + "header": { + "get-started": "Loslegen", + "documentation": "Dokumentation", + "support-us": "Unterstützt uns", + "resources": "Ressourcen" + }, + "footer": { + "copyright_and_the": " und die ", + "copyright_community": "Community" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "GitHub Diskussionen", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "support_us": { + "title": "Unterstütze uns", + "financial_donations_title": "Geldspenden", + "financial_donations_description": "Trilium wurde mit Hunderten von Arbeitsstunden entwickelt und wird mit diesem Aufwand auch gewartet. Ihre Unterstützung sorgt dafür, dass es Open Source bleibt, verbessert die Funktionen und deckt Kosten wie das Hosting.", + "financial_donations_cta": "Bitte unterstützen Sie den Hauptentwickler (eliandoran) der Anwendung über:", + "github_sponsors": "GitHub Sponsoren", + "paypal": "PayPal", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "contribute": { + "title": "Weitere Mƶglichkeiten zum Mitwirken", + "way_translate": "Übersetzen Sie die Anwendung über Weblate in Ihre Muttersprache.", + "way_community": "Interagieren Sie mit der Community auf GitHub Discussions oder auf Matrix.", + "way_reports": "Fehlfunktionen über GitHub-Issues melden.", + "way_document": "Verbessern Sie die Dokumentation, indem Sie uns auf Lücken hinweisen oder durch eigene BeitrƤge wie Anleitungen, FAQs oder Tutorials unterstützen.", + "way_market": "Weitersagen: Teilen Sie Trilium Notes mit Freunden, in Blogs und sozialen Medien." + }, + "404": { + "title": "404: Nicht gefunden", + "description": "Die gesuchte Seite konnte nicht gefunden werden. Mƶglicherweise wurde sie gelƶscht oder die URL ist falsch." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64-bit", + "title_arm64": "Windows on ARM", + "description_x64": "Kompatibel mit Intel- oder AMD-GerƤten unter Windows 10 und 11.", + "description_arm64": "Kompatibel mit ARM-GerƤten (z. B. mit Qualcomm Snapdragon).", + "quick_start": "Installation über Winget:", + "download_exe": "Installationsdatei herunterladen (.exe)", + "download_zip": "Portable (.zip)", + "download_scoop": "Scoop" + }, + "resources": { + "icon_packs": "Symbolpakete", + "download": "Herunterladen", + "website": "Webseite", + "title": "Ressourcen", + "icon_packs_intro": "Erweitere die Auswahl an verfügbaren Symbolen für deine Notizen, indem du ein Symbolpaket verwendest. Für weitere Informationen zu Symbolpaketen, schaue in die offizielle Dokumentation." + } +} diff --git a/apps/website/src/translations/el/translation.json b/apps/website/src/translations/el/translation.json new file mode 100644 index 0000000000..92aeaae1ca --- /dev/null +++ b/apps/website/src/translations/el/translation.json @@ -0,0 +1,200 @@ +{ + "get-started": { + "title": "ĪžĪµĪŗĪ¹Ī½Ī®ĻƒĻ„Īµ", + "desktop_title": "ĪšĪ±Ļ„ĪµĪ²Ī¬ĻƒĻ„Īµ την εφαρμογή desktop (v{{version}})", + "architecture": "Αρχιτεκτονική:", + "older_releases": "Δείτε Ļ€Ī±Ī»Ī±Ī¹ĻŒĻ„ĪµĻĪµĻ‚ ĪµĪŗĪ“ĻŒĻƒĪµĪ¹Ļ‚", + "server_title": "Ī”Ļ…ĪøĪ¼ĪÆĻƒĻ„Īµ έναν server για Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ· σε πολλαπλές ĻƒĻ…ĻƒĪŗĪµĻ…Ī­Ļ‚" + }, + "hero_section": { + "title": "ĪŸĻĪ³Ī±Ī½ĻŽĻƒĻ„Īµ τις ĻƒĪŗĪ­ĻˆĪµĪ¹Ļ‚ ĻƒĪ±Ļ‚. Ī”Ī·Ī¼Ī¹ĪæĻ…ĻĪ³Ī®ĻƒĻ„Īµ την Ļ€ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĪ® ĻƒĪ±Ļ‚ βάση Ī³Ī½ĻŽĻƒĪµĻ‰Ī½.", + "subtitle": "Το Trilium είναι μια Ī»ĻĻƒĪ· Ī±Ī½ĪæĪ¹ĪŗĻ„ĪæĻ ĪŗĻŽĪ“Ī¹ĪŗĪ± για τη λήψη και την ĪæĻĪ³Ī¬Ī½Ļ‰ĻƒĪ· μιας Ļ€ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĪ®Ļ‚ Ī²Ī¬ĻƒĪ·Ļ‚ Ī³Ī½ĻŽĻƒĪµĻ‰Ī½. Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĻ„Īµ το σε Ļ„ĪæĻ€Ī¹ĪŗĻŒ επίπεΓο ĻƒĻ„Īæ desktop ĻƒĪ±Ļ‚, Ī® ĻƒĻ…Ī³Ļ‡ĻĪæĪ½ĪÆĻƒĻ„Īµ το με τον Γικό ĻƒĪ±Ļ‚ server ĻƒĪ±Ļ‚ για να ĪŗĻĪ±Ļ„Ī®ĻƒĪµĻ„Īµ τις ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ ĻƒĪ±Ļ‚ ĻŒĻ€ĪæĻ… πηγαίνετε.", + "get_started": "ĪžĪµĪŗĪ¹Ī½Ī®ĻƒĻ„Īµ", + "screenshot_alt": "Ī£Ļ„Ī¹Ī³Ī¼Ī¹ĻŒĻ„Ļ…Ļ€Īæ ĪæĪøĻŒĪ½Ī·Ļ‚ της desktop εφαρμογής Trilium Notes", + "github": "GitHub", + "dockerhub": "Docker Hub" + }, + "organization_benefits": { + "title": "ĪŸĻĪ³Ī±Ī½Ī¹ĻƒĪ¼ĻŒĻ‚", + "note_structure_title": "Δομή ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½", + "note_structure_description": "Οι ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ Ī¼Ļ€ĪæĻĪæĻĪ½ να Ļ„Ī±Ī¾Ī¹Ī½ĪæĪ¼Ī·ĪøĪæĻĪ½ ιεραρχικά. Δεν χρειάζονται φάκελοι, ĪŗĪ±ĪøĻŽĻ‚ κάθε ĻƒĪ·Ī¼ĪµĪÆĻ‰ĻƒĪ· μπορεί να περιέχει Ī“ĪµĻ…Ļ„ĪµĻĪµĻĪæĻ…ĻƒĪµĻ‚ ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚. Μια μεμονωμένη ĻƒĪ·Ī¼ĪµĪÆĻ‰ĻƒĪ· μπορεί να Ļ€ĻĪæĻƒĻ„ĪµĪøĪµĪÆ σε πολλά σημεία της ιεραρχίας.", + "attributes_title": "Ετικέτες ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½ και ĻƒĻ‡Ī­ĻƒĪµĪ¹Ļ‚", + "attributes_description": "Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĻ„Īµ ĻƒĻ‡Ī­ĻƒĪµĪ¹Ļ‚ Ī¼ĪµĻ„Ī±Ī¾Ļ ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½ Ī® Ļ€ĻĪæĻƒĪøĪ­ĻƒĻ„Īµ ετικέτες για ĪµĻĪŗĪæĪ»Ī· ĪŗĪ±Ļ„Ī·Ī³ĪæĻĪ¹ĪæĻ€ĪæĪÆĪ·ĻƒĪ·. Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĻ„Īµ προωθημένες Ī¹Ī“Ī¹ĻŒĻ„Ī·Ļ„ĪµĻ‚ για να ĪµĪ¹ĻƒĪ¬Ī³ĪµĻ„Īµ Γομημένες πληροφορίες που Ī¼Ļ€ĪæĻĪæĻĪ½ να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī·ĪøĪæĻĪ½ σε πίνακες, ĻƒĻ…Ī¼Ī²ĪæĻĪ»Ī¹Ī±.", + "hoisting_description": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪÆĻƒĻ„Īµ ĪµĻĪŗĪæĪ»Ī± τις Ļ€ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĪ­Ļ‚ και τις ĪµĻĪ³Ī±ĻƒĪ¹Ī±ĪŗĪ­Ļ‚ ĻƒĪ±Ļ‚ ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ ĪæĪ¼Ī±Ī“ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ τις σε έναν Ļ‡ĻŽĻĪæ ĪµĻĪ³Ī±ĻƒĪÆĪ±Ļ‚, Īæ οποίος ĪµĻƒĻ„Ī¹Ī¬Ī¶ĪµĪ¹ το Γέντρο ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻŽĪ½ ĻƒĪ±Ļ‚ ĻŽĻƒĻ„Īµ να εμφανίζει μόνο ένα ĻƒĻ…Ī³ĪŗĪµĪŗĻĪ¹Ī¼Ī­Ī½Īæ ĻƒĻĪ½ĪæĪ»Īæ ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½.", + "hoisting_title": "Ī§ĻŽĻĪæĪ¹ ĪµĻĪ³Ī±ĻƒĪÆĪ±Ļ‚ και Ī±Ī½ĻĻˆĻ‰ĻƒĪ·" + }, + "productivity_benefits": { + "title": "Ī Ī±ĻĪ±Ī³Ļ‰Ī³Ī¹ĪŗĻŒĻ„Ī·Ļ„Ī± και Ī±ĻƒĻ†Ī¬Ī»ĪµĪ¹Ī±", + "revisions_title": "AĪ½Ī±ĪøĪµĻ‰ĻĪ®ĻƒĪµĪ¹Ļ‚ ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½", + "revisions_content": "Οι ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ Ī±Ļ€ĪæĪøĪ·ĪŗĪµĻĪæĪ½Ļ„Ī±Ī¹ περιοΓικά ĻƒĻ„Īæ Ļ€Ī±ĻĪ±ĻƒĪŗĪ®Ī½Ī¹Īæ και οι Ī±Ī½Ī±ĪøĪµĻ‰ĻĪ®ĻƒĪµĪ¹Ļ‚ Ī¼Ļ€ĪæĻĪæĻĪ½ να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī·ĪøĪæĻĪ½ για έλεγχο Ī® για αναίρεση τυχαίων Ī±Ī»Ī»Ī±Ī³ĻŽĪ½. Οι Ī±Ī½Ī±ĪøĪµĻ‰ĻĪ®ĻƒĪµĪ¹Ļ‚ Ī¼Ļ€ĪæĻĪæĻĪ½ ĪµĻ€ĪÆĻƒĪ·Ļ‚ να Ī“Ī·Ī¼Ī¹ĪæĻ…ĻĪ³Ī·ĪøĪæĻĪ½ κατ' Ī±Ļ€Ī±ĪÆĻ„Ī·ĻƒĪ·.", + "sync_title": "Ī£Ļ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĻŒĻ‚", + "sync_content": "Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĻ„Īµ μια Γικής ĻƒĪ±Ļ‚ ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· Ī® μια ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· cloud για να ĻƒĻ…Ī³Ļ‡ĻĪæĪ½ĪÆĻƒĪµĻ„Īµ ĪµĻĪŗĪæĪ»Ī± τις ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ ĻƒĪ±Ļ‚ σε πολλές ĻƒĻ…ĻƒĪŗĪµĻ…Ī­Ļ‚ και να Ī±Ļ€ĪæĪŗĻ„Ī®ĻƒĪµĻ„Īµ Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ· σε αυτές Ī±Ļ€ĻŒ το ĪŗĪ¹Ī½Ī·Ļ„ĻŒ ĻƒĪ±Ļ‚ τηλέφωνο Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ ένα PWA.", + "protected_notes_title": "Ī ĻĪæĻƒĻ„Ī±Ļ„ĪµĻ…Ī¼Ī­Ī½ĪµĻ‚ ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚", + "protected_notes_content": "Ī ĻĪæĻƒĻ„Ī±Ļ„Ī­ĻˆĻ„Īµ ĪµĻ…Ī±ĪÆĻƒĪøĪ·Ļ„ĪµĻ‚ Ļ€ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĪ­Ļ‚ πληροφορίες ĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ±Ļ†ĻŽĪ½Ļ„Ī±Ļ‚ τις ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ και ĪŗĪ»ĪµĪ¹Ī“ĻŽĪ½ĪæĪ½Ļ„Ī¬Ļ‚ τις Ļ€ĪÆĻƒĻ‰ Ī±Ļ€ĻŒ μια περίοΓο λειτουργίας που Ļ€ĻĪæĻƒĻ„Ī±Ļ„ĪµĻĪµĻ„Ī±Ī¹ με ĪŗĻ‰Ī“Ī¹ĪŗĻŒ Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ·Ļ‚.", + "jump_to_title": "Γρήγορη Ī±Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· και εντολές", + "jump_to_content": "ĪœĪµĻ„Ī±Ī²ĪµĪÆĻ„Īµ γρήγορα σε ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ Ī® εντολές σε όλη την ιεραρχία Ī±Ī½Ī±Ī¶Ī·Ļ„ĻŽĪ½Ļ„Ī±Ļ‚ τον τίτλο τους, με Ī±ĻƒĪ±Ļ†Ī® Ī±Ī½Ļ„Ī¹ĻƒĻ„ĪæĪÆĻ‡Ī¹ĻƒĪ· για να Ī»Ī·Ļ†ĪøĪæĻĪ½ Ļ…Ļ€ĻŒĻˆĪ· τυπογραφικά λάθη Ī® μικρές Γιαφορές.", + "search_title": "Ī™ĻƒĻ‡Ļ…ĻĪ® Ī±Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ·", + "search_content": "Εναλλακτικά, Ī±Ī½Ī±Ī¶Ī·Ļ„Ī®ĻƒĻ„Īµ κείμενο μέσα σε ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ και Ļ€ĪµĻĪ¹ĪæĻĪÆĻƒĻ„Īµ την Ī±Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· φιλτράροντας με βάση την Ī±Ī½ĻŽĻ„ĪµĻĪ· ĻƒĪ·Ī¼ĪµĪÆĻ‰ĻƒĪ· Ī® κατά βάθος.", + "web_clipper_title": "Εργαλείο αποκομμάτων web", + "web_clipper_content": "Πάρτε Ī¹ĻƒĻ„ĪæĻƒĪµĪ»ĪÆĪ“ĪµĻ‚ (Ī® ĻƒĻ„Ī¹Ī³Ī¼Ī¹ĻŒĻ„Ļ…Ļ€Ī± ĪæĪøĻŒĪ½Ī·Ļ‚) και Ļ„ĪæĻ€ĪæĪøĪµĻ„Ī®ĻƒĻ„Īµ τις απευθείας ĻƒĻ„Īæ Trilium Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ το εργαλείο αποκομμάτων web του προγράμματος Ļ€ĪµĻĪ¹Ī®Ī³Ī·ĻƒĪ·Ļ‚." + }, + "note_types": { + "text_title": "Ī£Ī·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ κειμένου", + "text_description": "Οι ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ επεξεργάζονται Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ έναν ĪæĻ€Ļ„Ī¹ĪŗĻŒ ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĻ„Ī® (WYSIWYG), με Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· για πίνακες, ĪµĪ¹ĪŗĻŒĪ½ĪµĻ‚, μαθηματικές ĪµĪŗĻ†ĻĪ¬ĻƒĪµĪ¹Ļ‚, μπλοκ ĪŗĻŽĪ“Ī¹ĪŗĪ± με ĪµĻ€Ī¹ĻƒĪ®Ī¼Ī±Ī½ĻƒĪ· ĻƒĻĪ½Ļ„Ī±Ī¾Ī·Ļ‚. ĪœĪæĻĻ†ĪæĻ€ĪæĪ¹Ī®ĻƒĻ„Īµ γρήγορα το κείμενο Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ ĻƒĻĪ½Ļ„Ī±Ī¾Ī· Ļ€Ī±ĻĻŒĪ¼ĪæĪ¹Ī± με το Markdown Ī® Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ εντολές με κάθετο.", + "code_title": "Ī£Ī·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ ĪŗĻŽĪ“Ī¹ĪŗĪ±", + "code_description": "Μεγάλα Γείγματα πηγαίου ĪŗĻŽĪ“Ī¹ĪŗĪ± Ī® scripts Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪæĻĪ½ έναν ειΓικό ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĻ„Ī®, με ĪµĻ€Ī¹ĻƒĪ®Ī¼Ī±Ī½ĻƒĪ· ĻƒĻĪ½Ļ„Ī±Ī¾Ī·Ļ‚ για πολλές Ī³Ī»ĻŽĻƒĻƒĪµĻ‚ Ļ€ĻĪæĪ³ĻĪ±Ī¼Ī¼Ī±Ļ„Ī¹ĻƒĪ¼ĪæĻ και με Γιάφορα χρωματικά θέματα.", + "file_title": "Ī£Ī·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ αρχείων", + "file_description": "Ī•Ī½ĻƒĻ‰Ī¼Ī±Ļ„ĻŽĻƒĻ„Īµ αρχεία Ļ€ĪæĪ»Ļ…Ī¼Ī­ĻƒĻ‰Ī½ ĻŒĻ€Ļ‰Ļ‚ PDF, ĪµĪ¹ĪŗĻŒĪ½ĪµĻ‚, βίντεο με Ļ€ĻĪæĪµĻ€Ī¹ĻƒĪŗĻŒĻ€Ī·ĻƒĪ· ĪµĪ½Ļ„ĻŒĻ‚ εφαρμογής.", + "title": "Πολλαπλοί Ļ„ĻĻŒĻ€ĪæĪ¹ για να Ī±Ļ€ĪµĪ¹ĪŗĪæĪ½ĪÆĻƒĪµĻ„Īµ τις πληροφορίες ĻƒĪ±Ļ‚", + "canvas_title": "ĪšĪ±Ī¼Ī²Ī¬Ļ‚", + "canvas_description": "Ī¤Ī±ĪŗĻ„ĪæĻ€ĪæĪ¹Ī®ĻƒĻ„Īµ ĻƒĻ‡Ī®Ī¼Ī±Ļ„Ī±, ĪµĪ¹ĪŗĻŒĪ½ĪµĻ‚ και κείμενο σε έναν άπειρο καμβά, Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ την ίΓια τεχνολογία Ļ€ĪÆĻƒĻ‰ Ī±Ļ€ĻŒ το excalidraw.com. Ī™Ī“Ī±Ī½Ī¹ĪŗĻŒ για Γιαγράμματα, ĻƒĪŗĪÆĻ„ĻƒĪ± και ĪæĻ€Ļ„Ī¹ĪŗĻŒ ĻƒĻ‡ĪµĪ“Ī¹Ī±ĻƒĪ¼ĻŒ.", + "mermaid_description": "Ī”Ī·Ī¼Ī¹ĪæĻ…ĻĪ³Ī®ĻƒĻ„Īµ Γιαγράμματα, ĻŒĻ€Ļ‰Ļ‚ Γιαγράμματα ροής, ταξικά και τα Γιαγράμματα ακολουθίας, Γιαγράμματα Gantt και πολλά άλλα, Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ τη ĻƒĻĪ½Ļ„Ī±Ī¾Ī· Mermaid.", + "mermaid_title": "Διαγράμματα Mermaid", + "mindmap_title": "Χάρτης ĻƒĪŗĪ­ĻˆĪ·Ļ‚", + "mindmap_description": "ĪŸĻĪ³Ī±Ī½ĻŽĻƒĻ„Īµ τις ĻƒĪŗĪ­ĻˆĪµĪ¹Ļ‚ ĻƒĪ±Ļ‚ οπτικά Ī® κάνετε μια ĻƒĻ…Ī½ĪµĪ“ĻĪÆĪ± brainstorming.", + "others_list": "και άλλα: <0> χάρτης ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½, <1>> χάρτης ĻƒĻ‡Ī­ĻƒĪµĻ‰Ī½<1>, <2>αποθηκευμένες Ī±Ī½Ī±Ī¶Ī·Ļ„Ī®ĻƒĪµĪ¹Ļ‚, <3>render ĻƒĪ·Ī¼ĪµĪÆĻ‰ĻƒĪ· και <4>προβολές Ī¹ĻƒĻ„ĪæĻ." + }, + "extensibility_benefits": { + "title": "Κοινή Ļ‡ĻĪ®ĻƒĪ· και ĪµĻ€ĪµĪŗĻ„Ī±ĻƒĪ¹Ī¼ĻŒĻ„Ī·Ļ„Ī±", + "import_export_title": "Ī•Ī¹ĻƒĪ±Ī³Ļ‰Ī³Ī®/εξαγωγή", + "import_export_description": "Ī‘Ī»Ī»Ī·Ī»ĪµĻ€Ī¹Ī“ĻĪ¬ĻƒĻ„Īµ ĪµĻĪŗĪæĪ»Ī± με άλλες εφαρμογές Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ μορφές Markdown, ENEX, OML.", + "share_title": "Κοινή Ļ‡ĻĪ®ĻƒĪ· ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½ ĻƒĻ„Īæ ΓιαΓίκτυο", + "share_description": "Εάν Γιαθέτετε Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī®, μπορεί να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī·ĪøĪµĪÆ για να Ī¼ĪæĪ¹ĻĪ±ĻƒĻ„ĪµĪÆĻ„Īµ ένα Ļ…Ļ€ĪæĻƒĻĪ½ĪæĪ»Īæ των ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½ ĻƒĪ±Ļ‚ με άλλους Ī±Ī½ĪøĻĻŽĻ€ĪæĻ…Ļ‚.", + "scripting_title": "Advanced scripting", + "scripting_description": "Ī”Ī·Ī¼Ī¹ĪæĻ…ĻĪ³Ī®ĻƒĻ„Īµ τις Γικές ĻƒĪ±Ļ‚ ĪµĪ½ĻƒĻ‰Ī¼Ī±Ļ„ĻŽĻƒĪµĪ¹Ļ‚ ĻƒĻ„Īæ Trilium με Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĻƒĪ¼Ī­Ī½Ī± widgets, Ī® server-side λογική.", + "api_title": "REST API", + "api_description": "Ī‘Ī»Ī»Ī·Ī»ĪµĻ€Ī¹Ī“ĻĪ¬ĻƒĻ„Īµ με το Trilium Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ το ĪµĪ½ĻƒĻ‰Ī¼Ī±Ļ„Ļ‰Ī¼Ī­Ī½Īæ REST API." + }, + "collections": { + "title": "Συλλογή", + "calendar_title": "Ī—Ī¼ĪµĻĪæĪ»ĻŒĪ³Ī¹Īæ", + "calendar_description": "ĪŸĻĪ³Ī±Ī½ĻŽĻƒĻ„Īµ τα Ļ€ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĪ¬ Ī® επαγγελματικά ĻƒĪ±Ļ‚ Ī³ĪµĪ³ĪæĪ½ĻŒĻ„Ī± Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ ένα ημερολόγιο, με Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· για όλα τα καθημερινά και πολυήμερη Ī³ĪµĪ³ĪæĪ½ĻŒĻ„Ī±. Δείτε τα Ī³ĪµĪ³ĪæĪ½ĻŒĻ„Ī± ĻƒĪ±Ļ‚ με μια ματιά με τις Ī±Ļ€ĻŒĻˆĪµĪ¹Ļ‚ της εβΓομάΓας, του μήνα και του έτους. ĪµĻĪŗĪæĪ»Ī· Ī±Ī»Ī»Ī·Ī»ĪµĻ€ĪÆĪ“ĻĪ±ĻƒĪ· για να Ļ€ĻĪæĻƒĪøĪ­ĻƒĪµĻ„Īµ Ī® να τραβήξετε ĪµĪŗĪ“Ī·Ī»ĻŽĻƒĪµĪ¹Ļ‚.", + "table_title": "Πίνακας", + "table_description": "Ī•Ī¼Ļ†Ī±Ī½ĪÆĻƒĻ„Īµ και ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĻ„ĪµĪÆĻ„Īµ πληροφορίες ĻƒĻ‡ĪµĻ„Ī¹ĪŗĪ¬ με τις ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ σε μια tabular Γομή, με Γιάφορες ĻƒĻ„Ī®Ī»ĪµĻ‚, ĻŒĻ€Ļ‰Ļ‚ κεμένου, αριθμό, κουτιά ελέγχου, ημερομηνία και ĻŽĻĪ±, ĻƒĻ…Ī½Ī“Ī­ĻƒĪ¼ĪæĪ¹ και Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· για ĻƒĻ‡Ī­ĻƒĪµĪ¹Ļ‚. Εναλλακτικά, ĪµĪ¼Ļ†Ī±Ī½ĪÆĻƒĻ„Īµ τις ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ μέσα σε μια ιεραρχία Γέντρου μέσα ĻƒĻ„ĪæĪ½ πίνακα.", + "board_title": "Πίνακας Kanban", + "board_description": "ĪŸĻĪ³Ī±Ī½ĻŽĻƒĻ„Īµ τις ĪµĻĪ³Ī±ĻƒĪÆĪµĻ‚ Ī® την ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· του έργου ĻƒĪ±Ļ‚ σε έναν πίνακα Kanban με έναν ĪµĻĪŗĪæĪ»Īæ Ļ„ĻĻŒĻ€Īæ για να Ī“Ī·Ī¼Ī¹ĪæĻ…ĻĪ³Ī®ĻƒĪµĻ„Īµ νέα ĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĪ± και ĻƒĻ„Ī®Ī»ĪµĻ‚ και Ī±Ļ€Ī»ĻŽĻ‚ να αλλάξετε την ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ® τους ĻƒĻĻĪæĪ½Ļ„Ī±Ļ‚ ĻƒĻ„ĪæĪ½ πίνακα.", + "geomap_title": "Ī“ĪµĻ‰Ī³ĻĪ±Ļ†Ī¹ĪŗĻŒĻ‚ χάρτης", + "geomap_description": "Ī£Ļ‡ĪµĪ“Ī¹Ī¬ĻƒĻ„Īµ τις Γιακοπές ĻƒĪ±Ļ‚ Ī® ĪµĻ€Ī¹ĻƒĪ·Ī¼Ī¬Ī½ĪµĻ„Īµ τα σημεία ενΓιαφέροντος ĻƒĪ±Ļ‚ απευθείας σε έναν Ī³ĪµĻ‰Ī³ĻĪ±Ļ†Ī¹ĪŗĻŒ χάρτη Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ Ļ€ĻĪæĻƒĪ±ĻĪ¼ĻŒĻƒĪ¹Ī¼Ī± Γείκτες. Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· καταγεγραμμένων GPX ĪŗĪæĪ¼Ī¼Ī±Ļ„Ī¹ĻŽĪ½ για να Ļ€Ī±ĻĪ±ĪŗĪæĪ»ĪæĻ…ĪøĪ®ĻƒĪµĻ„Īµ τα Γρομολόγια.", + "presentation_title": "Ī Ī±ĻĪæĻ…ĻƒĪÆĪ±ĻƒĪ·", + "presentation_description": "ĪŸĻĪ³Ī±Ī½ĻŽĻƒĻ„Īµ τις πληροφορίες σε Γιαφάνειες και Ļ€Ī±ĻĪæĻ…ĻƒĪ¹Ī¬ĻƒĻ„Īµ τις σε πλήρη οθόνη με ομαλές Ī¼ĪµĻ„Ī±Ī²Ī¬ĻƒĪµĪ¹Ļ‚. Οι Γιαφάνειες Ī¼Ļ€ĪæĻĪæĻĪ½ ĪµĻ€ĪÆĻƒĪ·Ļ‚ να ĪµĪ¾Ī±Ļ‡ĪøĪæĻĪ½ σε PDF για ĪµĻĪŗĪæĪ»Ī· κοινή Ļ‡ĻĪ®ĻƒĪ·." + }, + "faq": { + "title": "Συχνές ĪµĻĻ‰Ļ„Ī®ĻƒĪµĪ¹Ļ‚", + "mobile_question": "΄πάρχει εφαρμογή για κινητά;", + "mobile_answer": "Επί του Ļ€Ī±ĻĻŒĪ½Ļ„ĪæĻ‚ Γεν υπάρχει ĪµĻ€ĪÆĻƒĪ·Ī¼Ī· εφαρμογή για κινητά. Ī©ĻƒĻ„ĻŒĻƒĪæ, αν έχετε μια Ļ€ĪµĻĪÆĻ€Ļ„Ļ‰ĻƒĪ· Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® μπορείτε να έχετε Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ· Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ ένα Ļ€ĻĻŒĪ³ĻĪ±Ī¼Ī¼Ī± Ļ€ĪµĻĪ¹Ī®Ī³Ī·ĻƒĪ·Ļ‚ και ακόμη και να το ĪµĪ³ĪŗĪ±Ļ„Ī±ĻƒĻ„Ī®ĻƒĪµĻ„Īµ ως PWA. Για το Android, υπάρχει μια Ī±Ī½ĪµĻ€ĪÆĻƒĪ·Ī¼Ī· εφαρμογή που ονομάζεται TriliumDroid που λειτουργεί ακόμη και ĪµĪŗĻ„ĻŒĻ‚ ĻƒĻĪ½Ī“ĪµĻƒĪ·Ļ‚ (ĻŒĻ€Ļ‰Ļ‚ και ένας Ļ…Ļ€ĪæĪ»ĪæĪ³Ī¹ĻƒĻ„Ī®Ļ‚-πελάτης).", + "database_question": "Ī ĪæĻ Ī±Ļ€ĪæĪøĪ·ĪŗĪµĻĪæĪ½Ļ„Ī±Ī¹ τα ΓεΓομένα;", + "database_answer": "ĪŒĪ»ĪµĻ‚ οι ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ ĻƒĪ±Ļ‚ θα Ī±Ļ€ĪæĪøĪ·ĪŗĪµĻĪæĪ½Ļ„Ī±Ī¹ σε μια βάση ΓεΓομένων SQLite σε έναν φάκελο της εφαρμογής. Ο Ī»ĻŒĪ³ĪæĻ‚ για τον οποίο το Trilium Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ μια βάση ΓεΓομένων αντί για απλά αρχεία κειμένου είναι λόγο ĪµĻ€Ī¹Ī“ĻŒĻƒĪµĻ‰Ī½ και ορισμένα Ļ‡Ī±ĻĪ±ĪŗĻ„Ī·ĻĪ¹ĻƒĻ„Ī¹ĪŗĪ¬ θα ήταν Ļ€ĪæĪ»Ļ πιο Ī“ĻĻƒĪŗĪæĪ»Īæ να ĪµĻ†Ī±ĻĪ¼ĪæĻƒĻ„ĪæĻĪ½ ĻŒĻ€Ļ‰Ļ‚ οι ĪŗĪ»ĻŽĪ½ĪæĪ¹ (Ī· ίΓια ĻƒĪ·Ī¼ĪµĪÆĻ‰ĻƒĪµ σε πολλαπλά μέρη του Γέντρου). Για να βρείτε το φάκελο της εφαρμογής, απλά πηγαίνετε ĻƒĻ„Īæ παράθυρο Σχετικά.", + "server_question": "Χρειάζομαι Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® για να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĻ‰ το Trilium;", + "server_answer": "ĪŒĻ‡Ī¹, Īæ server επιτρέπει την Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ· Ī¼Ī­ĻƒĻ‰ ĪµĪ½ĻŒĻ‚ προγράμματος Ļ€ĪµĻĪ¹Ī®Ī³Ī·ĻƒĪ·Ļ‚ και Γιαχειρίζεται τον ĻƒĻ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĻŒ εάν έχετε πολλαπλές ĻƒĻ…ĻƒĪŗĪµĻ…Ī­Ļ‚. Για να Ī¾ĪµĪŗĪ¹Ī½Ī®ĻƒĪµĻ„Īµ, είναι Ī±ĻĪŗĪµĻ„ĻŒ για να ĪŗĪ±Ļ„ĪµĪ²Ī¬ĻƒĪµĻ„Īµ την εφαρμογή desktop και να Ī±ĻĻ‡ĪÆĻƒĪµĻ„Īµ να τη Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Īµ.", + "scaling_question": "Πόσο καλά ĪŗĪ»Ī¹Ī¼Ī±ĪŗĻŽĪ½ĪµĻ„Ī±Ī¹ Ī· εφαρμογή με μεγάλο αριθμό ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½;", + "scaling_answer": "Ανάλογα με τη Ļ‡ĻĪ®ĻƒĪ·, Ī· εφαρμογή θα είναι σε θέση να Ļ‡ĪµĪ¹ĻĪ¹ĻƒĻ„ĪµĪÆ Ļ„ĪæĻ…Ī»Ī¬Ļ‡Ī¹ĻƒĻ„ĪæĪ½ 100.000 ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ χωρίς Ļ€ĻĻŒĪ²Ī»Ī·Ī¼Ī±. Ī£Ī·Ī¼ĪµĪ¹ĻŽĻƒĻ„Īµ ĻŒĻ„Ī¹ Ī· ΓιαΓικασία ĻƒĻ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĪæĻ μπορεί μερικές φορές να Ī±Ļ€ĪæĻ„ĻĻ‡ĪµĪ¹ αν ανεβάσει πολλά μεγάλα αρχεία (1 GB ανά αρχείο) ΓεΓομένου ĻŒĻ„Ī¹ το Trilium προορίζεται Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪæ ως εφαρμογή Ī²Ī¬ĻƒĪ·Ļ‚ Ī³Ī½ĻŽĻƒĪµĻ‰Ī½ και ĻŒĻ‡Ī¹ ως Ī±Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ· αρχείων (ĻŒĻ€Ļ‰Ļ‚ το NextCloud, για παράΓειγμα).", + "network_share_question": "ĪœĻ€ĪæĻĻŽ να Ī¼ĪæĪ¹ĻĪ±ĻƒĻ„ĻŽ τη βάση ΓεΓομένων μου σε ένα Γίσκο ĻƒĻ„Īæ Γίκτυο;", + "network_share_answer": "ĪŒĻ‡Ī¹, γενικά Γεν είναι καλή ιΓέα να Ī¼ĪæĪ¹ĻĪ¬Ī¶ĪµĻƒĻ„Īµ μια βάση ΓεΓομένων SQLite Ī¼Ī­ĻƒĻ‰ μιας μονάΓας Ī“ĪÆĻƒĪŗĪæĻ… Ī“Ī¹ĪŗĻ„ĻĪæĻ…. Αν και μερικές φορές μπορεί να Ī»ĪµĪ¹Ļ„ĪæĻ…ĻĪ³Ī®ĻƒĪµĪ¹, υπάρχουν Ļ€Ī¹ĪøĪ±Ī½ĻŒĻ„Ī·Ļ„ĪµĻ‚ Ī· βάση ΓεΓομένων να ĪŗĪ±Ļ„Ī±ĻƒĻ„ĻĪ±Ļ†ĪµĪÆ Ī»ĻŒĪ³Ļ‰ Ī±Ļ„ĪµĪ»ĻŽĪ½ κλειΓωμάτων αρχείων σε ένα Γίκτυο.", + "security_question": "Ī ĻŽĻ‚ Ļ€ĻĪæĻƒĻ„Ī±Ļ„ĪµĻĪæĪ½Ļ„Ī±Ī¹ τα ΓεΓομένα μου;", + "security_answer": "Ī‘Ļ€ĻŒ προεπιλογή, οι ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ Γεν ĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ±Ļ†ĪæĻĪ½Ļ„Ī±Ī¹ και Ī¼Ļ€ĪæĻĪæĻĪ½ να Ī“Ī¹Ī±Ī²Ī±ĻƒĻ„ĪæĻĪ½ απευθείας Ī±Ļ€ĻŒ τη βάση ΓεΓομένων. ĪœĻŒĪ»Ī¹Ļ‚ μία ĻƒĪ·Ī¼ĪµĪÆĻ‰ĻƒĪ· χαρακτηρίζεται ως κρυπτογραφημένη, κρυπτογραφείται Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ AES-128-CBC." + }, + "final_cta": { + "title": "Ī•ĪÆĻƒĻ„Īµ έτοιμοι να Ī¾ĪµĪŗĪ¹Ī½Ī®ĻƒĪµĻ„Īµ με το Trilium Notes;", + "description": "Ī”Ī·Ī¼Ī¹ĪæĻ…ĻĪ³Ī®ĻƒĻ„Īµ την Ļ€ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĪ® ĻƒĪ±Ļ‚ βάση Ī³Ī½ĻŽĻƒĪµĻ‰Ī½ με Ī¹ĻƒĻ‡Ļ…ĻĪ¬ Ļ‡Ī±ĻĪ±ĪŗĻ„Ī·ĻĪ¹ĻƒĻ„Ī¹ĪŗĪ¬ και πλήρη Ī¹Ī“Ī¹Ļ‰Ļ„Ī¹ĪŗĻŒĻ„Ī·Ļ„Ī±.", + "get_started": "ĪžĪµĪŗĪ¹Ī½Ī®ĻƒĻ„Īµ" + }, + "components": { + "link_learn_more": "ĪœĪ¬ĪøĪµĻ„Īµ Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪ±..." + }, + "download_now": { + "text": "ĪšĪ±Ļ„ĪµĪ²Ī¬ĻƒĻ„Īµ Ļ„ĻŽĻĪ± ", + "platform_big": "v {{version}} για {{platform}}", + "platform_small": "για {{platform}}", + "linux_big": "v{{version}} για Linux", + "linux_small": "για Linux", + "more_platforms": "Ī ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪµĻ‚ Ļ€Ī»Ī±Ļ„Ļ†ĻŒĻĪ¼ĪµĻ‚ & ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· σε Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī®" + }, + "header": { + "get-started": "ĪžĪµĪŗĪ¹Ī½Ī®ĻƒĻ„Īµ", + "support-us": "Ī„Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¾Ļ„Īµ μας", + "documentation": "Ī¤ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ·" + }, + "footer": { + "copyright_and_the": " και ", + "copyright_community": "ĪŗĪæĪ¹Ī½ĻŒĻ„Ī·Ļ„Ī±" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "GitHub Ī£Ļ…Ī¶Ī·Ļ„Ī®ĻƒĪµĪ¹Ļ‚", + "matrix": "Matrix", + "reddit": "Redditt" + }, + "support_us": { + "title": "Ī„Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¾Ļ„Īµ μας", + "financial_donations_title": "ĪŸĪ¹ĪŗĪæĪ½ĪæĪ¼Ī¹ĪŗĪ­Ļ‚ Γωρεές", + "financial_donations_description": "Το Trilium Γημιουργείται και Γιατηρείται με εκατοντάΓες ĻŽĻĪµĻ‚ ĪµĻĪ³Ī±ĻƒĪÆĪ±Ļ‚ . Ī— Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī® ĻƒĪ±Ļ‚ το κρατά Ī±Ī½ĪæĪ¹Ļ‡Ļ„ĪæĻ ĪŗĻŽĪ“Ī¹ĪŗĪ±, Ī²ĪµĪ»Ļ„Ī¹ĻŽĪ½ĪµĪ¹ τις Ī“Ļ…Ī½Ī±Ļ„ĻŒĻ„Ī·Ļ„Ī­Ļ‚ του και ĪŗĪ±Ī»ĻĻ€Ļ„ĪµĪ¹ ĪŗĻŒĻƒĻ„Ī· ĻŒĻ€Ļ‰Ļ‚ Ī· φιλοξενία.", + "financial_donations_cta": "Ī•Ī¾ĪµĻ„Ī¬ĻƒĻ„Īµ το ĪµĪ½Ī“ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ να Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¾ĪµĻ„Īµ τον ĪŗĻĻĪ¹Īæ Ļ€ĻĪæĪ³ĻĪ±Ī¼Ī¼Ī±Ļ„Ī¹ĻƒĻ„Ī® (eliandoran) της εφαρμογής Ī¼Ī­ĻƒĻ‰:", + "github_sponsors": "GitHub Sponsors", + "paypal": "PayPal", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "contribute": { + "title": "Άλλοι Ļ„ĻĻŒĻ€ĪæĪ¹ ĻƒĻ…Ī½ĪµĪ¹ĻƒĻ†ĪæĻĪ¬Ļ‚", + "way_translate": "ĪœĪµĻ„Ī±Ļ†ĻĪ¬ĻƒĻ„Īµ την εφαρμογή ĻƒĻ„Ī· μητρική ĻƒĪ±Ļ‚ Ī³Ī»ĻŽĻƒĻƒĪ± Ī¼Ī­ĻƒĻ‰ του Weblate .", + "way_community": "Ī‘Ī»Ī»Ī·Ī»ĪµĻ€Ī¹Ī“ĻĪ¬ĻƒĻ„Īµ με την ĪŗĪæĪ¹Ī½ĻŒĻ„Ī·Ļ„Ī± ĻƒĻ„Īæ GitHub Ī£Ļ…Ī¶Ī·Ļ„Ī®ĻƒĪµĪ¹Ļ‚ Ī® ĻƒĻ„Īæ Matrix .", + "way_reports": "Αναφέρετε ĻƒĻ†Ī¬Ī»Ī¼Ī±Ļ„Ī± Ī¼Ī­ĻƒĻ‰ GitHub issues .", + "way_document": "Ī’ĪµĪ»Ļ„Ī¹ĻŽĻƒĻ„Īµ την Ļ„ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ· ĪµĪ½Ī·Ī¼ĪµĻĻŽĪ½ĪæĪ½Ļ„Ī¬Ļ‚ μας για κενά ĻƒĻ„Ī·Ī½ Ļ„ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ· Ī® ĻƒĻ…Ī½ĪµĪ¹ĻƒĻ†Ī­ĻĪæĪ½Ļ„ĪµĻ‚ ĪæĪ“Ī·Ī³ĪæĻĻ‚, ĻƒĻ…Ļ‡Ī½Ī­Ļ‚ ĪµĻĻ‰Ļ„Ī®ĻƒĪµĪ¹Ļ‚ Ī® παραΓείγματα.", + "way_market": "Ī”Ī¹Ī±Ī“ĻŽĻƒĻ„Īµ το: ĪœĪæĪ¹ĻĪ±ĻƒĻ„ĪµĪÆĻ„Īµ το Trilium Notes με φίλους Ī® σε blogs και μέσα κοινωνικής Ī“Ī¹ĪŗĻ„ĻĻ‰ĻƒĪ·Ļ‚." + }, + "404": { + "title": "404: Δεν υπάρχει", + "description": "Ī— σελίΓα που αναζητάτε Γεν Ī¼Ļ€ĪæĻĪæĻĻƒĪµ να βρεθεί. ĪŠĻƒĻ‰Ļ‚ έχει Γιαγραφεί Ī® το URL είναι λάθος." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64-bit", + "title_arm64": "Windows on ARM", + "description_x64": "Ī£Ļ…Ī¼Ī²Ī±Ļ„ĻŒ με ĻƒĻ…ĻƒĪŗĪµĻ…Ī­Ļ‚ Intel Ī® AMD που τρέχουν Windows 10 και 11.", + "description_arm64": "Ī£Ļ…Ī¼Ī²Ī±Ļ„ĻŒ με ĻƒĻ…ĻƒĪŗĪµĻ…Ī­Ļ‚ ARM (Ļ€.χ. με Qualcomm Snapdragon).", + "quick_start": "Για ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· Ī¼Ī­ĻƒĻ‰ Winget:", + "download_exe": "Ī›Ī®ĻˆĪ· προγράμματος ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·Ļ‚ (.exe)", + "download_zip": "Portable (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64-bit", + "title_arm64": "Linux on ARM", + "description_x64": "Για τις Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪµĻ‚ Γιανομές Linux, ĻƒĻ…Ī¼Ī²Ī±Ļ„Ī­Ļ‚ με την αρχιτεκτονική x86_64.", + "description_arm64": "Για τις ARM-based Γιανομές Linux, ĻƒĻ…Ī¼Ī²Ī±Ļ„Ī­Ļ‚ με την αρχιτεκτονική aarch64.", + "quick_start": "Επιλέξτε μια κατάλληλη μορφή πακέτου, ανάλογα με τη Γιανομή ĻƒĪ±Ļ‚:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "Portable (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS για Intel", + "title_arm64": "macOS για Apple Silicon", + "description_x64": "Για Macs με ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĻ„Ī® Intel με macOS Monterey Ī® Ī½ĪµĻŒĻ„ĪµĻĪ· έκΓοση.", + "description_arm64": "Για Apple Silicon Macs ĻŒĻ€Ļ‰Ļ‚ αυτοί με Ļ„ĻƒĪ¹Ļ€ M1 και M2.", + "quick_start": "Για ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· Ī¼Ī­ĻƒĻ‰ Homebrew:", + "download_dmg": "Ī›Ī®ĻˆĪ· προγράμματος ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·Ļ‚ (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "Portable (.zip)" + }, + "download_helper_server_docker": { + "title": "Self-hosted Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ Docker", + "description": "Ī‘Ī½Ī±Ļ€Ļ„ĻĪ¾Ļ„Īµ ĪµĻĪŗĪæĪ»Ī± ĻƒĻ„Ī± Windows, Linux Ī® macOS Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ ένα Docker container.", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "Self-hosted σε Linux", + "description": "Ī‘Ī½Ī±Ļ€Ļ„ĻĪ¾Ļ„Īµ το Trilium Notes ĻƒĻ„ĪæĪ½ Γικό ĻƒĪ±Ļ‚ Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® Ī® VPS, ĻƒĻ…Ī¼Ī²Ī±Ļ„ĻŒ με τις Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪµĻ‚ Γιανομές.", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tarxz)", + "download_nixos": "NixOS module" + }, + "download_helper_server_hosted": { + "title": "Φιλοξενία επί πληρωμή", + "description": "Trilium Notes φιλοξενείται ĻƒĻ„Īæ PikaPods, μια πληρωμένη Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪ± για ĪµĻĪŗĪæĪ»Ī· Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ· και Ī“Ī¹Ī±Ļ‡ĪµĪÆĻĪ¹ĻƒĪ·. ĪŒĻ‡Ī¹ άμεσα ĻƒĻ…Ī½Ī“ĪµĪ“ĪµĪ¼Ī­Ī½Ī· με την ομάΓα Trilium.", + "download_pikapod": "Ī”ĻĪøĪ¼Ī¹ĻƒĪ· σε PikaPods", + "download_triliumcc": "Εναλλακτικά Γείτε trilium.cc" + } +} diff --git a/apps/website/src/translations/en-GB/translation.json b/apps/website/src/translations/en-GB/translation.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/apps/website/src/translations/en-GB/translation.json @@ -0,0 +1 @@ +{} diff --git a/apps/website/src/translations/en/translation.json b/apps/website/src/translations/en/translation.json new file mode 100644 index 0000000000..4012fa2df3 --- /dev/null +++ b/apps/website/src/translations/en/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "title": "Get started", + "desktop_title": "Download the desktop application (v{{version}})", + "architecture": "Architecture:", + "older_releases": "See older releases", + "server_title": "Set up a server for access on multiple devices" + }, + "hero_section": { + "title": "Organize your thoughts. Build your personal knowledge base.", + "subtitle": "Trilium is an open-source solution for note-taking and organizing a personal knowledge base. Use it locally on your desktop, or sync it with your self-hosted server to keep your notes everywhere you go.", + "get_started": "Get started", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Screenshot of the Trilium Notes desktop application" + }, + "organization_benefits": { + "title": "Organization", + "note_structure_title": "Note structure", + "note_structure_description": "Notes can be arranged hierarchically. There's no need for folders, since each note can contain sub-notes. A single note can be added in multiple places in the hierarchy.", + "attributes_title": "Note labels and relationships", + "attributes_description": "Use relations between notes or add labels for easy categorization. Use promoted attributes to enter structured information which can be used in tables, boards.", + "hoisting_title": "Workspaces and hoisting", + "hoisting_description": "Easily separate your personal and work notes by grouping them under a workspace, which focuses your note tree to only show a specific set of notes." + }, + "productivity_benefits": { + "title": "Productivity and safety", + "revisions_title": "Note revisions", + "revisions_content": "Notes are periodically saved in the background and revisions can be used for review or to undo accidental changes. Revisions can also be created on-demand.", + "sync_title": "Synchronization", + "sync_content": "Use a self-hosted or cloud instance to easily synchronize your notes across multiple devices, and to access it from your mobile phone using a PWA.", + "protected_notes_title": "Protected notes", + "protected_notes_content": "Protect sensitive personal information by encrypting the notes and locking them behind a password-protected session.", + "jump_to_title": "Quick search and commands", + "jump_to_content": "Jump quickly to notes or UI commands across the hierarchy by searching for their title, with fuzzy matching to account for typos or slight differences.", + "search_title": "Powerful search", + "search_content": "Or search for text inside notes and narrow down the search by filtering by the parent note, or by depth.", + "web_clipper_title": "Web clipper", + "web_clipper_content": "Grab web pages (or screenshots) and place them directly into Trilium using the web clipper browser extension." + }, + "note_types": { + "title": "Multiple ways to represent your information", + "text_title": "Text notes", + "text_description": "The notes are edited using a visual (WYSIWYG) editor, with support for tables, images, math expressions, code blocks with syntax highlighting. Quickly format the text using Markdown-like syntax or using slash commands.", + "code_title": "Code notes", + "code_description": "Large samples of source code or scripts use a dedicated editor, with syntax highlighting for many programming languages and with various color themes.", + "file_title": "File notes", + "file_description": "Embed multimedia files such as PDFs, images, videos with an in-application preview.", + "canvas_title": "Canvas", + "canvas_description": "Arrange shapes, images and text across an infinite canvas, using the same technology behind excalidraw.com. Ideal for diagrams, sketches and visual planning.", + "mermaid_title": "Mermaid diagrams", + "mermaid_description": "Create diagrams such as flowcharts, class & sequence diagrams, Gantt charts and many more, using the Mermaid syntax.", + "mindmap_title": "Mindmap", + "mindmap_description": "Organize your thoughts visually or do a brainstorming session.", + "others_list": "and others: <0>note map, <1>relation map, <2>saved searches, <3>render note, and <4>web views." + }, + "extensibility_benefits": { + "title": "Sharing & extensibility", + "import_export_title": "Import/export", + "import_export_description": "Easily interact with other applications using Markdown, ENEX, OML formats.", + "share_title": "Share notes on the web", + "share_description": "If you have a server, it can be used to share a subset of your notes with other people.", + "scripting_title": "Advanced scripting", + "scripting_description": "Build your own integrations within Trilium with custom widgets, or server-side logic.", + "api_title": "REST API", + "api_description": "Interact with Trilium programatically using its builtin REST API." + }, + "collections": { + "title": "Collections", + "calendar_title": "Calendar", + "calendar_description": "Organize your personal or professional events using a calendar, with support for all-day and multi-day events. See your events at a glance with the week, month and year views. Easy interaction to add or drag events.", + "table_title": "Table", + "table_description": "Display and edit information about notes in a tabular structure, with various column types such as text, number, check boxes, date & time, links and colors and support for relations. Optionally, display the notes within a tree hierarchy inside the table.", + "board_title": "Kanban Board", + "board_description": "Organize your tasks or project status into a Kanban board with an easy way to create new items and columns and simply changing their status by dragging across the board.", + "geomap_title": "Geomap", + "geomap_description": "Plan your vacations or mark your points of interest directly on a geographical map using customizable markers. Display recorded GPX tracks to track itineraries.", + "presentation_title": "Presentation", + "presentation_description": "Organize information into slides and present them in full-screen with smooth transitions. The slides can also be exported to PDF for easy sharing." + }, + "faq": { + "title": "Frequently Asked Questions", + "mobile_question": "Is there a mobile application?", + "mobile_answer": "Currently there is no official mobile application. However, if you have a server instance you can access it using a web browser and even install it as a PWA. For Android, there is an unofficial application called TriliumDroid that even works offline (same as a desktop client).", + "database_question": "Where is the data stored?", + "database_answer": "All your notes will be stored in an SQLite database in an application folder. The reasoning why Trilium uses a database instead of plain text files is both performance and some features would be much more difficult to implement such as clones (same note in multiple places in the tree). To find the application folder, simply go to the About window.", + "server_question": "Do I need a server to use Trilium?", + "server_answer": "No, the server allows access via a web browser and manages the synchronization if you have multiple devices. To get started, it's enough to download the desktop application and start using it.", + "scaling_question": "How well does the application scale with a large amount of notes?", + "scaling_answer": "Depending on usage, the application should be able to handle at least 100,000 notes without an issue. Do note that the sync process can sometimes fail if uploading many large files (1 GB per file) since Trilium is meant more as a knowledge base application rather than a file store (like NextCloud, for example).", + "network_share_question": "Can I share my database over a network drive?", + "network_share_answer": "No, it's generally not a good idea to share a SQLite database over a network drive. Although sometimes it might work, there are chances that the database will get corrupted due to imperfect file locks over a network.", + "security_question": "How is my data protected?", + "security_answer": "By default, notes are not encrypted and can be read directly from the database. Once a note is marked as encrypted, the note is encrypted using AES-128-CBC." + }, + "final_cta": { + "title": "Ready to get started with Trilium Notes?", + "description": "Build your personal knowledge base with powerful features and full privacy.", + "get_started": "Get started" + }, + "components": { + "link_learn_more": "Learn more..." + }, + "download_now": { + "text": "Download now ", + "platform_big": "v{{version}} for {{platform}}", + "platform_small": "for {{platform}}", + "linux_big": "v{{version}} for Linux", + "linux_small": "for Linux", + "more_platforms": "More platforms & server setup" + }, + "header": { + "get-started": "Get started", + "documentation": "Documentation", + "resources": "Resources", + "support-us": "Support us" + }, + "footer": { + "copyright_and_the": " and the ", + "copyright_community": "community" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "GitHub Discussions", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "support_us": { + "title": "Support us", + "financial_donations_title": "Financial donations", + "financial_donations_description": "Trilium is built and maintained with hundreds of hours of work. Your support keeps it open-source, improves features, and covers costs such as hosting.", + "financial_donations_cta": "Consider supporting the main developer (eliandoran) of the application via:", + "github_sponsors": "GitHub Sponsors", + "paypal": "PayPal", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "contribute": { + "title": "Other ways to contribute", + "way_translate": "Translate the application into your native language via Weblate.", + "way_community": "Interact with the community on GitHub Discussions or on Matrix.", + "way_reports": "Report bugs via GitHub issues.", + "way_document": "Improve the documentation by informing us on gaps in the documentation or contributing guides, FAQs or tutorials.", + "way_market": "Spread the word: Share Trilium Notes with friends, or on blogs and social media." + }, + "404": { + "title": "404: Not Found", + "description": "The page you were looking for could not be found. Maybe it was deleted or the URL is incorrect." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64-bit", + "title_arm64": "Windows on ARM", + "description_x64": "Compatible with Intel or AMD devices running Windows 10 and 11.", + "description_arm64": "Compatible with ARM devices (e.g. with Qualcomm Snapdragon).", + "quick_start": "To install via Winget:", + "download_exe": "Download Installer (.exe)", + "download_zip": "Portable (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64-bit", + "title_arm64": "Linux on ARM", + "description_x64": "For most Linux distributions, compatible with x86_64 architecture.", + "description_arm64": "For ARM-based Linux distributions, compatible with aarch64 architecture.", + "quick_start": "Select an appropriate package format, depending on your distribution:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "Portable (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS for Intel", + "title_arm64": "macOS for Apple Silicon", + "description_x64": "For Intel-based Macs running macOS Monterey or later.", + "description_arm64": "For Apple Silicon Macs such as those with M1 and M2 chips.", + "quick_start": "To install via Homebrew:", + "download_dmg": "Download Installer (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "Portable (.zip)" + }, + "download_helper_server_docker": { + "title": "Self-hosted using Docker", + "description": "Easily deploy on Windows, Linux or macOS using a Docker container.", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "Self-hosted on Linux", + "description": "Deploy Trilium Notes on your own server or VPS, compatible with most distributions.", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "NixOS module" + }, + "download_helper_server_hosted": { + "title": "Paid hosting", + "description": "Trilium Notes hosted on PikaPods, a paid service for easy access and management. Not directly affiliated with the Trilium team.", + "download_pikapod": "Set up on PikaPods", + "download_triliumcc": "Alternatively see trilium.cc" + }, + "resources": { + "title": "Resources", + "icon_packs": "Icon packs", + "icon_packs_intro": "Expand the selection of available icons for your notes by using an icon pack. For more information about icon packs, see the official documentation.", + "download": "Download", + "website": "Website" + } +} diff --git a/apps/website/src/translations/es/translation.json b/apps/website/src/translations/es/translation.json new file mode 100644 index 0000000000..88bfdcccd9 --- /dev/null +++ b/apps/website/src/translations/es/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "title": "Comenzar", + "desktop_title": "Descarga la aplicación de escritorio (v{{version}})", + "architecture": "Arquitectura:", + "older_releases": "Ver versiones anteriores", + "server_title": "Configura un servidor para acceder desde mĆŗltiples dispositivos" + }, + "hero_section": { + "title": "Organiza tus ideas. Construye tu propia base de conocimiento personal.", + "subtitle": "Trilium es una aplicación de código abierto para tomar notas y organizar tu base de conocimiento personal. Puedes usarla localmente en tu escritorio o sincronizarla con tu propio servidor para tener tus notas disponibles en cualquier lugar.", + "get_started": "Comenzar", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Captura de pantalla de la aplicación de escritorio Trilium Notes" + }, + "organization_benefits": { + "title": "Organización", + "note_structure_title": "Estructura de notas", + "note_structure_description": "Las notas se pueden organizar de forma jerĆ”rquica. No necesitas carpetas, ya que cada nota puede contener subnotas. Una misma nota puede aƱadirse en varios lugares de la jerarquĆ­a.", + "attributes_title": "Etiquetas de notas y relaciones", + "attributes_description": "Puedes establecer relaciones entre notas o aƱadir etiquetas para categorizarlas mĆ”s fĆ”cilmente. Los atributos promovidos te permiten ingresar información estructurada, que luego puedes usar en tablas o tableros.", + "hoisting_title": "Espacios de trabajo y organización jerĆ”rquica", + "hoisting_description": "Se pueden separar fĆ”cilmente tus notas personales y de trabajo agrupĆ”ndolas en un espacio de trabajo, lo que centra el Ć”rbol de notas en mostrar Ćŗnicamente un conjunto especĆ­fico de ellas." + }, + "productivity_benefits": { + "title": "Productividad y seguridad", + "revisions_title": "Revisiones de notas", + "revisions_content": "Las notas se guardan automĆ”ticamente en segundo plano y las revisiones te permiten revisarlas o deshacer cambios accidentales. TambiĆ©n se pueden crear revisiones manualmente cuando se necesite.", + "sync_title": "Sincronización", + "sync_content": "Usa una instancia propia o en la nube para sincronizar fĆ”cilmente tus notas entre varios dispositivos y acceder a ellas desde el móvil mediante una PWA.", + "protected_notes_title": "Notas protegidas", + "protected_notes_content": "Protege información personal sensible cifrando las notas y bloqueĆ”ndolas dentro de una sesión protegida con contraseƱa.", + "jump_to_title": "BĆŗsqueda rĆ”pida y comandos", + "jump_to_content": "Accede rĆ”pidamente a notas o comandos de la interfaz en toda la jerarquĆ­a buscando por su tĆ­tulo, con bĆŗsqueda aproximada que corrige errores tipogrĆ”ficos o variaciones mĆ­nimas.", + "search_title": "BĆŗsqueda potente", + "search_content": "O busca texto dentro de las notas y acota la bĆŗsqueda filtrando por la nota principal o por nivel de profundidad.", + "web_clipper_title": "Clipper web", + "web_clipper_content": "Captura pĆ”ginas web (o capturas de pantalla) y agrĆ©galas directamente a Trilium usando la extensión del \"Clipper web\" para el navegador." + }, + "note_types": { + "text_title": "Notas tipo texto", + "text_description": "Las notas se editan con un editor visual (WYSIWYG), con soporte para tablas, imĆ”genes, expresiones matemĆ”ticas y bloques de código con resaltado de sintaxis. Puedes formatear rĆ”pidamente el texto usando una sintaxis similar a Markdown o mediante comandos con barra (/).", + "code_title": "Notas tipo código", + "code_description": "Fragmentos extensos de código fuente o scripts se manejan en un editor dedicado, con resaltado de sintaxis para mĆŗltiples lenguajes de programación y distintos temas de color.", + "file_title": "Notas tipo archivo", + "file_description": "Incorpora archivos multimedia, como PDFs, imĆ”genes o videos, con vista previa directamente en la aplicación.", + "canvas_title": "Lienzo", + "canvas_description": "Organiza formas, imĆ”genes y texto en un lienzo infinito, usando la misma tecnologĆ­a de excalidraw.com. Perfecto para diagramas, bocetos y planificación visual.", + "mermaid_title": "Diagramas Mermaid", + "mermaid_description": "Crea diagramas de flujo, de clases, de secuencia, de Gantt y muchos mĆ”s con la sintaxis de Mermaid.", + "mindmap_title": "Mapa mental", + "mindmap_description": "Organiza ideas visualmente o haz una sesión de lluvia de ideas.", + "others_list": "y otros: <0>mapa de notas, <1>mapa de relaciones, <2>bĆŗsquedas guardadas, <3>vista de nota, y <4>vistas web.", + "title": "MĆŗltiples formas de representar su información" + }, + "extensibility_benefits": { + "title": "Compartir y extensibilidad", + "import_export_title": "Importar/Exportar", + "import_export_description": "InteractĆŗa fĆ”cilmente con otras aplicaciones usando los formatos Markdown, ENEX y OML.", + "share_title": "Compartir notas en la web", + "share_description": "Si se dispone de un servidor, se puede usar para compartir un subconjunto de notas con otras personas.", + "scripting_title": "Scripting avanzado", + "scripting_description": "Crea tus propias integraciones en Trilium con widgets personalizados o lógica en el servidor.", + "api_title": "API REST", + "api_description": "InteractĆŗa con Trilium de forma programĆ”tica usando su API REST integrada." + }, + "collections": { + "calendar_title": "Calendario", + "calendar_description": "Organiza tus eventos personales o profesionales en un calendario, con soporte para eventos de todo el dĆ­a o de varios dĆ­as. Consulta tus eventos rĆ”pidamente con las vistas semanal, mensual y anual. AƱade o mueve eventos de forma sencilla.", + "table_title": "Tabla", + "table_description": "Muestra y edita información sobre las notas en una estructura tabular, con distintos tipos de columna como texto, nĆŗmero, casillas de verificación, fecha y hora, enlaces y colores, y con soporte para relaciones. Opcionalmente, muestra las notas dentro de una jerarquĆ­a en forma de Ć”rbol dentro de la tabla.", + "board_title": "Tablero Kanban", + "board_description": "Organiza tus tareas o el progreso de tus proyectos en un tablero Kanban. Crea fĆ”cilmente nuevos elementos y columnas, y cambia su estado simplemente arrastrĆ”ndolos por el tablero.", + "geomap_title": "Mapa geogrĆ”fico", + "geomap_description": "Planifica vacaciones o marca puntos de interĆ©s en un mapa geogrĆ”fico con marcadores personalizables. Visualiza rutas GPX registradas para seguir itinerarios.", + "title": "Colecciones", + "presentation_title": "Presentación", + "presentation_description": "Organiza la información en diapositivas y presĆ©ntalas en pantalla completa con transiciones fluidas. Las diapositivas tambiĆ©n se pueden exportar a PDF para compartirlas fĆ”cilmente." + }, + "faq": { + "title": "Preguntas frecuentes", + "mobile_question": "ĀæExiste una aplicación móvil?", + "mobile_answer": "Actualmente no hay una aplicación móvil oficial. Sin embargo, si se dispone de una instancia en un servidor, se puede acceder desde un navegador web e incluso instalarla como PWA. Para Android, existe una aplicación no oficial llamada TriliumDroid que funciona incluso sin conexión (igual que un cliente de escritorio).", + "database_question": "ĀæDónde se almacenan los datos?", + "database_answer": "Todas las notas se almacenan en una base de datos SQLite dentro de la carpeta de la aplicación. Trilium utiliza una base de datos en lugar de archivos de texto plano por motivos de rendimiento y porque algunas funciones, como los clones (la misma nota en varios lugares del Ć”rbol), serĆ­an mucho mĆ”s difĆ­ciles de implementar. Para localizar la carpeta de la aplicación, basta con abrir la ventana \"Acerca de\".", + "server_question": "ĀæEs necesario un servidor para usar Trilium?", + "server_answer": "No, el servidor permite acceder desde un navegador web y gestionar la sincronización si se usan varios dispositivos. Para empezar, basta con descargar la aplicación de escritorio y comenzar a usarla.", + "scaling_question": "ĀæCómo escala la aplicación con una gran cantidad de notas?", + "scaling_answer": "SegĆŗn el uso, la aplicación puede manejar al menos 100.000 notas sin problemas. Hay que tener en cuenta que la sincronización puede fallar al subir muchos archivos grandes (1 GB por archivo), ya que Trilium estĆ” pensado como una base de conocimiento y no como un almacenamiento de archivos (como NextCloud, por ejemplo).", + "network_share_question": "ĀæPuedo compartir mi base de datos a travĆ©s de una unidad de red?", + "network_share_answer": "No, generalmente no es recomendable compartir una base de datos SQLite mediante una unidad de red. Aunque a veces podrĆ­a funcionar, existe el riesgo de que la base de datos se corrompa debido a bloqueos de archivos imperfectos en la red.", + "security_question": "ĀæCómo se protegen mis datos?", + "security_answer": "Por defecto, las notas no estĆ”n encriptadas y se pueden leer directamente desde la base de datos. Una vez que una nota se marca como encriptada, se cifra usando AES-128-CBC." + }, + "final_cta": { + "title": "ĀæListo para empezar con Trilium Notes?", + "description": "Construye tu propia base de conocimiento con funciones avanzadas y total privacidad.", + "get_started": "Comenzar" + }, + "components": { + "link_learn_more": "Saber mĆ”s…" + }, + "download_now": { + "text": "Descarga ahora ", + "platform_big": "v{{version}} para {{platform}}", + "platform_small": "para {{platform}}", + "linux_big": "v{{version}} para Linux", + "linux_small": "para Linux", + "more_platforms": "MĆ”s plataformas y configuración del servidor" + }, + "footer": { + "copyright_and_the": " y el ", + "copyright_community": "comunidad" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "Discusiones de GitHub", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "support_us": { + "title": "Apóyanos", + "financial_donations_title": "Donaciones económicas", + "financial_donations_description": "Trilium se desarrolla y mantiene con cientos de horas de trabajo. Tu apoyo ayuda a mantenerlo de código abierto, mejorar sus funciones y cubrir gastos como el alojamiento.", + "financial_donations_cta": "Considera apoyar al desarrollador principal (eliandoran) de la aplicación a travĆ©s de:", + "github_sponsors": "Patrocinadores de GitHub", + "paypal": "PayPal", + "buy_me_a_coffee": "Compra un cafĆ©" + }, + "contribute": { + "title": "Otras formas de contribuir", + "way_translate": "Traduce la aplicación a tu idioma nativo a travĆ©s de Weblate.", + "way_community": "InteractĆŗa con la comunidad en GitHub Discussions o en Matrix.", + "way_reports": "Reporta errores a travĆ©s de GitHub Issues.", + "way_document": "Ayuda a mejorar la documentación seƱalando vacĆ­os en ella o contribuyendo con guĆ­as, preguntas frecuentes o tutoriales.", + "way_market": "Corre la voz: comparte Trilium Notes con amigos, en blogs o en redes sociales." + }, + "404": { + "title": "404: No encontrado", + "description": "La pĆ”gina que buscas no se pudo encontrar. Tal vez fue eliminada o la URL es incorrecta." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows de 64 bits", + "title_arm64": "Windows en ARM", + "description_x64": "Compatible con dispositivos Intel o AMD que ejecuten Windows 10 u 11.", + "description_arm64": "Compatible con dispositivos ARM (por ejemplo, con Qualcomm Snapdragon).", + "quick_start": "Para instalar mediante Winget:", + "download_exe": "Descarga instalador (.exe)", + "download_zip": "Versión portĆ”til (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux de 64 bits", + "title_arm64": "Linux en ARM", + "description_x64": "Compatible con la mayorĆ­a de distribuciones Linux, para arquitectura x86_64.", + "description_arm64": "Compatible con distribuciones Linux basadas en ARM, para arquitectura aarch64.", + "quick_start": "Selecciona el formato de paquete adecuado segĆŗn tu distribución:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "Versión portĆ”til (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS para Intel", + "title_arm64": "macOS para Apple Silicon", + "description_x64": "Para Macs con procesador Intel que ejecuten macOS Monterey o posterior.", + "description_arm64": "Para Macs con Apple Silicon, como los que tienen chips M1 y M2.", + "quick_start": "Para instalar mediante Homebrew:", + "download_dmg": "Descargar instalador (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "Versión portĆ”til (.zip)" + }, + "download_helper_server_docker": { + "title": "Autohospedado usando Docker", + "description": "Despliega fĆ”cilmente en Windows, Linux o macOS mediante un contenedor Docker.", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "Autohospedado en Linux", + "description": "Despliega Trilium Notes en tu propio servidor o VPS, compatible con la mayorĆ­a de las distribuciones.", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "Módulo de NixOS" + }, + "download_helper_server_hosted": { + "title": "Alojamiento de pago", + "description": "Trilium Notes hospedado en PikaPods, un servicio de pago que ofrece acceso y gestión sencillos. Sin afiliación directa con el equipo de Trilium.", + "download_pikapod": "Configurar en PikaPods", + "download_triliumcc": "Alternativamente, consulta trilium.cc" + }, + "header": { + "get-started": "Comencemos", + "documentation": "Documentación", + "support-us": "Apóyanos", + "resources": "Recursos" + }, + "resources": { + "title": "Recursos", + "icon_packs": "Paquetes de iconos", + "icon_packs_intro": "Ampliar la selección de iconos disponibles para sus notas utilizando un paquete de iconos. Para mĆ”s información acerca de paquetes de icono, vea la documentación oficial.", + "download": "Descargar", + "website": "Sitio web" + } +} diff --git a/apps/website/src/translations/fa/translation.json b/apps/website/src/translations/fa/translation.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/apps/website/src/translations/fa/translation.json @@ -0,0 +1 @@ +{} diff --git a/apps/website/src/translations/fi/translation.json b/apps/website/src/translations/fi/translation.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/apps/website/src/translations/fi/translation.json @@ -0,0 +1 @@ +{} diff --git a/apps/website/src/translations/fr/translation.json b/apps/website/src/translations/fr/translation.json new file mode 100644 index 0000000000..50a8ada17a --- /dev/null +++ b/apps/website/src/translations/fr/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "title": "Commencer", + "desktop_title": "TĆ©lĆ©charger l'application de bureau (v{{version}})", + "architecture": "ArchitectureĀ :", + "older_releases": "Voir les versions plus anciennes", + "server_title": "Configurer un serveur pour accĆ©der Ć  plusieurs appareils" + }, + "hero_section": { + "github": "GitHub", + "get_started": "Commencer", + "title": "Organisez vos pensĆ©es. Construisez votre base de connaissances personnelles.", + "subtitle": "Trilium est une solution open source pour la prise de notes et l'organisation de votre base de connaissances personnelle. Utilisez-la localement sur votre ordinateur ou synchronisez-la avec votre serveur auto-hĆ©bergĆ© pour conserver vos notes où que vous soyez.", + "dockerhub": "Docker Hub", + "screenshot_alt": "Capture d'Ć©cran de l'application de bureau Trilium Notes" + }, + "organization_benefits": { + "title": "Organisation", + "note_structure_title": "Structure des notes", + "note_structure_description": "Les notes peuvent ĆŖtre organisĆ©es hiĆ©rarchiquement. Il n'est pas nĆ©cessaire de crĆ©er des dossiers, car chaque note peut contenir des sous-notes. Une mĆŖme note peut ĆŖtre ajoutĆ©e Ć  plusieurs endroits de la hiĆ©rarchie.", + "attributes_title": "Noter les Ć©tiquettes et les relations", + "attributes_description": "Utilisez des relations entre les notes ou ajoutez des Ć©tiquettes pour faciliter la catĆ©gorisation. Utilisez les attributs promus pour saisir des informations structurĆ©es utilisables dans des tableaux et des tableaux de bord.", + "hoisting_title": "Espaces de travail et focalisation", + "hoisting_description": "SĆ©parez facilement vos notes personnelles et professionnelles en les regroupant sous un espace de travail, ce qui concentre votre arborescence de notes pour afficher uniquement l'ensemble spĆ©cifique de celles-ci." + }, + "productivity_benefits": { + "title": "ProductivitĆ© et sĆ©curitĆ©", + "revisions_title": "RĆ©visions de note", + "revisions_content": "Les notes sont sauvegardĆ©es pĆ©riodiquement en arriĆØre-plan, et les rĆ©visions peuvent ĆŖtre utilisĆ©es pour consulter l’historique ou annuler des modifications accidentelles. Il est Ć©galement possible de crĆ©er des rĆ©visions Ć  la demande.", + "sync_title": "Synchronisation", + "sync_content": "Utilisez une instance auto-hĆ©bergĆ©e ou cloud pour synchroniser facilement vos notes sur plusieurs appareils, et pour y accĆ©der Ć  partir de votre tĆ©lĆ©phone mobile en utilisant un PWA.", + "protected_notes_title": "Notes protĆ©gĆ©es", + "protected_notes_content": "ProtĆ©gez les informations personnelles sensibles en chiffrant les notes et en les verrouillant dans une session protĆ©gĆ©e par mot de passe.", + "jump_to_title": "Recherche rapide et commandes", + "jump_to_content": "AccĆ©dez rapidement Ć  des notes ou commandes de l’interface dans toute la hiĆ©rarchie en recherchant leur titre, avec une correspondance approximative pour gĆ©rer les fautes de frappe ou lĆ©gĆØres variations.", + "search_title": "Recherche puissante", + "search_content": "Ou recherchez du texte Ć  l’intĆ©rieur des notes et affinez les rĆ©sultats en filtrant par note parente ou par profondeur.", + "web_clipper_title": "Web clipper", + "web_clipper_content": "RĆ©cupĆ©rez des pages Web (ou des captures d'Ć©cran) et placez-les directement dans Trilium Ć  l'aide de l'extension de navigateur \"Web Clipper\"." + }, + "note_types": { + "text_title": "Notes de texte", + "text_description": "Les notes sont Ć©ditĆ©es Ć  l'aide d'un Ć©diteur visuel (WYSIWYG) prenant en charge les tableaux, les images, les expressions mathĆ©matiques et les blocs de code avec coloration syntaxique. Formatez rapidement le texte grĆ¢ce Ć  une syntaxe de type Markdown ou Ć  des commandes slash.", + "code_title": "Notes de code", + "code_description": "De grands Ć©chantillons de code source ou de scripts utilisent un Ć©diteur dĆ©diĆ©, avec une coloration syntaxique pour de nombreux langages de programmation et avec diffĆ©rents thĆØmes de couleurs.", + "file_title": "Notes de fichier", + "file_description": "IntĆ©grez des fichiers multimĆ©dias tels que des PDF, des images, des vidĆ©os avec un aperƧu intĆ©grĆ© Ć  l'application.", + "canvas_title": "Canvas", + "canvas_description": "Agencez formes, images et textes sur une surface infinie grĆ¢ce Ć  la mĆŖme technologie qu'excalidraw.com. IdĆ©al pour les diagrammes, les croquis et la planification visuelle.", + "mermaid_title": "Diagrammes Mermaid", + "mermaid_description": "CrĆ©ez des diagrammes tels que des organigrammes, des diagrammes de classes et de sĆ©quences, des diagrammes de Gantt et bien d'autres, en utilisant la syntaxe Mermaid.", + "mindmap_title": "Carte mentale", + "mindmap_description": "Organisez vos pensĆ©es visuellement ou faites une sĆ©ance de brainstorming.", + "others_list": "et autresĀ : <0>carte de notes, <1>carte de relations, <2>recherches enregistrĆ©es, <3>note de rendu et <4>vues Web.", + "title": "Plusieurs faƧons de reprĆ©senter vos informations" + }, + "faq": { + "database_question": "Où sont stockĆ©es les donnĆ©es ?", + "database_answer": "Toutes vos notes seront stockĆ©es dans une base de donnĆ©es SQLite, dans un dossier d'application. Trilium utilise une base de donnĆ©es plutĆ“t que des fichiers texte pour des raisons de performances, et certaines fonctionnalitĆ©s seraient beaucoup plus complexes Ć  implĆ©menter, comme les clones (mĆŖme note Ć  plusieurs endroits de l'arborescence). Pour trouver le dossier d'application, accĆ©dez simplement Ć  la fenĆŖtre « À proposĀ Ā».", + "mobile_answer": "Il n'existe actuellement aucune application mobile officielle. Cependant, si vous disposez d'une instance serveur, vous pouvez y accĆ©der via un navigateur web et mĆŖme l'installer en tant que PWA. Pour Android, il existe une application non officielle appelĆ©e \"TriliumDroid\", qui fonctionne mĆŖme hors ligne (comme un client de bureau).", + "mobile_question": "Y a-t-il une application mobile ?", + "title": "Foire aux questions", + "server_question": "Ai-je besoin d'un serveur pour utiliser Trilium ?", + "server_answer": "Non, le serveur permet l'accĆØs via un navigateur web et gĆØre la synchronisation si vous possĆ©dez plusieurs appareils. Pour commencer, il suffit de tĆ©lĆ©charger l'application de bureau et de l'utiliser.", + "scaling_question": "Dans quelle mesure l'application s'adapte-t-elle Ć  une grande quantitĆ© de notes ?", + "scaling_answer": "Selon l'utilisation, l'application devrait pouvoir gĆ©rer au moins 100Ā 000 notes sans problĆØme. Notez que la synchronisation peut parfois Ć©chouer lors du tĆ©lĆ©chargement de nombreux fichiers volumineux (1Ā Go par fichier), car Trilium est davantage conƧu comme une base de connaissances que comme un espace de stockage de fichiers (comme NextCloud, par exemple).", + "network_share_question": "Puis-je partager ma base de donnĆ©es sur un lecteur rĆ©seau ?", + "network_share_answer": "Non, il est gĆ©nĆ©ralement dĆ©conseillĆ© de partager une base de donnĆ©es SQLite sur un lecteur rĆ©seau. Bien que cela puisse parfois fonctionner, il existe un risque de corruption de la base de donnĆ©es en raison de verrous de fichiers imparfaits sur le rĆ©seau.", + "security_question": "Comment mes donnĆ©es sont-elles protĆ©gĆ©es?", + "security_answer": "Par dĆ©faut, les notes ne sont pas chiffrĆ©es et peuvent ĆŖtre consultĆ©es directement depuis la base de donnĆ©es. Une fois chiffrĆ©e, une note l'est avec le protocole AES-128-CBC." + }, + "final_cta": { + "title": "PrĆŖt Ć  commencer avec Trilium Notes ?", + "description": "CrĆ©ez votre base de connaissances personnelle avec des fonctionnalitĆ©s puissantes et une totale confidentialitĆ©.", + "get_started": "Commencer" + }, + "components": { + "link_learn_more": "En savoir plus..." + }, + "support_us": { + "financial_donations_title": "Dons financiers", + "financial_donations_description": "Trilium est dĆ©veloppĆ© et maintenu grĆ¢ce Ć  des centaines d'heures de travail. Votre soutien permet de maintenir son open-source, d'amĆ©liorer ses fonctionnalitĆ©s et de couvrir des coĆ»ts tels que l'hĆ©bergement.", + "financial_donations_cta": "Envisagez de soutenir le dĆ©veloppeur principal (eliandoran) de l'application viaĀ :", + "github_sponsors": "Sponsors GitHub", + "paypal": "PayPal", + "buy_me_a_coffee": "Offrez-moi un cafĆ©", + "title": "Soutenez-nous" + }, + "contribute": { + "title": "Autres faƧons de contribuer", + "way_translate": "Traduisez l'application dans votre langue maternelle via Weblate.", + "way_community": "Interagissez avec la communautĆ© sur GitHub Discussions ou sur Matrix.", + "way_reports": "Signalez les bugs via GitHub issues.", + "way_document": "AmĆ©liorez la documentation en nous informant des lacunes dans celle-ci ou en contribuant Ć  des guides, des FAQ ou des tutoriels.", + "way_market": "Passez le motĀ : partagez Trilium Notes avec vos amis, sur des blogs et sur les rĆ©seaux sociaux." + }, + "404": { + "title": "404Ā : introuvable", + "description": "La page que vous cherchiez est introuvable. Elle a peut-ĆŖtre Ć©tĆ© supprimĆ©e ou l'URL est incorrecte." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64-bit", + "title_arm64": "Windows sur ARM", + "description_x64": "Compatible avec les appareils Intel ou AMD exĆ©cutant Windows 10 et 11.", + "description_arm64": "Compatible avec les appareils ARM (par exemple avec Qualcomm Snapdragon).", + "quick_start": "Pour installer via WingetĀ :", + "download_exe": "tĆ©lĆ©charger l'installeur (.exe)", + "download_zip": "Portable (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64-bit", + "title_arm64": "Linux sur ARM", + "description_x64": "Pour la plupart des distributions Linux, compatible avec l'architecture x86_64.", + "description_arm64": "Pour les distributions Linux basĆ©es sur ARM, compatible avec l'architecture aarch64.", + "quick_start": "SĆ©lectionnez un format de package appropriĆ©, en fonction de votre distributionĀ :", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "Portable (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS pour Intel", + "title_arm64": "macOS pour Apple Silicon", + "description_x64": "Pour les Mac basĆ©s sur Intel exĆ©cutant macOS Monterey ou une version ultĆ©rieure.", + "description_arm64": "Pour les Mac Apple Silicon tels que ceux Ć©quipĆ©s de puces M1 et M2.", + "quick_start": "Pour installer via HomebrewĀ :", + "download_dmg": "TĆ©lĆ©charger le programme d'installation (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "Portable (.zip)" + }, + "download_helper_server_docker": { + "title": "Auto-hĆ©bergĆ© avec Docker", + "description": "DĆ©ployez facilement sur Windows, Linux ou macOS Ć  l'aide d'un conteneur Docker.", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "Auto-hĆ©bergĆ© sur Linux", + "description": "DĆ©ployez Trilium Notes sur votre propre serveur ou VPS, compatible avec la plupart des distributions.", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "Module NixOS" + }, + "download_helper_server_hosted": { + "title": "HĆ©bergement payant", + "description": "Notes Trilium hĆ©bergĆ©es sur PikaPods, un service payant pour un accĆØs et une gestion simplifiĆ©s. Non affiliĆ© directement Ć  l'Ć©quipe Trilium.", + "download_pikapod": "InstallĆ© sur PikaPods", + "download_triliumcc": "Voir Ć©galement trilium.cc" + }, + "extensibility_benefits": { + "title": "Partage et extensibilitĆ©", + "import_export_title": "Import/export", + "import_export_description": "Interagissez facilement avec d'autres applications utilisant les formats Markdown, ENEX, OML.", + "share_title": "Partager des notes sur le Web", + "share_description": "Si vous disposez d'un serveur, vous pouvez l'utiliser pour partager un sous-ensemble de vos notes avec d'autres personnes.", + "scripting_title": "Scripts avancĆ©s", + "scripting_description": "CrĆ©ez vos propres intĆ©grations dans Trilium avec des widgets personnalisĆ©s ou une logique cĆ“tĆ© serveur.", + "api_title": "REST API", + "api_description": "Interagissez avec Trilium par programmation Ć  l'aide de son API REST intĆ©grĆ©e." + }, + "collections": { + "calendar_title": "Calendrier", + "calendar_description": "Organisez vos Ć©vĆ©nements personnels ou professionnels grĆ¢ce Ć  un calendrier compatible avec les Ć©vĆ©nements d'une journĆ©e ou de plusieurs jours. Visualisez vos Ć©vĆ©nements en un coup d'œil grĆ¢ce aux vues hebdomadaire, mensuelle et annuelle. Ajoutez ou dĆ©placez facilement des Ć©vĆ©nements.", + "table_title": "Tableau", + "table_description": "Affichez et modifiez les informations relatives aux notes dans une structure tabulaire, avec diffĆ©rents types de colonnes (texte, nombre, cases Ć  cocher, date et heure, liens, couleurs) et la prise en charge des relations. Vous pouvez Ć©galement afficher les notes sous forme d'arborescence Ć  l'intĆ©rieur du tableau.", + "board_title": "Tableau de bord", + "board_description": "Organisez vos tĆ¢ches ou l'Ć©tat de vos projets dans un tableau Kanban avec un moyen simple de crĆ©er de nouveaux Ć©lĆ©ments et colonnes et de modifier simplement leur Ć©tat en les faisant glisser sur le tableau.", + "geomap_title": "GĆ©ocarte", + "geomap_description": "Planifiez vos vacances ou marquez vos points d'intĆ©rĆŖt directement sur une carte gĆ©ographique grĆ¢ce Ć  des marqueurs personnalisables. Affichez les traces GPX enregistrĆ©es pour suivre vos itinĆ©raires.", + "title": "Collections", + "presentation_title": "PrĆ©sentation", + "presentation_description": "Organisez les informations sous forme de diapositives et prĆ©sentez-les en plein Ć©cran avec des transitions fluides. Les diapositives peuvent Ć©galement ĆŖtre exportĆ©es au format PDF pour faciliter leur partage." + }, + "download_now": { + "text": "TĆ©lĆ©charger maintenant. ", + "platform_big": "v{{version}} pour {{platform}}", + "platform_small": "pour {{platform}}", + "linux_big": "v{{version}} pour Linux", + "linux_small": "pour Linux", + "more_platforms": "Plus de plateformes et de configuration de serveur" + }, + "footer": { + "copyright_and_the": " et le ", + "copyright_community": "communautĆ©" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "Discussions GitHub", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "header": { + "get-started": "Commencer", + "documentation": "Documentation", + "support-us": "Soutenez-nous", + "resources": "Ressources" + }, + "resources": { + "title": "Ressources", + "icon_packs": "Packs d'icĆ“nes", + "download": "TĆ©lĆ©charger", + "website": "Site Internet", + "icon_packs_intro": "Ɖlargissez la sĆ©lection d’icĆ“nes disponibles pour vos notes en utilisant un pack d’icĆ“nes. Pour plus d'informations sur les packs d'icĆ“nes, consultez la documentation officielle." + } +} diff --git a/apps/website/src/translations/ga/translation.json b/apps/website/src/translations/ga/translation.json new file mode 100644 index 0000000000..c19563443c --- /dev/null +++ b/apps/website/src/translations/ga/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "title": "Tosaigh", + "desktop_title": "ƍoslódĆ”il an feidhmchlĆ”r deisce (v{{version}})", + "architecture": "Ailtireacht:", + "older_releases": "FĆ©ach ar eisiĆŗintĆ­ nĆ­os sine", + "server_title": "Socraigh freastalaĆ­ le haghaidh rochtana ar ilghlĆ©asanna" + }, + "hero_section": { + "title": "Eagraigh do chuid smaointe. Tóg do bhunachar eolais pearsanta.", + "subtitle": "Is rĆ©iteach foinse oscailte Ć© Trilium chun nótaĆ­ a thógĆ”il agus bunachar eolais pearsanta a eagrĆŗ. Bain ĆŗsĆ”id as go hĆ”itiĆŗil ar do dheasc, nó sioncrónaigh Ć© le do fhreastalaĆ­ fĆ©inóstĆ”ilte chun do nótaĆ­ a choinneĆ”il cibĆ© Ć”it a thĆ©ann tĆŗ.", + "get_started": "Tosaigh", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "ScĆ”ileĆ”n den fheidhmchlĆ”r deisce Trilium Notes" + }, + "organization_benefits": { + "title": "EagraĆ­ocht", + "note_structure_title": "StruchtĆŗr nótaĆ­", + "note_structure_description": "Is fĆ©idir nótaĆ­ a shocrĆŗ go hiarlathach. NĆ­l aon ghĆ” le fillteĆ”in, ós rud Ć© gur fĆ©idir fo-nótaĆ­ a bheith i ngach nóta. Is fĆ©idir nóta aonair a chur leis i roinnt Ć”iteanna san ordlathas.", + "attributes_title": "LipĆ©id nótaĆ­ agus caidrimh", + "attributes_description": "Bain ĆŗsĆ”id as caidrimh idir nótaĆ­ nó cuir lipĆ©id leis le haghaidh catagóiriĆŗ Ć©asca. Bain ĆŗsĆ”id as trĆ©ithe ardaithe chun faisnĆ©is struchtĆŗrtha a iontrĆ”il ar fĆ©idir a ĆŗsĆ”id i dtĆ”blaĆ­ agus i gclĆ”ir.", + "hoisting_title": "SpĆ”sanna oibre agus ardaitheoir", + "hoisting_description": "Deighil do nótaĆ­ pearsanta agus oibre go hĆ©asca trĆ­ iad a ghrĆŗpĆ”il faoi spĆ”s oibre, rud a dhĆ­rĆ­onn ar do chrann nótaĆ­ chun sraith nótaĆ­ ar leith amhĆ”in a thaispeĆ”int." + }, + "productivity_benefits": { + "title": "TĆ”irgiĆŗlacht agus sĆ”bhĆ”ilteacht", + "revisions_title": "Athbhreithnithe nóta", + "revisions_content": "SĆ”bhĆ”iltear nótaĆ­ go trĆ©imhsiĆŗil sa chĆŗlra agus is fĆ©idir athbhreithnithe a ĆŗsĆ”id le haghaidh athbhreithnithe nó chun athruithe de thaisme a chealĆŗ. Is fĆ©idir athbhreithnithe a chruthĆŗ ar Ć©ileamh freisin.", + "sync_title": "SioncrónĆŗ", + "sync_content": "Bain ĆŗsĆ”id as cĆ”s fĆ©inóstĆ”ilte nó scamall chun do nótaĆ­ a shioncrónĆŗ go hĆ©asca ar fud ilghlĆ©asanna, agus chun rochtain a fhĆ”il orthu ó do ghuthĆ”n póca ag baint ĆŗsĆ”ide as PWA.", + "protected_notes_title": "NótaĆ­ faoi chosaint", + "protected_notes_content": "Cosain faisnĆ©is phearsanta Ć­ogair trĆ­ na nótaĆ­ a chriptiĆŗ agus iad a ghlasĆ”il taobh thiar de sheisiĆŗn atĆ” cosanta ag pasfhocal.", + "jump_to_title": "Cuardach tapa agus orduithe", + "jump_to_content": "LĆ©im go tapa chuig nótaĆ­ nó orduithe UI ar fud an ordlathais trĆ­ chuardach a dhĆ©anamh ar a dteideal, le meaitseĆ”il doilĆ©ir chun clóscrĆ­obh nó difrĆ­ochtaĆ­ beaga a chur san Ć”ireamh.", + "search_title": "Cuardach cumhachtach", + "search_content": "Nó dĆ©an cuardach ar thĆ©acs laistigh de nótaĆ­ agus caolaigh an cuardach trĆ­ scagadh a dhĆ©anamh de rĆ©ir an nóta tuismitheora, nó de rĆ©ir doimhneachta.", + "web_clipper_title": "Gearrthóir grĆ©asĆ”in", + "web_clipper_content": "Gabh leathanaigh ghrĆ©asĆ”in (nó scĆ”ileĆ”in) agus cuir iad go dĆ­reach i Trilium ag baint ĆŗsĆ”ide as sĆ­neadh brabhsĆ”laĆ­ an ghearrthóra grĆ©asĆ”in." + }, + "note_types": { + "title": "IlbhealaĆ­ chun d’fhaisnĆ©is a lĆ©iriĆŗ", + "text_title": "NótaĆ­ tĆ©acs", + "text_description": "DĆ©antar na nótaĆ­ a chur in eagar ag baint ĆŗsĆ”ide as eagarthóir amhairc (WYSIWYG), a thacaĆ­onn le tĆ”blaĆ­, Ć­omhĆ”nna, nathanna matamaitice, bloic chóid le haibhsiĆŗ comhrĆ©ire. FormĆ”idigh an tĆ©acs go tapa ag baint ĆŗsĆ”ide as comhrĆ©ir cosĆŗil le Markdown nó ag baint ĆŗsĆ”ide as orduithe slaise.", + "code_title": "NótaĆ­ cóid", + "code_description": "ÚsĆ”ideann samplaĆ­ móra de chód foinse nó scripteanna eagarthóir tiomnaithe, le haibhsiĆŗ comhrĆ©ire do go leor teangacha rĆ­omhchlĆ”rĆŗchĆ”in agus le tĆ©amaĆ­ dathanna Ć©agsĆŗla.", + "file_title": "NótaĆ­ comhaid", + "file_description": "Cuir comhaid ilmheĆ”n ar nós PDFanna, Ć­omhĆ”nna, fĆ­seĆ”in le chĆ©ile le rĆ©amhamharc san fheidhmchlĆ”r.", + "canvas_title": "CanbhĆ”s", + "canvas_description": "Socraigh cruthanna, Ć­omhĆ”nna agus tĆ©acs ar chanbhĆ”s gan teorainn, ag baint ĆŗsĆ”ide as an teicneolaĆ­ocht chĆ©anna atĆ” taobh thiar de excalidraw.com. OiriĆŗnach do lĆ©arĆ”idĆ­, sceitsĆ­ agus pleanĆ”il amhairc.", + "mermaid_title": "LĆ©arĆ”idĆ­ maighdeana mara", + "mermaid_description": "Cruthaigh lĆ©arĆ”idĆ­ ar nós cairteacha sreafa, lĆ©arĆ”idĆ­ ranga agus seicheamhacha, cairteacha Gantt agus go leor eile, ag baint ĆŗsĆ”ide as comhrĆ©ir Mermaid.", + "mindmap_title": "LĆ©arscĆ”il intinne", + "mindmap_description": "Eagraigh do chuid smaointe go hamhairc nó dĆ©an seisiĆŗn smaointeoireachta.", + "others_list": "agus cinn eile: <0>lĆ©arscĆ”il nótaĆ­, <1>lĆ©arscĆ”il gaoil, <2>cuardaigh shĆ”bhĆ”ilte, <3>nóta rindreĆ”la, agus <4>radhairc ghrĆ©asĆ”in." + }, + "extensibility_benefits": { + "title": "Comhroinnt & inleathnĆŗ", + "import_export_title": "IompórtĆ”il/onnmhairiĆŗ", + "import_export_description": "IdirghnĆ­omhaigh go hĆ©asca le feidhmchlĆ”ir eile ag baint ĆŗsĆ”ide as formĆ”idĆ­ Markdown, ENEX, OML.", + "share_title": "Comhroinn nótaĆ­ ar an ngrĆ©asĆ”n", + "share_description": "MĆ” tĆ” freastalaĆ­ agat, is fĆ©idir Ć© a ĆŗsĆ”id chun fo-thacar de do nótaĆ­ a roinnt le daoine eile.", + "scripting_title": "ScriptiĆŗ ardleibhĆ©il", + "scripting_description": "Tóg do chomhthĆ”thĆŗ fĆ©in laistigh de Trilium le giuirlĆ©idĆ­ saincheaptha, nó loighic taobh an fhreastalaĆ­.", + "api_title": "REST API", + "api_description": "IdirghnĆ­omhaigh le Trilium go rĆ­omhchlĆ”raitheach ag baint ĆŗsĆ”ide as a REST API ionsuite." + }, + "collections": { + "title": "BailiĆŗchĆ”in", + "calendar_title": "FĆ©ilire", + "calendar_description": "Eagraigh d’imeachtaĆ­ pearsanta nó gairmiĆŗla ag baint ĆŗsĆ”ide as fĆ©ilire, le tacaĆ­ocht d’imeachtaĆ­ uile-lae agus il-lae. FĆ©ach ar d’imeachtaĆ­ go tapa leis na radhairc seachtaine, mĆ­osa agus bliana. IdirghnĆ­omhaĆ­ocht Ć©asca chun imeachtaĆ­ a chur leis nó a tharraingt.", + "table_title": "TĆ”bla", + "table_description": "TaispeĆ”in agus cuir in eagar faisnĆ©is faoi nótaĆ­ i struchtĆŗr tĆ”blach, le cineĆ”lacha Ć©agsĆŗla colĆŗn amhail tĆ©acs, uimhir, boscaĆ­ seiceĆ”la, dĆ”ta & am, naisc agus dathanna agus tacaĆ­ocht do chaidrimh. De rogha air sin, taispeĆ”in na nótaĆ­ laistigh de ordlathas crainn taobh istigh den tĆ”bla.", + "board_title": "Bord Kanban", + "board_description": "Eagraigh stĆ”das do thascanna nó do thionscadail i mbord Kanban le bealach Ć©asca chun mĆ­reanna agus colĆŗin nua a chruthĆŗ agus a stĆ”das a athrĆŗ go simplĆ­ trĆ­ tharraingt trasna an chlĆ”ir.", + "geomap_title": "Geo-lĆ©arscĆ”il", + "geomap_description": "PleanĆ”il do laethanta saoire nó marcĆ”il do phointĆ­ spĆ©ise go dĆ­reach ar lĆ©arscĆ”il gheografach ag baint ĆŗsĆ”ide as marcóirĆ­ saincheaptha. TaispeĆ”in rianta GPX taifeadta chun bealaĆ­ taistil a rianĆŗ.", + "presentation_title": "Cur i LĆ”thair", + "presentation_description": "Eagraigh faisnĆ©is i sleamhnĆ”in agus cuir i lĆ”thair iad i lĆ”nscĆ”ileĆ”n le haistrithe rĆ©idhe. Is fĆ©idir na sleamhnĆ”in a onnmhairiĆŗ go PDF freisin le go mbeidh sĆ© Ć©asca iad a roinnt." + }, + "faq": { + "title": "Ceisteanna Coitianta", + "mobile_question": "An bhfuil feidhmchlĆ”r soghluaiste ann?", + "mobile_answer": "Faoi lĆ”thair nĆ­l aon aip shoghluaiste oifigiĆŗil ann. Mar sin fĆ©in, mĆ” tĆ” freastalaĆ­ agat is fĆ©idir leat rochtain a fhĆ”il air trĆ­ bhrabhsĆ”laĆ­ grĆ©asĆ”in a ĆŗsĆ”id agus fiĆŗ Ć© a shuiteĆ”il mar PWA. I gcĆ”s Android, tĆ” aip neamhoifigiĆŗil ann ar a dtugtar TriliumDroid a oibrĆ­onn as lĆ­ne fiĆŗ (cosĆŗil le cliant deisce).", + "database_question": "CĆ” bhfuil na sonraĆ­ stórĆ”ilte?", + "database_answer": "StórĆ”lfar do nótaĆ­ go lĆ©ir i mbunachar sonraĆ­ SQLite i bhfillteĆ”n feidhmchlĆ”ir. Is Ć© an chĆŗis a n-ĆŗsĆ”ideann Trilium bunachar sonraĆ­ in ionad comhaid tĆ©acs simplĆ­ nĆ” feidhmĆ­ocht agus go mbeadh roinnt gnĆ©ithe i bhfad nĆ­os deacra a chur i bhfeidhm amhail clóin (an nóta cĆ©anna in Ć”iteanna Ć©agsĆŗla sa chrann). Chun an fillteĆ”n feidhmchlĆ”ir a aimsiĆŗ, tĆ©igh go dtĆ­ an fhuinneog Maidir Linn.", + "server_question": "An bhfuil freastalaĆ­ ag teastĆ”il uaim le Trilium a ĆŗsĆ”id?", + "server_answer": "NĆ­ hea, ceadaĆ­onn an freastalaĆ­ rochtain trĆ­ bhrabhsĆ”laĆ­ grĆ©asĆ”in agus bainistĆ­onn sĆ© an sioncrónĆŗ mĆ” tĆ” ilghlĆ©asanna agat. Chun tĆŗs a chur leis, is leor an feidhmchlĆ”r deisce a Ć­oslódĆ”il agus tosĆŗ ag baint ĆŗsĆ”ide as.", + "scaling_question": "CĆ© chomh maith agus a scĆ”laĆ­onn an feidhmchlĆ”r le lĆ­on mór nótaĆ­?", + "scaling_answer": "Ag brath ar ĆŗsĆ”id, ba cheart go mbeadh an feidhmchlĆ”r in ann 100,000 nóta ar a laghad a lĆ”imhseĆ”il gan fadhb. Tabhair faoi deara go bhfĆ©adfadh teip a bheith ar an bpróiseas sioncrónaithe uaireanta mĆ” tĆ” go leor comhad mór Ć” uaslódĆ”il (1 GB in aghaidh an chomhaid) ós rud Ć© go bhfuil Trilium beartaithe nĆ­os mó mar fheidhmchlĆ”r bonn eolais seachas stór comhad (cosĆŗil le NextCloud, mar shampla).", + "network_share_question": "An fĆ©idir liom mo bhunachar sonraĆ­ a roinnt thar thiomĆ”ntĆ”n lĆ­onra?", + "network_share_answer": "NĆ­ hea, nĆ­ smaoineamh maith Ć© bunachar sonraĆ­ SQLite a roinnt thar thiomĆ”ntĆ”n lĆ­onra i gcoitinne. CĆ© go bhfĆ©adfadh sĆ© oibriĆŗ uaireanta, tĆ” seans ann go ndĆ©anfar an bunachar sonraĆ­ a thruailliĆŗ mar gheall ar ghlasanna comhad neamhfhoirfe thar lĆ­onra.", + "security_question": "Conas a chosnaĆ­tear mo chuid sonraĆ­?", + "security_answer": "De rĆ©ir rĆ©amhshocraithe, nĆ­ chriptĆ­tear nótaĆ­ agus is fĆ©idir iad a lĆ©amh go dĆ­reach ón mbunachar sonraĆ­. Nuair a mharcĆ”iltear nóta mar chriptithe, dĆ©antar an nóta a chriptiĆŗ ag baint ĆŗsĆ”ide as AES-128-CBC." + }, + "final_cta": { + "title": "RĆ©idh le tosĆŗ le Trilium Notes?", + "description": "Tóg do bhunachar eolais pearsanta le gnĆ©ithe cumhachtacha agus prĆ­obhĆ”ideacht iomlĆ”n.", + "get_started": "Tosaigh" + }, + "components": { + "link_learn_more": "Foghlaim nĆ­os mó..." + }, + "download_now": { + "text": "ƍoslódĆ”il anois ", + "platform_big": "v{{version}} do {{platform}}", + "platform_small": "do {{platform}}", + "linux_big": "v{{version}} do Linux", + "linux_small": "do Linux", + "more_platforms": "Tuilleadh ardĆ”n & socrĆŗ freastalaĆ­" + }, + "header": { + "get-started": "Tosaigh", + "documentation": "DoicimĆ©adĆŗ", + "support-us": "Tacaigh linn", + "resources": "AcmhainnĆ­" + }, + "footer": { + "copyright_and_the": " agus an ", + "copyright_community": "pobal" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "PlĆ©anna GitHub", + "matrix": "MaitrĆ­s", + "reddit": "Reddit" + }, + "support_us": { + "title": "Tacaigh linn", + "financial_donations_title": "SĆ­ntiĆŗis airgeadais", + "financial_donations_description": "Tógtar agus cothaĆ­tear Trilium le na cĆ©adta uair an chloig oibre. CoinnĆ­onn do thacaĆ­ocht Ć© foinse oscailte, feabhsaĆ­onn sĆ© gnĆ©ithe, agus clĆŗdaĆ­onn sĆ© costais amhail óstĆ”il.", + "financial_donations_cta": "Smaoinigh ar thacaĆ­ocht a thabhairt don phrĆ­omhfhorbróir (eliandoran) den fheidhmchlĆ”r trĆ­:", + "github_sponsors": "UrraitheoirĆ­ GitHub", + "paypal": "PayPal", + "buy_me_a_coffee": "Ceannaigh Caife Dom" + }, + "contribute": { + "title": "BealaĆ­ eile chun rannĆ­ocaĆ­ocht a dhĆ©anamh", + "way_translate": "Aistrigh an feidhmchlĆ”r go do theanga dhĆŗchais trĆ­ Weblate.", + "way_community": "DĆ©an idirghnĆ­omhĆŗ leis an bpobal ar GitHub Discussions nó ar Matrix.", + "way_reports": "Tuairiscigh fabhtanna trĆ­ Fadhbanna GitHub.", + "way_document": "Feabhas a chur ar an doicimĆ©adacht trĆ­ eolas a thabhairt dĆŗinn faoi bhearnaĆ­ sa doicimĆ©adacht nó trĆ­ threoracha, Ceisteanna Coitianta nó ranganna teagaisc a chur ar fĆ”il.", + "way_market": "Scaip an scĆ©al: Roinn NótaĆ­ Trilium le cairde, nó ar bhlaganna agus ar na meĆ”in shóisialta." + }, + "404": { + "title": "404: NĆ­or aimsĆ­odh", + "description": "NĆ­orbh fhĆ©idir an leathanach a bhĆ­ Ć” lorg agat a aimsiĆŗ. B’fhĆ©idir gur scriosadh Ć© nó go bhfuil an URL mĆ­cheart." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64-bit", + "title_arm64": "Windows ar ARM", + "description_x64": "Ag luĆ­ le glĆ©asanna Intel nó AMD a bhfuil Windows 10 agus 11 Ć” rith acu.", + "description_arm64": "Ag luĆ­ le glĆ©asanna ARM (m.sh. le Qualcomm Snapdragon).", + "quick_start": "Chun a shuiteĆ”il trĆ­ Winget:", + "download_exe": "ƍoslódĆ”il an SuiteĆ”laĆ­ (.exe)", + "download_zip": "Iniompartha (.zip)", + "download_scoop": "ScĆŗp" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64-bit", + "title_arm64": "Linux ar ARM", + "description_x64": "Don chuid is mó de na dĆ”iltĆ­ Linux, comhoiriĆŗnach le hailtireacht x86_64.", + "description_arm64": "I gcĆ”s dĆ”iltĆ­ Linux bunaithe ar ARM, comhoiriĆŗnach le hailtireacht aarch64.", + "quick_start": "Roghnaigh formĆ”id phacĆ”iste chuĆ­, ag brath ar do dhĆ”ileadh:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "Iniompartha (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS do Intel", + "title_arm64": "macOS do Apple Silicon", + "description_x64": "Do Macs bunaithe ar Intel a bhfuil macOS Monterey nó nĆ­os dĆ©anaĆ­ Ć” rith acu.", + "description_arm64": "Do rĆ­omhairĆ­ Mac Apple Silicon ar nós iad siĆŗd a bhfuil sceallóga M1 agus M2 acu.", + "quick_start": "Chun a shuiteĆ”il trĆ­ Homebrew:", + "download_dmg": "ƍoslódĆ”il an SuiteĆ”laĆ­ (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "Iniompartha (.zip)" + }, + "download_helper_server_docker": { + "title": "FĆ©inóstĆ”ilte ag baint ĆŗsĆ”ide as Docker", + "description": "Imscaradh go hĆ©asca ar Windows, Linux nó macOS ag baint ĆŗsĆ”ide as coimeĆ”dĆ”n Docker.", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "FĆ©inóstĆ”ilte ar Linux", + "description": "Imscar Trilium Notes ar do fhreastalaĆ­ nó VPS fĆ©in, atĆ” comhoiriĆŗnach leis an gcuid is mó de na dĆ”ileachĆ”in.", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "ModĆŗl NixOS" + }, + "download_helper_server_hosted": { + "title": "ƓstĆ”il Ć­octha", + "description": "NótaĆ­ Trilium atĆ” Ć” n-óstĆ”il ar PikaPods, seirbhĆ­s Ć­octha le haghaidh rochtana agus bainistĆ­ochta Ć©asca. NĆ­l baint dhĆ­reach aige le foireann Trilium.", + "download_pikapod": "Socraigh ar PikaPods", + "download_triliumcc": "Nó fĆ©ach ar trilium.cc" + }, + "resources": { + "title": "AcmhainnĆ­", + "icon_packs": "PacĆ”istĆ­ deilbhĆ­n", + "icon_packs_intro": "Leathnaigh rogha na ndeilbhĆ­nĆ­ atĆ” ar fĆ”il le do nótaĆ­ trĆ­ phacĆ”iste deilbhĆ­nĆ­ a ĆŗsĆ”id. Le haghaidh tuilleadh eolais faoi phacĆ”istĆ­ deilbhĆ­nĆ­, fĆ©ach ar an dhoicimĆ©adĆŗ oifigiĆŗil.", + "download": "ƍoslódĆ”il", + "website": "SuĆ­omh GrĆ©asĆ”in" + } +} diff --git a/apps/website/src/translations/hi/translation.json b/apps/website/src/translations/hi/translation.json new file mode 100644 index 0000000000..fd908577bf --- /dev/null +++ b/apps/website/src/translations/hi/translation.json @@ -0,0 +1,99 @@ +{ + "get-started": { + "title": "ą¤¶ą„ą¤°ą„‚ ą¤•ą¤°ą„‡ą¤‚", + "desktop_title": "ą¤”ą„‡ą¤øą„ą¤•ą¤Ÿą„‰ą¤Ŗ ą¤ą¤Ŗą„ą¤²ą¤æą¤•ą„‡ą¤¶ą¤Ø ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚ (v{{version}})", + "older_releases": "ą¤Ŗą„ą¤°ą¤¾ą¤Øą„‡ ą¤°ą¤æą¤²ą„€ą¤œą¤¼ ą¤¦ą„‡ą¤–ą„‡ą¤‚" + }, + "hero_section": { + "title": "ą¤…ą¤Ŗą¤Øą„‡ ą¤µą¤æą¤šą¤¾ą¤°ą„‹ą¤‚ ą¤•ą„‹ ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚ą„¤ अपना ą¤µą„ą¤Æą¤•ą„ą¤¤ą¤æą¤—ą¤¤ ą¤Øą„‰ą¤²ą„‡ą¤œ ą¤¬ą„‡ą¤ø ą¤¬ą¤Øą¤¾ą¤ą¤‚ą„¤", + "screenshot_alt": "ą¤Ÿą„ą¤°ą¤æą¤²ą¤æą¤Æą¤® ą¤Øą„‹ą¤Ÿą„ą¤ø ą¤”ą„‡ą¤øą„ą¤•ą¤Ÿą„‰ą¤Ŗ ą¤ą¤Ŗą„ą¤²ą¤æą¤•ą„‡ą¤¶ą¤Ø का ą¤øą„ą¤•ą„ą¤°ą„€ą¤Øą¤¶ą„‰ą¤Ÿ", + "get_started": "ą¤¶ą„ą¤°ą„‚ ą¤•ą¤°ą„‡ą¤‚", + "github": "ą¤—ą¤æą¤Ÿą¤¹ą¤¬", + "dockerhub": "ą¤”ą„‰ą¤•ą¤° हब" + }, + "organization_benefits": { + "note_structure_title": "ą¤Øą„‹ą¤Ÿ ą¤øą¤‚ą¤°ą¤šą¤Øą¤¾", + "note_structure_description": "ą¤Øą„‹ą¤Ÿą„‹ą¤‚ ą¤•ą„‹ ą¤Ŗą¤¦ą¤¾ą¤Øą„ą¤•ą„ą¤°ą¤®ą¤æą¤• ą¤°ą„‚ą¤Ŗ ą¤øą„‡ ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ किया जा सकता ą¤¹ą„ˆą„¤ ą¤«ą¤¼ą„‹ą¤²ą„ą¤”ą¤°ą„ą¤ø ą¤•ą„€ ą¤•ą„‹ą¤ˆ ą¤†ą¤µą¤¶ą„ą¤Æą¤•ą¤¤ą¤¾ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆ, ą¤•ą„ą¤Æą„‹ą¤‚ą¤•ą¤æ ą¤Ŗą„ą¤°ą¤¤ą„ą¤Æą„‡ą¤• ą¤Øą„‹ą¤Ÿ ą¤®ą„‡ą¤‚ उप-ą¤Øą„‹ą¤Ÿ ą¤¹ą„‹ ą¤øą¤•ą¤¤ą„‡ ą¤¹ą„ˆą¤‚ą„¤ ą¤ą¤• ą¤ą¤•ą¤² ą¤Øą„‹ą¤Ÿ ą¤•ą„‹ ą¤Ŗą¤¦ą¤¾ą¤Øą„ą¤•ą„ą¤°ą¤® ą¤®ą„‡ą¤‚ ą¤•ą¤ˆ ą¤øą„ą¤„ą¤¾ą¤Øą„‹ą¤‚ पर ą¤œą„‹ą¤”ą¤¼ą¤¾ जा सकता ą¤¹ą„ˆą„¤" + }, + "productivity_benefits": { + "protected_notes_title": "ą¤øą¤‚ą¤°ą¤•ą„ą¤·ą¤æą¤¤ ą¤Øą„‹ą¤Ÿą„ą¤ø", + "web_clipper_title": "ą¤µą„‡ą¤¬ ą¤•ą„ą¤²ą¤æą¤Ŗą¤°" + }, + "note_types": { + "canvas_title": "ą¤•ą„ˆą¤Øą¤µą¤¾ą¤ø", + "mindmap_title": "ą¤®ą¤¾ą¤‡ą¤‚ą¤”ą¤®ą„ˆą¤Ŗ", + "file_title": "फ़ाइल ą¤Øą„‹ą¤Ÿą„ą¤ø" + }, + "extensibility_benefits": { + "share_title": "ą¤µą„‡ą¤¬ पर ą¤Øą„‹ą¤Ÿą„ą¤ø ą¤¶ą„‡ą¤Æą¤° ą¤•ą¤°ą„‡ą¤‚", + "share_description": "अगर ą¤†ą¤Ŗą¤•ą„‡ पास ą¤øą¤°ą„ą¤µą¤° ą¤¹ą„ˆ, ą¤¤ą„‹ इसका ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤…ą¤Ŗą¤Øą„‡ ą¤Øą„‹ą¤Ÿą„ą¤ø ą¤•ą„‡ ą¤ą¤• ą¤¹ą¤æą¤øą„ą¤øą„‡ ą¤•ą„‹ ą¤…ą¤Øą„ą¤Æ ą¤²ą„‹ą¤—ą„‹ą¤‚ ą¤•ą„‡ साऄ ą¤¶ą„‡ą¤Æą¤° ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ किया जा सकता ą¤¹ą„ˆą„¤", + "import_export_title": "ą¤‡ą¤‚ą¤Ŗą„‹ą¤°ą„ą¤Ÿ/ą¤ą¤•ą„ą¤øą¤Ŗą„‹ą¤°ą„ą¤Ÿ" + }, + "collections": { + "calendar_title": "ą¤•ą„ˆą¤²ą„‡ą¤‚ą¤”ą¤°", + "table_title": "ą¤Ÿą„‡ą¤¬ą¤²", + "board_title": "कानबान ą¤¬ą„‹ą¤°ą„ą¤”" + }, + "download_now": { + "linux_small": "ą¤²ą¤æą¤Øą¤•ą„ą¤ø ą¤•ą„‡ ą¤²ą¤æą¤", + "more_platforms": "अधिक ą¤Ŗą„ą¤²ą„‡ą¤Ÿą¤«ą„‰ą¤°ą„ą¤® और ą¤øą¤°ą„ą¤µą¤° ą¤øą„‡ą¤Ÿą¤…ą¤Ŗ" + }, + "header": { + "get-started": "ą¤¶ą„ą¤°ą„‚ ą¤•ą¤°ą„‡ą¤‚", + "support-us": "ą¤¹ą¤®ą„‡ą¤‚ ą¤øą¤Ŗą„‹ą¤°ą„ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚" + }, + "social_buttons": { + "github": "ą¤—ą¤æą¤Ÿą¤¹ą¤¬", + "matrix": "ą¤®ą„ˆą¤Ÿą„ą¤°ą¤æą¤•ą„ą¤ø", + "reddit": "ą¤°ą„‡ą¤”ą¤æą¤Ÿ" + }, + "support_us": { + "title": "ą¤¹ą¤®ą„‡ą¤‚ ą¤øą¤Ŗą„‹ą¤°ą„ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚" + }, + "404": { + "description": "आप ą¤œą„‹ ą¤Ŗą„‡ą¤œ ą¤–ą„‹ą¤œ ą¤°ą¤¹ą„‡ ą¤„ą„‡ वह ą¤Øą¤¹ą„€ą¤‚ मिल ą¤Ŗą¤¾ą¤Æą¤¾ą„¤ शायद वह ą¤”ą¤æą¤²ą„€ą¤Ÿ ą¤¹ą„‹ ą¤šą„ą¤•ą¤¾ ą¤¹ą„ˆ या ą¤Æą„‚ą¤†ą¤°ą¤ą¤² (URL) गलत ą¤¹ą„ˆą„¤" + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64-bit", + "title_arm64": "ARM पर Windows", + "quick_start": "Winget ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ ą¤‡ą¤‚ą¤øą„ą¤Ÿą„‰ą¤² ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤:", + "download_exe": "ą¤‡ą¤‚ą¤øą„ą¤Ÿą„‰ą¤²ą¤° (.exe) ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚", + "download_zip": "ą¤Ŗą„‹ą¤°ą„ą¤Ÿą„‡ą¤¬ą¤² (.zip)" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64-bit", + "title_arm64": "ARM पर ą¤²ą¤æą¤Øą¤•ą„ą¤ø", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "ą¤Ŗą„‹ą¤°ą„ą¤Ÿą„‡ą¤¬ą¤² (.zip)", + "download_nixpkgs": "nixpkgs" + }, + "download_helper_desktop_macos": { + "title_x64": "Intel ą¤•ą„‡ ą¤²ą¤æą¤ macOS", + "title_arm64": "Apple Silicon ą¤•ą„‡ ą¤²ą¤æą¤ macOS", + "description_x64": "macOS Monterey या ą¤‰ą¤øą¤•ą„‡ बाद ą¤•ą„‡ ą¤µą¤°ą„ą„›ą¤Ø पर ą¤šą¤²ą¤Øą„‡ ą¤µą¤¾ą¤²ą„‡ Intel-आधारित Macs ą¤•ą„‡ ą¤²ą¤æą¤ą„¤", + "description_arm64": "Apple Silicon Macs ą¤•ą„‡ ą¤²ą¤æą¤, ą¤œą„ˆą¤øą„‡ कि M1 और M2 ą¤šą¤æą¤Ŗą„ą¤ø ą¤µą¤¾ą¤²ą„‡ ą¤®ą„‰ą¤”ą¤²ą„¤", + "quick_start": "Homebrew ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ ą¤‡ą¤‚ą¤øą„ą¤Ÿą„‰ą¤² ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤:", + "download_dmg": "ą¤‡ą¤‚ą¤øą„ą¤Ÿą„‰ą¤²ą¤° (.dmg) ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "ą¤Ŗą„‹ą¤°ą„ą¤Ÿą„‡ą¤¬ą¤² (.zip)" + }, + "download_helper_server_docker": { + "title": "Docker ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ ą¤øą„‡ą¤²ą„ą¤«-ą¤¹ą„‹ą¤øą„ą¤Ÿą„‡ą¤”", + "description": "Docker ą¤•ą¤‚ą¤Ÿą„‡ą¤Øą¤° का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤•ą„‡ Windows, Linux या macOS पर ą¤†ą¤øą¤¾ą¤Øą„€ ą¤øą„‡ ą¤”ą¤æą¤Ŗą„ą¤²ą„‰ą¤Æ ą¤•ą¤°ą„‡ą¤‚ą„¤", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "Linux पर ą¤øą„‡ą¤²ą„ą¤«-ą¤¹ą„‹ą¤øą„ą¤Ÿą„‡ą¤”", + "description": "ą¤Ÿą„ą¤°ą¤æą¤²ą¤æą¤Æą¤® ą¤Øą„‹ą¤Ÿą„ą¤ø ą¤•ą„‹ ą¤…ą¤Ŗą¤Øą„‡ ą¤–ą„ą¤¦ ą¤•ą„‡ ą¤øą¤°ą„ą¤µą¤° या VPS पर ą¤”ą¤æą¤Ŗą„ą¤²ą„‰ą¤Æ ą¤•ą¤°ą„‡ą¤‚, ą¤œą„‹ अधिकांश ą¤”ą¤æą¤øą„ą¤Ÿą„ą¤°ą„€ą¤¬ą„ą¤Æą„‚ą¤¶ą¤Øą„‹ ą¤•ą„‡ साऄ ą¤•ą¤®ą„ą¤Ŗą„‡ą¤Ÿą¤æą¤¬ą¤² ą¤¹ą„ˆą„¤", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "NixOS ą¤®ą„‰ą¤”ą„ą¤Æą„‚ą¤²" + }, + "download_helper_server_hosted": { + "title": "ą¤Ŗą„‡ą¤” ą¤¹ą„‹ą¤øą„ą¤Ÿą¤æą¤‚ą¤—", + "download_pikapod": "PikaPods पर ą¤øą„‡ą¤Ÿą¤…ą¤Ŗ ą¤•ą¤°ą„‡ą¤‚", + "download_triliumcc": "ą¤µą„ˆą¤•ą¤²ą„ą¤Ŗą¤æą¤• ą¤°ą„‚ą¤Ŗ ą¤øą„‡ trilium.cc ą¤¦ą„‡ą¤–ą„‡ą¤‚" + } +} diff --git a/apps/website/src/translations/hr/translation.json b/apps/website/src/translations/hr/translation.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/apps/website/src/translations/hr/translation.json @@ -0,0 +1 @@ +{} diff --git a/apps/website/src/translations/hu/translation.json b/apps/website/src/translations/hu/translation.json new file mode 100644 index 0000000000..a988c42ef1 --- /dev/null +++ b/apps/website/src/translations/hu/translation.json @@ -0,0 +1,44 @@ +{ + "get-started": { + "title": "KezdĆ©s", + "desktop_title": "Tƶltsd le az asztali alkalmazĆ”st (v{{version}})", + "architecture": "Szerkezet:", + "older_releases": "RĆ©gebbi kiadĆ”sok megtekintĆ©se", + "server_title": "Szerver beĆ”llĆ­tĆ”sa tƶbb eszkƶzről tƶrtĆ©nő hozzĆ”fĆ©rĆ©shez" + }, + "hero_section": { + "title": "Rendszerezd a gondolataidat. ƉpĆ­tsd fel a szemĆ©lyes tudĆ”sbĆ”zisodat.", + "subtitle": "A Trilium egy nyĆ­lt forrĆ”skódĆŗ megoldĆ”s jegyzetelĆ©shez Ć©s szemĆ©lyes tudĆ”sbĆ”zis rendszerezĆ©sĆ©hez. HasznĆ”ld helyben az asztali gĆ©peden, vagy szinkronizĆ”ld a sajĆ”t szervereddel, hogy jegyzeteid mindenhol elĆ©rhetőek legyenek.", + "get_started": "KezdĆ©s", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "A Trilium Notes asztali alkalmazĆ”s kĆ©pernyőkĆ©pe" + }, + "organization_benefits": { + "title": "Szervezet", + "note_structure_title": "Jegyzet szerkezet", + "note_structure_description": "A jegyzetek hierarchikusan rendezhetők. Nincs szüksĆ©g mappĆ”kra, mivel minden jegyzet tartalmazhat aljegyzeteket. Egyetlen jegyzet tƶbb helyre is hozzĆ”adható a hierarchiĆ”ban.", + "attributes_title": "JegyzetcĆ­mkĆ©k Ć©s kapcsolatok", + "attributes_description": "HasznĆ”ljon kapcsolatokat a jegyzetek kƶzƶtt, vagy adjon hozzĆ” cĆ­mkĆ©ket az egyszerű kategorizĆ”lĆ”s Ć©rdekĆ©ben. HasznĆ”ljon kiemelt attribĆŗtumokat strukturĆ”lt informĆ”ciók bevitelĆ©hez, amelyek tĆ”blĆ”zatokban Ć©s tĆ”blĆ”kon hasznĆ”lhatók.", + "hoisting_title": "Munkaterületek Ć©s kiemelĆ©s", + "hoisting_description": "KƶnnyedĆ©n külƶnĆ­tse el a szemĆ©lyes Ć©s munkahelyi jegyzeteit Ćŗgy, hogy csoportosĆ­tja őket egy munkaterület alatt, amely a jegyzetfĆ”t csak egy adott jegyzetkĆ©szlet megjelenĆ­tĆ©sĆ©re ƶsszpontosĆ­tja." + }, + "productivity_benefits": { + "title": "TermelĆ©kenysĆ©g Ć©s biztonsĆ”g", + "revisions_title": "MegjegyzĆ©s felülvizsgĆ”latai", + "revisions_content": "A jegyzetek rendszeresen tĆ”rolódnak a hĆ”ttĆ©rben, Ć©s a revĆ­ziók felhasznĆ”lhatók felülvizsgĆ”latra vagy vĆ©letlen vĆ”ltozĆ”sok visszavonĆ”sĆ”ra. A revĆ­ziók igĆ©ny szerint is lĆ©trehozhatók.", + "sync_title": "SzinkronizĆ”lĆ”s", + "sync_content": "HasznĆ”ljon sajĆ”t maga Ć”ltal üzemeltetett vagy felhő alapu pĆ©ldĆ”nyt, hogy kƶnnyen szinkronizĆ”lja a jegyzeteket tƶbb eszkƶzƶn keresztül, Ć©s hozzĆ”fĆ©rjen a mobiltelefonjĆ”ról egy PWA segĆ­tsĆ©gĆ©vel.", + "protected_notes_title": "VĆ©dett jegyzetek", + "protected_notes_content": "VĆ©dje az Ć©rzĆ©keny szemĆ©lyes adatokat a jegyzetek titkosĆ­tĆ”sĆ”val Ć©s a jelszóval vĆ©dett munkamenet mƶgƶtti zĆ”rolĆ”ssal.", + "jump_to_title": "Gyors keresĆ©s Ć©s parancsok", + "jump_to_content": "Ugorj gyorsan a jegyzetekhez vagy a felhasznĆ”lói felület parancsaihoz a hierarchia területĆ©n, keresve a cĆ­müket, a fuzzy illesztĆ©ssel, hogy megmagyarĆ”zza az elĆ­rĆ”sokat vagy az enyhe külƶnbsĆ©geket.", + "search_title": "Erőteljes keresĆ©s", + "search_content": "Vagy keressen szƶveget a jegyzetekben, Ć©s szűkĆ­tse le a keresĆ©st a szülői jegyzet szűrĆ©sĆ©vel vagy mĆ©lysĆ©gĆ©vel." + }, + "note_types": { + "file_description": "BeĆ”gyazott multimĆ©diĆ”s fĆ”jlokat, pĆ©ldĆ”ul PDF-eket, kĆ©peket, videókat, alkalmazĆ”son belüli előnĆ©zettel.", + "canvas_title": "VĆ”szon", + "canvas_description": "Rendezzen formĆ”kat, kĆ©peket Ć©s szƶveget egy vĆ©gtelen vĆ”szonra, ugyanazzal a technológiĆ”val mint ami excalidraw.com mƶgƶtt van. IdeĆ”lis diagramokhoz, vĆ”zlatokhoz Ć©s vizuĆ”lis tervezĆ©shez." + } +} diff --git a/apps/website/src/translations/id/translation.json b/apps/website/src/translations/id/translation.json new file mode 100644 index 0000000000..8f550f062e --- /dev/null +++ b/apps/website/src/translations/id/translation.json @@ -0,0 +1,89 @@ +{ + "get-started": { + "title": "Mulai", + "desktop_title": "Unduh aplikasi desktop (v{{version}})", + "architecture": "Arsitektur:", + "older_releases": "Lihat rilis sebelumnya", + "server_title": "Pasang server untuk akses dari lebih dari satu perangkat" + }, + "hero_section": { + "title": "Rapikan pikiranmu. Bangunlah pusat pengetahuan pribadimu.", + "subtitle": "Trilium adalah solusi sumber terbuka untuk mencatat dan pengorganisasian sebuah pusat pengetahuan. Pakai offline di desktop, atau sinkronisasi dengan server pribadi untuk mengakses catatanmu di manapun kamu berada.", + "get_started": "Mulai", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Cuplikan layar aplikasi desktop Trilium Notes" + }, + "organization_benefits": { + "title": "Organisasi", + "note_structure_title": "Struktur catatan", + "note_structure_description": "Catatan dapat disusun secara hirarkis. Tidak perlu folder, karena setiap catatan dapat mengandung catatan anak. Satu catatan dapat ditambah di beberapa tempat sekaligus dalam hirarki.", + "attributes_title": "Label dan hubungan catatan", + "attributes_description": "Gunakan relasi antar catatan atau tambahkan label untuk kategorisasi yang mudah. Gunakan atribut utama untuk memasukkan informasi terstruktur yang dapat digunakan dalam tabel atau papan (boards).", + "hoisting_title": "Workspace dan Area Fokus", + "hoisting_description": "Dengan mudah memisahkan catatan personal dan kerjaan dengan grouping dalam workspace, fokus hanya ke catatan-catatan yang spesifik di workspace tertentu." + }, + "productivity_benefits": { + "title": "Produktivitas dan Keamanan", + "revisions_title": "Revisi Catatan", + "revisions_content": "Catatan akan secara periodik disimpan dalam bentuk revisi secara otomatis dan versi revisi-revisi bisa digunakan untuk mengulas kembali atau melakukan undo jika ada kesalahan atau perubahan yang tidak disengaja. Versi revisi juga bisa dibuat sesuai kebutuhan.", + "sync_title": "Sinkronisasi", + "sync_content": "Gunakan hostinganmu sendiri atau instansi cloud untuk sinkronisasi mudah catatan-catatan anda pada beberapa perangkat, dan untuk akses dari ponsel anda dengan PWA.", + "search_content": "Atau cari teks di dalam catatan lalu lebih dalam dengan cari catatan induk, atau berdasarkan kedalaman.", + "web_clipper_title": "Penyemat Web", + "web_clipper_content": "Mengambil halaman web (atau foto halaman web) dan disematkan langsung ke catatan Trilium dengan ekstensi browser penyemat web.", + "protected_notes_title": "Catatan terlindungi", + "protected_notes_content": "Lindungi informasi pribadi sensitif dengan mengenkripsi catatan dan menguncinya di balik sesi yang dilindungi kata sandi.", + "jump_to_title": "Pencarian cepat dan perintah", + "jump_to_content": "Melompat dengan cepat ke catatan atau perintah UI di seluruh hierarki dengan mencari judulnya, dengan pencocokan kabur untuk memperhitungkan kesalahan ketik atau perbedaan kecil.", + "search_title": "Pencarian mumpuni" + }, + "note_types": { + "title": "Cara-cara menampilkan informasi Anda", + "text_title": "Catatan teks", + "text_description": "Catatan-catatan ini diedit dengan editor visual (WYSIWYG), dengan dukungan tabel, gambar, ekspresi matematika, blok kode dengan penyorotan sintaks. Format teks catatan anda dengan sintaks Markdown atau gunakan fungsi panggilan slash(/).", + "code_title": "Catatan kode", + "code_description": "Gunakan editor khusus untuk kode source yang besar yang mempunyai penyorotan sintaks untuk banyak bahasa pemograman dengan tema-tema warna yang bervariasi.", + "file_title": "Catatan file", + "file_description": "Sematkan file multimedia (PDF, gambar, video) dengan pratinjau dalam aplikasi.", + "canvas_title": "Kanvas", + "canvas_description": "Susun bentuk, gambar, dan teks di atas kanvas tak terbatas menggunakan teknologi yang sama dengan excalidraw.com. Sangat ideal untuk diagram, sketsa, dan perencanaan visual.", + "mermaid_title": "Diagram mermaid", + "mermaid_description": "Buat diagram seperti diagram alur (flowchart), diagram kelas & urutan (class & sequence), bagan Gantt, dan banyak lagi, menggunakan sintaks Mermaid.", + "mindmap_title": "Peta pikiran (Mindmap)", + "mindmap_description": "Organisasikan pemikiran Anda secara visual atau lakukan sesi brainstorming.", + "others_list": "dan lainnya: <0>peta catatan, <1>peta relasi, <2>pencarian tersimpan, <3>render catatan, dan <4>tampilan web." + }, + "collections": { + "table_description": "Tampilkan dan edit informasi catatan dalam struktur tabel, dengan berbagai tipe kolom seperti teks, angka, kotak centang, tanggal & waktu, tautan, dan warna, serta dukungan untuk relasi catatan. Secara opsional, tampilkan catatan dalam hierarki pohon di dalam tabel.", + "board_title": "Papan Kanban", + "board_description": "Atur tugas atau status proyek Anda ke dalam papan Kanban dengan cara mudah untuk membuat item dan kolom baru, serta mengubah statusnya cukup dengan menyeretnya di sepanjang papan.", + "geomap_title": "Peta Geo", + "geomap_description": "Rencanakan liburan Anda atau tandai titik minat langsung pada peta geografis menggunakan penanda titik yang dapat disesuaikan. Tampilkan rekaman jalur GPX untuk melacak rencana perjalanan.", + "presentation_title": "Presentasi", + "presentation_description": "Atur informasi ke dalam slide dan presentasikan dalam layar penuh dengan transisi yang mulus. Slide juga dapat diekspor ke PDF agar mudah dibagikan.", + "calendar_description": "Kelola acara pribadi atau profesional Anda menggunakan kalender, dengan dukungan untuk acara sepanjang hari dan beberapa hari. Lihat acara Anda sekilas dengan tampilan mingguan, bulanan, dan tahunan. Interaksi mudah untuk menambahkan atau menyeret acara.", + "title": "Koleksi", + "calendar_title": "Penanggalan", + "table_title": "Tabel" + }, + "faq": { + "title": "Tanya Jawab", + "mobile_question": "Apakah ada aplikasi mobile?", + "mobile_answer": "Saat ini belum ada aplikasi mobile resmi. Namun, jika Anda memiliki server, Anda dapat mengaksesnya menggunakan browser web dan bahkan menginstalnya sebagai PWA. Untuk Android, tersedia aplikasi tidak resmi bernama TriliumDroid yang dapat bekerja secara offline (sama seperti aplikasi desktop).", + "database_question": "Di manakah data disimpan?", + "database_answer": "Semua catatan Anda akan disimpan dalam basis data SQLite di dalam sebuah folder aplikasi. Alasan mengapa Trilium menggunakan basis data alih-alih file teks biasa adalah demi performa dan karena beberapa fitur akan jauh lebih sulit untuk diterapkan, seperti klon (catatan yang sama di beberapa tempat dalam hierarki). Untuk menemukan folder aplikasinya, cukup buka jendela 'Tentang'.", + "server_question": "Apakah saya butuh server untuk menjalankan Trilium?" + }, + "extensibility_benefits": { + "share_title": "Bagikan catatan di web", + "title": "Berbagi & perluasan", + "import_export_title": "Impor/ekspor", + "import_export_description": "Berinteraksi dengan mudah dengan aplikasi lain menggunakan format Markdown, ENEX, dan OML.", + "share_description": "Jika Anda memiliki server, server tersebut dapat digunakan untuk berbagi sebagian catatan Anda dengan orang lain.", + "scripting_title": "Pembuatan skrip tingkat lanjut", + "scripting_description": "Bangun integrasi Anda sendiri di dalam Trilium dengan widget khusus, atau logika sisi server.", + "api_title": "REST API", + "api_description": "Berinteraksi dengan Trilium secara terprogram menggunakan API REST bawaannya." + } +} diff --git a/apps/website/src/translations/it/translation.json b/apps/website/src/translations/it/translation.json new file mode 100644 index 0000000000..84b60d045c --- /dev/null +++ b/apps/website/src/translations/it/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "title": "Inizia", + "desktop_title": "Scarica l'applicazione desktop (v{{version}})", + "architecture": "Architettura:", + "older_releases": "Vedi le versioni precedenti", + "server_title": "Configurare un server per l'accesso su più dispositivi" + }, + "hero_section": { + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Screenshot dell'applicazione desktop Trilium Notes", + "title": "Organizza i tuoi pensieri. Costruisci la tua conoscenza personale.", + "subtitle": "Trilium ĆØ una soluzione open source per prendere appunti e organizzare una base di conoscenze personali. Utilizzalo localmente sul tuo desktop o sincronizzalo con il tuo server self-hosted per avere i tuoi appunti sempre con te, ovunque tu vada.", + "get_started": "Inizia ora" + }, + "organization_benefits": { + "title": "Organizzazione", + "note_structure_title": "Struttura della nota", + "note_structure_description": "Le note possono essere organizzate gerarchicamente. Non sono necessarie cartelle, poichĆ© ogni nota può contenere sottonote. Una singola nota può essere aggiunta in più punti della gerarchia.", + "attributes_title": "Nota etichette e relazioni", + "attributes_description": "Utilizza le relazioni tra le note o aggiungi etichette per una facile categorizzazione. Utilizza gli attributi promossi per inserire informazioni strutturate che possono essere utilizzate in tabelle e bacheche.", + "hoisting_title": "Aree di lavoro e ancoraggi", + "hoisting_description": "Separa facilmente le tue note personali da quelle di lavoro raggruppandole in un'area di lavoro, che concentra la struttura delle note in modo da mostrare solo un insieme specifico di note." + }, + "productivity_benefits": { + "title": "ProduttivitĆ  e sicurezza", + "revisions_title": "Nota sulle revisioni", + "revisions_content": "Le note vengono salvate periodicamente in background e le revisioni possono essere utilizzate per la revisione o per annullare modifiche accidentali. Le revisioni possono anche essere create su richiesta.", + "sync_title": "Sincronizzazione", + "sync_content": "Utilizza un'istanza self-hosted o cloud per sincronizzare facilmente le tue note su più dispositivi e accedervi dal tuo cellulare utilizzando una PWA.", + "protected_notes_title": "Note protette", + "protected_notes_content": "Proteggi le informazioni personali sensibili crittografando le note e bloccandole dietro una sessione protetta da password.", + "jump_to_title": "Ricerca rapida e comandi", + "jump_to_content": "Passa rapidamente alle note o ai comandi dell'interfaccia utente in tutta la gerarchia cercando il loro titolo, con corrispondenza approssimativa per tenere conto di errori di battitura o lievi differenze.", + "search_title": "Ricerca avanzata", + "search_content": "Oppure cerca del testo all'interno delle note e restringi la ricerca filtrando per nota principale o per profonditĆ .", + "web_clipper_title": "Web clipper", + "web_clipper_content": "Cattura pagine web (o screenshot) e inseriscile direttamente in Trilium utilizzando l'estensione del browser Web Clipper." + }, + "note_types": { + "text_title": "Note di testo", + "text_description": "Le note vengono modificate utilizzando un editor visivo (WYSIWYG), con supporto per tabelle, immagini, espressioni matematiche, blocchi di codice con evidenziazione della sintassi. Formatta rapidamente il testo utilizzando una sintassi simile a Markdown o utilizzando comandi slash.", + "code_title": "Note di codice", + "code_description": "Campioni di codice sorgente o script di grandi dimensioni utilizzano un editor dedicato, con evidenziazione della sintassi per molti linguaggi di programmazione e con vari temi cromatici.", + "file_title": "Note di file", + "file_description": "Incorpora file multimediali come PDF, immagini, video con un'anteprima nell'applicazione.", + "canvas_title": "Canvas", + "canvas_description": "Disponi forme, immagini e testo su una tela infinita, utilizzando la stessa tecnologia alla base di excalidraw.com. Ideale per diagrammi, schizzi e pianificazione visiva.", + "mermaid_title": "Diagrammi a sirena", + "mermaid_description": "Crea diagrammi come diagrammi di flusso, diagrammi di classe e sequenza, diagrammi di Gantt e molti altri, utilizzando la sintassi Mermaid.", + "mindmap_title": "Mappe mentali", + "mindmap_description": "Organizza i tuoi pensieri visivamente o fai una sessione di brainstorming.", + "others_list": "e altri: <0>mappa delle note, <1>mappa delle relazioni, <2>ricerche salvate, <3>renderizza nota e <4>visualizzazioni web.", + "title": "Diversi modi per rappresentare le tue informazioni" + }, + "extensibility_benefits": { + "title": "Condivisione ed estensibilitĆ ", + "import_export_title": "Importazione/esportazione", + "import_export_description": "Interagisci facilmente con altre applicazioni utilizzando i formati Markdown, ENEX e OML.", + "share_title": "Condividi note sul web", + "share_description": "Se disponi di un server, puoi utilizzarlo per condividere una parte delle tue note con altre persone.", + "scripting_title": "Scripting avanzato", + "scripting_description": "Crea le tue integrazioni all'interno di Trilium con widget personalizzati o logica lato server.", + "api_title": "REST API", + "api_description": "Interagisci con Trilium a livello di programmazione utilizzando la sua API REST integrata." + }, + "collections": { + "calendar_title": "Calendario", + "calendar_description": "Organizza i tuoi eventi personali o professionali utilizzando un calendario, con supporto per eventi di un giorno intero o di più giorni. Visualizza i tuoi eventi a colpo d'occhio con le viste settimanale, mensile e annuale. Interazione semplice per aggiungere o trascinare eventi.", + "table_title": "Tabella", + "table_description": "Visualizza e modifica le informazioni relative alle note in una struttura tabellare, con vari tipi di colonne quali testo, numeri, caselle di controllo, data e ora, collegamenti e colori, oltre al supporto per le relazioni. Facoltativamente, ĆØ possibile visualizzare le note all'interno di una gerarchia ad albero all'interno della tabella.", + "board_title": "Kanban Board", + "board_description": "Organizza le tue attivitĆ  o lo stato dei tuoi progetti in una lavagna Kanban con un modo semplice per creare nuovi elementi e colonne e modificare facilmente il loro stato trascinandoli sulla lavagna.", + "geomap_title": "Geomappa", + "geomap_description": "Pianifica le tue vacanze o segna i tuoi punti di interesse direttamente su una mappa geografica utilizzando indicatori personalizzabili. Visualizza le tracce GPX registrate per seguire gli itinerari.", + "title": "Collezioni", + "presentation_title": "Presentazione", + "presentation_description": "Organizza le informazioni in diapositive e presentale a schermo intero con transizioni fluide. Le diapositive possono anche essere esportate in formato PDF per una facile condivisione." + }, + "faq": { + "title": "Domande frequenti", + "mobile_question": "Esiste un'applicazione mobile?", + "mobile_answer": "Al momento non esiste un'applicazione mobile ufficiale. Tuttavia, se disponi di un'istanza server, puoi accedervi utilizzando un browser web e persino installarla come PWA. Per Android, esiste un'applicazione non ufficiale chiamata TriliumDroid che funziona anche offline (come un client desktop).", + "database_question": "Dove vengono archiviati i dati?", + "database_answer": "Tutte le tue note saranno archiviate in un database SQLite nella cartella dell'applicazione. Il motivo per cui Trilium utilizza un database anzichĆ© file di testo semplice ĆØ sia una questione di prestazioni sia perchĆ© alcune funzionalitĆ  sarebbero molto più difficili da implementare, come i cloni (stessa nota in più punti dell'albero). Per trovare la cartella dell'applicazione, basta andare alla finestra Informazioni.", + "server_question": "Ho bisogno di un server per usare Trilium?", + "server_answer": "No, il server consente l'accesso tramite un browser web e gestisce la sincronizzazione se si dispone di più dispositivi. Per iniziare, ĆØ sufficiente scaricare l'applicazione desktop e iniziare a utilizzarla.", + "scaling_question": "Quanto ĆØ scalabile l'applicazione con una grande quantitĆ  di note?", + "scaling_answer": "A seconda dell'utilizzo, l'applicazione dovrebbe essere in grado di gestire almeno 100.000 note senza problemi. Si noti che il processo di sincronizzazione a volte può fallire se si caricano molti file di grandi dimensioni (1 GB per file), poichĆ© Trilium ĆØ concepito più come un'applicazione di knowledge base che come un archivio di file (come NextCloud, ad esempio).", + "network_share_question": "Posso condividere il mio database su un'unitĆ  di rete?", + "network_share_answer": "No, in genere non ĆØ una buona idea condividere un database SQLite su un'unitĆ  di rete. Anche se a volte potrebbe funzionare, c'ĆØ il rischio che il database venga danneggiato a causa di blocchi dei file imperfetti sulla rete.", + "security_question": "Come vengono protetti i miei dati?", + "security_answer": "Per impostazione predefinita, le note non sono crittografate e possono essere lette direttamente dal database. Una volta contrassegnata come crittografata, la nota viene crittografata utilizzando AES-128-CBC." + }, + "final_cta": { + "title": "Pronti per iniziare con Trilium Notes?", + "description": "Costruisci la tua conoscenza personale con potenti funzionalitĆ  e privacy totale.", + "get_started": "Inizia ora" + }, + "components": { + "link_learn_more": "Per saperne di più..." + }, + "download_now": { + "text": "Scarica ora ", + "platform_big": "v{{version}} per {{platform}}", + "platform_small": "per {{platform}}", + "linux_big": "v{{version}} per Linux", + "linux_small": "per Linux", + "more_platforms": "Più piattaforme e configurazione del server" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "Discussioni GitHub", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "support_us": { + "title": "Supportaci", + "financial_donations_title": "Donazioni pecuniarie", + "financial_donations_description": "Trilium ĆØ costruito e mantenuto con centinaia di ore di lavoro. Il tuo supporto permette di mantenerlo open-source, di migliorare le funzionalitĆ  e di coprire i costi (ad esempio dell'hosting).", + "financial_donations_cta": "Considera di supportare lo sviluppatore principale dell'applicazione (eliandoran) attraverso:", + "github_sponsors": "Sponsor GitHub", + "paypal": "PayPal", + "buy_me_a_coffee": "Offrimi un caffĆØ" + }, + "footer": { + "copyright_community": "comunitĆ ", + "copyright_and_the": " e il " + }, + "contribute": { + "title": "Altre possibilitĆ  di contribuzione", + "way_translate": "Traduci l'applicazione nella tua madrelingua su Weblate.", + "way_community": "Interagisci con la comunitĆ  su GitHub Discussions o su Matrix.", + "way_reports": "Segnalare i bug tramite GitHub issues.", + "way_document": "Migliora la documentazione segnalandoci eventuali lacune o contribuendo con guide, domande frequenti o tutorial.", + "way_market": "Spargi la voce: condividi Trilium Notes con gli amici, sui blog e sui social media." + }, + "404": { + "title": "404: Non trovato", + "description": "La pagina che stavi cercando non ĆØ stata trovata. Forse ĆØ stata cancellata o l'URL non ĆØ corretto." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64-bit", + "title_arm64": "Windows on ARM", + "description_x64": "Compatibile con dispositivi Intel o AMD con sistema operativo Windows 10 e 11.", + "description_arm64": "Compatibile con dispositivi ARM (ad esempio con Qualcomm Snapdragon).", + "quick_start": "Per installare tramite Winget:", + "download_exe": "Scarica il programma di installazione (.exe)", + "download_zip": "Portatile (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64-bit", + "title_arm64": "Linux on ARM", + "description_x64": "Per la maggior parte delle distribuzioni Linux, compatibile con l'architettura x86_64.", + "description_arm64": "Per distribuzioni Linux basate su ARM, compatibili con l'architettura aarch64.", + "quick_start": "Seleziona un formato pacchetto appropriato, a seconda della tua distribuzione:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "Portatile (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS per Intel", + "title_arm64": "macOS per Apple Silicon", + "description_x64": "Per Mac basati su Intel con macOS Monterey o versioni successive.", + "description_arm64": "Per i Mac Apple Silicon, come quelli con chip M1 e M2.", + "quick_start": "Per installare tramite Homebrew:", + "download_dmg": "Scarica il programma di installazione (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "Portatile (.zip)" + }, + "download_helper_server_docker": { + "title": "Self-hosted utilizzando Docker", + "description": "Facile da implementare su Windows, Linux o macOS utilizzando un container Docker.", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "Self-hosted utilizzando Linux", + "description": "Distribuisci Trilium Notes sul tuo server o VPS, compatibile con la maggior parte delle distribuzioni.", + "download_nixos": "Modulo NixOS", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)" + }, + "download_helper_server_hosted": { + "title": "Hosting a pagamento", + "description": "Trilium Notes ĆØ ospitato su PikaPods, un servizio a pagamento che consente un facile accesso e una semplice gestione. Non ĆØ direttamente affiliato al team Trilium.", + "download_pikapod": "Configurazione su PikaPods", + "download_triliumcc": "In alternativa, consultare trilium.cc" + }, + "header": { + "get-started": "Inizia", + "documentation": "Documentazione", + "support-us": "Sostienici", + "resources": "Risorse" + }, + "resources": { + "title": "Risorse", + "icon_packs": "Pacchetti di icone", + "icon_packs_intro": "Ampliate la selezione di icone disponibili per le vostre note utilizzando un pacchetto di icone. Per ulteriori informazioni sui pacchetti di icone, consultate la documentazione ufficiale.", + "download": "Scarica", + "website": "Sito web" + } +} diff --git a/apps/website/src/translations/ja/translation.json b/apps/website/src/translations/ja/translation.json new file mode 100644 index 0000000000..68289aabd2 --- /dev/null +++ b/apps/website/src/translations/ja/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "title": "ćÆć˜ć‚ć‚‹", + "desktop_title": "ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ (v{{version}})", + "architecture": "ć‚¢ćƒ¼ć‚­ćƒ†ć‚Æćƒćƒ£:", + "older_releases": "ä»„å‰ć®ćƒŖćƒŖćƒ¼ć‚¹ć‚’č¦‹ć‚‹", + "server_title": "č¤‡ę•°ć®ćƒ‡ćƒć‚¤ć‚¹ć‹ć‚‰ć‚¢ć‚Æć‚»ć‚¹ć§ćć‚‹ć‚ˆć†ć«ć‚µćƒ¼ćƒćƒ¼ć‚’čØ­å®šć™ć‚‹" + }, + "hero_section": { + "title": "ę€č€ƒć‚’ę•“ē†ć—ć€č‡Ŗåˆ†ć ć‘ć®ēŸ„č­˜ćƒ™ćƒ¼ć‚¹ć‚’ę§‹ēÆ‰ć—ć¾ć—ć‚‡ć†ć€‚", + "subtitle": "TriliumćÆć€ćƒŽćƒ¼ćƒˆä½œęˆćØå€‹äŗŗć®ćƒŠćƒ¬ćƒƒć‚øćƒ™ćƒ¼ć‚¹ć®ę•“ē†ć«å½¹ē«‹ć¤ć‚Ŗćƒ¼ćƒ—ćƒ³ć‚½ćƒ¼ć‚¹ć‚½ćƒŖćƒ„ćƒ¼ć‚·ćƒ§ćƒ³ć§ć™ć€‚ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć§ćƒ­ćƒ¼ć‚«ćƒ«ć§ä½æē”Øć™ć‚‹ć“ćØć‚‚ć€ć‚»ćƒ«ćƒ•ćƒ›ć‚¹ćƒˆć‚µćƒ¼ćƒćƒ¼ćØåŒęœŸć—ć¦ć©ć“ć«ć„ć¦ć‚‚ćƒŽćƒ¼ćƒˆć‚’äæå­˜ć™ć‚‹ć“ćØć‚‚ć§ćć¾ć™ć€‚", + "get_started": "ćÆć˜ć‚ć‚‹", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Trilium Notes ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć®ć‚¹ć‚ÆćƒŖćƒ¼ćƒ³ć‚·ćƒ§ćƒƒćƒˆ" + }, + "organization_benefits": { + "title": "組織", + "note_structure_title": "ćƒŽćƒ¼ćƒˆć®ę§‹é€ ", + "note_structure_description": "ćƒŽćƒ¼ćƒˆćÆéšŽå±¤ēš„ć«ę•“ē†ć§ćć¾ć™ć€‚å„ćƒŽćƒ¼ćƒˆć«ć‚µćƒ–ćƒŽćƒ¼ćƒˆć‚’ä½œęˆć§ćć‚‹ćŸć‚ć€ćƒ•ć‚©ćƒ«ćƒ€ćÆåæ…č¦ć‚ć‚Šć¾ć›ć‚“ć€‚1ć¤ć®ćƒŽćƒ¼ćƒˆć‚’éšŽå±¤å†…ć®č¤‡ę•°ć®å “ę‰€ć«čæ½åŠ ć§ćć¾ć™ć€‚", + "attributes_title": "ćƒŽćƒ¼ćƒˆć®ćƒ©ćƒ™ćƒ«ćØćƒŖćƒ¬ćƒ¼ć‚·ćƒ§ćƒ³", + "attributes_description": "ćƒŽćƒ¼ćƒˆé–“ć®ćƒŖćƒ¬ćƒ¼ć‚·ćƒ§ćƒ³ć‚·ćƒƒćƒ—ć‚’ä½æē”Øć—ćŸć‚Šć€ćƒ©ćƒ™ćƒ«ć‚’čæ½åŠ ć—ćŸć‚Šć™ć‚‹ć“ćØć§ć€ē°”å˜ć«åˆ†é”žć§ćć¾ć™ć€‚ćƒ—ćƒ­ćƒ¢ćƒ¼ćƒˆå±žę€§ć‚’ä½æē”Øć—ć¦ć€č”Øć‚„ćƒœćƒ¼ćƒ‰ć§ä½æē”Øć§ćć‚‹ę§‹é€ åŒ–ć•ć‚ŒćŸęƒ…å ±ć‚’å…„åŠ›ć§ćć¾ć™ć€‚", + "hoisting_title": "ćƒÆćƒ¼ć‚Æć‚¹ćƒšćƒ¼ć‚¹ćØćƒ›ć‚¤ć‚¹ćƒˆ", + "hoisting_description": "ćƒÆćƒ¼ć‚Æć‚¹ćƒšćƒ¼ć‚¹ć®äø‹ć«ć‚°ćƒ«ćƒ¼ćƒ—åŒ–ć™ć‚‹ć“ćØć§ć€å€‹äŗŗē”ØćƒŽćƒ¼ćƒˆćØä»•äŗ‹ē”ØćƒŽćƒ¼ćƒˆć‚’ē°”å˜ć«åŒŗåˆ„ć§ćć¾ć™ć€‚ć“ć‚Œć«ć‚ˆć‚Šć€ćƒŽćƒ¼ćƒˆćƒ„ćƒŖćƒ¼ć«ē‰¹å®šć®ćƒŽćƒ¼ćƒˆć‚»ćƒƒćƒˆć®ćæćŒč”Øē¤ŗć•ć‚Œć‚‹ć‚ˆć†ć«ćŖć‚Šć¾ć™ć€‚" + }, + "productivity_benefits": { + "title": "ē”Ÿē”£ę€§ćØå®‰å…Øę€§", + "revisions_title": "ćƒŽćƒ¼ćƒˆć®å¤‰ę›“å±„ę­“", + "revisions_content": "ćƒŽćƒ¼ćƒˆćÆå®šęœŸēš„ć«ćƒćƒƒć‚Æć‚°ćƒ©ć‚¦ćƒ³ćƒ‰ć§äæå­˜ć•ć‚Œć€å¤‰ę›“å±„ę­“ćÆē¢ŗčŖć‚„čŖ¤ć£ć¦å¤‰ę›“ć—ć¦ć—ć¾ć£ćŸéƒØåˆ†ć‚’å…ƒć«ęˆ»ć™ćŸć‚ć«ä½æē”Øć§ćć¾ć™ć€‚ć¾ćŸć€å¤‰ę›“å±„ę­“ćÆć„ć¤ć§ć‚‚ä½œęˆć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚", + "sync_title": "同期", + "sync_content": "ć‚»ćƒ«ćƒ•ćƒ›ć‚¹ćƒˆåž‹ć¾ćŸćÆć‚Æćƒ©ć‚¦ćƒ‰ ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć‚’ä½æē”Øć™ć‚‹ćØć€č¤‡ę•°ć®ćƒ‡ćƒć‚¤ć‚¹é–“ć§ćƒŽćƒ¼ćƒˆć‚’ē°”å˜ć«åŒęœŸć—ć€PWA ć‚’ä½æē”Øć—ć¦ćƒ¢ćƒć‚¤ćƒ«ć‹ć‚‰ć‚¢ć‚Æć‚»ć‚¹ć§ćć¾ć™ć€‚", + "protected_notes_title": "äæč­·ć•ć‚ŒćŸćƒŽćƒ¼ćƒˆ", + "protected_notes_content": "ćƒŽćƒ¼ćƒˆć‚’ęš—å·åŒ–ć—ć€ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć§äæč­·ć•ć‚ŒćŸć‚»ćƒƒć‚·ćƒ§ćƒ³ć§ćƒ­ćƒƒć‚Æć™ć‚‹ć“ćØć§ć€ę©ŸåÆ†ę€§ć®é«˜ć„å€‹äŗŗęƒ…å ±ć‚’äæč­·ć—ć¾ć™ć€‚", + "jump_to_title": "ć‚Æć‚¤ćƒƒć‚Æę¤œē“¢ćØć‚³ćƒžćƒ³ćƒ‰", + "jump_to_content": "ć‚ć„ć¾ć„äø€č‡“ć«ć‚ˆć‚Šć‚æć‚¤ćƒ—ćƒŸć‚¹ć‚„ć‚ćšć‹ćŖé•ć„ć‚’č€ƒę…®ć—ćŖćŒć‚‰ć‚æć‚¤ćƒˆćƒ«ć‚’ę¤œē“¢ć™ć‚‹ć“ćØć§ć€éšŽå±¤å…Øä½“ć®ćƒŽćƒ¼ćƒˆć‚„ UI ć‚³ćƒžćƒ³ćƒ‰ć«ć™ć°ć‚„ćć‚øćƒ£ćƒ³ćƒ—ć§ćć¾ć™ć€‚", + "search_title": "å¼·åŠ›ćŖę¤œē“¢", + "search_content": "ćƒŽćƒ¼ćƒˆå†…ć®ćƒ†ć‚­ć‚¹ćƒˆć‚’ę¤œē“¢ć—ć€č¦ŖćƒŽćƒ¼ćƒˆć‚„éšŽå±¤ć®ę·±åŗ¦ć§ćƒ•ć‚£ćƒ«ć‚æćƒŖćƒ³ć‚°ć—ć¦ę¤œē“¢ć‚’ēµžć‚Šč¾¼ć‚€ć“ćØć‚‚ć§ćć¾ć™ć€‚", + "web_clipper_title": "Web ć‚ÆćƒŖćƒƒćƒ‘ćƒ¼", + "web_clipper_content": "web ć‚ÆćƒŖćƒƒćƒ‘ćƒ¼ ćƒ–ćƒ©ć‚¦ć‚¶ę‹”å¼µę©Ÿčƒ½ć‚’ä½æē”Øć—ć¦ć€web ćƒšćƒ¼ć‚ø (ć¾ćŸćÆć‚¹ć‚ÆćƒŖćƒ¼ćƒ³ć‚·ćƒ§ćƒƒćƒˆ) ć‚’å–å¾—ć—ć€Trilium ć«ē›“ęŽ„é…ē½®ć—ć¾ć™ć€‚" + }, + "note_types": { + "text_title": "ćƒ†ć‚­ć‚¹ćƒˆćƒŽćƒ¼ćƒˆ", + "text_description": "ćƒŽćƒ¼ćƒˆćÆćƒ“ć‚øćƒ„ć‚¢ćƒ«ļ¼ˆWYSIWYGļ¼‰ć‚Øćƒ‡ć‚£ć‚æćƒ¼ć§ē·Øé›†ć§ćć¾ć™ć€‚č”Øć€ē”»åƒć€ę•°å¼ć€ę§‹ę–‡ćƒć‚¤ćƒ©ć‚¤ćƒˆä»˜ćć®ć‚³ćƒ¼ćƒ‰ćƒ–ćƒ­ćƒƒć‚ÆćŖć©ć€ę§˜ć€…ćŖē·Øé›†ę©Ÿčƒ½ć‚’å‚™ćˆć¦ć„ć¾ć™ć€‚Markdownć®ć‚ˆć†ćŖę§‹ę–‡ć‚„ć‚¹ćƒ©ćƒƒć‚·ćƒ„ć‚³ćƒžćƒ³ćƒ‰ć‚’ä½æć£ć¦ć€ćƒ†ć‚­ć‚¹ćƒˆć‚’ē“ ę—©ććƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆć§ćć¾ć™ć€‚", + "code_title": "Code ćƒŽćƒ¼ćƒˆ", + "code_description": "ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ć‚„ć‚¹ć‚ÆćƒŖćƒ—ćƒˆć®å¤§ććŖć‚µćƒ³ćƒ—ćƒ«ć§ćÆć€å¤šćć®ćƒ—ćƒ­ć‚°ćƒ©ćƒŸćƒ³ć‚°čØ€čŖžć®ę§‹ę–‡ćƒć‚¤ćƒ©ć‚¤ćƒˆč”Øē¤ŗćØć•ć¾ć–ć¾ćŖć‚«ćƒ©ćƒ¼ ćƒ†ćƒ¼ćƒžć‚’å‚™ćˆćŸå°‚ē”Øć®ć‚Øćƒ‡ć‚£ć‚æćƒ¼ćŒä½æē”Øć§ćć¾ć™ć€‚", + "file_title": "ćƒ•ć‚”ć‚¤ćƒ«ćƒŽćƒ¼ćƒˆ", + "file_description": "PDFć€ē”»åƒć€ćƒ“ćƒ‡ć‚ŖćŖć©ć®ćƒžćƒ«ćƒćƒ”ćƒ‡ć‚£ć‚¢ ćƒ•ć‚”ć‚¤ćƒ«ć‚’ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³å†…ć«ćƒ—ćƒ¬ćƒ“ćƒ„ćƒ¼č”Øē¤ŗć§åŸ‹ć‚č¾¼ćæć¾ć™ć€‚", + "canvas_title": "ć‚­ćƒ£ćƒ³ćƒć‚¹", + "canvas_description": "excalidraw.comćØåŒć˜ęŠ€č”“ć‚’ä½æć£ć¦ć€ē„”é™ć®ć‚­ćƒ£ćƒ³ćƒć‚¹ć«å›³å½¢ć€ē”»åƒć€ćƒ†ć‚­ć‚¹ćƒˆć‚’é…ē½®ć§ćć¾ć™ć€‚å›³č”Øć€ć‚¹ć‚±ćƒƒćƒć€ćƒ“ć‚øćƒ„ć‚¢ćƒ«ćƒ—ćƒ©ćƒ³ćƒ‹ćƒ³ć‚°ć«ęœ€é©ć§ć™ć€‚", + "mermaid_title": "ćƒžćƒ¼ćƒ”ć‚¤ćƒ‰å›³", + "mermaid_description": "ćƒžćƒ¼ćƒ”ć‚¤ćƒ‰ę§‹ę–‡ć‚’ä½æē”Øć—ć¦ć€ćƒ•ćƒ­ćƒ¼ćƒćƒ£ćƒ¼ćƒˆć€ć‚Æćƒ©ć‚¹å›³ć€ć‚·ćƒ¼ć‚±ćƒ³ć‚¹å›³ć€ć‚¬ćƒ³ćƒˆ ćƒćƒ£ćƒ¼ćƒˆćŖć©ć®å›³ć‚’ä½œęˆć—ć¾ć™ć€‚", + "mindmap_title": "ćƒžć‚¤ćƒ³ćƒ‰ćƒžćƒƒćƒ—", + "mindmap_description": "č€ƒćˆć‚’č¦–č¦šēš„ć«ę•“ē†ć—ćŸć‚Šć€ćƒ–ćƒ¬ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒŸćƒ³ć‚° ć‚»ćƒƒć‚·ćƒ§ćƒ³ć‚’č”Œć£ćŸć‚Šć—ć¾ć™ć€‚", + "others_list": "ćć®ä»–: <0>ćƒŽćƒ¼ćƒˆćƒžćƒƒćƒ—ć€<1>ćƒŖćƒ¬ćƒ¼ć‚·ćƒ§ćƒ³ćƒžćƒƒćƒ—ć€<2>äæå­˜ć•ć‚ŒćŸę¤œē“¢ć€<3>ćƒ¬ćƒ³ćƒ€ćƒŖćƒ³ć‚°ćƒŽćƒ¼ćƒˆć€<4>web ćƒ“ćƒ„ćƒ¼ć€‚", + "title": "ęƒ…å ±ć‚’č”Øē¾ć™ć‚‹ćŸć‚ć®č¤‡ę•°ć®ę–¹ę³•" + }, + "extensibility_benefits": { + "title": "å…±ęœ‰ćØę‹”å¼µę€§", + "import_export_title": "ć‚¤ćƒ³ćƒćƒ¼ćƒˆ / ć‚Øć‚Æć‚¹ćƒćƒ¼ćƒˆ", + "import_export_description": "Markdown态ENEX态OML å½¢å¼ć‚’ä½æē”Øć—ć¦ä»–ć®ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ćØē°”å˜ć«é€£ęŗć§ćć¾ć™ć€‚", + "share_title": "web äøŠć§ćƒŽćƒ¼ćƒˆć‚’å…±ęœ‰", + "share_description": "ć‚µćƒ¼ćƒćƒ¼ć‚’ćŠęŒć”ć®å “åˆćÆć€ćć‚Œć‚’ä½æē”Øć—ć¦ćƒŽćƒ¼ćƒˆć®äø€éƒØć‚’ä»–ć®äŗŗćØå…±ęœ‰ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚", + "scripting_title": "é«˜åŗ¦ćŖć‚¹ć‚ÆćƒŖćƒ—ćƒˆ", + "scripting_description": "ć‚«ć‚¹ć‚æćƒ ć‚¦ć‚£ć‚øć‚§ćƒƒćƒˆć¾ćŸćÆć‚µćƒ¼ćƒćƒ¼å“ć®ćƒ­ć‚øćƒƒć‚Æć‚’ä½æē”Øć—ć¦ć€Trilium å†…ć§ē‹¬č‡Ŗć®ēµ±åˆę©Ÿčƒ½ć‚’ę§‹ēÆ‰ć§ćć¾ć™ć€‚", + "api_title": "REST API", + "api_description": "組み込みの REST API ć‚’ä½æē”Øć—ć¦ć€ćƒ—ćƒ­ć‚°ćƒ©ćƒ ć§ Trilium と対話します。" + }, + "collections": { + "calendar_title": "ć‚«ćƒ¬ćƒ³ćƒ€ćƒ¼", + "calendar_description": "ć‚«ćƒ¬ćƒ³ćƒ€ćƒ¼ć‚’ä½æć£ć¦ć€å€‹äŗŗēš„ćŖäŗˆå®šć‚„ä»•äŗ‹äøŠć®äŗˆå®šć‚’ē®”ē†ć—ć¾ć—ć‚‡ć†ć€‚ēµ‚ę—„ć‚¤ćƒ™ćƒ³ćƒˆćØč¤‡ę•°ę—„ć‚¤ćƒ™ćƒ³ćƒˆć«åÆ¾åæœć—ć¦ć„ć¾ć™ć€‚é€±ć€ęœˆć€å¹“č”Øē¤ŗć§ć‚¤ćƒ™ćƒ³ćƒˆć‚’äø€ē›®ć§ē¢ŗčŖć§ćć¾ć™ć€‚ć‚¤ćƒ™ćƒ³ćƒˆć®čæ½åŠ ć‚„ćƒ‰ćƒ©ćƒƒć‚°ę“ä½œć§ē°”å˜ć«č”Œćˆć¾ć™ć€‚", + "table_title": "ćƒ†ćƒ¼ćƒ–ćƒ«", + "table_description": "ćƒŽćƒ¼ćƒˆć«é–¢ć™ć‚‹ęƒ…å ±ć‚’č”Øå½¢å¼ć§č”Øē¤ŗćƒ»ē·Øé›†ć§ćć¾ć™ć€‚ćƒ†ć‚­ć‚¹ćƒˆć€ę•°å€¤ć€ćƒć‚§ćƒƒć‚Æćƒœćƒƒć‚Æć‚¹ć€ę—„ę™‚ć€ćƒŖćƒ³ć‚Æć€č‰²ćŖć©ć€ę§˜ć€…ćŖåˆ—ć‚æć‚¤ćƒ—ć«åÆ¾åæœć—ć€ćƒŖćƒ¬ćƒ¼ć‚·ćƒ§ćƒ³ć‚‚ć‚µćƒćƒ¼ćƒˆć—ć¦ć„ć¾ć™ć€‚ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć€ćƒŽćƒ¼ćƒˆć‚’č”Øå†…ć®ćƒ„ćƒŖćƒ¼éšŽå±¤ć«č”Øē¤ŗć™ć‚‹ć“ćØć‚‚ć§ćć¾ć™ć€‚", + "board_title": "ć‚«ćƒ³ćƒćƒ³ćƒœćƒ¼ćƒ‰", + "board_description": "ę–°ć—ć„é …ē›®ć‚„åˆ—ć‚’ē°”å˜ć«ä½œęˆć—ć€ćƒœćƒ¼ćƒ‰äøŠć§ćƒ‰ćƒ©ćƒƒć‚°ć™ć‚‹ć ć‘ć§ć‚¹ćƒ†ćƒ¼ć‚æć‚¹ć‚’å¤‰ę›“ć§ćć‚‹ć‚«ćƒ³ćƒćƒ³ ćƒœćƒ¼ćƒ‰ć§ć€ć‚æć‚¹ć‚Æć‚„ćƒ—ćƒ­ć‚øć‚§ć‚Æćƒˆć®ć‚¹ćƒ†ćƒ¼ć‚æć‚¹ć‚’ę•“ē†ć§ćć¾ć™ć€‚", + "geomap_title": "ć‚øć‚Ŗćƒžćƒƒćƒ—", + "geomap_description": "ć‚«ć‚¹ć‚æćƒžć‚¤ć‚ŗåÆčƒ½ćŖćƒžćƒ¼ć‚«ćƒ¼ć‚’ä½æć£ć¦ć€ä¼‘ęš‡ć‚’čØˆē”»ć—ćŸć‚Šć€čˆˆå‘³ć®ć‚ć‚‹å “ę‰€ć‚’åœ°å›³äøŠć«ē›“ęŽ„ćƒžćƒ¼ć‚Æć—ćŸć‚Šć§ćć¾ć™ć€‚čØ˜éŒ²ć•ć‚ŒćŸGPXćƒˆćƒ©ćƒƒć‚Æć‚’č”Øē¤ŗć—ć¦ć€ę—…ēØ‹ć‚’čæ½č·”ć§ćć¾ć™ć€‚", + "title": "ć‚³ćƒ¬ć‚Æć‚·ćƒ§ćƒ³", + "presentation_title": "ćƒ—ćƒ¬ć‚¼ćƒ³ćƒ†ćƒ¼ć‚·ćƒ§ćƒ³", + "presentation_description": "ęƒ…å ±ć‚’ć‚¹ćƒ©ć‚¤ćƒ‰ć«ę•“ē†ć—ć€ć‚¹ćƒ ćƒ¼ć‚ŗćŖé·ē§»ć§å…Øē”»é¢č”Øē¤ŗć§ćć¾ć™ć€‚ć‚¹ćƒ©ć‚¤ćƒ‰ćÆPDFć«ć‚Øć‚Æć‚¹ćƒćƒ¼ćƒˆć§ćć‚‹ć®ć§ć€ē°”å˜ć«å…±ęœ‰ć§ćć¾ć™ć€‚" + }, + "faq": { + "title": "ć‚ˆćć‚ć‚‹č³Ŗå•", + "mobile_question": "ćƒ¢ćƒć‚¤ćƒ«ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ćÆć‚ć‚Šć¾ć™ć‹ļ¼Ÿ", + "mobile_answer": "ē¾åœØć€å…¬å¼ćƒ¢ćƒć‚¤ćƒ«ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ćÆć‚ć‚Šć¾ć›ć‚“ć€‚ćŸć ć—ć€ć‚µćƒ¼ćƒćƒ¼ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć‚’ćŠęŒć”ć®å “åˆćÆć€web ćƒ–ćƒ©ć‚¦ć‚¶ć‹ć‚‰ć‚¢ć‚Æć‚»ć‚¹ć§ćć€PWAćØć—ć¦ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć™ć‚‹ć“ćØć‚‚ć§ćć¾ć™ć€‚Android å‘ć‘ć«ćÆć€ć‚Ŗćƒ•ćƒ©ć‚¤ćƒ³ć§ć‚‚å‹•ä½œć™ć‚‹ TriliumDroid ćØć„ć†éžå…¬å¼ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ćŒć‚ć‚Šć¾ć™ļ¼ˆćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć‚Æćƒ©ć‚¤ć‚¢ćƒ³ćƒˆćØåŒę§˜ć§ć™ļ¼‰ć€‚", + "database_question": "ćƒ‡ćƒ¼ć‚æćÆć©ć“ć«äæå­˜ć•ć‚Œć¾ć™ć‹ļ¼Ÿ", + "database_answer": "ć™ć¹ć¦ć®ćƒŽćƒ¼ćƒˆćÆć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ćƒ•ć‚©ćƒ«ćƒ€å†…ć® SQLite ćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ć«äæå­˜ć•ć‚Œć¾ć™ć€‚Trilium ćŒćƒ—ćƒ¬ćƒ¼ćƒ³ćƒ†ć‚­ć‚¹ćƒˆćƒ•ć‚”ć‚¤ćƒ«ć§ćÆćŖććƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ć‚’ä½æē”Øć™ć‚‹ē†ē”±ćÆć€ćƒ‘ćƒ•ć‚©ćƒ¼ćƒžćƒ³ć‚¹ćØć€ć‚Æćƒ­ćƒ¼ćƒ³ļ¼ˆćƒ„ćƒŖćƒ¼å†…ć®č¤‡ę•°ć®å “ę‰€ć«åŒć˜ćƒŽćƒ¼ćƒˆćŒå­˜åœØć™ć‚‹ēŠ¶ę…‹ļ¼‰ćŖć©ć®äø€éƒØć®ę©Ÿčƒ½ć®å®Ÿč£…ćŒćÆć‚‹ć‹ć«å›°é›£ć«ćŖć‚‹ć‹ć‚‰ć§ć™ć€‚ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ćƒ•ć‚©ćƒ«ćƒ€ć‚’č¦‹ć¤ć‘ć‚‹ć«ćÆć€ć€ŒAboutć€ć‚¦ć‚£ćƒ³ćƒ‰ć‚¦ć‚’é–‹ć„ć¦ćć ć•ć„ć€‚", + "server_question": "Trilium ć‚’ä½æē”Øć™ć‚‹ć«ćÆć‚µćƒ¼ćƒćƒ¼ćŒåæ…č¦ć§ć™ć‹ļ¼Ÿ", + "server_answer": "ć„ć„ćˆć€ć‚µćƒ¼ćƒćƒ¼ćÆ web ćƒ–ćƒ©ć‚¦ć‚¶ēµŒē”±ć§ć‚¢ć‚Æć‚»ć‚¹ć‚’čØ±åÆć—ć€č¤‡ę•°ć®ćƒ‡ćƒć‚¤ć‚¹ćŒć‚ć‚‹å “åˆć®åŒęœŸć‚’ē®”ē†ć—ć¾ć™ć€‚ä½æć„ćÆć˜ć‚ć‚‹ć«ćÆć€ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ć—ć¦ä½æć„ćÆć˜ć‚ć‚‹ć ć‘ć§ååˆ†ć§ć™ć€‚", + "scaling_question": "ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ćÆå¤§é‡ć®ćƒŽćƒ¼ćƒˆć«åÆ¾ć—ć¦ć©ć®ēØ‹åŗ¦ę‹”å¼µć§ćć¾ć™ć‹ļ¼Ÿ", + "scaling_answer": "ä½æē”ØēŠ¶ę³ć«ć‚‚ć‚ˆć‚Šć¾ć™ćŒć€ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ćÆå°‘ćŖććØć‚‚10äø‡ä»¶ć®ćƒŽćƒ¼ćƒˆć‚’å•é”ŒćŖćå‡¦ē†ć§ćć‚‹ćÆćšć§ć™ć€‚ćŸć ć—ć€Trilium ćÆćƒ•ć‚”ć‚¤ćƒ«ć‚¹ćƒˆć‚¢ļ¼ˆä¾‹ćˆć° NextCloudļ¼‰ć§ćÆćŖćć€ćƒŠćƒ¬ćƒƒć‚øćƒ™ćƒ¼ć‚¹ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ćØć—ć¦čØ­čØˆć•ć‚Œć¦ć„ć‚‹ćŸć‚ć€å¤§å®¹é‡ćƒ•ć‚”ć‚¤ćƒ«ļ¼ˆ1 ćƒ•ć‚”ć‚¤ćƒ«ć‚ćŸć‚Š 1GBļ¼‰ć‚’å¤šę•°ć‚¢ćƒƒćƒ—ćƒ­ćƒ¼ćƒ‰ć™ć‚‹ćØåŒęœŸćƒ—ćƒ­ć‚»ć‚¹ćŒå¤±ę•—ć™ć‚‹å “åˆćŒć‚ć‚‹ć“ćØć«ć”ę³Øę„ćć ć•ć„ć€‚", + "network_share_question": "ćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ć‚’ćƒćƒƒćƒˆćƒÆćƒ¼ć‚Æćƒ‰ćƒ©ć‚¤ćƒ–ēµŒē”±ć§å…±ęœ‰ć§ćć¾ć™ć‹ļ¼Ÿ", + "network_share_answer": "ć„ć„ćˆć€äø€čˆ¬ēš„ć« SQLite ćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ć‚’ćƒćƒƒćƒˆćƒÆćƒ¼ć‚Æćƒ‰ćƒ©ć‚¤ćƒ–ēµŒē”±ć§å…±ęœ‰ć™ć‚‹ć®ćÆćŠå‹§ć‚ć§ćć¾ć›ć‚“ć€‚å “åˆć«ć‚ˆć£ć¦ćÆå‹•ä½œć™ć‚‹ć“ćØć‚‚ć‚ć‚Šć¾ć™ćŒć€ćƒćƒƒćƒˆćƒÆćƒ¼ć‚ÆēµŒē”±ć®ćƒ•ć‚”ć‚¤ćƒ«ćƒ­ćƒƒć‚ÆćŒäøå®Œå…Øć§ć‚ć‚‹ćŸć‚ć€ćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ćŒē “ęć™ć‚‹åÆčƒ½ę€§ćŒć‚ć‚Šćˆć¾ć™ć€‚", + "security_question": "ćƒ‡ćƒ¼ć‚æćÆć©ć®ć‚ˆć†ć«äæč­·ć•ć‚Œć¾ć™ć‹ļ¼Ÿ", + "security_answer": "ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ćÆćƒŽćƒ¼ćƒˆćÆęš—å·åŒ–ć•ć‚Œć¦ćŠć‚‰ćšć€ćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ć‹ć‚‰ē›“ęŽ„čŖ­ćæå–ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ćƒŽćƒ¼ćƒˆćŒęš—å·åŒ–ęøˆćæćØć—ć¦ćƒžćƒ¼ć‚Æć•ć‚Œć‚‹ćØć€AES-128-CBC ć‚’ä½æē”Øć—ć¦ęš—å·åŒ–ć•ć‚Œć¾ć™ć€‚" + }, + "final_cta": { + "title": "Trilium Notes ć‚’ä½æć„ćÆć˜ć‚ć‚‹ęŗ–å‚™ćÆć§ćć¾ć—ćŸć‹ļ¼Ÿ", + "description": "å¼·åŠ›ćŖę©Ÿčƒ½ćØå®Œå…ØćŖćƒ—ćƒ©ć‚¤ćƒć‚·ćƒ¼ć‚’å‚™ćˆćŸå€‹äŗŗć®ēŸ„č­˜ćƒ™ćƒ¼ć‚¹ć‚’ę§‹ēÆ‰ć—ć¾ć™ć€‚", + "get_started": "ćÆć˜ć‚ć‚‹" + }, + "components": { + "link_learn_more": "ć•ć‚‰ć«č©³ć—ć..." + }, + "download_now": { + "text": "ä»Šć™ććƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ ", + "platform_big": "v{{version}} for {{platform}}", + "platform_small": "for {{platform}}", + "linux_big": "v{{version}} for Linux", + "linux_small": "for Linux", + "more_platforms": "ć‚ˆć‚Šå¤šćć®ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ćØć‚µćƒ¼ćƒćƒ¼čØ­å®š" + }, + "footer": { + "copyright_and_the": " ćŠć‚ˆć³ ", + "copyright_community": "ć‚³ćƒŸćƒ„ćƒ‹ćƒ†ć‚£" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "GitHubćƒ‡ć‚£ć‚¹ć‚«ćƒƒć‚·ćƒ§ćƒ³", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "support_us": { + "title": "ē§ćŸć”ć‚’ć‚µćƒćƒ¼ćƒˆć—ć¦ćć ć•ć„", + "financial_donations_title": "č³‡é‡‘ę“åŠ©", + "financial_donations_description": "Trilium は ę•°ē™¾ę™‚é–“ć‚‚ć®ä½œę„­ ć‚’ć‹ć‘ć¦ę§‹ēÆ‰ćƒ»ē¶­ęŒć•ć‚Œć¦ć„ć¾ć™ć€‚ēš†ę§˜ć®ć”ę”Æę“ć«ć‚ˆć‚Šć€ć‚Ŗćƒ¼ćƒ—ćƒ³ć‚½ćƒ¼ć‚¹ćØć—ć¦ć®ē¶­ęŒć€ę©Ÿčƒ½ć®å‘äøŠć€ćƒ›ć‚¹ćƒ†ć‚£ćƒ³ć‚°ćŖć©ć®č²»ē”Øć‚’č³„ć†ć“ćØćŒć§ćć¾ć™ć€‚", + "financial_donations_cta": "ę¬”ć®ę–¹ę³•ć§ć€ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć®äø»ćŖé–‹ē™ŗč€… (eliandoran) ć‚’ć‚µćƒćƒ¼ćƒˆć™ć‚‹ć“ćØć‚’ę¤œčØŽć—ć¦ćć ć•ć„:", + "github_sponsors": "GitHub Sponsors", + "paypal": "PayPal", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "contribute": { + "title": "ćć®ä»–ć®č²¢ēŒ®ę–¹ę³•", + "way_translate": "Weblate ć‚’ä½æē”Øć—ć¦ć€ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ęÆå›½čŖžć«ēæ»čØ³ć—ć¦ćć ć•ć„ć€‚", + "way_community": "GitHub Discussions または Matrix ć§ć‚³ćƒŸćƒ„ćƒ‹ćƒ†ć‚£ćØäŗ¤ęµć—ć¾ć—ć‚‡ć†ć€‚", + "way_reports": "GitHub issues ć§ćƒć‚°ć‚’å ±å‘Šć—ć¦ćć ć•ć„ć€‚", + "way_document": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć®äøč¶³ć—ć¦ć„ć‚‹ē‚¹ć‚’ćŠēŸ„ć‚‰ć›ć„ćŸć ćć‹ć€ć‚¬ć‚¤ćƒ‰ć€FAQć€ćƒćƒ„ćƒ¼ćƒˆćƒŖć‚¢ćƒ«ć‚’ęŠ•ēØæć—ć¦ć€ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’ę”¹å–„ć—ć¦ćć ć•ć„ć€‚", + "way_market": "åŗƒć‚ć¾ć—ć‚‡ć†: Trilium Notes ć‚’å‹é”ć‚„ćƒ–ćƒ­ć‚°ć€ć‚½ćƒ¼ć‚·ćƒ£ćƒ«ćƒ”ćƒ‡ć‚£ć‚¢ć§å…±ęœ‰ć—ć¾ć—ć‚‡ć†ć€‚" + }, + "404": { + "title": "404: Not Found", + "description": "ćŠęŽ¢ć—ć®ćƒšćƒ¼ć‚øćÆč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“ć§ć—ćŸć€‚å‰Šé™¤ć•ć‚ŒćŸć‹ć€URLćŒé–“é•ć£ć¦ć„ć‚‹åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚" + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64-bit", + "title_arm64": "Windows on ARM", + "description_x64": "Windows 10 ćŠć‚ˆć³ 11 ć‚’å®Ÿč”Œć—ć¦ć„ć‚‹ Intel または AMD ćƒ‡ćƒć‚¤ć‚¹ćØäŗ’ę›ę€§ćŒć‚ć‚Šć¾ć™ć€‚", + "description_arm64": "ARM ćƒ‡ćƒć‚¤ć‚¹ (例 Qualcomm Snapdragon など) ćØäŗ’ę›ę€§ćŒć‚ć‚Šć¾ć™ć€‚", + "quick_start": "Winget ēµŒē”±ć§ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć™ć‚‹ć«ćÆ:", + "download_exe": "ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ©ćƒ¼ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ (.exe)", + "download_zip": "ćƒćƒ¼ć‚æćƒ–ćƒ« (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64-bit", + "title_arm64": "Linux on ARM", + "description_x64": "ほとんどの Linux ćƒ‡ć‚£ć‚¹ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚·ćƒ§ćƒ³ć§ćÆć€x86_64 ć‚¢ćƒ¼ć‚­ćƒ†ć‚Æćƒćƒ£ćØäŗ’ę›ę€§ćŒć‚ć‚Šć¾ć™ć€‚", + "description_arm64": "ARM ćƒ™ćƒ¼ć‚¹ć® Linux ćƒ‡ć‚£ć‚¹ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚·ćƒ§ćƒ³ć®å “åˆć€aarch64 ć‚¢ćƒ¼ć‚­ćƒ†ć‚Æćƒćƒ£ćØäŗ’ę›ę€§ćŒć‚ć‚Šć¾ć™ć€‚", + "quick_start": "ćƒ‡ć‚£ć‚¹ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚·ćƒ§ćƒ³ć«åæœć˜ć¦é©åˆ‡ćŖćƒ‘ćƒƒć‚±ćƒ¼ć‚øå½¢å¼ć‚’éøęŠžć—ć¦ćć ć•ć„:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "ćƒćƒ¼ć‚æćƒ–ćƒ« (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "Intel 向け macOS", + "title_arm64": "Apple Silicon 向け macOS", + "description_x64": "macOS Monterey ä»„é™ć‚’å®Ÿč”Œć—ć¦ć„ć‚‹ Intel ćƒ™ćƒ¼ć‚¹ć® Mac 向け。", + "description_arm64": "M1 ćŠć‚ˆć³ M2 ćƒćƒƒćƒ—ć‚’ę­č¼‰ć—ćŸ Apple Silicon Mac 向け。", + "quick_start": "Homebrew ēµŒē”±ć§ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć™ć‚‹ć«ćÆ:", + "download_dmg": "ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ©ćƒ¼ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "ćƒćƒ¼ć‚æćƒ–ćƒ« (.zip)" + }, + "download_helper_server_docker": { + "title": "Docker ć‚’ä½æē”Øć—ćŸć‚»ćƒ«ćƒ•ćƒ›ć‚¹ćƒˆ", + "description": "Docker ć‚³ćƒ³ćƒ†ćƒŠć‚’ä½æē”Øć—ć¦ć€Windows态Linuxć€ć¾ćŸćÆ macOS ć«ē°”å˜ć«å±•é–‹ć§ćć¾ć™ć€‚", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "Linux ć§ć‚»ćƒ«ćƒ•ćƒ›ć‚¹ćƒˆ", + "description": "ć»ćØć‚“ć©ć®ćƒ‡ć‚£ć‚¹ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚·ćƒ§ćƒ³ćØäŗ’ę›ę€§ć®ć‚ć‚‹ Trilium Notes ć‚’ē‹¬č‡Ŗć®ć‚µćƒ¼ćƒćƒ¼ć€ć¾ćŸćÆ VPS ć«å±•é–‹ć§ćć¾ć™ć€‚", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "NixOS ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«" + }, + "download_helper_server_hosted": { + "title": "ęœ‰ę–™ćƒ›ć‚¹ćƒ†ć‚£ćƒ³ć‚°", + "description": "Trilium NotesćÆć€ć‚¢ć‚Æć‚»ć‚¹ćØē®”ē†ć‚’å®¹ę˜“ć«ć™ć‚‹ęœ‰ę–™ć‚µćƒ¼ćƒ“ć‚¹ PikaPods ć§ćƒ›ć‚¹ćƒˆć•ć‚Œć¦ć„ć¾ć™ć€‚Trilium ćƒćƒ¼ćƒ ćØćÆē›“ęŽ„é–¢äæ‚ć‚ć‚Šć¾ć›ć‚“ć€‚", + "download_pikapod": "PikaPods ć«ć‚»ćƒƒćƒˆć‚¢ćƒƒćƒ—ć™ć‚‹", + "download_triliumcc": "ć¾ćŸćÆć€trilium.cc ć‚’å‚ē…§ć—ć¦ćć ć•ć„" + }, + "header": { + "get-started": "ćÆć˜ć‚ć‚‹", + "documentation": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ", + "support-us": "ć‚µćƒćƒ¼ćƒˆ", + "resources": "ćƒŖć‚½ćƒ¼ć‚¹" + }, + "resources": { + "title": "ćƒŖć‚½ćƒ¼ć‚¹", + "icon_packs": "ć‚¢ć‚¤ć‚³ćƒ³ćƒ‘ćƒƒć‚Æ", + "icon_packs_intro": "ć‚¢ć‚¤ć‚³ćƒ³ćƒ‘ćƒƒć‚Æć‚’ä½æē”Øć™ć‚‹ćØć€ćƒŽćƒ¼ćƒˆć§ä½æē”Øć§ćć‚‹ć‚¢ć‚¤ć‚³ćƒ³ć®éøęŠžč‚¢ćŒåŗƒćŒć‚Šć¾ć™ć€‚ć‚¢ć‚¤ć‚³ćƒ³ćƒ‘ćƒƒć‚Æć®č©³ē“°ć«ć¤ć„ć¦ćÆć€å…¬å¼ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’ć”č¦§ćć ć•ć„ć€‚", + "download": "ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰", + "website": "Webć‚µć‚¤ćƒˆ" + } +} diff --git a/apps/website/src/translations/ko/translation.json b/apps/website/src/translations/ko/translation.json new file mode 100644 index 0000000000..8e31b1ea03 --- /dev/null +++ b/apps/website/src/translations/ko/translation.json @@ -0,0 +1,208 @@ +{ + "hero_section": { + "github": "ź¹ƒķ—ˆėøŒ", + "dockerhub": "ė„ģ»¤ ķ—ˆėøŒ", + "get_started": "ģ‹œģž‘ķ•˜źø°", + "title": "ģƒź°ģ„ ģ •ė¦¬ķ•˜ź³ , ź°œģø ģ§€ģ‹ źø°ė°˜ģ„ źµ¬ģ¶•ķ•˜ģ„øģš”.", + "subtitle": "Triliumģ€ ź°œģø ģ§€ģ‹ ė² ģ“ģŠ¤ė„¼ ģ •ė¦¬ķ•˜ź³  ė…øķŠøė„¼ ģž‘ģ„±ķ•˜ėŠ” ģ˜¤ķ”ˆģ†ŒģŠ¤ ģ†”ė£Øģ…˜ģž…ė‹ˆė‹¤. ė°ģŠ¤ķ¬ķ†±ģ—ģ„œ 딜컬딜 ģ‚¬ģš©ķ•˜ź±°ė‚˜, ģžģ²“ ķ˜øģŠ¤ķŒ… ģ„œė²„ģ™€ ė™źø°ķ™”ķ•˜ģ—¬ ģ–“ė””ģ—ģ„œė‚˜ ė…øķŠøė„¼ 볓꓀할 수 ģžˆģŠµė‹ˆė‹¤.", + "screenshot_alt": "Trilium Notes ė°ģŠ¤ķ¬ķ†± ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ģ˜ 스크린샷" + }, + "get-started": { + "title": "ģ‹œģž‘ķ•˜źø°", + "desktop_title": "ė°ģŠ¤ķ¬ķƒ‘ ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ 낓려받기 (v{{version}})", + "older_releases": "ģ˜¤ėž˜ėœ 릓리즈 볓기", + "architecture": "ģ•„ķ‚¤ķ…ģ³:", + "server_title": "ģ—¬ėŸ¬ źø°źø°ģ—ģ„œ ģ•”ģ„øģŠ¤ķ•  수 ģžˆėŠ” ģ„œė²„ 설정" + }, + "download_now": { + "text": "ģ§€źøˆ 낓려받기 ", + "platform_big": "{{platform}}용 v{{version}}", + "platform_small": "{{platform}}용", + "linux_big": "ė¦¬ėˆ…ģŠ¤ģš© v{{version}}", + "linux_small": "ė¦¬ėˆ…ģŠ¤ģš©", + "more_platforms": "ė” ė§Žģ€ ķ”Œėž«ķ¼ ė° ģ„œė²„ 구성" + }, + "organization_benefits": { + "title": "구성", + "note_structure_description": "ė…øķŠøėŠ” ź³„ģøµģ ģœ¼ė”œ 정리될 수 ģžˆģŠµė‹ˆė‹¤. 각 ė…øķŠøėŠ” ķ•˜ģœ„ ė…øķŠøė„¼ ķ¬ķ•Øķ•  수 ģžˆģœ¼ėÆ€ė”œ ķ“ė”ź°€ ķ•„ģš” ģ—†ģŠµė‹ˆė‹¤. ķ•˜ė‚˜ģ˜ ė…øķŠøź°€ 계층 źµ¬ģ”°ģ˜ ģ—¬ėŸ¬ ģœ„ģ¹˜ģ— 추가될 수 ģžˆģŠµė‹ˆė‹¤.", + "attributes_title": "ė…øķŠø ė¼ė²Øź³¼ ꓀계", + "attributes_description": "ģ‰¬ģš“ ė¶„ė„˜ė„¼ ģœ„ķ•“ ė…øķŠø ģ‚¬ģ“ģ˜ ꓀계넼 ģ“ģš©ķ•˜ź±°ė‚˜ ė¼ė²Øģ„ 추가할 수 ģžˆģŠµė‹ˆė‹¤. ķ…Œģ“ėø”ģ“ė‚˜ ė³“ė“œģ—ģ„œ ģ‚¬ģš©ė  수 ģžˆėŠ” źµ¬ģ”°ķ™”ėœ 정볓넼 ģž…ė „ķ•˜ė ¤ė©“ 승격된 ģ†ģ„±ģ„ ģ‚¬ģš©ķ•˜ģ„øģš”.", + "hoisting_title": "ģž‘ģ—… 공간과 ėŒģ–“ģ˜¬ė¦¬źø°", + "hoisting_description": "ģž‘ģ—… 공간에 ź°œģø ė…øķŠøģ™€ 업묓 ė…øķŠøė„¼ ź·øė£¹ķ™”ķ•˜ģ—¬ ģ‰½ź²Œ 분리할 수 ģžˆģœ¼ė©° 메모 ķŠøė¦¬ź°€ ķŠ¹ģ • 메모 ģ„øķŠøė§Œ ķ‘œģ‹œķ•˜ė„ė” ķ•  수 ģžˆģŠµė‹ˆė‹¤.", + "note_structure_title": "ė…øķŠø 구씰" + }, + "productivity_benefits": { + "title": "ģƒģ‚°ģ„±ź³¼ ģ•ˆģ „ģ„±", + "revisions_title": "ė…øķŠø ģˆ˜ģ •", + "revisions_content": "ė…øķŠøėŠ” 주기적으딜 ė°±ź·øė¼ģš“ė“œģ—ģ„œ ģ €ģž„ė˜ź³  ģˆ˜ģ • ė‚“ģš©ė“¤ģ€ ź²€ķ† ķ•˜ź±°ė‚˜ ģ‹¤ģˆ˜ė”œ ė³€ź²½ķ•œ ė‚“ģš©ģ„ ģ·Øģ†Œķ•˜ėŠ” ė° ģ‚¬ģš©ķ•  수 ģžˆģŠµė‹ˆė‹¤.ģˆ˜ģ • ė‚“ģ—­ė“¤ģ€ ķ•„ģš”ģ— ė”°ė¼ ģˆ˜ė™ģœ¼ė”œ ģƒģ„±ė  ģˆ˜ė„ ģžˆģŠµė‹ˆė‹¤.", + "sync_title": "ė™źø°ķ™”", + "sync_content": "ģžģ²“ ķ˜øģŠ¤ķŒ… ė˜ėŠ” ķ“ė¼ģš°ė“œ ģøģŠ¤ķ„“ģŠ¤ė„¼ ģ“ģš©ķ•˜ģ—¬ ģ—¬ėŸ¬ źø°źø° ģ‚¬ģ“ģ—ģ„œ ė…øķŠøė„¼ ģ‰½ź²Œ ė™źø°ķ™”ķ•˜ź³  PWA넼 통핓 ėŖØė°”ģ¼ ķ°ģ—ģ„œ 접근할 수 ģžˆģŠµė‹ˆė‹¤.", + "protected_notes_title": "볓호된 ė…øķŠø", + "protected_notes_content": "ė…øķŠøė„¼ ģ•”ķ˜øķ™”ķ•˜ź³  ė¹„ė°€ė²ˆķ˜øė”œ ė³“ķ˜øė˜ėŠ” ģ„øģ…˜ 뒤에 ģž ź¶ˆ ėÆ¼ź°ķ•œ ź°œģø 정볓넼 ė³“ķ˜øķ•˜ģ„øģš”.", + "jump_to_title": "빠넸 ź²€ģƒ‰ ė° 명령얓", + "jump_to_content": "ģ œėŖ©ģ„ ź²€ģƒ‰ķ•˜ź³  ģ˜¤ķƒ€ė‚˜ ģ•½ź°„ģ˜ ģ°Øģ“ė„¼ ģ„¤ėŖ…ķ•˜źø° ģœ„ķ•“ ķ¼ģ§€ ė§¤ģ¹­ģ„ 통핓 계층 ģ „ė°˜ģ— 걸쳐 ė…øķŠøė‚˜ UI ėŖ…ė ¹ģœ¼ė”œ 빠넓게 ģ“ė™ķ•˜ģ„øģš”.", + "search_title": "ģƒģ„ø ź²€ģƒ‰", + "search_content": "ė˜ėŠ” ė…øķŠø ė‚“ė¶€ģ—ģ„œ ė¬øģžė„¼ ź²€ģƒ‰ķ•˜ź±°ė‚˜ 부모 ė…øķŠø ė˜ėŠ” ė‹Øź³„ė³„ė”œ 필터링 ķ•˜ėŠ” 등 ź²€ģƒ‰ ė²”ģœ„ė„¼ ģ”°ģ •ķ•˜ģ„øģš”.", + "web_clipper_title": "웹 ķ“ė¦¬ķ¼", + "web_clipper_content": "웹 ķ“ė¦¬ķ¼ ķ™•ģž„ ķ”„ė”œź·øėžØģ„ ģ‚¬ģš©ķ•˜ģ—¬ 웹 ķŽ˜ģ“ģ§€(ė˜ėŠ” 스크린샷)넼 Trilium으딜 가져와 ė¬øģ„œģ— ģ‚¬ģš©ķ•˜ģ„øģš”." + }, + "header": { + "get-started": "ģ‹œģž‘ķ•˜źø°", + "documentation": "ė¬øģ„œ", + "support-us": "ķ›„ģ›ķ•˜źø°", + "resources": "ė¦¬ģ†ŒģŠ¤" + }, + "support_us": { + "financial_donations_title": "źøˆģ „ģ  źø°ė¶€", + "financial_donations_description": "Triliumģ€ ģˆ˜ė°±ģ‹œź°„ģ˜ ģž‘ģ—…ģ„ 통핓 źµ¬ģ¶•ė˜ź³  ģœ ģ§€ź“€ė¦¬ė©ė‹ˆė‹¤. ģ—¬ėŸ¬ė¶„ģ˜ ģ§€ģ›ģ€ Triliumģ„ ģ˜¤ķ”ˆģ†ŒģŠ¤ė”œ ģœ ģ§€ķ•˜ź³ , źø°ėŠ„ģ„ ź°œģ„ ķ•˜ź³ , ķ˜øģŠ¤ķŒ… ė“±ģ˜ ė¹„ģš©ģ„ ģ¶©ė‹¹ķ•©ė‹ˆė‹¤.", + "financial_donations_cta": "ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ģ˜ ģ£¼ģš” ź°œė°œģž (eliandoran)ģ„ ė‹¤ģŒ ė°©ė²•ģœ¼ė”œ ķ›„ģ›ķ•˜ėŠ” ź²ƒģ„ 고려핓 ģ£¼ģ‹­ģ‹œģ˜¤.", + "github_sponsors": "GitHub Sponsors", + "paypal": "ķŽ˜ģ“ķŒ”", + "buy_me_a_coffee": "Buy Me A Coffee", + "title": "ķ›„ģ›ķ•˜źø°" + }, + "contribute": { + "title": "기여할 수 ģžˆėŠ” 다넸 방법", + "way_translate": "Weblate넼 통핓 ģ“ ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ģ„ ė‹¹ģ‹ ģ˜ ėŖØźµ­ģ–“ė”œ ė²ˆģ—­ķ•˜ģ„øģš”.", + "way_community": "GitHub Discussionsė‚˜ Matrixģ—ģ„œ ģ»¤ė®¤ė‹ˆķ‹°ģ™€ ģ†Œķ†µķ•˜ģ„øģš”.", + "way_reports": "GitHub issues넼 통핓 버그넼 ģ œė³“ķ•˜ģ„øģš”.", + "way_document": "ė¬øģ„œģ˜ ė¶€ģ”±ķ•œ ė¶€ė¶„ģ„ ģ•Œė ¤ģ£¼ź±°ė‚˜ ź°€ģ“ė“œ, FAQ, ķŠœķ† ė¦¬ģ–¼ģ— źø°ģ—¬ķ•˜ģ—¬ ė¬øģ„œė„¼ ź°œģ„ ķ•˜ģ„øģš”.", + "way_market": "ģ†Œė¬øģ„ ė‚“ģ£¼ģ„øģš”: Trilium Notes넼 ģ¹œźµ¬ė“¤ź³¼, ķ˜¹ģ€ ėø”ė”œź·øė‚˜ SNSģ—ģ„œ ź³µģœ ķ•˜ģ„øģš”." + }, + "404": { + "title": "404: ķŽ˜ģ“ģ§€ė„¼ ģ°¾ģ„ 수 ģ—†ģŒ", + "description": "ģš”ģ²­ķ•˜ģ‹  ķŽ˜ģ“ģ§€ė„¼ ģ°¾ģ„ 수 ģ—†ģŠµė‹ˆė‹¤. 핓당 ķŽ˜ģ“ģ§€ź°€ ģ‚­ģ œė˜ģ—ˆź±°ė‚˜ URLģ“ ģž˜ėŖ»ė˜ģ—ˆģ„ 수 ģžˆģŠµė‹ˆė‹¤." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64ė¹„ķŠø", + "title_arm64": "Windows on ARM (WoA)", + "description_x64": "Windows 10 ė° 11ģ„ źµ¬ė™ķ•˜ėŠ” Intel ė˜ėŠ” AMD ģž„ģ¹˜ģ™€ ķ˜øķ™˜ė©ė‹ˆė‹¤.", + "description_arm64": "ARM ģž„ģ¹˜ģ™€ ķ˜øķ™˜ė©ė‹ˆė‹¤. (예: Qualcomm Snapdragon).", + "quick_start": "Wingetģ„ 통핓 ģ„¤ģ¹˜:", + "download_exe": "ģ„¤ģ¹˜ ķ”„ė”œź·øėžØ 낓려받기 (.exe)", + "download_zip": "ķ¬ķ„°ėø” (.zip)", + "download_scoop": "Scoop (ķŒØķ‚¤ģ§€ ź“€ė¦¬ģž)" + }, + "download_helper_desktop_linux": { + "title_x64": "ė¦¬ėˆ…ģŠ¤ 64ė¹„ķŠø", + "title_arm64": "ARM 기반 ė¦¬ėˆ…ģŠ¤", + "description_x64": "ėŒ€ė¶€ė¶„ģ˜ ė¦¬ėˆ…ģŠ¤ ė°°ķ¬ķŒģ—ģ„œ x86_64 ģ•„ķ‚¤ķ…ģ²˜ģ™€ ķ˜øķ™˜ė©ė‹ˆė‹¤.", + "description_arm64": "ARM 기반 ė¦¬ėˆ…ģŠ¤ ė°°ķ¬ķŒģ—ģ„œ aarch64 ģ•„ķ‚¤ķ…ģ²˜ģ™€ ķ˜øķ™˜ė©ė‹ˆė‹¤.", + "quick_start": "ģ‚¬ģš©ķ•˜ģ‹œėŠ” ė°°ķ¬ķŒģ— ė”°ė¼ ģ ģ ˆķ•œ ķŒØķ‚¤ģ§€ ķ˜•ģ‹ģ„ ģ„ ķƒķ•“ģ£¼ģ„øģš”:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "ķ¬ķ„°ėø” (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "note_types": { + "text_title": "ķ…ģŠ¤ķŠø ė…øķŠø", + "text_description": "ė…øķŠøėŠ” WYSIWYG ķŽøģ§‘źø°ė„¼ ģ‚¬ģš©ķ•˜ė©° ķ‘œ, ģ“ėÆøģ§€, ģˆ˜ķ•™ ķ‘œķ˜„ģ‹, 구문 ź°•ģ”° źø°ėŠ„ģ˜ ģ½”ė“œ ėø”ė”ģ„ ģ§€ģ›ķ•©ė‹ˆė‹¤. ķŠ¹ģˆ˜ė¬øģžė„¼ ģ‚¬ģš©ķ•œ ė§ˆķ¬ė‹¤ģš“ ģœ ģ‚¬ źµ¬ė¬øģ“ė‚˜ ģŠ¬ėž˜ģ‹œ(/) ėŖ…ė ¹ģœ¼ė”œ ķ…ģŠ¤ķŠø ģ„œģ‹ģ„ 빠넓게 지정할 수 ģžˆģŠµė‹ˆė‹¤.", + "code_title": "ģ½”ė“œ ė…øķŠø", + "title": "ė‹¹ģ‹ ģ˜ 정볓넼 ė³“ģ—¬ģ£¼ėŠ” ė‹¤ģ–‘ķ•œ 방법", + "code_description": "ėŒ€ź·œėŖØ ģ†ŒģŠ¤ ģ½”ė“œė‚˜ 스크립트 ģƒ˜ķ”Œģ€ ģ „ģš© ķŽøģ§‘źø°ė„¼ ģ‚¬ģš©ķ•˜ģ—¬ ė‹¤ģ–‘ķ•œ ķ”„ė”œź·øėž˜ė° 언얓에 ėŒ€ķ•œ 구문 ź°•ģ”° 기늄과 ė‹¤ģ–‘ķ•œ ģƒ‰ģƒ ķ…Œė§ˆė„¼ ģ œź³µķ•©ė‹ˆė‹¤.", + "file_title": "ķŒŒģ¼ ė…øķŠø", + "file_description": "PDF, ģ“ėÆøģ§€, ģøģ•± ģ–“ķ”Œė¦¬ģ¼€ģ“ģ…˜ 미리볓기넼 ķ¬ķ•Øķ•œ ė¹„ė””ģ˜¤ģ™€ ź°™ģ€ 멀티미디얓 ķŒŒģ¼ģ„ ģ €ģž„ķ•˜ģ„øģš”.", + "canvas_title": "ģŗ”ė²„ģŠ¤", + "canvas_description": "excalidraw.comź³¼ ė™ģ¼ķ•œ źø°ģˆ ģ„ ģ‚¬ģš©ķ•˜ģ—¬ ė¬“ķ•œķ•œ ģŗ”ė²„ģŠ¤ģ— ė„ķ˜•, ģ“ėÆøģ§€, ķ…ģŠ¤ķŠøė„¼ ė°°ģ¹˜ķ•˜ģ„øģš”. ė‹¤ģ“ģ–“ź·øėžØ, ģŠ¤ģ¼€ģ¹˜, ģ‹œź°ģ  ź³„ķšģ— ģ“ģƒģ ģž…ė‹ˆė‹¤.", + "mermaid_title": "Mermaid ė‹¤ģ“ģ–“ź·øėžØ", + "mermaid_description": "Mermaid źµ¬ė¬øģ„ ģ‚¬ģš©ķ•˜ģ—¬ ģˆœģ„œė„(Flowchart), ķ“ėž˜ģŠ¤ ė° ģ‹œķ€€ģŠ¤ ė‹¤ģ“ģ–“ź·øėžØ, ź°„ķŠø(Gantt) 차트 ė“±ģ˜ ė‹¤ģ“ģ–“ź·øėžØģ„ ė§Œė“¤ģ–“ ė³“ģ„øģš”.", + "mindmap_title": "ė§ˆģøė“œė§µ", + "mindmap_description": "ģƒź°ģ„ ģ‹œź°ģ ģœ¼ė”œ ģ •ė¦¬ķ•˜ź±°ė‚˜ ėøŒė ˆģøģŠ¤ķ† ė° ģ„øģ…˜ģ„ ģ§„ķ–‰ķ•˜ģ„øģš”.", + "others_list": "źø°ķƒ€: <0>ė…øķŠø ė§µ, <1>꓀계 ė§µ, <2>ģ €ģž„ėœ ź²€ģƒ‰, <3>ė Œė”ė§ ė…øķŠø, <4>웹 ė·°." + }, + "extensibility_benefits": { + "title": "공유 ė° ķ™•ģž„ģ„±", + "import_export_title": "ź°€ģ øģ˜¤źø°/낓볓낓기", + "import_export_description": "Markdown, ENEX, OML ķ˜•ģ‹ģœ¼ė”œ 다넸 ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ź³¼ ģ‰½ź²Œ 상호 ģž‘ģš©ķ•  수 ģžˆģŠµė‹ˆė‹¤.", + "share_title": "ģ›¹ģ—ģ„œ ė…øķŠø ź³µģœ ķ•˜źø°", + "share_description": "ė§Œģ•½ ģ„œė²„ė„¼ ģ‚¬ģš©ķ•œė‹¤ė©“, 다넸 ģ‚¬ėžŒė“¤ź³¼ ė©”ėŖØģ˜ ģ¼ė¶€ė„¼ ź³µģœ ķ•  수 ģžˆģŠµė‹ˆė‹¤.", + "scripting_title": "ź³ źø‰ Scripting", + "scripting_description": "ģ‚¬ģš©ģž ģ •ģ˜ ģœ„ģ Æ, ģ„œė²„ ģ‚¬ģ“ė“œ ė”œģ§ģ„ ģ‚¬ģš©ķ•˜ģ—¬ Trilium ė‚“ģ—ģ„œ 통합 ģ‹œģŠ¤ķ…œģ„ źµ¬ģ¶•ķ•“ė³“ģ„øģš”.", + "api_title": "REST API", + "api_description": "ė‚“ģž„ė˜ģ–“ģžˆėŠ” REST API넼 ģ‚¬ģš©ķ•˜ģ—¬ Triliumź³¼ ķ”„ė”œź·øėž˜ė° ė°©ģ‹ģœ¼ė”œ ģƒķ˜øģž‘ģš© ķ•“ė³“ģ„øģš”." + }, + "collections": { + "title": "ģ»¬ė ‰ģ…˜", + "calendar_title": "ģŗ˜ė¦°ė”", + "calendar_description": "ģŗ˜ė¦°ė”ė„¼ ģ‚¬ģš©ķ•˜ģ—¬ ź°œģø ė˜ėŠ” 업묓 ꓀련 ģ¼ģ •ģ„ ź“€ė¦¬ķ•˜ģ„øģš”. ķ•˜ė£Ø ė˜ėŠ” ė©°ģ¹  ė‹Øģœ„ė”œ ģ¼ģ •ģ„ ꓀리할 수 ģžˆģœ¼ė©°, 주별, 월별, ģ—°ė„ė³„ 볓기넼 통핓 ģ¼ģ •ģ„ ķ•œėˆˆģ— ķ™•ģøķ•  수 ģžˆģŠµė‹ˆė‹¤. 또 ź°„ķŽøķ•œ ģƒķ˜øģž‘ģš©ģ„ 통핓 ģ¼ģ •ģ„ ģ¶”ź°€ķ•˜ź±°ė‚˜ ėŒģ–“ė‹¤ ė†“ģ„ 수 ģžˆģŠµė‹ˆė‹¤.", + "table_title": "ķ…Œģ“ėø”", + "table_description": "ķ…ģŠ¤ķŠø, ģˆ«ģž, ģ²“ķ¬ė°•ģŠ¤, ė‚ ģ§œ ė° ģ‹œź°„, 링크, ģƒ‰ģƒ 등 ė‹¤ģ–‘ķ•œ ģ—“ ģœ ķ˜•ģ„ ģ œź³µķ•˜ź³  ꓀계 źø°ėŠ„ģ„ ģ§€ģ›ķ•˜ėŠ” ķ‘œ ķ˜•ģ‹ģœ¼ė”œ ė…øķŠøģ— ė‚“ģš©ģ„ ķ‘œģ‹œķ•˜ź³  ķŽøģ§‘ķ•  수 ģžˆģŠµė‹ˆė‹¤. ķ•„ģš”ģ— ė”°ė¼ ķ‘œ ģ•ˆģ— 트리 계층 źµ¬ģ”°ģ˜ ė…øķŠøė„¼ ķ‘œģ‹œķ•  ģˆ˜ė„ ģžˆģŠµė‹ˆė‹¤.", + "board_title": "칸반 ė³“ė“œ", + "board_description": "칸반 ė³“ė“œģ— ģž‘ģ—…ģ“ė‚˜ ķ”„ė”œģ ķŠø 상태넼 ģ •ė¦¬ķ•˜ģ„øģš”. 새 ķ•­ėŖ©ź³¼ ģ—“ģ„ ģ‰½ź²Œ ė§Œė“¤ 수 ģžˆź³ , ė³“ė“œ ģœ„ė”œ ė“œėž˜ź·øķ•˜ģ—¬ 상태넼 ź°„ė‹Øķžˆ 변경할 수 ģžˆģŠµė‹ˆė‹¤.", + "geomap_title": "지리 ģ§€ė„", + "geomap_description": "ģ»¤ģŠ¤ķ„°ė§ˆģ“ģ§•ģ“ ź°€ėŠ„ķ•œ 마커딜 ķœ“ź°€ė„¼ ź³„ķšķ•˜ź±°ė‚˜ ꓀심 ģ§€ģ ģ„ ģ§€ė„ģ— 직접 ķ‘œģ‹œķ•˜ģ„øģš”. źø°ė”ėœ GPX ķŠøėž™ģ„ ķ‘œģ‹œķ•˜ģ—¬ ģ—¬ģ •ģ„ 추적할 ģˆ˜ė„ ģžˆģŠµė‹ˆė‹¤.", + "presentation_title": "ķ”„ė ˆģ  ķ…Œģ“ģ…˜", + "presentation_description": "ģŠ¬ė¼ģ“ė“œģ— 정볓넼 ģ •ė¦¬ķ•˜ź³ , ė§¤ė„ėŸ¬ģš“ ģ „ķ™˜ ķšØź³¼ģ™€ ķ•Øź»˜ 전첓 ķ™”ė©“ģœ¼ė”œ ė°œķ‘œķ•˜ģ„øģš”. ģŠ¬ė¼ģ“ė“œė„¼ PDF딜 낓볓낓 ź°„ķŽøķ•˜ź²Œ ź³µģœ ķ•  ģˆ˜ė„ ģžˆģŠµė‹ˆė‹¤." + }, + "faq": { + "mobile_question": "ėŖØė°”ģ¼ ģ•±ģ“ ģžˆė‚˜ģš”?", + "mobile_answer": "ķ˜„ģž¬ ź³µģ‹ģ ģø ėŖØė°”ģ¼ ģ•±ģ€ ģ—†ģŠµė‹ˆė‹¤. ķ•˜ģ§€ė§Œ, ģ„œė²„ ģøģŠ¤ķ„“ģŠ¤ė„¼ 가지고 ģžˆė‹¤ė©“ 웹 ėøŒė¼ģš°ģ €ė„¼ ģ“ģš©ķ•“ ģ ‘ź·¼ķ•˜ź±°ė‚˜ PWA딜 ģ„¤ģ¹˜ķ•  수 ģžˆģŠµė‹ˆė‹¤. ģ•ˆė“œė”œģ“ė“œģ—ėŠ” (ė°ģŠ¤ķ¬ķƒ‘ ķ“ė¼ģ“ģ–øķŠøģ²˜ėŸ¼)ģ˜¤ķ”„ė¼ģøģ—ģ„œė„ ģž‘ė™ķ•˜ėŠ” TriliumDroidė¼ėŠ” ė¹„ź³µģ‹ ģ•±ģ“ ģžˆģŠµė‹ˆė‹¤.", + "database_question": "얓디에 ė°ģ“ķ„°ź°€ ģ €ģž„ė˜ė‚˜ģš”?", + "server_question": "Triliumģ„ ģ‚¬ģš©ķ•˜źø° ģœ„ķ•“ ģ„œė²„ź°€ ķ•„ģš”ķ•œź°€ģš”?", + "title": "ģžģ£¼ ė¬»ėŠ” 질문", + "database_answer": "ėŖØė“  ė…øķŠøėŠ” 앱 ķ“ė”ģ˜ SQLite ė°ģ“ķ„°ė² ģ“ģŠ¤ģ— ģ €ģž„ė©ė‹ˆė‹¤. Triliumģ“ ķ…ģŠ¤ķŠøķŒŒģ¼ ėŒ€ģ‹  ė°ģ“ķ„°ė² ģ“ģŠ¤ė„¼ ģ‚¬ģš©ķ•˜ėŠ” ģ“ģœ ėŠ” ģ„±ėŠ„ ķ–„ģƒź³¼ 복제(ķŠøė¦¬ģ˜ ģ—¬ėŸ¬ ģœ„ģ¹˜ģ— ź°™ģ€ ė…øķŠø) ź°™ģ€ 훨씬 ė” źµ¬ķ˜„ķ•˜źø° ģ–“ė ¤ģš“ 몇몇 źø°ėŠ„ė“¤ ė•Œė¬øģž…ė‹ˆė‹¤. Trilium Notes에 ėŒ€ķ•“ģ„œ ģ°½ģ—ģ„œ 앱 ķ“ė”ė„¼ ģ°¾ģ„ 수 ģžˆģŠµė‹ˆė‹¤.", + "server_answer": "ģ•„ė‹ˆģš”, ģ„œė²„ėŠ” 웹 ėøŒė¼ģš°ģ €ė„¼ 통핓 ģ ‘ģ†ķ•  수 ģžˆė„ė” ķ—ˆģš©ķ•˜ė©°, ģ—¬ėŸ¬ 기기넼 ģ‚¬ģš©ķ•˜ėŠ” 경우 ė™źø°ķ™”ė„¼ ź“€ė¦¬ķ•©ė‹ˆė‹¤. ģ‹œģž‘ķ•˜ė ¤ė©“ ė°ģŠ¤ķ¬ķ†± ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ģ„ ė‹¤ģš“ė”œė“œķ•˜ģ—¬ ģ‚¬ģš©ķ•˜źø°ė§Œ ķ•˜ė©“ ė©ė‹ˆė‹¤.", + "scaling_question": "ģ“ ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ģ€ ģ–¼ė§ˆė‚˜ ė§Žģ€ ė…øķŠøė„¼ ģ²˜ė¦¬ķ•  수 ģžˆė‚˜ģš”?", + "scaling_answer": "ģ‚¬ģš©ėŸ‰ģ— ė”°ė¼ ė‹¤ė„“ź² ģ§€ė§Œ, ģ“ ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ģ€ ģµœģ†Œ 10만 ź°œģ˜ ė…øķŠøė„¼ ė¬øģ œģ—†ģ“ ģ²˜ė¦¬ķ•  수 ģžˆģŠµė‹ˆė‹¤. ė‹¤ė§Œ, Triliumģ€ (NextCloud와 ź°™ģ€) ķŒŒģ¼ ģ €ģž„ģ†Œė¼źø°ė³“ė‹¤ėŠ” ģ§€ģ‹ 기반 ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ģ— ź°€ź¹źø° ė•Œė¬øģ—, ėŒ€ģš©ėŸ‰ ķŒŒģ¼(ķŒŒģ¼ė‹¹ 1GB ģ“ģƒ)ģ„ ė§Žģ“ ģ—…ė”œė“œķ•  경우 ė™źø°ķ™” ź³¼ģ •ģ“ ģ‹¤ķŒØķ•  수 ģžˆė‹¤ėŠ” 점에 ģœ ģ˜ķ•˜ģ‹­ģ‹œģ˜¤.", + "network_share_question": "ė‚“ ė°ģ“ķ„°ė² ģ“ģŠ¤ė„¼ ė„¤ķŠøģ›Œķ¬ ė“œė¼ģ“ėøŒė”œ ź³µģœ ķ•  수 ģžˆė‚˜ģš”?", + "network_share_answer": "ģ•„ė‹ˆģš”, ģ¼ė°˜ģ ģœ¼ė”œ SQLite ė°ģ“ķ„°ė² ģ“ģŠ¤ė„¼ ė„¤ķŠøģ›Œķ¬ ė“œė¼ģ“ėøŒė”œ ź³µģœ ķ•˜ėŠ” ź²ƒģ€ 좋지 ģ•ŠģŠµė‹ˆė‹¤. ź²½ģš°ģ— ė”°ė¼ ģž‘ė™ķ•  ģˆ˜ė„ ģžˆģ§€ė§Œ, ė„¤ķŠøģ›Œķ¬ė„¼ ķ†µķ•œ ķŒŒģ¼ ģž źøˆģ“ ģ™„ė²½ķ•˜ģ§€ ģ•Šģ•„ ė°ģ“ķ„°ė² ģ“ģŠ¤ź°€ ģ†ģƒė  ź°€ėŠ„ģ„±ģ“ ģžˆģŠµė‹ˆė‹¤.", + "security_question": "ė‚“ ė°ģ“ķ„°ėŠ” ģ–“ė–»ź²Œ ė³“ķ˜øė˜ė‚˜ģš”?", + "security_answer": "기본적으딜 ė…øķŠøėŠ” ģ•”ķ˜øķ™”ė˜ģ§€ ģ•Šģœ¼ė©° ė°ģ“ķ„°ė² ģ“ģŠ¤ģ—ģ„œ 직접 ģ½ģ„ 수 ģžˆģŠµė‹ˆė‹¤. ė…øķŠøė„¼ ģ•”ķ˜øķ™” ėŒ€ģƒģœ¼ė”œ ķ‘œģ‹œķ•˜ė©“, AES-128-CBC넼 ģ‚¬ģš©ķ•˜ģ—¬ ģ•”ķ˜øķ™”ė©ė‹ˆė‹¤." + }, + "final_cta": { + "title": "Trilium Notes넼 ģ‹œģž‘ķ•  준비가 ė˜ģ…Øė‚˜ģš”?", + "description": "ź°•ė „ķ•œ 기늄과 ģ™„ė²½ķ•œ ź°œģø 정볓 볓호넼 통핓 ė‚˜ė§Œģ˜ ģ§€ģ‹ źø°ė°˜ģ„ źµ¬ģ¶•ķ•˜ģ„øģš”.", + "get_started": "ģ‹œģž‘ķ•˜źø°" + }, + "components": { + "link_learn_more": "ģžģ„øķžˆ ģ•Œģ•„ė³“źø°..." + }, + "footer": { + "copyright_and_the": " 그리고 ", + "copyright_community": "ģ»¤ė®¤ė‹ˆķ‹°" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "GitHub Discussions", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS (Intel)", + "title_arm64": "macOS (Apple Silicon)", + "description_x64": "Intel Macģ€ Monterey 버전 ģ“ģƒ macOSģ—ģ„œ ģ§€ģ›ķ•©ė‹ˆė‹¤.", + "description_arm64": "M1, M2 칩과 ź°™ģ€ Apple Siliconģ“ ķƒ‘ģž¬ėœ Macs ģ „ģš©.", + "quick_start": "Homebrew딜 ģ„¤ģ¹˜ķ•˜ėŠ” 경우:", + "download_dmg": "ģ„¤ģ¹˜ ķ”„ė”œź·øėžØ 낓려받기 (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "ķ¬ķ„°ėø” (.zip)" + }, + "download_helper_server_docker": { + "title": "Docker넼 ģ‚¬ģš©ķ•œ 셀프 ķ˜øģŠ¤ķŒ…", + "description": "Docker ģ»Øķ…Œģ“ė„ˆė„¼ ģ‚¬ģš©ķ•˜ģ—¬ Windows, Linux ė˜ėŠ” macOS에 ź°„ķŽøķ•˜ź²Œ ė°°ķ¬ķ•  수 ģžˆģŠµė‹ˆė‹¤.", + "download_dockerhub": "ė„ģ»¤ ķ—ˆėøŒ", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "ė¦¬ėˆ…ģŠ¤ģ—ģ„œ 셀프 ķ˜øģŠ¤ķŒ…", + "description": "Trilium Notes넼 ģžģ²“ ģ„œė²„ ė˜ėŠ” VPS에 ė°°ķ¬ķ•˜ģ„øģš”. ėŒ€ė¶€ė¶„ģ˜ ė°°ķ¬ķŒź³¼ ķ˜øķ™˜ė©ė‹ˆė‹¤.", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "NixOS ėŖØė“ˆ" + }, + "download_helper_server_hosted": { + "title": "유료 ķ˜øģŠ¤ķŒ…", + "description": "Trilium NotesėŠ” ź°„ķŽøķ•œ ģ ‘ź·¼ ė° ꓀리넼 ģœ„ķ•“ 유료 ģ„œė¹„ģŠ¤ģø PikaPodsģ—ģ„œ ķ˜øģŠ¤ķŒ…ķ•  수 ģžˆģŠµė‹ˆė‹¤. Trilium ķŒ€ź³¼ 직접 ģ œķœ“ė˜ģ–“ģžˆģ§€ėŠ” ģ•ŠģŠµė‹ˆė‹¤.", + "download_pikapod": "PikaPodsģ—ģ„œ ģ„¤ģ¹˜ķ•˜źø°", + "download_triliumcc": "ė˜ėŠ” trilium.cc넼 ģ°øģ”°ķ•˜ģ„øģš”" + }, + "resources": { + "title": "ė¦¬ģ†ŒģŠ¤", + "icon_packs": "ģ•„ģ“ģ½˜ 팩", + "icon_packs_intro": "ģ•„ģ“ģ½˜ ķŒ©ģ„ ģ‚¬ģš©ķ•˜ģ—¬ ė…øķŠøģ— ģ‚¬ģš©ķ•  수 ģžˆėŠ” ģ•„ģ“ģ½˜ ģ¢…ė„˜ė„¼ ėŠ˜ė ¤ė³“ģ„øģš”. ģ•„ģ“ģ½˜ ķŒ©ģ— ėŒ€ķ•œ ģžģ„øķ•œ ė‚“ģš©ģ€ ź³µģ‹ ė¬øģ„œė„¼ ģ°øģ”°ķ•˜ģ„øģš”.", + "download": "ė‹¤ģš“ė”œė“œ", + "website": "ģ›¹ģ‚¬ģ“ķŠø" + } +} diff --git a/apps/website/src/translations/md/translation.json b/apps/website/src/translations/md/translation.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/apps/website/src/translations/md/translation.json @@ -0,0 +1 @@ +{} diff --git a/apps/website/src/translations/mr/translation.json b/apps/website/src/translations/mr/translation.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/apps/website/src/translations/mr/translation.json @@ -0,0 +1 @@ +{} diff --git a/apps/website/src/translations/nb-NO/translation.json b/apps/website/src/translations/nb-NO/translation.json new file mode 100644 index 0000000000..1d95d42604 --- /dev/null +++ b/apps/website/src/translations/nb-NO/translation.json @@ -0,0 +1,200 @@ +{ + "get-started": { + "title": "Kom i gang", + "architecture": "Arkitektur:", + "desktop_title": "Last ned skrivebordsprogram (v{{version}})", + "older_releases": "Se tidligere versjoner", + "server_title": "Sett opp en server for adgang fra flere enheter" + }, + "hero_section": { + "title": "Organiser tankene dine. Bygg din personlige kunnskapsbase.", + "github": "GitHub", + "get_started": "Kom i gang", + "dockerhub": "Docker Hub", + "screenshot_alt": "Screenshot fra Trilium Notes skrivebordsprogram", + "subtitle": "Trilium er en open-source-lĆøsning for Ć„ ta notater og organisere en personlig kunnskapsbase. Kan brukes lokalt pĆ„ arbeidsstasjonen din eller synkroniseres med en selv-hostet lĆøsning for Ć„ ha dine notater med deg overalt." + }, + "organization_benefits": { + "title": "Organisering", + "note_structure_title": "Notatstruktur", + "hoisting_title": "Arbeidsflate og fokusering", + "attributes_description": "Bruk relasjoner mellom notater eller legg til etiketter for enkel kategorisering. Bruk fremhevede attributter for Ć„ legge inn strukturert informasjon som kan brukes i tabeller og tavler.", + "note_structure_description": "Notater kan arrangeres herarkisk. Det trengs ikke mapper, siden alle notater kan inneholde undernotater. Ett notat kan legges inn flere steder i herarkiet.", + "attributes_title": "Notatetiketter og -relasjoner", + "hoisting_description": "Du kan enkelt skille personlige og arbeidsnotater ved Ć„ gruppere de under arbeidsrom, som fokuserer notat-treet ditt pĆ„ kun Ćønskede notater." + }, + "productivity_benefits": { + "sync_title": "Synkronisering", + "search_title": "Kraftig sĆøk", + "web_clipper_title": "Webklipper", + "revisions_title": "Notatrevisjon", + "protected_notes_title": "Beskyttede notater", + "title": "Produktivitet og sikkerhet", + "sync_content": "Bruk en selv-hostet eller cloud-instans for Ć„ enkelt synkronisere notater pĆ„ tvers av enheter, og ha de tilgjengelige fra din mobiltelefon ved hjelp av progressiv web-app.", + "jump_to_content": "Hopp raskt til notater eller grensesnittkommandoer over hele hierarkiet ved Ć„ sĆøke etter tittel, med \"fuzzy\" matching for Ć„ ta hensyn til skrivefeil eller smĆ„ differanser.", + "revisions_content": "Notater lagres periodisk i bakgrunnen og revisjonshistorikk kan brukes for tilbakeblikk eller Ć„ omgjĆøre uĆønskede endringer. Revisjoner kan ogsĆ„ lages manuelt.", + "protected_notes_content": "Beskytt sensitiv personlig informasjon ved Ć„ kryptere notater og lĆ„se de med en passordkryptert sesjon.", + "jump_to_title": "HurtigsĆøk og kommandoer", + "search_content": "Eller sĆøk etter tekst i notatene og finjuster sĆøket ved Ć„ filtrere pĆ„ foreldrenotat eller dybde.", + "web_clipper_content": "Hent nettsider (eller screenshots) og legg de direkte i Trilium ved hjelp av web clipper nettleserutvidelse." + }, + "note_types": { + "canvas_title": "Kanvas", + "mindmap_title": "Tankekart", + "text_title": "Tekstnotat", + "code_title": "Kodenotat", + "file_title": "Filnotat", + "mermaid_title": "Mermaid diagrammer", + "title": "Flere mĆ„ter Ć„ presentere informasjonen din", + "text_description": "Notatene redigeres med en visuell editor (WYSIWYG), som stĆøtter tabeller, bilder, matematiske uttrykk og kodeblokker med syntaksutheving. Formater tekst hurtig med Markdown-inspirert syntaks eller \"slash-kommandoer\".", + "code_description": "Store samlinger med kildekode eller skript bruker en dedikert editor med syntaksfremheving for mange programmeringssprĆ„k og med flere fargetema.", + "file_description": "Integrer multimediafiler som PDFer, bilder og video med forhĆ„ndsvisning i programmet.", + "mermaid_description": "Lag diagrammer som flytskjema, klasse- og sekvensdiagrammer, Ganttdiagrammer og mye mer ved hjelp av Mermaidsyntaks.", + "mindmap_description": "Organiser dine tanker visuelt eller gjĆør en brainstorming.", + "others_list": "og andre: <0>notatkart, <1>relasjonskart, <2>lagrede sĆøk, <3>rendret notat, og <4>web view.", + "canvas_description": "Arranger figurer, bilder og tekst pĆ„ et uendelig lerret som bruker samme teknologi som excalidraw.com. Ideelt for diagrammer, skisser og visuell planlegging." + }, + "extensibility_benefits": { + "import_export_title": "Import/eksport", + "scripting_title": "Avansert skripting", + "api_title": "REST API", + "title": "Deling og utvidbarhet", + "share_title": "Del notater pĆ„ nett", + "share_description": "Hvis du har en server, kan den brukes til Ć„ dele valgfrie notater med andre.", + "scripting_description": "Lag dine egne integrasjoner i Trilium med egendefinerte widgets, eller serversidelogikk.", + "import_export_description": "Samhandle med andre programmer ved hjelp av Markdown, ENEX og OML.", + "api_description": "Ved hjelp av den innebygde REST-APIen kan du programmatisk samhandle med Trilium." + }, + "collections": { + "title": "Samlinger", + "calendar_title": "Kalender", + "table_title": "Tabell", + "geomap_title": "Geokart", + "presentation_title": "Presentasjon", + "board_title": "Kanbantavle", + "geomap_description": "Planlegg ferien din eller merk deg dine interessepunkter pĆ„ et geografisk kart ved hjelp av definerbare markĆører. Vis lagrede GPX-spor for Ć„ se reisen din.", + "calendar_description": "Organiser dine personlige eller jobb-arrangement ved hjelp av kalender, med stĆøtte for heldags- og flerdagsarrangement. FĆ„ rask oversikt over dine arrangementer med ukes- mĆ„neds- og Ć„rsvisning. Dra og slipp hendelser for enkelt Ć„ gjĆøre endringer.", + "table_description": "Vis og rediger informasjon om notater i tabellform, med ulike kolonnetyper som tekst, nummer, avkrysningsbokser, dato og tid, lenker, farger og stĆøtte for relasjoner. Du kan ogsĆ„ vise notater i et hierarkisk tre i tabellen.", + "board_description": "Organiser oppgaver eller prosjekter i en Kanbantavle hvor du enkelt kan lage nye elementer og kolonner, og endre status pĆ„ elementer ved Ć„ dra de rundt pĆ„ tavlen.", + "presentation_description": "Organiser informasjon i lysbilder og presenter dem i fullskjermmodus med myke overganger. Lysbildene kan ogsĆ„ eksporteres til PDF for enkel deling." + }, + "header": { + "documentation": "Dokumentasjon", + "get-started": "Kom i gang", + "support-us": "StĆøtt oss" + }, + "social_buttons": { + "github": "GitHub", + "matrix": "Matrix", + "reddit": "Reddit", + "github_discussions": "GitHub-diskusjoner" + }, + "support_us": { + "paypal": "PayPal", + "title": "StĆøtt oss", + "financial_donations_title": "Finansiell donasjon", + "github_sponsors": "GitHub Sponsors", + "financial_donations_description": "Trilium er bygget og vedlikeholdt med flere hundre timers arbeid. Ditt bidrag hjelper Ć„ holde det Ć„pen kildekode, forbedre funksjonalitet og dekker driftskostnader.", + "financial_donations_cta": "Vurder gjerne Ć„ stĆøtte hovedutvikleren (eliandoran) av programmet via:", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "download_helper_desktop_windows": { + "download_scoop": "Scoop", + "title_x64": "Windows 64-bit", + "download_zip": "Portable (.zip)", + "title_arm64": "Windows pĆ„ ARM", + "download_exe": "Last ned installasjonsprogram (.exe)", + "description_x64": "Kompatibel med Intel- eller AMD-enheter som kjĆører Windows 10 og 11.", + "description_arm64": "Kompatibel med ARM-enheter (for eksempel Qualcomm Snapdragon).", + "quick_start": "For Ć„ installere via Winget:" + }, + "download_helper_desktop_linux": { + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR", + "title_x64": "Linux 64-bit", + "download_zip": "Portable (.zip)", + "title_arm64": "Linux pĆ„ ARM", + "description_x64": "For de fleste Linux-distribusjoner, kompatibelt med x86_64-arkitektur.", + "description_arm64": "For ARM-baserte Linux-distribusjoner, kompatibelt med aarch64-arkitektur.", + "quick_start": "Velg egnet pakkeformat avhengig av din distribusjon:" + }, + "download_helper_server_docker": { + "download_ghcr": "ghcr.io", + "download_dockerhub": "Docker Hub", + "title": "Selv-hostet med Docker", + "description": "Installer enkelt pĆ„ Windows, Linux eller macOS ved bruk av en Docker-container." + }, + "download_helper_desktop_macos": { + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "Portable (.zip)", + "title_x64": "macOS for Intel", + "download_dmg": "Last ned installasjonsprogram (.dmg)", + "title_arm64": "macOS for Apple Silicon", + "description_x64": "For Intel-baserte Mac-er med macOS Monterey eller nyere.", + "description_arm64": "For Apple Silicon Mac-er som de med M1- og M2-chiper.", + "quick_start": "For Ć„ installere via Homebrew:" + }, + "final_cta": { + "get_started": "Kom i gang", + "title": "Klar for Ć„ begynne med Trilium Notes?", + "description": "Skap din personlige kunnskapsbase med kraftig funksjonalitet og fullt personvern." + }, + "components": { + "link_learn_more": "LƦr mer..." + }, + "download_now": { + "text": "Last ned nĆ„ ", + "platform_small": "for {{platform}}", + "linux_small": "for Linux", + "platform_big": "v{{version}} for {{platform}}", + "linux_big": "v{{version}} for Linux", + "more_platforms": "Flere plattformer og serveroppsett" + }, + "footer": { + "copyright_and_the": " og ", + "copyright_community": "fellesskapet" + }, + "download_helper_server_linux": { + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "NixOS modul", + "title": "Selv-hostet pĆ„ Linux", + "description": "Installer Trilium Notes pĆ„ din egen server eller VPS, kompatibel med de fleste distribusjoner." + }, + "download_helper_server_hosted": { + "title": "Betalt hosting", + "download_triliumcc": "Alternativt sjekk trilium.cc", + "description": "Trilium Notes driftet pĆ„ PikaPods, en betalt tjeneste for enkel tilgang og administrasjon. Ikke direkte tilknyttet Trilium-teamet.", + "download_pikapod": "Installer pĆ„ PikaPods" + }, + "faq": { + "title": "Ofte stilte spĆørsmĆ„l", + "mobile_question": "Finnes det en mobil applikasjon?", + "mobile_answer": "ForelĆøpig er det ikke noe offisiell mobil applikasjon. Men hvis du har en serverinstans kan du koble til denne med en nettleser, og ogsĆ„ installere den som en progressiv web-app. For Android finnes det en uoffisiell applikasjon med navn TriliumDroid som ogsĆ„ fungerer offline (samme som en skrivebordsklient).", + "database_question": "Hvor lagres dataene?", + "database_answer": "Alle notater lagres i en SQLite-database i en programmappe. ƅrsaken til at Trilium bruker database i stedet for rene tekstfiler er bĆ„de ytelse og at visse funksjoner ellers ville vƦrt vanskelig Ć„ implementere, slik som klonede notater (samme notat flere steder). For Ć„ finne programmappen, Ć„pne \"om\"-vinduet i programmet.", + "server_question": "Trenger jeg en server for Ć„ bruke Trilium?", + "server_answer": "Nei, serveren tillater tilgang via nettleser og hĆ„ndterer synkronisering hvis du har flere enheter. For Ć„ komme i gang er det nok Ć„ laste ned skrivebordsprogrammet og begynne med det.", + "scaling_question": "Hvor godt skalerer programmet med store mengder notater?", + "scaling_answer": "Avhengig av bruk burde programmet kunne hĆ„ndtere minst 100.000 notater uten problemer. Merk at synkroniseringen noen ganger kan feile ved opplasting av mange store filer (1GB per fil) siden Trilium er ment for Ć„ vƦre en kunnskapsbase mer enn et fillager (som for eksempel NextCloud).", + "network_share_question": "Kan jeg dele databasen min over nettverksdeling?", + "network_share_answer": "Nei, det er stort sett ikke en god ide Ć„ dele en SQLite-database over nettverksdeling. Selv om det kan fungere, er det sjanser for at databasen kan bli Ćødelagt grunnet problemer med fillĆ„sing over nettverk.", + "security_question": "Hvordan er mine data beskyttet?", + "security_answer": "Som standard blir ikke notater kryptert og kan leses direkte fra databasen. NĆ„r et notat er markert kryptert, blir det kryptert med AES-128-CBC." + }, + "404": { + "title": "404: Siden ble ikke funnet", + "description": "Siden ble ikke funnet. Den kan ha blitt slettet eller adressen er feil." + }, + "contribute": { + "title": "Andre mĆ„ter Ć„ bidra", + "way_translate": "Oversett programmet til ditt sprĆ„k via Weblate.", + "way_community": "Ta del i felleskapet pĆ„ GitHub Discussions eller pĆ„ Matrix.", + "way_reports": "Meld feil via GitHub issues.", + "way_document": "Hjelp oss Ć„ forbedre dokumentasjonen ved Ć„ fortelle om mangler, eller bidra med veiledninger, Ofte Stilte SpĆørsmĆ„l eller tutorials.", + "way_market": "Spre ordet: Del Trilium Notes med venner, pĆ„ blogger eller i sosiale media." + } +} diff --git a/apps/website/src/translations/nl/translation.json b/apps/website/src/translations/nl/translation.json new file mode 100644 index 0000000000..99d661a48c --- /dev/null +++ b/apps/website/src/translations/nl/translation.json @@ -0,0 +1,47 @@ +{ + "get-started": { + "title": "Aan de slag", + "desktop_title": "Download de desktop applicatie (v{{version}})", + "architecture": "Architectuur:", + "older_releases": "Bekijk oudere versies", + "server_title": "Richt een server in voor toegang vanaf meerdere apparaten" + }, + "hero_section": { + "title": "Organiseer je gedachten. Bouw je persoonlijke kennisbank.", + "subtitle": "Trilium is een open-source oplossing voor notities en het organiseren van een persoonlijke kennisbank. Gebruik het lokaal op je desktop, of synchroniseer het met je zelfgehoste server om je notities overal bij de hand te hebben.", + "get_started": "Aan de slag", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Schermafbeelding van de Trilium Notes-desktopapplicatie" + }, + "organization_benefits": { + "title": "Organisatie", + "note_structure_title": "Notitie structuur", + "note_structure_description": "Notities kunnen hiĆ«rarchisch worden geordend. Mappen zijn niet nodig, aangezien elke notitie subnotities kan bevatten. Een enkele notitie kan bovendien op meerdere plaatsen in de hiĆ«rarchie worden toegevoegd.", + "attributes_title": "Notitielabels en relaties", + "attributes_description": "Gebruik relaties tussen notities of voeg labels toe voor eenvoudige categorisatie. Gebruik gepromoveerde attributen om gestructureerde informatie in te voeren die kan worden gebruikt in tabellen en borden.", + "hoisting_title": "Werkruimtes en focus (hoisting)", + "hoisting_description": "Scheid eenvoudig je persoonlijke en werknotities door ze te groeperen onder een werkruimte, waarmee je de notitieboom kunt focussen op een specifieke set notities." + }, + "productivity_benefits": { + "title": "Productiviteit en veiligheid", + "revisions_title": "Notitie revisies", + "revisions_content": "Notities worden periodiek op de achtergrond opgeslagen, en versies kunnen worden gebruikt om wijzigingen te bekijken of om per ongeluk gemaakte aanpassingen ongedaan te maken. Revisies kunnen ook handmatig worden aangemaakt.", + "sync_title": "Synchronisatie", + "sync_content": "Gebruik een zelfgehoste of cloudinstantie om je notities eenvoudig te synchroniseren tussen meerdere apparaten, en om er via een PWA toegang toe te krijgen op je mobiele telefoon.", + "protected_notes_title": "Beveiligde notities", + "protected_notes_content": "Bescherm gevoelige persoonlijke informatie door notities te versleutelen en te beschermen achter een met wachtwoord beveiligde sessie.", + "jump_to_title": "Snel zoeken en commando's", + "jump_to_content": "Spring snel naar notities of gebruikersinterfacecommando's binnen de hiĆ«rarchie door te zoeken naar de titel, met benaderingslogica om tikfouten en kleine verschillen te omzeilen.", + "search_title": "Krachtige zoekfunctie", + "search_content": "Of zoek naar tekst binnen notities en verfijn de zoekopdracht door in de bovenliggende notitie te filteren of zoekdiepte aan te geven.", + "web_clipper_title": "Web clipper", + "web_clipper_content": "Bewaar webpagina's (of schermafbeeldingen) en plaats deze direct in Trillium door de web clipper browser extensie te gebruiken." + }, + "note_types": { + "title": "Meerdere manieren om je informatie te tonen", + "text_title": "Tekstnotities", + "text_description": "De notities worden bewerkt met een visuele (WYSIWYG) editor, met ondersteuning voor tabellen, plaatjes, wiskundige tekens, codeblokken met syntax-highlighting. Lijn tekst uit met Markdown-achtige syntax of met slash-commando's.", + "code_title": "Codenotities" + } +} diff --git a/apps/website/src/translations/pl/translation.json b/apps/website/src/translations/pl/translation.json new file mode 100644 index 0000000000..727cf42dff --- /dev/null +++ b/apps/website/src/translations/pl/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "desktop_title": "Pobierz aplikację na komputer (v{{version}})", + "architecture": "Architektura:", + "older_releases": "SprawdÅŗ poprzednie wydania", + "server_title": "Skonfiguruj serwer, aby mieć dostęp z wielu urządzeń", + "title": "Start" + }, + "hero_section": { + "title": "Uporządkuj swoje myśli i zbuduj bazę Twojej wiedzy.", + "subtitle": "Trilium to otwartoÅŗródłowe rozwiązanie do notowania i organizacji swojej personalnej bazy wiedzy. Używaj go lokalnie na swoim komputerze lub synchronizuj swoje notatki na własnym serwerze i miej do nich dostęp gdziekolwiek jesteś.", + "get_started": "Start", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Zrzut ekranu wersji desktopowej Trilium Notes" + }, + "organization_benefits": { + "title": "Układ", + "note_structure_title": "Struktura notatek", + "note_structure_description": "Notatki mogą być ułożone w hierarchię. Każda notatka może zawierać w sobie inne, co pozwala umieścić tą samą notatkę w wielu miejscach w hierarchii i nie wymusza to tworzenia dodatkowych folderów.", + "attributes_title": "Etykiety i korelacje", + "attributes_description": "Porządkuj łatwiej swoje notatki przy użyciu relacji i etykiet, używaj ich jako odnośników w tabelach i tablicach.", + "hoisting_title": "Przestrzenie robocze i tryb skupienia", + "hoisting_description": "Łatwo oddziel swoje personalne notatki od tych z pracy przez grupowanie ich w przestrzenie robocze, które pomogą ci się skupić na danym temacie." + }, + "productivity_benefits": { + "title": "Produktywność i bezpieczeństwo", + "revisions_title": "Historia zmian", + "revisions_content": "Notatki są regularnie zapisywane w tle, pozwala to przeglądać i cofać wprowadzone zmiany. Zapisy można także wykonywać \"na życzenie\".", + "sync_title": "Synchronizacja", + "sync_content": "Używaj własnych lub chmurowych instancji do łatwiejszej synchronizacji notatek między wieloma urządzeniami, w tym twoim telefonem używając PWA.", + "protected_notes_title": "Notatki chronione", + "protected_notes_content": "Chroń wrażliwe informacje szyfrując notatki i blokując dostęp do nich za pomocą hasła sesji.", + "jump_to_title": "Szybkie wyszukiwanie i komendy", + "jump_to_content": "Szybko i łatwo wyszukuj swoje notatki używając funkcji lub komend, nawet gdy nie pamiętasz dokładnej ich nazwy.", + "search_title": "Dokładne wyszukiwanie", + "search_content": "Albo wyszukaj tekst w notatkach, możesz dostosować zakres szukania do konkretnej notatki albo hierarchii pliku.", + "web_clipper_title": "Web clipper", + "web_clipper_content": "Dołączaj strony internetowe albo ich zrzuty i umieszczaj je bezpośrednio w swoich notatkach dzięki rozszerzeniu do przeglądarki." + }, + "note_types": { + "text_title": "Notatki tekstowe", + "text_description": "Edytuj notatki w graficznym interfejsie (WYSIWYG), który wspiera tabele, obrazy, działania matematyczne i bloki kodu z podświetlaniem składni. Szybko formatuj tekst używając skrótów (Markdown), jak i komend (/).", + "code_title": "Notatki kodowe", + "code_description": "Duże fragmenty kodu Åŗródłowego albo skryptów można umieścić w dedykowanych plikach z własnym edytorem. Podświetlenie składni i struktur, różne motywy i wsparcie dla wielu języków programowania ułatwi edycję.", + "file_title": "Obsługa plików", + "file_description": "Dodawaj pliki takie jak PDF-y, zdjęcia i pliki wideo z podglądem w aplikacji.", + "canvas_title": "Płótno", + "canvas_description": "Dodawaj kształty, zdjęcia i tekst na nieskończonym płótnie, używając tej samej technologii co excalidraw.com. Idealne do diagramów, szkiców i projektowania.", + "mermaid_title": "Diagramy Mermaid", + "mermaid_description": "Twórz diagramy, takie jak schematy blokowe, diagramy klas i sekwencyjne, wykresy Gantta i wiele innych, korzystając z składni Mermaid.", + "mindmap_title": "Mapy myśli", + "mindmap_description": "Organizuj wizualnie swoje myśli albo przeprowadÅŗ sesję burzy mózgów.", + "others_list": "I wiele innych: <0>mapa notatek, <1>mapa powiązań, <2>zapisane wyszukiwania, <3>renderowane notatki i <4>podgląd stron www.", + "title": "Wiele sposobów przedstawienia Twoich informacji" + }, + "extensibility_benefits": { + "title": "Udostępnianie i rozszerzenia", + "import_export_title": "Import/Export", + "import_export_description": "Łatwa interakcja z innymi aplikacjami przy użyciu formatów Markdown, ENEX i OLM.", + "share_title": "Udostępniaj notatki w internecie", + "share_description": "Jeśli masz własny serwer, możesz go używać do udostępniania danych notatek z innymi.", + "scripting_title": "Zaawansowane skrypty", + "scripting_description": "Stwórz swoje własne integracje z Trilium przy użyciu personalizowanych widżetów albo z serwerowych skryptów.", + "api_title": "REST API", + "api_description": "Twórz integracje Trilium z użyciem REST API." + }, + "collections": { + "calendar_title": "Kalendarze", + "calendar_description": "Organizuj swoje prywatne i służbowe wydarzenia używając kalendarza. Miej plany pod kontrolą z tygodniowym, miesięcznym i rocznym podglądem. Twórz i edytuj wydarzenia w prosty i intuicyjny sposób.", + "table_title": "Tabele", + "table_description": "Wyświetlaj i edytuj informacje o notatkach w tabelach na wiele sposobów dzięki wielu typom kolumn: Tekstowym, numerycznym, z polami wyboru, z datami i godzinami, zawierającym linki, z kolorowymi wypełnieniami i powiązaniami notatek. Możesz nawet wyświetlić całe drzewo hierarchii w tabeli.", + "board_title": "Tablice Kanban", + "board_description": "Organizuj swoje zadania i postępy projektów w tablicach Kanban z prostym tworzeniem nowych elementów i kolumn, a możliwość graficznego ich przenoszenia ułatwi zmianę statusu i pozwoli zachować porządek.", + "geomap_title": "Mapy", + "geomap_description": "Zaplanuj wakacje albo interesujące miejsca bezpośrednio na mapie, używaj personalizowanych pinezek. Dzięki możliwości importu plików GPX możesz wyświetlać przebyte trasy.", + "title": "Kolekcje", + "presentation_title": "Prezentacje", + "presentation_description": "Zawrzyj informacje w slajdach i zaprezentuj je w pełnoekranowych prezentacjach, które możesz łatwo wyeksportować do plików PDF." + }, + "faq": { + "title": "Częste pytania", + "mobile_question": "Czy jest dostępna aplikacja mobilna?", + "mobile_answer": "Aktualnie nie ma oficjalnej aplikacji mobilnej, jednak jeśli posiadasz uruchomioną aplikacje na serwerze, to możesz mieć dostęp za pomocą przeglądarki, a nawet zainstalować ją jako PWA. Dla systemu android jest nieoficjalna aplikacja \"TriliumDroid\", która działa nawet w trybie offline (jak zwykła desktopowa).", + "database_question": "Gdzie są przechowywane moje dane?", + "database_answer": "Wszystkie twoje notatki są przechowywane w bazie danych SQLite, w folderze aplikacji (lokalnie). Trilium używa baz danych zamiast zwykłych plików tekstowych dla lepszej wydajności i niektórych funkcji, które byłoby trudno zaimplementować w inny sposób (np. ta sama notatka w wielu miejscach). Folder aplikacji możesz łatwo znaleźć w zakładce \"O programie\".", + "server_question": "Czy muszę posiadać serwer, aby używać Trilium?", + "server_answer": "Nie, serwer umożliwia dostęp do aplikacji z poziomu przeglądarki, i obsługuje synchronizację na wielu urządzeniach. Z początku wystarczającym rozwiązaniem jest aplikacja desktopowa.", + "scaling_question": "Jak dobrze aplikacja radzi sobie z dużą ilością notatek?", + "scaling_answer": "W zależności od użycia, aplikacja powinna być w stanie utrzymać bezproblemowo do 100 000 notatek. Trzeba zaznaczyć, że synchronizacja czasami może skończyć się niepowodzeniem w przypadku wielu plików ponad 1GB. Trilium jest bardziej przystosowane do tworzenia baz wiedzy, niż do jako katalog plików (np. NextCloud).", + "network_share_question": "Czy mogę udostępniać moje bazy danych przez dyski sieciowe?", + "network_share_answer": "Nie, ogólnie przesyłanie baz SQLite przez dyski sieciowe nie jest dobrym pomysłem. Czasami może to zadziałać, ale istnieje szansa, że taka baza danych może zostać uszkodzona przez niedoskonałości blokad plików w sieci.", + "security_question": "Jak są chronione moje dane?", + "security_answer": "Domyślnie notatki nie są szyfrowane i mogą być odczytane bezpośrednio z bazy danych. Kiedy notatka zostanie oznaczona jako zaszyfrowana, to ta notatka szyfrowana jest używając AES-128-CBC." + }, + "final_cta": { + "title": "Gotowy aby zacząć przygodę z Trilium Notes?", + "description": "Zbuduj swoją personalną bazę wiedzy z zaawansowanymi funkcjami i pełną prywatnością.", + "get_started": "Start" + }, + "components": { + "link_learn_more": "Dowiedz się więcej...." + }, + "download_now": { + "text": "Pobierz teraz ", + "platform_big": "v{{version}} dla {{platform}}", + "platform_small": "dla {{platform}}", + "linux_big": "v{{version}} dla Linuxa", + "linux_small": "dla Linuxa", + "more_platforms": "Więcej platform i konfiguracja serwera" + }, + "footer": { + "copyright_and_the": " i ", + "copyright_community": "społeczność" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "GitHub - Forum", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "support_us": { + "title": "Wesprzyj nas", + "financial_donations_title": "Wsparcie finansowe", + "financial_donations_description": "Trilium jest tworzone i rozwijane przez setki godzin pracy. Twoje wsparcie utrzymuje projekt jako otwartoÅŗródłowy, pomaga dodawać nowe rzeczy i pokrywa koszty hostingu.", + "financial_donations_cta": "Rozważ wsparcie głównego programisty (eliandoran) poza aplikacją przez:", + "github_sponsors": "GitHub Sponsors", + "paypal": "PayPal", + "buy_me_a_coffee": "Postaw mi wirtualną kawę" + }, + "contribute": { + "title": "Inne sposoby wsparcia", + "way_translate": "Przetłumacz aplikacja na swój natywny język przez Weblate.", + "way_community": "Dołącz do społeczności na GitHub Discussions lub na Matrix.", + "way_reports": "Zgłoś błędy przez GitHub issues.", + "way_document": "Pomóż nam w doskonaleniu dokumentacji przez informowanie nas o lukach albo sam pomóż w tworzeniu treści (dokumentacja, FAQ, poradniki).", + "way_market": "Powiedz o nas swoim znajomym, na blogu albo na social mediach." + }, + "404": { + "title": "404: Nie znaleziono strony", + "description": "Strona, której szukasz, nie istnieje. Mogła zostać usunięta, albo wpisany adres jest niepoprawny." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64-bit", + "title_arm64": "Windows na ARM", + "description_x64": "Kompatybilne z urządzeniami Intel i AMD działającymi pod kontrolą Windows 10 i 11.", + "description_arm64": "Kompatybilne z procesorami ARM (np. Qualcomm Snapdragon).", + "quick_start": "Aby zainstalować przez WinGet:", + "download_exe": "Pobierz instalator (.exe)", + "download_zip": "Wersja przenośna - Portable (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64-bit", + "title_arm64": "Linux na ARM", + "description_x64": "Dla większości dystrybucji Linux, kompatybilnych z architekturą x86_64.", + "description_arm64": "Dla dystrybucji ARM Linux kompatybilnych z architekturą aarch64.", + "quick_start": "Wybierz odpowiedni format paczki, w zależności od twojej dystrybucji:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "Wersja przenośna - Portable (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS z Intel", + "title_arm64": "macOS z Apple Silicon (ARM)", + "description_x64": "Dla macOS w wersji Big Sur i późniejszymi, z procesorem Intel.", + "description_arm64": "Dla produktów Apple z procesorami M1 i M2.", + "quick_start": "Instalacja przez Homebrew:", + "download_dmg": "Pobierz instalator (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "Wersja przenośna - Portable (.zip)" + }, + "download_helper_server_docker": { + "title": "Własny serwer przez Docker", + "description": "Łatwa instalacja na Windows, Linux albo macOS używając Docker container.", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "Własny serwer na Linux", + "description": "Wrzuć Trilium Notes na swój serwer albo VPS, kompatybilne z większością dystrybucji.", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "moduł NixOS" + }, + "download_helper_server_hosted": { + "title": "Płatny Serwer - Hosting", + "description": "Trilium Notes hostowane na PikaPods, płatnym serwisie dla łatwego dostępu i zarządzania. Bezpośrednio nie związanie z Trilium team.", + "download_pikapod": "Konfiguruj na PikaPods", + "download_triliumcc": "Alternatywnie patrz na trilium.cc" + }, + "header": { + "get-started": "Start", + "documentation": "Dokumentacja", + "support-us": "Wesprzyj nas", + "resources": "Zasoby" + }, + "resources": { + "title": "Zasoby", + "icon_packs": "Paczki ikon", + "icon_packs_intro": "Rozszerz wybór dostępnych ikon dla swoich notatek, korzystając z pakietu ikon. Więcej informacji na temat pakietów ikon znajdziesz w oficjalnej dokumentacji .", + "download": "Pobieranie", + "website": "Strona internetowa" + } +} diff --git a/apps/website/src/translations/pt-BR/translation.json b/apps/website/src/translations/pt-BR/translation.json new file mode 100644 index 0000000000..54325686b9 --- /dev/null +++ b/apps/website/src/translations/pt-BR/translation.json @@ -0,0 +1,200 @@ +{ + "get-started": { + "title": "Primeiros passos", + "desktop_title": "Baixar o aplicativo para desktop (v{{version}})", + "architecture": "Arquitetura:", + "older_releases": "Ver versƵes anteriores", + "server_title": "Configurar um servidor para acessar em vĆ”rios dispositivos" + }, + "hero_section": { + "title": "Organize seus pensamentos. Crie sua base de conhecimento pessoal.", + "subtitle": "Trilium Ć© uma solução de código aberto para fazer anotaƧƵes e organizar uma base de conhecimento pessoal. Use localmente no seu desktop ou sincronize com seu servidor auto-hospedado para manter suas notas onde quer que vocĆŖ vĆ”.", + "get_started": "Primeiros passos", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Captura de tela do aplicativo Trilium Notes para desktop" + }, + "organization_benefits": { + "title": "Organização", + "note_structure_title": "Estrutura de notas", + "note_structure_description": "As notas podem ser organizadas hierarquicamente. NĆ£o hĆ” necessidade de pastas, jĆ” que cada nota pode conter subnotas. Uma mesma nota pode ser adicionada em vĆ”rios lugares na hierarquia.", + "attributes_title": "Rótulos e relacionamentos das notas", + "attributes_description": "Use relaƧƵes entre notas ou adicione rótulos para facilitar a categorização. Use atributos promovidos para inserir informaƧƵes estruturadas que podem ser usadas em tabelas e quadros.", + "hoisting_title": "EspaƧos de trabalho e hoisting", + "hoisting_description": "Separe facilmente suas notas pessoais e de trabalho agrupando-as em um espaƧo de trabalho, que foca sua Ć”rvore de notas para exibir apenas um conjunto especĆ­fico de notas." + }, + "productivity_benefits": { + "title": "Produtividade e seguranƧa", + "revisions_title": "RevisƵes de notas", + "revisions_content": "As notas sĆ£o salvas periodicamente em segundo plano, e as revisƵes podem ser usadas para revisar ou desfazer alteraƧƵes acidentais. RevisƵes tambĆ©m podem ser criadas sob demanda.", + "sync_title": "Sincronização", + "sync_content": "Use uma instĆ¢ncia auto-hospedada ou na nuvem para sincronizar facilmente suas notas entre vĆ”rios dispositivos e acessĆ”-las no celular usando um PWA.", + "protected_notes_title": "Notas protegidas", + "protected_notes_content": "Proteja informaƧƵes pessoais sensĆ­veis criptografando as notas e bloqueando-as com uma sessĆ£o protegida por senha.", + "jump_to_title": "Busca rĆ”pida e comandos", + "jump_to_content": "VĆ” rapidamente para notas ou comandos da interface em toda a hierarquia pesquisando pelo tĆ­tulo, com correspondĆŖncia aproximada para lidar com erros de digitação ou pequenas diferenƧas.", + "search_title": "Busca poderosa", + "search_content": "Ou pesquise texto dentro das notas e refine a busca filtrando pela nota pai ou pela profundidade.", + "web_clipper_title": "Web Clipper", + "web_clipper_content": "Capture pĆ”ginas da web (ou capturas de tela) e insira-as diretamente no Trilium usando a extensĆ£o de navegador do Web Clipper." + }, + "note_types": { + "title": "VĆ”rias formas de representar suas informaƧƵes", + "text_title": "Notas de texto", + "text_description": "As notas sĆ£o editadas usando um editor visual (WYSIWYG), com suporte a tabelas, imagens, expressƵes matemĆ”ticas e blocos de código com realce de sintaxe. Formate rapidamente o texto usando sintaxe semelhante ao Markdown ou usando comandos de barra.", + "code_title": "Notas de código", + "code_description": "Amostras grandes de código-fonte ou scripts usam um editor dedicado, com realce de sintaxe para muitas linguagens de programação e diversos temas de cores.", + "file_title": "Notas de arquivo", + "file_description": "Incorpore arquivos multimĆ­dia como PDFs, imagens e vĆ­deos, com uma visualização dentro do aplicativo.", + "canvas_title": "Canvas", + "canvas_description": "Organize formas, imagens e texto em um canvas infinito, usando a mesma tecnologia por trĆ”s do excalidraw.com. Ideal para diagramas, esboƧos e planejamento visual.", + "mermaid_title": "Diagramas Mermaid", + "mermaid_description": "Crie diagramas como fluxogramas, diagramas de classe e de sequĆŖncia, grĆ”ficos de Gantt e muitos outros, usando a sintaxe Mermaid.", + "mindmap_title": "Mapa mental", + "mindmap_description": "Organize seus pensamentos de forma visual ou faƧa uma sessĆ£o de brainstorming.", + "others_list": "e outros: <0>mapa de notas, <1>mapa de relaƧƵes, <2>buscas salvas, <3>renderizar nota, e <4>visualizaƧƵes web." + }, + "extensibility_benefits": { + "title": "Compartilhamento e extensibilidade", + "import_export_title": "Importar/exportar", + "import_export_description": "Interaja facilmente com outros aplicativos usando os formatos Markdown, ENEX e OML.", + "share_title": "Compartilhe notas na web", + "share_description": "Se vocĆŖ tiver um servidor, ele pode ser usado para compartilhar um subconjunto das suas notas com outras pessoas.", + "scripting_title": "Scripts avanƧados", + "scripting_description": "Crie suas próprias integraƧƵes no Trilium com widgets personalizados ou lógica do lado do servidor.", + "api_title": "REST API", + "api_description": "Interaja com o Trilium programaticamente usando sua API REST integrada." + }, + "collections": { + "title": "ColeƧƵes", + "calendar_title": "CalendĆ”rio", + "calendar_description": "Organize seus eventos pessoais ou profissionais usando um calendĆ”rio, com suporte a eventos de dia inteiro e de mĆŗltiplos dias. Veja seus eventos rapidamente nas visualizaƧƵes de semana, mĆŖs e ano. Interação simples para adicionar eventos ou arrastĆ”-los.", + "table_title": "Tabela", + "table_description": "Exiba e edite informaƧƵes sobre notas em uma estrutura tabular, com vĆ”rios tipos de coluna, como texto, nĆŗmero, caixas de seleção, data e hora, links e cores, alĆ©m de suporte a relaƧƵes. Opcionalmente, exiba as notas dentro de uma hierarquia em Ć”rvore na tabela.", + "board_title": "Quadro Kanban", + "board_description": "Organize suas tarefas ou o status do projeto em um quadro Kanban, com uma forma simples de criar novos itens e colunas e alterar o status arrastando-os pelo quadro.", + "geomap_title": "Geomapa", + "geomap_description": "Planeje suas fĆ©rias ou marque seus pontos de interesse diretamente em um mapa geogrĆ”fico usando marcadores personalizĆ”veis. Exiba trilhas GPX gravadas para acompanhar itinerĆ”rios.", + "presentation_title": "Apresentação", + "presentation_description": "Organize informaƧƵes em slides e apresente em tela cheia com transiƧƵes suaves. Os slides tambĆ©m podem ser exportados para PDF para facilitar o compartilhamento." + }, + "faq": { + "title": "Perguntas frequentes", + "mobile_question": "Existe um aplicativo móvel?", + "mobile_answer": "Atualmente nĆ£o existe um aplicativo móvel oficial. No entanto, se vocĆŖ tiver uma instĆ¢ncia de servidor, pode acessĆ”-lo usando um navegador e atĆ© instalĆ”-lo como um PWA. Para Android, existe um aplicativo nĆ£o oficial chamado TriliumDroid que inclusive funciona offline (assim como um cliente de desktop).", + "database_question": "Onde os dados sĆ£o armazenados?", + "database_answer": "Todas as suas notas serĆ£o armazenadas em um banco de dados SQLite em uma pasta do aplicativo. O motivo de o Trilium usar um banco de dados em vez de arquivos de texto simples Ć© tanto desempenho quanto o fato de que alguns recursos seriam muito mais difĆ­ceis de implementar, como clones (a mesma nota em vĆ”rios lugares da Ć”rvore). Para encontrar a pasta do aplicativo, basta ir atĆ© a janela Sobre.", + "server_question": "Eu preciso de um servidor para usar o Trilium?", + "server_answer": "NĆ£o. O servidor permite acesso via navegador e gerencia a sincronização se vocĆŖ tiver vĆ”rios dispositivos. Para comeƧar, basta baixar o aplicativo para desktop e comeƧar a usĆ”-lo.", + "scaling_question": "QuĆ£o bem o aplicativo escala com uma grande quantidade de notas?", + "scaling_answer": "Dependendo do uso, o aplicativo deve ser capaz de lidar com pelo menos 100.000 notas sem problemas. Observe que o processo de sincronização Ć s vezes pode falhar ao enviar muitos arquivos grandes (1 GB por arquivo), jĆ” que o Trilium Ć© mais uma aplicação de base de conhecimento do que um armazenamento de arquivos (como o NextCloud, por exemplo).", + "network_share_question": "Posso compartilhar meu banco de dados em uma unidade de rede?", + "network_share_answer": "NĆ£o. Em geral, nĆ£o Ć© uma boa ideia compartilhar um banco de dados SQLite em uma unidade de rede. Embora Ć s vezes possa funcionar, hĆ” chances de o banco de dados ser corrompido devido a bloqueios de arquivo imperfeitos na rede.", + "security_question": "Como meus dados sĆ£o protegidos?", + "security_answer": "Por padrĆ£o, as notas nĆ£o sĆ£o criptografadas e podem ser lidas diretamente do banco de dados. Depois que uma nota Ć© marcada como criptografada, ela Ć© criptografada usando AES-128-CBC." + }, + "final_cta": { + "title": "Pronto para comeƧar com o Trilium Notes?", + "description": "Crie sua base de conhecimento pessoal com recursos poderosos e privacidade total.", + "get_started": "Primeiros passos" + }, + "components": { + "link_learn_more": "Saiba mais..." + }, + "download_now": { + "text": "Baixar agora ", + "platform_big": "v{{version}} para {{platform}}", + "platform_small": "para {{platform}}", + "linux_big": "v{{version}} para Linux", + "linux_small": "para Linux", + "more_platforms": "Mais plataformas e configuração de servidor" + }, + "header": { + "get-started": "Primeiros passos", + "documentation": "Documentação", + "support-us": "Apoie-nos" + }, + "footer": { + "copyright_and_the": " e a ", + "copyright_community": "comunidade" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "DiscussƵes no GitHub", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "support_us": { + "title": "Apoie-nos", + "financial_donations_title": "DoaƧƵes financeiras", + "financial_donations_description": "O Trilium Ć© desenvolvido e mantido com centenas de horas de trabalho. Seu apoio mantĆ©m o projeto de código aberto, melhora recursos e cobre custos como hospedagem.", + "financial_donations_cta": "Considere apoiar o principal desenvolvedor (eliandoran) do aplicativo por meio de:", + "github_sponsors": "GitHub Sponsors", + "paypal": "PayPal", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "contribute": { + "title": "Outras formas de contribuir", + "way_translate": "Traduza o aplicativo para o seu idioma nativo via Weblate.", + "way_community": "Interaja com a comunidade em GitHub Discussions ou no Matrix.", + "way_reports": "Reporte bugs via GitHub issues.", + "way_document": "Melhore a documentação informando lacunas ou contribuindo com guias, FAQs ou tutoriais.", + "way_market": "Divulgue: compartilhe o Trilium Notes com amigos ou em blogs e redes sociais." + }, + "404": { + "title": "404: NĆ£o encontrado", + "description": "A pĆ”gina que vocĆŖ procurava nĆ£o foi encontrada. Talvez tenha sido excluĆ­da ou a URL esteja incorreta." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64 bits", + "title_arm64": "Windows no ARM", + "description_x64": "CompatĆ­vel com dispositivos Intel ou AMD executando Windows 10 e 11.", + "description_arm64": "CompatĆ­vel com dispositivos ARM (ex.: com Qualcomm Snapdragon).", + "quick_start": "Para instalar via Winget:", + "download_exe": "Baixar instalador (.exe)", + "download_zip": "PortĆ”til (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64 bits", + "title_arm64": "Linux no ARM", + "description_x64": "Para a maioria das distribuiƧƵes Linux, compatĆ­vel com a arquitetura x86_64.", + "description_arm64": "Para distribuiƧƵes Linux baseadas em ARM, compatĆ­vel com a arquitetura aarch64.", + "quick_start": "Selecione um formato de pacote apropriado, dependendo da sua distribuição:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "PortĆ”til (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS para Intel", + "title_arm64": "macOS para Apple Silicon", + "description_x64": "Para Macs baseados em Intel executando macOS Monterey ou posterior.", + "description_arm64": "Para Macs com Apple Silicon, como os com chips M1 e M2.", + "quick_start": "Para instalar via Homebrew:", + "download_dmg": "Baixar instalador (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "PortĆ”til (.zip)" + }, + "download_helper_server_docker": { + "title": "Auto-hospedado usando Docker", + "description": "Implante facilmente no Windows, Linux ou macOS usando um contĆŖiner Docker.", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "Auto-hospedado no Linux", + "description": "Implante o Trilium Notes no seu próprio servidor ou VPS, compatĆ­vel com a maioria das distribuiƧƵes.", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "Módulo NixOS" + }, + "download_helper_server_hosted": { + "title": "Hospedagem paga", + "description": "Trilium Notes hospedado no PikaPods, um serviƧo pago para facilitar o acesso e o gerenciamento. NĆ£o Ć© diretamente afiliado Ć  equipe do Trilium.", + "download_pikapod": "Configurar no PikaPods", + "download_triliumcc": "Ou veja trilium.cc" + } +} diff --git a/apps/website/src/translations/pt/translation.json b/apps/website/src/translations/pt/translation.json new file mode 100644 index 0000000000..a4436fba70 --- /dev/null +++ b/apps/website/src/translations/pt/translation.json @@ -0,0 +1,22 @@ +{ + "get-started": { + "title": "ComeƧar", + "architecture": "Arquitetura:", + "older_releases": "Ver versƵes anteriores", + "server_title": "Configurar um servidor para aceder a partir de vĆ”rios dispositivos" + }, + "hero_section": { + "title": "Organiza as tuas ideias. Constrói a tua base de conhecimento pessoal.", + "subtitle": "O Trilium Ć© uma solução de código aberto para tomar notas e organizar a tua base de conhecimento pessoal. Usa-o localmente no teu computador ou sincroniza-o com o teu próprio servidor para teres as tuas notas acessĆ­veis em qualquer lugar.", + "get_started": "ComeƧar", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Captura de ecrĆ£ da aplicação Trilium Notes para computador" + }, + "organization_benefits": { + "title": "Organização", + "note_structure_description": "As notas podem ser organizadas de forma hierĆ”rquica. NĆ£o hĆ” necessidade de pastas, pois cada nota pode conter sub notas. Uma Ćŗnica nota pode ser adicionada em vĆ”rios locais da hierarquia.", + "attributes_description": "Utiliza relaƧƵes entre notas ou adiciona etiquetas para uma categorização fĆ”cil. Usa atributos promovidos para inserir informação estruturada, que pode ser utilizada em tabelas ou quadros.", + "hoisting_description": "Separa facilmente as tuas notas pessoais e de trabalho agrupando-as num espaƧo de trabalho, que focaliza a Ć”rvore de notas para mostrar apenas um conjunto especĆ­fico de notas." + } +} diff --git a/apps/website/src/translations/ro/translation.json b/apps/website/src/translations/ro/translation.json new file mode 100644 index 0000000000..538ca10b6b --- /dev/null +++ b/apps/website/src/translations/ro/translation.json @@ -0,0 +1,200 @@ +{ + "get-started": { + "title": "Primii pași", + "desktop_title": "Descărcați aplicația desktop (v{{version}})", + "architecture": "Arhitectură:", + "older_releases": "Versiuni mai vechi", + "server_title": "Versiunea server, pentru acces pe mai multe dispozitive" + }, + "hero_section": { + "title": "Organizați-vă gĆ¢ndurile. Construiți-vă propria bază de cunoștințe digitală.", + "subtitle": "Trilium este o aplicație open-source pentru notițe și pentru organizarea unei baze de cunoștințe personală. Se poate folosi local pe desktop sau se poate sincroniza cu un server găzduit de dvs. pentru a putea accesa notițele de oriunde.", + "get_started": "Primii pași", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Captură de ecran a aplicației de desktop Trilium Notes" + }, + "organization_benefits": { + "title": "Funcții de organizare", + "note_structure_title": "Structura notițelor", + "note_structure_description": "Notițele pot fi aranjate ierarhic. Nu este nevoie de dosare, deoarece fiecare notiță poate conține sub-notițe. O singură notiță poate fi adăugată Ć®n mai multe locuri Ć®n ierarhie.", + "attributes_title": "Etichete și relații pentru notițe", + "attributes_description": "Folosiți relațiile dintre notițe sau adăugați etichete pentru o categorizare ușoară. Folosiți atribute promovate pentru a introduce informații structurate ce pot fi utilizate ulterior Ć®n tabele sau table Kanban.", + "hoisting_title": "Spații de lucru și focalizare", + "hoisting_description": "Separați cu ușurință notițele personale și de muncă prin gruparea lor Ć®ntr-un spațiu de lucru, ce focalizează arborele de notițe astfel Ć®ncĆ¢t afișează un anumit set de notițe." + }, + "productivity_benefits": { + "title": "Productivitate și siguranță", + "revisions_title": "Revizii ale notițelor", + "revisions_content": "Notițele sunt salvate periodic Ć®n fundal, iar reviziile acestora pot fi utilizate pentru comparație sau pentru a anula modificări accidentale. Reviziile pot fi create și manual.", + "sync_title": "Sincronizare", + "sync_content": "Folosiți o instanță găzduită de dvs. sau Ć®n cloud pentru a putea sincroniza rapid notițele Ć®ntre mai multe dispozitive și pentru a putea să le accesați utilizĆ¢nd telefonul mobil (prin PWA).", + "protected_notes_title": "Notițe protejate", + "protected_notes_content": "Protejați informațiile personale prin criptarea acestora Ć®n spatele unei sesiuni protejate prin parolă.", + "jump_to_title": "Căutare și comenzi rapide", + "jump_to_content": "Navigați rapid printre notițe sau comenzi căutĆ¢nd după numele acestora, avĆ¢nd căutare de tip fuzzy pentru a ignora greșeli de tastare sau diferențe minore.", + "search_title": "Căutare performantă", + "search_content": "Căutați Ć®n interiorul notițelor și reduceți numărul de rezultate prin filtrarea după notița părinte, sau după adĆ¢ncime.", + "web_clipper_title": "Clipper web", + "web_clipper_content": "Preluați pagini web (sau capturi de ecran), care vor apărea direct Ć®n Trilium utilizĆ¢nd extensia de browser ā€žClipper webā€." + }, + "note_types": { + "text_title": "Notițe de tip text", + "text_description": "Aceste notițe sunt editate printr-un editor vizual (WYSIWYG), cu suport pentru tabele, imagini, expresii matematice și blocuri de cod cu evidențierea sintaxei. Formatați rapid textul folosind sintaxă similară cu Markdown sau folosind comenzi la tasta slash.", + "code_title": "Notițe de tip cod", + "code_description": "Stocați secvențe mari de cod sau script-uri utilizĆ¢nd un editor dedicat, cu evidențierea sintaxei pentru multe limbaje de programare și multiple teme de culori.", + "file_title": "Notițe de tip fișier", + "file_description": "Adăugați fișiere multimedia precum PDF-uri, imagini și video-uri cu previzualizare direct Ć®n aplicație.", + "canvas_title": "Schițe", + "canvas_description": "Aranjați forme geometrice, imagini și text pe o schiță infinită, utilizĆ¢nd aceeași tehnologie din spatele excalidraw.com. Ideală pentru diagrame, desene și planificare vizuală.", + "mermaid_title": "Diagrame Mermaid", + "mermaid_description": "Creați diagrame precum flowchart-uri, diagrame de secvență sau de clase, Gantt și multe altele, folosind sintaxa Mermaid.", + "mindmap_title": "Hartă mentală", + "mindmap_description": "Organizați-vă gĆ¢ndurile vizual sau organizați o sesiune de brainstorming.", + "others_list": "și altele: <0>hartă a notițelor, <1>hartă a relațiilor, <2>căutări salvate, <3>randare a notițelor, și <4>vizualizări web.", + "title": "Multiple modalități de a reprezenta informația" + }, + "extensibility_benefits": { + "title": "Partajare și extensibilitate", + "import_export_title": "Import/export", + "import_export_description": "Interacționați rapid cu alte aplicații utilizĆ¢nd formatele Markdown, ENEX și OML.", + "share_title": "Publicați notițe pe Internet", + "share_description": "Dacă aveți o instanță de server, puteți să partajați pe Internet un set de notițe.", + "scripting_title": "Script-are avansată", + "scripting_description": "Construiți-vă propriile integrări cu Trilium utilizĆ¢nd widget-uri personalizate sau logică la nivel de server.", + "api_title": "API REST", + "api_description": "Interacționați cu Trilium programatic folosind API-ul REST integrat." + }, + "collections": { + "calendar_title": "Calendar", + "calendar_description": "Organizați-vă evenimentele personale sau profesionale folosind un calendar, cu suport pentru evenimente pe toată ziua sau chiar pe mai multe zile. Vedeți evenimentele cu ușurință la nivel de săptămĆ¢nă, lună sau an. Interacțiune ușoară pentru a adăuga sau muta evenimente.", + "table_title": "Tabel", + "table_description": "Afișați și editați informații despre notițe Ć®ntr-o structură tabelară, cu multiple tipuri de coloane precum text, număr, bife, dată și timp, link-uri, culori și suport pentru relații. Opțional se poate afișa și structura ierarhică a notițelor Ć®n interiorul tabelului.", + "board_title": "Tabelă Kanban", + "board_description": "Organizați-vă sarcinile sau proiectele Ć®ntr-o tabelă Kanban cu o modalitate ușoară de a adăuga elemente și coloane noi și schimbarea stării acestora prin glisare cu mouse-ul.", + "geomap_title": "Hartă geografică", + "geomap_description": "Planificați-vă vacanțele sau marcați-vă punctele de interes direct pe o hartă geografică. Afișați traseele GPX Ć®nregistrate pentru a putea urmări itinerarii.", + "title": "Colecții", + "presentation_title": "Prezentare", + "presentation_description": "Organizați informația Ć®n diapozitive și prezentați-le pe tot ecranul, cu tranziții fine. Diapozitivele pot fi ulterior exportate ca PDF pentru o partajare ușoară." + }, + "faq": { + "title": "Ǝntrebări frecvente", + "mobile_question": "Există o aplicație de mobil?", + "mobile_answer": "Ǝn momentul de față nu există o aplicație de mobil oficială. Totuși, dacă aveți o instanță de server o puteți accesa folosind un navigator web și o puteți instala ca un PWA. Pentru Android, există o aplicație neoficială denumită TriliumDroid care poate funcționa chiar și offline (similar cu aplicația de desktop).", + "database_question": "Unde sunt stocate datele?", + "database_answer": "Toate notițele sunt stocate Ć®ntr-o bază de date SQLite la nivelul unui dosar al aplicației. Motivul pentru care Trilium folosește o bază de date Ć®n locul de fișiere text este legat de performanță și deoarece unele funcții ar fi fost mult mai greu de replicat precum clone (aceeași notițe Ć®n mai multe locuri). Pentru a găsi folder-ul aplicației, mergeți Ć®n fereastra ā€žDespreā€.", + "server_question": "Am nevoie de un server să folosesc Trilium?", + "server_answer": "Nu, server-ul permite accesarea printr-un browser web și coordonează sincronizarea dacă aveți dispozitive multiple. Pentru Ć®nceput este suficient să descărcați aplicația de desktop și s-o folosiți.", + "scaling_question": "CĆ¢t de bine suportă aplicația un număr mare de notițe?", + "scaling_answer": "Ǝn funcție de modul de utilizare, aplicația ar trebui să suporte cel puțin 100.000 de notițe fără probleme. De avut Ć®n vedere faptul că procesul de sincronizare poate eșua dacă se Ć®ncarcă prea multe fișiere mari (ex. 1 GB per fișier) deoarece Trilium este prevăzut mai mult ca o aplicație de bază de cunoștințe decĆ¢t de stocare a fișierelor (precum NextCloud, spre exemplu).", + "network_share_question": "Pot partaja baza mea de date pe rețea?", + "network_share_answer": "Nu, nu este o idee bună să partajați o bază de date SQLite pe rețea. Deși uneori poate funcționa, sunt șanse mari ca baza de date să se corupă din cauza sistemului de blocare al fișierului la nivel de rețea.", + "security_question": "Cum sunt datele mele protejate?", + "security_answer": "Ǝn mod implicit, notițele nu sunt criptate și pot fi citite direct din baza de date. Odată ce o notiță este marcată drept protejată, conținutul este criptat folosind AES-128-CBC." + }, + "final_cta": { + "title": "Gata de a folosi Trilium Notes?", + "description": "Construiți-vă baza de cunoștințe personală cu funcții puternice și intimitate maximă.", + "get_started": "Ǝncepe" + }, + "components": { + "link_learn_more": "Mai multe detalii..." + }, + "download_now": { + "text": "Descărcați acum ", + "platform_big": "v{{version}} pentru {{platform}}", + "platform_small": "pentru {{platform}}", + "linux_big": "v{{version}} pentru Linux", + "linux_small": "pentru Linux", + "more_platforms": "Mai multe platforme și instalarea server-ului" + }, + "header": { + "get-started": "Primii pași", + "documentation": "Documentație", + "support-us": "Sprijină-ne" + }, + "footer": { + "copyright_and_the": " și ", + "copyright_community": "comunitatea" + }, + "support_us": { + "title": "Sprijină-ne", + "financial_donations_title": "Donații financiare", + "financial_donations_description": "Trilium este construit și menținut prin sute de ore de muncă. Sprijinul dvs. ne ajută să-l menținem open-source, să Ć®mbunătățim funcțiile și să acoperim costuri precum găzduirea.", + "financial_donations_cta": "Considerați sprijinirea dezvoltatorului principal al aplicației (eliandoran) prin:", + "github_sponsors": "Sponsori GitHub", + "paypal": "PayPal", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "contribute": { + "title": "Alte modalități de a contribui", + "way_translate": "Traduceți aplicația Ć®ntr-o limbă străină prin Weblate.", + "way_community": "Interacționați cu comunitatea pe Discuții GitHub sau pe Matrix.", + "way_reports": "Raportați bug-uri prin GitHub Issues.", + "way_document": "Ǝmbunătățiți documentația prin a ne informa de lacune Ć®n documentație sau prin a contribui ghiduri, Ć®ntrebări frecvente și tutoriale.", + "way_market": "Informați-vă prietenii, colegii despre Trilium Notes sau prin blog-uri și social media." + }, + "404": { + "title": "404: Nu s-a găsit pagina", + "description": "Pagina pe care ați căutat-o nu a putut fi găsită. Posibil să fi fost ștearsă sau URL-ul să fie incorect." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64 biți", + "title_arm64": "Windows pe ARM", + "description_x64": "Compatibil cu dispozitive Intel sau AMD ce rulează Windows 10 și 11.", + "description_arm64": "Compatibil cu dispozitive ARM (ex. cu Qualcomm Snapdragon).", + "quick_start": "Instalare prin Winget:", + "download_exe": "Descarcă Installer (.exe)", + "download_zip": "Portabil (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64 biți", + "title_arm64": "Linux pe ARM", + "description_x64": "Pentru majoritatea distribuțiilor, compatibilă cu arhitectura x86_64.", + "description_arm64": "Pentru distribuțiile bazate pe ARM, compatibilă cu arhitectura aarch64.", + "quick_start": "Selectați un format de Ć®mpachetare potrivit pentru distribuția dvs.:", + "download_deb": ".deb", + "download_zip": "Portabil (.zip)", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS pentru Intel", + "title_arm64": "macOS pentru Apple Silicon", + "description_x64": "Pentru Mac-uri bazate pe Intel ce rulează macOS Monterey sau mai nou.", + "description_arm64": "Pentru Mac-uri bazate pe Apple Silicon, precum cele cu chip-uri M1, M2.", + "quick_start": "Instalați prin Homebrew:", + "download_dmg": "Descarcă instalatorul (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "Portabil (.zip)" + }, + "download_helper_server_docker": { + "title": "Găzduit Ć®n regim propriu prin Docker", + "description": "Lansați rapid o instanță pe Windows, Linux sau macOS folosind un container Docker.", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "Găzduit Ć®n regim propriu pe Linux", + "description": "Rulați Trilium Notes pe propriul server sau VPS, compatibil cu majoritatea distribuțiilor.", + "download_tar_x64": "x64 (.tar.xz)", + "download_nixos": "Modul NixOS", + "download_tar_arm64": "ARM (.tar.xz)" + }, + "download_helper_server_hosted": { + "title": "Găzduire contra cost", + "description": "Trilium Notes găzduit pe PikaPods, un serviciu plătit pentru acces facil. Nu este direct afiliat cu echipa Trilium.", + "download_pikapod": "Folosește PikaPods", + "download_triliumcc": "Alternativ, trilium.cc" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "GitHub Discussions", + "matrix": "Matrix", + "reddit": "Reddit" + } +} diff --git a/apps/website/src/translations/ru/translation.json b/apps/website/src/translations/ru/translation.json new file mode 100644 index 0000000000..ae2d1fbde1 --- /dev/null +++ b/apps/website/src/translations/ru/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "title": "ŠŠ°Ń‡Š°Š»Š¾ работы", + "desktop_title": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ приложение (v{{version}})", + "architecture": "ŠŃ€Ń…ŠøŃ‚ŠµŠŗŃ‚ŃƒŃ€Š°:", + "older_releases": "Дм. старые релизы", + "server_title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° сервера Š“Š»Ń работы с Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøŃ… ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²" + }, + "hero_section": { + "title": "Š£ŠæŠ¾Ń€ŃŠ“Š¾Ń‡ŠøŃ‚Šµ свои мысли. ДозГайте Š»ŠøŃ‡Š½ŃƒŃŽ базу знаний.", + "subtitle": "Trilium - ŃŃ‚Š¾ open-source Ń€ŠµŃˆŠµŠ½ŠøŠµ Š“Š»Ń заметок Šø организации личной базы знаний. Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ его локально, или ŃŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·ŠøŃ€ŃƒŠ¹Ń‚ŠµŃŃŒ с собственным сервером, чтобы ваши заметки всегГа были с вами.", + "get_started": "ŠŠ°Ń‡Š°Š»Š¾ работы", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Š”ŠŗŃ€ŠøŠ½ŃˆŠ¾Ń‚ ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ Trilium Notes Š“Š»Ń Š½Š°ŃŃ‚Š¾Š»ŃŒŠ½Š¾Š³Š¾ ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ" + }, + "organization_benefits": { + "title": "Š”Ń‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š°", + "note_structure_title": "Š”Ń‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š° заметки", + "note_structure_description": "Дтроки Š¼Š¾Š³ŃƒŃ‚ Ń€Š°ŃŠæŠ¾Š»Š°Š³Š°Ń‚ŃŒŃŃ иерархически. ŠŠµ нужно ŃŠ¾Š·Š“Š°Š²Š°Ń‚ŃŒ папки, так как ŠŗŠ°Š¶Š“Š°Ń заметка сама может ŃŠ¾Š“ŠµŃ€Š¶Š°Ń‚ŃŒ вложенные заметки. ŠžŠ“Š½Ńƒ Šø ту же Š·Š°Š¼ŠµŃ‚ŠŗŃƒ можно Ń€Š°Š·Š¼ŠµŃŃ‚ŠøŃ‚ŃŒ ŃŃ€Š°Š·Ńƒ в Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøŃ… местах в иерархии.", + "attributes_title": "Ярлыки Šø ŃŠ²ŃŠ·Šø заметок", + "hoisting_title": "Рабочие пространства Šø режим Ń„Š¾ŠŗŃƒŃŠ°", + "hoisting_description": "Легко Ń€Š°Š·Š“ŠµŠ»ŃŠ¹Ń‚Šµ заметки на личные Šø рабочие, Š³Ń€ŃƒŠæŠæŠøŃ€ŃƒŃ ŠøŃ… в рабочей области. Š‘Š»Š°Š³Š¾Š“Š°Ń€Ń ŃŃ‚Š¾Š¼Ńƒ в вашем Гереве Š±ŃƒŠ“ет Š¾Ń‚Š¾Š±Ń€Š°Š¶Š°Ń‚ŃŒŃŃ Ń‚Š¾Š»ŃŒŠŗŠ¾ опреГелённый набор заметок.", + "attributes_description": "Устанавливайте ŃŠ²ŃŠ·Šø межГу заметками или Š“Š¾Š±Š°Š²Š»ŃŠ¹Ń‚Šµ метки Š“Š»Ń уГобной категоризации. Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ Ń€Š°ŃŃˆŠøŃ€ŠµŠ½Š½Ń‹Šµ Š°Ń‚Ń€ŠøŠ±ŃƒŃ‚Ń‹ Š“Š»Ń ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€ŠøŠ·Š°Ń†ŠøŠø информации, ŠŗŠ¾Ń‚Š¾Ń€ŃƒŃŽ можно ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ в таблицах Šø Госках." + }, + "productivity_benefits": { + "revisions_content": "Ревизии заметок периоГически ŃŠ¾Ń…Ń€Š°Š½ŃŃŽŃ‚ŃŃ в фоне Š“Š»Ń просмотра или отмены ŃŠ»ŃƒŃ‡Š°Š¹Š½Ń‹Ń… изменений. Ревизии также можно ŃŠ¾Š·Š“Š°Š²Š°Ń‚ŃŒ ŃŠ°Š¼Š¾ŃŃ‚Š¾ŃŃ‚ŠµŠ»ŃŒŠ½Š¾.", + "sync_title": "Š”ŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·Š°Ń†ŠøŃ", + "protected_notes_title": "Защищённые заметки", + "jump_to_title": "ŠœŠ¾Ń‰Š½Ń‹Š¹ поиск Šø быстрые команГы", + "search_title": "Š“Š»ŃƒŠ±Š¾ŠŗŠøŠ¹ поиск", + "web_clipper_content": "Š”Š¾Ń…Ń€Š°Š½ŃŠ¹Ń‚Šµ целые веб-страницы (или ŃŠŗŃ€ŠøŠ½ŃˆŠ¾Ń‚Ń‹) в Trilium с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ Š±Ń€Š°ŃƒŠ·ŠµŃ€Š½Š¾Š³Š¾ Ń€Š°ŃŃˆŠøŃ€ŠµŠ½ŠøŃ web clipper.", + "title": "ŠŸŃ€Š¾Š“ŃƒŠŗŃ‚ŠøŠ²Š½Š¾ŃŃ‚ŃŒ Šø Š±ŠµŠ·Š¾ŠæŠ°ŃŠ½Š¾ŃŃ‚ŃŒ", + "revisions_title": "Š˜ŃŃ‚Š¾Ń€ŠøŃ изменений", + "sync_content": "Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ собственный сервер или облачное хранилище, чтобы легко ŃŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·ŠøŃ€Š¾Š²Š°Ń‚ŃŒ заметки на Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøŃ… ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š°Ń… Šø ŠæŠ¾Š»ŃƒŃ‡Š°Ń‚ŃŒ Šŗ ним Š“Š¾ŃŃ‚ŃƒŠæ с мобильного телефона с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ PWA.", + "protected_notes_content": "Защитите Š»ŠøŃ‡Š½ŃƒŃŽ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃŽ, Š·Š°ŃˆŠøŃ„Ń€Š¾Š²Š°Š² заметки Šø ограничив Šŗ ним Š“Š¾ŃŃ‚ŃƒŠæ ŠøŃ… с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ защищенного паролем сеанса.", + "jump_to_content": "Быстро перехоГите Šŗ заметкам или команГам, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃ поиск по ŠøŃ… заголовку, с поиском с ŃƒŃ‡ŠµŃ‚Š¾Š¼ опечаток Šø неточного ввоГа.", + "web_clipper_title": "Web clipper", + "search_content": "Или выполните поиск текста Š²Š½ŃƒŃ‚ри заметок Šø ŃŃƒŠ·ŃŒŃ‚Šµ Š¾Š±Š»Š°ŃŃ‚ŃŒ поиска, Š¾Ń‚Ń„ŠøŠ»ŃŒŃ‚Ń€Š¾Š²Š°Š² Ń€ŠµŠ·ŃƒŠ»ŃŒŃ‚Š°Ń‚Ń‹ по Ń€Š¾Š“ŠøŃ‚ŠµŠ»ŃŒŃŠŗŠ¾Š¹ заметке или по глубине поиска." + }, + "note_types": { + "title": "ŠœŠ½Š¾Š¶ŠµŃŃ‚Š²Š¾ способов преГставление информации", + "text_title": "Текстовые заметки", + "text_description": "Заметки Ń€ŠµŠ“Š°ŠŗŃ‚ŠøŃ€ŃƒŃŽŃ‚ŃŃ с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ визуального (WYSIWYG) реГактора, ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‰ŠµŠ³Š¾ таблицы, ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ, математические Š²Ń‹Ń€Š°Š¶ŠµŠ½ŠøŃ, блоки коГа с поГсветкой синтаксиса. Быстро Ń„Š¾Ń€Š¼Š°Ń‚ŠøŃ€ŃƒŠ¹Ń‚Šµ текст, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃ синтаксис, похожий на Markdown, или слеш-команГы.", + "code_title": "Заметки с коГом", + "code_description": "Š”Š»Ń работы с большими фрагментами исхоГного коГа или скриптами ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ся ŃŠæŠµŃ†ŠøŠ°Š»ŃŒŠ½Ń‹Š¹ реГактор с поГсветкой синтаксиса Š“Š»Ń многих ŃŠ·Ń‹ŠŗŠ¾Š² ŠæŃ€Š¾Š³Ń€Š°Š¼Š¼ŠøŃ€Š¾Š²Š°Š½ŠøŃ Šø различными цветовыми темами.", + "file_title": "Файлы", + "file_description": "Встраивайте Š¼ŃƒŠ»ŃŒŃ‚имеГийные файлы, такие как PDF-файлы, ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ Šø виГео, с преГпросмотром ŠæŃ€ŃŠ¼Š¾ в приложении.", + "canvas_title": "Єолст", + "canvas_description": "Размещайте Ń„ŠøŠ³ŃƒŃ€Ń‹, ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ Šø текст на бесконечном холсте, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃ ту же Ń‚ŠµŃ…Š½Š¾Š»Š¾Š³ŠøŃŽ, что Šø на сайте excalidraw.com. ИГеально поГхоГит Š“Š»Ń Гиаграмм, ŃŃŠŗŠøŠ·Š¾Š² Šø визуального ŠæŠ»Š°Š½ŠøŃ€Š¾Š²Š°Š½ŠøŃ.", + "mermaid_title": "Диаграммы Mermaid", + "mermaid_description": "ДозГавайте Гиаграммы, такие как блок-схемы, Гиаграммы классов Šø ŠæŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚ŠµŠ¹, Гиаграммы Ганта Šø многие Š“Ń€ŃƒŠ³ŠøŠµ, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃ синтаксис Mermaid.", + "mindmap_title": "Š˜Š½Ń‚ŠµŠ»Š»ŠµŠŗŃ‚-карта", + "mindmap_description": "Š’ŠøŠ·ŃƒŠ°Š»ŃŒŠ½Š¾ ŃŠøŃŃ‚ŠµŠ¼Š°Ń‚ŠøŠ·ŠøŃ€ŃƒŠ¹Ń‚Šµ свои мысли или провеГите мозговой ŃˆŃ‚ŃƒŃ€Š¼.", + "others_list": "а также: <0>карта заметок, <1>карта ŃŠ²ŃŠ·ŠµŠ¹, <2>сохраненный поиск, <3>ренГер, Šø <4>веб-страница." + }, + "download_now": { + "text": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ ", + "platform_big": "v{{version}} Š“Š»Ń {{platform}}", + "platform_small": "Š“Š»Ń {{platform}}", + "linux_big": "v{{version}} Š“Š»Ń Linux", + "linux_small": "Š“Š»Ń Linux", + "more_platforms": "Š”Ń€ŃƒŠ³ŠøŠµ платформы & сервер" + }, + "final_cta": { + "get_started": "ŠŠ°Ń‡Š°Š»Š¾ работы", + "title": "Готовы Š½Š°Ń‡Š°Ń‚ŃŒ Ń€Š°Š±Š¾Ń‚Ńƒ с Trilium Notes?", + "description": "ДозГайте ŃŠ²Š¾ŃŽ Š»ŠøŃ‡Š½ŃƒŃŽ базу знаний с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ мощных Ń„ŃƒŠ½ŠŗŃ†ŠøŠ¹ Šø c полной ŠŗŠ¾Š½Ń„ŠøŠ“ŠµŠ½Ń†ŠøŠ°Š»ŃŒŠ½Š¾ŃŃ‚ŃŒŃŽ." + }, + "header": { + "get-started": "ŠŠ°Ń‡Š°Š»Š¾ работы", + "support-us": "ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŃ‚Šµ нас", + "documentation": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃ", + "resources": "Š ŠµŃŃƒŃ€ŃŃ‹" + }, + "social_buttons": { + "github": "GitHub", + "matrix": "Matrix", + "reddit": "Reddit", + "github_discussions": "ŠžŠ±ŃŃƒŠ¶Š“ŠµŠ½ŠøŃ GitHub" + }, + "support_us": { + "github_sponsors": "Дпонсоры GitHub", + "title": "ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŃ‚Šµ нас", + "financial_donations_title": "Финансовые ŠæŠ¾Š¶ŠµŃ€Ń‚Š²Š¾Š²Š°Š½ŠøŃ", + "paypal": "PayPal", + "buy_me_a_coffee": "Buy Me A Coffee", + "financial_donations_cta": "Рассмотрите Š²Š¾Š·Š¼Š¾Š¶Š½Š¾ŃŃ‚ŃŒ поГГержки главного разработчика ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ (eliandoran) через:", + "financial_donations_description": "Trilium созГан Šø ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ŃŃ Š±Š»Š°Š³Š¾Š“Š°Ń€Ń ŃŠ¾Ń‚Š½ŃŠ¼ часов работы. Š’Š°ŃˆŠ° поГГержка ŠæŠ¾Š·Š²Š¾Š»ŃŠµŃ‚ ŃŠ¾Ń…Ń€Š°Š½ŠøŃ‚ŃŒ его открытым, ŃƒŠ»ŃƒŃ‡ŃˆŠøŃ‚ŃŒ Ń„ŃƒŠ½ŠŗŃ†ŠøŠ¾Š½Š°Š»ŃŒŠ½Š¾ŃŃ‚ŃŒ Šø ŠæŠ¾ŠŗŃ€Ń‹Ń‚ŃŒ такие расхоГы, как хостинг." + }, + "components": { + "link_learn_more": "ŠŸŠ¾Š“Ń€Š¾Š±Š½ŠµŠµ..." + }, + "faq": { + "database_answer": "Все ваши заметки Ń…Ń€Š°Š½ŃŃ‚ŃŃ в базе Ганных SQLite в папке ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ. Trilium ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ базу Ганных вместо обычных текстовых файлов ŠøŠ·-за соображений ŠæŃ€Š¾ŠøŠ·Š²Š¾Š“ŠøŃ‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚Šø, а также ŠæŠ¾Ń‚Š¾Š¼Ńƒ, что Ń€ŠµŠ°Š»ŠøŠ·Š°Ń†ŠøŃ некоторых Ń„ŃƒŠ½ŠŗŃ†ŠøŠ¹, таких как клонирование (оГна Šø та же заметка в Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøŃ… местах Герева), была бы горазГо сложнее. Чтобы найти папку ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ, просто перейГите в окно Ā«Šž программе».", + "scaling_answer": "Š’ зависимости от интенсивности ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŃ, приложение Голжно без проблем Š¾Š±Ń€Š°Š±Š°Ń‚Ń‹Š²Š°Ń‚ŃŒ не менее 100 000 заметок. Š”Š»ŠµŠ“ŃƒŠµŃ‚ Š¾Ń‚Š¼ŠµŃ‚ŠøŃ‚ŃŒ, что процесс синхронизации иногГа может Š·Š°Š²ŠµŃ€ŃˆŠ°Ń‚ŃŒŃŃ с ошибкой при Š·Š°Š³Ń€ŃƒŠ·ŠŗŠµ большого количества Š±Š¾Š»ŃŒŃˆŠøŃ… файлов (1 ГБ на файл), поскольку Trilium преГназначен скорее Š“Š»Ń ŃŠ¾Š·Š“Š°Š½ŠøŃ базы знаний, чем Š“Š»Ń Ń…Ń€Š°Š½ŠµŠ½ŠøŃ файлов (как, например, NextCloud).", + "mobile_answer": "Š’ Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń Š¾Ń„ŠøŃ†ŠøŠ°Š»ŃŒŠ½Š¾Š³Š¾ мобильного ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ нет. ŠžŠ“Š½Š°ŠŗŠ¾, если у вас ŠµŃŃ‚ŃŒ сервер, вы можете ŠæŠ¾Š»ŃƒŃ‡ŠøŃ‚ŃŒ Šŗ нему Š“Š¾ŃŃ‚ŃƒŠæ через веб-Š±Ń€Š°ŃƒŠ·ŠµŃ€ Šø Гаже ŃƒŃŃ‚Š°Š½Š¾Š²ŠøŃ‚ŃŒ его как PWA. Š”Š»Ń Android ŃŃƒŃ‰ŠµŃŃ‚Š²ŃƒŠµŃ‚ Š½ŠµŠ¾Ń„ŠøŃ†ŠøŠ°Š»ŃŒŠ½Š¾Šµ приложение TriliumDroid, которое работает Гаже в автономном режиме (аналогично Š½Š°ŃŃ‚Š¾Š»ŃŒŠ½Š¾Š¼Ńƒ ŠŗŠ»ŠøŠµŠ½Ń‚Ńƒ).", + "server_answer": "ŠŠµŃ‚, сервер обеспечивает Š“Š¾ŃŃ‚ŃƒŠæ через веб-Š±Ń€Š°ŃƒŠ·ŠµŃ€ Šø ŃƒŠæŃ€Š°Š²Š»ŃŠµŃ‚ синхронизацией, если у вас несколько ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š². Š”Š»Ń начала Гостаточно Š·Š°Š³Ń€ŃƒŠ·ŠøŃ‚ŃŒ Š½Š°ŃŃ‚Š¾Š»ŃŒŠ½Š¾Šµ приложение Šø Š½Š°Ń‡Š°Ń‚ŃŒ им ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒŃŃ.", + "title": "Часто заГаваемые вопросы", + "mobile_question": "Š•ŃŃ‚ŃŒ ли мобильное приложение?", + "server_question": "ŠŃƒŠ¶ŠµŠ½ ли мне сервер Š“Š»Ń ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŃ Trilium?", + "network_share_question": "Могу ли я ŃŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·ŠøŃ€Š¾Š²Š°Ń‚ŃŒ базу Ганных или ŠæŠ¾Š“ŠµŠ»ŠøŃ‚ŃŒŃŃ ей через облачный Гиск?", + "network_share_answer": "ŠŠµŃ‚, в целом, не Ń€ŠµŠŗŠ¾Š¼ŠµŠ½Š“ŃƒŠµŃ‚ŃŃ ŠæŃ€ŠµŠ“Š¾ŃŃ‚Š°Š²Š»ŃŃ‚ŃŒ общий Š“Š¾ŃŃ‚ŃƒŠæ Šŗ базе Ганных SQLite через сетевой Гиск. Š„Š¾Ń‚Ń иногГа ŃŃ‚Š¾ может ŃŃ€Š°Š±Š¾Ń‚Š°Ń‚ŃŒ, ŃŃƒŃ‰ŠµŃŃ‚Š²ŃƒŠµŃ‚ Š²ŠµŃ€Š¾ŃŃ‚Š½Š¾ŃŃ‚ŃŒ ŠæŠ¾Š²Ń€ŠµŠ¶Š“ŠµŠ½ŠøŃ базы Ганных ŠøŠ·-за ненаГежной блокировки файлов в сети.", + "database_question": "ГГе Ń…Ń€Š°Š½ŃŃ‚ŃŃ Ганные ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ?", + "scaling_question": "ŠŠ°ŃŠŗŠ¾Š»ŃŒŠŗŠ¾ Ń…Š¾Ń€Š¾ŃˆŠ¾ приложение Š¼Š°ŃŃˆŃ‚Š°Š±ŠøŃ€ŃƒŠµŃ‚ŃŃ при большом объеме заметок?", + "security_question": "Как защищены мои Ганные?", + "security_answer": "По ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ заметки не ŃˆŠøŃ„Ń€ŃƒŃŽŃ‚ŃŃ Šø Š¼Š¾Š³ŃƒŃ‚ Š±Ń‹Ń‚ŃŒ прочитаны непосреГственно ŠøŠ· базы Ганных. Если вы Š²ŠŗŠ»ŃŽŃ‡ŠøŃ‚Šµ режим ŃˆŠøŃ„Ń€Š¾Š²Š°Š½ŠøŃ Š“Š»Ń заметки, она Š·Š°ŃˆŠøŃ„Ń€ŃƒŠµŃ‚ŃŃ с использованием алгоритма AES-128-CBC." + }, + "extensibility_benefits": { + "title": "ŠŸŃƒŠ±Š»ŠøŠŗŠ°Ń†ŠøŃ заметок Šø Ń€Š°ŃŃˆŠøŃ€ŃŠµŠ¼Š¾ŃŃ‚ŃŒ", + "import_export_title": "Š˜Š¼ŠæŠ¾Ń€Ń‚/ŃŠŗŃŠæŠ¾Ń€Ń‚", + "share_title": "ŠŸŃƒŠ±Š»ŠøŃ‡Š½Ń‹Š¹ Š“Š¾ŃŃ‚ŃƒŠæ Šŗ заметкам", + "scripting_title": "ŠŸŃ€Š¾Š“Š²ŠøŠ½ŃƒŃ‚Ń‹Š¹ скриптинг", + "scripting_description": "ДозГавайте собственные интеграции в Trilium с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŃ… виГжетов или серверной логики.", + "api_title": "REST API", + "api_description": "Š’Š·Š°ŠøŠ¼Š¾Š“ŠµŠ¹ŃŃ‚Š²ŃƒŠ¹Ń‚Šµ с Trilium программно, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃ встроенный REST API.", + "import_export_description": "УГобное взаимоГействие с Š“Ń€ŃƒŠ³ŠøŠ¼Šø ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃŠ¼Šø Š±Š»Š°Š³Š¾Š“Š°Ń€Ń ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŃŽ форматов Markdown, ENEX Šø OML.", + "share_description": "Если у вас ŠµŃŃ‚ŃŒ сервер, его можно ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ Š“Š»Ń обмена Ń‡Š°ŃŃ‚ŃŒŃŽ Š²Š°ŃˆŠøŃ… заметок с Š“Ń€ŃƒŠ³ŠøŠ¼Šø Š»ŃŽŠ“ŃŒŠ¼Šø." + }, + "contribute": { + "way_community": "Š’Š·Š°ŠøŠ¼Š¾Š“ŠµŠ¹ŃŃ‚Š²ŃƒŠ¹Ń‚Šµ с сообществом на GitHub Discussions или на Matrix.", + "title": "Š”Ń€ŃƒŠ³ŠøŠµ способы внести свой вклаГ", + "way_document": "Š£Š»ŃƒŃ‡ŃˆŠøŃ‚Šµ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃŽ, сообщив нам о пробелах в ней или Гобавив Ń€ŃƒŠŗŠ¾Š²Š¾Š“ŃŃ‚Š²Š°, часто заГаваемые вопросы или Š¾Š±ŃƒŃ‡Š°ŃŽŃ‰ŠøŠµ материалы.", + "way_market": "Расскажите о Trillium Š“Ń€ŃƒŠ·ŃŒŃŠ¼, в блоге Šø ŃŠ¾Ń†ŠøŠ°Š»ŃŒŠ½Ń‹Ń… ŃŠµŃ‚ŃŃ….", + "way_reports": "Дообщайте об Š¾ŃˆŠøŠ±ŠŗŠ°Ń… через GitHub issues.", + "way_translate": "ŠŸŠµŃ€ŠµŠ²ŠµŠ“ŠøŃ‚Šµ приложение на свой роГной ŃŠ·Ń‹Šŗ с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ Weblate." + }, + "collections": { + "title": "ŠšŠ¾Š»Š»ŠµŠŗŃ†ŠøŠø", + "calendar_title": "ŠšŠ°Š»ŠµŠ½Š“Š°Ń€ŃŒ", + "table_title": "Таблица", + "board_description": "ŠžŃ€Š³Š°Š½ŠøŠ·ŃƒŠ¹Ń‚Šµ свои заГачи или ŃŃ‚Š°Ń‚ŃƒŃ проекта на Госке Kanban, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃ простой способ ŃŠ¾Š·Š“Š°Š½ŠøŃ новых ŃŠ»ŠµŠ¼ŠµŠ½Ń‚Š¾Š² Šø столбцов, а также ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŃ ŠøŃ… ŃŃ‚Š°Ń‚ŃƒŃŠ° простым перетаскиванием по Госке.", + "board_title": "Канбан-Госка", + "presentation_description": "ŠžŃ€Š³Š°Š½ŠøŠ·ŃƒŠ¹Ń‚Šµ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃŽ в виГе слайГов Šø Š“ŠµŠ¼Š¾Š½ŃŃ‚Ń€ŠøŃ€ŃƒŠ¹Ń‚Šµ ŠøŃ… в ŠæŠ¾Š»Š½Š¾ŃŠŗŃ€Š°Š½Š½Š¾Š¼ режиме с плавными перехоГами. ДлайГы также можно ŃŠŗŃŠæŠ¾Ń€Ń‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ в PDF Š“Š»Ń уГобного обмена.", + "presentation_title": "ŠŸŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†ŠøŃ", + "geomap_description": "ŠŸŠ»Š°Š½ŠøŃ€ŃƒŠ¹Ń‚Šµ свой Š¾Ń‚ŠæŃƒŃŠŗ или отмечайте ŠøŠ½Ń‚ŠµŃ€ŠµŃŃƒŃŽŃ‰ŠøŠµ вас места ŠæŃ€ŃŠ¼Š¾ на карте с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ настраиваемых меток. ŠžŃ‚Š¾Š±Ń€Š°Š¶Š°Š¹Ń‚Šµ записанные GPX-треки Š“Š»Ń Š¾Ń‚ŃŠ»ŠµŠ¶ŠøŠ²Š°Š½ŠøŃ Š¼Š°Ń€ŃˆŃ€ŃƒŃ‚Š°.", + "geomap_title": "ŠšŠ°Ń€Ń‚Š°", + "table_description": "ŠžŃ‚Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ Šø реГактирование информации о заметках в виГе таблицы с различными типами столбцов, такими как текст, число, флажки, Гата Šø Š²Ń€ŠµŠ¼Ń, ссылки Šø цвета, а также поГГержкой ŃŠ²ŃŠ·ŠµŠ¹. ŠžŃ‚Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ заметок в ГревовиГном виГе Š²Š½ŃƒŃ‚ри таблицы.", + "calendar_description": "ŠžŃ€Š³Š°Š½ŠøŠ·ŃƒŠ¹Ń‚Šµ свои личные или ŠæŃ€Š¾Ń„ŠµŃŃŠøŠ¾Š½Š°Š»ŃŒŠ½Ń‹Šµ ŃŠ¾Š±Ń‹Ń‚ŠøŃ с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ ŠŗŠ°Š»ŠµŠ½Š“Š°Ń€Ń, ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‰ŠµŠ³Š¾ ŃŠ¾Š±Ń‹Ń‚ŠøŃ на весь Гень Šø на несколько Гней. Работайте с каленГарем в неГельном, Š¼ŠµŃŃŃ‡Š½Š¾Š¼ Šø гоГовом режимах просмотра. ŠŸŃ€Š¾ŃŃ‚Š¾Šµ Гобавление, событий." + }, + "download_helper_desktop_windows": { + "title_arm64": "Windows на ARM", + "description_arm64": "Довместимо с ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š°Š¼Šø на базе ARM (например, с процессорами Qualcomm Snapdragon).", + "download_scoop": "Scoop", + "download_zip": "ŠŸŠ¾Ń€Ń‚Š°Ń‚ŠøŠ²Š½Š°Ń Š²ŠµŃ€ŃŠøŃ (.zip)", + "title_x64": "Windows x64", + "description_x64": "Довместимо с ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š°Š¼Šø Intel или AMD поГ ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŠµŠ¼ Windows 10 Šø 11.", + "quick_start": "Š”Š»Ń ŃƒŃŃ‚Š°Š½Š¾Š²ŠŗŠø через Winget:", + "download_exe": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ ŃƒŃŃ‚Š°Š½Š¾Š²Ń‰ŠøŠŗ (.exe)" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS Š“Š»Ń Intel", + "title_arm64": "macOS Š“Š»Ń Apple Silicon", + "description_x64": "Š”Š»Ń ŠŗŠ¾Š¼ŠæŃŒŃŽŃ‚ŠµŃ€Š¾Š² Mac на базе процессоров Intel поГ ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŠµŠ¼ macOS Monterey или более позГней версии.", + "description_arm64": "Š”Š»Ń ŠŗŠ¾Š¼ŠæŃŒŃŽŃ‚ŠµŃ€Š¾Š² Mac на базе процессоров Apple Silicon, таких как M1 Šø M2.", + "quick_start": "Š”Š»Ń ŃƒŃŃ‚Š°Š½Š¾Š²ŠŗŠø через Homebrew:", + "download_dmg": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ ŃƒŃŃ‚Š°Š½Š¾Š²Ń‰ŠøŠŗ (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "ŠŸŠ¾Ń€Ń‚Š°Ń‚ŠøŠ²Š½Š°Ń Š²ŠµŃ€ŃŠøŃ (.zip)" + }, + "download_helper_server_docker": { + "description": "Легко развертывайте ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ на Windows, Linux или macOS с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ Docker контейнера.", + "title": "Двой сервер с Docker", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_desktop_linux": { + "download_zip": "ŠŸŠ¾Ń€Ń‚Š°Ń‚ŠøŠ²Š½Š°Ń Š²ŠµŃ€ŃŠøŃ (.zip)", + "title_x64": "Linux x64", + "title_arm64": "Linux Š“Š»Ń ARM", + "description_x64": "Довместимо с Š°Ń€Ń…ŠøŃ‚ŠµŠŗŃ‚ŃƒŃ€Š¾Š¹ x86_64 Š“Š»Ń Š±Š¾Š»ŃŒŃˆŠøŠ½ŃŃ‚Š²Š° Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Š¾Š² Linux.", + "description_arm64": "Š”Š»Ń Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Š¾Š² Linux на базе ARM, совместимых с Š°Ń€Ń…ŠøŃ‚ŠµŠŗŃ‚ŃƒŃ€Š¾Š¹ aarch64.", + "quick_start": "Выберите ŠæŠ¾Š“Ń…Š¾Š“ŃŃ‰ŠøŠ¹ формат пакета в зависимости от вашего Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Š°:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_server_linux": { + "title": "Двой сервер на Linux", + "description": "Разверните Trilium Notes на собственном сервере или VPS, совместимом с Š±Š¾Š»ŃŒŃˆŠøŠ½ŃŃ‚Š²Š¾Š¼ Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Š¾Š².", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "МоГуль NixOS" + }, + "download_helper_server_hosted": { + "title": "ŠŸŠ»Š°Ń‚Š½Ń‹Š¹ хостинг", + "description": "Trilium Notes размещен на PikaPods, платном сервисе Š“Š»Ń уГобного Š“Š¾ŃŃ‚ŃƒŠæŠ° Šø ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŃ. ŠŠµ имеет ŠæŃ€ŃŠ¼Š¾Š³Š¾ Š¾Ń‚Š½Š¾ŃˆŠµŠ½ŠøŃ Šŗ команГе Trilium.", + "download_pikapod": "Š—Š°ŠæŃƒŃŃ‚ŠøŃ‚ŃŒ на PikaPods", + "download_triliumcc": "Или trilium.cc" + }, + "footer": { + "copyright_and_the": " Šø ", + "copyright_community": "сообщество" + }, + "404": { + "title": "404: ŠŠµ найГено", + "description": "Дтраница, ŠŗŠ¾Ń‚Š¾Ń€ŃƒŃŽ вы искали, не найГена. Возможно, она была уГалена или URL-аГрес указан неверно." + }, + "resources": { + "title": "Š ŠµŃŃƒŃ€ŃŃ‹", + "icon_packs": "ŠŠ°Š±Š¾Ń€Ń‹ иконок", + "download": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ", + "website": "Дайт", + "icon_packs_intro": "Š Š°ŃŃˆŠøŃ€ŃŒŃ‚Šµ выбор значков Š“Š»Ń заметок, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃ набор иконок. ŠŸŠ¾Š“Ń€Š¾Š±Š½ŠµŠµ о наборах иконок смотрите в Š¾Ń„ŠøŃ†ŠøŠ°Š»ŃŒŠ½Š¾Š¹ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŠø." + } +} diff --git a/apps/website/src/translations/sl/translation.json b/apps/website/src/translations/sl/translation.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/apps/website/src/translations/sl/translation.json @@ -0,0 +1 @@ +{} diff --git a/apps/website/src/translations/sr/translation.json b/apps/website/src/translations/sr/translation.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/apps/website/src/translations/sr/translation.json @@ -0,0 +1 @@ +{} diff --git a/apps/website/src/translations/sv/translation.json b/apps/website/src/translations/sv/translation.json new file mode 100644 index 0000000000..abbec67988 --- /dev/null +++ b/apps/website/src/translations/sv/translation.json @@ -0,0 +1,31 @@ +{ + "get-started": { + "title": "Kom igĆ„ng", + "desktop_title": "Ladda ner skrivbordsprogrammet (v{{version}})", + "architecture": "Arkitektur:", + "older_releases": "Se Ƥldre versioner", + "server_title": "Skapa en server fƶr Ć„tkomst pĆ„ flera enheter" + }, + "hero_section": { + "title": "Organisera dina tankar. Skapa din personliga kunskapsbank.", + "subtitle": "Trilium Ƥr en lƶsning med ƶppen kƤllkod som mƶjliggƶr anteckningar och organisering av en personlig kunskapsbank. AnvƤnd den lokalt pĆ„ ditt skrivbord, eller synka till en sjƤlvhostad server fƶr att komma Ć„t dina anteckningar ƶverallt.", + "screenshot_alt": "SkƤrmdump av Trilium Notes skrivbordsapplikation", + "get_started": "Kom igĆ„ng", + "github": "GitHub", + "dockerhub": "Docker Hub" + }, + "organization_benefits": { + "title": "Organisation", + "note_structure_title": "Anteckningsstruktur", + "note_structure_description": "Anteckningar kan sorteras hierarkiskt. Det behƶvs inga mappar eftersom varje anteckning kan innehĆ„lla underordnade anteckningar. En enskild anteckning kan placeras pĆ„ flera stƤllen samtidigt i hierarkin.", + "attributes_title": "Hantera etiketter och relationer", + "attributes_description": "AnvƤnd relationer mellan anteckningar eller lƤgg till etiketter fƶr enkel kategorisering. AnvƤnd framhƤvda attribut fƶr att ange strukturerad information som sedan kan visas i tabeller och tavlor.", + "hoisting_title": "Arbetsyta och fokusomrĆ„de", + "hoisting_description": "Separera enkelt privata- och jobbanteckningar genom att gruppera dem pĆ„ en arbetsyta, vilket fokuserar anteckningshierarkin att enbart visa en viss grupp av anteckningar." + }, + "productivity_benefits": { + "title": "Produktivitet och sƤkerhet", + "revisions_title": "Anteckningshistorik", + "revisions_content": "Anteckningar sparas regelbundet i bakgrunden och versioner kan anvƤndas fƶr att sƶka- eller Ć„ngra oavsiktliga Ƥndringar. En version kan ocksĆ„ skapas manuellt." + } +} diff --git a/apps/website/src/translations/tr/translation.json b/apps/website/src/translations/tr/translation.json new file mode 100644 index 0000000000..76d93f32bf --- /dev/null +++ b/apps/website/src/translations/tr/translation.json @@ -0,0 +1,29 @@ +{ + "get-started": { + "title": "BaşlangıƧ", + "desktop_title": "Masaüstü uygulamasını indirin (v{{version}})", + "architecture": "Mimari:", + "older_releases": "Eski sürümleri gƶrüntüle", + "server_title": "Birden fazla cihazdan erişim iƧin bir sunucu kurun" + }, + "hero_section": { + "title": "Düşüncelerinizi organize edin. Kişisel bilgi birikiminizi oluşturun.", + "subtitle": "Trilium, not tutma ve kişisel bir bilgi tabanını düzenleme iƧin aƧık kaynaklı bir Ƨƶzümdür. Bunu masaüstünü bilgisayarınızda kullanabilir veya kendi barındırdığınız sunucuyla senkronize ederek notlarınızı gittiğiniz her yerde yanınızda bulundurabilirsiniz.", + "get_started": "Başlayın", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Trilium Notes masaüstü uygulamasının ekran gƶrüntüsü" + }, + "organization_benefits": { + "title": "Organizasyon", + "note_structure_title": "Not yapısı", + "note_structure_description": "Notlar hiyerarşik olarak düzenlenebilir. Her not 'alt notlar' iƧerebildiği iƧin klasƶrlere ihtiyaƧ duyulmaz. Tek bir not, hiyerarşinin birden fazla noktasına eklenebilir.", + "attributes_description": "Notlar arasında ilişkiler kurun veya kolay kategorizasyon iƧin etiketler ekleyin. Tablolarda ve panolarda kullanılabilen yapılandırılmış bilgileri eklemek iƧin ƶne Ƨıkan ƶznitelikleri kullanın.", + "hoisting_description": "Kişisel ve iş notlarınızı bir Ƨalışma alanı altında gruplandırarak kolayca ayırın; bu sayede not ağacınız yalnızca belirli bir not kümesini gƶsterecek şekilde odaklanacaktır.", + "attributes_title": "Not etiketleri ve ilişkileri" + }, + "productivity_benefits": { + "title": "Üretkenlik ve güvenlik", + "revisions_title": "Note düzenlemeleri" + } +} diff --git a/apps/website/src/translations/uk/translation.json b/apps/website/src/translations/uk/translation.json new file mode 100644 index 0000000000..bc93eb9000 --- /dev/null +++ b/apps/website/src/translations/uk/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "title": "ŠŸŠ¾Ń‡Š°Ń‚Šø", + "desktop_title": "Завантажити ŠæŃ€Š¾Š³Ń€Š°Š¼Ńƒ Š“Š»Ń ПК (v{{version}})", + "architecture": "ŠŃ€Ń…Ń–Ń‚ŠµŠŗŃ‚ŃƒŃ€Š°:", + "older_releases": "Š”ŠøŠ²ŠøŃ‚ŠøŃŃ ŃŃ‚Š°Ń€Ń–ŃˆŃ– випуски", + "server_title": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ¹Ń‚Šµ сервер Š“Š»Ń Š“Š¾ŃŃ‚ŃƒŠæŃƒ на ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… ŠæŃ€ŠøŃŃ‚Ń€Š¾ŃŃ…" + }, + "hero_section": { + "title": "Š£ŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ¹Ń‚Šµ свої Гумки. Š”Ń‚Š²Š¾Ń€Ń–Ń‚ŃŒ ŃŠ²Š¾ŃŽ Š¾ŃŠ¾Š±ŠøŃŃ‚Ńƒ базу знань.", + "subtitle": "Trilium — це Ń€Ń–ŃˆŠµŠ½Š½Ń Š· віГкритим коГом Š“Š»Ń Š²ŠµŠ“ŠµŠ½Š½Ń нотаток та організації особистої бази знань. Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ¹Ń‚Šµ його локально на ŃŠ²Š¾Ń”Š¼Ńƒ Ń€Š¾Š±Š¾Ń‡Š¾Š¼Ńƒ столі або ŃŠøŠ½Ń…Ń€Š¾Š½Ń–Š·ŃƒŠ¹Ń‚Šµ Š·Ń– своїм власним сервером, щоб мати свої нотатки піГ Ń€ŃƒŠŗŠ¾ŃŽ, Ге б ви не були.", + "get_started": "ŠŸŠ¾Ń‡Š°Ń‚Šø", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Знімок екрана програми Trilium Notes Š“Š»Ń ПК" + }, + "organization_benefits": { + "title": "ŠžŃ€Š³Š°Š½Ń–Š·Š°Ń†Ń–Ń", + "note_structure_title": "Š”Ń‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š° нотатки", + "note_structure_description": "ŠŠ¾Ń‚Š°Ń‚ŠŗŠø можна Š²ŠæŠ¾Ń€ŃŠ“ŠŗŠ¾Š²ŃƒŠ²Š°Ń‚Šø ієрархічно. ŠŠµŠ¼Š°Ń” потреби в папках, Š¾ŃŠŗŃ–Š»ŃŒŠŗŠø кожна нотатка може містити піГнотатки. ŠžŠ“Š½Ńƒ Š½Š¾Ń‚Š°Ń‚ŠŗŃƒ можна ГоГати в ŠŗŃ–Š»ŃŒŠŗŠ° Š¼Ń–ŃŃ†ŃŒ в ієрархії.", + "attributes_title": "ŠœŃ–Ń‚ŠŗŠø та зв'ŃŠ·ŠŗŠø нотаток", + "attributes_description": "Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ¹Ń‚Šµ зв'ŃŠ·ŠŗŠø між нотатками або ГоГавайте мітки Š“Š»Ń легкої категоризації. Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ¹Ń‚Šµ піГвищені Š°Ń‚Ń€ŠøŠ±ŃƒŃ‚Šø Š“Š»Ń Š²Š²ŠµŠ“ŠµŠ½Š½Ń ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š¾Š²Š°Š½Š¾Ń— інформації, ŃŠŗŃƒ можна Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø в Ń‚Š°Š±Š»ŠøŃ†ŃŃ…, на Š“Š¾ŃˆŠŗŠ°Ń….", + "hoisting_title": "Робочі області та хостинг", + "hoisting_description": "Легко Ń€Š¾Š·Š“Ń–Š»ŃŠ¹Ń‚Šµ особисті нотатки та робочі, Š³Ń€ŃƒŠæŃƒŃŽŃ‡Šø їх у робочій області, що Ń„Š¾ŠŗŃƒŃŃƒŃ” ваше Герево нотаток на віГображенні лише певного Š½Š°Š±Š¾Ń€Ńƒ нотаток." + }, + "productivity_benefits": { + "title": "ŠŸŃ€Š¾Š“ŃƒŠŗŃ‚ŠøŠ²Š½Ń–ŃŃ‚ŃŒ та безпека", + "revisions_title": "Ревізії нотаток", + "revisions_content": "ŠŠ¾Ń‚Š°Ń‚ŠŗŠø періоГично Š·Š±ŠµŃ€Ń–Š³Š°ŃŽŃ‚ŃŒŃŃ у Ń„Š¾Š½Š¾Š²Š¾Š¼Ńƒ режимі, а ревізії можна Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø Š“Š»Ń ŠæŠµŃ€ŠµŠ³Š»ŃŠ“Ńƒ або ŃŠŗŠ°ŃŃƒŠ²Š°Š½Š½Ń випаГкових змін. Ревізії також можна ŃŃ‚Š²Š¾Ń€ŃŽŠ²Š°Ń‚Šø на вимогу.", + "sync_title": "Š”ŠøŠ½Ń…Ń€Š¾Š½Ń–Š·Š°Ń†Ń–Ń", + "sync_content": "Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ¹Ń‚Šµ власний або хмарний ŠµŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€, щоб легко ŃŠøŠ½Ń…Ń€Š¾Š½Ń–Š·ŃƒŠ²Š°Ń‚Šø нотатки на ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… ŠæŃ€ŠøŃŃ‚Ń€Š¾ŃŃ… та Š¾Ń‚Ń€ŠøŠ¼ŃƒŠ²Š°Ń‚Šø Го них Š“Š¾ŃŃ‚ŃƒŠæ Š· Š¼Š¾Š±Ń–Š»ŃŒŠ½Š¾Š³Š¾ Ń‚ŠµŠ»ŠµŃ„Š¾Š½Ńƒ за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ PWA.", + "protected_notes_title": "Захищені нотатки", + "protected_notes_content": "Š—Š°Ń…ŠøŃŃ‚Ń–Ń‚ŃŒ ŠŗŠ¾Š½Ń„Ń–Š“ŠµŠ½Ń†Ń–Š¹Š½Ńƒ Š¾ŃŠ¾Š±ŠøŃŃ‚Ńƒ Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ, Š·Š°ŃˆŠøŃ„Ń€ŃƒŠ²Š°Š²ŃˆŠø нотатки та заблокувавши їх за сеансом, захищеним паролем.", + "jump_to_title": "ШвиГкий пошук і команГи", + "jump_to_content": "ШвиГко ŠæŠµŃ€ŠµŃ…Š¾Š“ŃŒŃ‚Šµ Го нотаток або команГ Ń–Š½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŃƒ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° в ієрархії, ŃˆŃƒŠŗŠ°ŃŽŃ‡Šø їх за Š½Š°Š·Š²Š¾ŃŽ, Š· нечітким Š·Ń–ŃŃ‚Š°Š²Š»ŠµŠ½Š½ŃŠ¼ Š“Š»Ń Š²Ń€Š°Ń…ŃƒŠ²Š°Š½Š½Ń Š“Ń€ŃƒŠŗŠ°Ń€ŃŃŒŠŗŠøŃ… помилок або незначних віГмінностей.", + "search_title": "ŠŸŠ¾Ń‚ŃƒŠ¶Š½ŠøŠ¹ пошук", + "search_content": "Або ŃˆŃƒŠŗŠ°Š¹Ń‚Šµ текст ŃƒŃŠµŃ€ŠµŠ“ŠøŠ½Ń– нотаток та Š·Š²ŃƒŠ·ŃŒŃ‚е пошук, Š²Ń–Š“Ń„Ń–Š»ŃŒŃ‚Ń€ŃƒŠ²Š°Š²ŃˆŠø за Š±Š°Ń‚ŃŒŠŗŃ–Š²ŃŃŒŠŗŠ¾ŃŽ Š½Š¾Ń‚Š°Ń‚ŠŗŠ¾ŃŽ чи за Š³Š»ŠøŠ±ŠøŠ½Š¾ŃŽ.", + "web_clipper_title": "Web-кліпер", + "web_clipper_content": "Š—Š±ŠµŃ€Ń–Ń‚ŃŒ веб-сторінки (або ŃŠŗŃ€Ń–Š½ŃˆŠ¾Ń‚Šø) та Ń€Š¾Š·Š¼Ń–ŃŃ‚Ń–Ń‚ŃŒ їх Š±ŠµŠ·ŠæŠ¾ŃŠµŃ€ŠµŠ“Š½ŃŒŠ¾ в Trilium за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ Ń€Š¾Š·ŃˆŠøŃ€ŠµŠ½Š½Ń Š±Ń€Š°ŃƒŠ·ŠµŃ€Š° Web Clipper." + }, + "note_types": { + "text_title": "Текстові нотатки", + "text_description": "ŠŠ¾Ń‚Š°Ń‚ŠŗŠø Ń€ŠµŠ“Š°Š³ŃƒŃŽŃ‚ŃŒŃŃ за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ Š²Ń–Š·ŃƒŠ°Š»ŃŒŠ½Š¾Š³Š¾ (WYSIWYG) реГактора Š· ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŠŗŠ¾ŃŽ Ń‚Š°Š±Š»ŠøŃ†ŃŒ, Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŃŒ, математичних виразів, блоків коГу Š· ŠæŃ–Š“ŃŠ²Ń–Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼ ŃŠøŠ½Ń‚Š°ŠŗŃŠøŃŃƒ. ШвиГко Ń„Š¾Ń€Š¼Š°Ń‚ŃƒŠ¹Ń‚Šµ текст, Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‡Šø синтаксис, поГібний Го Markdown, або Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‡Šø команГи Š·Ń– слеш-рисками.", + "code_title": "ŠŠ¾Ń‚Š°Ń‚ŠŗŠø Š· коГом", + "code_description": "Великі зразки вихіГного коГу або скриптів Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‚ŃŒ ŃŠæŠµŃ†Ń–Š°Š»ŃŒŠ½ŠøŠ¹ реГактор Ń–Š· ŠæŃ–Š“ŃŠ²Ń–Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼ ŃŠøŠ½Ń‚Š°ŠŗŃŠøŃŃƒ Š“Š»Ń Š±Š°Š³Š°Ń‚ŃŒŠ¾Ń… мов ŠæŃ€Š¾Š³Ń€Š°Š¼ŃƒŠ²Š°Š½Š½Ń та різними колірними темами.", + "file_title": "Файлові нотатки", + "file_description": "Š’Š±ŃƒŠ“Š¾Š²ŃƒŠ¹Ń‚Šµ Š¼ŃƒŠ»ŃŒŃ‚ŠøŠ¼ŠµŠ“Ń–Š¹Š½Ń– файли, такі ŃŠŗ PDF-файли, Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń, віГео, Š· попереГнім ŠæŠµŃ€ŠµŠ³Š»ŃŠ“Š¾Š¼ у програмі.", + "canvas_title": "ŠŸŠ¾Š»Š¾Ń‚Š½Š¾", + "title": "ŠšŃ–Š»ŃŒŠŗŠ° способів ŠæŃ€ŠµŠ“ŃŃ‚Š°Š²Š»ŠµŠ½Š½Ń Š²Š°ŃˆŠ¾Ń— інформації", + "canvas_description": "Š Š¾Š·Ń‚Š°ŃˆŠ¾Š²ŃƒŠ¹Ń‚Šµ Ń„Ń–Š³ŃƒŃ€Šø, Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń та текст на Š½ŠµŃŠŗŃ–Š½Ń‡ŠµŠ½Š½Š¾Š¼Ńƒ полотні, Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‡Šø ту саму Ń‚ŠµŃ…Š½Š¾Š»Š¾Š³Ń–ŃŽ, що й excalidraw.com. Š†Š“ŠµŠ°Š»ŃŒŠ½Š¾ ŠæŃ–Š“Ń…Š¾Š“ŠøŃ‚ŃŒ Š“Š»Ń Гіаграм, ескізів та Š²Ń–Š·ŃƒŠ°Š»ŃŒŠ½Š¾Š³Š¾ ŠæŠ»Š°Š½ŃƒŠ²Š°Š½Š½Ń.", + "mermaid_description": "Š”Ń‚Š²Š¾Ń€ŃŽŠ¹Ń‚Šµ Гіаграми, такі ŃŠŗ блок-схеми, Гіаграми класів та посліГовностей, Гіаграми Ганта та багато Ń–Š½ŃˆŠ¾Š³Š¾, Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‡Šø синтаксис Mermaid.", + "others_list": "та Ń–Š½ŃˆŃ–: <0>карта нотаток, <1>карта зв'ŃŠ·ŠŗŃ–Š², <2>збережені пошуки, <3>Š²Ń–Š·ŃƒŠ°Š»Ń–Š·Š°Ń†Ń–Ń нотаток та <4>веб-ŠæŠµŃ€ŠµŠ³Š»ŃŠ“Šø.", + "mermaid_title": "Mermaid Гіаграми", + "mindmap_title": "ŠšŠ°Ń€Ń‚Š° Гумок", + "mindmap_description": "Š’Ń–Š·ŃƒŠ°Š»ŃŒŠ½Š¾ ŃƒŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ¹Ń‚Šµ свої Гумки або ŠæŃ€Š¾Š²ŠµŠ“Ń–Ń‚ŃŒ мозковий ŃˆŃ‚ŃƒŃ€Š¼." + }, + "extensibility_benefits": { + "title": "Š”ŠæŃ–Š»ŃŒŠ½Šµ Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń та Ń€Š¾Š·ŃˆŠøŃ€ŃŽŠ²Š°Š½Ń–ŃŃ‚ŃŒ", + "import_export_title": "Імпорт/експорт", + "import_export_description": "Легко взаємоГійте Š· Ń–Š½ŃˆŠøŠ¼Šø програмами, Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‡Šø формати Markdown, ENEX, OML.", + "share_title": "Š”Ń–Š»Ń–Ń‚ŃŒŃŃ нотатками в Інтернеті", + "share_description": "Якщо у Вас є сервер, Š’Šø можете використати його, щоб ŠæŠ¾Š“Ń–Š»ŠøŃ‚ŠøŃŃ Ń‡Š°ŃŃ‚ŠøŠ½Š¾ŃŽ своїх нотаток Š· Ń–Š½ŃˆŠøŠ¼Šø Š»ŃŽŠ“ŃŒŠ¼Šø.", + "api_title": "REST API", + "api_description": "ВзаємоГійте Š· Trilium програмно, Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‡Šø його вбуГований REST API.", + "scripting_title": "Š Š¾Š·ŃˆŠøŃ€ŠµŠ½ŠøŠ¹ скриптинг", + "scripting_description": "Š”Ń‚Š²Š¾Ń€ŃŽŠ¹Ń‚Šµ власні інтеграції в Trilium за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŃ… віГжетів або серверної логіки." + }, + "collections": { + "title": "ŠšŠ¾Š»ŠµŠŗŃ†Ń–Ń—", + "calendar_title": "ŠšŠ°Š»ŠµŠ½Š“Š°Ń€", + "calendar_description": "ŠžŃ€Š³Š°Š½Ń–Š·Š¾Š²ŃƒŠ¹Ń‚Šµ свої особисті або професійні поГії за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ ŠŗŠ°Š»ŠµŠ½Š“Š°Ń€Ń Š· ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŠŗŠ¾ŃŽ цілоГенних та багатоГенних поГій. ŠŸŠµŃ€ŠµŠ³Š»ŃŠ“Š°Š¹Ń‚Šµ свої поГії Š· ŠæŠµŃ€ŃˆŠ¾Š³Š¾ ŠæŠ¾Š³Š»ŃŠ“Ńƒ Š·Š°Š²Š“ŃŠŗŠø Ń‚ŠøŠ¶Š½ŠµŠ²Š¾Š¼Ńƒ, Š¼Ń–ŃŃŃ‡Š½Š¾Š¼Ńƒ та Ń€Ń–Ń‡Š½Š¾Š¼Ńƒ ŠæŠµŃ€ŠµŠ³Š»ŃŠ“Š°Š¼. Легке Š“Š¾Š“Š°Š²Š°Š½Š½Ń або ŠæŠµŃ€ŠµŃ‚ŃŠ³ŃƒŠ²Š°Š½Š½Ń поГій.", + "table_title": "Š¢Š°Š±Š»ŠøŃ†Ń", + "table_description": "ВіГображайте та Ń€ŠµŠ“Š°Š³ŃƒŠ¹Ń‚Šµ Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ про нотатки в табличній ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ń– Š· різними типами стовпців, такими ŃŠŗ текст, число, прапорці, Гата й час, ŠæŠ¾ŃŠøŠ»Š°Š½Š½Ń та ŠŗŠ¾Š»ŃŒŠ¾Ń€Šø, а також піГтримка зв'ŃŠ·ŠŗŃ–Š². За потреби віГображайте нотатки в ГеревопоГібній ієрархії всереГині таблиці.", + "board_title": "Š”Š¾ŃˆŠŗŠ° Kanban", + "board_description": "ŠžŃ€Š³Š°Š½Ń–Š·ŃƒŠ¹Ń‚Šµ свої Š·Š°Š²Š“Š°Š½Š½Ń або ŃŃ‚Š°Ń‚ŃƒŃŠø проектів на Š“Š¾ŃˆŃ†Ń– Kanbanза Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ простого способу ŃŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń нових елементів і стовпців, а також простої зміни їх ŃŃ‚Š°Ń‚ŃƒŃŃƒ ŃˆŠ»ŃŃ…Š¾Š¼ ŠæŠµŃ€ŠµŃ‚ŃŠ³ŃƒŠ²Š°Š½Š½Ń по Š“Š¾ŃˆŃ†Ń–.", + "geomap_title": "Геокарта", + "geomap_description": "ŠŸŠ»Š°Š½ŃƒŠ¹Ń‚Šµ ŃŠ²Š¾ŃŽ Š²Ń–Š“ŠæŃƒŃŃ‚ŠŗŃƒ або позначайте цікаві Š¼Ń–ŃŃ†Ń Š±ŠµŠ·ŠæŠ¾ŃŠµŃ€ŠµŠ“Š½ŃŒŠ¾ на географічній карті за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ Š½Š°Š»Š°ŃˆŃ‚Š¾Š²ŃƒŠ²Š°Š½ŠøŃ… маркерів. ВіГображайте записані GPX-треки Š“Š»Ń Š²Ń–Š“ŃŃ‚ŠµŠ¶ŠµŠ½Š½Ń Š¼Š°Ń€ŃˆŃ€ŃƒŃ‚Ń–Š².", + "presentation_title": "ŠŸŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†Ń–Ń", + "presentation_description": "Š£ŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ¹Ń‚Šµ Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ у слайГи та ŠæŃ€ŠµŠ·ŠµŠ½Ń‚ŃƒŠ¹Ń‚Šµ їх у ŠæŠ¾Š²Š½Š¾ŠµŠŗŃ€Š°Š½Š½Š¾Š¼Ńƒ режимі Š· плавними перехоГами. ДлайГи також можна ŠµŠŗŃŠæŠ¾Ń€Ń‚ŃƒŠ²Š°Ń‚Šø у PDF Š“Š»Ń Š·Ń€ŃƒŃ‡Š½Š¾Š³Š¾ Š¾Š±Š¼Ń–Š½Ńƒ." + }, + "faq": { + "title": "Часті Š·Š°ŠæŠøŃ‚Š°Š½Š½Ń", + "mobile_question": "Чи є Š¼Š¾Š±Ń–Š»ŃŒŠ½ŠøŠ¹ ГоГаток?", + "mobile_answer": "ŠŠ°Ń€Š°Š·Ń– офіційного Š¼Š¾Š±Ń–Š»ŃŒŠ½Š¾Š³Š¾ Š·Š°ŃŃ‚Š¾ŃŃƒŠ½ŠŗŃƒ немає. ŠžŠ“Š½Š°Šŗ, ŃŠŗŃ‰Š¾ у вас є серверний ŠµŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€, ви можете отримати Го нього Š“Š¾ŃŃ‚ŃƒŠæ за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ Š²ŠµŠ±Š±Ń€Š°ŃƒŠ·ŠµŃ€Š° та Š½Š°Š²Ń–Ń‚ŃŒ встановити його ŃŠŗ PWA. Š”Š»Ń Android Ń–ŃŠ½ŃƒŃ” неофіційний Š·Š°ŃŃ‚Š¾ŃŃƒŠ½Š¾Šŗ піГ Š½Š°Š·Š²Š¾ŃŽ TriliumDroid, ŃŠŗŠøŠ¹ ŠæŃ€Š°Ń†ŃŽŃ” Š½Š°Š²Ń–Ń‚ŃŒ офлайн (так само, ŃŠŗ і клієнт Š“Š»Ń Š½Š°ŃŃ‚Ń–Š»ŃŒŠ½ŠøŃ… ŠŗŠ¾Š¼Šæā€™ŃŽŃ‚ŠµŃ€Ń–Š²).", + "database_question": "Де Š·Š±ŠµŃ€Ń–Š³Š°ŃŽŃ‚ŃŒŃŃ Гані?", + "database_answer": "Усі Š²Š°ŃˆŃ– нотатки Š·Š±ŠµŃ€Ń–Š³Š°Ń‚ŠøŠ¼ŃƒŃ‚ŃŒŃŃ в базі Ганих SQLite в папці програми. ŠŸŃ€ŠøŃ‡ŠøŠ½Š°, Ń‡Š¾Š¼Ńƒ Trilium Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” базу Ганих Š·Š°Š¼Ń–ŃŃ‚ŃŒ звичайних текстових файлів, пов'ŃŠ·Š°Š½Š° ŃŠŗ Š· ŠæŃ€Š¾Š“ŃƒŠŗŃ‚ŠøŠ²Š½Ń–ŃŃ‚ŃŽ, так і Š· тим, що Š“ŠµŃŠŗŃ– Ń„ŃƒŠ½ŠŗŃ†Ń–Ń— було б набагато ŃŠŗŠ»Š°Š“Š½Ń–ŃˆŠµ Ń€ŠµŠ°Š»Ń–Š·ŃƒŠ²Š°Ń‚Šø, такі ŃŠŗ клони (оГна й та сама нотатка в ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… Š¼Ń–ŃŃ†ŃŃ… Герева). Щоб знайти папку програми, просто ŠæŠµŃ€ŠµŠ¹Š“Ń–Ń‚ŃŒ Го вікна Ā«ŠŸŃ€Š¾ ŃŠøŃŃ‚ŠµŠ¼ŃƒĀ».", + "server_question": "Чи потрібен мені сервер Š“Š»Ń Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń Trilium?", + "server_answer": "ŠŃ–, сервер Š“Š¾Š·Š²Š¾Š»ŃŃ” Š“Š¾ŃŃ‚ŃƒŠæ через Š²ŠµŠ±Š±Ń€Š°ŃƒŠ·ŠµŃ€ і ŠŗŠµŃ€ŃƒŃ” ŃŠøŠ½Ń…Ń€Š¾Š½Ń–Š·Š°Ń†Ń–Ń”ŃŽ, ŃŠŗŃ‰Š¾ у вас ŠŗŃ–Š»ŃŒŠŗŠ° пристроїв. Щоб розпочати, Š“Š¾ŃŃ‚Š°Ń‚Š½ŃŒŠ¾ завантажити Гесктопний Š·Š°ŃŃ‚Š¾ŃŃƒŠ½Š¾Šŗ і почати ним ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‚ŠøŃŃ.", + "scaling_question": "ŠŠ°ŃŠŗŃ–Š»ŃŒŠŗŠø Гобре Š¼Š°ŃŃˆŃ‚Š°Š±ŃƒŃ”Ń‚ŃŒŃŃ Š·Š°ŃŃ‚Š¾ŃŃƒŠ½Š¾Šŗ Š· Š²ŠµŠ»ŠøŠŗŠ¾ŃŽ ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŽ нотаток?", + "scaling_answer": "Залежно віГ Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń, програма має Š±ŃƒŃ‚Šø Š·Š“Š°Ń‚Š½Š¾ŃŽ без проблем Š¾Š±Ń€Š¾Š±Š»ŃŃ‚Šø Ń‰Š¾Š½Š°Š¹Š¼ŠµŠ½ŃˆŠµ 100 000 нотаток. Š—Š²ŠµŃ€Š½Ń–Ń‚ŃŒ увагу, що процес синхронізації іноГі може Š·Š°Š²ŠµŃ€ŃˆŠøŃ‚ŠøŃŃ Š½ŠµŠ²Š“Š°Ń‡ŠµŃŽ, ŃŠŗŃ‰Š¾ Š·Š°Š²Š°Š½Ń‚Š°Š¶ŃƒŠ²Š°Ń‚Šø багато великих файлів (1 ГБ на файл), Š¾ŃŠŗŃ–Š»ŃŒŠŗŠø Trilium призначений Ń€Š°Š“ŃˆŠµ ŃŠŗ програма бази знань, ніж ŃŠŗ сховище файлів (наприклаГ, NextCloud).", + "network_share_question": "Чи можна наГати ŃŠæŃ–Š»ŃŒŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŃƒŠæ Го бази Ганих через мережевий Гиск?", + "network_share_answer": "ŠŃ–, зазвичай не Ń€ŠµŠŗŠ¾Š¼ŠµŠ½Š“ŃƒŃ”Ń‚ŃŒŃŃ Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø ŃŠæŃ–Š»ŃŒŠ½ŠøŠ¹ Š“Š¾ŃŃ‚ŃƒŠæ Го бази Ганих SQLite через мережевий Гиск. Єоча іноГі це може ŃŠæŃ€Š°Ń†ŃŽŠ²Š°Ń‚Šø, Ń–ŃŠ½ŃƒŃ” Š¹Š¼Š¾Š²Ń–Ń€Š½Ń–ŃŃ‚ŃŒ ŠæŠ¾ŃˆŠŗŠ¾Š“Š¶ŠµŠ½Š½Ń бази Ганих через неГосконале Š±Š»Š¾ŠŗŃƒŠ²Š°Š½Š½Ń файлів у мережі.", + "security_question": "ŠÆŠŗ захищені мої Гані?", + "security_answer": "За Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼ нотатки не ŃˆŠøŃ„Ń€ŃƒŃŽŃ‚ŃŒŃŃ та їх можна Š·Ń‡ŠøŃ‚ŃƒŠ²Š°Ń‚Šø Š±ŠµŠ·ŠæŠ¾ŃŠµŃ€ŠµŠ“Š½ŃŒŠ¾ Š· бази Ганих. ŠŸŃ–ŃŠ»Ń того, ŃŠŗ Š½Š¾Ń‚Š°Ń‚ŠŗŃƒ позначено ŃŠŗ Š·Š°ŃˆŠøŃ„Ń€Š¾Š²Š°Š½Ńƒ, вона ŃˆŠøŃ„Ń€ŃƒŃ”Ń‚ŃŒŃŃ за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ AES-128-CBC." + }, + "final_cta": { + "title": "Готові розпочати Ń€Š¾Š±Š¾Ń‚Ńƒ Š· Trilium Notes?", + "description": "Š”Ń‚Š²Š¾Ń€Ń–Ń‚ŃŒ ŃŠ²Š¾ŃŽ Š¾ŃŠ¾Š±ŠøŃŃ‚Ńƒ базу знань за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ ŠæŠ¾Ń‚ŃƒŠ¶Š½ŠøŃ… Ń„ŃƒŠ½ŠŗŃ†Ń–Š¹ та повної конфіГенційності.", + "get_started": "ŠŸŠ¾Ń‡Š°Ń‚Šø" + }, + "components": { + "link_learn_more": "Š”Ń–Š·Š½Š°Ń‚ŠøŃŃ Š±Ń–Š»ŃŒŃˆŠµ..." + }, + "download_now": { + "text": "Завантажити зараз ", + "platform_big": "v{{version}} Š“Š»Ń {{platform}}", + "platform_small": "Š“Š»Ń {{platform}}", + "linux_big": "v{{version}} Š“Š»Ń Linux", + "linux_small": "Š“Š»Ń Linux", + "more_platforms": "Š‘Ń–Š»ŃŒŃˆŠµ платформ та Š½Š°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń серверів" + }, + "header": { + "get-started": "ŠŸŠ¾Ń‡Š°Ń‚Šø", + "documentation": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń", + "support-us": "ŠŸŃ–Š“Ń‚Ń€ŠøŠ¼Š°Š¹Ń‚Šµ нас", + "resources": "Š ŠµŃŃƒŃ€ŃŠø" + }, + "footer": { + "copyright_and_the": " і ", + "copyright_community": "ŃŠæŃ–Š»ŃŒŠ½Š¾Ń‚Š°" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "ŠžŠ±Š³Š¾Š²Š¾Ń€ŠµŠ½Š½Ń на GitHub", + "matrix": "ŠœŠ°Ń‚Ń€ŠøŃ†Ń", + "reddit": "Reddit" + }, + "support_us": { + "title": "ŠŸŃ–Š“Ń‚Ń€ŠøŠ¼Š°Š¹Ń‚Šµ нас", + "financial_donations_title": "Фінансова піГтримка", + "financial_donations_description": "Trilium створено та ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ”Ń‚ŃŒŃŃ Š·Š°Š²Š“ŃŠŗŠø ŃŠ¾Ń‚Š½ŃŠ¼ гоГин роботи. Š’Š°ŃˆŠ° піГтримка Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŃƒŃ” його віГкритий вихіГний коГ, ŠæŠ¾ŠŗŃ€Š°Ń‰ŃƒŃ” Ń„ŃƒŠ½ŠŗŃ†Ń–Ń— та покриває витрати, такі ŃŠŗ хостинг.", + "financial_donations_cta": "Š Š¾Š·Š³Š»ŃŠ½ŃŒŃ‚Šµ Š¼Š¾Š¶Š»ŠøŠ²Ń–ŃŃ‚ŃŒ піГтримки головного розробника (eliandoran) програми через:", + "github_sponsors": "GitHub Дпонсори", + "paypal": "PayPal", + "buy_me_a_coffee": "Купи мені кави" + }, + "contribute": { + "title": "Š†Š½ŃˆŃ– способи зробити внесок", + "way_translate": "ŠŸŠµŃ€ŠµŠŗŠ»Š°Š“Ń–Ń‚ŃŒ ŠæŃ€Š¾Š³Ń€Š°Š¼Ńƒ Š²Š°ŃˆŠ¾ŃŽ Ń€Ń–Š“Š½Š¾ŃŽ Š¼Š¾Š²Š¾ŃŽ за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ Weblate.", + "way_community": "ВзаємоГійте Š·Ń– ŃŠæŃ–Š»ŃŒŠ½Š¾Ń‚Š¾ŃŽ на GitHub ŠžŠ±Š³Š¾Š²Š¾Ń€ŠµŠ½Š½Ń або на Matrix.", + "way_reports": "ŠŸŠ¾Š²Ń–Š“Š¾Š¼Š»ŃŠ¹Ń‚Šµ про помилки через ŠŸŃ€Š¾Š±Š»ŠµŠ¼Šø GitHub.", + "way_document": "ŠŸŠ¾ŠŗŃ€Š°Ń‰ŃƒŠ¹Ń‚Šµ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–ŃŽ, ŠæŠ¾Š²Ń–Š“Š¾Š¼Š»ŃŃŽŃ‡Šø нас про прогалини в ній або Š½Š°Š“Š°ŃŽŃ‡Šø посібники, віГповіГі на ŠæŠ¾ŃˆŠøŃ€ŠµŠ½Ń– Š·Š°ŠæŠøŃ‚Š°Š½Š½Ń чи Š½Š°Š²Ń‡Š°Š»ŃŒŠ½Ń– посібники.", + "way_market": "ŠŸŠ¾ŃˆŠøŃ€Ń‚Šµ Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ: ŠæŠ¾Š“Ń–Š»Ń–Ń‚ŃŒŃŃ нотатками Trilium Š· Š“Ń€ŃƒŠ·ŃŠ¼Šø або в блогах і ŃŠ¾Ń†Ń–Š°Š»ŃŒŠ½ŠøŃ… мережах." + }, + "404": { + "title": "404: ŠŠµ знайГено", + "description": "Š”Ń‚Š¾Ń€Ń–Š½ŠŗŃƒ, ŃŠŗŃƒ ви шукали, не знайГено. Можливо, її виГалили або URL-аГреса Š½ŠµŠæŃ€Š°Š²ŠøŠ»ŃŒŠ½Š°." + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64-bit", + "title_arm64": "Windows на ARM", + "description_x64": "Š”ŃƒŠ¼Ń–ŃŠ½ŠøŠ¹ Š· ŠæŃ€ŠøŃŃ‚Ń€Š¾ŃŠ¼Šø Intel або AMD піГ ŃƒŠæŃ€Š°Š²Š»Ń–Š½Š½ŃŠ¼ Windows 10 та 11.", + "description_arm64": "Š”ŃƒŠ¼Ń–ŃŠ½ŠøŠ¹ Š· ŠæŃ€ŠøŃŃ‚Ń€Š¾ŃŠ¼Šø ARM (наприклаГ, Š· Qualcomm Snapdragon).", + "quick_start": "Щоб встановити через Winget:", + "download_exe": "Завантажити Ń–Š½ŃŃ‚Š°Š»ŃŃ‚Š¾Ń€ (.exe)", + "download_zip": "ŠŸŠ¾Ń€Ń‚Š°Ń‚ŠøŠ²Š½ŠøŠ¹ (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64-bit", + "title_arm64": "Linux на ARM", + "description_x64": "Š”Š»Ń Š±Ń–Š»ŃŒŃˆŠ¾ŃŃ‚Ń– Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Ń–Š² Linux, ŃŃƒŠ¼Ń–ŃŠ½ŠøŃ… Š· Š°Ń€Ń…Ń–Ń‚ŠµŠŗŃ‚ŃƒŃ€Š¾ŃŽ x86_64.", + "description_arm64": "Š”Š»Ń Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Ń–Š² Linux на базі ARM, ŃŃƒŠ¼Ń–ŃŠ½ŠøŃ… Š· Š°Ń€Ń…Ń–Ń‚ŠµŠŗŃ‚ŃƒŃ€Š¾ŃŽ aarch64.", + "quick_start": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ віГповіГний формат пакета, залежно віГ вашого Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Š°:", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_nixpkgs": "nixpkgs", + "download_zip": "Portable (.zip)", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS Š“Š»Ń Intel", + "title_arm64": "macOS Š“Š»Ń Apple Silicon", + "quick_start": "Š”Š»Ń того, щоб встановити за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ Homebrew:", + "download_homebrew_cask": "Homebrew Cask", + "description_x64": "Š”Š»Ń ŠŗŠ¾Š¼Šæā€™ŃŽŃ‚ŠµŃ€Ń–Š² Mac на базі Intel Š· macOS Monterey або ŠæŃ–Š·Š½Ń–ŃˆŠ¾Ń— версії.", + "description_arm64": "Š”Š»Ń комп'ŃŽŃ‚ŠµŃ€Ń–Š² Apple Silicon Mac, таких ŃŠŗ ті, що Š¼Š°ŃŽŃ‚ŃŒ чіпи M1 та M2.", + "download_dmg": "Завантажити Ń–Š½ŃŃ‚Š°Š»ŃŃ‚Š¾Ń€ (.dmg)", + "download_zip": "Portable (.zip)" + }, + "download_helper_server_docker": { + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io", + "title": "Self-hosted using Docker", + "description": "Легке Ń€Š¾Š·Š³Š¾Ń€Ń‚Š°Š½Š½Ń на Windows, Linux або macOS за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ контейнера Docker." + }, + "download_helper_server_linux": { + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "title": "Self-hosted on Linux", + "description": "Š Š¾Š·Š³Š¾Ń€Š½Ń–Ń‚ŃŒ Trilium Notes на власному сервері або VPS, ŃŃƒŠ¼Ń–ŃŠ½Š¾Š¼Ńƒ Š· Š±Ń–Š»ŃŒŃˆŃ–ŃŃ‚ŃŽ Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Ń–Š².", + "download_nixos": "NixOS module" + }, + "download_helper_server_hosted": { + "title": "ŠŸŠ»Š°Ń‚Š½ŠøŠ¹ хостинг", + "description": "ŠŠ¾Ń‚Š°Ń‚ŠŗŠø Trilium розміщені на PikaPods, ŠæŠ»Š°Ń‚Š½Š¾Š¼Ńƒ сервісі Š“Š»Ń легкого Š“Š¾ŃŃ‚ŃƒŠæŃƒ та ŠŗŠµŃ€ŃƒŠ²Š°Š½Š½Ń. ŠŠµ пов'ŃŠ·Š°Š½ŠøŠ¹ Š±ŠµŠ·ŠæŠ¾ŃŠµŃ€ŠµŠ“Š½ŃŒŠ¾ Š· ŠŗŠ¾Š¼Š°Š½Š“Š¾ŃŽ Trilium.", + "download_pikapod": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń на PikaPods", + "download_triliumcc": "Або Гив. trilium.cc" + }, + "resources": { + "title": "Š ŠµŃŃƒŃ€ŃŠø", + "icon_packs": "ŠŸŠ°ŠŗŠµŃ‚Šø піктограм", + "icon_packs_intro": "Š Š¾Š·ŃˆŠøŃ€Ń‚Šµ вибір Š“Š¾ŃŃ‚ŃƒŠæŠ½ŠøŃ… піктограм Š“Š»Ń Š²Š°ŃˆŠøŃ… нотаток за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ ŠæŠ°ŠŗŠµŃ‚Ńƒ піктограм. Щоб отримати Š“Š¾ŠŗŠ»Š°Š“Š½Ń–ŃˆŃƒ Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ про пакети піктограм, Гив. Š¾Ń„Ń–Ń†Ń–Š¹Š½Ńƒ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–ŃŽ.", + "download": "Завантажити", + "website": "Вебсайт" + } +} diff --git a/apps/website/src/translations/vi/translation.json b/apps/website/src/translations/vi/translation.json new file mode 100644 index 0000000000..0c3088655b --- /dev/null +++ b/apps/website/src/translations/vi/translation.json @@ -0,0 +1,24 @@ +{ + "get-started": { + "title": "BįŗÆt đầu", + "desktop_title": "Tįŗ£i về ứng dỄng desktop (v{{version}})", + "architecture": "Kiįŗæn trĆŗc:", + "older_releases": "Xem cĆ”c bįŗ£n phĆ”t hĆ nh cÅ© hĘ”n", + "server_title": "Thiįŗæt lįŗ­p mĆ”y chį»§ Ä‘į»ƒ truy cįŗ­p trĆŖn nhiều thiįŗæt bị" + }, + "hero_section": { + "title": "SįŗÆp xįŗæp những suy nghÄ©. XĆ¢y dį»±ng cĘ” sở tri thức cĆ” nhĆ¢n cį»§a bįŗ”n.", + "subtitle": "Trilium lĆ  mį»™t giįŗ£i phĆ”p mĆ£ nguồn mở cho việc ghi chĆŗ vĆ  tổ chức cĘ” sở tri thức cĆ” nhĆ¢n. Sį»­ dỄng nó cỄc bį»™ trĆŖn mĆ”y tĆ­nh, hoįŗ·c đồng bį»™ vį»›i mį»™t mĆ”y chį»§ tį»± triển khai cį»§a riĆŖng bįŗ”n Ä‘į»ƒ mang theo cĆ”c ghi chĆŗ mį»i nĘ”i bįŗ”n đến.", + "get_started": "BįŗÆt đầu", + "github": "Github", + "dockerhub": "Kho Docker", + "screenshot_alt": "įŗ¢nh chỄp mĆ n hƬnh ứng dỄng Trilium Notes (desktop)" + }, + "organization_benefits": { + "title": "Tổ chức", + "note_structure_title": "Cįŗ„u trĆŗc ghi chĆŗ", + "note_structure_description": "Ghi chĆŗ có thể được sįŗÆp xįŗæp theo thứ bįŗ­c. KhĆ“ng cįŗ§n thʰ mỄc, vƬ mį»—i ghi chĆŗ có thể chứa cĆ”c ghi chĆŗ phỄ. Mį»™t ghi chĆŗ có thể được thĆŖm vĆ o nhiều vị trĆ­ trong hệ thống phĆ¢n cįŗ„p.", + "attributes_title": "CĆ”c nhĆ£n ghi chĆŗ vĆ  cĆ”c mối quan hệ", + "attributes_description": "Sį»­ dỄng mối quan hệ giữa cĆ”c ghi chĆŗ hoįŗ·c thĆŖm nhĆ£n Ä‘į»ƒ phĆ¢n loįŗ”i dį»… dĆ ng. Sį»­ dỄng cĆ”c thuį»™c tĆ­nh được khuyįŗæn khĆ­ch Ä‘į»ƒ nhįŗ­p thĆ“ng tin có cįŗ„u trĆŗc có thể được sį»­ dỄng trong bįŗ£ng, bįŗ£ng biểu." + } +} diff --git a/apps/website/src/translations/zh-Hans/translation.json b/apps/website/src/translations/zh-Hans/translation.json new file mode 100644 index 0000000000..f6aeba9812 --- /dev/null +++ b/apps/website/src/translations/zh-Hans/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "desktop_title": "äø‹č½½ę”Œé¢ē‰ˆåŗ”ē”Ø (v{{version}})", + "architecture": "ęž¶ęž„ļ¼š", + "title": "开始使用", + "older_releases": "ęŸ„ēœ‹åŽ†å²ē‰ˆęœ¬", + "server_title": "č®¾ē½®ęœåŠ”å™Øä»„ä¾›å¤šå°č®¾å¤‡č®æé—®" + }, + "organization_benefits": { + "hoisting_description": "ä½ åÆä»„é€ščæ‡å°†äøŖäŗŗē¬”č®°å’Œå·„ä½œē¬”č®°åˆ†ē»„åˆ°äøåŒēš„å·„ä½œåŒŗäø­ļ¼Œč½»ę¾åœ°å°†å®ƒä»¬åˆ†å¼€ć€‚ęÆäøŖå·„ä½œåŒŗä¼ščšē„¦äŗŽē‰¹å®šēš„ē¬”č®°é›†åˆļ¼Œä½æä½ ēš„ē¬”č®°ę ‘ä»…ę˜¾ē¤ŗē›øå…³å†…å®¹ć€‚", + "title": "组织", + "note_structure_title": "ē¬”č®°ē»“ęž„", + "note_structure_description": "ē¬”č®°åÆęŒ‰å±‚ēŗ§ęŽ’åˆ—ć€‚ē”±äŗŽęÆę”ē¬”č®°å‡åÆåŒ…å«å­ē¬”č®°ļ¼Œå› ę­¤ę— éœ€ä½æē”Øę–‡ä»¶å¤¹ć€‚å•ę”ē¬”č®°åÆåœØå±‚ēŗ§ē»“ęž„äø­ēš„å¤šäøŖä½ē½®ę·»åŠ ć€‚", + "attributes_title": "ē¬”č®°ę ‡ē­¾åŠå…³ē³»", + "attributes_description": "åˆ©ē”Øē¬”č®°é—“ēš„å…³ē³»ęˆ–ę·»åŠ ę ‡ē­¾čæ›č”Œä¾æę·åˆ†ē±»ć€‚ä½æē”Øęå‡å±žę€§č¾“å…„ē»“ęž„åŒ–äæ”ęÆļ¼Œčæ™äŗ›äæ”ęÆåÆē”ØäŗŽč”Øę ¼å’Œēœ‹ęæäø­ć€‚", + "hoisting_title": "å·„ä½œåŒŗäøŽęå‡" + }, + "productivity_benefits": { + "title": "é«˜ę•ˆäø”å®‰å…Ø", + "revisions_title": "ē¬”č®°åŽ†å²ē‰ˆęœ¬", + "revisions_content": "ē¬”č®°ä¼šåœØåŽå°å®šęœŸäæå­˜ļ¼Œäø”äæ®č®¢ē‰ˆęœ¬åÆē”ØäŗŽå›žé”¾ęˆ–ę’¤é”€čÆÆäæ®ę”¹ć€‚ä½ ä¹ŸåÆä»„ęŒ‰éœ€åˆ›å»ŗäæ®č®¢ē‰ˆęœ¬ć€‚", + "sync_title": "同歄", + "sync_content": "ä½æē”Øč‡Ŗå»ŗęˆ–äŗ‘ē«Æå®žä¾‹ļ¼ŒåÆä»„č½»ę¾åœ°åœØå¤šč®¾å¤‡ä¹‹é—“åŒę­„ē¬”č®°ļ¼Œå¹¶é€ščæ‡ PWA ä»Žę‰‹ęœŗäøŠč®æé—®å®ƒć€‚", + "protected_notes_title": "č¢«äæęŠ¤ēš„ē¬”č®°", + "protected_notes_content": "é€ščæ‡åŠ åÆ†ē¬”č®°å¹¶å°†å…¶é”å®šåœØå—åÆ†ē äæęŠ¤ēš„ä¼ščÆäø­ļ¼Œę„äæęŠ¤ę•ę„Ÿēš„äøŖäŗŗäæ”ęÆć€‚", + "jump_to_title": "åæ«é€Ÿēš„ęœē“¢å’Œå‘½ä»¤", + "jump_to_content": "é€ščæ‡ęœē“¢ę ‡é¢˜ļ¼ŒåÆä»„åœØå±‚ēŗ§ē»“ęž„äø­åæ«é€Ÿč·³č½¬åˆ°ē¬”č®°ęˆ– UI å‘½ä»¤ļ¼›ęØ”ē³ŠåŒ¹é…åÆå®¹åæę‹¼å†™é”™čÆÆęˆ–ē»†å¾®å·®å¼‚ć€‚", + "search_content": "ęˆ–č€…åœØē¬”č®°äø­ęœē“¢ę–‡ęœ¬ļ¼Œå¹¶é€ščæ‡ē­›é€‰ēˆ¶ē¬”č®°ęˆ–ę·±åŗ¦ę„ē¼©å°ęœē“¢čŒƒå›“ć€‚", + "web_clipper_content": "ęŠ“å–ē½‘é”µļ¼ˆęˆ–ęˆŖå›¾ļ¼‰ļ¼Œå¹¶é€ščæ‡ē½‘é”µå‰Ŗč—ęµč§ˆå™Øę‰©å±•ē›“ęŽ„äæå­˜åˆ° Trilium 中。", + "search_title": "å¼ŗå¤§ēš„ęœē“¢åŠŸčƒ½", + "web_clipper_title": "ē½‘é”µęŠ“å–å™Ø" + }, + "note_types": { + "text_title": "ę–‡ęœ¬ē¬”č®°", + "text_description": "ē¬”č®°ę˜Æä½æē”ØåÆč§†åŒ–ļ¼ˆę‰€č§å³ę‰€å¾—ļ¼ŒWYSIWYGļ¼‰ē¼–č¾‘å™Øčæ›č”Œē¼–č¾‘ēš„ļ¼Œę”ÆęŒč”Øę ¼ć€å›¾åƒć€ę•°å­¦č”Øč¾¾å¼å’Œåø¦čÆ­ę³•é«˜äŗ®ēš„ä»£ē å—ć€‚ä½ åÆä»„é€ščæ‡ē±»ä¼¼ Markdown ēš„čÆ­ę³•ęˆ–ä½æē”Øę–œę å‘½ä»¤åæ«é€Ÿę ¼å¼åŒ–ę–‡ęœ¬ć€‚", + "code_title": "代码笔记", + "code_description": "å¤§é‡ęŗä»£ē ęˆ–č„šęœ¬é€šåøøä½æē”Øäø“é—Øēš„ē¼–č¾‘å™Øčæ›č”Œē¼–å†™ļ¼Œčæ™ē±»ē¼–č¾‘å™Øäøŗå¤šē§ē¼–ēØ‹čÆ­čØ€ęä¾›čÆ­ę³•é«˜äŗ®ļ¼Œå¹¶ę”ÆęŒå¤šē§é…č‰²äø»é¢˜ć€‚", + "file_title": "文件笔记", + "file_description": "åµŒå…„å¤šåŖ’ä½“ę–‡ä»¶ļ¼ˆå¦‚ PDFć€å›¾åƒć€č§†é¢‘ļ¼‰ļ¼Œå¹¶åœØåŗ”ē”ØēØ‹åŗå†…čæ›č”Œé¢„č§ˆć€‚", + "canvas_title": "ē”»åøƒ", + "canvas_description": "åœØę— é™ē”»åøƒäøŠęŽ’åˆ—å½¢ēŠ¶ć€å›¾åƒå’Œę–‡ęœ¬ļ¼Œä½æē”ØäøŽ excalidraw.com ē›øåŒēš„ęŠ€ęœÆć€‚éžåøøé€‚åˆē”ØäŗŽē»˜åˆ¶å›¾č”Øć€č‰å›¾å’Œčæ›č”ŒåÆč§†åŒ–č§„åˆ’ć€‚", + "mermaid_title": "Mermaid 图蔨", + "mermaid_description": "使用 Mermaid čÆ­ę³•åˆ›å»ŗå„ē§å›¾č”Øļ¼Œä¾‹å¦‚ęµēØ‹å›¾ć€ē±»å›¾å’Œę—¶åŗå›¾ć€ē”˜ē‰¹å›¾ē­‰ć€‚", + "mindmap_title": "ę€ē»“åÆ¼å›¾", + "mindmap_description": "ęŠŠä½ ēš„ęƒ³ę³•ē”Øč§†č§‰ę–¹å¼ę•“ē†å‡ŗę„ļ¼Œęˆ–č€…čæ›č”Œäø€ę¬”å¤“č„‘é£Žęš“ć€‚", + "others_list": "ä»„åŠå…¶ä»–å†…å®¹ļ¼š<0>ē¬”č®°ę˜ å°„ć€<1>å…³ē³»ę˜ å°„ć€<2>å·²äæå­˜ēš„ęœē“¢ć€<3>ęø²ęŸ“ē¬”č®° 和 <4>网锵视图。", + "title": "å¤šē§äæ”ęÆå‘ˆēŽ°ę–¹å¼" + }, + "extensibility_benefits": { + "title": "åˆ†äŗ«äøŽåÆę‰©å±•ę€§", + "import_export_title": "导兄/导出", + "import_export_description": "使用 Markdown态ENEX态OML ę ¼å¼å³åÆč½»ę¾äøŽå…¶ä»–åŗ”ē”ØēØ‹åŗäŗ¤äŗ’ć€‚", + "share_title": "åœØē½‘ē»œäøŠåˆ†äŗ«ē¬”č®°", + "share_description": "å¦‚ęžœä½ ęœ‰äø€å°ęœåŠ”å™Øļ¼Œå®ƒåÆä»„ē”Øę„äøŽä»–äŗŗå…±äŗ«ä½ ēš„äø€éƒØåˆ†ē¬”č®°ć€‚", + "scripting_title": "é«˜ēŗ§č„šęœ¬ē¼–å†™", + "scripting_description": "在 Trilium äø­é€ščæ‡č‡Ŗå®šä¹‰å°éƒØä»¶ęˆ–ęœåŠ”å™Øē«Æé€»č¾‘ęž„å»ŗäø“å±žé›†ęˆę–¹ę”ˆć€‚", + "api_title": "REST API", + "api_description": "é€ščæ‡å…¶å†…ē½®ēš„ REST API ä»„ē¼–ēØ‹ę–¹å¼äøŽ Trilium čæ›č”Œäŗ¤äŗ’ć€‚" + }, + "download_helper_server_hosted": { + "download_triliumcc": "ä¹ŸåÆä»„č®æé—® trilium.cc", + "title": "ä»˜č“¹ę‰˜ē®”", + "description": "Trilium Notes ę‰˜ē®”äŗŽ PikaPodsļ¼ŒčÆ„ä»˜č“¹ęœåŠ”ęä¾›ä¾æę·č®æé—®äøŽē®”ē†åŠŸčƒ½ć€‚äøŽ Trilium å›¢é˜Ÿę— ē›“ęŽ„å…³č”ć€‚", + "download_pikapod": "在 PikaPods 上设置" + }, + "download_helper_desktop_linux": { + "download_aur": "AUR", + "download_nixpkgs": "nixpkgs", + "title_x64": "Linux 64位", + "title_arm64": "åŸŗäŗŽ ARM ęž¶ęž„ēš„ Linux", + "description_x64": "é€‚ē”ØäŗŽå¤§å¤šę•° Linux å‘č”Œē‰ˆļ¼Œå…¼å®¹ x86_64 ꞶꞄ怂", + "description_arm64": "é€‚ē”ØäŗŽåŸŗäŗŽ ARM ęž¶ęž„ēš„ Linux å‘č”Œē‰ˆļ¼Œå…¼å®¹ aarch64 ꞶꞄ怂", + "quick_start": "ę ¹ę®ä½ ēš„å‘č”Œē‰ˆé€‰ę‹©åˆé€‚ēš„č½Æä»¶åŒ…ę ¼å¼ļ¼š", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "ä¾æęŗē‰ˆļ¼ˆ.zip)" + }, + "hero_section": { + "title": "ę•“ē†ä½ ēš„ę€č·Æć€‚å»ŗē«‹ä½ ēš„äøŖäŗŗēŸ„čÆ†åŗ“ć€‚", + "subtitle": "Trilium ę˜Æäø€ę¬¾å¼€ęŗēš„ē¬”č®°å·„å…·ļ¼Œē”ØäŗŽč®°å½•å’Œę•“ē†äøŖäŗŗēŸ„čÆ†åŗ“ć€‚ä½ åÆä»„åœØęœ¬åœ°ę”Œé¢ä½æē”Øå®ƒļ¼Œęˆ–å°†å…¶äøŽč‡Ŗå»ŗęœåŠ”å™ØåŒę­„ļ¼Œč®©ē¬”č®°éšč”Œéšč®°ć€‚", + "get_started": "开始使用", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Trilium Notes ę”Œé¢åŗ”ē”ØēØ‹åŗēš„å±å¹•ęˆŖå›¾" + }, + "collections": { + "title": "集合", + "calendar_title": "ę—„åŽ†", + "calendar_description": "ä½æē”Øę—„åŽ†ē®”ē†äøŖäŗŗęˆ–å·„ä½œę“»åŠØļ¼Œę”ÆęŒå…Øå¤©åŠå¤šę—„ę“»åŠØć€‚é€ščæ‡å‘Øč§†å›¾ć€ęœˆč§†å›¾å’Œå¹“č§†å›¾åæ«é€ŸęŸ„ēœ‹ę‰€ęœ‰ę“»åŠØć€‚č½»ę¾äŗ¤äŗ’å³åÆę·»åŠ ęˆ–ę‹–ę‹½ę“»åŠØć€‚", + "table_title": "蔨格", + "table_description": "ä»„č”Øę ¼ē»“ęž„ę˜¾ē¤ŗå’Œē¼–č¾‘ē¬”č®°äæ”ęÆļ¼Œę”ÆęŒå¤šē§åˆ—ē±»åž‹ļ¼ŒåŒ…ę‹¬ę–‡ęœ¬ć€ę•°å­—ć€å¤é€‰ę”†ć€ę—„ęœŸäøŽę—¶é—“ć€é“¾ęŽ„å’Œé¢œč‰²ļ¼Œå¹¶ę”ÆęŒå…³ē³»åŠŸčƒ½ć€‚åÆé€‰åœ°ļ¼ŒåœØč”Øę ¼å†…ä»„ę ‘å½¢å±‚ę¬”ē»“ęž„ę˜¾ē¤ŗē¬”č®°ć€‚", + "board_title": "ēœ‹ęæ", + "board_description": "å°†ä»»åŠ”ęˆ–é”¹ē›®ēŠ¶ę€ę•“ē†ęˆēœ‹ęæļ¼Œč½»ę¾åˆ›å»ŗę–°äŗ‹é”¹å’Œåˆ—ļ¼ŒåŖéœ€åœØēœ‹ęæäøŠę‹–ę‹½å³åÆē®€å•ę›“ę”¹ēŠ¶ę€ć€‚", + "geomap_title": "åœ°ē†åœ°å›¾", + "geomap_description": "ä½æē”ØåÆč‡Ŗå®šä¹‰ēš„ę ‡č®°ļ¼Œē›“ęŽ„åœØåœ°ē†åœ°å›¾äøŠč§„åˆ’ę‚Øēš„å‡ęœŸęˆ–ę ‡č®°å…“č¶£ē‚¹ć€‚ę˜¾ē¤ŗč®°å½•ēš„ GPX č½Øčæ¹ä»„čæ½čøŖč”ŒēØ‹č·Æēŗæć€‚", + "presentation_title": "演示", + "presentation_description": "å°†äæ”ęÆę•“ē†ęˆå¹»ēÆē‰‡ļ¼Œå¹¶ä»„å…Øå±ęØ”å¼å‘ˆēŽ°ļ¼Œé…ä»„ęµē•…ēš„čæ‡ęø”ę•ˆęžœć€‚å¹»ēÆē‰‡čæ˜åÆåÆ¼å‡ŗäøŗ PDF ę ¼å¼ļ¼Œä¾æäŗŽč½»ę¾åˆ†äŗ«ć€‚" + }, + "faq": { + "title": "åøøč§é—®é¢˜č§£ē­”", + "mobile_question": "ę˜Æå¦ęœ‰ē§»åŠØåŗ”ē”ØēØ‹åŗļ¼Ÿ", + "mobile_answer": "ē›®å‰å°šę— å®˜ę–¹ē§»åŠØåŗ”ē”ØēØ‹åŗć€‚ä½†č‹„ę‚Øę‹„ęœ‰ęœåŠ”å™Øå®žä¾‹ļ¼ŒåÆé€ščæ‡ē½‘é”µęµč§ˆå™Øč®æé—®ļ¼Œē”šč‡³å°†å…¶å®‰č£…äøŗęøčæ›å¼ē½‘é”µåŗ”ē”Øļ¼ˆPWAļ¼‰ć€‚åÆ¹äŗŽå®‰å“ē”Øęˆ·ļ¼Œå­˜åœØäø€ę¬¾åäøŗ TriliumDroid ēš„éžå®˜ę–¹åŗ”ē”ØēØ‹åŗļ¼ŒčÆ„ēØ‹åŗę”ÆęŒē¦»ēŗæä½æē”Øļ¼ˆäøŽę”Œé¢å®¢ęˆ·ē«ÆåŠŸčƒ½ē›øåŒļ¼‰ć€‚", + "database_question": "ę•°ę®å­˜å‚ØåœØä½•å¤„ļ¼Ÿ", + "database_answer": "ę‰€ęœ‰ē¬”č®°éƒ½å°†å­˜å‚ØåœØåŗ”ē”ØēØ‹åŗę–‡ä»¶å¤¹äø­ēš„ SQLite ę•°ę®åŗ“å†…ć€‚Trilium é‡‡ē”Øę•°ę®åŗ“č€ŒéžēŗÆę–‡ęœ¬ę–‡ä»¶ēš„åŽŸå› åœØäŗŽļ¼šę•°ę®åŗ“čƒ½ęå‡ę€§čƒ½ļ¼Œäø”ęŸäŗ›åŠŸčƒ½ļ¼ˆå¦‚å…‹éš†åŠŸčƒ½ā€”ā€”å³åœØę ‘å½¢ē»“ęž„äø­å¤šå¤„ę˜¾ē¤ŗåŒäø€ē¬”č®°ļ¼‰é€ščæ‡ę–‡ęœ¬ę–‡ä»¶å®žēŽ°éš¾åŗ¦č¾ƒå¤§ć€‚č‹„éœ€ęŸ„ę‰¾åŗ”ē”ØēØ‹åŗę–‡ä»¶å¤¹ļ¼ŒčÆ·å‰å¾€ā€œå…³äŗŽā€ēŖ—å£å³åÆć€‚", + "server_question": "使用 Trilium éœ€č¦ęœåŠ”å™Øå—ļ¼Ÿ", + "server_answer": "äøļ¼ŒęœåŠ”å™Øę”ÆęŒé€ščæ‡ē½‘é”µęµč§ˆå™Øč®æé—®ļ¼Œå¹¶čƒ½åœØę‚Øę‹„ęœ‰å¤šå°č®¾å¤‡ę—¶ē®”ē†åŒę­„ć€‚č‹„ę— åŒę­„éœ€ę±‚ļ¼ŒåŖéœ€äø‹č½½ę”Œé¢åŗ”ē”ØēØ‹åŗå³åÆć€‚", + "scaling_question": "čÆ„åŗ”ē”ØēØ‹åŗåœØå¤„ē†å¤§é‡ē¬”č®°ę—¶ę‰©å±•ę€§å¦‚ä½•ļ¼Ÿ", + "scaling_answer": "ę ¹ę®ä½æē”Øęƒ…å†µļ¼ŒčÆ„åŗ”ē”ØēØ‹åŗåŗ”čƒ½ę— éšœē¢å¤„ē†č‡³å°‘ 10 äø‡ę”ē¬”č®°ć€‚čÆ·ę³Øę„ļ¼Œč‹„äøŠä¼ å¤§é‡å¤§ę–‡ä»¶ļ¼ˆå•äøŖę–‡ä»¶č¾¾ 1 GBļ¼‰ļ¼ŒåŒę­„čæ‡ēØ‹åÆčƒ½å¤±č“„ļ¼Œå› äøŗ Trilium ę›“ä¾§é‡äŗŽēŸ„čÆ†åŗ“åŗ”ē”Øč€Œéžę–‡ä»¶å­˜å‚Øļ¼ˆä¾‹å¦‚ NextCloud )。", + "network_share_question": "ęˆ‘čƒ½å¦é€ščæ‡ē½‘ē»œē”¬ē›˜å…±äŗ«ęˆ‘ēš„ę•°ę®åŗ“ļ¼Ÿ", + "network_share_answer": "äøļ¼Œé€šåøøäøå»ŗč®®é€ščæ‡ē½‘ē»œē”¬ē›˜å…±äŗ« SQLite ę•°ę®åŗ“ć€‚č™½ē„¶ęœ‰ę—¶åÆčƒ½ęœ‰ę•ˆļ¼Œä½†ē”±äŗŽē½‘ē»œēŽÆå¢ƒäø‹ę–‡ä»¶é”å®šęœŗåˆ¶ēš„äøå®Œå–„ļ¼Œę•°ę®åŗ“å­˜åœØęŸåēš„é£Žé™©ć€‚", + "security_question": "ęˆ‘ēš„ę•°ę®å¦‚ä½•å¾—åˆ°äæęŠ¤ļ¼Ÿ", + "security_answer": "é»˜č®¤ęƒ…å†µäø‹ļ¼Œē¬”č®°äøä¼šåŠ åÆ†ļ¼ŒåÆē›“ęŽ„ä»Žę•°ę®åŗ“äø­čÆ»å–ć€‚äø€ę—¦ē¬”č®°č¢«ę ‡č®°äøŗåŠ åÆ†ēŠ¶ę€ļ¼ŒčÆ„ē¬”č®°å°†ä½æē”Ø AES-128-CBC ē®—ę³•čæ›č”ŒåŠ åÆ†ć€‚" + }, + "final_cta": { + "title": "准备儽开始使用 Trilium Notes äŗ†å—ļ¼Ÿ", + "description": "å€ŸåŠ©å¼ŗå¤§åŠŸčƒ½å’Œå®Œå…Øéšē§äæęŠ¤ļ¼Œęž„å»ŗę‚Øēš„äøŖäŗŗēŸ„čÆ†åŗ“ć€‚", + "get_started": "开始使用" + }, + "components": { + "link_learn_more": "äŗ†č§£ę›“å¤šā€¦" + }, + "download_now": { + "text": "ēŽ°åœØäø‹č½½ ", + "platform_big": "v{{version}} é€‚ē”ØäŗŽ {{platform}}", + "platform_small": "é€‚ē”ØäŗŽ {{platform}}", + "linux_big": "v{{version}} é€‚ē”ØäŗŽ Linux", + "linux_small": "é€‚ē”ØäŗŽ Linux", + "more_platforms": "ę›“å¤šå¹³å°äøŽęœåŠ”å™Øč®¾ē½®" + }, + "header": { + "get-started": "开始使用", + "documentation": "文攣", + "support-us": "ę”ÆęŒęˆ‘ä»¬", + "resources": "资源" + }, + "footer": { + "copyright_and_the": " 仄及 ", + "copyright_community": "社区" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "GitHub 讨论", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "support_us": { + "title": "ę”ÆęŒęˆ‘ä»¬", + "financial_donations_title": "č“¢åŠ”ęčµ ", + "financial_donations_description": "Trilium ēš„å¼€å‘äøŽē»“ęŠ¤å‡čšäŗ† ę•°ē™¾å°ę—¶ēš„å·„ä½œć€‚ę‚Øēš„ę”ÆęŒē”®äæå…¶å¼€ęŗę€§č“Øå¾—ä»„å»¶ē»­ļ¼ŒęŽØåŠØåŠŸčƒ½ęŒē»­ä¼˜åŒ–ļ¼Œå¹¶č¦†ē›–ę‰˜ē®”ē­‰čæč„ęˆęœ¬ć€‚", + "financial_donations_cta": "čÆ·č€ƒč™‘é€ščæ‡ä»„äø‹ę–¹å¼ę”ÆęŒčÆ„åŗ”ē”ØēØ‹åŗēš„äø»č¦å¼€å‘č€…ļ¼ˆeliandoranļ¼‰ļ¼š", + "github_sponsors": "GitHub Sponsors", + "paypal": "PayPal", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "contribute": { + "title": "å…¶ä»–č“”ēŒ®ę–¹å¼", + "way_translate": "é€ščæ‡Weblateå°†åŗ”ē”ØēØ‹åŗēæ»čÆ‘ęˆä½ ēš„ęÆčÆ­ć€‚", + "way_community": "在 GitHub č®Øč®ŗęˆ– Matrix äøŠäøŽē¤¾åŒŗäŗ’åŠØć€‚", + "way_reports": "é€ščæ‡GitHub issuesęŠ„å‘Šé”™čÆÆć€‚", + "way_document": "é€ščæ‡å‘ŠēŸ„ę–‡ę”£äø­ēš„ē¼ŗå¤±å†…å®¹ęˆ–č“”ēŒ®ęŒ‡å—ć€åøøč§é—®é¢˜č§£ē­”ęˆ–ę•™ēØ‹ę„å®Œå–„ę–‡ę”£ć€‚", + "way_market": "å¹æč€Œå‘Šä¹‹ļ¼šå°† Trilium Notes åˆ†äŗ«ē»™ęœ‹å‹ļ¼Œęˆ–å‘åøƒåœØåšå®¢å’Œē¤¾äŗ¤åŖ’ä½“äøŠć€‚" + }, + "404": { + "title": "404ļ¼šęœŖę‰¾åˆ°", + "description": "ä½ č¦ęŸ„ę‰¾ēš„é”µé¢ę— ę³•ę‰¾åˆ°ć€‚åÆčƒ½ę˜ÆčÆ„é”µé¢å·²č¢«åˆ é™¤ļ¼Œęˆ–č€…ē½‘å€ęœ‰čÆÆć€‚" + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64位", + "title_arm64": "åŸŗäŗŽ ARM ēš„ Windows 系统", + "description_x64": "å…¼å®¹čæč”Œ Windows 10 和 11 ēš„č‹±ē‰¹å°”ęˆ– AMD 设备。", + "description_arm64": "兼容 ARM č®¾å¤‡ļ¼ˆä¾‹å¦‚ę­č½½é«˜é€šéŖé¾™å¤„ē†å™Øēš„č®¾å¤‡ļ¼‰ć€‚", + "quick_start": "é€ščæ‡ Winget å®‰č£…ļ¼š", + "download_exe": "äø‹č½½å®‰č£…ēØ‹åŗļ¼ˆ.exe)", + "download_zip": "ä¾æęŗē‰ˆļ¼ˆ.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_macos": { + "title_x64": "é€‚ē”ØäŗŽč‹±ē‰¹å°”å¤„ē†å™Øēš„ macOS", + "title_arm64": "é€‚ē”ØäŗŽ Apple Silicon ēš„ macOS", + "description_x64": "é€‚ē”ØäŗŽčæč”Œ macOS Monterey ęˆ–ę›“é«˜ē‰ˆęœ¬ēš„åŸŗäŗŽč‹±ē‰¹å°”å¤„ē†å™Øēš„ Mac怂", + "description_arm64": "é€‚ē”ØäŗŽę­č½½č‹¹ęžœč‡Ŗē ”čŠÆē‰‡ēš„ Mac ē”µč„‘ļ¼Œä¾‹å¦‚é…å¤‡ M1 和 M2 čŠÆē‰‡ēš„ęœŗåž‹ć€‚", + "quick_start": "é€ščæ‡ Homebrew å®‰č£…ļ¼š", + "download_dmg": "äø‹č½½å®‰č£…ēØ‹åŗ (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "ä¾æęŗē‰ˆļ¼ˆ.zip)" + }, + "download_helper_server_docker": { + "title": "使用 Docker čæ›č”Œč‡Ŗę‰˜ē®”", + "description": "č½»ę¾é€ščæ‡ Docker å®¹å™ØåœØ Windows态Linux ꈖ macOS äøŠéƒØē½²ć€‚", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "在 Linux äøŠč‡Ŗč”Œę‰˜ē®”", + "description": "åœØä½ č‡Ŗå·±ēš„ęœåŠ”å™Øęˆ–č™šę‹Ÿäø»ęœŗäøŠéƒØē½² Trilium Notesļ¼Œå…¼å®¹å¤§å¤šę•°å‘č”Œē‰ˆć€‚", + "download_tar_x64": "64 位 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "NixOS ęØ”å—" + }, + "resources": { + "icon_packs": "å›¾ę ‡åŒ…", + "icon_packs_intro": "ä½æē”Øå›¾ę ‡åŒ…åÆä»„ę‰©å±•ē¬”č®°äø­åÆē”Øēš„å›¾ę ‡é€‰ę‹©ć€‚ęœ‰å…³å›¾ę ‡åŒ…ēš„ę›“å¤šäæ”ęÆļ¼ŒčÆ·å‚é˜…å®˜ę–¹ę–‡ę”£ć€‚", + "download": "äø‹č½½", + "website": "网站", + "title": "资源" + } +} diff --git a/apps/website/src/translations/zh-Hant/translation.json b/apps/website/src/translations/zh-Hant/translation.json new file mode 100644 index 0000000000..4b13a97d10 --- /dev/null +++ b/apps/website/src/translations/zh-Hant/translation.json @@ -0,0 +1,208 @@ +{ + "get-started": { + "title": "開始使用", + "desktop_title": "äø‹č¼‰ę”Œé¢ę‡‰ē”ØēØ‹å¼ (v{{version}})", + "architecture": "ęž¶ę§‹ļ¼š", + "older_releases": "ęŸ„ēœ‹ę­·å²ē‰ˆęœ¬", + "server_title": "čØ­å®šä¼ŗęœå™Øä»„ä¾›å¤šå°č£ē½®å­˜å–" + }, + "hero_section": { + "title": "ę•“ē†ę‚Øēš„ę€ē·’ć€‚å»ŗē«‹ę‚Øēš„å€‹äŗŗēŸ„č­˜åŗ«ć€‚", + "subtitle": "Trilium ę˜Æäø€ę¬¾é–‹ęŗč§£ę±ŗę–¹ę”ˆļ¼Œå°ˆē‚ŗē­†čØ˜čØ˜éŒ„čˆ‡å€‹äŗŗēŸ„č­˜åŗ«ē®”ē†č€Œē”Ÿć€‚ę‚ØåÆéøę“‡åœØę”Œé¢ē«Æęœ¬åœ°ä½æē”Øļ¼Œęˆ–čˆ‡č‡Ŗęž¶ä¼ŗęœå™ØåŒę­„ļ¼Œč®“ē­†čØ˜éšØč”Œē„”é˜»ć€‚", + "get_started": "開始使用", + "github": "GitHub", + "dockerhub": "Docker Hub", + "screenshot_alt": "Trilium Notes ę”Œé¢ę‡‰ē”ØēØ‹å¼ēš„čž¢å¹•ęˆŖåœ–" + }, + "organization_benefits": { + "title": "組織", + "note_structure_title": "ē­†čØ˜ēµę§‹", + "note_structure_description": "ē­†čØ˜åÆä¾å±¤ē“šęŽ’åˆ—ć€‚ē”±ę–¼ęÆå‰‡ē­†čØ˜ēš†åÆåŒ…å«å­ē­†čØ˜ļ¼Œę•…ē„”éœ€ä½æē”Øč³‡ę–™å¤¾ć€‚å–®äø€ē­†čØ˜åÆåœØå±¤ē“šēµę§‹äø­ēš„å¤šå€‹ä½ē½®ę·»åŠ ć€‚", + "attributes_title": "ē­†čØ˜ęØ™ē±¤åŠé—œčÆ", + "attributes_description": "é‹ē”Øē­†čØ˜é–“ēš„é—œčÆęˆ–ę·»åŠ ęØ™ē±¤ä»„åˆ©åˆ†é”žć€‚ä½æē”Øęå‡å±¬ę€§č¼øå…„ēµę§‹åŒ–č³‡čØŠļ¼Œę­¤é”žč³‡čØŠåÆē”Øę–¼č”Øę ¼čˆ‡ēœ‹ęæäø­ć€‚", + "hoisting_title": "å·„ä½œå€åŠčšē„¦", + "hoisting_description": "č¼•é¬†å°‡å€‹äŗŗē­†čØ˜čˆ‡å·„ä½œē­†čØ˜åˆ†é–‹ē®”ē†ļ¼ŒåŖéœ€å°‡å®ƒå€‘ę­øé”žč‡³ē‰¹å®šå·„ä½œå€ļ¼Œč©²å·„ä½œå€ęœƒčšē„¦é”Æē¤ŗē­†čØ˜ęØ¹äø­ēš„ē‰¹å®šē­†čØ˜ē¾¤ēµ„ć€‚" + }, + "productivity_benefits": { + "title": "ē”Ÿē”¢åŠ›åŠå®‰å…Øę€§", + "revisions_title": "ē­†čØ˜ę­·å²ē‰ˆęœ¬", + "revisions_content": "ē­†čØ˜ęœƒå®šęœŸåœØčƒŒę™Æč‡Ŗå‹•å„²å­˜ļ¼Œę‚ØåÆé€éŽē‰ˆęœ¬čØ˜éŒ„åŠŸčƒ½ęŖ¢č¦–äæ®ę”¹ę­·ēØ‹ęˆ–ę’¤éŠ·ę„å¤–č®Šę›“ć€‚ē‰ˆęœ¬čØ˜éŒ„äŗ¦åÆä¾éœ€ę±‚ę‰‹å‹•å»ŗē«‹ć€‚", + "sync_title": "同歄", + "sync_content": "ä½æē”Øč‡ŖčØ—ē®”ęˆ–é›²ē«ÆåÆ¦ä¾‹ļ¼Œč¼•é¬†åœØå¤šå°č£ē½®é–“åŒę­„ē­†čØ˜ļ¼Œäø¦é€éŽ PWA å¾žę‰‹ę©Ÿå­˜å–ć€‚", + "protected_notes_title": "å—äæč­·ēš„ē­†čØ˜", + "protected_notes_content": "é€éŽåŠ åÆ†ē­†čØ˜äø¦å°‡å…¶éŽ–å®šåœØåÆ†ē¢¼äæč­·ēš„å·„ä½œéšŽę®µäø­ļ¼Œä»„äæč­·ę•ę„Ÿēš„å€‹äŗŗč³‡čØŠć€‚", + "jump_to_title": "åæ«é€Ÿęœå°‹åŠå‘½ä»¤", + "jump_to_content": "é€éŽęœå°‹ęØ™é”Œåæ«é€Ÿč·³č½‰č‡³å„å±¤ē“šēš„ē­†čØ˜ęˆ–ä»‹é¢ęŒ‡ä»¤ļ¼Œäø¦ę”Æę“ęØ”ē³ŠåŒ¹é…ä»„å®¹čØ±ę‹¼åÆ«éŒÆčŖ¤ęˆ–ē“°å¾®å·®ē•°ć€‚", + "search_title": "å¼·å¤§ēš„ęœå°‹åŠŸčƒ½", + "search_content": "ęˆ–åœØē­†čØ˜å…§ęœå°‹ę–‡å­—ļ¼Œäø¦é€éŽēÆ©éøēˆ¶ē­†čØ˜ęˆ–å±¤ē“šę·±åŗ¦ä¾†ēø®å°ęœå°‹ēÆ„åœć€‚", + "web_clipper_title": "ē¶²é å‰Ŗå–å™Ø", + "web_clipper_content": "ä½æē”Øē¶²é å‰Ŗå–å™Øē€č¦½å™Øę““å……åŠŸčƒ½ļ¼Œē›“ęŽ„ę“·å–ē¶²é ļ¼ˆęˆ–ęˆŖåœ–ļ¼‰äø¦å°‡å…¶ē½®å…„ Trilium怂" + }, + "note_types": { + "text_title": "ę–‡å­—ē­†čØ˜", + "text_description": "ē­†čØ˜ęŽ”ē”Øę‰€č¦‹å³ę‰€å¾—ļ¼ˆWYSIWYGļ¼‰ē·Øč¼Æå™Øé€²č”Œē·Øč¼Æļ¼Œę”Æę“č”Øę ¼ć€åœ–ē‰‡ć€ę•øå­øå…¬å¼åŠåø¶ęœ‰čŖžę³•é«˜äŗ®ēš„ēØ‹å¼ē¢¼å€å”Šć€‚ę‚ØåÆé€éŽé”ž Markdown čŖžę³•ęˆ–ę–œē·šęŒ‡ä»¤åæ«é€Ÿę ¼å¼åŒ–ę–‡å­—ć€‚", + "code_title": "ēØ‹å¼ē¢¼ē­†čØ˜", + "code_description": "å¤§åž‹åŽŸå§‹ē¢¼ęˆ–č…³ęœ¬ęØ£ęœ¬ęŽ”ē”Øå°ˆē”Øē·Øč¼Æå™Øļ¼Œę”Æę“å¤šēØ®ēØ‹å¼čŖžčØ€ēš„čŖžę³•é«˜äŗ®é”Æē¤ŗļ¼Œäø¦ęä¾›å¤šēØ®č‰²å½©äø»é”Œć€‚", + "file_title": "ęŖ”ę”ˆē­†čØ˜", + "file_description": "åµŒå…„å¤šåŖ’é«”ęŖ”ę”ˆļ¼ˆä¾‹å¦‚ PDFć€åœ–ē‰‡ć€å½±ē‰‡ļ¼‰ļ¼Œäø¦ęä¾›ę‡‰ē”ØēØ‹å¼å…§é č¦½åŠŸčƒ½ć€‚", + "canvas_title": "ē•«åøƒ", + "canvas_description": "åœØē„”é™ē•«åøƒäøŠęŽ’åˆ—åœ–å½¢ć€åœ–åƒčˆ‡ę–‡å­—ļ¼ŒęŽ”ē”Øčˆ‡ excalidraw.com ē›øåŒēš„ęŠ€č”“ć€‚é©ē”Øę–¼ē¹Ŗč£½åœ–č”Øć€č‰åœ–čˆ‡č¦–č¦ŗåŒ–č¦åŠƒć€‚", + "mermaid_title": "ē¾Žäŗŗé­šåœ–", + "mermaid_description": "使用 Mermaid čŖžę³•ē¹Ŗč£½ęµēØ‹åœ–ć€é”žåˆ„åœ–čˆ‡åŗåˆ—åœ–ć€ē”˜ē‰¹åœ–ē­‰å¤šēØ®åœ–č”Øć€‚", + "mindmap_title": "åæƒę™ŗåœ–", + "mindmap_description": "ä»„č¦–č¦ŗę–¹å¼ę•“ē†ę€ē·’ļ¼Œęˆ–é€²č”Œč…¦åŠ›ęæ€ē›Ŗć€‚", + "others_list": "åŠå…¶ä»–é …ē›®ļ¼š<0>ē­†čØ˜åœ°åœ–ć€<1>é—œčÆåœ°åœ–ć€<2>å„²å­˜ęœå°‹ć€<3>ęø²ęŸ“ē­†čØ˜ļ¼Œä»„åŠ<4>網頁檢視。", + "title": "å¤šēØ®ę–¹å¼å‘ˆē¾ę‚Øēš„č³‡čØŠ" + }, + "extensibility_benefits": { + "title": "åˆ†äŗ«åŠę““å±•ę€§", + "import_export_title": "åŒÆå…„/åŒÆå‡ŗ", + "import_export_description": "č¼•é¬†é€éŽ Markdown态ENEX态OML ę ¼å¼čˆ‡å…¶ä»–ę‡‰ē”ØēØ‹å¼äŗ’å‹•ć€‚", + "share_title": "åœØē¶²é äøŠåˆ†äŗ«ē­†čØ˜", + "share_description": "č‹„ę‚Øę“ęœ‰ä¼ŗęœå™Øļ¼Œä¾æåÆč—‰ę­¤čˆ‡ä»–äŗŗå…±äŗ«ē­†čØ˜ēš„å­é›†ć€‚", + "scripting_title": "é€²éšŽč…³ęœ¬ē·ØåÆ«", + "scripting_description": "在 Trilium äø­é€éŽč‡ŖčØ‚å°å·„å…·ęˆ–ä¼ŗęœå™Øē«Æé‚č¼Æļ¼Œę‰“é€ å°ˆå±¬ę•“åˆę–¹ę”ˆć€‚", + "api_title": "REST API", + "api_description": "é€éŽå…¶å…§å»ŗēš„ REST API ä»„ēØ‹å¼åŒ–ę–¹å¼čˆ‡ Trilium é€²č”Œäŗ’å‹•ć€‚" + }, + "collections": { + "calendar_title": "ꗄꛆ", + "calendar_description": "ä½æē”Øč”Œäŗ‹ę›†č¦åŠƒå€‹äŗŗęˆ–å°ˆę„­ę“»å‹•ļ¼Œę”Æę“å…Øå¤©åŠå¤šę—„ę“»å‹•ć€‚é€éŽé€±ć€ęœˆć€å¹“ęŖ¢č¦–ęØ”å¼ļ¼Œäø€č¦½ę‰€ęœ‰ę“»å‹•ć€‚é€šéŽē°”å–®äŗ’å‹•å³åÆę–°å¢žęˆ–ę‹–ę›³ę“»å‹•ć€‚", + "table_title": "蔨格", + "table_description": "ä»„č”Øę ¼ēµę§‹é”Æē¤ŗäø¦ē·Øč¼Æē­†čØ˜č³‡čØŠļ¼Œę”Æę“å¤šēØ®ę¬„ä½é”žåž‹ļ¼ŒåŒ…ę‹¬ę–‡å­—ć€ę•øå­—ć€ę øå–ę–¹å”Šć€ę—„ęœŸčˆ‡ę™‚é–“ć€é€£ēµåŠé”č‰²ļ¼Œäø¦ę”Æę“é—œčÆåŠŸčƒ½ć€‚åÆéøę“‡ę€§åœ°åœØč”Øę ¼å…§ä»„ęØ¹ē‹€å±¤ē“šēµę§‹é”Æē¤ŗē­†čØ˜å…§å®¹ć€‚", + "board_title": "ēœ‹ęæ", + "board_description": "å°‡ę‚Øēš„ä»»å‹™ęˆ–å°ˆę”ˆē‹€ę…‹ę•“ē†ęˆēœ‹ęæļ¼Œč¼•é¬†å»ŗē«‹ę–°é …ē›®čˆ‡ę¬„ä½ļ¼Œäø¦é€éŽåœØēœ‹ęæäøŠę‹–ę›³å³åÆē°”å–®č®Šę›“ē‹€ę…‹ć€‚", + "geomap_title": "åœ°ē†åœ°åœ–", + "geomap_description": "ä½æē”ØåÆč‡ŖčØ‚ēš„ęØ™čØ˜ļ¼Œē›“ęŽ„åœØåœ°åœ–äøŠč¦åŠƒę‚Øēš„å‡ęœŸč”ŒēØ‹ęˆ–ęØ™čØ˜ę„Ÿčˆˆč¶£ēš„åœ°é»žć€‚é”Æē¤ŗå·²čØ˜éŒ„ēš„GPXč»Œč·”ļ¼Œä»„ä¾æčæ½č¹¤č”ŒēØ‹č·Æē·šć€‚", + "title": "集合", + "presentation_title": "簔報", + "presentation_description": "å°‡č³‡čØŠę•“ē†ęˆęŠ•å½±ē‰‡ļ¼Œäø¦ä»„å…Øčž¢å¹•ęØ”å¼åŠęµęš¢ēš„č½‰å “ę•ˆęžœå‘ˆē¾ć€‚ęŠ•å½±ē‰‡äŗ¦åÆåŒÆå‡ŗē‚ŗ PDF ę ¼å¼ļ¼Œę–¹ä¾æåˆ†äŗ«ć€‚" + }, + "faq": { + "title": "åøøč¦‹å•é”Œ", + "mobile_question": "ę˜Æå¦ęœ‰č”Œå‹•ę‡‰ē”ØēØ‹å¼ļ¼Ÿ", + "mobile_answer": "ē›®å‰å°šē„”å®˜ę–¹č”Œå‹•ę‡‰ē”ØēØ‹å¼ć€‚äøéŽļ¼Œč‹„ę‚Øę“ęœ‰ä¼ŗęœå™ØåÆ¦ä¾‹ļ¼ŒåÆé€éŽē¶²é ē€č¦½å™Øå­˜å–ļ¼Œē”šč‡³čƒ½å°‡å…¶å®‰č£ē‚ŗé€²ēØ‹å¼ē¶²č·Æę‡‰ē”ØēØ‹å¼ļ¼ˆPWA)。至於 Androidē³»ēµ±ļ¼Œå‰‡ęœ‰ę¬¾åē‚ŗ TriliumDroid ēš„éžå®˜ę–¹ę‡‰ē”ØēØ‹å¼ļ¼Œå…¶åŠŸčƒ½čˆ‡ę”Œé¢ē«Æå®¢ęˆ¶ē«Æē›øåŒļ¼Œē”šč‡³ę”Æę“é›¢ē·šé‹ä½œć€‚", + "database_question": "č³‡ę–™å„²å­˜åœØå“Ŗč£”ļ¼Ÿ", + "database_answer": "ę‰€ęœ‰ē­†čØ˜éƒ½å°‡å„²å­˜ę–¼ę‡‰ē”ØēØ‹å¼č³‡ę–™å¤¾å…§ēš„ SQLite 資料庫中。Trilium ęŽ”ē”Øč³‡ę–™åŗ«č€Œéžē“”ę–‡å­—ęŖ”ę”ˆēš„č€ƒé‡ļ¼ŒåœØę–¼ę•ˆčƒ½č”Øē¾ļ¼Œä»„åŠęŸäŗ›åŠŸčƒ½ļ¼ˆä¾‹å¦‚č¤‡č£½ē­†čØ˜ā€”ā€”åœØęØ¹ē‹€ēµę§‹äø­å¤šč™•å‡ŗē¾ē›øåŒē­†čØ˜ļ¼‰č‹„ä»„ē“”ę–‡å­—ęŖ”ę”ˆåÆ¦ē¾å°‡å›°é›£å¾—å¤šć€‚č‹„éœ€å°‹ę‰¾ę‡‰ē”ØēØ‹å¼č³‡ę–™å¤¾ä½ē½®ļ¼Œč«‹ē›“ęŽ„é–‹å•Ÿć€Œé—œę–¼ć€č¦–ēŖ—å³åÆć€‚", + "server_question": "使用 Trilium ę˜Æå¦éœ€č¦ä¼ŗęœå™Øļ¼Ÿ", + "server_answer": "äøļ¼Œä¼ŗęœå™Øå…čØ±é€éŽē¶²é ē€č¦½å™Øå­˜å–ļ¼Œäø¦åœØę‚Øę“ęœ‰å¤šå°č£ē½®ę™‚ē®”ē†åŒę­„ä½œę„­ć€‚č‹„ē„”å¤šå°č£ē½®åŒę­„éœ€ę±‚ļ¼ŒåŖéœ€äø‹č¼‰ę”Œé¢ę‡‰ē”ØēØ‹å¼äø¦å•Ÿå‹•å³åÆć€‚", + "scaling_question": "ę‡‰ē”ØēØ‹å¼åœØē­†čØ˜ę•øé‡é¾å¤§ę™‚č”Øē¾å¦‚ä½•ļ¼Ÿ", + "scaling_answer": "ę ¹ę“šä½æē”Øęƒ…å¢ƒļ¼Œęœ¬ę‡‰ē”ØēØ‹å¼ę‡‰čƒ½ē„”éšœē¤™č™•ē†č‡³å°‘åč¬ē­†ē­†čØ˜ć€‚č«‹ę³Øę„ļ¼Œč‹„äøŠå‚³å¤§é‡å¤§åž‹ęŖ”ę”ˆļ¼ˆå–®äø€ęŖ”ę”ˆé” 1 GBļ¼‰ļ¼ŒåŒę­„éŽēØ‹åÆčƒ½ē™¼ē”Ÿå¤±ę•—ļ¼Œå›  Trilium ęœ¬č³ŖäøŠę›“åå‘ēŸ„č­˜åŗ«ę‡‰ē”ØēØ‹å¼ļ¼Œč€ŒéžęŖ”ę”ˆå„²å­˜ęœå‹™ļ¼ˆä¾‹å¦‚ NextCloud)。", + "network_share_question": "ęˆ‘čƒ½å¦é€éŽē¶²č·Æē£ē¢Ÿę©Ÿå…±äŗ«ęˆ‘ēš„č³‡ę–™åŗ«ļ¼Ÿ", + "network_share_answer": "äøļ¼Œé€šåøøäøå»ŗč­°é€éŽē¶²č·Æē£ē¢Ÿę©Ÿå…±äŗ« SQLite č³‡ę–™åŗ«ć€‚é›–ē„¶ęœ‰ę™‚åÆčƒ½é‹ä½œę­£åøøļ¼Œä½†ē”±ę–¼ē¶²č·Æē’°å¢ƒäø­ęŖ”ę”ˆéŽ–å®šę©Ÿåˆ¶äøå®Œå–„ļ¼Œč³‡ę–™åŗ«ä»å­˜åœØęęÆ€ēš„é¢ØéšŖć€‚", + "security_question": "ęˆ‘ēš„č³‡ę–™å¦‚ä½•å—åˆ°äæč­·ļ¼Ÿ", + "security_answer": "é čØ­ęƒ…ę³äø‹ļ¼Œē­†čØ˜äøęœƒé€²č”ŒåŠ åÆ†ļ¼ŒåÆē›“ęŽ„å¾žč³‡ę–™åŗ«č®€å–ć€‚äø€ę—¦å°‡ē­†čØ˜ęØ™čØ˜ē‚ŗåŠ åÆ†ē‹€ę…‹ļ¼Œē³»ēµ±ä¾æęœƒä½æē”Ø AES-128-CBC ę¼”ē®—ę³•å°č©²ē­†čØ˜é€²č”ŒåŠ åÆ†ć€‚" + }, + "final_cta": { + "title": "準備儽開始使用 Trilium Notes äŗ†å—Žļ¼Ÿ", + "description": "é‹ē”Øå¼·å¤§åŠŸčƒ½čˆ‡å®Œę•“éš±ē§äæč­·ļ¼Œå»ŗē«‹ę‚Øēš„å€‹äŗŗēŸ„č­˜åŗ«ć€‚", + "get_started": "開始使用" + }, + "components": { + "link_learn_more": "äŗ†č§£ę›“å¤šā€¦" + }, + "download_now": { + "text": "é¦¬äøŠäø‹č¼‰ ", + "platform_big": "v{{version}} 適用於 {{platform}}", + "platform_small": "適用於 {{platform}}", + "linux_big": "v{{version}} 適用於 Linux", + "linux_small": "適用於 Linux", + "more_platforms": "ę›“å¤šå¹³å°čˆ‡ä¼ŗęœå™ØčØ­å®š" + }, + "footer": { + "copyright_and_the": " 仄及 ", + "copyright_community": "社群" + }, + "social_buttons": { + "github": "GitHub", + "github_discussions": "GitHub čØŽč«–", + "matrix": "Matrix", + "reddit": "Reddit" + }, + "support_us": { + "title": "ę”ÆęŒęˆ‘å€‘", + "financial_donations_title": "č²”å‹™ęč“ˆ", + "financial_donations_description": "Trilium ēš„é–‹ē™¼čˆ‡ē¶­č­·č€—č²»äŗ† ę•øē™¾å°ę™‚ēš„å·„ä½œć€‚ę‚Øēš„ę”ÆęŒčƒ½ē¢ŗäæå…¶é–‹ęŗę€§č³Ŗć€ęå‡åŠŸčƒ½å“č³Ŗļ¼Œäø¦ę”Æä»˜ä¼ŗęœå™ØčØ—ē®”ē­‰ē›øé—œęˆęœ¬ć€‚", + "financial_donations_cta": "č«‹č€ƒę…®é€éŽä»„äø‹ę–¹å¼ę”ÆęŒęœ¬ę‡‰ē”ØēØ‹å¼ēš„äø»č¦é–‹ē™¼č€…ļ¼ˆeliandoranļ¼‰ļ¼š", + "github_sponsors": "GitHub Sponsors", + "paypal": "PayPal", + "buy_me_a_coffee": "Buy Me A Coffee" + }, + "contribute": { + "title": "å…¶ä»–č²¢ē»ę–¹å¼", + "way_translate": "透過 Weblate å°‡ę‡‰ē”ØēØ‹å¼ēæ»č­Æęˆę‚Øēš„ęÆčŖžć€‚", + "way_community": "在 GitHub Discussions ꈖ Matrix äøŠčˆ‡ē¤¾ē¾¤äŗ’å‹•ć€‚", + "way_reports": "透過 GitHub issues å›žå ±éŒÆčŖ¤ć€‚", + "way_document": "å‘ŠčØ“ęˆ‘å€‘ę–‡ä»¶äø­ēš„ē¼ŗę¼ä¹‹č™•ļ¼Œęˆ–č²¢ē»ęŒ‡å—ć€åøøč¦‹å•é”Œč§£ē­”ęˆ–ę•™å­øå…§å®¹ļ¼Œå”åŠ©å®Œå–„ę–‡ä»¶ć€‚", + "way_market": "å»£ē‚ŗå®£å‚³ļ¼šå°‡ Trilium Notes åˆ†äŗ«ēµ¦ęœ‹å‹ļ¼Œęˆ–ē™¼ä½ˆę–¼éƒØč½ę ¼čˆ‡ē¤¾ē¾¤åŖ’é«”ć€‚" + }, + "404": { + "title": "404ļ¼šę‰¾äøåˆ°ę­¤é é¢", + "description": "ę‚Øę‰€å°‹ę‰¾ēš„é é¢ē„”ę³•ę‰¾åˆ°ć€‚åÆčƒ½ę˜Æč©²é é¢å·²č¢«åˆŖé™¤ļ¼Œęˆ–ę˜Æē¶²å€ęœ‰čŖ¤ć€‚" + }, + "download_helper_desktop_windows": { + "title_x64": "Windows 64 位元", + "title_arm64": "Windows on ARM", + "description_x64": "ē›øå®¹ę–¼é‹č”Œ Windows 10 及 11 ēš„ Intel ꈖ AMD č£ē½®ć€‚", + "description_arm64": "相容於 ARM č£ē½®ļ¼ˆä¾‹å¦‚ę­č¼‰é«˜é€šé©é¾č™•ē†å™Øēš„č£ē½®ļ¼‰ć€‚", + "quick_start": "透過 Winget å®‰č£ļ¼š", + "download_exe": "äø‹č¼‰å®‰č£ēØ‹å¼ (.exe)", + "download_zip": "å…å®‰č£ē‰ˆ (.zip)", + "download_scoop": "Scoop" + }, + "download_helper_desktop_linux": { + "title_x64": "Linux 64 位元", + "title_arm64": "Linux on ARM", + "description_x64": "é©ē”Øę–¼å¤§å¤šę•ø Linux ē™¼č”Œē‰ˆļ¼Œē›øå®¹ę–¼ x86_64 Ꞷ꧋怂", + "description_arm64": "é©ē”Øę–¼åŸŗę–¼ ARM ęž¶ę§‹ēš„ Linux ē™¼č”Œē‰ˆļ¼Œē›øå®¹ę–¼ aarch64 Ꞷ꧋怂", + "quick_start": "č«‹ę ¹ę“šę‚Øēš„ē™¼č”Œē‰ˆéøę“‡é©ē•¶ēš„å„—ä»¶ę ¼å¼ļ¼š", + "download_deb": ".deb", + "download_rpm": ".rpm", + "download_flatpak": ".flatpak", + "download_zip": "å…å®‰č£ē‰ˆ (.zip)", + "download_nixpkgs": "nixpkgs", + "download_aur": "AUR" + }, + "download_helper_desktop_macos": { + "title_x64": "macOS 適用於 Intel", + "title_arm64": "macOS 適用於 Apple Silicon", + "description_x64": "適用於搭載 Intel č™•ē†å™Øēš„ Macļ¼Œäø¦é‹č”Œ macOS Monterey ęˆ–ę›“ę–°ē‰ˆęœ¬ć€‚", + "description_arm64": "適用於搭載 Apple Silicon ēš„ Macļ¼Œä¾‹å¦‚é…å‚™ M1 和 M2 ę™¶ē‰‡ēš„ę©Ÿåž‹ć€‚", + "quick_start": "透過 Homebrew å®‰č£ļ¼š", + "download_dmg": "äø‹č¼‰å®‰č£ēØ‹å¼ (.dmg)", + "download_homebrew_cask": "Homebrew Cask", + "download_zip": "å…å®‰č£ē‰ˆ (.zip)" + }, + "download_helper_server_docker": { + "title": "使用 Docker č‡Ŗč”ŒčØ—ē®”", + "description": "č¼•é¬†é€éŽ Docker å®¹å™ØåœØ Windows态Linux ꈖ macOS äøŠéƒØē½²ć€‚", + "download_dockerhub": "Docker Hub", + "download_ghcr": "ghcr.io" + }, + "download_helper_server_linux": { + "title": "在 Linux äøŠč‡Ŗč”Œęž¶čØ­", + "description": "åœØę‚Øč‡Ŗå·±ēš„ä¼ŗęœå™Øęˆ–č™›ę“¬äø»ę©ŸäøŠéƒØē½² Trilium Notesļ¼Œē›øå®¹ę–¼å¤§å¤šę•øē™¼č”Œē‰ˆć€‚", + "download_tar_x64": "x64 (.tar.xz)", + "download_tar_arm64": "ARM (.tar.xz)", + "download_nixos": "NixOS 樔組" + }, + "download_helper_server_hosted": { + "title": "ä»˜č²»čØ—ē®”", + "description": "Trilium Notes 託箔於 PikaPodsļ¼Œę­¤ē‚ŗä»˜č²»ęœå‹™ļ¼Œęä¾›ä¾æę·å­˜å–čˆ‡ē®”ē†åŠŸčƒ½ć€‚čˆ‡ Trilium åœ˜éšŠē„”ē›“ęŽ„é—œčÆć€‚", + "download_pikapod": "在 PikaPods 上設定", + "download_triliumcc": "ęˆ–åƒč¦‹ trilium.cc" + }, + "header": { + "get-started": "開始使用", + "documentation": "ꖇ件", + "support-us": "ę”ÆęŒęˆ‘å€‘", + "resources": "資源" + }, + "resources": { + "title": "資源", + "icon_packs": "åœ–ē¤ŗåŒ…", + "icon_packs_intro": "ä½æē”Øåœ–ē¤ŗåŒ…ä»„ę““å……ē­†čØ˜ēš„åÆē”Øåœ–ē¤ŗéøę“‡ć€‚ęœ‰é—œåœ–ē¤ŗåŒ…ēš„č©³ē“°č³‡čØŠļ¼Œč«‹åƒé–±å®˜ę–¹ę–‡ä»¶ć€‚", + "download": "下載", + "website": "網站" + } +} diff --git a/apps/website/src/types.d.ts b/apps/website/src/types.d.ts new file mode 100644 index 0000000000..c779c89c7e --- /dev/null +++ b/apps/website/src/types.d.ts @@ -0,0 +1 @@ +/// diff --git a/apps/website/static/favicon.png b/apps/website/static/favicon.png deleted file mode 120000 index 17ded225a6..0000000000 --- a/apps/website/static/favicon.png +++ /dev/null @@ -1 +0,0 @@ -../../../apps/client/src/assets/icon.png \ No newline at end of file diff --git a/apps/website/static/note-types/canvas.png b/apps/website/static/note-types/canvas.png deleted file mode 100644 index ad5c74b363..0000000000 Binary files a/apps/website/static/note-types/canvas.png and /dev/null differ diff --git a/apps/website/static/note-types/geo-map.png b/apps/website/static/note-types/geo-map.png deleted file mode 100644 index cd891b6465..0000000000 Binary files a/apps/website/static/note-types/geo-map.png and /dev/null differ diff --git a/apps/website/static/note-types/mermaid.png b/apps/website/static/note-types/mermaid.png deleted file mode 100644 index 1e8bd73866..0000000000 Binary files a/apps/website/static/note-types/mermaid.png and /dev/null differ diff --git a/apps/website/static/note-types/mind-map.png b/apps/website/static/note-types/mind-map.png deleted file mode 100644 index a970d485ff..0000000000 Binary files a/apps/website/static/note-types/mind-map.png and /dev/null differ diff --git a/apps/website/static/screenshots/desktop-win.png b/apps/website/static/screenshots/desktop-win.png deleted file mode 100644 index ab6ee05ec5..0000000000 Binary files a/apps/website/static/screenshots/desktop-win.png and /dev/null differ diff --git a/apps/website/static/screenshots/macos/dark.png b/apps/website/static/screenshots/macos/dark.png deleted file mode 100644 index 2eae66f18a..0000000000 Binary files a/apps/website/static/screenshots/macos/dark.png and /dev/null differ diff --git a/apps/website/static/screenshots/macos/light.png b/apps/website/static/screenshots/macos/light.png deleted file mode 100644 index a2b64b7fba..0000000000 Binary files a/apps/website/static/screenshots/macos/light.png and /dev/null differ diff --git a/apps/website/static/technical-features/grafana-metrics.png b/apps/website/static/technical-features/grafana-metrics.png deleted file mode 120000 index 1dd11db675..0000000000 --- a/apps/website/static/technical-features/grafana-metrics.png +++ /dev/null @@ -1 +0,0 @@ -../../../../docs/User Guide/User Guide/Advanced Usage/1_Metrics_image.png \ No newline at end of file diff --git a/apps/website/svelte.config.js b/apps/website/svelte.config.js deleted file mode 100644 index 0cd57a52d6..0000000000 --- a/apps/website/svelte.config.js +++ /dev/null @@ -1,11 +0,0 @@ -import { mdsvex } from 'mdsvex'; -import adapter from '@sveltejs/adapter-auto'; -import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; - -const config = { - preprocess: [vitePreprocess(), mdsvex()], - kit: { adapter: adapter() }, - extensions: ['.svelte', '.svx'] -}; - -export default config; diff --git a/apps/website/tsconfig.json b/apps/website/tsconfig.json index 5adb685c03..68e45adef8 100644 --- a/apps/website/tsconfig.json +++ b/apps/website/tsconfig.json @@ -1,20 +1,23 @@ { - "extends": "./.svelte-kit/tsconfig.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { - "allowJs": true, - "checkJs": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "sourceMap": true, - "strict": true, + "composite": true, + "target": "ES2020", + "module": "ESNext", "moduleResolution": "bundler", - "composite": true - } - // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias - // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files - // - // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes - // from the referenced tsconfig.json - TypeScript does not merge them in + /* Preact Config */ + "jsx": "react-jsx", + "jsxImportSource": "preact", + "skipLibCheck": true, + "types": [ + "vite/client", + "vitest/config" + ], + "paths": { + "react": ["../../node_modules/preact/compat/"], + "react-dom": ["../../node_modules/preact/compat/"] + } + }, + "include": ["node_modules/vite/client.d.ts", "**/*"], + "exclude": ["dist"] } diff --git a/apps/website/types-assets.d.ts b/apps/website/types-assets.d.ts new file mode 100644 index 0000000000..32e7448399 --- /dev/null +++ b/apps/website/types-assets.d.ts @@ -0,0 +1,9 @@ +declare module "*?raw" { + var content: string; + export default content; +} + +declare module "*.svg" { + var path: string; + export default path; +} diff --git a/apps/website/vite.config.ts b/apps/website/vite.config.ts index 135fc634d5..2c4f5e5ee1 100644 --- a/apps/website/vite.config.ts +++ b/apps/website/vite.config.ts @@ -1,24 +1,25 @@ -import tailwindcss from '@tailwindcss/vite'; -import { paraglideVitePlugin } from '@inlang/paraglide-js'; -import { sveltekit } from '@sveltejs/kit/vite'; -import { defineConfig, type Plugin } from 'vite'; +import { defineConfig } from 'vitest/config'; +import preact from '@preact/preset-vite'; -export default () => { - // See https://github.com/nrwl/nx/issues/28978. - const cwd = process.cwd(); - process.chdir(__dirname); // Temporarily change the working directory - - const config = defineConfig({ - plugins: [ - tailwindcss(), - sveltekit(), - paraglideVitePlugin({ - project: './project.inlang', - outdir: './src/lib/paraglide' - }) - ] as Plugin[] - }); - - process.chdir(cwd); // Restore the original working directory - return config; -}; +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + preact({ + prerender: { + enabled: true, + renderTarget: '#app', + additionalPrerenderRoutes: [ + '/404', + '/get-started', + '/resources', + '/support-us' + ], + previewMiddlewareEnabled: true, + previewMiddlewareFallback: '/404', + }, + }), + ], + test: { + environment: "happy-dom" + } +}); diff --git a/docs/.pages b/docs/.pages new file mode 100644 index 0000000000..7ebf7a9e2a --- /dev/null +++ b/docs/.pages @@ -0,0 +1,7 @@ +# Navigation order for top-level sections +nav: + - index.md + - User Guide + - Developer Guide + - Script API + - Release Notes \ No newline at end of file diff --git a/docs/Developer Guide/!!!meta.json b/docs/Developer Guide/!!!meta.json index 0b94c1dd66..3d865230e9 100644 --- a/docs/Developer Guide/!!!meta.json +++ b/docs/Developer Guide/!!!meta.json @@ -1,6 +1,6 @@ { "formatVersion": 2, - "appVersion": "0.97.1", + "appVersion": "0.101.3", "files": [ { "isClone": false, @@ -14,8 +14,45 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "T2W7WCZrYZBU", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "cxfTSHIUQtt2", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "label:shareAlias", + "value": "promoted,alias=Slug,single,text", + "isInheritable": true, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-code-alt", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "developer-guide", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", + "dataFileName": "Developer Guide.md", "attachments": [], "dirFileName": "Developer Guide", "children": [ @@ -27,24 +64,78 @@ "T2W7WCZrYZBU" ], "title": "Environment Setup", - "notePosition": 50, + "notePosition": 260, "prefix": null, "isExpanded": false, "type": "text", "mime": "text/html", "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "TLXJwBDo8Rdv", + "isInheritable": false, + "position": 10 + }, { "type": "label", "name": "iconClass", "value": "bx bx-cog", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "environment-setup", + "isInheritable": false, + "position": 20 } ], "format": "markdown", "dataFileName": "Environment Setup.md", "attachments": [] }, + { + "isClone": false, + "noteId": "ccIoz7nqgDRK", + "notePath": [ + "jdjRLhLV3TtI", + "ccIoz7nqgDRK" + ], + "title": "Branching strategy", + "notePosition": 270, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "4nwtTJyjNDKd", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-git-merge", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "branching-strategy", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Branching strategy.md", + "attachments": [] + }, { "isClone": false, "noteId": "cxfTSHIUQtt2", @@ -53,7 +144,1166 @@ "cxfTSHIUQtt2" ], "title": "Project Structure", - "notePosition": 190, + "notePosition": 280, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "a0mkxxB4Uvbf", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-component", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "project-structure", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Project Structure.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "MhwWMgxwDTZL", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL" + ], + "title": "Architecture", + "notePosition": 290, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "architecture", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-arch", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Architecture.md", + "attachments": [], + "dirFileName": "Architecture", + "children": [ + { + "isClone": false, + "noteId": "dsMq2EIOMOBU", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "dsMq2EIOMOBU" + ], + "title": "Frontend", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "frontend", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Frontend.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "tsswRlmHEnYW", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "tsswRlmHEnYW" + ], + "title": "Backend", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "backend", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Backend.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "pRZhrVIGCbMu", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu" + ], + "title": "Database", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "database", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-data", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Database.md", + "attachments": [], + "dirFileName": "Database", + "children": [ + { + "isClone": false, + "noteId": "vNMojjUN76jc", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc" + ], + "title": "Database structure", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "tables", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "attachments": [], + "dirFileName": "Database structure", + "children": [ + { + "isClone": false, + "noteId": "e6GnYOXeIWjg", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "e6GnYOXeIWjg" + ], + "title": "attachments", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "DSkl8C325tEC", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "UvXpeSqfYc6d", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "VIcWnKGs0sMh", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "tM3rIZQzlum4", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "attachments", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "attachments.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "ciL84vNBNi9y", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "ciL84vNBNi9y" + ], + "title": "attributes", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "DSkl8C325tEC", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "tM3rIZQzlum4", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "attributes", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "attributes.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "VIcWnKGs0sMh", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "VIcWnKGs0sMh" + ], + "title": "blobs", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "blobs", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "blobs.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "GskLPkgY5n6E", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "GskLPkgY5n6E" + ], + "title": "branches", + "notePosition": 50, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "DSkl8C325tEC", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "h8AsuFjSD4fB", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "tM3rIZQzlum4", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "branches", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "branches.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "ohhExR078MPU", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "ohhExR078MPU" + ], + "title": "entity_changes", + "notePosition": 51, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "entity-changes", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "entity_changes.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "bRqbIg633nCs", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "bRqbIg633nCs" + ], + "title": "etapi_tokens", + "notePosition": 52, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "tM3rIZQzlum4", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "etapi-tokens", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "etapi_tokens.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "DSkl8C325tEC", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "DSkl8C325tEC" + ], + "title": "notes", + "notePosition": 53, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "UvXpeSqfYc6d", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "VIcWnKGs0sMh", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "tM3rIZQzlum4", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "notes", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "notes.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "4oeftEmy77Bt", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "4oeftEmy77Bt" + ], + "title": "options", + "notePosition": 54, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "options", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "options.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "VyFirdgAOoh5", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "VyFirdgAOoh5" + ], + "title": "recent_notes", + "notePosition": 55, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "DSkl8C325tEC", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "recent-notes", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "recent_notes.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "s7ZBiaJVNumK", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "s7ZBiaJVNumK" + ], + "title": "revisions", + "notePosition": 56, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "DSkl8C325tEC", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "UvXpeSqfYc6d", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "VIcWnKGs0sMh", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "revisions", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "revisions.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "6DG1au6rgOTl", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "6DG1au6rgOTl" + ], + "title": "sessions", + "notePosition": 66, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "sessions", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "sessions.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "zWY2LKmas9os", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "pRZhrVIGCbMu", + "vNMojjUN76jc", + "zWY2LKmas9os" + ], + "title": "user_data", + "notePosition": 76, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "user_data.md", + "attachments": [] + } + ] + } + ] + }, + { + "isClone": false, + "noteId": "Wxn82Em8B7U5", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "Wxn82Em8B7U5" + ], + "title": "APIs", + "notePosition": 50, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "api", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "APIs.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "Vk4zD1Iirarg", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "Vk4zD1Iirarg" + ], + "title": "Arhitecture Decision Records", + "notePosition": 60, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "Jg7clqogFOyD", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "adr", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Arhitecture Decision Records.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "RHbKw3xiwk3S", + "notePath": [ + "jdjRLhLV3TtI", + "MhwWMgxwDTZL", + "RHbKw3xiwk3S" + ], + "title": "Security", + "notePosition": 80, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "security", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Security.md", + "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "zdQzavvHDl1k", + "notePath": [ + "jdjRLhLV3TtI", + "zdQzavvHDl1k" + ], + "title": "Documentation", + "notePosition": 300, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "T2W7WCZrYZBU", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "documentation", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-book-open", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Documentation.md", + "attachments": [], + "dirFileName": "Documentation", + "children": [ + { + "isClone": false, + "noteId": "LjqM0VUL1CrU", + "notePath": [ + "jdjRLhLV3TtI", + "zdQzavvHDl1k", + "LjqM0VUL1CrU" + ], + "title": "Documentation references in the application", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "doc-references", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Documentation references in th.md", + "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "a0mkxxB4Uvbf", + "notePath": [ + "jdjRLhLV3TtI", + "a0mkxxB4Uvbf" + ], + "title": "Building", + "notePosition": 310, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "building", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-terminal", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "attachments": [], + "dirFileName": "Building", + "children": [ + { + "isClone": false, + "noteId": "czgXkoEYwclZ", + "notePath": [ + "jdjRLhLV3TtI", + "a0mkxxB4Uvbf", + "czgXkoEYwclZ" + ], + "title": "Running a development build", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "T2W7WCZrYZBU", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "mXFYlhuEr1mZ", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "dev-build", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Running a development build.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "mXFYlhuEr1mZ", + "notePath": [ + "jdjRLhLV3TtI", + "a0mkxxB4Uvbf", + "mXFYlhuEr1mZ" + ], + "title": "Docker", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "docker", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxl-docker", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Docker.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "aGlhNBEA9wwo", + "notePath": [ + "jdjRLhLV3TtI", + "a0mkxxB4Uvbf", + "aGlhNBEA9wwo" + ], + "title": "Build information", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "build-info", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-info-circle", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Build information.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "fI16A7NrT713", + "notePath": [ + "jdjRLhLV3TtI", + "a0mkxxB4Uvbf", + "fI16A7NrT713" + ], + "title": "Live reload (HMR)", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "live-reload", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Live reload (HMR).md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "PXzm2t3sCdsP", + "notePath": [ + "jdjRLhLV3TtI", + "a0mkxxB4Uvbf", + "PXzm2t3sCdsP" + ], + "title": "Build deliveries locally", + "notePosition": 50, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "build-deliveries", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-package", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Build deliveries locally.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "4nwtTJyjNDKd", + "notePath": [ + "jdjRLhLV3TtI", + "a0mkxxB4Uvbf", + "4nwtTJyjNDKd" + ], + "title": "Releasing a new version", + "notePosition": 70, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "ccIoz7nqgDRK", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "zdQzavvHDl1k", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-rocket", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "releasing", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Releasing a new version.md", + "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "qalhAaJoQ7AN", + "notePath": [ + "jdjRLhLV3TtI", + "qalhAaJoQ7AN" + ], + "title": "Dependencies", + "notePosition": 330, "prefix": null, "isExpanded": false, "type": "text", @@ -62,26 +1312,97 @@ { "type": "label", "name": "iconClass", - "value": "bx bx-list-ul", + "value": "bx bxs-component", "isInheritable": false, - "position": 10 + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "dependencies", + "isInheritable": false, + "position": 30 } ], "format": "markdown", - "dataFileName": "Project Structure.md", "attachments": [], - "dirFileName": "Project Structure", + "dirFileName": "Dependencies", "children": [ + { + "isClone": false, + "noteId": "fa6hAJ9Ith3A", + "notePath": [ + "jdjRLhLV3TtI", + "qalhAaJoQ7AN", + "fa6hAJ9Ith3A" + ], + "title": "Per-dependency checks", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "Xfi1ScuBTKJf", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "updating-deps", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Per-dependency checks.md", + "attachments": [], + "dirFileName": "Per-dependency checks", + "children": [ + { + "isClone": false, + "noteId": "Xfi1ScuBTKJf", + "notePath": [ + "jdjRLhLV3TtI", + "qalhAaJoQ7AN", + "fa6hAJ9Ith3A", + "Xfi1ScuBTKJf" + ], + "title": "bettersqlite binaries", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "bettersqlite-binaries", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "bettersqlite binaries.md", + "attachments": [] + } + ] + }, { "isClone": false, "noteId": "Jg7clqogFOyD", "notePath": [ "jdjRLhLV3TtI", - "cxfTSHIUQtt2", + "qalhAaJoQ7AN", "Jg7clqogFOyD" ], "title": "CKEditor", - "notePosition": 10, + "notePosition": 20, "prefix": null, "isExpanded": false, "type": "text", @@ -100,6 +1421,13 @@ "value": "bx bx-package", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "ckeditor", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -112,7 +1440,7 @@ "noteId": "BRhQZHgwaGyw", "notePath": [ "jdjRLhLV3TtI", - "cxfTSHIUQtt2", + "qalhAaJoQ7AN", "Jg7clqogFOyD", "BRhQZHgwaGyw" ], @@ -122,10 +1450,97 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "plugin-migration", + "isInheritable": false, + "position": 20 + } + ], "format": "markdown", "dataFileName": "Plugin migration guide.md", "attachments": [] + }, + { + "isClone": false, + "noteId": "5gBYmUqiupBl", + "notePath": [ + "jdjRLhLV3TtI", + "qalhAaJoQ7AN", + "Jg7clqogFOyD", + "5gBYmUqiupBl" + ], + "title": "Differences from upstream", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "lY19SLxUMj3J", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "fullContentWidth", + "value": "", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "differences-from-upstream", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Differences from upstream.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "lY19SLxUMj3J", + "notePath": [ + "jdjRLhLV3TtI", + "qalhAaJoQ7AN", + "Jg7clqogFOyD", + "lY19SLxUMj3J" + ], + "title": "ckeditor5-math", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "ckeditor5-math", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "ckeditor5-math.md", + "attachments": [ + { + "attachmentId": "UlSZYhYX8Kfj", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "ckeditor5-math_image.png" + } + ] } ] } @@ -133,13 +1548,13 @@ }, { "isClone": false, - "noteId": "YjerxU7Aii8X", + "noteId": "yeqU0zo0ZQ83", "notePath": [ "jdjRLhLV3TtI", - "YjerxU7Aii8X" + "yeqU0zo0ZQ83" ], - "title": "Troubleshooting", - "notePosition": 200, + "title": "Concepts", + "notePosition": 340, "prefix": null, "isExpanded": false, "type": "text", @@ -147,65 +1562,393 @@ "attributes": [ { "type": "label", - "name": "iconClass", - "value": "bx bx-bug", + "name": "shareAlias", + "value": "concepts", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-sitemap", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "sorted", + "value": "", + "isInheritable": false, + "position": 30 } ], "format": "markdown", "attachments": [], - "dirFileName": "Troubleshooting", + "dirFileName": "Concepts", "children": [ { "isClone": false, - "noteId": "g9nFZ6dRz1Cg", + "noteId": "3mz4ZYhi9Cy8", "notePath": [ "jdjRLhLV3TtI", - "YjerxU7Aii8X", - "g9nFZ6dRz1Cg" + "yeqU0zo0ZQ83", + "3mz4ZYhi9Cy8" ], - "title": "better-sqlite3 was compiled against a different Node.js version", + "title": "Backlinks", "notePosition": 10, "prefix": null, "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "backlinks", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-link-alt", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", - "dataFileName": "better-sqlite3 was compiled ag.md", + "dataFileName": "Backlinks.md", "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "wbVIolLKDhe2", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2" - ], - "title": "Development and architecture", - "notePosition": 220, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Development and architecture", - "children": [ + }, + { + "isClone": false, + "noteId": "h8AsuFjSD4fB", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "h8AsuFjSD4fB" + ], + "title": "Branch prefixes", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "branch-prefix", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Branch prefixes.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "6Yms5izbd0GF", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "6Yms5izbd0GF" + ], + "title": "Cache", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-microchip", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "cache", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Cache.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "oqg9OpK8xfcm", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "oqg9OpK8xfcm" + ], + "title": "CI", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "ci", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "attachments": [], + "dirFileName": "CI", + "children": [ + { + "isClone": false, + "noteId": "IxkDdjTogO18", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "oqg9OpK8xfcm", + "IxkDdjTogO18" + ], + "title": "Main", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "PXzm2t3sCdsP", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "main", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Main.md", + "attachments": [ + { + "attachmentId": "c3aGEk60ZR2Q", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Main_image.png" + }, + { + "attachmentId": "q9OGTAguCyWf", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_Main_image.png" + } + ] + } + ] + }, + { + "isClone": false, + "noteId": "tM3rIZQzlum4", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "tM3rIZQzlum4" + ], + "title": "Deleted notes", + "notePosition": 50, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "deleted-notes", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-trash", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Deleted notes.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "oLhKpfi2kGON", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "oLhKpfi2kGON" + ], + "title": "Demo document", + "notePosition": 60, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "demo-document", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-file-archive", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Demo document.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "TiUll0Osoaz6", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "TiUll0Osoaz6" + ], + "title": "Entities", + "notePosition": 70, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "entities", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-note", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Entities.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "UzRirf46Xi46", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "UzRirf46Xi46" + ], + "title": "Hidden notes", + "notePosition": 80, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "hidden-notes", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-low-vision", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Hidden notes.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "m2W35hwSDUeh", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "m2W35hwSDUeh" + ], + "title": "Icons", + "notePosition": 90, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "PXzm2t3sCdsP", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oLhKpfi2kGON", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "icons", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Icons.md", + "attachments": [] + }, { "isClone": false, "noteId": "TLXJwBDo8Rdv", "notePath": [ "jdjRLhLV3TtI", - "wbVIolLKDhe2", + "yeqU0zo0ZQ83", "TLXJwBDo8Rdv" ], "title": "Internationalisation / Translations", - "notePosition": 10, + "notePosition": 100, "prefix": null, "isExpanded": false, "type": "text", @@ -218,12 +1961,26 @@ "isInheritable": false, "position": 10 }, + { + "type": "relation", + "name": "internalLink", + "value": "lXjOyKpUSKgE", + "isInheritable": false, + "position": 20 + }, { "type": "label", "name": "iconClass", "value": "bx bx-globe", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "i18n", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -236,7 +1993,7 @@ "noteId": "ky5zpmxXZhhr", "notePath": [ "jdjRLhLV3TtI", - "wbVIolLKDhe2", + "yeqU0zo0ZQ83", "TLXJwBDo8Rdv", "ky5zpmxXZhhr" ], @@ -246,7 +2003,15 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "guidelines", + "isInheritable": false, + "position": 20 + } + ], "format": "markdown", "dataFileName": "Guidelines.md", "attachments": [] @@ -256,7 +2021,7 @@ "noteId": "VTebBD3jZjdp", "notePath": [ "jdjRLhLV3TtI", - "wbVIolLKDhe2", + "yeqU0zo0ZQ83", "TLXJwBDo8Rdv", "VTebBD3jZjdp" ], @@ -273,6 +2038,13 @@ "value": "ky5zpmxXZhhr", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "i18n-ally", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -284,7 +2056,7 @@ "noteId": "KhDvxPlQQybs", "notePath": [ "jdjRLhLV3TtI", - "wbVIolLKDhe2", + "yeqU0zo0ZQ83", "TLXJwBDo8Rdv", "KhDvxPlQQybs" ], @@ -294,253 +2066,29 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "server-translation", + "isInheritable": false, + "position": 20 + } + ], "format": "markdown", "dataFileName": "Server translations.md", "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "fI16A7NrT713", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "fI16A7NrT713" - ], - "title": "Live reload", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Live reload.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "7BCukQTCm7fv", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "7BCukQTCm7fv" - ], - "title": "Themes", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Themes.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "n9wYW9nUTynV", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "n9wYW9nUTynV" - ], - "title": "Synchronisation", - "notePosition": 40, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Synchronisation", - "children": [ - { - "isClone": false, - "noteId": "wA6tm9xcWWaB", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "n9wYW9nUTynV", - "wA6tm9xcWWaB" - ], - "title": "Content hashing", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Content hashing.md", - "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "aGlhNBEA9wwo", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "aGlhNBEA9wwo" - ], - "title": "Build information", - "notePosition": 50, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "PXzm2t3sCdsP", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Build information.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "vNMojjUN76jc", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc" - ], - "title": "Database", - "notePosition": 60, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Database", - "children": [ - { - "isClone": false, - "noteId": "e6GnYOXeIWjg", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc", - "e6GnYOXeIWjg" - ], - "title": "attachments", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "DSkl8C325tEC", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "UvXpeSqfYc6d", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "VIcWnKGs0sMh", - "isInheritable": false, - "position": 30 - }, - { - "type": "relation", - "name": "internalLink", - "value": "tM3rIZQzlum4", - "isInheritable": false, - "position": 40 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "attachments.md", - "attachments": [] }, { "isClone": false, - "noteId": "ciL84vNBNi9y", + "noteId": "lXjOyKpUSKgE", "notePath": [ "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc", - "ciL84vNBNi9y" + "yeqU0zo0ZQ83", + "TLXJwBDo8Rdv", + "lXjOyKpUSKgE" ], - "title": "attributes", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "r11Bh3uxFGRj", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "DSkl8C325tEC", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "tM3rIZQzlum4", - "isInheritable": false, - "position": 30 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "attributes.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "VIcWnKGs0sMh", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc", - "VIcWnKGs0sMh" - ], - "title": "blobs", + "title": "Adding a new locale", "notePosition": 40, "prefix": null, "isExpanded": false, @@ -549,26 +2097,466 @@ "attributes": [ { "type": "label", - "name": "iconClass", - "value": "bx bx-table", + "name": "shareAlias", + "value": "new-locale", "isInheritable": false, - "position": 10 + "position": 20 } ], "format": "markdown", - "dataFileName": "blobs.md", + "dataFileName": "Adding a new locale.md", "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "Usiyzn9C4WFv", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "Usiyzn9C4WFv" + ], + "title": "Launchers", + "notePosition": 110, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "launchers", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Launchers.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "qjQNyaYXSNWu", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "qjQNyaYXSNWu" + ], + "title": "Note Revisions", + "notePosition": 120, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "revisions", + "isInheritable": false, + "position": 20 }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-history", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Note Revisions.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "7RBJMqVz2EsJ", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "7RBJMqVz2EsJ" + ], + "title": "Note Types", + "notePosition": 130, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "note-types", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "attachments": [], + "dirFileName": "Note Types", + "children": [ { "isClone": false, - "noteId": "GskLPkgY5n6E", + "noteId": "AdNRgGrYeTCy", "notePath": [ "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc", - "GskLPkgY5n6E" + "yeqU0zo0ZQ83", + "7RBJMqVz2EsJ", + "AdNRgGrYeTCy" ], - "title": "branches", + "title": "Adding a new note type", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "new-note-type", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "attachments": [], + "dirFileName": "Adding a new note type", + "children": [ + { + "isClone": false, + "noteId": "UFtOg3sLumZM", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "7RBJMqVz2EsJ", + "AdNRgGrYeTCy", + "UFtOg3sLumZM" + ], + "title": "First steps", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "lgFwLJT72mdf", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oLhKpfi2kGON", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "first-steps", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "First steps.md", + "attachments": [], + "dirFileName": "First steps", + "children": [ + { + "isClone": false, + "noteId": "aSO1wqK7L1ma", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "7RBJMqVz2EsJ", + "AdNRgGrYeTCy", + "UFtOg3sLumZM", + "aSO1wqK7L1ma" + ], + "title": "mind_map.js", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "code", + "mime": "application/javascript;env=frontend", + "attributes": [], + "dataFileName": "mind_map.js", + "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "lgFwLJT72mdf", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "7RBJMqVz2EsJ", + "AdNRgGrYeTCy", + "lgFwLJT72mdf" + ], + "title": "Note type checklist", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "UFtOg3sLumZM", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "OGYpAbrmEXbX", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-list-check", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "checklist", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "Note type checklist.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "PoxUNujeKJ7T", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "7RBJMqVz2EsJ", + "AdNRgGrYeTCy", + "PoxUNujeKJ7T" + ], + "title": "Saving data via spaced update", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "OGYpAbrmEXbX", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "saving-data", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Saving data via spaced update.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "xYVE7qA3EBwb", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "7RBJMqVz2EsJ", + "AdNRgGrYeTCy", + "xYVE7qA3EBwb" + ], + "title": "Loading data", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "PoxUNujeKJ7T", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "loading-data", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Loading data.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "OGYpAbrmEXbX", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "7RBJMqVz2EsJ", + "AdNRgGrYeTCy", + "OGYpAbrmEXbX" + ], + "title": "SVG rendering", + "notePosition": 50, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "svg-rendering", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "SVG rendering.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "Q8hgB8EEen80", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "7RBJMqVz2EsJ", + "AdNRgGrYeTCy", + "Q8hgB8EEen80" + ], + "title": "Copy image reference to the clipboard", + "notePosition": 60, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "copy-image-reference", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Copy image reference to the cl.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "AwWq8bJRl6XD", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "7RBJMqVz2EsJ", + "AdNRgGrYeTCy", + "AwWq8bJRl6XD" + ], + "title": "Export diagram as SVG", + "notePosition": 70, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "OGYpAbrmEXbX", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "export-to-svg", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Export diagram as SVG.md", + "attachments": [] + } + ] + } + ] + }, + { + "isClone": false, + "noteId": "6dC7ha5vjqqS", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "6dC7ha5vjqqS" + ], + "title": "Options", + "notePosition": 140, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "options", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-cog", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Options.md", + "attachments": [], + "dirFileName": "Options", + "children": [ + { + "isClone": false, + "noteId": "NcHcYOEn4ol5", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "6dC7ha5vjqqS", + "NcHcYOEn4ol5" + ], + "title": "Creating a new option", "notePosition": 50, "prefix": null, "isExpanded": false, @@ -576,274 +2564,70 @@ "mime": "text/html", "attributes": [ { - "type": "relation", - "name": "internalLink", - "value": "h8AsuFjSD4fB", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "DSkl8C325tEC", + "type": "label", + "name": "shareAlias", + "value": "new-option", "isInheritable": false, "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "tM3rIZQzlum4", - "isInheritable": false, - "position": 30 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", - "isInheritable": false, - "position": 10 } ], "format": "markdown", - "dataFileName": "branches.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "ohhExR078MPU", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc", - "ohhExR078MPU" - ], - "title": "entity_changes", - "notePosition": 51, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "entity_changes.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "bRqbIg633nCs", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc", - "bRqbIg633nCs" - ], - "title": "etapi_tokens", - "notePosition": 52, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "tM3rIZQzlum4", - "isInheritable": false, - "position": 10 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "etapi_tokens.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "DSkl8C325tEC", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc", - "DSkl8C325tEC" - ], - "title": "notes", - "notePosition": 53, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "VIcWnKGs0sMh", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "UvXpeSqfYc6d", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "tM3rIZQzlum4", - "isInheritable": false, - "position": 30 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "notes.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "4oeftEmy77Bt", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc", - "4oeftEmy77Bt" - ], - "title": "options", - "notePosition": 54, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "options.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "VyFirdgAOoh5", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc", - "VyFirdgAOoh5" - ], - "title": "recent_notes", - "notePosition": 55, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "DSkl8C325tEC", - "isInheritable": false, - "position": 10 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "recent_notes.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "s7ZBiaJVNumK", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "vNMojjUN76jc", - "s7ZBiaJVNumK" - ], - "title": "revisions", - "notePosition": 56, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "DSkl8C325tEC", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "VIcWnKGs0sMh", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "UvXpeSqfYc6d", - "isInheritable": false, - "position": 30 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "revisions.md", + "dataFileName": "Creating a new option.md", "attachments": [] } ] }, + { + "isClone": false, + "noteId": "W0msUwLxm40d", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "W0msUwLxm40d" + ], + "title": "Printing and exporting to PDF", + "notePosition": 150, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "k7RavjuXQt8z", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "printing", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-printer", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "Printing and exporting to PDF.md", + "attachments": [] + }, { "isClone": false, "noteId": "UvXpeSqfYc6d", "notePath": [ "jdjRLhLV3TtI", - "wbVIolLKDhe2", + "yeqU0zo0ZQ83", "UvXpeSqfYc6d" ], "title": "Protected entities", - "notePosition": 80, + "notePosition": 160, "prefix": null, "isExpanded": false, "type": "text", @@ -869,6 +2653,20 @@ "value": "s7ZBiaJVNumK", "isInheritable": false, "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "protected-entities", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-lock-alt", + "isInheritable": false, + "position": 50 } ], "format": "markdown", @@ -877,1218 +2675,83 @@ }, { "isClone": false, - "noteId": "tM3rIZQzlum4", + "noteId": "vphziLmQeQHY", "notePath": [ "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "tM3rIZQzlum4" + "yeqU0zo0ZQ83", + "vphziLmQeQHY" ], - "title": "Deleted notes", - "notePosition": 90, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Deleted notes.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "r11Bh3uxFGRj", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "r11Bh3uxFGRj" - ], - "title": "Special notes", - "notePosition": 100, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Special notes.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "h8AsuFjSD4fB", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "h8AsuFjSD4fB" - ], - "title": "Branch prefixes", - "notePosition": 110, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Branch prefixes.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "qjQNyaYXSNWu", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "qjQNyaYXSNWu" - ], - "title": "Revisions", - "notePosition": 120, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Revisions.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "3mz4ZYhi9Cy8", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "3mz4ZYhi9Cy8" - ], - "title": "Backlinks", - "notePosition": 130, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Backlinks.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "ItZRqNGeGSU0", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "ItZRqNGeGSU0" - ], - "title": "Note types", - "notePosition": 140, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "DSkl8C325tEC", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Note types.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "64ZTlUPgEPtW", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "64ZTlUPgEPtW" - ], - "title": "Safe mode", - "notePosition": 150, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Safe mode.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "m2W35hwSDUeh", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "m2W35hwSDUeh" - ], - "title": "Icons", - "notePosition": 160, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "PXzm2t3sCdsP", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "oLhKpfi2kGON", - "isInheritable": false, - "position": 20 - } - ], - "format": "markdown", - "dataFileName": "Icons.md", - "attachments": [], - "dirFileName": "Icons", - "children": [ - { - "isClone": false, - "noteId": "rUkJPiX0sJSk", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "m2W35hwSDUeh", - "rUkJPiX0sJSk" - ], - "title": "Removed icons", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Removed icons.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "GzrBXey1UTUW", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "m2W35hwSDUeh", - "GzrBXey1UTUW" - ], - "title": "Icons on Mac", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Icons on Mac.md", - "attachments": [ - { - "attachmentId": "gMQM37l1tgDc", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Icons on Mac_image.png" - }, - { - "attachmentId": "KBbeDSs1hueu", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Icons on Mac_image.png" - } - ], - "dirFileName": "Icons on Mac", - "children": [ - { - "isClone": false, - "noteId": "0btkkp7llQdO", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "m2W35hwSDUeh", - "GzrBXey1UTUW", - "0btkkp7llQdO" - ], - "title": "Slightly blurry icon on Mac", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Slightly blurry icon on Mac.md", - "attachments": [ - { - "attachmentId": "6USSTMu15E6N", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Slightly blurry icon on Ma.png" - }, - { - "attachmentId": "KEkBj1bOyfQ5", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Slightly blurry icon on Ma.png" - }, - { - "attachmentId": "XaG2VbiqKYtR", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "2_Slightly blurry icon on Ma.png" - } - ] - }, - { - "isClone": false, - "noteId": "8zAJ5J8SFEp8", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "m2W35hwSDUeh", - "GzrBXey1UTUW", - "8zAJ5J8SFEp8" - ], - "title": "Adaptive icon", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Adaptive icon.md", - "attachments": [ - { - "attachmentId": "38usIA7IJTpY", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Adaptive icon_image.png" - }, - { - "attachmentId": "4eQa9Eqkuekv", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Adaptive icon_image.png" - }, - { - "attachmentId": "gM1I22x3bYDv", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "2_Adaptive icon_image.png" - }, - { - "attachmentId": "Im2xMquSwizu", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "3_Adaptive icon_image.png" - }, - { - "attachmentId": "l2xu0BHxfPfq", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "4_Adaptive icon_image.png" - }, - { - "attachmentId": "wM6YPPsas7tA", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "5_Adaptive icon_image.png" - }, - { - "attachmentId": "zPLIBv0Xvgwm", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "6_Adaptive icon_image.png" - } - ] - } - ] - } - ] - }, - { - "isClone": false, - "noteId": "oLhKpfi2kGON", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "oLhKpfi2kGON" - ], - "title": "Demo document", + "title": "Share", "notePosition": 170, "prefix": null, "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Demo document.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "mXFYlhuEr1mZ", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "mXFYlhuEr1mZ" - ], - "title": "Docker", - "notePosition": 180, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Docker.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "6dC7ha5vjqqS", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "6dC7ha5vjqqS" - ], - "title": "Options", - "notePosition": 190, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Options.md", - "attachments": [], - "dirFileName": "Options", - "children": [ - { - "isClone": false, - "noteId": "Qk5Q0Xty3ITv", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "6dC7ha5vjqqS", - "Qk5Q0Xty3ITv" - ], - "title": "Check box option", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Check box option.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "VnqYvYEuMMvb", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "6dC7ha5vjqqS", - "VnqYvYEuMMvb" - ], - "title": "Trigger UI refresh", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Trigger UI refresh.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "3TbiQZODAp6y", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "6dC7ha5vjqqS", - "3TbiQZODAp6y" - ], - "title": "Displaying the option in settings", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Displaying the option in setti.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "1TVWljchsc0t", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "6dC7ha5vjqqS", - "1TVWljchsc0t" - ], - "title": "Refresh widget with option change", - "notePosition": 40, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Refresh widget with option cha.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "NcHcYOEn4ol5", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "6dC7ha5vjqqS", - "NcHcYOEn4ol5" - ], - "title": "Creating a new option", - "notePosition": 50, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Creating a new option.md", - "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "AdNRgGrYeTCy", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "AdNRgGrYeTCy" - ], - "title": "Adding a new note type", - "notePosition": 210, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Adding a new note type", - "children": [ - { - "isClone": false, - "noteId": "UFtOg3sLumZM", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "AdNRgGrYeTCy", - "UFtOg3sLumZM" - ], - "title": "First steps", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "lgFwLJT72mdf", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "oLhKpfi2kGON", - "isInheritable": false, - "position": 20 - } - ], - "format": "markdown", - "dataFileName": "First steps.md", - "attachments": [], - "dirFileName": "First steps", - "children": [ - { - "isClone": false, - "noteId": "aSO1wqK7L1ma", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "AdNRgGrYeTCy", - "UFtOg3sLumZM", - "aSO1wqK7L1ma" - ], - "title": "mind_map.js", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "code", - "mime": "application/javascript;env=frontend", - "attributes": [], - "dataFileName": "mind_map.js", - "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "lgFwLJT72mdf", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "AdNRgGrYeTCy", - "lgFwLJT72mdf" - ], - "title": "Note type checklist", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "UFtOg3sLumZM", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "OGYpAbrmEXbX", - "isInheritable": false, - "position": 20 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-list-check", - "isInheritable": false, - "position": 40 - } - ], - "format": "markdown", - "dataFileName": "Note type checklist.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "PoxUNujeKJ7T", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "AdNRgGrYeTCy", - "PoxUNujeKJ7T" - ], - "title": "Saving data via spaced update", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "OGYpAbrmEXbX", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Saving data via spaced update.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "xYVE7qA3EBwb", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "AdNRgGrYeTCy", - "xYVE7qA3EBwb" - ], - "title": "Loading data", - "notePosition": 40, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "PoxUNujeKJ7T", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Loading data.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "OGYpAbrmEXbX", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "AdNRgGrYeTCy", - "OGYpAbrmEXbX" - ], - "title": "SVG rendering", - "notePosition": 50, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "SVG rendering.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "Q8hgB8EEen80", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "AdNRgGrYeTCy", - "Q8hgB8EEen80" - ], - "title": "Copy image reference to the clipboard", - "notePosition": 60, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Copy image reference to the cl.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "AwWq8bJRl6XD", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "AdNRgGrYeTCy", - "AwWq8bJRl6XD" - ], - "title": "Export diagram as SVG", - "notePosition": 70, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "OGYpAbrmEXbX", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Export diagram as SVG.md", - "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "W0msUwLxm40d", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "W0msUwLxm40d" - ], - "title": "Printing", - "notePosition": 220, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Printing.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "Usiyzn9C4WFv", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "Usiyzn9C4WFv" - ], - "title": "Launchers", - "notePosition": 230, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Launchers.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "k7RavjuXQt8z", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "k7RavjuXQt8z" - ], - "title": "Syntax highlighting", - "notePosition": 240, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Syntax highlighting.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "UzRirf46Xi46", - "notePath": [ - "jdjRLhLV3TtI", - "wbVIolLKDhe2", - "UzRirf46Xi46" - ], - "title": "Hidden notes", - "notePosition": 250, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Hidden notes.md", - "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "VHhyVRYK43gI", - "notePath": [ - "jdjRLhLV3TtI", - "VHhyVRYK43gI" - ], - "title": "Building and deployment", - "notePosition": 230, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Building and deployment", - "children": [ - { - "isClone": false, - "noteId": "Un4wj2Mak2Ky", - "notePath": [ - "jdjRLhLV3TtI", - "VHhyVRYK43gI", - "Un4wj2Mak2Ky" - ], - "title": "Nix flake", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Nix flake.md", - "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "ibAPHul7Efvr", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr" - ], - "title": "Old documentation", - "notePosition": 260, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Old documentation", - "children": [ - { - "isClone": false, - "noteId": "PXzm2t3sCdsP", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "PXzm2t3sCdsP" - ], - "title": "Build deliveries locally", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Build deliveries locally.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "rLWcPPQi7Eso", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "rLWcPPQi7Eso" - ], - "title": "Releasing a version", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Releasing a version.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "czgXkoEYwclZ", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "czgXkoEYwclZ" - ], - "title": "Running a development build", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Running a development build.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "sUqOpnrQyEC7", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "sUqOpnrQyEC7" - ], - "title": "Building and deployment", - "notePosition": 40, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Building and deployment", - "children": [ - { - "isClone": true, - "noteId": "PXzm2t3sCdsP", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "sUqOpnrQyEC7", - "PXzm2t3sCdsP" - ], - "title": "Build deliveries locally", - "prefix": null, - "dataFileName": "Build deliveries locally.clone.md", - "type": "text", - "format": "markdown", - "isExpanded": false - }, - { - "isClone": false, - "noteId": "zdQzavvHDl1k", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "sUqOpnrQyEC7", - "zdQzavvHDl1k" - ], - "title": "Documentation", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Documentation.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "oqg9OpK8xfcm", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "sUqOpnrQyEC7", - "oqg9OpK8xfcm" - ], - "title": "CI", - "notePosition": 50, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "CI", - "children": [ - { - "isClone": false, - "noteId": "IxkDdjTogO18", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "sUqOpnrQyEC7", - "oqg9OpK8xfcm", - "IxkDdjTogO18" - ], - "title": "Main", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "PXzm2t3sCdsP", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Main.md", - "attachments": [ - { - "attachmentId": "c3aGEk60ZR2Q", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Main_image.png" - }, - { - "attachmentId": "q9OGTAguCyWf", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Main_image.png" - } - ] - } - ] - }, - { - "isClone": true, - "noteId": "rLWcPPQi7Eso", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "sUqOpnrQyEC7", - "rLWcPPQi7Eso" - ], - "title": "Releasing a version", - "prefix": null, - "dataFileName": "Releasing a version.clone.md", - "type": "text", - "format": "markdown", - "isExpanded": false - }, - { - "isClone": true, - "noteId": "czgXkoEYwclZ", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "sUqOpnrQyEC7", - "czgXkoEYwclZ" - ], - "title": "Running a development build", - "prefix": null, - "dataFileName": "Running a development build.clone.md", - "type": "text", - "format": "markdown", - "isExpanded": false - } - ] - }, - { - "isClone": false, - "noteId": "Kqzuchw6MmPm", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "Kqzuchw6MmPm" - ], - "title": "Dependency Management", - "notePosition": 50, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", "attributes": [ { "type": "label", "name": "iconClass", - "value": "bx bx-package", + "value": "bx bx-share-alt", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "share", + "isInheritable": false, + "position": 20 } ], "format": "markdown", - "attachments": [], - "dirFileName": "Dependency Management", - "children": [ - { - "isClone": false, - "noteId": "YH5JPX12BYFk", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "Kqzuchw6MmPm", - "YH5JPX12BYFk" - ], - "title": "Adding a new client library", - "notePosition": 0, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Adding a new client library.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "C5CNXGgti17i", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "Kqzuchw6MmPm", - "C5CNXGgti17i" - ], - "title": "Having a simpler packaging system", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Having a simpler packaging sys.md", - "attachments": [] - } - ] + "dataFileName": "Share.md", + "attachments": [] }, { "isClone": false, - "noteId": "6BWwXzPCph4G", + "noteId": "n9wYW9nUTynV", "notePath": [ "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "6BWwXzPCph4G" + "yeqU0zo0ZQ83", + "n9wYW9nUTynV" ], - "title": "Project maintenance", - "notePosition": 60, + "title": "Synchronisation", + "notePosition": 180, "prefix": null, "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "sync", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-sync", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", + "dataFileName": "Synchronisation.md", "attachments": [], - "dirFileName": "Project maintenance", + "dirFileName": "Synchronisation", "children": [ { "isClone": false, - "noteId": "fa6hAJ9Ith3A", + "noteId": "wA6tm9xcWWaB", "notePath": [ "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "6BWwXzPCph4G", - "fa6hAJ9Ith3A" + "yeqU0zo0ZQ83", + "n9wYW9nUTynV", + "wA6tm9xcWWaB" ], - "title": "Updating dependencies", + "title": "Content hashing", "notePosition": 10, "prefix": null, "isExpanded": false, @@ -2096,768 +2759,360 @@ "mime": "text/html", "attributes": [ { - "type": "relation", - "name": "internalLink", - "value": "Xfi1ScuBTKJf", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Updating dependencies.md", - "attachments": [], - "dirFileName": "Updating dependencies", - "children": [ - { - "isClone": false, - "noteId": "Xfi1ScuBTKJf", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "6BWwXzPCph4G", - "fa6hAJ9Ith3A", - "Xfi1ScuBTKJf" - ], - "title": "bettersqlite binaries", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "PXzm2t3sCdsP", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "bettersqlite binaries.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "v5zBZNLR358v", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "6BWwXzPCph4G", - "fa6hAJ9Ith3A", - "v5zBZNLR358v" - ], - "title": "Node.js, Electron and `better-sqlite3`", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Node.js, Electron and `better-.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "aPQ1fSuoBCTC", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "6BWwXzPCph4G", - "fa6hAJ9Ith3A", - "aPQ1fSuoBCTC" - ], - "title": "Testing compatibility", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Testing compatibility.md", - "attachments": [] - } - ] - } - ] - }, - { - "isClone": false, - "noteId": "re0QTuqiYnVb", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "re0QTuqiYnVb" - ], - "title": "Scripting", - "notePosition": 80, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Scripting", - "children": [ - { - "isClone": false, - "noteId": "gz6zq5rlHqMa", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "re0QTuqiYnVb", - "gz6zq5rlHqMa" - ], - "title": "Widgets", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Widgets.md", - "attachments": [], - "dirFileName": "Widgets", - "children": [ - { - "isClone": false, - "noteId": "M8IppdwVHSjG", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "re0QTuqiYnVb", - "gz6zq5rlHqMa", - "M8IppdwVHSjG" - ], - "title": "Right pane widget", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Right pane widget.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "VqGQnnPGnqAU", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "re0QTuqiYnVb", - "gz6zq5rlHqMa", - "VqGQnnPGnqAU" - ], - "title": "CSS", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "CSS.md", - "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "fZ2IGYFXjkEy", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "re0QTuqiYnVb", - "fZ2IGYFXjkEy" - ], - "title": "Server-side imports", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Server-side imports.md", - "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "Sow7ThJozkzJ", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "Sow7ThJozkzJ" - ], - "title": "Documentation", - "notePosition": 90, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Documentation.md", - "attachments": [ - { - "attachmentId": "2bUrJyt2yfsd", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Documentation_image.png" - } - ], - "dirFileName": "Documentation", - "children": [ - { - "isClone": false, - "noteId": "LjqM0VUL1CrU", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "Sow7ThJozkzJ", - "LjqM0VUL1CrU" - ], - "title": "Documentation references in the application", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Documentation references in th.md", - "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "dtKC3FmoWOrv", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dtKC3FmoWOrv" - ], - "title": "Testing", - "notePosition": 100, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Testing.md", - "attachments": [], - "dirFileName": "Testing", - "children": [ - { - "isClone": false, - "noteId": "C5MUQczZ5R9N", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dtKC3FmoWOrv", - "C5MUQczZ5R9N" - ], - "title": "Integration testing", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Integration testing", - "children": [ - { - "isClone": false, - "noteId": "pH4RsxqifVpK", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dtKC3FmoWOrv", - "C5MUQczZ5R9N", - "pH4RsxqifVpK" - ], - "title": "Setting up authentication", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Setting up authentication.md", - "attachments": [ - { - "attachmentId": "aWFXFuXNon7J", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Setting up authentication_.png" - }, - { - "attachmentId": "JRbtB4byzewo", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Setting up authentication_.png" - } - ] - }, - { - "isClone": false, - "noteId": "bIfKwfCnqpeI", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dtKC3FmoWOrv", - "C5MUQczZ5R9N", - "bIfKwfCnqpeI" - ], - "title": "Test database", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Test database.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "w6gMvKh0UAVT", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dtKC3FmoWOrv", - "C5MUQczZ5R9N", - "w6gMvKh0UAVT" - ], - "title": "Running tests", - "notePosition": 40, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Running tests.md", - "attachments": [] - } - ] - } - ] - }, - { - "isClone": false, - "noteId": "dHfw0XZE515z", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dHfw0XZE515z" - ], - "title": "Sub-projects", - "notePosition": 110, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Sub-projects", - "children": [ - { - "isClone": false, - "noteId": "JkTy2zz8Zbyq", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dHfw0XZE515z", - "JkTy2zz8Zbyq" - ], - "title": "CKEditor", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "CKEditor", - "children": [ - { - "isClone": false, - "noteId": "5yWZVlKPjLCC", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dHfw0XZE515z", - "JkTy2zz8Zbyq", - "5yWZVlKPjLCC" - ], - "title": "Environment setup", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "CaInsmrlZhR6", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Environment setup.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "CaInsmrlZhR6", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dHfw0XZE515z", - "JkTy2zz8Zbyq", - "CaInsmrlZhR6" - ], - "title": "Building the editor", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "5yWZVlKPjLCC", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Building the editor.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "5gBYmUqiupBl", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dHfw0XZE515z", - "JkTy2zz8Zbyq", - "5gBYmUqiupBl" - ], - "title": "Differences from upstream", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "lY19SLxUMj3J", - "isInheritable": false, - "position": 10 - }, - { - "type": "label", - "name": "fullContentWidth", - "value": "", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Differences from upstream.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "Q9FyKVERd1Lb", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dHfw0XZE515z", - "JkTy2zz8Zbyq", - "Q9FyKVERd1Lb" - ], - "title": "Updating to a newer version of CKEditor", - "notePosition": 40, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "5yWZVlKPjLCC", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "CaInsmrlZhR6", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "yAFSS6awVbaZ", - "isInheritable": false, - "position": 30 - } - ], - "format": "markdown", - "dataFileName": "Updating to a newer version of.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "yAFSS6awVbaZ", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dHfw0XZE515z", - "JkTy2zz8Zbyq", - "yAFSS6awVbaZ" - ], - "title": "Versions and external plugins", - "notePosition": 50, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "lY19SLxUMj3J", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Versions and external plugins.md", - "attachments": [] - } - ] - }, - { - "isClone": false, - "noteId": "lY19SLxUMj3J", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dHfw0XZE515z", - "lY19SLxUMj3J" - ], - "title": "ckeditor5-math", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "JkTy2zz8Zbyq", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "UMN2ABrBU5D7", + "type": "label", + "name": "shareAlias", + "value": "content-hashing", "isInheritable": false, "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "CaInsmrlZhR6", - "isInheritable": false, - "position": 30 } ], "format": "markdown", - "dataFileName": "ckeditor5-math.md", - "attachments": [ - { - "attachmentId": "UlSZYhYX8Kfj", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "ckeditor5-math_image.png" - } - ], - "dirFileName": "ckeditor5-math", - "children": [ - { - "isClone": false, - "noteId": "vpbbBaypScLb", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dHfw0XZE515z", - "lY19SLxUMj3J", - "vpbbBaypScLb" - ], - "title": "Updating with upstream", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "UMN2ABrBU5D7", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Updating with upstream.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "UMN2ABrBU5D7", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "dHfw0XZE515z", - "lY19SLxUMj3J", - "UMN2ABrBU5D7" - ], - "title": "Release management & continuous integration", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Release management & continuou.md", - "attachments": [] - } - ] - } - ] - }, - { - "isClone": false, - "noteId": "QRLbiDXNxoWN", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "QRLbiDXNxoWN" - ], - "title": "Troubleshooting", - "notePosition": 120, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Troubleshooting", - "children": [ - { - "isClone": false, - "noteId": "QUb0fRhbpT8E", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "QRLbiDXNxoWN", - "QUb0fRhbpT8E" - ], - "title": "Error [TransformError]: The package \"@esbuild/linux-x64\" could not be found, and is needed by esbuild.", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Error [TransformError] The pac.md", + "dataFileName": "Content hashing.md", "attachments": [] } ] }, { "isClone": false, - "noteId": "x6lgrdztQwVB", + "noteId": "k7RavjuXQt8z", "notePath": [ "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "x6lgrdztQwVB" + "yeqU0zo0ZQ83", + "k7RavjuXQt8z" ], - "title": "Installation", - "notePosition": 130, + "title": "Syntax highlighting", + "notePosition": 190, "prefix": null, "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], - "format": "markdown", - "attachments": [], - "dirFileName": "Installation", - "children": [ + "attributes": [ { - "isClone": false, - "noteId": "bOjeTrUViwLw", - "notePath": [ - "jdjRLhLV3TtI", - "ibAPHul7Efvr", - "x6lgrdztQwVB", - "bOjeTrUViwLw" - ], - "title": "Download latest nightly and install it", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Download latest nightly and in.md", - "attachments": [] + "type": "label", + "name": "shareAlias", + "value": "syntax-highlighting", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-highlight", + "isInheritable": false, + "position": 30 } - ] + ], + "format": "markdown", + "dataFileName": "Syntax highlighting.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "7BCukQTCm7fv", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "7BCukQTCm7fv" + ], + "title": "Themes", + "notePosition": 200, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "themes", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-palette", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Themes.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "YTAxJMA3uWwn", + "notePath": [ + "jdjRLhLV3TtI", + "yeqU0zo0ZQ83", + "YTAxJMA3uWwn" + ], + "title": "Web Clipper", + "notePosition": 210, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "web-clipper", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-paperclip", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Web Clipper.md", + "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "YjerxU7Aii8X", + "notePath": [ + "jdjRLhLV3TtI", + "YjerxU7Aii8X" + ], + "title": "Troubleshooting", + "notePosition": 380, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-bug", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "troubleshooting", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "attachments": [], + "dirFileName": "Troubleshooting", + "children": [ + { + "isClone": false, + "noteId": "g9nFZ6dRz1Cg", + "notePath": [ + "jdjRLhLV3TtI", + "YjerxU7Aii8X", + "g9nFZ6dRz1Cg" + ], + "title": "better-sqlite3 was compiled against a different Node.js version", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "better-sqlite3", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "better-sqlite3 was compiled ag.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "QUb0fRhbpT8E", + "notePath": [ + "jdjRLhLV3TtI", + "YjerxU7Aii8X", + "QUb0fRhbpT8E" + ], + "title": "Error [TransformError]: The package \"@esbuild/linux-x64\" could not be found, and is needed by esbuild.", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "esbuild-error", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Error [TransformError] The pac.md", + "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "dtKC3FmoWOrv", + "notePath": [ + "jdjRLhLV3TtI", + "dtKC3FmoWOrv" + ], + "title": "Testing", + "notePosition": 400, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "w6gMvKh0UAVT", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "testing", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-eyedropper", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Testing.md", + "attachments": [], + "dirFileName": "Testing", + "children": [ + { + "isClone": false, + "noteId": "ETeT5YO61DAW", + "notePath": [ + "jdjRLhLV3TtI", + "dtKC3FmoWOrv", + "ETeT5YO61DAW" + ], + "title": "Unit tests", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "unit-tests", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Unit tests.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "C5MUQczZ5R9N", + "notePath": [ + "jdjRLhLV3TtI", + "dtKC3FmoWOrv", + "C5MUQczZ5R9N" + ], + "title": "Integration testing", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "integration", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Integration testing.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "bIfKwfCnqpeI", + "notePath": [ + "jdjRLhLV3TtI", + "dtKC3FmoWOrv", + "bIfKwfCnqpeI" + ], + "title": "Test database", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "test-database", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Test database.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "w6gMvKh0UAVT", + "notePath": [ + "jdjRLhLV3TtI", + "dtKC3FmoWOrv", + "w6gMvKh0UAVT" + ], + "title": "End-to-end tests", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "running-tests", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "End-to-end tests.md", + "attachments": [] } ] } diff --git a/docs/Developer Guide/Developer Guide.md b/docs/Developer Guide/Developer Guide.md new file mode 100644 index 0000000000..8f5721b305 --- /dev/null +++ b/docs/Developer Guide/Developer Guide.md @@ -0,0 +1,15 @@ +# Developer Guide +This documentation is intended for developers planning to implement new features or maintain the Trilium Notes application, as it describes the architecture of the application. + +For the user-facing documentation, including how to write scripts and the various APIs, consult the [user guide](https://docs.triliumnotes.org/user-guide/) instead. + +### Quick links + +* Environment Setup +* Project Structure + +### External links + +* The [Trilium Notes website](https://triliumnotes.org/), for a quick presentation of the application. +* [User Guide](https://docs.triliumnotes.org/user-guide/), to understand the concepts of the application itself. +* [GitHub Repository (TriliumNext/Trilium)](https://github.com/TriliumNext/Trilium/) \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Architecture.md b/docs/Developer Guide/Developer Guide/Architecture.md new file mode 100644 index 0000000000..66cb82eea2 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture.md @@ -0,0 +1,202 @@ +# Architecture +Trilium Notes is a hierarchical note-taking application built as a TypeScript monorepo. It supports multiple deployment modes (desktop, server, mobile web) and features advanced capabilities including synchronization, scripting, encryption, and rich content editing. + +### Key Characteristics + +* **Monorepo Architecture**: Uses pnpm workspaces for dependency management +* **Multi-Platform**: Desktop (Electron), Server (Node.js/Express), and Mobile Web +* **TypeScript-First**: Strong typing throughout the codebase +* **Plugin-Based**: Extensible architecture for note types and UI components +* **Offline-First**: Full functionality without network connectivity +* **Synchronization-Ready**: Built-in sync protocol for multi-device usage + +### Technology Stack + +* **Runtime**: Node.js (backend), Browser/Electron (frontend) +* **Language**: TypeScript, JavaScript +* **Database**: SQLite (better-sqlite3) +* **Build Tools**: + * Client: Vite, + * Server: ESBuild (bundling) + * Package manager: pnpm +* **UI Framework**: Custom widget-based system (vanilla HTML, CSS & JavaScript + jQuery), in the process of converting to React/Preact. +* **Rich Text**: CKEditor 5 (customized) +* **Code Editing**: CodeMirror 6 +* **Desktop**: Electron +* **Server**: Express.js + +## Main architecture + +Trilium follows a **client-server architecture** even in desktop mode, where Electron runs both the backend server and frontend client within the same process. + +``` +graph TB + subgraph Frontend + Widgets[Widgets
    System] + Froca[Froca
    Cache] + UIServices[UI
    Services] + end + + subgraph Backend["Backend Server"] + Express[Express
    Routes] + Becca[Becca
    Cache] + ScriptEngine[Script
    Engine] + Database[(SQLite
    Database)] + end + + Widgets -.-> API[WebSocket & REST API] + Froca -.-> API + UIServices -.-> API + API -.-> Express + API -.-> Becca + API -.-> ScriptEngine + Becca --> Database + Express --> Database + ScriptEngine --> Database +``` + +### Deployment Modes + +1. **Desktop Application** + * Electron wrapper running both frontend and backend + * Local SQLite database + * Full offline functionality + * Cross-platform (Windows, macOS, Linux) +2. **Server Installation** + * Node.js server exposing web interface + * Multi-user capable + * Can sync with desktop clients + * Docker deployment supported +3. **Mobile Web** + * Optimized responsive interface + * Accessed via browser + * Requires server installation + +## Monorepo Structure + +Trilium uses **pnpm workspaces** to manage its monorepo structure, with apps and packages clearly separated. + +``` +trilium/ +ā”œā”€ā”€ apps/ # Runnable applications +│ ā”œā”€ā”€ client/ # Frontend application (shared by server & desktop) +│ ā”œā”€ā”€ server/ # Node.js server with web interface +│ ā”œā”€ā”€ desktop/ # Electron desktop application +│ ā”œā”€ā”€ web-clipper/ # Browser extension for web content capture +│ ā”œā”€ā”€ db-compare/ # Database comparison tool +│ ā”œā”€ā”€ dump-db/ # Database export tool +│ ā”œā”€ā”€ edit-docs/ # Documentation editing tool +│ ā”œā”€ā”€ build-docs/ # Documentation build tool +│ └── website/ # Marketing website +│ +ā”œā”€ā”€ packages/ # Shared libraries +│ ā”œā”€ā”€ commons/ # Shared interfaces and utilities +│ ā”œā”€ā”€ ckeditor5/ # Custom rich text editor +│ ā”œā”€ā”€ codemirror/ # Code editor customizations +│ ā”œā”€ā”€ highlightjs/ # Syntax highlighting +│ ā”œā”€ā”€ ckeditor5-admonition/ # CKEditor plugin: admonitions +│ ā”œā”€ā”€ ckeditor5-footnotes/ # CKEditor plugin: footnotes +│ ā”œā”€ā”€ ckeditor5-keyboard-marker/# CKEditor plugin: keyboard shortcuts +│ ā”œā”€ā”€ ckeditor5-math/ # CKEditor plugin: math equations +│ ā”œā”€ā”€ ckeditor5-mermaid/ # CKEditor plugin: diagrams +│ ā”œā”€ā”€ express-partial-content/ # HTTP partial content middleware +│ ā”œā”€ā”€ share-theme/ # Shared note theme +│ ā”œā”€ā”€ splitjs/ # Split pane library +│ └── turndown-plugin-gfm/ # Markdown conversion +│ +ā”œā”€ā”€ docs/ # Documentation +ā”œā”€ā”€ scripts/ # Build and utility scripts +└── patches/ # Package patches (via pnpm) +``` + +### Package Dependencies + +The monorepo uses workspace protocol (`workspace:*`) for internal dependencies: + +``` +desktop → client → commons +server → client → commons +client → ckeditor5, codemirror, highlightjs +ckeditor5 → ckeditor5-* plugins +``` + +## Security summary + +### Encryption System + +**Per-Note Encryption:** + +* Notes can be individually protected +* AES-128-CBC encryption for encrypted notes. +* Separate protected session management + +**Protected Session:** + +* Time-limited access to protected notes +* Automatic timeout +* Re-authentication required +* Frontend: `protected_session.ts` +* Backend: `protected_session.ts` + +### Authentication + +**Password Auth:** + +* PBKDF2 key derivation +* Salt per installation +* Hash verification + +**OpenID Connect:** + +* External identity provider support +* OAuth 2.0 flow +* Configurable providers + +**TOTP (2FA):** + +* Time-based one-time passwords +* QR code setup +* Backup codes + +### Authorization + +**Single-User Model:** + +* Desktop: single user (owner) +* Server: single user per installation + +**Share Notes:** + +* Public access without authentication +* Separate Shaca cache +* Read-only access + +### CSRF Protection + +**CSRF Tokens:** + +* Required for state-changing operations +* Token in header or cookie +* Validation middleware + +### Input Sanitization + +**XSS Prevention:** + +* DOMPurify for HTML sanitization +* CKEditor content filtering +* CSP headers + +**SQL Injection:** + +* Parameterized queries only +* Better-sqlite3 prepared statements +* No string concatenation in SQL + +### Dependency Security + +**Vulnerability Scanning:** + +* Renovate bot for updates +* npm audit integration +* Override vulnerable sub-dependencies \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Architecture/APIs.md b/docs/Developer Guide/Developer Guide/Architecture/APIs.md new file mode 100644 index 0000000000..cdd954a610 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture/APIs.md @@ -0,0 +1,72 @@ +# APIs +### Internal API + +**REST Endpoints** (`/api/*`) + +Used by the frontend for all operations: + +**Note Operations:** + +* `GET /api/notes/:noteId` - Get note +* `POST /api/notes/:noteId/content` - Update content +* `PUT /api/notes/:noteId` - Update metadata +* `DELETE /api/notes/:noteId` - Delete note + +**Tree Operations:** + +* `GET /api/tree` - Get note tree +* `POST /api/branches` - Create branch +* `PUT /api/branches/:branchId` - Update branch +* `DELETE /api/branches/:branchId` - Delete branch + +**Search:** + +* `GET /api/search?query=...` - Search notes +* `GET /api/search-note/:noteId` - Execute search note + +### ETAPI (External API) + +Located at: `apps/server/src/etapi/` + +**Purpose:** Third-party integrations and automation + +**Authentication:** Token-based (ETAPI tokens) + +**OpenAPI Spec:** Auto-generated + +**Key Endpoints:** + +* `/etapi/notes` - Note CRUD +* `/etapi/branches` - Branch management +* `/etapi/attributes` - Attribute operations +* `/etapi/attachments` - Attachment handling + +**Example:** + +``` +curl -H "Authorization: YOUR_TOKEN" \ + https://trilium.example.com/etapi/notes/noteId +``` + +### WebSocket API + +Located at: `apps/server/src/services/ws.ts` + +**Purpose:** Real-time updates and synchronization + +**Protocol:** WebSocket (Socket.IO-like custom protocol) + +**Message Types:** + +* `sync` - Synchronization request +* `entity-change` - Entity update notification +* `refresh-tree` - Tree structure changed +* `open-note` - Open note in UI + +**Client Subscribe:** + +```typescript +ws.subscribe('entity-change', (data) => { + froca.processEntityChange(data) +}) +``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Architecture/Arhitecture Decision Records.md b/docs/Developer Guide/Developer Guide/Architecture/Arhitecture Decision Records.md new file mode 100644 index 0000000000..c524642cd9 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture/Arhitecture Decision Records.md @@ -0,0 +1,62 @@ +# Arhitecture Decision Records +## šŸš€ Future milestones + +* [Mobile](https://github.com/TriliumNext/Trilium/issues/7447) +* [Multi-user](https://github.com/TriliumNext/Trilium/issues/4956) + +## Aug 2025 - present: Port the client to React + +- [x] [Type widgets](https://github.com/TriliumNext/Trilium/pull/7044) +- [x] [Collections](https://github.com/TriliumNext/Trilium/pull/6837) +- [x] [Various widgets](https://github.com/TriliumNext/Trilium/pull/6830) +- [x] [Floating buttons](https://github.com/TriliumNext/Trilium/pull/6811) +- [x] [Settings](https://github.com/TriliumNext/Trilium/pull/6660) + +## Aug 2025 - Move away from NX + +We took the decision of moving away from the NX monorepo tool, due to: + +* Various issues with the cache, especially after an update of the NX dependencies which required periodical `nx reset` to get rid of. +* Various issues with memory and CPU consumption along the way, due to the NX daemon (including it remaining as a background process after closing the IDE). +* On Windows, almost always there was a freeze on every second build. +* Various hacks that were needed to achieve what we needed (especially for artifacts since NX would not copy assets if they were in `.gitignore` for some arbitrary reason and requiring a patch that made it difficult to maintain across updates). + +As a result, we decided to switch to… nothing. Why? + +* `pnpm` (which we were already using) covers the basic needs of a monorepo via workspaces on its own. +* Our client-side solution, Vite already supports navigating through projects without requiring built artifacts. This makes the build process slightly faster (especially cold starts) at a slighter bigger RAM consumption. +* ESBuild, on the server-side, also seems happy to go across projects without an issue. + +Apart from this: + +* In dev mode, the server now runs directly using `tsx` and not built and then run. This means that it'll run much faster. +* We're back to an architecture where the `server` and the `desktop` host their own Vite instance as a middleware. What this means that there is no `client:dev` and no separate port to handle. + * This makes it possible to easily test on mobile in dev mode, since there's a single port to access. + * The downside is that the initial start up time is longer while Vite is spinning up. Nevertheless, it's still slightly faster than it used to be anyway. +* No more asset copying, which should also improve performance. +* No more messing around with the native dependency of `better-sqlite3` that caused those dreaded mismatches when running between server and desktop. We have (hopefully) found a permanent solution for it that involves no user input. +* A decent solution was put in place to allow easier development on NixOS for the desktop application. +* The desktop version has also gained back the ability to automatically refresh the client when a change is made, including live changes for React components. + +Migration steps, as a developer: + +1. In VS Code, uninstall the NX Console unless you plan to use it for other projects. +2. Remove `.nx` at project level. +3. It's ideal to clean up all your `node_modules` in the project (do note that it's not just the top-level one, but also in `apps/client`, `apps/server`, `apps/desktop`, etc.). +4. Run a `pnpm i` to set up the new dependencies and the installation +5. Instead of `nx run server:serve`, now you can simply run `pnpm dev` while in `apps/server`, or `pnpm server:start` while in the root. +6. When first starting the server, it will take slightly longer than usual to see something on the screen since the dependencies are being rebuilt. Those are later cached so subsequent runs should work better. If you end up with a white screen, simply refresh the page a few times until it shows up correctly. + +## Apr 2025: NX-based monorepo + +* Goal: Restructure the application from a mix where the client was a subfolder within the server and other dependencies such asĀ CKEditorĀ were scattered in various repositories to a monorepo powered by NX. +* [Initial discussion](https://github.com/TriliumNext/Trilium/issues/4941) +* [Relevant PR](https://github.com/TriliumNext/Notes/pull/1773) + +## Dec 2024: Front-end conversion to TypeScript + +* [Relevant PRs on GitHub](https://github.com/TriliumNext/Notes/pulls?q=is%3Apr+is%3Aclosed+%22Port+frontend+to+TypeScript%22) + +## Apr 2024: Back-end conversion to TypeScript + +* [Relevant PRs on GitHub](https://github.com/TriliumNext/Notes/pulls?q=is%3Apr+%22convert+backend+to+typescript%22) \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Architecture/Backend.md b/docs/Developer Guide/Developer Guide/Architecture/Backend.md new file mode 100644 index 0000000000..df0ddf21db --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture/Backend.md @@ -0,0 +1,88 @@ +# Backend +### Application Entry Point + +Location: `apps/server/src/main.ts` + +**Startup Sequence:** + +1. Load configuration +2. Initialize database +3. Run migrations +4. Load Becca cache +5. Start Express server +6. Initialize WebSocket +7. Start scheduled tasks + +### Service Layer + +Located at: `apps/server/src/services/` + +**Core Services:** + +* **Notes Management** + * `notes.ts` - CRUD operations + * `note_contents.ts` - Content handling + * `note_types.ts` - Type-specific logic + * `cloning.ts` - Note cloning/multi-parent +* **Tree Operations** + * `tree.ts` - Tree structure management + * `branches.ts` - Branch operations + * `consistency_checks.ts` - Tree integrity +* **Search** + * `search/search.ts` - Main search engine + * `search/expressions/` - Search expression parsing + * `search/services/` - Search utilities +* **Sync** + * `sync.ts` - Synchronization protocol + * `sync_update.ts` - Update handling + * `sync_mutex.ts` - Concurrency control +* **Scripting** + * `backend_script_api.ts` - Backend script API + * `script_context.ts` - Script execution context +* **Import/Export** + * `import/` - Various import formats + * `export/` - Export to different formats + * `zip.ts` - Archive handling +* **Security** + * `encryption.ts` - Note encryption + * `protected_session.ts` - Session management + * `password.ts` - Password handling + +### Route Structure + +Located at: `apps/server/src/routes/` + +``` +routes/ +ā”œā”€ā”€ index.ts # Route registration +ā”œā”€ā”€ api/ # REST API endpoints +│ ā”œā”€ā”€ notes.ts +│ ā”œā”€ā”€ branches.ts +│ ā”œā”€ā”€ attributes.ts +│ ā”œā”€ā”€ search.ts +│ ā”œā”€ā”€ login.ts +│ └── ... +└── custom/ # Special endpoints + ā”œā”€ā”€ setup.ts + ā”œā”€ā”€ share.ts + └── ... +``` + +**API Endpoint Pattern:** + +```typescript +router.get('/api/notes/:noteId', (req, res) => { + const noteId = req.params.noteId + const note = becca.getNote(noteId) + res.json(note.getPojoWithContent()) +}) +``` + +### Middleware + +Key middleware components: + +* `auth.ts` - Authentication +* `csrf.ts` - CSRF protection +* `request_context.ts` - Request-scoped data +* `error_handling.ts` - Error responses \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Architecture/Database.md b/docs/Developer Guide/Developer Guide/Architecture/Database.md new file mode 100644 index 0000000000..b8836b56d4 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture/Database.md @@ -0,0 +1,40 @@ +# Database +Trilium uses **SQLite** (via `better-sqlite3`) as its embedded database engine, providing a reliable, file-based storage system that requires no separate database server. The database stores all notes, their relationships, metadata, and configuration. + +Schema location: `apps/server/src/assets/db/schema.sql` + +### Data Access Patterns + +**Direct SQL:** + +```typescript +// apps/server/src/services/sql.ts +sql.getRows("SELECT * FROM notes WHERE type = ?", ['text']) +sql.execute("UPDATE notes SET title = ? WHERE noteId = ?", [title, noteId]) +``` + +**Through Becca:** + +```typescript +// Recommended approach - uses cache +const note = becca.getNote('noteId') +note.title = 'New Title' +note.save() +``` + +**Through Froca (Frontend):** + +```typescript +// Read-only access +const note = froca.getNote('noteId') +console.log(note.title) +``` + +### Database Migrations + +* The migration system is in `server/src/migrations/migrations.ts` (actual definitions) and `src/services/migration.ts`. +* Both SQLite and TypeScript migrations are supported. + * Small migrations are contained directly in `src/migrations/migrations.ts`. + * Bigger TypeScript migrations are sequentially numbered (e.g., `XXXX_migration_name.ts`) and dynamically imported by `migrations.ts`. +* Automatic execution on version upgrade. +* Schema version tracked in options table. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Database/attachments.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/attachments.md similarity index 90% rename from docs/Developer Guide/Developer Guide/Development and architecture/Database/attachments.md rename to docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/attachments.md index 4312832dd4..09ae80d4b5 100644 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Database/attachments.md +++ b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/attachments.md @@ -6,11 +6,11 @@ | `role` | Text | Non-null | | The role of the attachment: `image` for images that are attached to a note, `file` for uploaded files. | | `mime` | Text | Non-null | | The MIME type of the attachment (e.g. `image/png`) | | `title` | Text | Non-null | | The title of the attachment. | -| `isProtected` | Integer | Non-null | 0 | `1` if the entity is [protected](../Protected%20entities.md), `0` otherwise. | +| `isProtected` | Integer | Non-null | 0 | `1` if the entity is [protected](../../../Concepts/Protected%20entities.md), `0` otherwise. | | `position` | Integer | Non-null | 0 | Not sure where the position is relevant for attachments (saw it with values of 10 and 0). | | `blobId` | Text | Nullable | `null` | The corresponding `blobId` from theĀ blobsĀ table. | | `dateModified` | Text | Non-null | | Localized modification date (e.g. `2023-11-08 18:43:44.204+0200`) | | `utcDateModified` | Text | Non-null | | Modification date in UTC format (e.g. `2023-11-08 16:43:44.204Z`) | | `utcDateScheduledForErasure` | Text | Nullable | `null` | | -| `isDeleted` | Integer | Non-null | | `1` if the entity is [deleted](../Deleted%20notes.md), `0` otherwise. | +| `isDeleted` | Integer | Non-null | | `1` if the entity is [deleted](../../../Concepts/Deleted%20notes.md), `0` otherwise. | | `deleteId` | Text | Nullable | `null` | | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/attributes.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/attributes.md new file mode 100644 index 0000000000..f1cbb99c47 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/attributes.md @@ -0,0 +1,2 @@ +# attributes +
    Column NameData TypeNullityDefault valueDescription
    attributeIdTextNon-null Unique Id of the attribute (e.g. qhC1vzU4nwSE), can also have a special unique ID for Special notes (e.g. _lbToday_liconClass).
    noteIdTextNon-null The ID of the note this atttribute belongs to
    typeTextNon-null The type of attribute (label or relation).
    nameTextNon-null The name/key of the attribute.
    valueTextNon-null""
    • For label attributes, a free-form value of the attribute.
    • For relation attributes, the ID of the note the relation is pointing to.
    positionIntegerNon-null0The position of the attribute compared to the other attributes. Some predefined attributes such as originalFileName have a value of 1000.
    utcDateModifiedTextNon-null Modification date in UTC format (e.g. 2023-11-08 16:43:44.204Z)
    isDeletedIntegerNon-null 1 if the entity is deleted, 0 otherwise.
    deleteIdTextNullablenull 
    isInheritableIntegerNullable0 
    \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/blobs.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/blobs.md new file mode 100644 index 0000000000..63bf8c24d9 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/blobs.md @@ -0,0 +1,2 @@ +# blobs +
    Column NameData TypeNullityDefault valueDescription
    blobIdTextNon-null 

    The unique ID of the blob (e.g. XXbfAJXqWrYnSXcelLFA).

    contentTextNullablenull

    The content of the blob, can be either:

    • text (for plain text notes or HTML notes).
    • binary (for images and other types of attachments)
    dateModifiedTextNon-null Creation date with timezone offset (e.g. 2023-11-08 18:43:44.204+0200)
    utcDateModifiedTextNon-null 

    Creation date in UTC format (e.g. 2023-11-08 16:43:44.204Z).

    Blobs cannot be modified, so this timestamp specifies when the blob was created.

    \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Database/branches.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/branches.md similarity index 82% rename from docs/Developer Guide/Developer Guide/Development and architecture/Database/branches.md rename to docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/branches.md index d9b12dea56..18cf290905 100644 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Database/branches.md +++ b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/branches.md @@ -5,8 +5,8 @@ | `noteId` | Text | Non-null | | The ID of the [note](notes.md). | | `parentNoteId` | Text | Non-null | | The ID of the parent [note](notes.md) the note belongs to. | | `notePosition` | Integer | Non-null | | The position of the branch within the same level of hierarchy, the value is usually a multiple of 10. | -| `prefix` | Text | Nullable | | The [branch prefix](../Branch%20prefixes.md) if any, or `NULL` otherwise. | +| `prefix` | Text | Nullable | | The [branch prefix](../../../Concepts/Branch%20prefixes.md) if any, or `NULL` otherwise. | | `isExpanded` | Integer | Non-null | 0 | Whether the branch should appear expanded (its children shown) to the user. | -| `isDeleted` | Integer | Non-null | 0 | `1` if the entity is [deleted](../Deleted%20notes.md), `0` otherwise. | +| `isDeleted` | Integer | Non-null | 0 | `1` if the entity is [deleted](../../../Concepts/Deleted%20notes.md), `0` otherwise. | | `deleteId` | Text | Nullable | `null` | | | `utcDateModified` | Text | Non-null | | Modification date in UTC format (e.g. `2023-11-08 16:43:44.204Z`) | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Database/entity_changes.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/entity_changes.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Database/entity_changes.md rename to docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/entity_changes.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Database/etapi_tokens.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/etapi_tokens.md similarity index 90% rename from docs/Developer Guide/Developer Guide/Development and architecture/Database/etapi_tokens.md rename to docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/etapi_tokens.md index 25fe4e5dad..3f11dffa9f 100644 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Database/etapi_tokens.md +++ b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/etapi_tokens.md @@ -6,4 +6,4 @@ | `tokenHash` | Text | Non-null | | The token itself. | | `utcDateCreated` | Text | Non-null | | Creation date in UTC format (e.g. `2023-11-08 16:43:44.204Z`) | | `utcDateModified` | Text | Non-null | | Modification date in UTC format (e.g. `2023-11-08 16:43:44.204Z`) | -| `isDeleted` | Integer | Non-null | 0 | `1` if the entity is [deleted](../Deleted%20notes.md), `0` otherwise. | \ No newline at end of file +| `isDeleted` | Integer | Non-null | 0 | `1` if the entity is [deleted](../../../Concepts/Deleted%20notes.md), `0` otherwise. | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Database/notes.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/notes.md similarity index 87% rename from docs/Developer Guide/Developer Guide/Development and architecture/Database/notes.md rename to docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/notes.md index 572c7f6dbd..108ea8b267 100644 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Database/notes.md +++ b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/notes.md @@ -3,13 +3,13 @@ | --- | --- | --- | --- | --- | | `noteId` | Text | Non-null | | The unique ID of the note (e.g. `2LJrKqIhr0Pe`). | | `title` | Text | Non-null | `"note"` | The title of the note, as defined by the user. | -| `isProtected` | Integer | Non-null | 0 | `1` if the entity is [protected](../Protected%20entities.md), `0` otherwise. | +| `isProtected` | Integer | Non-null | 0 | `1` if the entity is [protected](../../../Concepts/Protected%20entities.md), `0` otherwise. | | `type` | Text | Non-null | `"text"` | The type of note (i.e. `text`, `file`, `code`, `relationMap`, `mermaid`, `canvas`). | | `mime` | Text | Non-null | `"text/html"` | The MIME type of the note (e.g. `text/html`).. Note that it can be an empty string in some circumstances, but not null. | -| `isDeleted` | Integer | Nullable | 0 | `1` if the entity is [deleted](../Deleted%20notes.md), `0` otherwise. | +| `blobId` | Text | Nullable | `null` | The corresponding ID fromĀ blobs. Although it can theoretically be `NULL`, haven't found any such note yet. | +| `isDeleted` | Integer | Nullable | 0 | `1` if the entity is [deleted](../../../Concepts/Deleted%20notes.md), `0` otherwise. | | `deleteId` | Text | Non-null | `null` | | | `dateCreated` | Text | Non-null | | Localized creation date (e.g. `2023-11-08 18:43:44.204+0200`) | | `dateModified` | Text | Non-null | | Localized modification date (e.g. `2023-11-08 18:43:44.204+0200`) | | `utcDateCreated` | Text | Non-null | | Creation date in UTC format (e.g. `2023-11-08 16:43:44.204Z`) | -| `utcDateModified` | Text | Non-null | | Modification date in UTC format (e.g. `2023-11-08 16:43:44.204Z`) | -| `blobId` | Text | Nullable | `null` | The corresponding ID fromĀ blobs. Although it can theoretically be `NULL`, haven't found any such note yet. | \ No newline at end of file +| `utcDateModified` | Text | Non-null | | Modification date in UTC format (e.g. `2023-11-08 16:43:44.204Z`) | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Database/options.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/options.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Database/options.md rename to docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/options.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Database/recent_notes.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/recent_notes.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Database/recent_notes.md rename to docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/recent_notes.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Database/revisions.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/revisions.md similarity index 88% rename from docs/Developer Guide/Developer Guide/Development and architecture/Database/revisions.md rename to docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/revisions.md index 210e05356e..faae5421cb 100644 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Database/revisions.md +++ b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/revisions.md @@ -1,12 +1,12 @@ # revisions | Column Name | Data Type | Nullity | Default value | Description | | --- | --- | --- | --- | --- | -| `revisionId` | TextText | Non-null | | Unique ID of the revision (e.g. `0GjgUqnEudI8`). | +| `revisionId` | Text | Non-null | | Unique ID of the revision (e.g. `0GjgUqnEudI8`). | | `noteId` | Text | Non-null | | ID of the [note](notes.md) this revision belongs to. | | `type` | Text | Non-null | `""` | The type of note (i.e. `text`, `file`, `code`, `relationMap`, `mermaid`, `canvas`). | | `mime` | Text | Non-null | `""` | The MIME type of the note (e.g. `text/html`). | | `title` | Text | Non-null | | The title of the note, as defined by the user. | -| `isProtected` | Integer | Non-null | 0 | `1` if the entity is [protected](../Protected%20entities.md), `0` otherwise. | +| `isProtected` | Integer | Non-null | 0 | `1` if the entity is [protected](../../../Concepts/Protected%20entities.md), `0` otherwise. | | `blobId` | Text | Nullable | `null` | The corresponding ID fromĀ blobs. Although it can theoretically be `NULL`, haven't found any such note yet. | | `utcDateLastEdited` | Text | Non-null | | **Not sure how it differs from modification date.** | | `utcDateCreated` | Text | Non-null | | Creation date in UTC format (e.g. `2023-11-08 16:43:44.204Z`) | diff --git a/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/sessions.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/sessions.md new file mode 100644 index 0000000000..4562361522 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/sessions.md @@ -0,0 +1,8 @@ +# sessions +Contains user sessions for authentication purposes. The table is almost a direct mapping of the information that `express-session` requires. + +| Column Name | Data Type | Nullity | Default value | Description | +| --- | --- | --- | --- | --- | +| `id` | Text | Non-null | | Unique, non-sequential ID of the session, directly as indicated by `express-session` | +| `data` | Text | Non-null | | The session information, in stringified JSON format. | +| `expires` | Integer | Non-null | | The expiration date of the session, extracted from the session information. Used to rapidly clean up expired sessions. | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/user_data.md b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/user_data.md new file mode 100644 index 0000000000..3b27ee30fe --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture/Database/Database structure/user_data.md @@ -0,0 +1,17 @@ +# user_data +Contains the user information for two-factor authentication. This table is **not** used for multi-user. + +Relevant files: + +* `apps/server/src/services/encryption/open_id_encryption.ts` + +| Column Name | Data Type | Nullity | Default value | Description | +| --- | --- | --- | --- | --- | +| `tmpID` | Integer | | | A sequential ID of the user. Since only one user is supported by Trilium, this value is always zero. | +| `username` | Text | | | The user name as returned from the OAuth operation. | +| `email` | Text | | | The email as returned from the OAuth operation. | +| `userIDEncryptedDataKey` | Text | | | An encrypted hash of the user subject identifier from the OAuth operation. | +| `userIDVerificationHash` | Text | | | A salted hash of the subject identifier from the OAuth operation. | +| `salt` | Text | | | The verification salt. | +| `derivedKey` | Text | | | A random secure token. | +| `isSetup` | Text | | `"false"` | Indicates that the user has been saved (`"true"`). | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Architecture/Frontend.md b/docs/Developer Guide/Developer Guide/Architecture/Frontend.md new file mode 100644 index 0000000000..9ef0acbdfb --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture/Frontend.md @@ -0,0 +1,61 @@ +# Frontend +### Application Entry Point + +**Desktop:** `apps/client/src/desktop.ts` **Web:** `apps/client/src/index.ts` + +### Service Layer + +Located at: `apps/client/src/services/` + +Key services: + +* `froca.ts` - Frontend cache +* `server.ts` - API communication +* `ws.ts` - WebSocket connection +* `tree_service.ts` - Note tree management +* `note_context.ts` - Active note tracking +* `protected_session.ts` - Encryption key management +* `link.ts` - Note linking and navigation +* `export.ts` - Note export functionality + +### UI Components + +**Component Locations:** + +* `widgets/containers/` - Layout containers +* `widgets/buttons/` - Toolbar buttons +* `widgets/dialogs/` - Modal dialogs +* `widgets/ribbon_widgets/` - Tab widgets +* `widgets/type_widgets/` - Note type editors + +### Event System + +**Application Events:** + +```typescript +// Subscribe to events +appContext.addBeforeUnloadListener(() => { + // Cleanup before page unload +}) + +// Trigger events +appContext.trigger('noteTreeLoaded') +``` + +**Note Context Events:** + +```typescript +// NoteContextAwareWidget automatically receives: +- noteSwitched() +- noteChanged() +- refresh() +``` + +### State Management + +Trilium uses **custom state management** rather than Redux/MobX: + +* `note_context.ts` - Active note and context +* `froca.ts` - Entity cache +* Component local state +* URL parameters for shareable state \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Architecture/Security.md b/docs/Developer Guide/Developer Guide/Architecture/Security.md new file mode 100644 index 0000000000..f1ef4da771 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Architecture/Security.md @@ -0,0 +1,464 @@ +# Security +Trilium implements a **defense-in-depth security model** with multiple layers of protection for user data. The security architecture covers authentication, authorization, encryption, input sanitization, and secure communication. + +## Security Principles + +1. **Data Privacy**: User data is protected at rest and in transit +2. **Encryption**: Per-note encryption for sensitive content +3. **Authentication**: Multiple authentication methods supported +4. **Authorization**: Single-user model with granular protected sessions +5. **Input Validation**: All user input sanitized +6. **Secure Defaults**: Security features enabled by default +7. **Transparency**: Open source allows security audits + +## Threat Model + +### Threats Considered + +1. **Unauthorized Access** + * Physical access to device + * Network eavesdropping + * Stolen credentials + * Session hijacking +2. **Data Exfiltration** + * Malicious scripts + * XSS attacks + * SQL injection + * CSRF attacks +3. **Data Corruption** + * Malicious modifications + * Database tampering + * Sync conflicts +4. **Privacy Leaks** + * Unencrypted backups + * Search indexing + * Temporary files + * Memory dumps + +### Out of Scope + +* Nation-state attackers +* Zero-day vulnerabilities in dependencies +* Hardware vulnerabilities (Spectre, Meltdown) +* Physical access with unlimited time +* Quantum computing attacks + +## Authentication + +### Password Authentication + +**Implementation:** `apps/server/src/services/password.ts` + +### TOTP (Two-Factor Authentication) + +**Implementation:** `apps/server/src/routes/api/login.ts` + +### OpenID Connect + +**Implementation:** `apps/server/src/routes/api/login.ts` + +**Supported Providers:** + +* Any OpenID Connect compatible provider +* Google, GitHub, Auth0, etc. + +**Flow:** + +```typescript +// 1. Redirect to provider +GET /api/login/openid + +// 2. Provider redirects back with code +GET /api/login/openid/callback?code=... + +// 3. Exchange code for tokens +const tokens = await openidClient.callback(redirectUri, req.query) + +// 4. Verify ID token +const claims = tokens.claims() + +// 5. Create session +req.session.loggedIn = true +``` + +### Session Management + +**Session Storage:** SQLite database (sessions table) + +**Session Configuration:** + +```typescript +app.use(session({ + secret: sessionSecret, + resave: false, + saveUninitialized: false, + rolling: true, + cookie: { + maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days + httpOnly: true, + secure: isHttps, + sameSite: 'lax' + }, + store: new SqliteStore({ + db: db, + table: 'sessions' + }) +})) +``` + +**Session Invalidation:** + +* Automatic timeout after inactivity +* Manual logout clears session +* Server restart invalidates all sessions (optional) + +## Authorization + +### Single-User Model + +**Desktop:** + +* Single user (owner of device) +* No multi-user support +* Full access to all notes + +**Server:** + +* Single user per installation +* Authentication required for all operations +* No user roles or permissions + +### Protected Sessions + +**Purpose:** Temporary access to encrypted (protected) notes + +**Implementation:** `apps/server/src/services/protected_session.ts` + +**Workflow:** + +```typescript +// 1. User enters password for protected notes +POST /api/protected-session/enter +Body: { password: "protected-password" } + +// 2. Derive encryption key +const protectedDataKey = deriveKey(password) + +// 3. Verify password (decrypt known encrypted value) +const decrypted = decrypt(testValue, protectedDataKey) +if (decrypted === expectedValue) { + // 4. Store in memory (not in session) + protectedSessionHolder.setProtectedDataKey(protectedDataKey) + + // 5. Set timeout + setTimeout(() => { + protectedSessionHolder.clearProtectedDataKey() + }, timeout) +} +``` + +**Protected Session Timeout:** + +* Default: 10 minutes (configurable) +* Extends on activity +* Cleared on browser close +* Separate from main session + +### API Authorization + +**Internal API:** + +* Requires authenticated session +* CSRF token validation +* Same-origin policy + +**ETAPI (External API):** + +* Token-based authentication +* No session required +* Rate limiting + +## Encryption + +### Note Encryption + +**Encryption Algorithm:** AES-256-CBC + +**Key Hierarchy:** + +``` +User Password + ↓ (scrypt) +Data Key (for protected notes) + ↓ (AES-128) +Protected Note Content +``` + +**Protected Note Metadata:** + +* Content IS encrypted +* Type and MIME are NOT encrypted +* Attributes are NOT encrypted + +### Data Key Management + +**Key Rotation:** + +* Not currently supported +* Requires re-encrypting all protected notes + +### Transport Encryption + +**HTTPS:** + +* Recommended for server installations +* TLS 1.2+ only +* Strong cipher suites preferred +* Certificate validation enabled + +**Desktop:** + +* Local communication (no network) +* No HTTPS required + +### Backup Encryption + +**Database Backups:** + +* Protected notes remain encrypted in backup +* Backup file should be protected separately +* Consider encrypting backup storage location + +## Input Sanitization + +### XSS Prevention + +* **HTML Sanitization** +* **CKEditor Configuration:** + + ``` + // apps/client/src/widgets/type_widgets/text_type_widget.ts + ClassicEditor.create(element, { + // Restrict allowed content + htmlSupport: { + allow: [ + { name: /./, attributes: true, classes: true, styles: true } + ], + disallow: [ + { name: 'script' }, + { name: 'iframe', attributes: /^(?!src$).*/ } + ] + } + }) + ``` +* Content Security Policy + +### SQL Injection Prevention + +**Parameterized Queries:** + +```typescript +const notes = sql.getRows( + 'SELECT * FROM notes WHERE title = ?', + [userInput] +) +``` + +**ORM Usage:** + +```typescript +// Entity-based access prevents SQL injection +const note = becca.getNote(noteId) +note.title = userInput // Sanitized by entity +note.save() // Parameterized query +``` + +### CSRF Prevention + +**CSRF Token Validation:** + +Location: `apps/server/src/routes/csrf_protection.ts` + +Stateless CSRF using [Double Submit Cookie Pattern](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie) via [`csrf-csrf`](https://github.com/Psifi-Solutions/csrf-csrf). + +### File Upload Validation + +**Validation:** + +```typescript +// Validate file size +const maxSize = 100 * 1024 * 1024 // 100 MB +if (file.size > maxSize) { + throw new Error('File too large') +} +``` + +## Network Security + +### HTTPS Configuration + +**Certificate Validation:** + +* Require valid certificates in production +* Self-signed certificates allowed for development +* Certificate pinning not implemented + +### Rate Limiting + +**Login Rate Limiting:** + +```typescript +const loginLimiter = rateLimit({ + windowMs: 15 * 60 * 1000, + max: 10, // 10 failed attempts + skipSuccessfulRequests: true +}) + +app.post('/api/login/password', loginLimiter, loginHandler) +``` + +## Data Security + +### Secure Data Deletion + +**Soft Delete:** + +```typescript +// Mark as deleted (sync first) +note.isDeleted = 1 +note.deleteId = generateUUID() +note.save() + +// Entity change tracked for sync +addEntityChange('notes', noteId, note) +``` + +**Hard Delete (Erase):** + +```typescript +// After sync completed +sql.execute('DELETE FROM notes WHERE noteId = ?', [noteId]) +sql.execute('DELETE FROM branches WHERE noteId = ?', [noteId]) +sql.execute('DELETE FROM attributes WHERE noteId = ?', [noteId]) + +// Mark entity change as erased +sql.execute('UPDATE entity_changes SET isErased = 1 WHERE entityId = ?', [noteId]) +``` + +**Blob Cleanup:** + +```typescript +// Find orphaned blobs (not referenced by any note/revision/attachment) +const orphanedBlobs = sql.getRows(` + SELECT blobId FROM blobs + WHERE blobId NOT IN (SELECT blobId FROM notes WHERE blobId IS NOT NULL) + AND blobId NOT IN (SELECT blobId FROM revisions WHERE blobId IS NOT NULL) + AND blobId NOT IN (SELECT blobId FROM attachments WHERE blobId IS NOT NULL) +`) + +// Delete orphaned blobs +for (const blob of orphanedBlobs) { + sql.execute('DELETE FROM blobs WHERE blobId = ?', [blob.blobId]) +} +``` + +### Memory Security + +**Protected Data in Memory:** + +* Protected data keys stored in memory only +* Cleared on timeout +* Not written to disk +* Not in session storage + +## Dependency Security + +### Vulnerability Scanning + +**Tools:** + +* Renovate bot - Automatic dependency updates +* `pnpm audit` - Check for known vulnerabilities +* GitHub Dependabot alerts + +**Process:** + +``` +# Check for vulnerabilities +npm audit + +# Fix automatically +npm audit fix + +# Manual review for breaking changes +npm audit fix --force +``` + +### Dependency Pinning + +**package.json:** + +``` +{ + "dependencies": { + "express": "4.18.2", // Exact version + "better-sqlite3": "^9.2.2" // Compatible versions + } +} +``` + +**pnpm Overrides:** + +``` +{ + "pnpm": { + "overrides": { + "lodash@<4.17.21": ">=4.17.21", // Force minimum version + "axios@<0.21.2": ">=0.21.2" + } + } +} +``` + +### Patch Management + +**pnpm Patches:** + +``` +# Create patch +pnpm patch @ckeditor/ckeditor5 + +# Edit files in temporary directory +# ... + +# Generate patch file +pnpm patch-commit /tmp/ckeditor5-patch + +# Patch applied automatically on install +``` + +## Security Auditing + +### Logs + +**Security Events Logged:** + +* Login attempts (success/failure) +* Protected session access +* Password changes +* ETAPI token usage +* Failed CSRF validations + +**Log Location:** + +* Desktop: Console output +* Server: Log files or stdout + +### Monitoring + +**Metrics to Monitor:** + +* Failed login attempts +* API error rates +* Unusual database changes +* Large exports/imports \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Branching strategy.md b/docs/Developer Guide/Developer Guide/Branching strategy.md new file mode 100644 index 0000000000..e302f4ee15 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Branching strategy.md @@ -0,0 +1,30 @@ +# Branching strategy +## Main branch + +The main development branch is conveniently called `main`. This branch contains all the merged features and is considered semi-stable. + +## Development + +Every new development must be done in a separate branch (usually prefixed with `feature/`). The PR must then be reviewed. + +## Reviewing + +Each PR must be tested manually and reviewed by a maintainer. For PRs that are made by the maintainers themselves, an LLM review from Copilot or Gemini are also accepted. + +After a PR is approved, it is merged into the `main` branch and the change log draft is updated. + +## Releasing + +[Releasing a new version](Building/Releasing%20a%20new%20version.md) is done straight from the `main` branch once it's deemed stable enough for production. + +## Hot-fixing + +After releasing a new version, it's sometimes desirable to create a hotfix in order to fix some issues with the production version without introducing many changes that might have already been merged in `main`. + +To do so, the procedure is as follows: + +1. A `hotfix` branch is created, from the tag of the release. +2. If fixes/features from the `main` branch are needed, they are cherry-picked directly onto the branch. +3. New fixes/features are either developed directly on the `hotfix` branch or an a PR that targets this branch, depending on the complexity. +4. A new version is released from the `hotfix` version. +5. The `hotfix` version is merged back into `main`, via a PR. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Building/Build deliveries locally.md b/docs/Developer Guide/Developer Guide/Building/Build deliveries locally.md new file mode 100644 index 0000000000..3c78ae4aa6 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Building/Build deliveries locally.md @@ -0,0 +1,34 @@ +# Build deliveries locally +## Building the desktop + +Go to `apps/desktop`, and: + +* To generate the packages, run `pnpm electron-forge:make`. +* To only build the Flatpak, run `pnpm electron-forge:make-flatpak`. +* To only build without packaging it, run `pnpm electron-forge:package`. + +## Building the server + +Go to `apps/server` and run `pnpm package` to run the build script. The built artifacts will appear in `apps/server/dist`, whereas the packaged build will be available in `apps/server/out`. + +## On NixOS + +Under NixOS the following `nix-shell` is needed: + +``` +nix-shell -p jq +``` + +For Linux builds: + +``` +nix-shell -p jq fakeroot dpkg +``` + +To test the Linux builds, use `steam-run`: + +```javascript +$ NIXPKGS_ALLOW_UNFREE=1 nix-shell -p steam-run +[nix-shell] cd dist/trilium-linux-x64 +[nix-shell] steam-run ./trilium +``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Building/Build information.md b/docs/Developer Guide/Developer Guide/Building/Build information.md new file mode 100644 index 0000000000..b1fd0437ba --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Building/Build information.md @@ -0,0 +1,4 @@ +# Build information +* Provides context about when the build was made and the corresponding Git revision. +* The information is displayed to the client when going in the about dialog. +* The build information is hard-coded in `apps/server/src/services/build.ts`. This file is generated automatically via `chore:update-build-info` which itself is run automatically whenever making a build in the CI. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Building/Docker.md b/docs/Developer Guide/Developer Guide/Building/Docker.md new file mode 100644 index 0000000000..ea5782ad2b --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Building/Docker.md @@ -0,0 +1,8 @@ +# Docker +To build the server for Docker: + +* Go to `apps/server` and run: + * `pnpm docker-build-debian` or + * `pnpm docker-build-alpine`. +* Similarly, to build the rootless versions: `pnpm docker-build-rootless-debian` or `pnpm docker-build-rootless-alpine`. +* To not only build but also run the Docker container, simply replace `docker-build` with `docker-start` (e.g. `pnpm docker-start-debian`). \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Building/Live reload (HMR).md b/docs/Developer Guide/Developer Guide/Building/Live reload (HMR).md new file mode 100644 index 0000000000..8ae38f99a5 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Building/Live reload (HMR).md @@ -0,0 +1,10 @@ +# Live reload (HMR) +Trilium uses Vite's HMR (hot module reloading) mechanism. + +## Server live reload + +If running the server using `pnpm server:start`, the server will watch for changes. For React components, they will be hot-reloaded without requiring a refresh. For other services, it will reload the page. + +## Desktop live reload + +`pnpm desktop:start` acts the same as `pnpm server:start` with hot-reloading for client-side changes. Changes on the desktop side require a complete re-run of the `pnpm desktop:start` command. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Building/Releasing a new version.md b/docs/Developer Guide/Developer Guide/Building/Releasing a new version.md new file mode 100644 index 0000000000..dc6793a025 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Building/Releasing a new version.md @@ -0,0 +1,19 @@ +# Releasing a new version +Releasing is mostly handled by the CI: + +* The version on GitHub is published automatically, including the description with the change log which is taken from the documentation. +* A PR is created automatically on the Winget repository to update to the new version. + +Releases are usually made directly from the `main` branch. For hot-fixes the process is the same but with a different branch, consult theĀ Branching strategyĀ for more information. + +The process is as follows: + +1. Edit theĀ DocumentationĀ to add a corresponding entry in the _Release notes_ section. +2. In the root `package.json`, set `version` to the new version to be released. +3. Run `chore:update-version` to automatically update the version of the rest of the `package.json` files. +4. Run `pnpm i` to update the package lock as well. +5. Commit the changes to the `package.json` files and the `package-lock.json`. The commit message is usually `chore(release): prepare for v1.2.3`. +6. Tag the newly created commit: `git tag v1.2.3` +7. Push the commit and the newly created tag: `git push; git push --tags`. +8. Wait for the CI to finish. +9. When the release is automatically created in GitHub, download it to make sure it works OK. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Building/Running a development build.md b/docs/Developer Guide/Developer Guide/Building/Running a development build.md new file mode 100644 index 0000000000..c69e19d50b --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Building/Running a development build.md @@ -0,0 +1,33 @@ +# Running a development build +First, follow theĀ Environment Setup. + +## Client + +The client is not meant to be run by itself, despite being described as an app. See the documentation on the server instead. + +## Server + +* To run the server in development mode, run `server:start`. The dev port is `8080`. +* To run the server in production mode (with its own copy of the assets), run `server:start-prod`. +* To build for Docker, seeĀ Docker. + +To run with a custom port, change the `TRILIUM_PORT` environment variable from the `package.json`. + +## Desktop + +* To run in development mode, use `pnpm desktop:start`. +* To run in production mode, use `pnpm desktop:start-prod`. + +## Safe mode + +Safe mode is off by default, to enable it temporarily on a Unix shell, prepend the environment variable setting: + +``` +pnpm cross-env TRILIUM_SAFE_MODE=1 pnpm server:start +``` + +## Running on NixOS + +When doing development, the Electron binary retrieved from NPM is not going to be compatible with NixOS, resulting in errors when trying to run it. However Trilium handles it automatically when running `pnpm desktop:start`. + +If there's no `electron` the system path it will attempt to use `nix-shell` to obtain it. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Backlinks.md b/docs/Developer Guide/Developer Guide/Concepts/Backlinks.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Backlinks.md rename to docs/Developer Guide/Developer Guide/Concepts/Backlinks.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Branch prefixes.md b/docs/Developer Guide/Developer Guide/Concepts/Branch prefixes.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Branch prefixes.md rename to docs/Developer Guide/Developer Guide/Concepts/Branch prefixes.md diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/CI/1_Main_image.png b/docs/Developer Guide/Developer Guide/Concepts/CI/1_Main_image.png similarity index 100% rename from docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/CI/1_Main_image.png rename to docs/Developer Guide/Developer Guide/Concepts/CI/1_Main_image.png diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/CI/Main.md b/docs/Developer Guide/Developer Guide/Concepts/CI/Main.md similarity index 83% rename from docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/CI/Main.md rename to docs/Developer Guide/Developer Guide/Concepts/CI/Main.md index c7d6320ae6..cae0613aff 100644 --- a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/CI/Main.md +++ b/docs/Developer Guide/Developer Guide/Concepts/CI/Main.md @@ -2,7 +2,7 @@ The main workflow of the CI: * Builds the Docker image and publishes in the GitHub Docker registry. -* Builds using a portion of the [delivery script](../../Build%20deliveries%20locally.md) artifacts for the following platforms: +* Builds using a portion of the [delivery script](../../Building/Build%20deliveries%20locally.md) artifacts for the following platforms: * Windows `x86_64` as .zip file * Windows `x86_64` installer (using Squirrel) * macOS `x86_64` and `aarch64`. @@ -13,7 +13,7 @@ The main workflow of the CI runs on `develop` branches as well as any branch tha ## Downloading the artifacts from the main branch -Simply go to the [`develop` branch on GitHub](https://github.com/TriliumNext/Notes) and look at the commit bar: +Simply go to the [`develop` branch on GitHub](https://github.com/TriliumNext/Trilium) and look at the commit bar:
    diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/CI/Main_image.png b/docs/Developer Guide/Developer Guide/Concepts/CI/Main_image.png similarity index 100% rename from docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/CI/Main_image.png rename to docs/Developer Guide/Developer Guide/Concepts/CI/Main_image.png diff --git a/docs/Developer Guide/Developer Guide/Concepts/Cache.md b/docs/Developer Guide/Developer Guide/Concepts/Cache.md new file mode 100644 index 0000000000..91a6f8b6d3 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Cache.md @@ -0,0 +1,111 @@ +# Cache +### Three-Layer Cache System + +Trilium implements a sophisticated **three-tier caching system** to optimize performance and enable offline functionality: + +#### 1\. Becca (Backend Cache) + +Located at: `apps/server/src/becca/` + +```typescript +// Becca caches all entities in memory +class Becca { + notes: Record + branches: Record + attributes: Record + attachments: Record + // ... other entity collections +} +``` + +**Responsibilities:** + +* Server-side entity cache +* Maintains complete note tree in memory +* Handles entity relationships and integrity +* Provides fast lookups without database queries +* Manages entity lifecycle (create, update, delete) + +**Key Files:** + +* `becca.ts` - Main cache instance +* `becca_loader.ts` - Loads entities from database +* `becca_service.ts` - Cache management operations +* `entities/` - Entity classes (BNote, BBranch, etc.) + +#### 2\. Froca (Frontend Cache) + +Located at: `apps/client/src/services/froca.ts` + +```typescript +// Froca is a read-only mirror of backend data +class Froca { + notes: Record + branches: Record + attributes: Record + // ... other entity collections +} +``` + +**Responsibilities:** + +* Frontend read-only cache +* Lazy loading of note tree +* Minimizes API calls +* Enables fast UI rendering +* Synchronizes with backend via WebSocket + +**Loading Strategy:** + +* Initial load: root notes and immediate children +* Lazy load: notes loaded when accessed +* When note is loaded, all parent and child branches load +* Deleted entities tracked via missing branches + +#### 3\. Shaca (Share Cache) + +Located at: `apps/server/src/share/` + +**Responsibilities:** + +* Optimized cache for shared/published notes +* Handles public note access without authentication +* Performance-optimized for high-traffic scenarios +* Separate from main Becca to isolate concerns + +### Cache Invalidation + +**Server-Side:** + +* Entities automatically update cache on save +* WebSocket broadcasts changes to all clients +* Synchronization updates trigger cache refresh + +**Client-Side:** + +* WebSocket listeners update Froca +* Manual reload via `froca.loadSubTree(noteId)` +* Full reload on protected session changes + +### Cache Consistency + +**Entity Change Tracking:** + +```typescript +// Every entity modification tracked +entity_changes ( + entityName: 'notes', + entityId: 'note123', + hash: 'abc...', + changeId: 'change456', + utcDateChanged: '2025-11-02...' +) +``` + +**Sync Protocol:** + +1. Client requests changes since last sync +2. Server returns entity\_changes records +3. Client applies changes to Froca +4. Client sends local changes to server +5. Server updates Becca and database \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Deleted notes.md b/docs/Developer Guide/Developer Guide/Concepts/Deleted notes.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Deleted notes.md rename to docs/Developer Guide/Developer Guide/Concepts/Deleted notes.md diff --git a/docs/Developer Guide/Developer Guide/Concepts/Demo document.md b/docs/Developer Guide/Developer Guide/Concepts/Demo document.md new file mode 100644 index 0000000000..90429bdb18 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Demo document.md @@ -0,0 +1,22 @@ +# Demo document +The demo document is an exported .zip that resides in `apps/server/src/assets/db/demo.zip`. + +During on-boarding, if the user selects that they are a new user then the `demo.zip` is imported into the root note. + +## Modifying the document + +1. In the Git root, run `pnpm edit-docs:edit-demo`. +2. Wait for the desktop application to show up with the docs. +3. Simply make the needed modifications. +4. Wait for a few seconds for the change to be processed in the background. +5. Commit the change in Git. + +## Testing the changes + +1. Run: + + ``` + rm -r data + pnpm server:start + ``` +2. And then do the on-boarding again. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Concepts/Entities.md b/docs/Developer Guide/Developer Guide/Concepts/Entities.md new file mode 100644 index 0000000000..faac90af75 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Entities.md @@ -0,0 +1,109 @@ +# Entities +### Entity System + +Trilium's data model is based on five core entities: + +``` +graph TD + Note[Note
    BNote] + Branch[Branch
    BBranch] + Attribute[Attribute
    BAttribute] + Revision[Revision
    BRevision] + Attachment[Attachment
    BAttachment] + + Note -->|linked by| Branch + Note -.->|metadata| Attribute + Branch -->|creates| Revision + Note -->|has| Attachment + + style Note fill:#e1f5ff + style Branch fill:#fff4e1 + style Attribute fill:#ffe1f5 + style Revision fill:#f5ffe1 + style Attachment fill:#ffe1e1 +``` + +#### Entity Definitions + +**1\. BNote** (`apps/server/src/becca/entities/bnote.ts`) + +* Represents a note with title, content, and metadata +* Type can be: text, code, file, image, canvas, mermaid, etc. +* Contains content via blob reference +* Can be protected (encrypted) +* Has creation and modification timestamps + +**2\. BBranch** (`apps/server/src/becca/entities/bbranch.ts`) + +* Represents parent-child relationship between notes +* Enables note cloning (multiple parents) +* Contains positioning information +* Has optional prefix for customization +* Tracks expansion state in tree + +**3\. BAttribute** (`apps/server/src/becca/entities/battribute.ts`) + +* Key-value metadata attached to notes +* Two types: labels (tags) and relations (links) +* Can be inheritable to child notes +* Used for search, organization, and scripting +* Supports promoted attributes (displayed prominently) + +**4\. BRevision** (`apps/server/src/becca/entities/brevision.ts`) + +* Stores historical versions of note content +* Automatic versioning on edits +* Retains title, type, and content +* Enables note history browsing and restoration + +**5\. BAttachment** (`apps/server/src/becca/entities/battachment.ts`) + +* File attachments linked to notes +* Has owner (note), role, and mime type +* Content stored in blobs +* Can be protected (encrypted) + +**6\. BBlob** (`apps/server/src/becca/entities/bblob.ts`) + +* Binary large object storage +* Stores actual note content and attachments +* Referenced by notes, revisions, and attachments +* Supports encryption for protected content + +### Widget-Based UI + +The frontend uses a **widget system** for modular, reusable UI components. + +Located at: `apps/client/src/widgets/` + +```typescript +// Widget Hierarchy +BasicWidget +ā”œā”€ā”€ NoteContextAwareWidget (responds to note changes) +│ ā”œā”€ā”€ RightPanelWidget (displayed in right sidebar) +│ └── Type-specific widgets +ā”œā”€ā”€ Container widgets (tabs, ribbons, etc.) +└── Specialized widgets (search, calendar, etc.) +``` + +**Base Classes:** + +1. **BasicWidget** (`basic_widget.ts`) + * Base class for all UI components + * Lifecycle: construction → rendering → events → destruction + * Handles DOM manipulation + * Event subscription management + * Child widget management +2. **NoteContextAwareWidget** (`note_context_aware_widget.ts`) + * Extends BasicWidget + * Automatically updates when active note changes + * Accesses current note context + * Used for note-dependent UI +3. **RightPanelWidget** + * Widgets displayed in right sidebar + * Collapsible sections + * Context-specific tools and information + +**Type-Specific Widgets:** + +Each note type has a dedicated widget, which are located in `apps/client/src/widgets/type_widgets`. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Hidden notes.md b/docs/Developer Guide/Developer Guide/Concepts/Hidden notes.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Hidden notes.md rename to docs/Developer Guide/Developer Guide/Concepts/Hidden notes.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons.md b/docs/Developer Guide/Developer Guide/Concepts/Icons.md similarity index 59% rename from docs/Developer Guide/Developer Guide/Development and architecture/Icons.md rename to docs/Developer Guide/Developer Guide/Concepts/Icons.md index 791e26f6ce..826ebc9bb5 100644 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Icons.md +++ b/docs/Developer Guide/Developer Guide/Concepts/Icons.md @@ -21,7 +21,7 @@ These are stored in `images`: ## App icons -
    NameResolutionDescription
    ios/apple-touch-icon.png180x180Used as apple-touch-icon, but only in login.ejs and set_password.ejs for some reason.
    mac/icon.icns512x512Provided as --icon to electron-packager for mac-arm64 and mac-x64 builds.
    png/128x128.png128x128Used in linux-x64 build, to provide an icon.png.
    png/256x256-dev.png256x256Used by the Electron window icon, if in dev mode.
    png/256x256.pngUsed by the Electron window icon, if not in dev mode.
    win/icon.ico
    • ICO 16x16
    • ICO 32x32
    • ICO 48x48
    • ICO 64x64
    • ICO 128x128
    • PNG 256x256
    • Used by the win-x64 build.
    • Used by Squirrel Windows installer for: setup icon, app icon, control panel icon
    • Used as the favicon.
    win/setup-banner.gif640x480Used by the Squirrel Windows installer during the installation process. Has only one frame.
    +
    NameResolutionDescription
    ios/apple-touch-icon.png180x180Used as apple-touch-icon, but only in login.ejs and set_password.ejs for some reason.
    mac/icon.icns512x512Provided as --icon to electron-packager for mac-arm64 and mac-x64 builds.
    png/128x128.png128x128Used in linux-x64 build, to provide an icon.png.
    png/256x256-dev.png256x256Used by the Electron window icon, if in dev mode.
    png/256x256.pngUsed by the Electron window icon, if not in dev mode.
    win/icon.ico
    • ICO 16x16
    • ICO 32x32
    • ICO 48x48
    • ICO 64x64
    • ICO 128x128
    • PNG 256x256
    • Used by the win-x64 build.
    • Used by Squirrel Windows installer for: setup icon, app icon, control panel icon
    • Used as the favicon.
    win/setup-banner.gif640x480Used by the Squirrel Windows installer during the installation process. Has only one frame.
    ## Additional locations where the branding is used diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Internationalisation Translat.md b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translat.md similarity index 91% rename from docs/Developer Guide/Developer Guide/Development and architecture/Internationalisation Translat.md rename to docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translat.md index 7ae59016fc..f420ff7ada 100644 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Internationalisation Translat.md +++ b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translat.md @@ -27,11 +27,7 @@ Follow theĀ Adding a new locale. ### Changing the language diff --git a/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/Adding a new locale.md b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/Adding a new locale.md new file mode 100644 index 0000000000..0d73a1c0eb --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/Adding a new locale.md @@ -0,0 +1,12 @@ +# Adding a new locale +Once the Weblate translations for a single language have reached ~50% in coverage, it's time to add it to the application. + +To do so: + +1. In `packages/commons` look for `i18n.ts` and add a new entry to `UNSORTED_LOCALES` for the language. +2. In `packages/commons` look for `dayjs.ts` and add a mapping for the new language in `DAYJS_LOADER`. Sort the entire list. +3. In `apps/client`, look for `collections/calendar/index.tsx` and modify `LOCALE_MAPPINGS` to add support to the new language. +4. In `apps/client`, look for `widgets/type_widgets/canvas/i18n.ts` and modify `LANGUAGE_MAPPINGS`. A unit test ensures that the language is actually loadable. +5. In `apps/client`, look for `widgets/type_widgets/MindMap.tsx` and modify `LOCALE_MAPPINGS`. The type definitions should already validate if the new value is supported by Mind Elixir. +6. In `packages/ckeditor5`, look for `i18n.ts` and modify `LOCALE_MAPPINGS`. The import validation should already check if the new value is supported by CKEditor, and there's also a test to ensure it. +7. Locale mappings for PDF.js might need adjustment. To do so, in `packages/pdfjs-viewer/scripts/build.ts` there is `LOCALE_MAPPINGS`. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Internationalisation Translations/Guidelines.md b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/Guidelines.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Internationalisation Translations/Guidelines.md rename to docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/Guidelines.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Internationalisation Translations/Server translations.md b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/Server translations.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Internationalisation Translations/Server translations.md rename to docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/Server translations.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Internationalisation Translations/i18n-ally.md b/docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/i18n-ally.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Internationalisation Translations/i18n-ally.md rename to docs/Developer Guide/Developer Guide/Concepts/Internationalisation Translations/i18n-ally.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Launchers.md b/docs/Developer Guide/Developer Guide/Concepts/Launchers.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Launchers.md rename to docs/Developer Guide/Developer Guide/Concepts/Launchers.md diff --git a/docs/Developer Guide/Developer Guide/Concepts/Note Revisions.md b/docs/Developer Guide/Developer Guide/Concepts/Note Revisions.md new file mode 100644 index 0000000000..7624b1d78e --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Note Revisions.md @@ -0,0 +1,2 @@ +# Note Revisions +The revision API on the server side is managed by `apps/server/src/routes/api/revisions.ts` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/Copy image reference to the cl.md b/docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/Copy image reference to the cl.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/Copy image reference to the cl.md rename to docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/Copy image reference to the cl.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/Export diagram as SVG.md b/docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/Export diagram as SVG.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/Export diagram as SVG.md rename to docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/Export diagram as SVG.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/First steps.md b/docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/First steps.md similarity index 95% rename from docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/First steps.md rename to docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/First steps.md index f60138817f..fa860fe591 100644 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/First steps.md +++ b/docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/First steps.md @@ -41,7 +41,7 @@ Go to `src/becca/entities/rows.ts` and add the new note type to `ALLOWED_NOTE_TY ## Final steps -* Update theĀ Demo documentĀ to showcase the new note type. +* Update theĀ Demo documentĀ to showcase the new note type. ## Troubleshooting diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/First steps/mind_map.js b/docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/First steps/mind_map.js similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/First steps/mind_map.js rename to docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/First steps/mind_map.js diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/Loading data.md b/docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/Loading data.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/Loading data.md rename to docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/Loading data.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/Note type checklist.md b/docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/Note type checklist.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/Note type checklist.md rename to docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/Note type checklist.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/SVG rendering.md b/docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/SVG rendering.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/SVG rendering.md rename to docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/SVG rendering.md diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/Saving data via spaced update.md b/docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/Saving data via spaced update.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Adding a new note type/Saving data via spaced update.md rename to docs/Developer Guide/Developer Guide/Concepts/Note Types/Adding a new note type/Saving data via spaced update.md diff --git a/docs/Developer Guide/Developer Guide/Concepts/Options.md b/docs/Developer Guide/Developer Guide/Concepts/Options.md new file mode 100644 index 0000000000..ce0d348f53 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Options.md @@ -0,0 +1,43 @@ +# Options +## Read an option + +Add the import to the service (make sure the relative path is correct): + +```javascript +import options from "../../services/options.js"; +``` + +Them simply read the option: + +```javascript +this.firstDayOfWeek = options.getInt("firstDayOfWeek"); +``` + +## Adding new options + +### Checkbox option + +Refer to this example in `backup.tsx`: + +```javascript +export function AutomaticBackup() { + const [ dailyBackupEnabled, setDailyBackupEnabled ] = useTriliumOptionBool("dailyBackupEnabled"); + + return ( + + + + + + {t("backup.backup_recommendation")} + + ) +} +``` + +> [!TIP] +> To trigger a UI refresh (e.g. `utils#reloadFrontendApp`), simply pass a `true` as the second argument to `useTriliumOption` methods. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Options/Creating a new option.md b/docs/Developer Guide/Developer Guide/Concepts/Options/Creating a new option.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Options/Creating a new option.md rename to docs/Developer Guide/Developer Guide/Concepts/Options/Creating a new option.md diff --git a/docs/Developer Guide/Developer Guide/Concepts/Printing and exporting to PDF.md b/docs/Developer Guide/Developer Guide/Concepts/Printing and exporting to PDF.md new file mode 100644 index 0000000000..ad057206bb --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Printing and exporting to PDF.md @@ -0,0 +1,18 @@ +# Printing and exporting to PDF +Note printing is handled by `note_detail.js`, in the `printActiveNoteEvent` method. Exporting to PDF works similarly. + +## How it works + +Both printing and exporting as PDF use the same mechanism: a note is rendered individually in a separate webpage that is then sent to the browser or the Electron application either for printing or exporting as PDF. + +The webpage that renders a single note can actually be accessed in a web browser. For example `http://localhost:8080/#root/WWRGzqHUfRln/RRZsE9Al8AIZ?ntxId=0o4fzk` becomes `http://localhost:8080/?print#root/WWRGzqHUfRln/RRZsE9Al8AIZ`. + +Accessing the print note in a web browser allows for easy debugging to understand why a particular note doesn't render well. The mechanism for rendering is similar to the one used inĀ Note List. + +## Syntax highlighting + +Syntax highlighting for code blocks is supported as well: + +* It works by injecting a Highlight.js stylesheet into the print. +* The theme used is hard-coded (the _Visual Studio Light theme_, at the time of writing) in order not to have a dark background in print. +* Syntax highlightingĀ is handled by the content renderer. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Concepts/Protected entities.md b/docs/Developer Guide/Developer Guide/Concepts/Protected entities.md new file mode 100644 index 0000000000..31d5250c0d --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Protected entities.md @@ -0,0 +1,6 @@ +# Protected entities +The following entities can be made protected, via their `isProtected` flag: + +* attachments +* notes +* revisions \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Concepts/Share.md b/docs/Developer Guide/Developer Guide/Concepts/Share.md new file mode 100644 index 0000000000..22dc512f58 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Share.md @@ -0,0 +1,30 @@ +# Share +## Share theme + +The share theme represents the layout, styles and scripts behind the Share notes functionality. The current implementation is a heavy adaptation of [trilium.rocks](https://trilium.rocks/) which is a third-party share theme. + +* The theme resides in `packages/share-theme`. +* The HTML is defined in `src/templates` using EJS templating. +* The `src/scripts` and `src/styles` subdirectories house the rest of the theme. + +## Building the share theme + +* In `packages/share-theme`, run `pnpm build` to trigger a build. This will generate `dist` which will then be used by the server. +* Alternatively, use `pnpm dev` to watch for changes. + +## Integration with the server for the share functionality + +The server renders the templates using EJS templating from the share theme and hosts the assets. + +* In dev mode, the templates and assets are served directly from `packages/share-theme/dist`. + * Modifications to the assets (scripts or styles) will reflect without having to restart the server. However the share theme needs to be built first (see previous section). + * Changes to the template will require a restart of the server, since they are cached. Simply press Enter in the console with `pnpm server:start` to quickly trigger a restart. +* In production mode, the share theme is automatically built by the server build script and copied to `dist/share-theme`. + +The server route handling this functionality is in `src/share/routes.ts`. + +## Exporting to static HTML files + +This functionality is also handled by the server, but in `src/services/export/zip/share_theme` instead. It works quite similar to the normal sharing functionality, but it uses `BNote` instead of `SNote` (and so on for other entity types), in order to work regardless of whether a note is shared or not. + +The same templates are used and rendered by the server, except that they are stored in a file instead of served to web clients. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Concepts/Synchronisation.md b/docs/Developer Guide/Developer Guide/Concepts/Synchronisation.md new file mode 100644 index 0000000000..45a520cb68 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Synchronisation.md @@ -0,0 +1,484 @@ +# Synchronisation +Trilium implements a **bidirectional synchronization system** that allows users to sync their note databases across multiple devices (desktop clients and server instances). The sync protocol is designed to handle: + +* Concurrent modifications across devices +* Simple conflict resolution (without ā€œmerge conflictā€ indication). +* Partial sync (only changed entities) +* Protected note synchronization +* Efficient bandwidth usage + +## Sync Architecture + +``` +graph TB + Desktop1[Desktop 1
    Client] + Desktop2[Desktop 2
    Client] + + subgraph SyncServer["Sync Server"] + SyncService[Sync Service
    - Entity Change Management
    - Conflict Resolution
    - Version Tracking] + SyncDB[(Database
    entity_changes)] + end + + Desktop1 <-->|WebSocket/HTTP| SyncService + Desktop2 <-->|WebSocket/HTTP| SyncService + SyncService --> SyncDB +``` + +## Core Concepts + +### Entity Changes + +Every modification to any entity (note, branch, attribute, etc.) creates an **entity change** record: + +``` +entity_changes ( + id, -- Auto-increment ID + entityName, -- 'notes', 'branches', 'attributes', etc. + entityId, -- ID of the changed entity + hash, -- Content hash for integrity + isErased, -- If entity was erased (deleted permanently) + changeId, -- Unique change identifier + componentId, -- Unique component/widget identifier + instanceId, -- Process instance identifier + isSynced, -- Whether synced to server + utcDateChanged -- When change occurred +) +``` + +**Key Properties:** + +* **changeId**: Globally unique identifier (UUID) for the change +* **componentId**: Unique identifier of the component/widget that generated to change (can be used to avoid refreshing the widget being edited). +* **instanceId**: Unique per process (changes on restart) +* **hash**: SHA-256 hash of entity data for integrity verification + +### Sync Versions + +Each Trilium installation tracks: + +* **Local sync version**: Highest change ID seen locally +* **Server sync version**: Highest change ID on server +* **Entity versions**: Last sync version for each entity type + +### Change Tracking + +**When an entity is modified:** + +```typescript +// apps/server/src/services/entity_changes.ts +function addEntityChange(entityName, entityId, entity) { + const hash = calculateHash(entity) + const changeId = generateUUID() + + sql.insert('entity_changes', { + entityName, + entityId, + hash, + changeId, + componentId: config.componentId, + instanceId: config.instanceId, + isSynced: 0, + utcDateChanged: now() + }) +} +``` + +**Entity modification triggers:** + +* Note content update +* Note metadata change +* Branch creation/deletion/reorder +* Attribute addition/removal +* Options modification + +## Sync Protocol + +### Sync Handshake + +**Step 1: Client Initiates Sync** + +```typescript +// Client sends current sync version +POST /api/sync/check +{ + "sourceId": "client-component-id", + "maxChangeId": 12345 +} +``` + +**Step 2: Server Responds with Status** + +```typescript +// Server checks for changes +Response: +{ + "entityChanges": 567, // Changes on server + "maxChangeId": 12890, // Server's max change ID + "outstandingPushCount": 23 // Client changes not yet synced +} +``` + +**Step 3: Decision** + +* If `entityChanges > 0`: Pull changes from server +* If `outstandingPushCount > 0`: Push changes to server +* Both can happen in sequence + +### Pull Sync (Server → Client) + +**Client Requests Changes:** + +```typescript +POST /api/sync/pull +{ + "sourceId": "client-component-id", + "lastSyncedChangeId": 12345 +} +``` + +**Server Responds:** + +```typescript +Response: +{ + "notes": [ + { noteId: "abc", title: "New Note", ... } + ], + "branches": [...], + "attributes": [...], + "revisions": [...], + "attachments": [...], + "entityChanges": [ + { entityName: "notes", entityId: "abc", changeId: "...", ... } + ], + "maxChangeId": 12890 +} +``` + +**Client Processing:** + +1. Apply entity changes to local database +2. Update Froca cache +3. Update local sync version +4. Trigger UI refresh + +### Push Sync (Client → Server) + +**Client Sends Changes:** + +```typescript +POST /api/sync/push +{ + "sourceId": "client-component-id", + "entities": [ + { + "entity": { + "noteId": "xyz", + "title": "Modified Note", + ... + }, + "entityChange": { + "changeId": "change-uuid", + "entityName": "notes", + ... + } + } + ] +} +``` + +**Server Processing:** + +1. Validate changes +2. Check for conflicts +3. Apply changes to database +4. Update Becca cache +5. Mark as synced +6. Broadcast to other connected clients via WebSocket + +**Conflict Detection:** + +```typescript +// Check if entity was modified on server since client's last sync +const serverEntity = becca.getNote(noteId) +const serverLastModified = serverEntity.utcDateModified + +if (serverLastModified > clientSyncVersion) { + // CONFLICT! + resolveConflict(serverEntity, clientEntity) +} +``` + +## Conflict Resolution + +### Conflict Types + +**1\. Content Conflict** + +* Both client and server modified same note content +* **Resolution**: Last-write-wins based on `utcDateModified` + +**2\. Structure Conflict** + +* Branch moved/deleted on one side, modified on other +* **Resolution**: Tombstone records, reconciliation + +**3\. Attribute Conflict** + +* Same attribute modified differently +* **Resolution**: Last-write-wins + +### Conflict Resolution Strategy + +**Last-Write-Wins:** + +```typescript +if (clientEntity.utcDateModified > serverEntity.utcDateModified) { + // Client wins, apply client changes + applyClientChange(clientEntity) +} else { + // Server wins, reject client change + // Client will pull server version on next sync +} +``` + +**Tombstone Records:** + +* Deleted entities leave tombstone in `entity_changes` +* Prevents re-sync of deleted items +* `isErased = 1` for permanent deletions + +### Protected Notes Sync + +**Challenge:** Encrypted content can't be synced without password + +**Solution:** + +1. **Encrypted sync**: Content synced in encrypted form +2. **Hash verification**: Integrity checked without decryption +3. **Lazy decryption**: Only decrypt when accessed + +## Sync States + +### Connection States + +* **Connected**: WebSocket connection active +* **Disconnected**: No connection to sync server +* **Syncing**: Actively transferring data +* **Conflict**: Sync paused due to conflict + +### Entity Sync States + +Each entity can be in: + +* **Synced**: In sync with server +* **Pending**: Local changes not yet pushed +* **Conflict**: Conflicting changes detected + +### UI Indicators + +```typescript +// apps/client/src/widgets/sync_status.ts +class SyncStatusWidget { + showSyncStatus() { + if (isConnected && allSynced) { + showIcon('synced') + } else if (isSyncing) { + showIcon('syncing-spinner') + } else { + showIcon('not-synced') + } + } +} +``` + +## Performance Optimizations + +### Incremental Sync + +Only entities changed since last sync are transferred: + +``` +SELECT * FROM entity_changes +WHERE id > :lastSyncedChangeId +ORDER BY id ASC +LIMIT 1000 +``` + +### Batch Processing + +Changes sent in batches to reduce round trips: + +```typescript +const BATCH_SIZE = 1000 +const changes = getUnsyncedChanges(BATCH_SIZE) +await syncBatch(changes) +``` + +### Hash-Based Change Detection + +```typescript +// Only sync if hash differs +const localHash = calculateHash(localEntity) +const serverHash = getServerHash(entityId) + +if (localHash !== serverHash) { + syncEntity(localEntity) +} +``` + +### Compression + +Large payloads compressed before transmission: + +```typescript +// Server sends compressed response +res.setHeader('Content-Encoding', 'gzip') +res.send(gzip(syncData)) +``` + +## Error Handling + +### Network Errors + +Reported to the user and the sync will be retried after the interval passes. + +### Sync Integrity Checks + +**Hash Verification:** + +```typescript +// Verify entity hash matches +const calculatedHash = calculateHash(entity) +const receivedHash = entityChange.hash + +if (calculatedHash !== receivedHash) { + throw new Error('Hash mismatch - data corruption detected') +} +``` + +**Consistency Checks:** + +* Orphaned branches detection +* Missing parent notes +* Invalid entity references +* Circular dependencies + +## Sync Server Configuration + +### Server Setup + +**Required Options:** + +```javascript +{ + "syncServerHost": "https://sync.example.com", + "syncServerTimeout": 60000, + "syncProxy": "" // Optional HTTP proxy +} +``` + +**Authentication:** + +* Username/password or +* Sync token (generated on server) + +## Sync API Endpoints + +Located at: `apps/server/src/routes/api/sync.ts` + +## WebSocket Sync Updates + +Real-time sync via WebSocket: + +```typescript +// Server broadcasts change to all connected clients +ws.broadcast('frontend-update', { + lastSyncedPush, + entityChanges +}) + +// Client receives and processed the information. +``` + +## Sync Scheduling + +### Automatic Sync + +**Desktop:** + +* Sync on startup +* Periodic sync (configurable interval, default: 60s) + +**Server:** + +* Sync on entity modification +* WebSocket push to connected clients + +### Manual Sync + +User can trigger: + +* Full sync +* Sync now +* Sync specific subtree + +## Troubleshooting + +### Common Issues + +**Sync stuck:** + +``` +-- Reset sync state +UPDATE entity_changes SET isSynced = 0; +DELETE FROM options WHERE name LIKE 'sync%'; +``` + +**Hash mismatch:** + +* Data corruption detected +* Re-sync from backup +* Check database integrity + +**Conflict loop:** + +* Manual intervention required +* Export conflicting notes +* Choose winning version +* Re-sync + +## Security Considerations + +### Encrypted Sync + +* Protected notes synced encrypted +* No plain text over network +* Server cannot read protected content + +### Authentication + +* Username/password over HTTPS only +* Sync tokens for token-based auth +* Session cookies with CSRF protection + +### Authorization + +* Users can only sync their own data +* No cross-user sync support +* Sync server validates ownership + +## Performance Metrics + +**Typical Sync Performance:** + +* 1000 changes: ~2-5 seconds +* 10000 changes: ~20-50 seconds +* Initial full sync (100k notes): ~5-10 minutes + +**Factors:** + +* Network latency +* Database size +* Number of protected notes +* Attachment sizes \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Synchronisation/Content hashing.md b/docs/Developer Guide/Developer Guide/Concepts/Synchronisation/Content hashing.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Synchronisation/Content hashing.md rename to docs/Developer Guide/Developer Guide/Concepts/Synchronisation/Content hashing.md diff --git a/docs/Developer Guide/Developer Guide/Concepts/Syntax highlighting.md b/docs/Developer Guide/Developer Guide/Concepts/Syntax highlighting.md new file mode 100644 index 0000000000..841e6699d3 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Syntax highlighting.md @@ -0,0 +1,93 @@ +# Syntax highlighting +## Defining the MIME type + +The first step to supporting a new language for either code blocks or code notes is to define the MIME type. Go to `mime_type.ts` in `packages/commons` and add a corresponding entry: + +``` +{ title: "ABAP (SAP)", mime: "text/x-abap", mdLanguageCode: "abap" } +``` + +Where `mdLanguageCode` is a Markdown-friendly name of the language. + +## Syntax highlighting for Highlight.js + +The Highlight.js instance in Trilium identifies the code to highlight by the mime type mappings defined in `syntax_highlighting.ts` in `packages/highlightjs`. + +There are three possible cases, all involving modifying the `byMimeType` record: + +### Highlight.js built-in languages: + +Simply add a corresponding entry: + +``` +"application/dart": () => import("highlight.js/lib/languages/dart"), +``` + +### External modules from NPM + +1. Install the module as a dependency in `packages/highlight.js` +2. Import: + + ``` + "application/x-cypher-query": () => import("highlightjs-cypher") + ``` +3. Do this if the npm module is relatively new and it has TypeScript mappings, if not see the last option. + +### Modules integrated directly into Trilium + +* Allows making small modifications if needed (especially if the module is old). +* Works well for modules missing type definitions, since types are added directly in code. + +Steps: + +1. Copy the syntax highlighting file ([example](https://github.com/highlightjs/highlightjs-sap-abap/blob/main/src/abap.js)) into `packages/highlightjs/src/languages/[code].ts`. +2. Add a link in a comment at the top of the file linking to the original source code. +3. Replace `module.exports =` by `export default`. +4. Add types to the method: + + ``` + import { HLJSApi, Language } from "highlight.js"; + + export default function (hljs: HLJSApi): Language { + // [...] + } + ``` +5. Remove any module loading mechanism or shims outside the main highlight function. +6. Modify `syntax_highlighting.js` to support the new language: + + ``` + "text/x-abap": () => import("./languages/abap.js"), + ``` + +## Syntax highlighting for CodeMirror + +> [!NOTE] +> Newer versions of Trilium use CodeMirror 6, so the plugin must be compatible with this version. + +### Adding the MIME type mapping + +Similar to Highlight.js, the mappings for each MIME type are handled in `syntax_highlighting.ts` in `packages/codemirror`, by modifying the `byMimeType` record. + +1. Official modules: + + ``` + async () => (await import('@codemirror/lang-html')).html(), + ``` +2. Legacy modules (ported from CodeMirror 5): + + ``` + "text/turtle": async () => (await import('@codemirror/legacy-modes/mode/turtle')).turtle,  + ``` +3. Modules integrated into Trilium: + + ``` + "application/x-bat": async () => (await import("./languages/batch.js")).batch, + ``` + +### Integrating existing modules + +* Add a comment at the beginning indicating the link to the original source code. +* Some imports might require updating: + * Instead of + `import { StreamParser, StringStream } from "@codemirror/stream-parser";`, use   + `import { StreamParser, StringStream } from "@codemirror/language";` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Themes.md b/docs/Developer Guide/Developer Guide/Concepts/Themes.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Themes.md rename to docs/Developer Guide/Developer Guide/Concepts/Themes.md diff --git a/docs/Developer Guide/Developer Guide/Concepts/Web Clipper.md b/docs/Developer Guide/Developer Guide/Concepts/Web Clipper.md new file mode 100644 index 0000000000..dc504658ea --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Concepts/Web Clipper.md @@ -0,0 +1,42 @@ +# Web Clipper +The Web Clipper is present in the monorepo in `apps/web-clipper`. It's based on [WXT](https://wxt.dev/guide/introduction.html), a framework for building web extensions that allows very easy development and publishing. + +## Manifest version + +Originally the Web Clipper supported only Manifest v2, which made the extension incompatible with Google Chrome. [#8494](https://github.com/TriliumNext/Trilium/pull/8494) introduces Manifest v3 support for Google Chrome, alongside with Manifest v2 for Firefox. + +Although Firefox does support Manifest v3, we are still using Manifest v2 for it because WXT dev mode doesn't work for the Firefox / Manifest v3 combination and there were some mentions about Manifest v3 not being well supported on Firefox Mobile (and we plan to have support for it). + +## Development + +WXT allows easy development of the plugin, with full TypeScript support and live reload. To enter dev mode: + +* Run `pnpm --filter web-clipper dev` to enter dev mode for Chrome (with manifest v3). +* Run `pnpm --filter web-clipper dev:firefox` to enter dev mode for Firefox (with manifest v2). + +This will open a separate browser instance in which the extension is automatically injected. + +> [!NOTE] +> On NixOS, the same development commands work just fine. Just make sure the browser is available in the system path: +> +> ```sh +> nix-shell -p chromium +> ``` + +## Default port + +The default port is: + +* `37742` if in development mode. This makes it possible to use `pnpm desktop:start` to spin up a desktop instance to use the Clipper with. +* `37840` in production, the default Trilium port. + +## Building + +* Run `build` (Chrome) or `build:firefox` to generate the output files, which will be in `.output/[browser]`. +* Run `zip` or `zip:firefox` to generate the ZIP files. + +## CI + +`.github/workflows/web-clipper.yml` handles the building of the web clipper. Whenever the web clipper is modified, it generates the ZIPs and uploads them as artifacts. + +There is currently no automatic publishing to the app stores. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Project Structure/CKEditor.md b/docs/Developer Guide/Developer Guide/Dependencies/CKEditor.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Project Structure/CKEditor.md rename to docs/Developer Guide/Developer Guide/Dependencies/CKEditor.md diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Differences from upstream.md b/docs/Developer Guide/Developer Guide/Dependencies/CKEditor/Differences from upstream.md similarity index 81% rename from docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Differences from upstream.md rename to docs/Developer Guide/Developer Guide/Dependencies/CKEditor/Differences from upstream.md index a5230d8f7f..d8e2db46bc 100644 --- a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Differences from upstream.md +++ b/docs/Developer Guide/Developer Guide/Dependencies/CKEditor/Differences from upstream.md @@ -1,5 +1,5 @@ # Differences from upstream -* Embeds [`~~isaul32/ckeditor5-math~~`](https://github.com/isaul32/ckeditor5-math)Ā  ckeditor5-math, which is a third-party plugin for adding math support. CKEditor itself also has a [math plugin](https://ckeditor.com/docs/ckeditor5/latest/features/math-equations.html) with MathType and ChemType but it's premium-only. +* Embeds [`~~isaul32/ckeditor5-math~~`](https://github.com/isaul32/ckeditor5-math)Ā  ckeditor5-math, which is a third-party plugin for adding math support. CKEditor itself also has a [math plugin](https://ckeditor.com/docs/ckeditor5/latest/features/math-equations.html) with MathType and ChemType but it's premium-only. * Zadam left a TODO in `findandreplaceUI`: `// FIXME: keyboard shortcut doesn't work:` [`https://github.com/ckeditor/ckeditor5/issues/10645`](https://github.com/ckeditor/ckeditor5/issues/10645) * `packages\ckeditor5-build-balloon-block\src\mention_customization.js` introduces note insertion via `@` character. diff --git a/docs/Developer Guide/Developer Guide/Project Structure/CKEditor/Plugin migration guide.md b/docs/Developer Guide/Developer Guide/Dependencies/CKEditor/Plugin migration guide.md similarity index 98% rename from docs/Developer Guide/Developer Guide/Project Structure/CKEditor/Plugin migration guide.md rename to docs/Developer Guide/Developer Guide/Dependencies/CKEditor/Plugin migration guide.md index 8b87f2721f..47a4b5e83a 100644 --- a/docs/Developer Guide/Developer Guide/Project Structure/CKEditor/Plugin migration guide.md +++ b/docs/Developer Guide/Developer Guide/Dependencies/CKEditor/Plugin migration guide.md @@ -34,7 +34,7 @@ In the newly copied package, go to `package.json` and edit: 2. In `peerDependencies`, change `ckeditor5` to the same version as from the previous step. 3. Similarly, update `vitest` dependencies to match the monorepo one. 4. Remove the `prepare` entry from the `scripts` section. -5. Change `build:dist` to simply `build` in order to integrate it with NX. +5. Change `build:dist` to simply `build`. 6. In `tsconfig.dist.json`, change `typings/types` to `../typings/types.d.ts` to be compatible with the latest TypeScript version. ## Step 4. Install missing dependencies and build errors diff --git a/docs/Developer Guide/Developer Guide/Dependencies/CKEditor/ckeditor5-math.md b/docs/Developer Guide/Developer Guide/Dependencies/CKEditor/ckeditor5-math.md new file mode 100644 index 0000000000..e47a59f125 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Dependencies/CKEditor/ckeditor5-math.md @@ -0,0 +1,16 @@ +# ckeditor5-math +
    ckeditor5-math in action.
    + +A fork of [isaul32/ckeditor5-math](https://github.com/isaul32/ckeditor5-math), which is the CKEditor5 plugin which adds the math functionality. We keep our own version to be able to use it on the latest version of CKEditor, alongside some custom improvements. + +## Development environment + +* Tested on Node.js 20. +* The package manager is yarn 1 (v1.22.22 is known to be working fine for it at the time of writing). + +Important commands: + +* To check if the code has any formatting issues: `yarn lint` +* To start a live preview: `yarn start` +* To run the tests: `yarn test` + * Note that this requires Chromium, on NixOS this can be achieved by running a `nix-shell -p chromium`, and running `CHROME_BIN=$(which chromium) yarn test` inside it. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math_image.png b/docs/Developer Guide/Developer Guide/Dependencies/CKEditor/ckeditor5-math_image.png similarity index 100% rename from docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math_image.png rename to docs/Developer Guide/Developer Guide/Dependencies/CKEditor/ckeditor5-math_image.png diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies.md b/docs/Developer Guide/Developer Guide/Dependencies/Per-dependency checks.md similarity index 96% rename from docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies.md rename to docs/Developer Guide/Developer Guide/Dependencies/Per-dependency checks.md index fb27cb6bf0..309042ffca 100644 --- a/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies.md +++ b/docs/Developer Guide/Developer Guide/Dependencies/Per-dependency checks.md @@ -1,2 +1,2 @@ -# Updating dependencies -
    DependencyName in library_loaderThings to check for a basic sanity check Protected by unit tests
    better-sqlite3 See bettersqlite binaries.  
    jsdom 
    • Note map
    • Clipper
    • Note similarity
    Protected by typings, should catch any potential changes in API.Yes
    async-mutex 
    • Sync
      
    axios 
    • Can't be directly tested, as it's exposed only via the backend script API.
      
    sax 
    • EverNote imports
      
    • ws
    • debounce
     
    • Check any action is reported from server to client (e.g. delete a note).
      
    ejs 
    • Onboarding / first setup
      
    dayjs 
    • Day notes
      
    semver 
    • Application should start.
      
    https-proxy-agent ???  
    sax 
    • EverNote import
      
    ini 
    • Affects config, generally if the application starts then it should be OK.
      
    jsplumbRELATION_MAP
    • Relation map note type
      
    jquery.mark.es6MARKJS
    • In search, when highlighting the text that matched.
    • In search in HTML, which might not actually be used since it seems to have been replaced by CKEditor's own find & replace dialog.
      
    knockout.js 
    • Used in rendering the login and main layout of the application.
      
    normalize.min.css 
    • Used in shared notes.
      
    wheel-zoom.min.jsWHEEL_ZOOM
    • When opening a image that is in attachment.
    • When opening a stand-alone image note.
    • When zooming in a mermaid chart.
      
    fancytree 
    • The note tree should be fully functional.
      
    bootstrap 
    • Check mostly the on-boarding pages, when there is no database.
      
    electron-debug 
    • Run electron using npm run start-electron and check that the debug hotkeys are still working (Ctrl+Shift+I on Windows/Linux, Cmd+Alt+I for dev tools, Cmd/Ctrl+R for reload).
      
    electron-dl    
    eslint    
    marked 
    • Importing a markdown note.
     Yes
    force-graph 
    • Note map
      
    \ No newline at end of file +# Per-dependency checks +
    DependencyName in library_loaderThings to check for a basic sanity check Protected by unit tests
    better-sqlite3 See bettersqlite binaries.  
    jsdom 
    • Note map
    • Clipper
    • Note similarity
    Protected by typings, should catch any potential changes in API.Yes
    async-mutex 
    • Sync
      
    axios 
    • Can't be directly tested, as it's exposed only via the backend script API.
      
    sax 
    • EverNote imports
      
    • ws
    • debounce
     
    • Check any action is reported from server to client (e.g. delete a note).
      
    ejs 
    • Onboarding / first setup
      
    dayjs 
    • Day notes
      
    semver 
    • Application should start.
      
    https-proxy-agent ???  
    sax 
    • EverNote import
      
    ini 
    • Affects config, generally if the application starts then it should be OK.
      
    jsplumbRELATION_MAP
    • Relation map note type
      
    jquery.mark.es6MARKJS
    • In search, when highlighting the text that matched.
    • In search in HTML, which might not actually be used since it seems to have been replaced by CKEditor's own find & replace dialog.
      
    knockout.js 
    • Used in rendering the login and main layout of the application.
      
    normalize.min.css 
    • Used in shared notes.
      
    wheel-zoom.min.jsWHEEL_ZOOM
    • When opening a image that is in attachment.
    • When opening a stand-alone image note.
    • When zooming in a mermaid chart.
      
    fancytree 
    • The note tree should be fully functional.
      
    bootstrap 
    • Check mostly the on-boarding pages, when there is no database.
      
    electron-debug 
    • Run electron using npm run start-electron and check that the debug hotkeys are still working (Ctrl+Shift+I on Windows/Linux, Cmd+Alt+I for dev tools, Cmd/Ctrl+R for reload).
      
    electron-dl    
    eslint    
    marked 
    • Importing a markdown note.
     Yes
    force-graph 
    • Note map
      
    \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Dependencies/Per-dependency checks/bettersqlite binaries.md b/docs/Developer Guide/Developer Guide/Dependencies/Per-dependency checks/bettersqlite binaries.md new file mode 100644 index 0000000000..5a473b5e51 --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Dependencies/Per-dependency checks/bettersqlite binaries.md @@ -0,0 +1,25 @@ +# bettersqlite binaries +### The native node bindings + +`better-sqlite3` has native Node bindings. With updates of `better-sqlite3`, but also of Electron and Node.js versions, these bindings need to be updated. + +Note that Electron and Node.js versions need different versions of these bindings, since Electron usually packs a different version of Node.js. + +During development, `pnpm install` tries to build or reuse prebuilt natives for the current Node.js version. This makes `npm run start-server` work out of the box. Trying to run `npm run start-electron` with these versions generally causes an error such as this: + +``` +Uncaught Exception: +Error: The module '/Users/elian/Projects/Notes/node_modules/better-sqlite3/build/Release/better_sqlite3.node' +was compiled against a different Node.js version using +NODE_MODULE_VERSION 108. This version of Node.js requires +NODE_MODULE_VERSION 116. Please try re-compiling or re-installing +the module (for instance, using `npm rebuild` or `npm install`). +``` + +### How the natives are handled + +To avoid issues between the `server` and the `desktop`, the `desktop` build gets its own copy of the `bettersqlite3` dependency in its `node_module`. This copy is then rebuilt automatically to match the Electron version. + +This process of rebuilding is handled by `scripts/electron-rebuild.mts` which runs automatically after `pnpm install` (via `postinstall`). + +If needed, the script can be run manually again via `pnpm postinstall`. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Build information.md b/docs/Developer Guide/Developer Guide/Development and architecture/Build information.md deleted file mode 100644 index 475d902f55..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Build information.md +++ /dev/null @@ -1,4 +0,0 @@ -# Build information -* Provides context about when the build was made and the corresponding Git revision. -* The information is displayed to the client when going in the about dialog. -* The build information is hard-coded in `src/services/build.ts`. This file is generated automatically via `npm run update-build-info` which itself is run automatically whenever making a build in the CI, or a [local delivery](../Old%20documentation/Build%20deliveries%20locally.md). \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Database/attributes.md b/docs/Developer Guide/Developer Guide/Development and architecture/Database/attributes.md deleted file mode 100644 index 4e7ca6a4c9..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Database/attributes.md +++ /dev/null @@ -1,2 +0,0 @@ -# attributes -
    Column NameData TypeNullityDefault valueDescription
    attributeIdTextNon-null Unique Id of the attribute (e.g. qhC1vzU4nwSE), can also have a special unique ID for Special notes (e.g. _lbToday_liconClass).
    noteIdTextNon-null The ID of the note this atttribute belongs to
    typeTextNon-null The type of attribute (label or relation).
    nameTextNon-null The name/key of the attribute.
    valueTextNon-null""
    • For label attributes, a free-form value of the attribute.
    • For relation attributes, the ID of the note the relation is pointing to.
    positionIntegerNon-null0The position of the attribute compared to the other attributes. Some predefined attributes such as originalFileName have a value of 1000.
    utcDateModifiedTextNon-null Modification date in UTC format (e.g. 2023-11-08 16:43:44.204Z)
    isDeletedIntegerNon-null 1 if the entity is deleted, 0 otherwise.
    deleteIdTextNullablenull 
    isInheritableIntegerNullable0 
    \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Database/blobs.md b/docs/Developer Guide/Developer Guide/Development and architecture/Database/blobs.md deleted file mode 100644 index d0efc54345..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Database/blobs.md +++ /dev/null @@ -1,2 +0,0 @@ -# blobs -
    Column NameData TypeNullityDefault valueDescription
    blobIdTextNon-null The unique ID of the blob (e.g. XXbfAJXqWrYnSXcelLFA).

    Important: this ID is actually a hash of the content, see AbstractBeccaEntity#saveBlob! It is a logic error to modify an existing blob.

    contentTextNullablenull

    The content of the blob, can be either:

    • text (for plain text notes or HTML notes).
    • binary (for images and other types of attachments)
    dateModifiedTextNon-null Creation date with timezone offset (e.g. 2023-11-08 18:43:44.204+0200)
    utcDateModifiedTextNon-null Creation date in UTC format (e.g. 2023-11-08 16:43:44.204Z).

    Blobs cannot be modified, so this timestamp specifies when the blob was created.

    \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Demo document.md b/docs/Developer Guide/Developer Guide/Development and architecture/Demo document.md deleted file mode 100644 index 5987385de0..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Demo document.md +++ /dev/null @@ -1,19 +0,0 @@ -# Demo document -The demo document is an exported .zip that resides in `db/demo.zip`. - -During on-boarding, if the user selects that they are a new user then the `demo.zip` is imported into the root note. - -## Modifying the document - -On a dev server, remove all your existing notes in order to ensure a clean setup. Right click → Import to note and select the .zip file in `db/demo.zip`. Make sure to disable ā€œSafe importā€. - -After making the necessary modifications, simply export the ā€œTrilium Demoā€ note as ā€œHTML in ZIP archiveā€ and replace `db/demo.zip` with the newly exported one. - -## Testing the changes - -``` -rm -r data -npm run start-server -``` - -And then do the on-boarding again. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Docker.md b/docs/Developer Guide/Developer Guide/Development and architecture/Docker.md deleted file mode 100644 index 3a32bba514..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Docker.md +++ /dev/null @@ -1,18 +0,0 @@ -# Docker -To run a Docker build: - -``` -./bin/builder-docker.sh -``` - -To run the built Docker image: - -``` -sudo docker run -p 8081:8080 triliumnext/notes:v0.90.6-beta -``` - -To enter a shell in the Docker container: - -``` -sudo docker run -it --entrypoint=/bin/sh zadam/trilium:0.63-latest -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/1_Icons on Mac_image.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/1_Icons on Mac_image.png deleted file mode 100644 index 4fa4deed17..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/1_Icons on Mac_image.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac.md b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac.md deleted file mode 100644 index 0921f74765..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac.md +++ /dev/null @@ -1,8 +0,0 @@ -# Icons on Mac -Looks great in Finder: - -
    - -Looks great in Dock: - -
    \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/1_Adaptive icon_image.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/1_Adaptive icon_image.png deleted file mode 100644 index 4fa4deed17..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/1_Adaptive icon_image.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/1_Slightly blurry icon on Ma.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/1_Slightly blurry icon on Ma.png deleted file mode 100644 index 1a0232adfc..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/1_Slightly blurry icon on Ma.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/2_Adaptive icon_image.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/2_Adaptive icon_image.png deleted file mode 100644 index e429268523..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/2_Adaptive icon_image.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/2_Slightly blurry icon on Ma.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/2_Slightly blurry icon on Ma.png deleted file mode 100644 index c30743ecef..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/2_Slightly blurry icon on Ma.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/3_Adaptive icon_image.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/3_Adaptive icon_image.png deleted file mode 100644 index 99b0ce3d44..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/3_Adaptive icon_image.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/4_Adaptive icon_image.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/4_Adaptive icon_image.png deleted file mode 100644 index afcfacc11e..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/4_Adaptive icon_image.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/5_Adaptive icon_image.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/5_Adaptive icon_image.png deleted file mode 100644 index e99523df8e..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/5_Adaptive icon_image.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/6_Adaptive icon_image.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/6_Adaptive icon_image.png deleted file mode 100644 index eacecb265d..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/6_Adaptive icon_image.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Adaptive icon.md b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Adaptive icon.md deleted file mode 100644 index f3947eb0e8..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Adaptive icon.md +++ /dev/null @@ -1,15 +0,0 @@ -# Adaptive icon -| | | -| --- | --- | -| Before |
    | -| After |
    | -| With new scale |
    | - -## Scale - -| | | -| --- | --- | -| 0.9 |
    | -| 0.85 |
    | -| 0.8 |
    | -| 0.75 |
    | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Adaptive icon_image.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Adaptive icon_image.png deleted file mode 100644 index eeec79a01b..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Adaptive icon_image.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Slightly blurry icon on Ma.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Slightly blurry icon on Ma.png deleted file mode 100644 index c32a45801b..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Slightly blurry icon on Ma.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Slightly blurry icon on Mac.md b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Slightly blurry icon on Mac.md deleted file mode 100644 index a59a8abfeb..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac/Slightly blurry icon on Mac.md +++ /dev/null @@ -1,50 +0,0 @@ -# Slightly blurry icon on Mac -Slightly blurry in extended preview on Mac - -
    - -In the screenshot, the icon is around 650px whereas the closest image we have is 512px, so that might explain the blur. Adding an `ic10` (`1024x1024`, aka `512x512@2x` to see what happens). - -Before: - -``` -File: ../images/app-icons/mac/icon.icns - ic09: 62069 bytes, png: 512x512 -``` - -After: - -``` -File: ../images/app-icons/mac/icon.icns - icp4: 1140 bytes, png: 16x16 - icp5: 1868 bytes, png: 32x32 - ic07: 9520 bytes, png: 128x128 - ic09: 62069 bytes, png: 512x512 - ic10: 180442 bytes, png: 512x512@2x -``` - -Even with a 1024x1024 icon, the image is still blurry. - -Comparing the `.icns` file from the Electron build reveals that the `.icns` file has been tampered with: - -
    The electron.icns from the resulting buildThe icon source
    File: images/app-icons/mac/electron.icns
    -  icp4: 1140 bytes, png: 16x16
    -  icp5: 1868 bytes, png: 32x32
    -  ic07: 9520 bytes, png: 128x128
    -  ic09: 62069 bytes, png: 512x512
    -  ic10: 180442 bytes, png: 512x512@2x
    File: images/app-icons/mac/icon.icns
    -  icp4: 1648 bytes, png: 16x16
    -  icp5: 4364 bytes, png: 32x32
    -  ic07: 26273 bytes, png: 128x128
    -  ic09: 206192 bytes, png: 512x512
    -  ic10: 716034 bytes, png: 512x512@2x
    - -The bluriness might come from the image itself: [https://stackoverflow.com/questions/54030521/convert-svg-to-png-with-sharp-edges](https://stackoverflow.com/questions/54030521/convert-svg-to-png-with-sharp-edges)Ā  - -Rendering with Inkscape (left) vs ImageMagick (right): - -
    - -Now in macOS it's also rendering quite nicely: - -
    \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac_image.png b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac_image.png deleted file mode 100644 index f587c31cf4..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Icons on Mac_image.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Removed icons.md b/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Removed icons.md deleted file mode 100644 index 97b126515a..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Icons/Removed icons.md +++ /dev/null @@ -1,27 +0,0 @@ -# Removed icons -The following icons were removed: - -## Main images - -These are stored in `images`: - -| Name | Resolution | Description | -| --- | --- | --- | -| `icon-black.png` | 36x36 | Does not appear to be used. | -| `icon-color.png` | 36x36 | Used only by some tests in `test-etapi`. | -| `icon-grey.png` | 36x36 | Does not appear to be used. | -| `icon.svg` | 210x297 | Does not appear to be used. | - -## App icons - -| Name | Resolution | Description | -| --- | --- | --- | -| `png/16x16-bw.png` | 16x16 | Do not appear to be used. | -| `png/16x16.png` | | | -| `png/24x24.png` | 24x24 | | -| `png/32x32.png` | 32x32 | | -| `png/48x48.png` | 48x48 | | -| `png/64x64.png` | 64x64 | | -| `png/96x96.png` | 96x96 | | -| `png/512x512.png` | 512x512 | Does not appear to be used. | -| `win/setup-banner.xcf` | | GIMP source for `win/setup-banner.gif`. Provided only for future editing. | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Live reload.md b/docs/Developer Guide/Developer Guide/Development and architecture/Live reload.md deleted file mode 100644 index 0efebd014c..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Live reload.md +++ /dev/null @@ -1,20 +0,0 @@ -# Live reload -## Server live reload - -If running the server using `npm run start-server`, the server will watch for changes in `src/public` and trigger a frontend reload if that occurs. - -## Electron live reload - -Similarly, `npm run start-electron` supports live refresh Ā as well. - -However, a core difference is that Electron watches `dist/src/public` instead of `src/public` since Electron runs on its own copy of the files. - -To ameliorate that, a separate watch script has been implemented which automatically copies files from `src/public` to `dist/src/public` whenever a change is detected. To run it: - -``` -npm run -``` - -## Technical details - -* This mechanism is managed at server level by watching for changes in`services/ws.ts`. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Note types.md b/docs/Developer Guide/Developer Guide/Development and architecture/Note types.md deleted file mode 100644 index e8b9c6a3ca..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Note types.md +++ /dev/null @@ -1,30 +0,0 @@ -# Note types -The note type is defined by the `type` column inĀ notes. - -Possible types: - -
    Note Typetype valueCorresponding MIME typeContent of the note's blobRelevant attributes
    Texttext The HTML of the note. 
    Relation Map relationMapapplication/json

    A JSON describing the note:

    {
    -    "notes": [
    -        {
    -            "noteId": "gFQDL11KEm9G",
    -            "x": 142,
    -            "y": 405
    -        },
    -        {
    -            "noteId": "8GcjEKyrrCgl",
    -            "x": 100.10406374385552,
    -            "y": 757.0364424520196
    -        }
    -    ],
    -    "transform": {
    -        "scale": 0.3,
    -        "x": 480.29766098682165,
    -        "y": 116.83892021963081
    -    }
    -}
    None
    Render Noterendertext/html or blank.An empty blob.~renderNote pointing to the HTML note to render.
    Canvascanvasapplication/json
    {
    -	"appState": {},
    -	"elemenets": {},
    -	"files": {},
    -	"type": "excalidraw",
    -	"version": 2
    -}
    None
    Mermaid Diagrammermaidtext/mermaid or text/plainThe plain text content of the Mermaid diagram.None
    Bookbooktext/html or blank.An empty blob.
    • #viewType which can be either grid or list.
    • #expanded

    both options are shown to the user via the ā€œBook Propertiesā€ ribbon widget.

    Web ViewwebViewblankAn empty blob.#webViewSrc pointing to an URL to render.
    CodecodeDepends on the language (e.g. text/plain, text/x-markdown, text/x-c++src).The plain text content. 
    \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Options.md b/docs/Developer Guide/Developer Guide/Development and architecture/Options.md deleted file mode 100644 index a56f2bbed7..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Options.md +++ /dev/null @@ -1,14 +0,0 @@ -# Options -## Read an option - -Add the import to the service (make sure the relative path is correct): - -```javascript -import options from "../../services/options.js"; -``` - -Them simply read the option: - -```javascript -this.firstDayOfWeek = options.getInt("firstDayOfWeek"); -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Options/Check box option.md b/docs/Developer Guide/Developer Guide/Development and architecture/Options/Check box option.md deleted file mode 100644 index fa2258336e..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Options/Check box option.md +++ /dev/null @@ -1,37 +0,0 @@ -# Check box option -In the TPL: - -``` -
    -

    Background effects

    - -

    On the desktop application, it's possible to use a semi-transparent background tinted in the colors of the user's wallpaper to add a touch of color.

    - -
    - -
    -
    -``` - -In `doRender()`: - -``` -doRender() { - this.$backgroundEffects = this.$widget.find("input.background-effects"); - - this.$backgroundEffects.on("change", () => this.updateCheckboxOption("backgroundEffects", this.$backgroundEffects)); -} -``` - -In `optionsLoaded(options)`: - -``` -async optionsLoaded(options) { - - this.setCheckboxState(this.$backgroundEffects, options.backgroundEffects); - -} -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Options/Displaying the option in setti.md b/docs/Developer Guide/Developer Guide/Development and architecture/Options/Displaying the option in setti.md deleted file mode 100644 index b135025e05..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Options/Displaying the option in setti.md +++ /dev/null @@ -1,36 +0,0 @@ -# Displaying the option in settings -Go to `src/public/app/widgets/type_widgets/options` and select a corresponding category, such as `appearance` and edit one of the JS files. - -For example, to create a select: - -First, modify the template (`TPL`), to add the new widget: - -``` -
    - - -
    -``` - -Secondly, create a reference to the new element in `doRender()`: - -``` -this.$firstDayOfWeek = this.$widget.find(".first-day-of-week-select"); -``` - -Then in `optionsLoaded` adjust the value to the one set in the database: - -``` -this.$firstDayOfWeek.val(options.firstDayOfWeek); -``` - -To actually update the option, add a listener in `doRender`: - -``` -this.$firstDayOfWeek.on("change", () => { - this.updateOption("firstDayOfWeek", this.$firstDayOfWeek.val()); -}); -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Options/Refresh widget with option cha.md b/docs/Developer Guide/Developer Guide/Development and architecture/Options/Refresh widget with option cha.md deleted file mode 100644 index a79f1ac1d9..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Options/Refresh widget with option cha.md +++ /dev/null @@ -1,10 +0,0 @@ -# Refresh widget with option change -To make a widget react to a change of a given option, simply add the following to the widget: - -```javascript -async entitiesReloadedEvent({loadResults}) { - if (loadResults.getOptionNames().includes("firstDayOfWeek")) { - // Do something. - } -} -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Options/Trigger UI refresh.md b/docs/Developer Guide/Developer Guide/Development and architecture/Options/Trigger UI refresh.md deleted file mode 100644 index d8cf12f2a4..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Options/Trigger UI refresh.md +++ /dev/null @@ -1,12 +0,0 @@ -# Trigger UI refresh -Call `utils.reloadFrontendApp`, but make sure to wait for the option to be saved first. - -``` -this.$backgroundEffects.on("change", async () => { - - await this.updateCheckboxOption("backgroundEffects", this.$backgroundEffects); - - utils.reloadFrontendApp("background effect change"); - -}); -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Printing.md b/docs/Developer Guide/Developer Guide/Development and architecture/Printing.md deleted file mode 100644 index 9614ee7864..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Printing.md +++ /dev/null @@ -1,15 +0,0 @@ -# Printing -Note printing is handled by `note_detail.js`, in the `printActiveNoteEvent` method. - -The application uses the [`print-this`](https://www.npmjs.com/package/print-this) library to isolate `.note-detail-printable:visible` and prepare it for printing. - -Some scripts like KaTeX are manually injected in the footer, and the CSS to be used is manually defined. The most important one is `print.css`. - -## Syntax highlighting - -Syntax highlighting for code blocks is supported as well: - -* It works by injecting a Highlight.js stylesheet into the print. -* The theme used is hard-coded (the _Visual Studio Light theme_, at the time of writing) in order not to have a dark background in print. -* The Highlight.js library is not needed since the `.note-detail-printable` which is rendered already has the `.hljs` classes added to it in order to achieve the syntax highlighting. -* The user's choice of whether to enable syntax highlighting is also respected. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Protected entities.md b/docs/Developer Guide/Developer Guide/Development and architecture/Protected entities.md deleted file mode 100644 index 225c740e70..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Protected entities.md +++ /dev/null @@ -1,6 +0,0 @@ -# Protected entities -The following entities can be made protected, via their `isProtected` flag: - -* attachments -* notes -* revisions \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Special notes.md b/docs/Developer Guide/Developer Guide/Development and architecture/Special notes.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Syntax highlighting.md b/docs/Developer Guide/Developer Guide/Development and architecture/Syntax highlighting.md deleted file mode 100644 index f848660bd7..0000000000 --- a/docs/Developer Guide/Developer Guide/Development and architecture/Syntax highlighting.md +++ /dev/null @@ -1,84 +0,0 @@ -# Syntax highlighting -## Defining the MIME type - -The first step to supporting a new language for either code blocks or code notes is to define the MIME type. Go to `mime_types.ts` and add a corresponding entry: - -``` -{ title: "Batch file (DOS)", mime: "application/x-bat" } -``` - -## Syntax highlighting for Highlight.js - -### Built-in languages - -Highlight.js supports a lot of languages out of the box, for some of them we just need to enable them by specifying one of the language aliases in the `highlightJs` field in the `mime_types` definition: - -``` -{ title: "Batch file (DOS)", mime: "application/x-bat", highlightJs: "dos" } -``` - -For the full list of supported languages, see [Supported Languages — highlight.js 11.9.0 documentation](https://highlightjs.readthedocs.io/en/latest/supported-languages.html). Look for the ā€œPackageā€ column to see if another library needs to be installed to support it. - -Note that we are using the CDN build which may or may not have all the languages listed as predefined in the ā€œSupported languagesā€ list. To view the real list of supported files, see the `node_modules/@highlightjs/cdn-assets/languages` directory. - -### Custom language - -When the source code for a language is available, one way is to simply copy it to `libraries/highlightjs/{id}.js` where `id` matches the name for `highlightJs`. - -Make sure in the script that the language is registered: - -``` -hljs.registerLanguage('terraform', hljsDefineTerraform); -``` - -Then in `mime_types.ts` make sure to set `highlightJsSource` to `libraries` to load it. - -``` -{ title: "Terraform (HCL)", mime: "text/x-hcl", highlightJs: "terraform", highlightJsSource: "libraries", codeMirrorSource: "libraries/codemirror/hcl.js" }, -``` - -## Syntax highlighting for CodeMirror - -### Custom language - -Generally new languages are not added in the base installation and need to be separately registered. For CodeMirror 5 it seems that (at least for simple languages), the modes are distributed as _simple modes_ and can generally be copy-pasted in `libraries/codemirror`. An example would be: - -``` -(() => { - - CodeMirror.defineSimpleMode("batch", { - - start: [], - - echo: [] - - }); - - - - CodeMirror.defineMIME("application/x-bat", "batch"); - - CodeMirror.modeInfo.push({ - - ext: [ "bat", "cmd" ], - - mime: "application/x-bat", - - mode: "batch", - - name: "Batch file" - - }); - -})(); - - -``` - -Note that changing `modeInfo` is crucial, otherwise syntax highlighting will not work. The `mime` field is mandatory, even if `mimes` is used instead. - -Afterwards, register it in `mime_types.ts`, specifying `codeMirrorSource` to point to the newly created file: - -``` -{ title: "Batch file (DOS)", mime: "application/x-bat", highlightJs: "dos", codeMirrorSource: "libraries/codemirror/batch.js" } -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Documentation.md b/docs/Developer Guide/Developer Guide/Documentation.md similarity index 66% rename from docs/Developer Guide/Developer Guide/Old documentation/Documentation.md rename to docs/Developer Guide/Developer Guide/Documentation.md index c1d2a80646..839d012711 100644 --- a/docs/Developer Guide/Developer Guide/Old documentation/Documentation.md +++ b/docs/Developer Guide/Developer Guide/Documentation.md @@ -1,29 +1,32 @@ # Documentation -
    - -There are multiple types of documentation for Trilium: +There are multiple types of documentation for Trilium: * The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing F1. * The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers. * _Release Notes_, this contains the change log for each released or soon-to-be-released version. The release notes are used automatically by the CI when releasing a version. * The _Script API_, which is an automatically generated documentation for the front-end and back-end APIs for scripts. -## Editing documentation +## Location of the documentation + +All documentation is stored in the [Trilium](https://github.com/TriliumNext/Trilium) repository: + +* `docs/Developer Guide` contains Markdown documentation that can be modified either externally (using a Markdown editor, or internally using Trilium). +* `docs/Release Notes` is also stored in Markdown format and can be freely edited. +* `docs/Script API` contains auto-generated files and thus must not be modified. +* `docs/User Guide` contains also Markdown-only documentation but must generally not be edited externally. + * The reason is that the `pnpm edit-docs:edit-docs` feature will not only import/export this documentation, but also generate the corresponding HTML documentation and meta structure in `src/public/app/doc_notes/en/User Guide`. + * It's theoretically possible to edit the Markdown files externally and then run `docs:edit` and trigger a change in order to build the documentation, but that would not be a very productive workflow. + +## Editing the documentation There are two ways to modify documentation: * Using a special mode of Trilium. * By manually editing the files. -### Using `docs:edit` +### Using the `edit-docs` app -To edit the documentation using Trilium, set up a working development environment and run the following commands: - -* On most operating systems, `npm run electron:switch` followed by `npm run docs:edit` -* On NixOS, `npm run docs:edit-nix`. - -> [!NOTE] -> `npm run docs:edit` acts very similar to `npm run electron:start` in the sense that you cannot both be editing documentation and starting a server. Using both `npm run electron:start` and `docs:edit` is possible, since they are using the same Electron instance. +To edit the documentation using Trilium, set up a working development environment viaĀ Environment SetupĀ and run the following command: `pnpm edit-docs:edit-docs`. How it works: @@ -50,24 +53,30 @@ Important aspects to consider: * The Trilium import/export mechanism is not perfect, so if you make some modifications to the documentation using `docs:edit`, at the next import/export/import cycle some whitespace might get thrown in. It's generally safe to commit the changes as-is. * Since we are importing Markdown, editing HTML and then exporting the HTML back to Markdown there might be some edge cases where the formatting is not properly preserved. Try to identify such cases and report them in order to get them fixed (this will benefit also the users). -## Location of the documentation +## Automation -All documentation is stored in the [Notes](https://github.com/TriliumNext/Notes) repository: +The documentation is built via `apps/build-docs`: -* `docs/Developer Guide` contains Markdown documentation that can be modified either externally (using a Markdown editor, or internally using Trilium). -* `docs/Release Notes` is also stored in Markdown format and can be freely edited. -* `docs/Script API` contains auto-generated files and thus must not be modified. -* `docs/User Guide` contains also Markdown-only documentation but must generally not be edited externally. - * The reason is that the `docs:edit` feature will not only import/export this documentation, but also generate the corresponding HTML documentation and meta structure in `src/public/app/doc_notes/en/User Guide`. - * It's theoretically possible to edit the Markdown files externally and then run `docs:edit` and trigger a change in order to build the documentation, but that would not be a very productive workflow. +1. The output directory is cleared. +2. The User Guide and the Developer Guide are built. + 1. The documentation from the repo is archived and imported into an in-memory instance. + 2. The documentation is exported using the shared theme. +3. The API docs (internal and ETAPI) are statically rendered via Redocly. +4. The script API is generated via `typedoc` + +The `deploy-docs` workflow triggers the documentation build and uploads it to CloudFlare Pages. ## Updating the Script API As mentioned previously, the Script API is not manually editable since it is auto-generated using TypeDoc. -To update the API documentation, simply run `npm run docs:build`. Compare the changes (if any) and commit them. +To update the API documentation, simply run `pnpm docs:build`. Compare the changes (if any) and commit them. -Note that in order to simulate the environment a script would have, some fake source files (in the sense that they are only used for documentation) are being used as entrypoints for the documentation: +Note that in order to simulate the environment a script would have, some fake source files (in the sense that they are only used for documentation) are being used as entrypoints for the documentation. Look for `backend_script_entrypoint` and `frontend_script_entrypoint` in `apps/build-docs/src`. -* For back-end scripts, the script is located in `src/services/backend_script_entrypoint.ts`. -* For front-end scripts, the script is located in `src/public/app/services/frontend_script_entrypoint.ts`. \ No newline at end of file +## Building locally + +In the Git root: + +* Run `pnpm docs:build`. The built documentation will be available in `site` at Git root. +* To also run a webserver to test it, run `pnpm docs:preview` (this will not build the documentation) and navigate to `localhost:9000`. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Documentation/Documentation references in th.md b/docs/Developer Guide/Developer Guide/Documentation/Documentation references in th.md similarity index 69% rename from docs/Developer Guide/Developer Guide/Old documentation/Documentation/Documentation references in th.md rename to docs/Developer Guide/Developer Guide/Documentation/Documentation references in th.md index 1c9a9fea91..79c1bd80e9 100644 --- a/docs/Developer Guide/Developer Guide/Old documentation/Documentation/Documentation references in th.md +++ b/docs/Developer Guide/Developer Guide/Documentation/Documentation references in th.md @@ -13,6 +13,8 @@ https://triliumnext.github.io/Docs/Wiki/ There is a pattern of ā€œ?ā€ buttons throughout the application which make use of the `data-help-page` attribute. Whenever these buttons are pressed, the user is redirected to the corresponding wiki page by prepending the wiki root URL to the `data-help-page` attribute. +### Deprecated `help-page` attribute + Since the current wiki has a different structure than the original, for example to link to [https://github.com/TriliumNext/Docs/blob/main/Wiki/tree-concepts.md](https://github.com/TriliumNext/Docs/blob/main/Wiki/tree-concepts.md) the `data-help-page` attribute must be set to `tree-concepts.md`. For links to headings, simply add the heading after the `.md`: `tree-concepts.md#prefix` @@ -20,4 +22,12 @@ For links to headings, simply add the heading after the `.md`: `tree-concepts.md You can identify those by looking for: * `.attr("data-help-page"` -* `data-help-page="` \ No newline at end of file +* `data-help-page="` + +### More modern `data-in-app-help` attribute + +Instead of opening in a web browser, this opens the help directly in the application in a split view. This is handled via the `data-in-app-help` attribute, where the value is the note ID of the help page without the `_help_` prefix. + +### React + +Use the `HelpButton` component in the same fashion as the `data-in-app-help` attribute. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Environment Setup.md b/docs/Developer Guide/Developer Guide/Environment Setup.md index f1d706429d..f958b4eec0 100644 --- a/docs/Developer Guide/Developer Guide/Environment Setup.md +++ b/docs/Developer Guide/Developer Guide/Environment Setup.md @@ -24,10 +24,13 @@ As a quick heads-up of some differences when compared to `npm`: ## Installing dependencies -Run `pnpm i` at the top of the `Notes` repository to install the dependencies. +Run `pnpm i` at the top of the `Trilium` repository to install the dependencies. + +> [!NOTE] +> Dependencies are kept up to date periodically in the project. Generally it's a good rule to do `pnpm i` after each `git pull` on the main branch. ## IDE -Our recommended IDE for working on TriliumNext is Visual Studio Code (or VSCodium if you are looking for a fully open-source alternative). +Our recommended IDE for working on Trilium is Visual Studio Code (or VSCodium if you are looking for a fully open-source alternative). -By default we include a number of suggested extensions which should appear when opening the repository in VS Code. Most of the extensions are for integrating various technologies we are using such as Playwright and Vitest for testing and NX for mono-repo management. \ No newline at end of file +By default we include a number of suggested extensions which should appear when opening the repository in VS Code. Most of the extensions are for integrating various technologies we are using such as Playwright and Vitest for testing or forĀ Internationalisation / Translations. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Build deliveries locally.md b/docs/Developer Guide/Developer Guide/Old documentation/Build deliveries locally.md deleted file mode 100644 index 31a6ee0e2e..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Build deliveries locally.md +++ /dev/null @@ -1,32 +0,0 @@ -# Build deliveries locally -In the project root: - -| Platform | Architecture | Application | Build command | -| --- | --- | --- | --- | -| macOS | x86\_64 | Desktop / Electron app | `./bin/build-mac-x64.sh` | -| ARM 64 | Desktop / Electron app | `./bin/build-mac-arm64.sh` | | -| Linux | x86\_64 | Desktop / Electron app | `./bin/build-linux-x64.sh` | -| Server | `./bin/build-server.sh` | | | -| Windows | x86\_64 | Desktop / Electron app | `./bin/build-win-x64.sh` | - -Under NixOS the following `nix-shell` is needed: - -``` -nix-shell -p jq -``` - -For Linux builds: - -``` -nix-shell -p jq fakeroot dpkg -``` - -The resulting build will be in the `dist` directory under the project root. - -### Testing the Linux builds under NixOS - -
    Desktop clientServer
    $ NIXPKGS_ALLOW_UNFREE=1 nix-shell -p steam-run
    -[nix-shell] cd dist/trilium-linux-x64
    -[nix-shell] steam-run ./trilium
    $ NIXPKGS_ALLOW_UNFREE=1 nix-shell -p steam-run
    -[nix-shell] cd dist/trilium-linux-x64-server
    -[nix-shell] steam-run ./trilium.sh
    \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Build deliveries locally.clone.md b/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Build deliveries locally.clone.md deleted file mode 100644 index 3ee7c825ba..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Build deliveries locally.clone.md +++ /dev/null @@ -1,2 +0,0 @@ -# Build deliveries locally -This is a clone of a note. Go to its [primary location](../Build%20deliveries%20locally.md). \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Documentation.md b/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Documentation.md deleted file mode 100644 index 672b64f7c6..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Documentation.md +++ /dev/null @@ -1,34 +0,0 @@ -# Documentation -Development notes are published on [triliumnext.github.io/Notes](https://triliumnext.github.io/Notes) by the CI using GitHub Pages. - -The GitHub Pages deployment works by taking the files from the Notes repository, in the `docs` directory. - -## How it works - -There is a script that uses `wget` to download all the files from a share, that means: - -1. You must have a local instance of Trilium Notes server. -2. You must have the documentation imported, up to date and shared. - -Note that currently the documentation source file is not distributed (the note export), until a way is found to automate this process. Contact `eliandoran` should you require to obtain a copy of the documentation. - -## Setting up `.env` file - -Go to `bin/docs` and copy `.env.example` to `.env` and edit it: - -1. Change the `SHARE_PROTOCOL` to either `http` or `https` depending on your setup. -2. Change `SHARE_HOST` to match the domain name or the URL to the host (without the protocol or any slashes). - -Generally `ROOT_NOTE_ID` should not be changed since the note ID must match if the files were imported correctly. - -## Triggering a build - -Run: - -``` -./bin/docs/prepare.sh -``` - -This will attempt to download all the notes from the share URL and put them in `docs`, rewritten for GitHub Pages. - -Commit the results and follow the normal development process to push them. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Releasing a version.clone.md b/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Releasing a version.clone.md deleted file mode 100644 index 3e2019da0d..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Releasing a version.clone.md +++ /dev/null @@ -1,2 +0,0 @@ -# Releasing a version -This is a clone of a note. Go to its [primary location](../Releasing%20a%20version.md). \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Running a development build.clone.md b/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Running a development build.clone.md deleted file mode 100644 index d56a46aeab..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Building and deployment/Running a development build.clone.md +++ /dev/null @@ -1,2 +0,0 @@ -# Running a development build -This is a clone of a note. Go to its [primary location](../Running%20a%20development%20build.md). \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Dependency Management/Adding a new client library.md b/docs/Developer Guide/Developer Guide/Old documentation/Dependency Management/Adding a new client library.md deleted file mode 100644 index 64ffcf5288..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Dependency Management/Adding a new client library.md +++ /dev/null @@ -1,116 +0,0 @@ -# Adding a new client library -In the past some libraries have been copy-pasted (and adapted if needed) to the repository. However, new libraries must be obtained exclusively through npm. - -The first step is to install the desired library. As an example we are going to install `i18next`: - -``` -npm i i18next -``` - -### Step 1. Understanding the structure of the import - -After installing the dependency, it's important to know how it's structured. You can do this by looking at the directory structure of the newly imported dependency: - -``` -$ tree node_modules/i18next -node_modules/i18next -ā”œā”€ā”€ dist -│ ā”œā”€ā”€ cjs -│ │ └── i18next.js -│ ā”œā”€ā”€ esm -│ │ ā”œā”€ā”€ i18next.bundled.js -│ │ ā”œā”€ā”€ i18next.js -│ │ └── package.json -│ └── umd -│ ā”œā”€ā”€ i18next.js -│ └── i18next.min.js -ā”œā”€ā”€ i18next.js -ā”œā”€ā”€ i18next.min.js -ā”œā”€ā”€ index.d.mts -ā”œā”€ā”€ index.d.ts -ā”œā”€ā”€ index.js -ā”œā”€ā”€ index.v4.d.ts -ā”œā”€ā”€ LICENSE -ā”œā”€ā”€ package.json -ā”œā”€ā”€ README.md -└── typescript - ā”œā”€ā”€ helpers.d.ts - ā”œā”€ā”€ options.d.ts - ā”œā”€ā”€ t.d.ts - └── t.v4.d.ts -``` - -Generally you should be looking for a `.min.js` file. Note that the `esm` and `cjs` variants generally don't work, we are looking for the classic, no module dependency. - -### Step 2. Exposing the library from the server - -The library must be delivered by the server and this is done via `src/routes/assets.ts`. In the `register` function, add a new entry near the bottom of the function: - -```javascript -app.use(`/${assetPath}/node_modules/i18next/`, persistentCacheStatic(path.join(srcRoot, "..", 'node_modules/i18next/'))); -``` - -### Step 3. Adding it to the library loader - -The library loader is a client module which is in charge of downloading the library from the server and importing it. The loader is located in `src/public/app/services/library_loader.js`. - -To add a new library, start by creating a constant for it, with the value pointing to the minified JS identified at the first step: - -```javascript -const I18NEXT = { - js: [ - "node_modules/i18next/i18next.min.js" - ] -}; -``` - -Then add it to the `export default` section: - -```diff - export default { - requireCss, - requireLibrary, - CKEDITOR, - CODE_MIRROR, - ESLINT, - RELATION_MAP, - PRINT_THIS, - CALENDAR_WIDGET, - KATEX, - WHEEL_ZOOM, - FORCE_GRAPH, - MERMAID, - EXCALIDRAW, -- MARKJS -+ MARKJS, -+ I18NEXT - } -``` - -### Step 4. Using the library - -To import the library, simply use the following mechanism: - -```diff -import library_loader from "./library_loader.js"; - -await library_loader.requireLibrary(library_loader.I18NEXT); -``` - -Make sure to replace `I18NEXT` with the library that was created at the previous steps. - -Note that because we are not using a module management mechanism such as ES Modules or Common.js modules, the `requireLibrary` method does not actually return anything.Ā  - -To benefit from the library, it must export on its own an object in `window`. - -In the case of `i18next`, it sets `window.i18next` and that can be used directly: - -```diff -i18next.init({}); -``` - -### Step 5. Adding Electron support - -For Electron, the `node_modules` are copied as a separate step by `bin/copy-dist.ts`. - -Scroll all the way down to the `nodeModulesFolder` and append an entry for the newly added libraries. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Dependency Management/Having a simpler packaging sys.md b/docs/Developer Guide/Developer Guide/Old documentation/Dependency Management/Having a simpler packaging sys.md deleted file mode 100644 index 05271e3907..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Dependency Management/Having a simpler packaging sys.md +++ /dev/null @@ -1,8 +0,0 @@ -# Having a simpler packaging system -The current build scripts are a bit complicated and maintaining them is not easy. - -[Electron Forge](https://www.electronforge.io/) seems more mature and has a boatload of features, including Flatpak, snaps, Windows installers & more. - -Have a look also at the [Plugins](https://www.electronforge.io/config/plugins) section since there are quite a few interesting things there as well. - -Afterwards consider running a new round ofĀ Reducing binary size, especially taking into consideration removing of the unnecessary locales. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Documentation_image.png b/docs/Developer Guide/Developer Guide/Old documentation/Documentation_image.png deleted file mode 100644 index 542bb7858c..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Old documentation/Documentation_image.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Installation/Download latest nightly and in.md b/docs/Developer Guide/Developer Guide/Old documentation/Installation/Download latest nightly and in.md deleted file mode 100644 index 90a7740bef..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Installation/Download latest nightly and in.md +++ /dev/null @@ -1,12 +0,0 @@ -# Download latest nightly and install it -On Ubuntu: - -``` -#!/usr/bin/env bash - -name=TriliumNotes-linux-x64-nightly.deb -rm -f $name* -wget https://github.com/TriliumNext/Notes/releases/download/nightly/$name -sudo apt-get install ./$name -rm $name -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies/Node.js, Electron and `better-.md b/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies/Node.js, Electron and `better-.md deleted file mode 100644 index 93b94ab729..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies/Node.js, Electron and `better-.md +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js, Electron and `better-sqlite3` -## Node.js, Electron and `better-sqlite3` - -`better-sqlite3` requires a native module in order to work. In order to ease the installation process, prebuilt binaries are provided by the library developers. - -Trilium Next started with version [8.4.0](https://github.com/WiseLibs/better-sqlite3/releases/tag/v8.4.0) for `better-sqlite3` - -| | | | | -| --- | --- | --- | --- | -| `better-sqlite3` version | SQLite version | Node.js prebuilds | Electron.js prebuilds | -| 8.4.0 | <3.43.0 | v20 | ??? | -| 8.5.0 | v20 | v25 | | -| 8.5.1 | | v26 | | -| 8.5.2 | v20 (macOS + arm64) | | | -| 8.6.0 | 3.43.0 | | | -| 8.7.0 | 3.43.1 | | | -| 9.0.0 | 3.43.2 | | v27 | -| 9.1.0 | 3.44.0 | | | -| 9.1.1 | macOS + Alpine | | | -| 9.2.0 | 3.44.2 | | | -| 9.2.1 / 9.2.2 | | v28 | | -| 9.3.0 | 3.45.0 | | | -| 9.4.0 | 3.45.1 | | | -| 9.4.1 | Windows arm, arm64 | | | -| 9.4.2 | | 21 | | | -| 11.1.0 (prerelease) | | | v31 | -| 11.1.1 | | | | -| 11.1.2 | | | | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies/Testing compatibility.md b/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies/Testing compatibility.md deleted file mode 100644 index 3813260558..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies/Testing compatibility.md +++ /dev/null @@ -1,15 +0,0 @@ -# Testing compatibility -| `better-sqlite3` version
    [Change log](https://github.com/WiseLibs/better-sqlite3/releases) | SQLite version
    [Change log](https://www.sqlite.org/changes.html) | Compatibility with upstream Trilium | -| --- | --- | --- | -| 8.4.0 | <3.43.0 | Compatible, same version. | -| 8.6.0 | 3.43.0 | | -| 8.7.0 | 3.43.1 | | -| 9.0.0 | 3.43.2 | | -| 9.1.0 + 9.1.1 | 3.44.0 | | -| 9.2.0 + 9.2.1 + 9.2.2 | 3.44.2 | | -| 9.3.0 | 3.45.0 | | -| 9.4.0, 9.4.1, 9.4.2, 9.4.3, 9.4.4, 9.4.5 | 3.45.1 | | -| 9.5.0 | 3.45.2 | | -| 9.6.0 / 10.0.0 | 3.45.3 | | -| 10.1.0 / 11.0.0 / 11.1.1 / 11.1.2 / 11.2.0 / 11.2.1 | 3.46.0 | | -| 11.3.0 | 3.46.1 | | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies/bettersqlite binaries.md b/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies/bettersqlite binaries.md deleted file mode 100644 index 12fdd7e70b..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Project maintenance/Updating dependencies/bettersqlite binaries.md +++ /dev/null @@ -1,41 +0,0 @@ -# bettersqlite binaries -### The native node bindings - -`better-sqlite3` has native Node bindings. With updates of `better-sqlite3`, but also of Electron and Node.js versions, these bindings need to be updated. - -Note that Electron and Node.js versions need different versions of these bindings, since Electron usually packs a different version of Node.js. - -During development, `npm install` tries to build or reuse prebuilt natives for the current Node.js version. This makes `npm run start-server` work out of the box. Trying to run `npm run start-electron` with these versions generally causes an error such as this: - -``` -Uncaught Exception: -Error: The module '/Users/elian/Projects/Notes/node_modules/better-sqlite3/build/Release/better_sqlite3.node' -was compiled against a different Node.js version using -NODE_MODULE_VERSION 108. This version of Node.js requires -NODE_MODULE_VERSION 116. Please try re-compiling or re-installing -the module (for instance, using `npm rebuild` or `npm install`). -``` - -### How the natives are handled - -Locally, this can be fixed by rebuilding the binaries, which is what `npm run switch-electron` does, which uses `electron-rebuild` under the hood. - -When the deliveries are built (seeĀ Build deliveries locally), it is not feasible to rebuild the dependencies since we are building for multiple platforms. Luckily, `better-sqlite3` provides these prebuilt binaries from us, available as artifacts on [their GitHub releases page](https://github.com/WiseLibs/better-sqlite3/releases/).Ā  - -The build script manages the natives for `better-sqlite3` by keeping a copy of the `.node` file for every platform in `bin/better-sqlite3`. - -Whenever the version of `better-sqlite3` changes, the `.node` files must also be renewed based on their releases page. To simplify this process, a script was created in `bin/better-sqlite3/update.sh`. - -## How to update the natives - -The update script needs to know the version of Electron or Node.js for which to download the prebuilt binaries. - -If you get errors during download, check on the [releases page](https://github.com/WiseLibs/better-sqlite3/releases/) to ensure that this particular combination of Electron/Node actually exists for the given release. - -To determine the `NODE_MODULE_VERSION` that is required, look for `This version of Node.js requires` -`NODE_MODULE_VERSION` in the error when starting Trilium via: - -* `npm run start-electron` (or run any Electron [delivery](../../Build%20deliveries%20locally.md)), case in which the `ELECTRON_VERSION` variable needs to be changed. -* `npm run start-server` (or run the Linux server delivery), case in which the `NODE_VERSION` variable needs to be changed. - -Check which files got changed after running the update script and for each platform that got changed, test it locally viaĀ Build deliveries locallyĀ or via the CI. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Releasing a version.md b/docs/Developer Guide/Developer Guide/Old documentation/Releasing a version.md deleted file mode 100644 index 63b75ddecc..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Releasing a version.md +++ /dev/null @@ -1,22 +0,0 @@ -# Releasing a version -On NixOS: - -``` -nix-shell -p dpkg fakeroot jq nodejs_20 -``` - -Then simply run from project root: - -``` -./bin/release.sh 1.2.3 -``` - -where `1.2.3` is the desired release version. - -If a version ends with `-beta`, it will automatically be marked as pre-release in GitHub. - -This will automatically generate a release in GitHub if everything goes according to plan. - -Note that the Windows installer is not automatically uploaded yet, it has to be taken from the [main workflow of the CI from the `develop` branch](Building%20and%20deployment/CI/Main.md). - -Make sure to check test the artifacts of the release. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Running a development build.md b/docs/Developer Guide/Developer Guide/Old documentation/Running a development build.md deleted file mode 100644 index 539dc3d033..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Running a development build.md +++ /dev/null @@ -1,89 +0,0 @@ -# Running a development build -As always, install the dependencies for the first time (and re-run whenever there are errors about missing dependencies): - -``` -npm install -``` - -## Run server - -Run with default settings: - -``` -npm run start-server -``` - -Run with custom port: - -``` -TRILIUM_PORT=8082 npm run start-server -``` - -## Run Electron - -Rebuild `better-sqlite3` dependency: - -``` -npm run switch-electron -``` - -Then run Electron: - -``` -npm run start-electron -``` - -To run Electron using the same data directory as the production version: - -``` -npm run start-electron-no-dir -``` - -When done, switch back the `better-sqlite3` dependency: - -``` -npm run switch-server -``` - -## Quick switch - -To start Electron without running `switch-electron` first: - -``` -npm run qstart-electron -``` - -Similarly, to start the server without running `switch-server` first: - -``` -npm run qstart-server -``` - -## Safe mode - -Safe mode is off by default, to enable it temporarily on a Unix shell, prepend the environment variable setting: - -``` -TRILIUM_SAFE_MODE=1 npm run start-server -``` - -To have the same behaviour on Windows, we would need to alter `package.json`: - -```diff --"start-electron": "npm run prepare-dist && cross-env TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron-main.js --inspect=5858 .", -+"start-electron": "npm run prepare-dist && cross-env TRILIUM_SAFE_MODE=1 TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./dist/electron-main.js --inspect=5858 .", -``` - -## Running on NixOS - -When doing development, the Electron binary retrieved from NPM is not going to be compatible with NixOS, resulting in errors when trying to run it. To bypass this, there is a special command to run electron using `nix-shell`: - -``` -npm run start-electron-nix -``` - -Similarly to the original command, to use the same data directory as the production version: - -``` -npm run start-electron-no-dir-nix -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Server-side imports.md b/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Server-side imports.md deleted file mode 100644 index c19366cee3..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Server-side imports.md +++ /dev/null @@ -1,16 +0,0 @@ -# Server-side imports -Trilium Notes allowed the use of Common.js module imports inside backend scripts, such as: - -``` -const isBetween = require('dayjs/plugin/isBetween') -api.dayjs.extend(isBetween) -``` - -For TriliumNext, the backend has been switched to use ESM which has a slightly more complicated syntax. Instead of `require` we now have `import` but which is asynchronous so it will require an `await`: - -``` -const isBetween = (await import("dayjs/plugin/isBetween")).default; -api.dayjs.extend(isBetween); -``` - -Note that `.default` is also usually needed to obtain the same behaviour as a CJS import. When in doubt, use `console.log` to see the output of the value returned by `await import`. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Widgets.md b/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Widgets.md deleted file mode 100644 index 57de0ad159..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Widgets.md +++ /dev/null @@ -1,33 +0,0 @@ -# Widgets -To create a basic widget, simply create a code note with type ā€œJS frontendā€. Add the `#widget` label in order for it to be loaded at startup. - -``` -const template = `
    `; - -class MyWidget extends api.BasicWidget { - get position() { return 1; } - get parentWidget() { return "left-pane" } - - doRender() { - this.$widget = $(template); - return this.$widget; - } -} - -module.exports = new MyWidget(); -``` - -`parentWidget()` can be given the following values: - -* `left-pane` - This renders the widget on the left side of the screen where the note tree lives. -* `center-pane` - This renders the widget in the center of the layout in the same location that notes and splits appear. -* `note-detail-pane` - This renders the widget _with_ the note in the center pane. This means it can appear multiple times with splits. -* `right-pane` - This renders the widget to the right of any opened notes. - -* * * - -Reference: - -* [https://trilium.rocks/X7pxYpiu0lgU](https://trilium.rocks/X7pxYpiu0lgU) -* [https://github.com/zadam/trilium/wiki/Widget-Basics](https://github.com/zadam/trilium/wiki/Widget-Basics) -* [https://github.com/zadam/trilium/wiki/Frontend-Basics](https://github.com/zadam/trilium/wiki/Frontend-Basics) \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Widgets/CSS.md b/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Widgets/CSS.md deleted file mode 100644 index ff1a86b270..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Widgets/CSS.md +++ /dev/null @@ -1,15 +0,0 @@ -# CSS -In `doRender()`: - -``` -this.cssBlock(`#my-widget { - position: absolute; - bottom: 40px; - left: 60px; - z-index: 1; -}`) -``` - -* * * - -Reference: [https://trilium.rocks/X7pxYpiu0lgU](https://trilium.rocks/X7pxYpiu0lgU) \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Widgets/Right pane widget.md b/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Widgets/Right pane widget.md deleted file mode 100644 index 1f44ae36c7..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Scripting/Widgets/Right pane widget.md +++ /dev/null @@ -1,32 +0,0 @@ -# Right pane widget -* `doRender` must not be overridden, instead `doRenderBody()` has to be overridden. -* `parentWidget()` must be set to `ā€œrightPaneā€`. -* `widgetTitle()` getter can optionally be overriden, otherwise the widget will be displayed as ā€œUntitled widgetā€. - -``` -const template = `
    Hi
    `; - -class ToDoListWidget extends api.RightPanelWidget { - - get widgetTitle() { - return "Title goes here"; - } - - get parentWidget() { return "right-pane" } - - doRenderBody() { - this.$body.empty().append($(template)); - } - - async refreshWithNote(note) { - this.toggleInt(false); - this.triggerCommand("reEvaluateRightPaneVisibility"); - this.toggleInt(true); - this.triggerCommand("reEvaluateRightPaneVisibility"); - } -} - -module.exports = new ToDoListWidget(); -``` - -The implementation is in `src/public/app/widgets/right_panel_widget.js`. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Building the editor.md b/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Building the editor.md deleted file mode 100644 index 9406170260..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Building the editor.md +++ /dev/null @@ -1,21 +0,0 @@ -# Building the editor -First, make sureĀ Environment setupĀ is set up. - -## Trigger the build - -``` -cd packages/ckeditor5-build-trilium -yarn build -``` - -This will trigger a change in the `build` directory. - -## Copy the build artifact to the main repo - -Go to `packages/ckeditor5-build-balloon-trilium/build` and copy `ckeditor.js` and `ckeditor.js.map` to `libraries/ckeditor` in the `Notes` repository. - -An example shell command to copy it: - -``` -cp build/ckeditor.* ~/Projects/TriliumNext/Notes/libraries/ckeditor/ -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Environment setup.md b/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Environment setup.md deleted file mode 100644 index 76819a12b8..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Environment setup.md +++ /dev/null @@ -1,26 +0,0 @@ -# Environment setup -## Clone the repository - -To set up the repository: - -``` -git clone https://github.com/TriliumNext/trilium-ckeditor5.git -``` - -## Install dependencies - -First, install root dependencies: - -``` -cd trilium-ckeditor5 -yarn install -``` - -Secondly, install the Trilium build dependencies: - -``` -cd packages/ckeditor5-build-trilium -yarn install -``` - -To trigger the build, seeĀ Building the editor. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Updating to a newer version of.md b/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Updating to a newer version of.md deleted file mode 100644 index 6e7808f67b..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Updating to a newer version of.md +++ /dev/null @@ -1,65 +0,0 @@ -# Updating to a newer version of CKEditor -## Before updating - -Make sure that all the plugins are compatible with this version:Ā  Versions and external plugins. If not, they will need to be updated to the same version as the one you are updating, by altering their `package.json`. - -If the plugin is external to the Trilium organisation, it needs to be forked first. - -## Environment setup - -The first step is to add the CKEditor source as a remote. This only needs to be done once. - -``` -git remote add upstream ssh://git@github.com/ckeditor/ckeditor5.git -git fetch upstream -``` - -## Update steps - -Due to how the repository is structured, updates to the CKEditor are a bit difficult. - -1. `git fetch upstream` -2. Pick a version and merge with it: `git merge -X theirs v99.2.0` -3. When there are complicated conflicts, sometimes it's easier to take everything from the target version instead, for a given path: `git checkout v99.2.0 -- "packages/ckeditor5-list/**"`. -4. Go in `packages/ckeditor5-build-trilium/package.json` and run `node sync-version.js` to update the `package.json` with the new versions. Review and commit the change. -5. Follow again the dependency setup inĀ Environment setup, as they have changed. -6. [Run the build](Building%20the%20editor.md) and check that it works. - -## Final steps - -1. Start the TriliumNext server -2. If updated to a newer version of CKEditor, check type `CKEDITOR_VERSION` in the browser/Electron console to ensure that the correct version is used. -3. Do a basic sanity check as well. -4. Commit and push the change on both sides (in the `trilium-ckeditor5` repo and in the `Notes` repo). - -## Troubleshooting client side errors - -These errors might show up when testing the Trilium app: - -``` -ReferenceError: CKEditor is not defined -``` - -Usually this is a side effect of another error, check the logs carefully to see if there is any other related error (perhaps a `CKEditorError`). - -* * * - -``` -Uncaught error: Message: CKEditorError: ckeditor-duplicated-modules -``` - -Most likely cause is one of the external plugins is incompatible with this version. - -For example, to disable the Math plugin, go to `packages/ckeditor5-build-trilium/src/config.ts` and modify: - -```diff --import Math from '@triliumnext/ckeditor5-math/src/math'; --import AutoformatMath from '@triliumnext/ckeditor5-math/src/autoformatmath'; - -export const COMMON_PLUGINS = [ -- Math, -- AutoformatMath, -] -``` - -In this case, make sure to align the version of all the external plugins with the one you are updating to, usually by forking the external plugin and updating its versions. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Versions and external plugins.md b/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Versions and external plugins.md deleted file mode 100644 index 2fe124c314..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/CKEditor/Versions and external plugins.md +++ /dev/null @@ -1,8 +0,0 @@ -# Versions and external plugins -## External plugins - -| | | | -| --- | --- | --- | -| trilium-ckeditor5 | 43.2.0 | | -| `ckeditor5-math` | | SeeĀ ckeditor5-math. | -| | | | \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math.md b/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math.md deleted file mode 100644 index 91b6b265ff..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math.md +++ /dev/null @@ -1,29 +0,0 @@ -# ckeditor5-math -
    ckeditor5-math in action.
    - -A fork of [isaul32/ckeditor5-math](https://github.com/isaul32/ckeditor5-math), which is the CKEditor5 plugin which adds the math functionality. The fork was created to handleĀ #297: Insert Math appears to be broken. - -## Development environment - -* Tested on Node.js 20. -* The package manager is yarn 1 (v1.22.22 is known to be working fine for it at the time of writing). - -Important commands: - -* To check if the code has any formatting issues: `yarn lint` -* To start a live preview: `yarn start` -* To run the tests: `yarn test` - * Note that this requires Chromium, on NixOS this can be achieved by running a `nix-shell -p chromium`, and running `CHROME_BIN=$(which chromium) yarn test` inside it. - -## šŸ“¦ Packages - -The built artifact of the plugin is released by the CI and available on the [GitHub NPM registry](https://github.com/TriliumNext/ckeditor5-math/pkgs/npm/ckeditor5-math). - -Note that due to limitations on GitHub's registry, it is not possible to install this package without setting up a personal access token (even though the package itself is public). SeeĀ [missing note]Ā for more information. - -## ā¬†ļø Integrating withĀ CKEditor - -1. Release a new version:Ā Release management & continuous integration -2. In `trilium-ckeditor5`, go to `packages/ckeditor5-build-trilium/package.json` in the CKEditor repository and change the dependency of `@triliumnext/ckeditor5-math` to the newly released version. -3. Run `yarn install`. -4. Proceed withĀ Building the editorĀ to integrate everything into TriliumNext and then commit the change. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math/Release management & continuou.md b/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math/Release management & continuou.md deleted file mode 100644 index 1511f4bfcd..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math/Release management & continuou.md +++ /dev/null @@ -1,16 +0,0 @@ -# Release management & continuous integration -To automate the release process, a GitHub workflow has been added which builds the package and releases it over to GitHub NPM registry. - -The workflow publishes a release whenever a tag with the correct format is pushed. - -The steps are as follows: - -1. Ensure that the source code is clean and ready for a release. -2. Go to `package.json` and bump the `version` field. -3. Commit the changes. -4. Tag the commit with `v1.2.3`, with the correct version number. -5. Push the changes. - -Then follow the CI and it should indicate success. Afterwards, check the [package](https://github.com/TriliumNext/ckeditor5-math/pkgs/npm/ckeditor5-math)section to ensure that the package is in the ā€œRecent Versionsā€ section. - -If the changes could benefit upstream, consider opening a pull request with the changes there as well. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math/Updating with upstream.md b/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math/Updating with upstream.md deleted file mode 100644 index b690033581..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Sub-projects/ckeditor5-math/Updating with upstream.md +++ /dev/null @@ -1,21 +0,0 @@ -# Updating with upstream -If there was a change in the upstream repository ([isaul32/ckeditor5-math](https://github.com/isaul32/ckeditor5-math)), it can be integrated as follows: - -1. Add the upstream as remote (`git remote add upstream ssh://git@github.com/isaul32/ckeditor5-math.git`). -2. Fetch the changes: `git fetch upstream` -3. Merge with a tag: `git merge v43.1.2` -4. Solve the conflict in `package.json` by: - 1. Taking the same version as the upcoming one and appending `-hotfix1`. - 2. Keeping the `@triliumnext/ckeditor5-math` name. -5. Install dependencies: `yarn install` -6. Check that the build works via `yarn prepublishOnly`. -7. Commit the changes, push them. -8. Release a version withĀ Release management & continuous integration. - -## CI job not triggered after pushing all the upstream tags - -If the CI job was not triggered, you might have accidentally pushed a lot of tags using `git push --tags`. Manually delete the tag and push it again: - -```diff -git push -d origin v43.1.2-hotfix1 && git push --tags -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/1_Setting up authentication_.png b/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/1_Setting up authentication_.png deleted file mode 100644 index 020472c6d9..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/1_Setting up authentication_.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Running tests.md b/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Running tests.md deleted file mode 100644 index 3ab98a39c4..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Running tests.md +++ /dev/null @@ -1,38 +0,0 @@ -# Running tests -## First-time run - -Before starting Playwright, it has to be installed locally via: - -``` -npx playwright install -``` - -## Starting the integration test server - -There are two types of integration test servers: - -* `npm run integration-mem-db` will run a server with dev mode disabled. - * This is usually what the end user will see when accessing a server instance. - * It will not test the Electron/desktop side of the application. - * Changes to the public scripts will not take effect until running `npm run webpack`. -* `npm run integration-mem-db-dev` will run a server with dev mode enabled. - * This is usually what a dev sees when running `npm run start-server`. - * The difference with the production one is that the assets are loaded directly from files and as such it does not require `npm run webpack` to see changes. - -Either options will open up a server on [localhost:8082](http://localhost:8082) that can be accessed either manually via the browser or via Playwright. - -When asked for a password, the password is `demo1234`. - -## Starting the interactive test runner - -After starting the integration test server, to run the Playwright UI, run in the terminal: - -``` -npx playwright test --ui -``` - -It is also possible to run the interactive code generator instead: - -``` -npx playwright codegen -``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Setting up authentication.md b/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Setting up authentication.md deleted file mode 100644 index 4df7880fe9..0000000000 --- a/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Setting up authentication.md +++ /dev/null @@ -1,12 +0,0 @@ -# Setting up authentication -There is a setup test that stores the authentication token so that it can be reused throughout all the tests. - -If tests fail due to being stuck on login, then it must be run. - -To run it manually press ā€œallā€ near the ā€œStatus:ā€ text on top-left of the window - -
    - -Then check ā€œsetupā€ and look for `auth.setup.ts` and press its corresponding Run button: - -
    \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Setting up authentication_.png b/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Setting up authentication_.png deleted file mode 100644 index 4b260dfbc7..0000000000 Binary files a/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Setting up authentication_.png and /dev/null differ diff --git a/docs/Developer Guide/Developer Guide/Project Structure.md b/docs/Developer Guide/Developer Guide/Project Structure.md index ff0c954a26..2e2a5438d4 100644 --- a/docs/Developer Guide/Developer Guide/Project Structure.md +++ b/docs/Developer Guide/Developer Guide/Project Structure.md @@ -1,5 +1,5 @@ # Project Structure -As the application grew in complexity, our build system was growing even more difficult to maintain and was spread across multiple repositories. As such we have decided to use a mono-repo approach, and to do so we chose to have NX manage our mono-repo. +As the application grew in complexity, we decided to switch to a monorepo based on `pnpm`. Our initial monorepo implementation used NX, but we've switched to pure `pnpm` workspaces and our own build scripts. ## Project structure @@ -9,48 +9,22 @@ The mono-repo is mainly structured in: * `client`, representing the front-end that is used both by the server and the desktop application. * `server`, representing the Node.js / server version of the application. * `desktop`, representing the Electron-based desktop application. + * `web-clipper`, representing the browser extension to easily clip web pages into Trilium, with support for both Firefox and Chrome (manifest V3). * `packages`, containing dependencies used by one or more `apps`. * `commons`, containing shared code for all the apps. -## Working with NX - -### Running tasks via the CLI +## Working with the project For example to run the server instance: ``` -pnpm exec nx run server:serve +pnpm server:start ``` -NX has built-in cache support which should make development much faster. Sometimes, it can get in the way; to skip the cache simply append `--skip-nx-cache` to the command you are running. +## Running and building -### Running tasks using Visual Studio Code - -If you are using Visual Studio Code as your development tool for Trilium, consider using the NX Console. It allows running tasks/targets much easier via the dedicated tab. Right-click a target in the list for more options, such as bypassing the cache. - -## Important tasks - -Each application has a number of tasks (called _targets_ by NX). Here's a non-exhaustive list of the tasks that are useful during development. - -To run any of the task use `pnpm exec nx run project:task`, or use the Visual Studio Code integration as described above. - -* `client`: - * The client is not meant to be run by itself, despite being described as an app. See the documentation on the server instead. -* `server`: - * To run the server in development mode, run `client:serve` (which will only serve the public assets), followed by `server:serve` (which will proxy the assets of the client as well). The dev port remains the same as always, `8080`. - * To run the server in production mode (with its own copy of the assets), run `server:start-prod`. - * To build the server for Docker, run `docker-build` which will automatically build and tag the image if Docker is installed locally. - * Similarly, run `docker-start` to build and run the Docker image. -* `desktop`: - * To run the desktop, run `desktop:serve`. - * Unlike the server, this one does not require the client since it will automatically get a production copy of it. The only downside is that modifications to the code will only take effect after restarting the task. - -## Building packages - -Generally, the building process of a project generates a `dist` folder containing everything needed for production. To trigger a build run `pnpm nx build project` where `project` is the name of a project from either `apps` or `packages`. +Each application has a number of tasks. Here's a non-exhaustive list of the tasks that are useful during development. SeeĀ Building. ## Managing dependencies across the mono-repo -We are using [pnpm workspaces](https://pnpm.io/workspaces) to manage the project structure, further augmented by NX which is described in a different section. - -The workspace configuration is in `pnpm-workspace.yaml` at project level but it generally should not be modified. \ No newline at end of file +We are using [pnpm workspaces](https://pnpm.io/workspaces) to manage the project structure. The workspace configuration is in `pnpm-workspace.yaml` at project level but it generally should not be modified. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Testing.md b/docs/Developer Guide/Developer Guide/Testing.md similarity index 54% rename from docs/Developer Guide/Developer Guide/Old documentation/Testing.md rename to docs/Developer Guide/Developer Guide/Testing.md index 95efd99192..570f52ded2 100644 --- a/docs/Developer Guide/Developer Guide/Old documentation/Testing.md +++ b/docs/Developer Guide/Developer Guide/Testing.md @@ -1,4 +1,48 @@ # Testing +### Test Organization + +**Parallel Tests** (can run simultaneously): + +* Client tests +* Package tests +* E2E tests (isolated databases) + +**Sequential Tests** (shared resources): + +* Server tests (shared database) +* CKEditor plugin tests + +### Test Frameworks + +* **Vitest** - Unit and integration tests +* **Playwright** - E2E tests +* **Happy-DOM** - DOM testing environment + +## Test locations + +``` +apps/ +ā”œā”€ā”€ server/ +│ └── src/**/*.spec.ts # Server tests +ā”œā”€ā”€ client/ +│ └── src/**/*.spec.ts # Client tests +└── server-e2e/ +│ └── tests/**/*.spec.ts # E2E tests +└── desktop/ + └── e2e + └── tests/**/*.spec.ts # E2E tests +``` + +## Running tests + +At project root: + +``` +pnpm test:all # All tests +pnpm test:parallel # Fast parallel tests +pnpm test:sequential # Sequential tests only +``` + ## Unit testing and integration testing Using `vitest`, there are some unit and integration tests done for both the client and the server. @@ -17,17 +61,14 @@ Note that some integration tests rely on an in-memory database in order to funct ### REST API testing for the server -Some original work was done by Zadam in `/test-etapi`, using `.http` files. - -New effort using `vitest` and `supertest` to initialize the Express server and run assertions without having to make actual requests to the server. +API tests are handled via `vitest` and `supertest` to initialize the Express server and run assertions without having to make actual requests to the server. An important aspect is that we have access to the Express `app` which allows for interesting assertions such as checking the state of the server, registering debug middleware and so on. -One example is `src/share/routes.spec.ts`. +One example is `src/share/routes.spec.ts`, or for the ETAPI in `apps/server/spec/etapi`. These integration tests are run alongside unit tests. ## End-to-end testing -* This tests both the client and the server, by running the server and then using Playwright to query the state of the page. -* These can be found in `/e2e`. \ No newline at end of file +SeeĀ End-to-end tests. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Testing/End-to-end tests.md b/docs/Developer Guide/Developer Guide/Testing/End-to-end tests.md new file mode 100644 index 0000000000..60060adaee --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Testing/End-to-end tests.md @@ -0,0 +1,40 @@ +# End-to-end tests +**Server E2E:** + +* Tests the entire ETAPI. +* Tests WebSocket functionality + +**Desktop E2E:** + +* Playwright with Electron +* Tests some basic functionality such as creating a new document. + +These can be found in `apps/server-e2e` and `apps/desktop/e2e`. + +## First-time run + +Before starting Playwright, it has to be installed locally via: + +``` +pnpm playwright install +``` + +## Starting the integration test server + +Simply run `pnpm e2e` in one of the e2e projects. + +The integration server doesn't have authentication enabled to avoid login issues. + +## Starting the interactive test runner + +After starting the integration test server, to run the Playwright UI, run in the terminal: + +``` +pnpm playwright test --ui +``` + +It is also possible to run the interactive code generator instead: + +``` +pnpm playwright codegen +``` \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/AI/AI Provider Information/OpenAI.html b/docs/Developer Guide/Developer Guide/Testing/Integration testing.md similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/AI/AI Provider Information/OpenAI.html rename to docs/Developer Guide/Developer Guide/Testing/Integration testing.md diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Test database.md b/docs/Developer Guide/Developer Guide/Testing/Test database.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Old documentation/Testing/Integration testing/Test database.md rename to docs/Developer Guide/Developer Guide/Testing/Test database.md diff --git a/docs/Developer Guide/Developer Guide/Testing/Unit tests.md b/docs/Developer Guide/Developer Guide/Testing/Unit tests.md new file mode 100644 index 0000000000..a009b8d92b --- /dev/null +++ b/docs/Developer Guide/Developer Guide/Testing/Unit tests.md @@ -0,0 +1,7 @@ +# Unit tests +At project level: + +* `pnpm server:test` +* `pnpm client:test` + +Unit tests are stored in the same directory as the source code being tested, with the `.spec.ts` suffix. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Old documentation/Troubleshooting/Error [TransformError] The pac.md b/docs/Developer Guide/Developer Guide/Troubleshooting/Error [TransformError] The pac.md similarity index 99% rename from docs/Developer Guide/Developer Guide/Old documentation/Troubleshooting/Error [TransformError] The pac.md rename to docs/Developer Guide/Developer Guide/Troubleshooting/Error [TransformError] The pac.md index 8a93a52bea..82a5d93a8f 100644 --- a/docs/Developer Guide/Developer Guide/Old documentation/Troubleshooting/Error [TransformError] The pac.md +++ b/docs/Developer Guide/Developer Guide/Troubleshooting/Error [TransformError] The pac.md @@ -36,5 +36,5 @@ The solution is to remove `node_modules` and reinstall all dependencies: ``` rm -r node_modules -npm install +pnpm install ``` \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Troubleshooting/better-sqlite3 was compiled ag.md b/docs/Developer Guide/Developer Guide/Troubleshooting/better-sqlite3 was compiled ag.md index af8d7c70ac..a048e3b4ea 100644 --- a/docs/Developer Guide/Developer Guide/Troubleshooting/better-sqlite3 was compiled ag.md +++ b/docs/Developer Guide/Developer Guide/Troubleshooting/better-sqlite3 was compiled ag.md @@ -1,6 +1,6 @@ # better-sqlite3 was compiled against a different Node.js version This generally can happen when running the development version of either the `desktop` or `server`, but it should not happen as often as it used to. The reason is that `better-sqlite3` is a native dependency and has different builds for either the system's Node.js (as used by the `server`), or Electron's one (as used by the `desktop`). -To solve this, go to `apps/server` and run `pnpm rebuild`. For Electron this step is not necessary as it's already handled by the `rebuild-deps` NX target. +To solve this, go to `apps/server` and run `pnpm rebuild`. For Electron (`desktop`) this step generally not necessary, however `pnpm postinstall` should solve it. If you can reproduce this issue consistently, please open a bug report. \ No newline at end of file diff --git a/docs/README-ZH_CN.md b/docs/README-ZH_CN.md index e63f1da63f..682a30e3d0 100644 --- a/docs/README-ZH_CN.md +++ b/docs/README-ZH_CN.md @@ -1,97 +1,256 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + # Trilium Notes -[English](../README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads +(ę‰€ęœ‰čµ„äŗ§ļ¼Œę‰€ęœ‰åŽ†å²ē‰ˆęœ¬)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![ēæ»čÆ‘ēŠ¶ę€](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) -Trilium Notes ę˜Æäø€äøŖå±‚ę¬”åŒ–ēš„ē¬”č®°åŗ”ē”ØēØ‹åŗļ¼Œäø“ę³ØäŗŽå»ŗē«‹å¤§åž‹äøŖäŗŗēŸ„čÆ†åŗ“ć€‚čÆ·å‚é˜…[å±å¹•ęˆŖå›¾](https://triliumnext.github.io/Docs/Wiki/screenshot-tour)ä»„åæ«é€Ÿäŗ†č§£ļ¼š + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + -Trilium Screenshot +Trilium Notes ę˜Æäø€ę¬¾å…č“¹äø”å¼€ęŗć€č·Øå¹³å°ēš„é˜¶å±‚å¼ē¬”č®°åŗ”ē”ØēØ‹åŗļ¼Œäø“ę³ØäŗŽå»ŗē«‹å¤§åž‹äøŖäŗŗēŸ„čÆ†åŗ“ć€‚ -## āš ļø äøŗä»€ä¹ˆé€‰ę‹©TriliumNext? +Trilium Screenshot -[åŽŸå§‹ēš„Triliumé”¹ē›®ē›®å‰å¤„äŗŽē»“ęŠ¤ęØ”å¼](https://github.com/zadam/trilium/issues/4620) +## ā¬ äø‹č½½ +- [ęœ€ę–°ē‰ˆęœ¬](https://github.com/TriliumNext/Trilium/releases/latest) – + ēØ³å®šē‰ˆęœ¬ļ¼ŒęŽØčē»™å¤§å¤šę•°ē”Øęˆ·ć€‚ +- [ęÆę—„ęž„å»ŗ](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + äøēØ³å®šå¼€å‘ē‰ˆęœ¬ļ¼ŒęÆę—„ę›“ę–°ļ¼ŒåŒ…å«ęœ€ę–°åŠŸčƒ½äøŽäæ®å¤ć€‚ -## šŸ—­ äøŽęˆ‘ä»¬č®Øč®ŗ +## šŸ“– ꖇ件 -ę¬¢čæŽåŠ å…„ęˆ‘ä»¬ēš„å®˜ę–¹č®Øč®ŗå’Œē¤¾åŒŗć€‚ęˆ‘ä»¬äø“ę³ØäŗŽTriliumēš„å¼€å‘ļ¼Œä¹äŗŽå¬å–ę‚ØåÆ¹åŠŸčƒ½ć€å»ŗč®®ęˆ–é—®é¢˜ēš„ę„č§ļ¼ +**čÆ·č®æé—®ęˆ‘ä»¬å®Œę•“ēš„ę–‡ę”£ļ¼š[docs.triliumnotes.org](https://docs.triliumnotes.org/)** -- [Matrix](https://matrix.to/#/#triliumnext:matrix.org)ļ¼ˆē”ØäŗŽåŒę­„č®Øč®ŗļ¼‰ -- [Github Discussions](https://github.com/TriliumNext/Notes/discussions)ļ¼ˆē”ØäŗŽå¼‚ę­„č®Øč®ŗļ¼‰ -- [Wiki](https://triliumnext.github.io/Docs/)ļ¼ˆē”ØäŗŽåøøč§ę“ä½œé—®é¢˜å’Œē”Øęˆ·ęŒ‡å—ļ¼‰ +ęˆ‘ä»¬ēš„ę–‡ę”£ęœ‰å¤šē§ę ¼å¼åÆä¾›ä½æē”Øļ¼š +- **åœØēŗæę–‡ę”£**ļ¼ščÆ·č®æé—®ęˆ‘ä»¬å®Œę•“ēš„ę–‡ę”£ļ¼š[docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **åŗ”ē”Øå†…åø®åŠ©**:在 Trilium äø­ęŒ‰äø‹`F1`å³åÆē›“ęŽ„åœØåŗ”ē”ØēØ‹åŗå†…č®æé—®ē›øåŒę–‡ę”£ +- **GitHub**ļ¼šęµč§ˆę­¤å­˜å‚Øåŗ“äø­ēš„[ē”Øęˆ·ęŒ‡å—](./User%20Guide/User%20Guide/) -äøŠé¢é“¾ęŽ„ēš„äø¤äøŖęˆæé—“ę˜Æé•œåƒēš„ļ¼Œę‰€ä»„ę‚ØåÆä»„åœØä»»ę„å¹³å°äøŠä½æē”ØXMPPꈖ者Matrixę„å’Œęˆ‘ä»¬äŗ¤ęµć€‚ +### åæ«é€Ÿé“¾ęŽ„ +- [ē”Øęˆ·čÆ“ę˜Ž](https://docs.triliumnotes.org/) +- [å®‰č£…čÆ“ę˜Ž](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + 设置](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [å‡ēŗ§ TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [åŸŗęœ¬ę¦‚åæµäøŽē‰¹ę€§](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [äøŖäŗŗēŸ„čÆ†åŗ“ęØ”å¼](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) -### éžå®˜ę–¹ē¤¾åŒŗ +## šŸŽ 功能 -[Trilium Rocks](https://discord.gg/aqdX9mXX4r) +* ē¬”č®°åÆē»„ē»‡ęˆä»»ę„ę·±åŗ¦ēš„ę ‘å½¢ē»“ęž„ć€‚å•äø€ē¬”č®°åÆę”¾åœØę ‘äø­ēš„å¤šäøŖä½ē½®ļ¼ˆå‚č§ + [ē¬”č®°å¤åˆ¶/克隆](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* äø°åÆŒēš„ę‰€č§å³ę‰€å¾—ļ¼ˆWYSIWYGļ¼‰ē¬”č®°ē¼–č¾‘å™Øļ¼Œę”ÆęŒč”Øę ¼ć€å›¾ē‰‡äøŽ[ę•°å­¦å…¬å¼](https://docs.triliumnotes.org/user-guide/note-types/text)ļ¼Œå¹¶å…·å¤‡ + Markdown + ēš„[č‡ŖåŠØę ¼å¼](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* ę”ÆęŒē¼–č¾‘[ēØ‹åŗä»£ē ē¬”č®°](https://docs.triliumnotes.org/user-guide/note-types/code), + ļ¼ŒåŒ…å«čÆ­ę³•é«˜äŗ® +* åæ«é€Ÿć€č½»ę¾åœ°åœØē¬”č®°é—“[导航](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation)ć€å…Øę–‡ęœē“¢ļ¼Œä»„åŠ[ē¬”č®°čšē„¦ļ¼ˆhoisting)](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* ę— ē¼ēš„[ē¬”č®°ē‰ˆęœ¬ē®”ē†](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* 笔记[å±žę€§](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes)åÆē”ØäŗŽē¬”č®°ēš„ē»„ē»‡ć€ęŸ„čÆ¢äøŽé«˜ēŗ§[č„šęœ¬](https://docs.triliumnotes.org/user-guide/scripts) +* ęŽ„å£ęä¾›č‹±ę–‡ć€å¾·ę–‡ć€č„æē­ē‰™ę–‡ć€ę³•ę–‡ć€ē½—é©¬å°¼äŗšę–‡äøŽäø­ę–‡ļ¼ˆē®€ä½“äøŽę­£ä½“ļ¼‰ +* ē›“ęŽ„ę•“åˆ[OpenID äøŽ TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) + ä»„å®žēŽ°ę›“å®‰å…Øēš„ē™»å½• +* äøŽč‡Ŗęž¶ēš„åŒę­„ęœåŠ”å™Øčæ›č”Œ[同歄](https://docs.triliumnotes.org/user-guide/setup/synchronization) + * ꜉[ē¬¬äø‰ę–¹ęœåŠ”ē”ØäŗŽę‰˜ē®”åŒę­„ęœåŠ”å™Ø](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* 将笔记[åˆ†äŗ«](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing)ļ¼ˆå…¬å¼€å‘åøƒļ¼‰åˆ°äŗ’č”ē½‘ +* ä»„ęÆåˆ™ē¬”č®°äøŗē²’åŗ¦ēš„å¼ŗå¤§ + [ē¬”č®°åŠ åÆ†](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) +* ę‰‹ē»˜/ē¤ŗę„å›¾ļ¼šåŸŗäŗŽ [Excalidraw](https://excalidraw.com/) ļ¼ˆē¬”č®°ē±»åž‹äøŗć€Œcanvasć€ļ¼‰ +* ē”ØäŗŽåÆč§†åŒ–ē¬”č®°åŠå…¶å…³ē³»ēš„[关系图](https://docs.triliumnotes.org/user-guide/note-types/relation-map)和[笔记/é“¾ęŽ„å›¾](https://docs.triliumnotes.org/user-guide/note-types/note-map) +* ę€ē»“åÆ¼å›¾ļ¼šåŸŗäŗŽ[Mind Elixir](https://docs.mind-elixir.com/) +* å…·ęœ‰å®šä½é’‰äøŽ GPX + č½Øčæ¹ēš„[地图](https://docs.triliumnotes.org/user-guide/collections/geomap) +* [č„šęœ¬](https://docs.triliumnotes.org/user-guide/scripts) - å‚č§ + [é«˜ēŗ§å±•ē¤ŗ](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* ē”ØäŗŽč‡ŖåŠØåŒ–ēš„ [REST + API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) +* åœØåÆē”Øę€§äøŽę•ˆčƒ½äøŠå‡åÆč‰Æå„½ę‰©å±•ļ¼Œę”ÆęŒč¶…čæ‡ 100,000 笔笔记 +* äøŗę‰‹ęœŗäøŽå¹³ęæä¼˜åŒ–ēš„[ē§»åŠØå‰ē«Æ](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) +* 内置[ę·±č‰²äø»é¢˜](https://docs.triliumnotes.org/user-guide/concepts/themes) +* [Evernote + 导兄](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote)äøŽ + [Markdown + åÆ¼å…„äøŽåÆ¼å‡ŗ](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* ē”ØäŗŽåæ«é€Ÿäæå­˜ē½‘é”µå†…å®¹ēš„ [Web + Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) +* åÆč‡Ŗå®šä¹‰ēš„ UIļ¼ˆä¾§č¾¹ę ęŒ‰é’®ć€ē”Øęˆ·č‡Ŗå®šä¹‰å°ē»„ä»¶ē­‰ļ¼‰ +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics)ļ¼Œä»„åŠ + Grafana ä»Ŗč”Øęæć€‚ -## šŸŽ 特性 +✨ ęƒ³č¦ę›“å¤š TriliumNext ēš„äø»é¢˜ć€č„šęœ¬ć€å¤–ęŒ‚äøŽčµ„ęŗļ¼Œäŗ¦åÆå‚č€ƒä»„äø‹ē¬¬äø‰ę–¹čµ„ęŗļ¼ē¤¾ē¾¤ļ¼š -* ē¬”č®°åÆä»„ęŽ’åˆ—ęˆä»»ę„ę·±ēš„ę ‘ć€‚å•äøŖē¬”č®°åÆä»„ę”¾åœØę ‘äø­ēš„å¤šäøŖä½ē½®ļ¼ˆčÆ·å‚é˜…[克隆](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) -* äø°åÆŒēš„ę‰€č§å³ę‰€å¾—ē¬”č®°ē¼–č¾‘åŠŸčƒ½ļ¼ŒåŒ…ę‹¬åø¦ęœ‰ Markdown [č‡ŖåŠØę ¼å¼åŒ–åŠŸčƒ½ēš„](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)č”Øę ¼ļ¼Œå›¾åƒå’Œ[ę•°å­¦å…¬å¼](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) -* ę”ÆęŒē¼–č¾‘[ä½æē”Øęŗä»£ē ēš„ē¬”č®°](https://triliumnext.github.io/Docs/Wiki/code-notes)ļ¼ŒåŒ…ę‹¬čÆ­ę³•é«˜äŗ®ę˜¾ē¤ŗ -* ē¬”č®°ä¹‹é—“åæ«é€Ÿ[导航](https://triliumnext.github.io/Docs/Wiki/note-navigation)ļ¼Œå…Øę–‡ęœē“¢å’Œ[ęå‡ē¬”č®°](https://triliumnext.github.io/Docs/Wiki/note-hoisting) -* ę— ē¼[ē¬”č®°ē‰ˆęœ¬ęŽ§åˆ¶](https://triliumnext.github.io/Docs/Wiki/note-revisions) -* 笔记[å±žę€§](https://triliumnext.github.io/Docs/Wiki/attributes)åÆē”ØäŗŽē¬”č®°ē»„ē»‡ļ¼ŒęŸ„čÆ¢å’Œé«˜ēŗ§[č„šęœ¬ē¼–å†™](https://triliumnext.github.io/Docs/Wiki/scripts) -* [同歄](https://triliumnext.github.io/Docs/Wiki/synchronization)äøŽč‡Ŗę‰˜ē®”åŒę­„ęœåŠ”å™Ø - * ęœ‰äø€äøŖ[ē¬¬äø‰ę–¹ęä¾›ēš„åŒę­„ęœåŠ”å™Øę‰˜ē®”ęœåŠ”](https://trilium.cc/paid-hosting) -* 公开地[åˆ†äŗ«](https://triliumnext.github.io/Docs/Wiki/sharing)ļ¼ˆå‘åøƒļ¼‰ē¬”č®°åˆ°äŗ’č”ē½‘ -* å…·ęœ‰ęŒ‰ē¬”č®°ē²’åŗ¦ēš„å¼ŗå¤§ēš„[ē¬”č®°åŠ åÆ†](https://triliumnext.github.io/Docs/Wiki/protected-notes) -* ä½æē”Øč‡Ŗåø¦ēš„ Excalidraw ę„ē»˜åˆ¶å›¾č”Øļ¼ˆē¬”č®°ē±»åž‹ā€œē”»åøƒā€ļ¼‰ -* [关系图](https://triliumnext.github.io/Docs/Wiki/relation-map)和[é“¾ęŽ„å›¾](https://triliumnext.github.io/Docs/Wiki/link-map)ļ¼Œē”ØäŗŽåÆč§†åŒ–ē¬”č®°åŠå…¶å…³ē³» -* [č„šęœ¬](https://triliumnext.github.io/Docs/Wiki/scripts) - čÆ·å‚é˜…[é«˜ēŗ§åŠŸčƒ½å±•ē¤ŗ](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) -* åÆē”ØäŗŽč‡ŖåŠØåŒ–ēš„ [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) -* åœØę‹„ęœ‰č¶…čæ‡ 10 äø‡ę”ē¬”č®°ę—¶ä»čƒ½äæęŒč‰Æå„½ēš„åÆē”Øę€§å’Œę€§čƒ½ -* é’ˆåÆ¹ę™ŗčƒ½ę‰‹ęœŗå’Œå¹³ęæē”µč„‘čæ›č”Œä¼˜åŒ–ēš„[ē”ØäŗŽē§»åŠØč®¾å¤‡ēš„å‰ē«Æ](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) -* [å¤œé—“äø»é¢˜](https://triliumnext.github.io/Docs/Wiki/themes) -* [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) 和 [Markdown 导兄导出](https://triliumnext.github.io/Docs/Wiki/markdown)功能 -* 使用[ē½‘é”µå‰Ŗč—](https://triliumnext.github.io/Docs/Wiki/web-clipper)č½»ę¾äæå­˜äŗ’č”ē½‘äøŠēš„å†…å®¹ +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) ļ¼ˆē¬¬äø‰ę–¹äø»é¢˜ć€č„šęœ¬ć€å¤–ęŒ‚äøŽę›“å¤šļ¼‰ć€‚ +- [TriliumRocks!](https://trilium.rocks/) ļ¼ˆę•™å­¦ć€ęŒ‡å—ē­‰ē­‰ļ¼‰ć€‚ -✨ ęŸ„ēœ‹ä»„äø‹ē¬¬äø‰ę–¹čµ„ęŗļ¼ŒčŽ·å–ę›“å¤šå…³äŗŽTriliumNextēš„å„½äøœč„æļ¼š +## āš ļø äøŗä»€ä¹ˆę˜Æ TriliumNext? -- [awesome-trilium](https://github.com/Nriver/awesome-trilium)ļ¼šęä¾›ē¬¬äø‰ę–¹äø»é¢˜ć€č„šęœ¬ć€ę’ä»¶ē­‰čµ„ęŗēš„åˆ—č”Øć€‚ -- [TriliumRocks!](https://trilium.rocks/)ļ¼šęä¾›ę•™ēØ‹ć€ęŒ‡å—ē­‰ę›“å¤šå†…å®¹ć€‚ +Trilium ēš„åŽŸå§‹å¼€å‘č€…ļ¼ˆ[Zadam](https://github.com/zadam)ļ¼‰å·²ę…·ę…Øåœ°å°† Trilium +ä»£ē åŗ“ē§»äŗ¤č‡³ē¤¾åŒŗé”¹ē›®ļ¼ŒčÆ„é”¹ē›®ēŽ°ę‰˜ē®”äŗŽļ¼šhttps://github.com/TriliumNext -## šŸ— ęž„å»ŗ +### ā¬†ļø 从 Trilium 迁移? -Trilium åÆä»„ē”Øä½œę”Œé¢åŗ”ē”ØēØ‹åŗļ¼ˆLinux 和 Windowsļ¼‰ęˆ–ęœåŠ”å™Øļ¼ˆLinuxļ¼‰äøŠę‰˜ē®”ēš„ Web åŗ”ē”ØēØ‹åŗć€‚č™½ē„¶ęœ‰ macOS ē‰ˆęœ¬ēš„ę”Œé¢åŗ”ē”ØēØ‹åŗļ¼Œä½†å®ƒ[äøå—ę”ÆęŒ](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support)怂 +ä»Žę—¢ęœ‰ēš„ zadam/Trilium ä¾‹é”¹čæē§»åˆ° TriliumNext/Notes äøéœ€č¦ē‰¹åˆ«ēš„čæē§»ę­„éŖ¤ć€‚åŖč¦[ē…§äø€čˆ¬ę–¹å¼å®‰č£… +TriliumNext/Notes](#-installation)(#-安装)ļ¼Œå®ƒå°±ä¼šē›“ęŽ„ä½æē”Øä½ ēŽ°ęœ‰ēš„ę•°ę®åŗ“ć€‚ -* å¦‚ęžœč¦åœØę”Œé¢äøŠä½æē”Ø Triliumļ¼ŒčÆ·ä»Ž[ęœ€ę–°ē‰ˆęœ¬](https://github.com/TriliumNext/Notes/releases/latest)äø‹č½½é€‚ē”ØäŗŽę‚Øå¹³å°ēš„äŗŒčæ›åˆ¶ē‰ˆęœ¬ļ¼Œč§£åŽ‹ē¼©čÆ„č½Æä»¶åŒ…å¹¶čæč”Œ`trilium`åÆę‰§č”Œę–‡ä»¶ć€‚ -* å¦‚ęžœč¦åœØęœåŠ”å™ØäøŠå®‰č£… Triliumļ¼ŒčÆ·å‚č€ƒ[ę­¤é”µé¢](https://triliumnext.github.io/Docs/Wiki/server-installation)怂 - * å½“å‰ä»…ę”ÆęŒļ¼ˆęµ‹čÆ•čæ‡ļ¼‰ęœ€čæ‘å‘åøƒēš„ Chrome 和 Firefox ęµč§ˆå™Øć€‚ +ē‰ˆęœ¬č‡³å¤šč‡³ [v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) äøŽ +zadam/trilium ęœ€ę–°ē‰ˆęœ¬ +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7)å…¼å®¹ć€‚ä¹‹åŽēš„ +TriliumNext ē‰ˆęœ¬å·²ęå‡åŒę­„ē‰ˆęœ¬å·ļ¼ˆäøŽäøŠčæ°äøå†å…¼å®¹ļ¼‰ć€‚ -Trilium ä¹Ÿęä¾› Flatpak: +## šŸ’¬ äøŽęˆ‘ä»¬äŗ¤ęµ -[](https://flathub.org/apps/details/com.github.zadam.trilium) +ę¬¢čæŽåŠ å…„å®˜ę–¹ē¤¾ē¾¤ć€‚ęˆ‘ä»¬å¾ˆä¹ę„å¬åˆ°ä½ åÆ¹åŠŸčƒ½ć€å»ŗč®®ęˆ–é—®é¢˜ēš„ęƒ³ę³•ļ¼ -## šŸ“ 文攣 +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org)ļ¼ˆåŒę­„č®Øč®ŗļ¼‰ + - `General` Matrix ęˆæé—“ä¹Ÿę”„ęŽ„åˆ° [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [GitHub + Discussions](https://github.com/TriliumNext/Trilium/discussions)ļ¼ˆå¼‚ę­„č®Øč®ŗļ¼‰ć€‚ +- [GitHub Issues](https://github.com/TriliumNext/Trilium/issues)ļ¼ˆå›žęŠ„é”™čÆÆäøŽęå‡ŗåŠŸčƒ½éœ€ę±‚ļ¼‰ć€‚ -[ęœ‰å…³ę–‡ę”£é”µé¢ēš„å®Œę•“åˆ—č”Øļ¼ŒčÆ·å‚č§ Wiki怂](https://triliumnext.github.io/Docs/) +## šŸ— 安装 -* [Wiki ēš„äø­ę–‡ēæ»čÆ‘ē‰ˆęœ¬](https://github.com/baddate/trilium/wiki/) +### Windows / macOS + +从[ęœ€ę–°é‡Šå‡ŗé”µé¢](https://github.com/TriliumNext/Trilium/releases/latest)äø‹č½½ä½ å¹³å°ēš„äŗŒčæ›åˆ¶ę–‡ä»¶ļ¼Œč§£åŽ‹ē¼©åŽę‰§č”Œ +`trilium` åÆę‰§č”Œę–‡ä»¶ć€‚ + +### Linux + +å¦‚ęžœä½ ēš„å‘č”Œē‰ˆå¦‚äø‹č”Øę‰€åˆ—ļ¼ŒčÆ·ä½æē”ØčÆ„å‘č”Œē‰ˆēš„å„—ä»¶ć€‚ + +[![ę‰“åŒ…ēŠ¶ę€](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +ä½ ä¹ŸåÆä»„ä»Ž[ęœ€ę–°é‡Šå‡ŗé”µé¢](https://github.com/TriliumNext/Trilium/releases/latest)äø‹č½½åÆ¹åŗ”å¹³å°ēš„äŗŒčæ›åˆ¶ę–‡ä»¶ļ¼Œč§£åŽ‹ē¼©åŽę‰§č”Œ +`trilium` åÆę‰§č”Œę–‡ä»¶ć€‚ + +TriliumNext ä¹Ÿęä¾› Flatpakļ¼ŒęƒŸå°šęœŖå‘åøƒåˆ° FlatHub怂 + +### ęµč§ˆå™Øļ¼ˆä»»ä½•ę“ä½œē³»ē»Ÿļ¼‰ + +č‹„ä½ ęœ‰ļ¼ˆå¦‚äø‹ę‰€čæ°ēš„ļ¼‰ęœåŠ”å™Øå®‰č£…ļ¼Œä¾æåÆē›“ęŽ„å­˜å–ē½‘é”µē•Œé¢ļ¼ˆå…¶äøŽę”Œé¢åŗ”ē”Øå‡ ä¹Žē›øåŒļ¼‰ć€‚ + +ē›®å‰ä»…ę”ÆęŒļ¼ˆå¹¶å®žęµ‹ļ¼‰ęœ€ę–°ē‰ˆēš„ Chrome äøŽ Firefox怂 + +### ē§»åŠØč£…ē½® + +č‹„č¦åœØč”ŒåŠØč£…ē½®äøŠä½æē”Ø TriliumNextļ¼Œä½ åÆä»„é€čæ‡ē§»åŠØęŸ„ēœ‹å™Øå­˜å–ęœåŠ”å™Øå®‰č£…ēš„ē§»åŠØē‰ˆęŽ„å£ļ¼ˆč§äø‹ļ¼‰ć€‚ + +ęœ‰å…³ē§»åŠØåŗ”ē”Øę”ÆęŒēš„ę›“å¤šäæ”ęÆļ¼ŒčÆ·å‚é˜…é—®é¢˜ https://github.com/TriliumNext/Trilium/issues/4962怂 + +å¦‚ęžœä½ åå„½åŽŸē”Ÿ Android åŗ”ē”Øļ¼ŒåÆä½æē”Ø +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid)ć€‚å›žęŠ„é—®é¢˜ęˆ–ē¼ŗå°‘ēš„åŠŸčƒ½ļ¼ŒčÆ·č‡³[å…¶å‚Øå­˜åŗ“](https://github.com/FliegendeWurst/TriliumDroid)怂 + +### ęœåŠ”å™Ø + +č‹„č¦åœØä½ č‡Ŗå·±ēš„ęœåŠ”å™ØäøŠå®‰č£… TriliumNextļ¼ˆåŒ…ę‹¬ä»Ž [Docker +Hub](https://hub.docker.com/r/triliumnext/trilium) 使用 Docker +éƒØē½²ļ¼‰ļ¼ŒčÆ·éµå¾Ŗ[ęœåŠ”å™Øå®‰č£…ę–‡ä»¶](https://docs.triliumnotes.org/user-guide/setup/server)怂 -ę‚Øčæ˜åÆä»„é˜…čÆ»[äøŖäŗŗēŸ„čÆ†åŗ“ęØ”å¼](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)ļ¼Œä»„čŽ·å–ęœ‰å…³å¦‚ä½•ä½æē”Ø Trilium ēš„ēµę„Ÿć€‚ ## šŸ’» 蓔献 +### 翻译 -ęˆ–č€…å…‹éš†ęœ¬ä»“åŗ“åˆ°ęœ¬åœ°ļ¼Œå¹¶čæč”Œ +å¦‚ęžœä½ ę˜ÆęÆčÆ­äŗŗå£«ļ¼Œę¬¢čæŽå‰å¾€ęˆ‘ä»¬ēš„ [Weblate 锵面](https://hosted.weblate.org/engage/trilium/)ååŠ©ēæ»čÆ‘ +Trilium怂 +ä»„äø‹ę˜Æē›®å‰ēš„čÆ­čØ€č¦†ē›–ēŠ¶ę€ļ¼š + +[![ēæ»čÆ‘ēŠ¶ę€](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### ēØ‹åŗä»£ē  + +äø‹č½½å‚Øå­˜åŗ“ļ¼Œä½æē”Ø `pnpm` å®‰č£…ē›øä¾å„—ä»¶ļ¼ŒęŽ„ē€åÆåŠØęœåŠ”å™Øļ¼ˆäŗŽ http://localhost:8080 ęä¾›ęœåŠ”ļ¼‰ļ¼š ```shell -npm install -npm run server:start +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start ``` -## šŸ‘ 臓谢 +### ꖇ件 -* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - åø‚é¢äøŠęœ€å„½ēš„ę‰€č§å³ę‰€å¾—ē¼–č¾‘å™Øļ¼Œę‹„ęœ‰äŗ’åŠØę€§å¼ŗäø”č†å¬čƒ½åŠ›å¼ŗēš„å›¢é˜Ÿ -* [FancyTree](https://github.com/mar10/fancytree) - äø€äøŖéžåøøäø°åÆŒēš„å…³äŗŽę ‘ēš„åŗ“ļ¼Œå¼ŗå¤§åˆ°ę²”ęœ‰åÆ¹ę‰‹ć€‚ę²”ęœ‰å®ƒļ¼ŒTrilium Notes å°†äøä¼šå¦‚ę­¤ć€‚ -* [CodeMirror](https://github.com/codemirror/CodeMirror) - ę”ÆęŒå¤§é‡čÆ­čØ€ēš„ä»£ē ē¼–č¾‘å™Ø -* [jsPlumb](https://github.com/jsplumb/jsplumb) - å¼ŗå¤§ēš„åÆč§†åŒ–čæžęŽ„åŗ“ć€‚ē”ØäŗŽ[关系图](https://triliumnext.github.io/Docs/Wiki/relation-map)和[é“¾ęŽ„å›¾](https://triliumnext.github.io/Docs/Wiki/link-map) +äø‹č½½å‚Øå­˜åŗ“ļ¼Œä½æē”Ø `pnpm` å®‰č£…ē›øä¾å„—ä»¶ļ¼ŒęŽ„ē€åÆåŠØē¼–č¾‘ę–‡ä»¶ę‰€éœ€ēš„ēŽÆå¢ƒļ¼š +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` -## šŸ¤ ęčµ  +### å»ŗē½®ę”Œé¢åÆę‰§č”Œę–‡ä»¶ +äø‹č½½å‚Øå­˜åŗ“ļ¼Œä½æē”Ø `pnpm` å®‰č£…ē›øä¾å„—ä»¶ļ¼Œē„¶åŽäøŗ Windows å»ŗē½®ę”Œé¢åŗ”ē”Øļ¼š +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` -ä½ åÆä»„é€ščæ‡ GitHub Sponsors,[PayPal](https://paypal.me/za4am) ęˆ–č€…ęÆ”ē‰¹åø (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2) ę„ęčµ ć€‚ +ę›“å¤šē»†čŠ‚čÆ·å‚č§[å¼€å‘ę–‡ä»¶](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide)怂 -## šŸ”‘ č®øåÆčÆ +### å¼€å‘č€…ę–‡ę”£ -ęœ¬ēØ‹åŗę˜Æč‡Ŗē”±č½Æä»¶ļ¼šä½ åÆä»„å†å‘åøƒęœ¬č½Æä»¶å’Œ/ęˆ–äæ®ę”¹ęœ¬č½Æä»¶ļ¼ŒåŖč¦ä½ éµå¾Ŗ Free Software Foundation å‘åøƒēš„ GNU Affero General Public License ēš„ē¬¬äø‰ē‰ˆęˆ–č€…ä»»ä½•ļ¼ˆē”±ä½ é€‰ę‹©ļ¼‰ę›“ę™šēš„ē‰ˆęœ¬ć€‚ +čÆ¦ęƒ…čÆ·å‚é˜…[ę–‡ę”£ęŒ‡å—](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md)ć€‚å¦‚ęœ‰ę›“å¤šē–‘é—®ļ¼Œę¬¢čæŽé€ščæ‡äøŠę–¹ā€œč”ē³»ęˆ‘ä»¬ā€éƒØåˆ†ęä¾›ēš„é“¾ęŽ„äøŽęˆ‘ä»¬ę²Ÿé€šć€‚ + +## šŸ‘ 鸣谢 + +* [zadam](https://github.com/zadam) åÆ¹äŗŽåŗ”ē”ØēØ‹åŗēš„åŽŸå§‹ę¦‚åæµč®¾č®”äøŽå®žēŽ°ć€‚ +* [Sarah Hussein](https://github.com/Sarah-Hussein) äøŗåŗ”ē”ØēØ‹åŗč®¾č®”å›¾ę ‡ć€‚ +* [nriver](https://github.com/nriver) åÆ¹å…¶åœØå›½é™…åŒ–å·„ä½œäø­ēš„č“”ēŒ®ć€‚ +* [Thomas Frei](https://github.com/thfrei) å› å…¶åœØ Canvas ę–¹é¢ēš„åŽŸåˆ›å·„ä½œć€‚ +* [antoniotejada](https://github.com/nriver) åŽŸå§‹čÆ­ę³•é«˜äŗ®å°éƒØä»¶ēš„ä½œč€…ć€‚ +* [Dosu](https://dosu.dev/) äøŗęˆ‘ä»¬ęä¾› GitHub é—®é¢˜å’Œč®Øč®ŗēš„č‡ŖåŠØåŒ–å›žå¤ć€‚ +* [Tabler Icons](https://tabler.io/icons) ē”ØäŗŽē³»ē»Ÿę‰˜ē›˜å›¾ę ‡ć€‚ + +č‹„ę²”ęœ‰ę”Æę’‘å…¶čƒŒåŽēš„ęŠ€ęœÆļ¼ŒTrilium é”¹ē›®ä¾æę— ę³•å®žēŽ°ļ¼š + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) —— + ę–‡ęœ¬ē¬”č®°čƒŒåŽēš„åÆč§†åŒ–ē¼–č¾‘å™Øć€‚ęˆ‘ä»¬éžåøøę„Ÿč°¢čƒ½čŽ·å¾—čæ™å„—é«˜ēŗ§åŠŸčƒ½ēš„ä½æē”Øęƒé™ć€‚ +* [CodeMirror](https://github.com/codemirror/CodeMirror) —— ę”ÆęŒęµ·é‡ē¼–ēØ‹čÆ­čØ€ēš„ä»£ē ē¼–č¾‘å™Øć€‚ +* [Excalidraw](https://github.com/excalidraw/excalidraw) —— ē”»åøƒē¬”č®°äø­ä½æē”Øēš„ę— é™ē™½ęæć€‚ +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) —— ęä¾›ę€ē»“åÆ¼å›¾åŠŸčƒ½ć€‚ +* [Leaflet](https://github.com/Leaflet/Leaflet) —— ē”ØäŗŽęø²ęŸ“åœ°ē†åœ°å›¾ć€‚ +* [Tabulator](https://github.com/olifolkerd/tabulator) —— ē”ØäŗŽé›†åˆäø­ēš„äŗ¤äŗ’å¼č”Øę ¼ć€‚ +* [FancyTree](https://github.com/mar10/fancytree) —— åŠŸčƒ½äø°åÆŒēš„ę ‘å½¢ęŽ§ä»¶åŗ“ļ¼Œę— åÆåŒ¹ę•Œć€‚ +* [jsPlumb](https://github.com/jsplumb/jsplumb) —— + åÆč§†åŒ–čæžęŽ„åŗ“ć€‚ē”ØäŗŽ[关系图](https://docs.triliumnotes.org/user-guide/note-types/relation-map)和[é“¾ęŽ„å›¾](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ ę”ÆęŒęˆ‘ä»¬ + +Trilium +ēš„å¼€å‘äøŽē»“ęŠ¤å‡čšäŗ†[ę•°ē™¾å°ę—¶ēš„å·„ä½œ](https://github.com/TriliumNext/Trilium/graphs/commit-activity)ć€‚ä½ ēš„ę”ÆęŒå°†ē”®äæå…¶å¼€ęŗę€§č“Øļ¼ŒęŽØåŠØåŠŸčƒ½ę”¹čæ›ļ¼Œå¹¶č¦†ē›–ę‰˜ē®”ē­‰ē›øå…³ęˆęœ¬ć€‚ + +čÆ·č€ƒč™‘é€ščæ‡ä»„äø‹ę–¹å¼ę”ÆęŒčÆ„åŗ”ē”ØēØ‹åŗēš„äø»č¦å¼€å‘č€…ļ¼ˆ[eliandoran](https://github.com/eliandoran)ļ¼‰ļ¼š + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ ęŽˆęƒę”ę¬¾ + +Copyright 2017–2025 zadam态Elian Doran äøŽå…¶ä»–č“”ēŒ®č€… + +ęœ¬ēØ‹åŗē³»č‡Ŗē”±č½Æä»¶ļ¼šä½ åÆä»„åœØč‡Ŗē”±č½Æä»¶åŸŗé‡‘ä¼šļ¼ˆFree Software Foundationļ¼‰ę‰€å‘åøƒēš„ GNU Affero é€šē”Øå…¬ä¼—ęŽˆęƒę”ę¬¾ļ¼ˆGNU +AGPL)第 3 ē‰ˆęˆ–ļ¼ˆē”±ä½ é€‰ę‹©ļ¼‰ä»»ä½•åŽē»­ē‰ˆęœ¬ä¹‹ę”ę¬¾äø‹é‡ę–°ę•£åøƒęˆ–äæ®ę”¹ęœ¬ēØ‹åŗć€‚ diff --git a/docs/README-ZH_TW.md b/docs/README-ZH_TW.md new file mode 100644 index 0000000000..b189198b7c --- /dev/null +++ b/docs/README-ZH_TW.md @@ -0,0 +1,256 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (ꉀ꜉ assets 及 +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![翻譯狀態](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes ę˜Æäø€ę¬¾å…č²»äø”é–‹ęŗć€č·Øå¹³å°ēš„éšŽå±¤å¼ē­†čØ˜ę‡‰ē”ØēØ‹å¼ļ¼Œå°ˆę³Øę–¼å»ŗē«‹å¤§åž‹å€‹äŗŗēŸ„č­˜åŗ«ć€‚ + +Trilium Screenshot + +## ā¬ 下載 +- [ęœ€ę–°ē‰ˆęœ¬](https://github.com/TriliumNext/Trilium/releases/latest) – + ē©©å®šē‰ˆęœ¬ļ¼ŒęŽØč–¦ēµ¦å¤§å¤šę•øä½æē”Øč€…ć€‚ +- [å¤œé–“ę§‹å»ŗ](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + äøē©©å®šé–‹ē™¼ē‰ˆęœ¬ļ¼ŒęÆę—„ę›“ę–°ęœ€ę–°åŠŸčƒ½čˆ‡äæ®å¾©å…§å®¹ć€‚ + +## šŸ“š ꖇ件 + +**åÆä»„åœØ [docs.triliumnotes.org](https://docs.triliumnotes.org/) ęŸ„ēœ‹å®Œę•“ä½æē”ØčŖŖę˜Ž** + +ęˆ‘å€‘ēš„ä½æē”ØčŖŖę˜ŽåŒ…å«å¤šēØ®ę ¼å¼ļ¼š +- **ē·šäøŠę–‡ä»¶**ļ¼šåÆę–¼ [docs.triliumnotes.org](https://docs.triliumnotes.org/) ęŸ„ēœ‹å®Œę•“ä½æē”ØčŖŖę˜Ž +- **ę‡‰ē”ØēØ‹å¼å…§čŖŖę˜Ž**:在 Trilium äø­ęŒ‰äø‹ `F1` å³åÆē›“ęŽ„ę–¼ę‡‰ē”ØēØ‹å¼å…§å­˜å–ē›øåŒę–‡ä»¶ +- **GitHub**ļ¼šč«‹åƒé–±ę­¤å„²å­˜åŗ«äø­ēš„[ä½æē”ØčŖŖę˜Ž](./User%20Guide/User%20Guide/) + +### åæ«é€Ÿé€£ēµ +- [äøŠę‰‹ęŒ‡å—](https://docs.triliumnotes.org/) +- [å®‰č£čŖŖę˜Ž](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + 設定](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [å‡ē“š TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [åŸŗē¤Žč§€åæµčˆ‡åŠŸčƒ½](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [å€‹äŗŗēŸ„č­˜åŗ«ēš„ęØ”å¼](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ 功能 + +* ē­†čØ˜åÆēµ„ē¹”ęˆä»»ę„ę·±åŗ¦ēš„ęØ¹ē‹€ēµę§‹ć€‚å–®äø€ē­†čØ˜åÆę”¾åœØęØ¹äø­ēš„å¤šå€‹ä½ē½®ļ¼ˆåƒč¦‹[ē­†čØ˜å…‹éš†](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* č±åÆŒēš„ę‰€č¦‹å³ę‰€å¾—ļ¼ˆWYSIWYGļ¼‰ē­†čØ˜ē·Øč¼Æå™Øļ¼Œę”Æę“č”Øę ¼ć€åœ–ē‰‡čˆ‡[ę•øå­øå…¬å¼](https://docs.triliumnotes.org/user-guide/note-types/text)ļ¼Œäø¦å…·å‚™ + Markdown + ēš„[č‡Ŗå‹•ę ¼å¼åŒ–](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* ę”Æę“ē·Øč¼Æ[ēØ‹å¼ē¢¼ē­†čØ˜](https://docs.triliumnotes.org/user-guide/note-types/code)ļ¼ŒåŒ…å«čŖžę³•é«˜äŗ® +* åæ«é€Ÿć€č¼•é¬†åœ°åœØē­†čØ˜é–“[å°ŽčˆŖ](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation)ć€å…Øę–‡ęœå°‹ļ¼Œä»„åŠ[ē­†čØ˜čšē„¦ļ¼ˆhoisting)](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* ē„”ēø«ēš„[ē­†čØ˜ē‰ˆęœ¬ē®”ē†](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* ē­†čØ˜[屬性](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes)åÆē”Øę–¼ē­†čØ˜ēš„ēµ„ē¹”ć€ęŸ„č©¢čˆ‡é€²éšŽ[č…³ęœ¬](https://docs.triliumnotes.org/user-guide/scripts) +* ä»‹é¢ęä¾›č‹±ę–‡ć€å¾·ę–‡ć€č„æē­ē‰™ę–‡ć€ę³•ę–‡ć€ē¾…é¦¬å°¼äŗžę–‡čˆ‡äø­ę–‡ļ¼ˆē°”é«”čˆ‡ę­£é«”ļ¼‰ +* ē›“ęŽ„[ę•“åˆ OpenID 與 + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) ä»„åÆ¦ē¾ę›“å®‰å…Øēš„ē™»å…„ +* čˆ‡č‡Ŗęž¶ēš„åŒę­„ä¼ŗęœå™Øé€²č”Œ[同歄](https://docs.triliumnotes.org/user-guide/setup/synchronization) + * ꜉[ē¬¬äø‰ę–¹ęœå‹™åÆčØ—ē®”åŒę­„ä¼ŗęœå™Ø](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* å°‡ē­†čØ˜[åˆ†äŗ«](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing)ļ¼ˆå…¬é–‹ē™¼åøƒļ¼‰åˆ°ē¶²éš›ē¶²č·Æ +* ä»„ęÆå‰‡ē­†čØ˜ē‚ŗē²’åŗ¦ēš„å¼·å¤§[ē­†čØ˜åŠ åÆ†](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) +* 手繪/ē¤ŗę„åœ–ļ¼šåŸŗę–¼ [Excalidraw](https://excalidraw.com/)ļ¼ˆē­†čØ˜é”žåž‹ē‚ŗć€Œcanvasć€ļ¼‰ +* [é—œäæ‚åœ–](https://docs.triliumnotes.org/user-guide/note-types/relation-map) 與 + [ē­†čØ˜/é€£ēµåœ–](https://docs.triliumnotes.org/user-guide/note-types/note-map) + ē”Øę–¼č¦–č¦ŗåŒ–å‘ˆē¾ē­†čØ˜åŠå…¶é—œčÆę€§ +* åæƒę™ŗåœ–ļ¼šåŸŗę–¼ [Mind Elixir](https://docs.mind-elixir.com/) +* å…·ęœ‰å®šä½é‡˜čˆ‡ GPX + č»Œč·”ēš„[地圖](https://docs.triliumnotes.org/user-guide/collections/geomap) +* [č…³ęœ¬](https://docs.triliumnotes.org/user-guide/scripts)ā€”ā€”åƒč¦‹[é€²éšŽå±•ē¤ŗ](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* ē”Øę–¼č‡Ŗå‹•åŒ–ēš„ [REST + API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) +* åœØåÆē”Øę€§čˆ‡ę•ˆčƒ½äøŠå‡åÆč‰Æå„½ę““å±•ļ¼Œę”Æę“č¶…éŽåč¬ē­†ē­†čØ˜ +* ē‚ŗę‰‹ę©Ÿčˆ‡å¹³ęæęœ€ä½³åŒ–ēš„[č”Œå‹•å‰ē«Æ](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) +* 內建[ę·±č‰²äø»é”Œ](https://docs.triliumnotes.org/user-guide/concepts/themes)ļ¼Œäø¦ę”Æę“č‡ŖčØ‚äø»é”Œ +* [Evernote + åŒÆå…„](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote)與 + [Markdown + åŒÆå…„čˆ‡åŒÆå‡ŗ](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* ē”Øę–¼åæ«é€Ÿäæå­˜ē¶²é å…§å®¹ēš„ [Web + Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) +* åÆč‡ŖčØ‚ēš„ UIļ¼ˆå“é‚Šę¬„ęŒ‰éˆ•ć€ä½æē”Øč€…č‡ŖčØ‚å°å·„å…·ē­‰ļ¼‰ +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics)ļ¼Œä»„åŠ + Grafana å„€č”Øęæć€‚ + +✨ ęƒ³č¦ę›“å¤š Trilium Notes ēš„äø»é”Œć€č…³ęœ¬ć€å¤–ęŽ›čˆ‡č³‡ęŗļ¼Œäŗ¦åÆåƒč€ƒä»„äø‹ē¬¬äø‰ę–¹č³‡ęŗ / 社群: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium)ļ¼ˆē¬¬äø‰ę–¹äø»é”Œć€č…³ęœ¬ć€å¤–ęŽ›čˆ‡ę›“å¤šļ¼‰ć€‚ +- [TriliumRocks!](https://trilium.rocks/)ļ¼ˆę•™å­øć€ęŒ‡å—ē­‰ē­‰ļ¼‰ć€‚ + +## ā“ē‚ŗä»€éŗ¼ę˜Æ TriliumNext? + +åŽŸå§‹ēš„ Trilium 開發者 ([Zadam](https://github.com/zadam)) å·²ę…·ę…Øåœ°å°‡ Trilium +å„²å­˜åŗ«ē§»äŗ¤ēµ¦ē¤¾ē¾¤å°ˆę”ˆļ¼Œč©²å°ˆę”ˆē¾å­˜ę”¾ę–¼ https://github.com/TriliumNext + +### ā¬†ļøå¾ž Zadam/Trilium 遷移? + +å¾žę—¢ęœ‰ēš„ zadam/Trilium ä¾‹é …é·ē§»åˆ° TriliumNext/Notes äøéœ€č¦ē‰¹åˆ„ēš„é·ē§»ę­„é©Ÿć€‚åŖč¦ē…§äø€čˆ¬ę–¹å¼[å®‰č£ +TriliumNext/Notes](#-installation)ļ¼Œå®ƒå°±ęœƒē›“ęŽ„ä½æē”Øä½ ē¾ęœ‰ēš„č³‡ę–™åŗ«ć€‚ + +ē‰ˆęœ¬ęœ€é«˜č‡³ [v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) 與 +zadam/trilium ęœ€ę–°ē‰ˆęœ¬ +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7) ē›øå®¹ć€‚ä¹‹å¾Œēš„ +TriliumNext ē‰ˆęœ¬å·²ęå‡åŒę­„ē‰ˆęœ¬č™Ÿļ¼ˆčˆ‡äøŠčæ°äøå†ē›øå®¹ļ¼‰ć€‚ + +## šŸ’¬ čˆ‡ęˆ‘å€‘äŗ¤ęµ + +ę­”čæŽåŠ å…„å®˜ę–¹ē¤¾ē¾¤ć€‚ęˆ‘å€‘å¾ˆęØ‚ę„č½åˆ°ä½ å°åŠŸčƒ½ć€å»ŗč­°ęˆ–å•é”Œēš„ęƒ³ę³•ļ¼ + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org)ļ¼ˆåŒę­„čØŽč«–ļ¼‰ + - `General` Matrix ęˆæé–“ä¹Ÿę©‹ęŽ„åˆ° [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [GitHub + Discussions](https://github.com/TriliumNext/Trilium/discussions)ļ¼ˆéžåŒę­„čØŽč«–ć€‚ļ¼‰ +- [GitHub Issues](https://github.com/TriliumNext/Trilium/issues)ļ¼ˆå›žå ±éŒÆčŖ¤čˆ‡ęå‡ŗåŠŸčƒ½éœ€ę±‚ć€‚ļ¼‰ + +## šŸ— å®‰č£ + +### Windows / MacOS + +從[ęœ€ę–°é‡‹å‡ŗé é¢](https://github.com/TriliumNext/Trilium/releases/latest)äø‹č¼‰ę‚Øå¹³å°ēš„äŗŒé€²ä½ęŖ”ļ¼Œč§£å£“ēø®å¾ŒåŸ·č”Œ +`trilium` åÆåŸ·č”ŒęŖ”ć€‚ + +### Linux + +å¦‚ęžœę‚Øēš„ē™¼č”Œē‰ˆå¦‚äø‹č”Øę‰€åˆ—ļ¼Œč«‹ä½æē”Øč©²ē™¼č”Œē‰ˆēš„å„—ä»¶ć€‚ + +[![ę‰“åŒ…ē‹€ę…‹](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +ę‚Øä¹ŸåÆä»„å¾ž[ęœ€ę–°é‡‹å‡ŗé é¢](https://github.com/TriliumNext/Trilium/releases/latest)äø‹č¼‰å°ę‡‰å¹³å°ēš„äŗŒé€²ä½ęŖ”ļ¼Œč§£å£“ēø®å¾ŒåŸ·č”Œ +`trilium` åÆåŸ·č”ŒęŖ”ć€‚ + +TriliumNext ä¹Ÿęä¾› Flatpakļ¼ŒęƒŸå°šęœŖē™¼ä½ˆåˆ° FlatHub怂 + +### ē€č¦½å™Øļ¼ˆä»»ä½•ä½œę„­ē³»ēµ±ļ¼‰ + +č‹„ę‚Øęœ‰ļ¼ˆå¦‚äø‹ę‰€čæ°ēš„ļ¼‰ä¼ŗęœå™Øå®‰č£ļ¼Œä¾æåÆē›“ęŽ„å­˜å–ē¶²é ä»‹é¢ļ¼ˆå…¶čˆ‡ę”Œé¢ę‡‰ē”Øå¹¾ä¹Žē›øåŒļ¼‰ć€‚ + +ē›®å‰åƒ…ę”Æę“ļ¼ˆäø¦åÆ¦ęø¬ļ¼‰ęœ€ę–°ē‰ˆēš„ Chrome 與 Firefox怂 + +### č”Œå‹•č£ē½® + +č‹„č¦åœØč”Œå‹•č£ē½®äøŠä½æē”Ø TriliumNextļ¼Œä½ åÆä»„é€éŽč”Œå‹•ē€č¦½å™Øå­˜å–ä¼ŗęœå™Øå®‰č£ēš„č”Œå‹•ē‰ˆä»‹é¢ļ¼ˆč¦‹äø‹ļ¼‰ć€‚ + +ę›“å¤šé—œę–¼č”Œå‹•ę‡‰ē”Øę”Æę“ēš„č³‡čØŠļ¼Œč«‹č¦‹č­°é”Œļ¼šhttps://github.com/TriliumNext/Trilium/issues/4962怂 + +č‹„ę‚Øåå„½åŽŸē”Ÿ Android ę‡‰ē”ØēØ‹å¼ļ¼ŒåÆä½æē”Ø +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid)。請至 +[å…¶å„²å­˜åŗ«](https://github.com/FliegendeWurst/TriliumDroid) å›žå ±éŒÆčŖ¤čˆ‡åŠŸčƒ½ē¼ŗå¤±ć€‚ę³Øę„ļ¼šä½æē”Ø +TriliumDroid ę™‚ļ¼Œå»ŗč­°åœē”Øä¼ŗęœå™Øå®‰č£ē‰ˆęœ¬ēš„č‡Ŗå‹•ę›“ę–°åŠŸčƒ½ļ¼ˆč©³č¦‹äø‹ę–‡ļ¼‰ļ¼Œå›  Trilium 與 TriliumDroid é–“ēš„åŒę­„ē‰ˆęœ¬åæ…é ˆäæęŒäø€č‡“ć€‚ + +### ä¼ŗęœå™Ø + +č‹„č¦åœØę‚Øč‡Ŗå·±ēš„ä¼ŗęœå™ØäøŠå®‰č£ TriliumNextļ¼ˆåŒ…ę‹¬å¾ž [Docker +Hub](https://hub.docker.com/r/triliumnext/trilium) 使用 Docker +éƒØē½²ļ¼‰ļ¼Œč«‹éµå¾Ŗ[ä¼ŗęœå™Øå®‰č£ę–‡ä»¶](https://docs.triliumnotes.org/user-guide/setup/server)怂 + + +## šŸ’» č²¢ē» + +### 翻譯 + +å¦‚ęžœę‚Øę˜ÆęÆčŖžäŗŗå£«ļ¼Œę­”čæŽå‰å¾€ęˆ‘å€‘ēš„ [Weblate 頁面](https://hosted.weblate.org/engage/trilium/)å”åŠ©ēæ»č­Æ +Trilium怂 + +ä»„äø‹ę˜Æē›®å‰ēš„čŖžčØ€č¦†č“‹ē‹€ę…‹ļ¼š + +[![翻譯狀態](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### ēØ‹å¼ē¢¼ + +äø‹č¼‰å„²å­˜åŗ«ļ¼Œä½æē”Ø `pnpm` å®‰č£ē›øä¾å„—ä»¶ļ¼ŒęŽ„č‘—å•Ÿå‹•ä¼ŗęœå™Øļ¼ˆå°‡ę–¼ http://localhost:8080 ęä¾›ęœå‹™ļ¼‰ļ¼š +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### ꖇ件 + +äø‹č¼‰å„²å­˜åŗ«ļ¼Œä½æē”Ø `pnpm` å®‰č£ē›øä¾å„—ä»¶ļ¼ŒęŽ„č‘—å•Ÿå‹•ē·Øč¼Æę–‡ä»¶ę‰€éœ€ēš„ē’°å¢ƒļ¼š +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### å»ŗē½®ę”Œé¢åÆåŸ·č”ŒęŖ” +äø‹č¼‰å„²å­˜åŗ«ļ¼Œä½æē”Ø `pnpm` å®‰č£ē›øä¾å„—ä»¶ļ¼Œē„¶å¾Œē‚ŗ Windows å»ŗē½®ę”Œé¢ę‡‰ē”Øļ¼š +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +ę›“å¤šē“°ēÆ€č«‹åƒč¦‹[開發者文件](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide)怂 + +### 開發者文件 + +č«‹åƒé–±[ę–‡ä»¶ęŒ‡å—](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md)ć€‚č‹„ęœ‰ę›“å¤šē–‘å•ļ¼Œę­”čæŽé€éŽäøŠę–¹ć€Œčˆ‡ęˆ‘å€‘äŗ¤ęµć€ē« ēÆ€ę‰€åˆ—é€£ēµčˆ‡ęˆ‘å€‘čÆē¹«ć€‚ + +## šŸ‘ é³“č¬ + +* [zadam](https://github.com/zadam) ē‚ŗęœ¬ę‡‰ē”ØēØ‹å¼ēš„åŽŸå§‹ę¦‚åæµčˆ‡åÆ¦ä½œć€‚ +* [Sarah Hussein](https://github.com/Sarah-Hussein) ē‚ŗę‡‰ē”ØēØ‹å¼čØ­čØˆåœ–ē¤ŗć€‚ +* [nriver](https://github.com/nriver) å°å…¶åœØåœ‹éš›åŒ–ę–¹é¢ēš„č²¢ē»ć€‚ +* [Thomas Frei](https://github.com/thfrei) 對 Canvas åŽŸå§‹ä½œå“ēš„č²¢ē»ć€‚ +* [antoniotejada](https://github.com/nriver) ē‚ŗåŽŸå§‹čŖžę³•é«˜äŗ®å°å·„å…·ēš„č²¢ē»ć€‚ +* [Dosu](https://dosu.dev/) ē‚ŗęˆ‘å€‘ęä¾› GitHub å•é”Œčˆ‡čØŽč«–ēš„č‡Ŗå‹•åŒ–å›žę‡‰ć€‚ +* [Tabler Icons](https://tabler.io/icons) ē”Øę–¼ē³»ēµ±åŒ£åœ–ē¤ŗć€‚ + +č‹„ē„”å…¶čƒŒå¾Œēš„ęŠ€č”“ę”Æę’ļ¼ŒTrilium ä¾æē„”ę³•é–‹ē™¼å®Œęˆļ¼š + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) —— + ę–‡å­—ē­†čØ˜čƒŒå¾Œēš„č¦–č¦ŗåŒ–ē·Øč¼Æå™Øć€‚ęˆ‘å€‘č”·åæƒę„Ÿč¬ē²č“ˆé€™å„—é€²éšŽåŠŸčƒ½å„—ä»¶ć€‚ +* [CodeMirror](https://github.com/codemirror/CodeMirror) —— ę”Æę“å¤§é‡čŖžčØ€ēš„ēØ‹å¼ē¢¼ē·Øč¼Æå™Øć€‚ +* [Excalidraw](https://github.com/excalidraw/excalidraw) —— ē•«åøƒē­†čØ˜äø­ä½æē”Øēš„ē„”é™ē™½ęæć€‚ +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) —— ęä¾›åæƒę™ŗåœ–åŠŸčƒ½ć€‚ +* [Leaflet](https://github.com/Leaflet/Leaflet) —— ē”Øę–¼ęø²ęŸ“åœ°ē†åœ°åœ–ć€‚ +* [Tabulator](https://github.com/olifolkerd/tabulator) —— ē”Øę–¼é›†åˆäø­ēš„äŗ’å‹•å¼č”Øę ¼ć€‚ +* [FancyTree](https://github.com/mar10/fancytree) —— åŠŸčƒ½éžåøøč±åÆŒēš„ęØ¹ē‹€å…ƒä»¶ļ¼Œē„”åÆåŒ¹ę•µć€‚ +* [jsPlumb](https://github.com/jsplumb/jsplumb) —— + č¦–č¦ŗé€£ē·šå‡½å¼åŗ«ć€‚ē”Øę–¼[é—œčÆåœ–](https://docs.triliumnotes.org/user-guide/note-types/relation-map)與[é€£ēµåœ–](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ ę”Æę“ęˆ‘å€‘ + +Trilium +ēš„é–‹ē™¼čˆ‡ē¶­č­·č€—č²»äŗ†[ę•øē™¾å°ę™‚ēš„å·„ä½œę™‚é–“](https://github.com/TriliumNext/Trilium/graphs/commit-activity)ć€‚ę‚Øēš„ę”ÆęŒčƒ½ē¢ŗäæå…¶é–‹ęŗę€§č³Ŗć€ęå‡åŠŸčƒ½å“č³Ŗļ¼Œäø¦ę”Æä»˜ä¼ŗęœå™ØčØ—ē®”ē­‰ē›øé—œęˆęœ¬ć€‚ + +č«‹č€ƒę…®é€éŽä»„äø‹ę–¹å¼ę”ÆęŒęœ¬ę‡‰ē”ØēØ‹å¼ēš„äø»č¦é–‹ē™¼č€… ([eliandoran](https://github.com/eliandoran)): + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ ęŽˆę¬Šę¢ę¬¾ + +Copyright 2017–2025 zadam态Elian Doran čˆ‡å…¶ä»–č²¢ē»č€… + +ęœ¬ēØ‹å¼äæ‚č‡Ŗē”±č»Ÿé«”ļ¼šę‚ØåÆä»„åœØč‡Ŗē”±č»Ÿé«”åŸŗé‡‘ęœƒļ¼ˆFree Software Foundationļ¼‰ę‰€ē™¼ä½ˆēš„ GNU Affero é€šē”Øå…¬ēœ¾ęŽˆę¬Šę¢ę¬¾ļ¼ˆGNU +AGPL)第 3 ē‰ˆęˆ–ļ¼ˆē”±ä½ éøę“‡ļ¼‰ä»»ä½•å¾ŒēŗŒē‰ˆęœ¬ä¹‹ę¢ę¬¾äø‹é‡ę–°ę•£åøƒęˆ–äæ®ę”¹ęœ¬ēØ‹å¼ć€‚ diff --git a/docs/README-ar.md b/docs/README-ar.md new file mode 100644 index 0000000000..adfd57b9e6 --- /dev/null +++ b/docs/README-ar.md @@ -0,0 +1,339 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# ملاحظات ŲŖŲ±ŁŠŁ„ŁŠŁˆŁ… + +![Ų±Ų¹Ų§Ų© GitHub](https://img.shields.io/github/sponsors/eliandoran) ![ŲÆŲ§Ų¹Ł…Łˆ +LiberaPay](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Ų¹Ł…Ł„ŁŠŲ§ŲŖ Ų³Ų­ŲØ Docker](https://img.shields.io/docker/pulls/triliumnext/trilium) +![ŲŖŁ†Ų²ŁŠŁ„Ų§ŲŖ GitHub (Ų¬Ł…ŁŠŲ¹ Ų§Ł„Ų£ŲµŁˆŁ„ŲŒ Ų¬Ł…ŁŠŲ¹ +ال؄صدارات)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![حالة +الترجمة](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +ŲŖŲ±ŁŠŁ„ŁŠŁˆŁ… Ł‡Łˆ برنامج Ł…Ų¬Ų§Ł†ŁŠ Ł…ŁŲŖŁˆŲ­ Ų§Ł„Ł…ŲµŲÆŲ±ŲŒ ŁŠŁ…ŁƒŁ† استخدامه في أكثر من جهاز بنفس Ų§Ł„ŁˆŁ‚ŲŖŲŒ +Ł…ŲØŁ†ŁŠ على كتابة الملاحظات بالتفرعات Ų§Ł„Ų“Ų¬Ų±ŁŠŲ© Ł…Ų¹ Ų§Ł„ŲŖŲ±ŁƒŁŠŲ² على بناؔ قاعدة ŲØŁŠŲ§Ł†Ų§ŲŖ +Ł…Ų¹Ų±ŁŁŠŲ© ضخمة. + +Trilium Screenshot + +## ā¬‡ļø Ų§Ł„ŲŖŁ†Ų²ŁŠŁ„ +- [النسخة Ų§Ł„Ų£Ų®ŁŠŲ±Ų©](https://github.com/TriliumNext/Trilium/releases/latest) – + نسخة Ł…Ų³ŲŖŁ‚Ų±Ų©ŲŒ Ł…Ų­ŲØŲ°Ų© Ł„Ų£ŁƒŲ«Ų± Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ†. +- [ال؄صدار Ų§Ł„Ł„ŁŠŁ„ŁŠ](https://github.com/TriliumNext/Trilium/releases/tag/nightly) + – Ų„ŲµŲÆŲ§Ų± تطوير غير Ł…Ų³ŲŖŁ‚Ų±ŲŒ ŁŠŲŖŁ… ŲŖŲ­ŲÆŁŠŲ«Ł‡ ŁŠŁˆŁ…ŁŠŁ‹Ų§ ŲØŲ£Ų­ŲÆŲ« Ų§Ł„Ł…ŁŠŲ²Ų§ŲŖ ŁˆŲ§Ł„Ų„ŲµŁ„Ų§Ų­Ų§ŲŖ. + +## šŸ“š Ų§Ł„ŁˆŲ«Ų§Ų¦Ł‚ + +**ŁŠŁ…ŁƒŁ†ŁƒŁ… الاطلاع على ŁˆŲ«Ų§Ų¦Ł‚Ł†Ų§ الؓاملة على الرابط Ų§Ł„ŲŖŲ§Ł„ŁŠ: +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +يتوفر Ų§Ł„ŲŖŁˆŲ«ŁŠŁ‚ Ł„ŲÆŁŠŁ†Ų§ بصيغ Ł…ŲŖŲ¹ŲÆŲÆŲ©: +- **Ų§Ł„ŁˆŲ«Ų§Ų¦Ł‚ Ų§Ł„Ų„Ł„ŁƒŲŖŲ±ŁˆŁ†ŁŠŲ©**: تصفح Ų§Ł„ŁˆŲ«Ų§Ų¦Ł‚ Ų§Ł„ŁƒŲ§Ł…Ł„Ų© على + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **المساعدة داخل Ų§Ł„ŲŖŲ·ŲØŁŠŁ‚**: Ų§Ų¶ŲŗŲ· على مفتاح `F1` داخل ŲŖŲ·ŲØŁŠŁ‚ Trilium Ł„Ł„ŁˆŲµŁˆŁ„ ؄لى + نفس Ų§Ł„ŁˆŲ«Ų§Ų¦Ł‚ Ł…ŲØŲ§Ų“Ų±Ų©Ł‹ داخل Ų§Ł„ŲŖŲ·ŲØŁŠŁ‚ +- **GitHub**: تصفح [ŲÆŁ„ŁŠŁ„ المستخدم](./User%20Guide/User%20Guide/) في هذا Ų§Ł„Ł…Ų³ŲŖŁˆŲÆŲ¹ + +### روابط سريعة +- [ŲÆŁ„ŁŠŁ„ البدؔ Ų§Ł„Ų³Ų±ŁŠŲ¹](https://docs.triliumnotes.org/) +- [ŲŖŲ¹Ł„ŁŠŁ…Ų§ŲŖ Ų§Ł„ŲŖŲ«ŲØŁŠŲŖ](https://docs.triliumnotes.org/user-guide/setup) +- [Ų§Ų¹ŲÆŲ§ŲÆ + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [ŲŖŲ±Ł‚ŁŠŲ© ŲŖŲ±ŁŠŁ„ŁŠŁˆŁ… + للملاحظات](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Ł…ŁŲ§Ł‡ŁŠŁ… ŁˆŁ…Ł…ŁŠŲ²Ų§ŲŖ + أساسية](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [أنماط قاعدة المعرفة + Ų§Ł„Ų“Ų®ŲµŁŠŲ©](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Ų§Ł„Ł…Ł…ŁŠŲ²Ų§ŲŖ + +* ŁŠŁ…ŁƒŁ† ŲŖŁ†ŲøŁŠŁ… الملاحظات في Ų“Ų¬Ų±Ų© Ų°Ų§ŲŖ عمق غير Ł…Ų­ŲÆŁˆŲÆ. ŁƒŁ…Ų§ ŁŠŁ…ŁƒŁ† وضع الملاحظة Ų§Ł„ŁˆŲ§Ų­ŲÆŲ© + في Ų£Ł…Ų§ŁƒŁ† Ł…ŲŖŲ¹ŲÆŲÆŲ© داخل الؓجرة (Ų±Ų§Ų¬Ų¹ + [الاستنساخ](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Ł…Ų­Ų±Ų± ملاحظات WYSIWYG ŲŗŁ†ŁŠ ŁŠŲŖŲ¶Ł…Ł† على Ų³ŲØŁŠŁ„ المثال Ų§Ł„Ų¬ŲÆŲ§ŁˆŁ„ ŁˆŲ§Ł„ŲµŁˆŲ± + و[Ų§Ł„Ų±ŁŠŲ§Ų¶ŁŠŲ§ŲŖ](https://docs.triliumnotes.org/user-guide/note-types/text) Ł…Ų¹ + Markdown [ŲŖŁ†Ų³ŁŠŁ‚ + ŲŖŁ„Ł‚Ų§Ų¦ŁŠ](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* دعم تحرير [ملاحظات Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ…Ų§ŲŖ + Ų§Ł„ŲØŲ±Ł…Ų¬ŁŠŲ©](https://docs.triliumnotes.org/user-guide/note-types/code)، ŲØŁ…Ų§ في + Ų°Ł„Łƒ ŲŖŁ…ŁŠŁŠŲ² بناؔ الجملة +* [التنقل ŲØŁŠŁ† + الملاحظات](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation) + سهل وسريع، Ł…Ų¹ دعم البحث في النص Ų§Ł„ŁƒŲ§Ł…Ł„ŲŒ و[رفع + الملاحظات](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* نظام [Ų„ŲµŲÆŲ§Ų±Ų§ŲŖ + الملاحظات](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) + السلس +* ŁŠŁ…ŁƒŁ† Ų§Ų³ŲŖŲ®ŲÆŲ§Ł… + [السمات](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + Ł„ŲŖŁ†ŲøŁŠŁ… الملاحظات ŁˆŲ§Ł„Ų§Ų³ŲŖŲ¹Ł„Ų§Ł… عنها و[البرمجة + Ų§Ł„Ł†ŲµŁŠŲ©](https://docs.triliumnotes.org/user-guide/scripts) المتقدمة +* ŁˆŲ§Ų¬Ł‡Ų© المستخدم Ł…ŲŖŁˆŁŲ±Ų© باللغات Ų§Ł„Ų„Ł†Ų¬Ł„ŁŠŲ²ŁŠŲ© ŁˆŲ§Ł„Ų£Ł„Ł…Ų§Ł†ŁŠŲ© ŁˆŲ§Ł„Ų„Ų³ŲØŲ§Ł†ŁŠŲ© ŁˆŲ§Ł„ŁŲ±Ł†Ų³ŁŠŲ© + ŁˆŲ§Ł„Ų±ŁˆŁ…Ų§Ł†ŁŠŲ© ŁˆŲ§Ł„ŲµŁŠŁ†ŁŠŲ© (المبسطة ŁˆŲ§Ł„ŲŖŁ‚Ł„ŁŠŲÆŁŠŲ©) +* ŲŖŁƒŲ§Ł…Ł„ Ł…ŲØŲ§Ų“Ų± Ł…Ų¹ [أنظمة Ų§Ł„Ł‡ŁˆŁŠŲ© Ų§Ł„Ł…ŁŲŖŁˆŲ­Ų© OpenID ŁˆŁƒŁ„Ł…Ų§ŲŖ Ų§Ł„Ł…Ų±ŁˆŲ± المؤقتة + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) Ł„ŲŖŲ³Ų¬ŁŠŁ„ ŲÆŲ®ŁˆŁ„ + أكثر أماناً +* [المزامنة](https://docs.triliumnotes.org/user-guide/setup/synchronization) Ł…Ų¹ + Ų®Ų§ŲÆŁ… مزامنة Ł…ŁŲ³ŲŖŲ¶Ų§Ł Ų°Ų§ŲŖŁŠŁ‹Ų§ + * توجد [Ų®ŲÆŁ…Ų§ŲŖ خارجية لاستضافة Ų®Ų§ŲÆŁ… + المزامنة](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Ł…Ų“Ų§Ų±ŁƒŲ©](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + الملاحظات (نؓرها) على ؓبكة ال؄نترنت العامة +* [تؓفير + الملاحظات](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + تؓفير Ł‚ŁˆŁŠ Ł…Ų¹ Ų„Ł…ŁƒŲ§Ł†ŁŠŲ© Ų§Ł„ŲŖŲ­ŁƒŁ… ŲØŁƒŁ„ ملاحظة على Ų­ŲÆŲ© +* رسم Ų§Ł„Ł…Ų®Ų·Ų·Ų§ŲŖŲŒ بالاعتماد على Ų„ŁƒŲ³ŁƒŲ§Ł„ŁŠŲÆŲ±Ų§ [Excalidraw](https://excalidraw.com/) + (Ł†ŁˆŲ¹ الملاحظة "Ł„ŁˆŲ­Ų© رسم") +* [Ų®Ų±Ų§Ų¦Ų· + العلاقات](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + و[Ų®Ų±Ų§Ų¦Ų· الملاحظات + ŁˆŲ§Ł„Ų±ŁˆŲ§ŲØŲ·](https://docs.triliumnotes.org/user-guide/note-types/note-map) Ł„ŲŖŲµŁˆŲ± + الملاحظات ŁˆŲ§Ų±ŲŖŲØŲ§Ų·Ų§ŲŖŁ‡Ų§ ŲØŲµŲ±ŁŠŲ§Ł‹ +* الخرائط Ų§Ł„Ų°Ł‡Ł†ŁŠŲ©ŲŒ بالاعتماد على Ł…Ų§ŁŠŁ†ŲÆ Ų„Ł„ŁŠŁƒŲ³Ų± [Mind + Elixir](https://docs.mind-elixir.com/) +* "[الخرائط + Ų§Ł„Ų¬ŲŗŲ±Ų§ŁŁŠŲ©](https://docs.triliumnotes.org/user-guide/collections/geomap) Ł…Ų¹ + دبابيس Ų§Ł„Ł…ŁˆŁ‚Ų¹ ŁˆŁ…Ų³Ų§Ų±Ų§ŲŖ GPX (GPX = ŲŖŁ†Ų³ŁŠŁ‚ ŲŖŲØŲ§ŲÆŁ„ ŲØŁŠŲ§Ł†Ų§ŲŖ نظام تحديد Ų§Ł„Ł…ŁˆŲ§Ł‚Ų¹ + Ų§Ł„Ų¹Ų§Ł„Ł…ŁŠ) +* [البرمجة Ų§Ł„Ł†ŲµŁŠŲ©](https://docs.triliumnotes.org/user-guide/scripts) - Ų±Ų§Ų¬Ų¹ + [نماذج العرض + المتقدمة](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [ŁˆŲ§Ų¬Ł‡Ų© REST + API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) للأتمتة +* ŁŠŲŖŁ…ŁŠŲ² ŲØŲ³Ł‡ŁˆŁ„Ų© الاستخدام ŁˆŲ§Ł„Ų£ŲÆŲ§Ų” Ų§Ł„Ų¹Ų§Ł„ŁŠŁŠŁ†ŲŒ ويستوعب أكثر من 100,000 ملاحظة +* [ŁˆŲ§Ų¬Ł‡Ų© Ų¬ŁˆŲ§Ł„](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) + محسنة Ł„Ł„Ł…Ų³ŲŒ Ł…Ų®ŲµŲµŲ© Ł„Ł„Ł‡ŁˆŲ§ŲŖŁ Ų§Ł„Ų°ŁƒŁŠŲ© ŁˆŲ§Ł„Ų£Ų¬Ł‡Ų²Ų© Ų§Ł„Ł„ŁˆŲ­ŁŠŲ© +* [Ų§Ł„ŁˆŲ¶Ų¹ Ų§Ł„ŲÆŲ§ŁƒŁ†](https://docs.triliumnotes.org/user-guide/concepts/themes) + Ų§Ł„Ł…ŲÆŁ…Ų¬ŲŒ ŁˆŲÆŲ¹Ł… سمات المستخدم +* [Ų„ŁŠŁŁŠŲ±Ł†ŁˆŲŖ + (Evernote)](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + و[استيراد وتصدير ملفات + Markdown](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Ų£ŲÆŲ§Ų© قص Ų§Ł„ŁˆŁŠŲØ](https://docs.triliumnotes.org/user-guide/setup/web-clipper) + لحفظ Ł…Ų­ŲŖŁˆŁ‰ Ų§Ł„ŁˆŁŠŲØ ŲØŲ³Ł‡ŁˆŁ„Ų© +* ŁˆŲ§Ų¬Ł‡Ų© Ł…Ų³ŲŖŲ®ŲÆŁ… قابلة Ł„Ł„ŲŖŲ®ŲµŁŠŲµ (Ų£Ų²Ų±Ų§Ų± Ų§Ł„Ų“Ų±ŁŠŲ· Ų§Ł„Ų¬Ų§Ł†ŲØŁŠŲŒ أدوات المستخدم Ų§Ł„Ł…Ų­ŲÆŲÆŲ©ŲŒ ...) +* [Ł…Ų¤Ų“Ų±Ų§ŲŖ + الأداؔ](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics)، Ł…Ų¹ + Ł„ŁˆŲ­Ų© ŲŖŲ­ŁƒŁ… Grafana. + +✨ اطلع على Ų§Ł„Ł…ŁˆŲ§Ų±ŲÆ/المجتمعات Ų§Ł„Ų®Ų§Ų±Ų¬ŁŠŲ© Ų§Ł„ŲŖŲ§Ł„ŁŠŲ© Ł„Ł…Ų²ŁŠŲÆ من Ų§Ł„Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ Ų§Ł„Ł…ŁŁŠŲÆŲ© +المتعلقة ŲØŁ€ TriliumNext: + +- Ł„Ł„Ł‚ŁˆŲ§Ł„ŲØ ŁˆŲ§Ł„ŲØŲ±Ų§Ł…Ų¬ Ų§Ł„Ł†ŲµŁŠŲ© ŁˆŲ§Ł„Ų„Ų¶Ų§ŁŲ§ŲŖ Ų§Ł„Ų®Ų§Ų±Ų¬ŁŠŲ© ŁˆŲ§Ł„Ł…Ų²ŁŠŲÆ + [awesome-trillium](https://github.com/Nriver/awesome-trilium). +- Ł„Ł„Ų­ŲµŁˆŁ„ على دروس ŲŖŲ¹Ł„ŁŠŁ…ŁŠŲ©ŲŒ ŁˆŲ£ŲÆŁ„Ų©ŲŒ وغير Ų°Ł„Łƒ Ų§Ł„ŁƒŲ«ŁŠŲ± + [TriliumRocks!](https://trilium.rocks/). + +## ŲŸŁ„Ł…Ų§Ų°Ų§ TriliumNext؟ + +قام Ł…Ų·ŁˆŲ± Trilium Ų§Ł„Ų£ŲµŁ„ŁŠ ([Zadam](https://github.com/zadam)) Ł…Ų“ŁƒŁˆŲ±Ł‹Ų§ ب؄هداؔ +Ł…Ų³ŲŖŁˆŲÆŲ¹ Trilium ؄لى Ł…Ų“Ų±ŁˆŲ¹ المجتمع Ų§Ł„Ł…ŁˆŲ¬ŁˆŲÆ على الرابط Ų§Ł„ŲŖŲ§Ł„ŁŠ: +https://github.com/TriliumNext + +### ā¬†ļøŲ§Ł„Ų§Ł†ŲŖŁ‚Ų§Ł„ من Zadam/Trilium؟ + +لا توجد خطوات انتقال Ų®Ų§ŲµŲ© للانتقال من نسخة zadam/Trilium ؄لى نسخة +TriliumNext/Trilium. Ł…Ų§ Ų¹Ł„ŁŠŁƒ Ų³ŁˆŁ‰ تثبيت TriliumNext/Trilium ŁƒŲ§Ł„Ł…Ų¹ŲŖŲ§ŲÆŲŒ ŁˆŲ³ŁŠŲ³ŲŖŲ®ŲÆŁ… +قاعدة ŲØŁŠŲ§Ł†Ų§ŲŖŁƒ Ų§Ł„Ų­Ų§Ł„ŁŠŲ©. + +ال؄صدارات حتى ال؄صدار +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) Ł…ŲŖŁˆŲ§ŁŁ‚Ų© +Ł…Ų¹ Ų£Ų­ŲÆŲ« Ų„ŲµŲÆŲ§Ų± من zadam/trillium ŁˆŁ‡Łˆ [v0.63.7]{2]. أما ال؄صدارات اللاحقة من +TriliumNext/Trilium، فقد ŲŖŁ… تحديث أرقام المزامنة الخاصة ŲØŁ‡Ų§ŲŒ Ł…Ł…Ų§ ŁŠŁ…Ł†Ų¹ Ų§Ł„ŲŖŲ±Ł‚ŁŠŲ© +المباؓرة. + +## šŸ’¬ ناقؓ معنا + +لا تترددوا في الانضمام ؄لى محادثاتنا Ų§Ł„Ų±Ų³Ł…ŁŠŲ©. ŁŠŲ³Ų¹ŲÆŁ†Ų§ أن نسمع عن Ų§Ł„Ł…ŁŠŲ²Ų§ŲŖ أو +الاقتراحات أو Ų§Ł„Ł…Ų“Ų§ŁƒŁ„ Ų§Ł„ŲŖŁŠ قد ŲŖŁˆŲ§Ų¬Ł‡ŁˆŁ†Ł‡Ų§! + +- [Ł…Ų§ŲŖŲ±ŁŠŁƒŲ³ (Matrix)](https://matrix.to/#/#triliumnext:matrix.org) (للمناقؓات + المتزامنة.) + - غرفة Ł…Ų§ŲŖŲ±ŁŠŁƒŲ³ `العامة` Ł…Ų±ŲŖŲØŲ·Ų© Ų£ŁŠŲ¶Ų§Ł‹ ŲØŁ€ + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) (Extensible Messaging and + Presence Protocol) +- [مناقؓات GitHub](https://github.com/TriliumNext/Trilium/discussions) + (للمناقؓات غير المتزامنة.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (Ł„ŲŖŁ‚ŲÆŁŠŁ… ŲŖŁ‚Ų§Ų±ŁŠŲ± + الأخطاؔ ŁˆŲ·Ł„ŲØŲ§ŲŖ Ų§Ł„Ł…ŁŠŲ²Ų§ŲŖ.) + +## šŸ—ļø Ų§Ł„ŲŖŲ«ŲØŁŠŲŖ + +### ŁˆŁŠŁ†ŲÆŁˆŲ² (Windows) / نظام ŲŖŲ“ŲŗŁŠŁ„ Ł…Ų§Łƒ (MacOS) + +نزل ال؄صدار Ų§Ł„Ų«Ł†Ų§Ų¦ŁŠ (Binary) المناسب Ł„Ł…Ł†ŲµŲŖŁƒ من [صفحة Ų£Ų­ŲÆŲ« +ال؄صدارات](https://github.com/TriliumNext/Trilium/releases/latest)، Ų«Ł… فك Ų¶ŲŗŲ· +الحزمة ŁˆŲ“ŲŗŁ‘Ł„ ملف `trilium` Ų§Ł„ŲŖŁ†ŁŁŠŲ°ŁŠ. + +### Ł„ŁŠŁ†ŁƒŲ³ (Linux) + +Ų„Ų°Ų§ ŁƒŲ§Ł†ŲŖ توزيعتك Ł…ŲÆŲ±Ų¬Ų© في Ų§Ł„Ų¬ŲÆŁˆŁ„ Ų£ŲÆŁ†Ų§Ł‡ŲŒ فاستخدم الحزمة الخاصة بتوزيعتك. + +[![حالة +الحزم](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +ŁŠŁ…ŁƒŁ†Łƒ Ų£ŁŠŲ¶Ł‹Ų§ ŲŖŁ†Ų²ŁŠŁ„ ال؄صدار Ų§Ł„Ų«Ł†Ų§Ų¦ŁŠ Ł„Ł…Ł†ŲµŲŖŁƒ من [صفحة Ų£Ų­ŲÆŲ« +Ų„ŲµŲÆŲ§Ų±](https://github.com/TriliumNext/Trilium/releases/latest)، وفك Ų¶ŲŗŲ· الحزمة +ŁˆŲŖŲ“ŲŗŁŠŁ„ الملف Ų§Ł„ŲŖŁ†ŁŁŠŲ°ŁŠ `trillium`. + +ŁŠŲŖŁ… توفير TriliumNext Ų£ŁŠŲ¶Ł‹Ų§ ŁƒŁ€ Flatpak، ŁˆŁ„ŁƒŁ† لم ŁŠŲŖŁ… نؓره ŲØŲ¹ŲÆ على FlatHub. + +### متصفح (أي نظام ŲŖŲ“ŲŗŁŠŁ„) + +Ų„Ų°Ų§ ŁƒŁ†ŲŖ ŲŖŲ³ŲŖŲ®ŲÆŁ… تثبيت الخادم (انظر أدناه)، ŁŁŠŁ…ŁƒŁ†Łƒ Ų§Ł„ŁˆŲµŁˆŁ„ Ł…ŲØŲ§Ų“Ų±Ų© ؄لى ŁˆŲ§Ų¬Ł‡Ų© Ų§Ł„ŁˆŁŠŲØ +(ŁˆŁ‡ŁŠ مطابقة ŲŖŁ‚Ų±ŁŠŲØŁ‹Ų§ Ł„ŲŖŲ·ŲØŁŠŁ‚ Ų³Ų·Ų­ Ų§Ł„Ł…ŁƒŲŖŲØ). + +Ų­Ų§Ł„ŁŠŲ§Ł‹ŲŒ ŁŠŲŖŁ… دعم Ų£Ų­ŲÆŲ« Ų„ŲµŲÆŲ§Ų±Ų§ŲŖ Ł…ŲŖŲµŁŲ­ŁŠ Chrome و Firefox فقط (ŁˆŲ§Ł„ŲŖŁŠ ŲŖŁ… اختبارها). + +### الهاتف Ų§Ł„Ł…Ų­Ł…ŁˆŁ„ + +لاستخدام TriliumNext على الأجهزة Ų§Ł„Ł…Ų­Ł…ŁˆŁ„Ų©ŲŒ ŁŠŁ…ŁƒŁ†Łƒ Ų§Ų³ŲŖŲ®ŲÆŲ§Ł… المتصفح Ł„Ł„ŁˆŲµŁˆŁ„ ؄لى +ŁˆŲ§Ų¬Ł‡Ų© Ų§Ł„Ų¬ŁˆŲ§Ł„ الخاصة بنسخة الخادم المثبتة (انظر أدناه). + +Ų±Ų§Ų¬Ų¹ Ų§Ł„Ł…Ų“ŁƒŁ„Ų© رقم https://github.com/TriliumNext/Trilium/issues/4962 Ł„Ł…Ų²ŁŠŲÆ من +Ų§Ł„Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ Ų­ŁˆŁ„ دعم Ų„ŲµŲÆŲ§Ų± الهاتف Ų§Ł„Ł…Ų­Ł…ŁˆŁ„. + +Ų„Ų°Ų§ ŁƒŁ†ŲŖ تفضل ŲŖŲ·ŲØŁŠŁ‚Ł‹Ų§ Ų£ŲµŁ„ŁŠŁ‹Ų§ لنظام Android، ŁŠŁ…ŁƒŁ†Łƒ Ų§Ų³ŲŖŲ®ŲÆŲ§Ł… +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +أبلغ عن الأخطاؔ ŁˆŲ§Ł„Ł…ŁŠŲ²Ų§ŲŖ Ų§Ł„Ł…ŁŁ‚ŁˆŲÆŲ© في +[Ł…Ų³ŲŖŁˆŲÆŲ¹Ł‡Ł…](https://github.com/FliegendeWurst/TriliumDroid). ملاحظة: ŁŠŁŁŲ¶Ł„ ŲŖŲ¹Ų·ŁŠŁ„ +Ų§Ł„ŲŖŲ­ŲÆŁŠŲ«Ų§ŲŖ Ų§Ł„ŲŖŁ„Ł‚Ų§Ų¦ŁŠŲ© على تثبيت الخادم الخاص بك (انظر أدناه) عند Ų§Ų³ŲŖŲ®ŲÆŲ§Ł… +TriliumDroid، حيث يجب أن ŲŖŲŖŲ·Ų§ŲØŁ‚ نسخة المزامنة ŲØŁŠŁ† Trilium وTriliumDroid. + +### Ų®Ų§ŲÆŁ… + +Ł„ŲŖŲ«ŲØŁŠŲŖ TriliumNext على Ų®Ų§ŲÆŁ…Łƒ الخاص (ŲØŁ…Ų§ في Ų°Ł„Łƒ Ų¹ŲØŲ± Docker من +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) Ų§ŲŖŲØŲ¹ [ŁˆŲ«Ų§Ų¦Ł‚ تثبيت +الخادم]{2]. + + +## šŸ’» المساهمة + +### الترجمات + +Ų„Ų°Ų§ ŁƒŁ†ŲŖ متحدثًا Ų£ŲµŁ„ŁŠŁ‹Ų§ Ł„Ł„ŲŗŲ©ŲŒ فساعدنا في ترجمة Trilium من خلال Ų§Ł„ŲŖŁˆŲ¬Ł‡ ؄لى [صفحة +Ų§Ł„ŁˆŁŠŲØ]{1]. + +Ų„Ł„ŁŠŁƒ قائمة نسبة Ų§ŁƒŲŖŁ…Ų§Ł„ اللغات Ų§Ł„Ł…ŲÆŲ¹ŁˆŁ…Ų© حتى الآن: + +[![حالة +الترجمة](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ…Ų§ŲŖ Ų§Ł„ŲØŲ±Ł…Ų¬ŁŠŲ© + +قم ŲØŲŖŁ†Ų²ŁŠŁ„ Ų§Ł„Ł…Ų³ŲŖŁˆŲÆŲ¹ŲŒ ŁˆŁ‚Ł… بتثبيت Ų§Ł„ŲŖŲØŲ¹ŁŠŲ§ŲŖ ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… `pnpm`، Ų«Ł… قم ŲØŲŖŲ“ŲŗŁŠŁ„ الخادم +(المتاح على http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Ų§Ł„ŲŖŁˆŲ«ŁŠŁ‚ + +قم ŲØŲŖŁ†Ų²ŁŠŁ„ Ų§Ł„Ł…Ų³ŲŖŁˆŲÆŲ¹ŲŒ ŁˆŁ‚Ł… بتثبيت Ų§Ł„ŲŖŲØŲ¹ŁŠŲ§ŲŖ ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… `pnpm`، Ų«Ł… قم ŲØŲŖŲ“ŲŗŁŠŁ„ Ų§Ł„ŲØŁŠŲ¦Ų© +Ų§Ł„Ł…Ų·Ł„ŁˆŲØŲ© Ł„ŲŖŲ­Ų±ŁŠŲ± Ų§Ł„ŁˆŲ«Ų§Ų¦Ł‚: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### بناؔ الملف Ų§Ł„ŲŖŁ†ŁŁŠŲ°ŁŠ +قم ŲØŲŖŁ†Ų²ŁŠŁ„ Ų§Ł„Ł…Ų³ŲŖŁˆŲÆŲ¹ŲŒ ŁˆŁ‚Ł… بتثبيت Ų§Ł„ŲŖŲØŲ¹ŁŠŲ§ŲŖ ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… `pnpm`، Ų«Ł… قم ببناؔ ŲŖŲ·ŲØŁŠŁ‚ Ų³Ų·Ų­ +Ų§Ł„Ł…ŁƒŲŖŲØ لنظام Ų§Ł„ŲŖŲ“ŲŗŁŠŁ„ ŁˆŁŠŁ†ŲÆŁˆŲ² (Windows): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Ł„Ł…Ų²ŁŠŲÆ من Ų§Ł„ŲŖŁŲ§ŲµŁŠŁ„ŲŒ Ų±Ų§Ų¬Ų¹ [ŁˆŲ«Ų§Ų¦Ł‚ +Ų§Ł„ŲŖŲ·ŁˆŁŠŲ±](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### ŁˆŲ«Ų§Ų¦Ł‚ Ų§Ł„Ł…Ų·ŁˆŲ±ŁŠŁ† + +ŁŠŲ±Ų¬Ł‰ الاطلاع على [ŲÆŁ„ŁŠŁ„ +Ų§Ł„ŲŖŁˆŲ«ŁŠŁ‚](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +Ł„Ł…Ų²ŁŠŲÆ من Ų§Ł„ŲŖŁŲ§ŲµŁŠŁ„. Ų„Ų°Ų§ ŁƒŲ§Ł†ŲŖ Ł„ŲÆŁŠŁƒŁ… أي استفسارات Ų£Ų®Ų±Ł‰ŲŒ فلا تترددوا في Ų§Ł„ŲŖŁˆŲ§ŲµŁ„ معنا +Ų¹ŲØŲ± Ų§Ł„Ų±ŁˆŲ§ŲØŲ· Ų§Ł„Ł…ŁˆŲ¶Ų­Ų© في قسم "ناقؓ معنا" أعلاه. + +## šŸ‘ ؓكر Ų®Ų§Ųµ + +* لـ [zadam](https://github.com/zadam): Ł„Ł„Ł…ŁŁ‡ŁˆŁ… Ų§Ł„Ų£ŲµŁ„ŁŠ ŁˆŲŖŁ†ŁŁŠŲ° Ų§Ł„ŲŖŲ·ŲØŁŠŁ‚. +* لـ [Ų³Ų§Ų±Ų© Ų­Ų³ŁŠŁ† (Sarah Hussein)](https://github.com/Sarah-Hussein): Ł„ŲŖŲµŁ…ŁŠŁ… + Ų£ŁŠŁ‚ŁˆŁ†Ų© Ų§Ł„ŲŖŲ·ŲØŁŠŁ‚. +* لـ [nriver](https://github.com/nriver): لعمله على ŲŖŲÆŁˆŁŠŁ„ Ų§Ł„ŲŖŲ·ŲØŁŠŁ‚ (دعم اللغات). +* لـ [Thomas Frei](https://github.com/thfrei): لعمله Ų§Ł„Ų£ŲµŁ„ŁŠ على "Ų§Ł„Ł„ŁˆŲ­Ų©" + (Canvas). +* لـ [antoniotejada](https://github.com/nriver): لأداة ŲŖŁ…ŁŠŁŠŲ² Ų§Ł„ŲµŁŠŲŗŲ© Ų§Ł„ŲØŲ±Ł…Ų¬ŁŠŲ© + (Syntax highlight) Ų§Ł„Ų£ŲµŁ„ŁŠŲ©. +* لـ [Dosu](https://dosu.dev/): Ł„ŲŖŲ²ŁˆŁŠŲÆŁ†Ų§ ŲØŲ§Ł„Ų±ŲÆŁˆŲÆ Ų§Ł„Ų¢Ł„ŁŠŲ© على Ł…Ų“ŁƒŁ„Ų§ŲŖ ŁˆŁ†Ł‚Ų§Ų“Ų§ŲŖ + GitHub. +* لـ [Tabler Icons](https://tabler.io/icons): Ł„Ų£ŁŠŁ‚ŁˆŁ†Ų§ŲŖ ؓريط النظام. + +لم ŁŠŁƒŁ† لـ Trilium أن ŁŠŲ±Ł‰ Ų§Ł„Ł†ŁˆŲ± Ł„ŁˆŁ„Ų§ Ų§Ł„ŲŖŁ‚Ł†ŁŠŲ§ŲŖ Ų§Ł„ŲŖŁŠ تقف خلفه: + +* Ł…Ų­Ų±Ų± [CKEditor 5](https://github.com/ckeditor/ckeditor5): - المحرر Ų§Ł„Ł…Ų±Ų¦ŁŠ خلف + الملاحظات Ų§Ł„Ł†ŲµŁŠŲ©. نحن Ł…Ł…ŲŖŁ†ŁˆŁ† Ł„Ų­ŲµŁˆŁ„Ł†Ų§ على Ł…Ų¬Ł…ŁˆŲ¹Ų© من Ų§Ł„Ł…ŁŠŲ²Ų§ŲŖ Ų§Ł„Ł…ŲÆŁŁˆŲ¹Ų© (Premium). +* Ł…Ų­Ų±Ų± [CodeMirror](https://github.com/codemirror/CodeMirror): - Ł…Ų­Ų±Ų± أكواد ŁŠŲÆŲ¹Ł… + Ų¹ŲÆŲÆŲ§Ł‹ هائلاً من اللغات. +* برنامج [Excalidraw](https://github.com/excalidraw/excalidraw): - Ų§Ł„Ų³ŲØŁˆŲ±Ų© + Ų§Ł„ŲØŁŠŲ¶Ų§Ų” Ų§Ł„Ł„Ų§Ł†Ł‡Ų§Ų¦ŁŠŲ© المستخدمة في ملاحظات Canvas. +* برنامج [Mind Elixir](https://github.com/SSShooter/mind-elixir-core): - يوفر + وظائف الخرائط Ų§Ł„Ų°Ł‡Ł†ŁŠŲ©. +* برنامج [Leaflet](https://github.com/Leaflet/Leaflet): - لعرض الخرائط + Ų§Ł„Ų¬ŲŗŲ±Ų§ŁŁŠŲ©. +* Ł…ŁƒŲŖŲØŲ© [Tabulator](https://github.com/olifolkerd/tabulator): - Ł„Ł„Ų¬ŲÆŲ§ŁˆŁ„ + Ų§Ł„ŲŖŁŲ§Ų¹Ł„ŁŠŲ© المستخدمة في Ų§Ł„Ł…Ų¬Ł…ŁˆŲ¹Ų§ŲŖ. +* Ł…ŁƒŲŖŲØŲ© [FancyTree](https://github.com/mar10/fancytree): - Ł…ŁƒŲŖŲØŲ© "ؓجرية" ŲŗŁ†ŁŠŲ© + ŲØŲ§Ł„Ł…ŁŠŲ²Ų§ŲŖ ŁˆŁ„Ų§ يوجد لها منافس Ų­Ł‚ŁŠŁ‚ŁŠ. +* Ł…ŁƒŲŖŲØŲ© [jsPlumb](https://github.com/jsplumb/jsplumb): - Ł…ŁƒŲŖŲØŲ© للربط Ų§Ł„Ł…Ų±Ų¦ŁŠŲŒ + ŲŖŁŲ³ŲŖŲ®ŲÆŁ… في [Ų®Ų±Ų§Ų¦Ų· + العلاقات](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + و[Ų®Ų±Ų§Ų¦Ų· + Ų§Ł„Ų±ŁˆŲ§ŲØŲ·](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ الدعم + +ŲŖŁ… بناؔ ŁˆŲµŁŠŲ§Ł†Ų© برنامج Trilium ŲØŁ…Ų¦Ų§ŲŖ الساعات من العمل. ŲÆŲ¹Ł…ŁƒŁ… يحافظ على ŁƒŁˆŁ†Ł‡ Ł…ŁŲŖŁˆŲ­ +Ų§Ł„Ł…ŲµŲÆŲ±ŲŒ ŁˆŁŠŲ­Ų³Ł† Ų§Ł„Ł…ŁŠŲ²Ų§ŲŖŲŒ ويغطي Ų§Ł„ŲŖŁƒŲ§Ł„ŁŠŁ Ł…Ų«Ł„ الاستضافة. + +ŁŠŲ±Ų¬Ł‰ Ų§Ł„ŲŖŁŁƒŁŠŲ± في دعم Ų§Ł„Ł…Ų·ŁˆŲ± Ų§Ł„Ų±Ų¦ŁŠŲ³ŁŠ ([eliandoran](https://github.com/eliandoran)) +Ł„Ł„ŲŖŲ·ŲØŁŠŁ‚ Ų¹ŲØŲ±: + +- [Ų±Ų¹Ų§Ų© GitHub](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [اؓترِ Ł„ŁŠ Ł‚Ł‡ŁˆŲ©](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ Ų§Ł„ŲŖŲ±Ų®ŁŠŲµ + +Ų¬Ł…ŁŠŲ¹ Ų§Ł„Ų­Ł‚ŁˆŁ‚ Ł…Ų­ŁŁˆŲøŲ© لـ zadam ŁˆŲ„Ł„ŁŠŲ§Ł† ŲÆŁˆŲ±Ų§Ł† ŁˆŁ…Ų³Ų§Ł‡Ł…ŁŠŁ† Ų¢Ų®Ų±ŁŠŁ†ŲŒ من Ų¹Ų§Ł… 2017 ؄لى Ų¹Ų§Ł… +2025 + +هذا البرنامج Ł‡Łˆ برنامج Ł…Ų¬Ų§Ł†ŁŠ: ŁŠŁ…ŁƒŁ†Łƒ Ų„Ų¹Ų§ŲÆŲ© ŲŖŁˆŲ²ŁŠŲ¹Ł‡ و/أو ŲŖŲ¹ŲÆŁŠŁ„Ł‡ ŲØŁ…ŁˆŲ¬ŲØ ؓروط Ų±Ų®ŲµŲ© Ų¬Ł†Łˆ +أفيرو (GNU Affero) العامة ŁƒŁ…Ų§ نؓرتها Ł…Ų¤Ų³Ų³Ų© Ų§Ł„ŲØŲ±Ł…Ų¬ŁŠŲ§ŲŖ Ų§Ł„Ų­Ų±Ų©ŲŒ سواؔ ال؄صدار 3 من +Ų§Ł„Ų±Ų®ŲµŲ©ŲŒ أو (Ų­Ų³ŲØ اختيارك) أي Ų„ŲµŲÆŲ§Ų± لاحق. diff --git a/docs/README-bg.md b/docs/README-bg.md new file mode 100644 index 0000000000..0da3a37bf9 --- /dev/null +++ b/docs/README-bg.md @@ -0,0 +1,337 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking +application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation + directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-ca.md b/docs/README-ca.md new file mode 100644 index 0000000000..db5d437085 --- /dev/null +++ b/docs/README-ca.md @@ -0,0 +1,338 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trillium Notes Ć©s una aplicació gratuĆÆta i de codi obert, multiplataforma, per +prendre notes jerĆ rquiques, amb l'objectiu de crear grans bases de coneixement +personal. + +Trilium Screenshot + +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation + directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-cs.md b/docs/README-cs.md new file mode 100644 index 0000000000..aa93e2bd04 --- /dev/null +++ b/docs/README-cs.md @@ -0,0 +1,339 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![Sponzoři GitHubu](https://img.shields.io/github/sponsors/eliandoran) ![Patroni +LiberaPay](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![StahovĆ”nĆ­ GitHubu (vÅ”echny soubory, vÅ”echna +vydĆ”nĆ­)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Stav +překladu](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes je open-source, cross-platform aplikace pro hierarchiĆ”lnĆ­ psanĆ­ +poznĆ”mek. + +Trilium Screenshot + +## ā¬ StĆ”hnout +- [NejnovějŔí verze](https://github.com/TriliumNext/Trilium/releases/latest) – + stabilnĆ­ verze, doporučena pro větÅ”inu uživatelÅÆ. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + nestabilnĆ­ vývojovĆ” verze, denně aktualizovanĆ” o nejnovějŔí funkce a opravy. + +## šŸ“š Dokumentace + +**NavÅ”tivte naÅ”i rozsĆ”hlou dokumentaci na +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +NaÅ”e dokumenatce je dostupnĆ” ve vĆ­cero formĆ”tech: +- **Online dokumentace**: ProhlĆ©dněte si kompletnĆ­ dokumentaci na + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Pomoc v aplikaci**: V Trilium stiskněte `F1`, pro přístup k stejnĆ© + dokumentaci přímo v aplikaci +- **GitHub**: Projděte si [Uživatelskou příručku](./User%20Guide/User%20Guide/) + v tomto repozitÔři + +### RychlĆ© odkazy +- [NĆ”vod pro zaÄĆ”tečnĆ­ky](https://docs.triliumnotes.org/) +- [Pokyny pro instalaci](https://docs.triliumnotes.org/user-guide/setup) +- [NastavenĆ­ + Dockeru](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [AktualizovĆ”nĆ­ + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [ZĆ”kladnĆ­ pojmy a + funkce](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Vzory osobnĆ­ znalostnĆ­ + bĆ”ze](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Funkce + +* PoznĆ”mky lze uspořÔdat do libovolně hlubokĆ©ho stromu. Jedna poznĆ”mka může být + umĆ­stěna na vĆ­ce mĆ­stech ve stromu (viz + [klonovĆ”nĆ­](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Bohatý editor poznĆ”mek WYSIWYG zahrnujĆ­cĆ­ např. tabulky, obrĆ”zky a + [math](https://docs.triliumnotes.org/user-guide/note-types/text) s + automatickým formĆ”tovĆ”nĆ­m + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Podpora pro Ćŗpravy [poznĆ”mek se zdrojovým + kódem](https://docs.triliumnotes.org/user-guide/note-types/code), včetně + zvýrazněnĆ­ syntaxe +* RychlĆ” a snadnĆ” [navigace mezi + poznĆ”mkami](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + vyhledĆ”vĆ”nĆ­ v plnĆ©m textu a [zvedĆ”nĆ­ + poznĆ”mek](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* BezproblĆ©movĆ” [poznĆ”mka k + verzĆ­m](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* PoznĆ”mka + [atributy](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + lze použít pro organizaci poznĆ”mek, dotazovĆ”nĆ­ a pokročilĆ© + [skriptovĆ”nĆ­](https://docs.triliumnotes.org/user-guide/scripts) +* UživatelskĆ© rozhranĆ­ je k dispozici v angličtině, čeÅ”tině, němčině, + Å”panělÅ”tině, francouzÅ”tině, rumunÅ”tině a čƭnÅ”tině (zjednoduÅ”enĆ© a tradičnĆ­) +* PřímĆ” integrace [OpenID a + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) pro + bezpečnějŔí přihlÔŔenĆ­ +* [Synchronizace](https://docs.triliumnotes.org/user-guide/setup/synchronization) + s vlastnĆ­m synchronizačnĆ­m serverem + * existujĆ­ [služby třetĆ­ch stran pro hostovĆ”nĆ­ synchronizačnĆ­ch + serverÅÆ](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [SdĆ­lenĆ­](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (zveřejňovĆ”nĆ­) poznĆ”mek na veřejnĆ©m internetu +* SilnĆ© [Å”ifrovĆ”nĆ­ + poznĆ”mek](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + s granularitou na Ćŗrovni jednotlivých poznĆ”mek +* NĆ”Ärt diagramÅÆ na zĆ”kladě [Excalidraw](https://excalidraw.com/) (poznĆ”mka typu + ā€žplĆ”tnoā€œ) +* [Mapy vazeb](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + a [PoznĆ”mka/mapa + odkazÅÆ](https://docs.triliumnotes.org/user-guide/note-types/note-map) pro + vizualizaci poznĆ”mek a jejich vazeb +* MyÅ”lenkovĆ© mapy založenĆ© na [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo mapy](https://docs.triliumnotes.org/user-guide/collections/geomap) s + lokalizačnĆ­mi značkami a trasami GPX +* [SkriptovĆ”nĆ­](https://docs.triliumnotes.org/user-guide/scripts) – viz + [PokročilĆ© + ukĆ”zky](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) pro + automatizaci +* Dobře Å”kĆ”lovatelný jak z hlediska použitelnosti, tak výkonu až do 100 000 + poznĆ”mek +* OptimalizovanĆ© pro dotykovĆ© ovlĆ”dĆ”nĆ­ [mobilnĆ­ + rozhranĆ­](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) pro + smartphony a tablety +* Vestavěný [tmavý + motiv](https://docs.triliumnotes.org/user-guide/concepts/themes), podpora + uživatelských motivÅÆ +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-de.md b/docs/README-de.md new file mode 100644 index 0000000000..051d0af07a --- /dev/null +++ b/docs/README-de.md @@ -0,0 +1,354 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes ist eine freie, open-source, plattformfreie, hierarchische +Notiz-Anwendung mit Fokus auf die Erstellung großer persƶnlicher +Wissenssammlungen. + +Trilium Screenshot + +## ā¬ Download +- [Neueste Version](https://github.com/TriliumNext/Trilium/releases/latest) – + stabile Version, für die meisten Benutzer empfohlen. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + instabile Entwicklungsversion, die tƤglich mit den neuesten Funktionen und + Fehlerbehebungen aktualisiert wird. + +## šŸ“š Dokumentation + +**Besuche unsere umfassende Dokumentation unter +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Unsere Dokumentation ist verfügbar in mehreren Formaten: +- **Online-Dokumentation**: Die vollstƤndige Dokumentation finden man unter + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App-Hilfe**: drücke `F1` in Trilium, um dieselbe Dokumentation direkt in + der Anwendung aufzurufen +- **GitHub**: Durchsuche das [Benutzerhandbuch](./User%20Guide/User%20Guide/) in + diesem Repository + +### Schnellzugriff +- [Erste Schritte](https://docs.triliumnotes.org/) +- [Installationsanleitung](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Einrichten](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [TriliumNext + aktualisieren](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Grundkonzepte und + Funktionen](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Muster persƶnlicher + Wissensdatenbanken](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Funktionen + +* Notizen lassen sich in beliebig tiefe Baumstrukturen einordnen. Eine einzelne + Notiz kann an mehreren Stellen im Baum existieren (siehe + [Klonen](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Umfangreicher WYSIWYG-Editor für Notizen, z. B. mit Tabellen, Bildern und + [Mathematik](https://docs.triliumnotes.org/user-guide/note-types/text) mit + Markdown-Autoformatierung +* Unterstützung für das Bearbeiten von [Notizen mit + Quellcode](https://docs.triliumnotes.org/user-guide/note-types/code), inkl. + Syntaxhervorhebung +* Schnelle und einfache [Navigation zwischen + Notizen](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + Volltextsuche sowie + [Notizhervorhebung](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Nahtlose [Versionierung von + Notizen](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Notiz + [Attribute](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + kƶnnen zur Organisation von Notizen, für Abfragen und erweiterte + [Skripterstellung](https://docs.triliumnotes.org/user-guide/scripts) verwendet + werden +* BenutzeroberflƤche verfügbar in Englisch, Deutsch, Spanisch, Franzƶsisch, + RumƤnisch sowie Chinesisch (vereinfacht und traditionell) +* Direkte [OpenID- und + TOTP-Integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) + für eine sicherere Anmeldung +* [Synchronisierung](https://docs.triliumnotes.org/user-guide/setup/synchronization) + mit einem selbst gehosteten Synchronisierungsserver + * Es gibt [Drittanbieter-Dienste für das Hosting von + Synchronisationsservern](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Freigabe](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (Verƶffentlichung) von Notizen im ƶffentlichen Internet +* Starke + [Notizverschlüsselung](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + mit GranularitƤt pro Notiz +* Skizzieren von Diagrammen basierend auf [Excalidraw](https://excalidraw.com/) + (Notiztyp ā€žLeinwandā€œ) +* [Beziehungskarten](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + und + [Notiz-/Link-Karten](https://docs.triliumnotes.org/user-guide/note-types/note-map) + zur Visualisierung von Notizen und ihren Beziehungen +* Mindmaps, basierend auf [Mind Elixir](https://docs.mind-elixir.com/) +* [Geokarten](https://docs.triliumnotes.org/user-guide/collections/geomap) mit + Standortmarkierungen und GPX-Tracks +* [Skripting](https://docs.triliumnotes.org/user-guide/scripts) – siehe + [Erweiterte + Showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST-API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) für + die Automatisierung +* Skalierbar in Bedienbarkeit und Performance — geeignet für über 100.000 + Notizen +* Touch-optimiertes [mobiles + Frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) für + Smartphones und Tablets +* Integriertes [dunkles + Design](https://docs.triliumnotes.org/user-guide/concepts/themes), + Unterstützung für benutzerdefinierte Designs +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + und [Markdown importieren und + exportieren](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) zum + einfachen Speichern von Webinhalten +* Anpassbare BenutzeroberflƤche (Seitenleisten-SchaltflƤchen, benutzerdefinierte + Widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + zusƤtzlich mit dem Grafana Dashboard. + +✨ Weitere Informationen zu TriliumNext findet man in den folgenden +Ressourcen/Communities von Drittanbietern: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) bietet von + Drittanbietern erstellte Themes, Skripte, Plugins und vieles mehr. +- [TriliumRocks!](https://trilium.rocks/) für Tutorials, Anleitungen und vieles + mehr. + +## ā“ Warum TriliumNext? + +Der ursprüngliche Entwickler von Trilium ([Zadam](https://github.com/zadam)) hat +das Trilium-Repository der Gemeinschaft übergeben, die nun unter +https://github.com/TriliumNext agiert + +### Migration von Zadam/Trilium? + +Es sind keine speziellen Migrationsschritte erforderlich, um von einer +zadam/Trilium-Instanz auf eine TriliumNext/Trilium-Instanz umzustellen. +[Installiere TriliumNext/Trilium](#-installation) einfach wie gewohnt, und die +vorhandene Datenbank wird verwendet. + +Versionen bis einschließlich +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) sind +kompatibel mit der letzten zadam/trilium-Version +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Alle spƤteren +Versionen von TriliumNext/Trilium haben ihre Sync-Versionen erhƶht, was eine +direkte Migration verhindert. + +## šŸ’¬ Diskussion mit uns + +Nehme gerne an den offiziellen Diskussionen teil. Feedback, FunktionsvorschlƤge +oder Problemberichte sind jederzeit willkommen! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (für + Echtzeit-Diskussionen.) + - Der `allgemeine` Matrix-Raum ist zusƤtzlich mit + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) verbunden +- [Github Diskussionen](https://github.com/TriliumNext/Trilium/discussions) (für + asynchrone Diskussionen) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (für + Fehlerberichte und Funktionsanfragen) + +## šŸ— Installation + +### Windows / MacOS + +Lade die BinƤrversion für deine Plattform von der Seite mit der [neuesten +Version](https://github.com/TriliumNext/Trilium/releases/latest) herunter, +entpacke das Paket und führe die ausführbare Datei `trilium` aus. + +### Linux + +Wenn deine Distribution in der folgenden Tabelle aufgeführt ist, verwende das +Paket deiner Distribution. + +[![Paketierungsstatus](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +Du kannst auch die BinƤrversion für deine Plattform von der Seite mit der +[neuesten Version](https://github.com/TriliumNext/Trilium/releases/latest) +herunterladen, das Paket entpacken und die ausführbare Datei `trilium` +ausführen. + +TriliumNext ist auch als Flatpak verfügbar, jedoch noch nicht auf Flathub +verƶffentlicht. + +### Browser (beliebiges Betriebssystem) + +Bei Verwendung einer Server-Installation (siehe unten) kann direkt auf die +WeboberflƤche zugegriffen werden. (die nahezu identisch mit der +Desktop-Anwendung ist). + +Derzeit werden ausschließlich die neuesten Versionen von Chrome und Firefox +unterstützt (und getestet). + +### MobilgerƤte + +Um TriliumNext auf einem mobilen GerƤt zu verwenden, kann ein mobiler Webbrowser +genutzt werden, um die mobile OberflƤche einer Server-Installation (siehe unten) +aufzurufen. + +Weitere Informationen zur Unterstützung mobiler Apps findest du unter +https://github.com/TriliumNext/Trilium/issues/4962. + +Wenn du eine native Android-App bevorzugst, kannst du +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid) +verwenden. Melde Fehler und fehlende Funktionen unter [ihrem +Repository](https://github.com/FliegendeWurst/TriliumDroid). Hinweis: Bei +Verwendung von TriliumDroid solltest du die automatischen Updates auf deinem +Server deaktivieren (siehe unten), da die Synchronisierungsversion zwischen +Trilium und TriliumDroid übereinstimmen muss. + +### Server + +Um TriliumNext auf deinen eigenen Server zu installieren (einschließlich über +Docker von [Dockerhub](https://hub.docker.com/r/triliumnext/trilium)), befolge +[die +Server-Installationsanweisungen](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Mitwirken + +### Übersetzungen + +Wenn du Trilium in einer weiteren Sprache unterstützen mƶchtest, kannst du über +unsere [Weblate-Seite](https://hosted.weblate.org/engage/trilium/) an den +Übersetzungen mitwirken. + +Hier ist die bisherige Sprachabdeckung: + +[![Status der +Übersetzung](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Lade das Repository herunter, die AbhƤngigkeiten mit `pnpm` installieren und +anschließend den Server starten (verfügbar unter http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Dokumentation + +Das Repository herunterladen, die AbhƤngigkeiten mit `pnpm` installieren und +anschließend die Umgebung starten, die zum Bearbeiten der Dokumentation benƶtigt +wird: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Erstellung der ausführbaren Datei +Das Repository herunterladen, die AbhƤngigkeiten mit `pnpm` installieren und +anschließend die Desktop-Anwendung für Windows erstellen: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Weitere Informationen finden sich in der +[Entwicklerdokumentation](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Entwicklerdokumentation + +Die +[Dokumentationsanleitung](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +enthƤlt weitere Details. Bei offenen Fragen kann über die im Abschnitt +ā€žDiskussion mit unsā€œ genannten KommunikationskanƤle Kontakt aufgenommen werden. + +## šŸ‘ Dankeschƶn + +* [zadam](https://github.com/zadam) für das ursprüngliche Konzept und die + Implementierung der Anwendung. +* [Sarah Hussein](https://github.com/Sarah-Hussein) für die Gestaltung des + Anwendungssymbols. +* [nriver](https://github.com/nriver) für seine Arbeit zur + Internationalisierung. +* [Thomas Frei](https://github.com/thfrei) für seine originelle Arbeit an + Canvas. +* [antoniotejada](https://github.com/nriver) für das ursprüngliche + Syntaxhervorhebungs-Widget. +* [Dosu](https://dosu.dev/) für die Bereitstellung automatisierter Antworten auf + GitHub-Issues und Diskussionen. +* [Tabler-Icons](https://tabler.io/icons) für die Symbole in der Taskleiste. + +Trilium wƤre ohne die zugrundeliegenden Technologien nicht mƶglich: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) – der visuelle Editor + hinter Textnotizen. Wir sind dankbar dafür, dass uns eine Reihe von + Premium-Funktionen zur Verfügung gestellt werden. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - Code-Editor mit + Unterstützung für eine Vielzahl von Sprachen. +* [Excalidraw](https://github.com/excalidraw/excalidraw) – das unendliche + Whiteboard, verwendet in Leinwand-Notizen. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) – bietet die + Mindmap-FunktionalitƤt. +* [Leaflet](https://github.com/Leaflet/Leaflet) – für die Darstellung + geografischen Karten. +* [Tabulator](https://github.com/olifolkerd/tabulator) - für die interaktive + Tabelle in Kollektionen. +* [FancyTree](https://github.com/mar10/fancytree) – funktionsreiche + Baum-Bibliothek ohne echte Konkurrenz. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visuelle + Verbindungsbibliothek. Verwendet in + [Beziehungskarten](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + und + [Verbindungskarten](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Unterstützung + +Trilium wurde mit [Hunderten von +Arbeitsstunden](https://github.com/TriliumNext/Trilium/graphs/commit-activity) +entwickelt und wird auch so weitergeführt. Deine Unterstützung sorgt dafür, dass +es Open Source bleibt, verbessert die Funktionen und deckt Kosten wie das +Hosting. + +Bitte unterstütze den Hauptentwickler +([eliandoran](https://github.com/eliandoran)) der Anwendung über: + +- [GitHub Unterstützer](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Kauf mir einen Kaffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ Lizenz + +Copyright 2017-2025 zadam, Elian Doran, und andere Unterstützer + +Dieses Programm ist freie Software: Sie kƶnnen es unter den Bedingungen der GNU +Affero General Public License, wie von der Free Software Foundation +verƶffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 3 der +Lizenz oder (nach Ihrer Wahl) jeder spƤteren Version. diff --git a/docs/README-el.md b/docs/README-el.md new file mode 100644 index 0000000000..f031c0d960 --- /dev/null +++ b/docs/README-el.md @@ -0,0 +1,356 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Το Trilium Notes είναι μια Γωρεάν και Ī±Ī½ĪæĪ¹Ļ‡Ļ„ĪæĻ ĪŗĻŽĪ“Ī¹ĪŗĪ±, ιεραρχική εφαρμογή +ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½ Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»ĻŽĪ½ Ļ€Ī»Ī±Ļ„Ļ†ĪæĻĪ¼ĻŽĪ½ με Ī­Ī¼Ļ†Ī±ĻƒĪ· ĻƒĻ„Ī· Γημιουργία μεγάλων Ļ€ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĻŽĪ½ +Ī²Ī¬ĻƒĪµĻ‰Ī½ Ī³Ī½ĻŽĻƒĪµĻ‰Ī½. + +Trilium Screenshot + +## ā¬ Ī›Ī®ĻˆĪ· +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) - + ĻƒĻ„Ī±ĪøĪµĻĪ® έκΓοση, ĻƒĻ…Ī½Ī¹ĻƒĻ„Ī¬Ļ„Ī±Ī¹ για τους Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪæĻ…Ļ‚ Ļ‡ĻĪ®ĻƒĻ„ĪµĻ‚. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + Ī±ĻƒĻ„Ī±ĪøĪ®Ļ‚ έκΓοση ανάπτυξης, ĪµĪ½Ī·Ī¼ĪµĻĻŽĪ½ĪµĻ„Ī±Ī¹ καθημερινά με τις τελευταίες + Ī“Ļ…Ī½Ī±Ļ„ĻŒĻ„Ī·Ļ„ĪµĻ‚ και Ī“Ī¹ĪæĻĪøĻŽĻƒĪµĪ¹Ļ‚. + +## šŸ“š Ī¤ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ· + +**Ī•Ļ€Ī¹ĻƒĪŗĪµĻ†ĪøĪµĪÆĻ„Īµ την ολοκληρωμένη Ļ„ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ® μας ĻƒĻ„Ī· Ī“Ī¹ĪµĻĪøĻ…Ī½ĻƒĪ· +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Ī— Ļ„ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ· μας είναι Γιαθέσιμη σε πολλαπλές μορφές: +- **Online Documentation **: Περιηγηθείτε ĻƒĻ„Ī·Ī½ πλήρη Ļ„ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ· + [docs.triliumnotes.org] +- ** In-App Help **: Ī Ī±Ļ„Ī®ĻƒĻ„Īµ `F1 ` ĪµĪ½Ļ„ĻŒĻ‚ Trilium για την Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ· ĻƒĻ„Ī·Ī½ ίΓια + Ļ„ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ· απευθείας ĻƒĻ„Ī·Ī½ εφαρμογή +- **GitHub**: Περιηγηθείτε ĻƒĻ„ĪæĪ½ [ΟΓηγό Ļ‡ĻĪ®ĻƒĪ·Ļ‚](./User%20Guide/User%20Guide/) σε + Ī±Ļ…Ļ„ĻŒ το αποθετήριο + +### Γρήγοροι Ī£ĻĪ½Ī“ĪµĻƒĪ¼ĪæĪ¹ +- [ĪŸĪ“Ī·Ī³ĻŒĻ‚ για να Ī¾ĪµĪŗĪ¹Ī½Ī®ĻƒĪµĻ„Īµ](https://docs.triliumnotes.org/) +- [ĪŸĪ“Ī·Ī³ĪÆĪµĻ‚ Ī•Ī³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·Ļ‚](https://docs.triliumnotes.org/user-guide/setup) +- [Ī”ĻĪøĪ¼Ī¹ĻƒĪ· + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Ī‘Ī½Ī±Ī²Ī¬ĪøĪ¼Ī¹ĻƒĪ· + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Ī’Ī±ĻƒĪ¹ĪŗĪ­Ļ‚ έννοιες και + Ī§Ī±ĻĪ±ĪŗĻ„Ī·ĻĪ¹ĻƒĻ„Ī¹ĪŗĪ¬](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [ĪœĪæĻ„ĪÆĪ²Ī± Ī ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĪ®Ļ‚ Ī’Ī¬ĻƒĪ·Ļ‚ + Ī“Ī½ĻŽĻƒĪµĻ‰Ī½](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Ī§Ī±ĻĪ±ĪŗĻ„Ī·ĻĪ¹ĻƒĻ„Ī¹ĪŗĪ¬ + +* Οι ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ Ī¼Ļ€ĪæĻĪæĻĪ½ να ĪŗĪ±Ī½ĪæĪ½Ī¹ĻƒĻ„ĪæĻĪ½ σε αυθαίρετα Ī²Ī±ĪøĻ Γέντρο. Μία ĻƒĪ·Ī¼ĪµĪÆĻ‰ĻƒĪ· + μπορεί να τοποθετηθεί σε πολλαπλά μέρη του Γέντρου (βλέπε + [αντιγραφή](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Ī Ī»ĪæĻĻƒĪ¹ĪæĻ‚ ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĻ„Ī®Ļ‚ ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½ WYSIWYG που περιλαμβάνει Ļ€.χ. πίνακες, + ĪµĪ¹ĪŗĻŒĪ½ĪµĻ‚ και + [μαθηματικά](https://docs.triliumnotes.org/user-guide/note-types/text) με + σήμανση [Ī±Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· + Ī¼ĪæĻĻ†ĪæĻ€ĪæĪÆĪ·ĻƒĪ·](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Ī„Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· για ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĪÆĪ± [ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ με πηγαίο + ĪŗĻŽĪ“Ī¹ĪŗĪ±](https://docs.triliumnotes.org/user-guide/note-types/code), + ĻƒĻ…Ī¼Ļ€ĪµĻĪ¹Ī»Ī±Ī¼Ī²Ī±Ī½ĪæĪ¼Ī­Ī½Ī·Ļ‚ της ĪµĻ€Ī¹ĻƒĪ®Ī¼Ī±Ī½ĻƒĪ·Ļ‚ ĻƒĻĪ½Ļ„Ī±Ī¾Ī·Ļ‚ +* Γρήγορη και ĪµĻĪŗĪæĪ»Ī· [Ļ€Ī»ĪæĪ®Ī³Ī·ĻƒĪ· Ī¼ĪµĻ„Ī±Ī¾Ļ + ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + Ī±Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· πλήρους κειμένου και [Ī±Ī½ĻĻˆĻ‰ĻƒĪ· + ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Ī‘Ļ€ĻĻŒĻƒĪŗĪæĻ€Ļ„Ī· [έκΓοση + ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Ī£Ī·Ī¼ĪµĪÆĻ‰ĻƒĪ· + [Ļ‡Ī±ĻĪ±ĪŗĻ„Ī·ĻĪ¹ĻƒĻ„Ī¹ĪŗĪ¬](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + μπορεί να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī·ĪøĪæĻĪ½ για ĪæĻĪ³Ī¬Ī½Ļ‰ĻƒĪ· ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½, ερωτήματα και advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* Ī— UI είναι Γιαθέσιμη ĻƒĻ„Ī± Αγγλικά, Γερμανικά, Ī™ĻƒĻ€Ī±Ī½Ī¹ĪŗĪ¬, Γαλλικά, Δουμανικά και + Κινεζικά (απλοποιημένα και Ļ€Ī±ĻĪ±Ī“ĪæĻƒĪ¹Ī±ĪŗĪ¬) +* Ī†Ī¼ĪµĻƒĪ· [ĪµĪ½ĻƒĻ‰Ī¼Ī¬Ļ„Ļ‰ĻƒĪ· OpenID και + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) για πιο + Ī±ĻƒĻ†Ī±Ī»Ī® ĻƒĻĪ½Ī“ĪµĻƒĪ· +* [Ī£Ļ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĻŒĻ‚](https://docs.triliumnotes.org/user-guide/setup/synchronization) + με self-hosted Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® ĻƒĻ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĪæĻ + * ΄πάρχουν [Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪµĻ‚ τρίτων για φιλοξενία Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® + ĻƒĻ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĪæĻ](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Κοινή Ļ‡ĻĪ®ĻƒĪ·](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (Ī“Ī·Ī¼ĪæĻƒĪÆĪµĻ…ĻƒĪ·) ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½ ĻƒĻ„Īæ Γημόσιο ΓιαΓίκτυο +* Ī™ĻƒĻ‡Ļ…ĻĪ® [ĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ· + ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + με Ļ…Ļ€ĪæĪ“Ī¹Ī±ĪÆĻĪµĻƒĪ· ανά ĻƒĪ·Ī¼ĪµĪÆĻ‰ĻƒĪ· +* Ī£Ļ‡ĪµĪ“ĪÆĪ±ĻƒĪ· Γιαγραμμάτων, με βάση το [Excalidraw](https://excalidraw.com/) (Ļ„ĻĻ€ĪæĻ‚ + ĻƒĪ·Ī¼ĪµĪÆĻ‰ĻƒĪ·Ļ‚ "καμβάς") +* [Χάρτες + ĻƒĻ…ĻƒĻ‡ĪµĻ„ĪÆĻƒĪµĻ‰Ī½](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + και [χάρτες + ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½/ĻƒĻ…Ī½Ī“Ī­ĻƒĪ¼Ļ‰Ī½](https://docs.triliumnotes.org/user-guide/note-types/note-map) + για την ĪæĻ€Ļ„Ī¹ĪŗĪæĻ€ĪæĪÆĪ·ĻƒĪ· ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĻ‰Ī½ και των ĻƒĻ…ĻƒĻ‡ĪµĻ„ĪÆĻƒĪµĻŽĪ½ τους +* ĪĪæĪ·Ļ„Ī¹ĪŗĪæĪÆ χάρτες, βασισμένοι ĻƒĻ„Īæ [Mind Elixir](https://docs.mind-elixir.com/) +* [Γεωγραφικοί + χάρτες](https://docs.triliumnotes.org/user-guide/collections/geomap) με + ĪŗĪ±ĻĻ†ĪÆĻ„ĻƒĪµĻ‚ Ļ„ĪæĻ€ĪæĪøĪµĻƒĪÆĪ±Ļ‚ και κομμάτια GPX +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - ανατρέξτε ĻƒĻ„Ī·Ī½ + ĪµĪ½ĻŒĻ„Ī·Ļ„Ī± [Προθήκες για + προχωρημένους](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) για + Ī±Ļ…Ļ„ĪæĪ¼Ī±Ļ„ĪæĻ€ĪæĪÆĪ·ĻƒĪ· +* ĪšĪ»Ī¹Ī¼Ī±ĪŗĻŽĪ½ĪµĻ„Ī±Ī¹ καλά Ļ„ĻŒĻƒĪæ ĻƒĻ„Ī· Ļ‡ĻĪ·ĻƒĻ„Ī¹ĪŗĻŒĻ„Ī·Ļ„Ī± όσο και ĻƒĻ„Ī·Ī½ Ī±Ļ€ĻŒĪ“ĪæĻƒĪ· πάνω Ī±Ļ€ĻŒ 100.000 + ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ +* Ī’ĪµĪ»Ļ„Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ī¼Ī­Ī½Ī· αφή [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) για + smartphones και tablets +* Ī•Ī½ĻƒĻ‰Ī¼Ī±Ļ„Ļ‰Ī¼Ī­Ī½Īæ [ĻƒĪŗĪæĻĻĪæ + θέμα](https://docs.triliumnotes.org/user-guide/concepts/themes), Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· + για θέματα Ļ‡ĻĪ®ĻƒĻ„Ī· +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown ĪµĪ¹ĻƒĪ±Ī³Ļ‰Ī³Ī® & + εξαγωγή](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) για + ĪµĻĪŗĪæĪ»Ī· Ī±Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ· περιεχομένου Ī¹ĻƒĻ„ĪæĻ +* Προσαρμόσιμο UI (κουμπιά Ļ€Ī»Ī±ĻŠĪ½Ī®Ļ‚ γραμμής, γραφικά ĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĪ± που ορίζονται Ī±Ļ€ĻŒ + το Ļ‡ĻĪ®ĻƒĻ„Ī·,...) +* [ĪœĪµĻ„ĻĪ¹ĪŗĪ­Ļ‚](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + μαζί με ένα Grafana Dashboard. + +✨ Δίξτε μια ματιά ĻƒĻ„ĪæĻ…Ļ‚ Ī±ĪŗĻŒĪ»ĪæĻ…ĪøĪæĻ…Ļ‚ Ļ€ĻŒĻĪæĻ…Ļ‚/ĪŗĪæĪ¹Ī½ĻŒĻ„Ī·Ļ„ĪµĻ‚ τρίτων για Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪµĻ‚ +Ī“Ļ…Ī½Ī±Ļ„ĻŒĻ„Ī·Ļ„ĪµĻ‚ που ĻƒĻ‡ĪµĻ„ĪÆĪ¶ĪæĪ½Ļ„Ī±Ī¹ με το TriliumNext: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) για θέματα + τρίτων, scripts, ĪµĻ€ĪµĪŗĻ„Ī¬ĻƒĪµĪ¹Ļ‚ και άλλα. +- [TriliumRocks!](https://trilium.rocks/) για σεμινάρια, ĪæĪ“Ī·Ī³ĪæĻĻ‚ και πολλά άλλα. + +## ā“Ī“Ī¹Ī±Ļ„ĪÆ TriliumNext; + +Ο Ī±ĻĻ‡Ī¹ĪŗĻŒĻ‚ Ļ€ĻĪæĪ³ĻĪ±Ī¼Ī¼Ī±Ļ„Ī¹ĻƒĻ„Ī®Ļ‚ του Trilium ([Zadam](https://github.com/zadam)) Ī­Ī“Ļ‰ĻƒĪµ +ευγενικά το αποθετήριο Trilium ĻƒĻ„Ī·Ī½ ĪŗĪæĪ¹Ī½ĻŒĻ„Ī·Ļ„Ī± που Ī²ĻĪÆĻƒĪŗĪµĻ„Ī±Ī¹ ĻƒĻ„Īæ +https://github.com/TriliumNext + +### ā¬†ļøĪœĪµĻ„ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· Ī±Ļ€ĻŒ Zadam/Trilium; + +Δεν υπάρχουν ειΓικά βήματα για τη Ī¼ĪµĻ„ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· Ī±Ļ€ĻŒ μια έκΓοση zadam/Trilium σε +μια έκΓοση TriliumNext/Trilium. Ī‘Ļ€Ī»ĻŽĻ‚ [ĪµĪ³ĪŗĪ±Ļ„Ī±ĻƒĻ„Ī®ĻƒĻ„Īµ το +TriliumNext/Trilium](#-installation) ως ĻƒĻ…Ī½Ī®ĪøĻ‰Ļ‚ και θα Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĪ¹ την +Ļ…Ļ€Ī¬ĻĻ‡ĪæĻ…ĻƒĪ± βάση ΓεΓομένων ĻƒĪ±Ļ‚. + +Οι ĪµĪŗĪ“ĻŒĻƒĪµĪ¹Ļ‚ έως και την +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) είναι +ĻƒĻ…Ī¼Ī²Ī±Ļ„Ī­Ļ‚ με την πιο Ļ€ĻĻŒĻƒĻ†Ī±Ļ„Ī· έκΓοση zadam/trilium της +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). ĪŸĻ€ĪæĪ¹ĪµĻƒĪ“Ī®Ļ€ĪæĻ„Īµ +Ī½ĪµĻŒĻ„ĪµĻĪµĻ‚ ĪµĪŗĪ“ĻŒĻƒĪµĪ¹Ļ‚ του TriliumNext/Trilium έχουν αυξημένες ĪµĪŗĪ“ĻŒĻƒĪµĪ¹Ļ‚ ĻƒĻ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĪæĻ, +Ī³ĪµĪ³ĪæĪ½ĻŒĻ‚ που αποτρέπει την άμεση Ī¼ĪµĻ„ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·. + +## šŸ’¬ Ī£Ļ…Ī¶Ī·Ļ„Ī®ĻƒĻ„Īµ μαζί μας + +Μη Ī“Ī¹ĻƒĻ„Ī¬ĻƒĪµĻ„Īµ να ĻƒĻ…Ī¼Ī¼ĪµĻ„Ī¬ĻƒĻ‡ĪµĻ„Īµ ĻƒĻ„Ī¹Ļ‚ ĪµĻ€ĪÆĻƒĪ·Ī¼ĪµĻ‚ ĻƒĻ…Ī½ĪæĪ¼Ī¹Ī»ĪÆĪµĻ‚ μας. Θα θέλαμε να +Ī±ĪŗĪæĻĻƒĪæĻ…Ī¼Īµ ποιες Ī“Ļ…Ī½Ī±Ļ„ĻŒĻ„Ī·Ļ„ĪµĻ‚, Ļ€ĻĪæĻ„Ī¬ĻƒĪµĪ¹Ļ‚ Ī® προβλήματα μπορεί να έχετε! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Για ĻƒĻĪ³Ļ‡ĻĪæĪ½ĪµĻ‚ + ĻƒĻ…Ī¶Ī·Ļ„Ī®ĻƒĪµĪ¹Ļ‚.) + - Το Γωμάτιο `General` Matrix είναι ĪµĻ€ĪÆĻƒĪ·Ļ‚ γεφυρωμένο με το + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Ī£Ļ…Ī¶Ī·Ļ„Ī®ĻƒĪµĪ¹Ļ‚](https://github.com/TriliumNext/Trilium/discussions) (Για + Ī±ĻƒĻĪ³Ļ‡ĻĪæĪ½ĪµĻ‚ ĻƒĻ…Ī¶Ī·Ļ„Ī®ĻƒĪµĪ¹Ļ‚.) +- [Github Ζητήματα](https://github.com/TriliumNext/Trilium/issues) (Για αναφορές + ĻƒĻ†Ī±Ī»Ī¼Ī¬Ļ„Ļ‰Ī½ και αιτήματα Ī»ĪµĪ¹Ļ„ĪæĻ…ĻĪ³Ī¹ĻŽĪ½.) + +## šŸ— Ī•Ī³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· + +### Windows / MacOS + +ĪšĪ±Ļ„ĪµĪ²Ī¬ĻƒĻ„Īµ τη ΓυαΓική έκΓοση για την Ļ€Ī»Ī±Ļ„Ļ†ĻŒĻĪ¼Ī± ĻƒĪ±Ļ‚ Ī±Ļ€ĻŒ την [τελευταία σελίΓα +Ī­ĪŗĪ“ĪæĻƒĪ·Ļ‚](https://github.com/TriliumNext/Trilium/releases/latest), Ī±Ļ€ĪæĻƒĻ…Ī¼Ļ€Ī¹Ī­ĻƒĻ„Īµ +το πακέτο και ĪµĪŗĻ„ĪµĪ»Ī­ĻƒĻ„Īµ το ĪµĪŗĻ„ĪµĪ»Ī­ĻƒĪ¹Ī¼Īæ αρχείο `trilium`. + +### Linux + +Εάν Ī· Γιανομή ĻƒĪ±Ļ‚ περιλαμβάνεται ĻƒĻ„ĪæĪ½ παρακάτω πίνακα, Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĻ„Īµ το πακέτο +της Γιανομής ĻƒĪ±Ļ‚. + +[![ĪšĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· του +πακέτου](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +ĪœĻ€ĪæĻĪµĪÆĻ„Īµ ĪµĻ€ĪÆĻƒĪ·Ļ‚ να ĪŗĪ±Ļ„ĪµĪ²Ī¬ĻƒĪµĻ„Īµ τη ΓυαΓική έκΓοση για την Ļ€Ī»Ī±Ļ„Ļ†ĻŒĻĪ¼Ī± ĻƒĪ±Ļ‚ Ī±Ļ€ĻŒ την +[τελευταία σελίΓα +Ī­ĪŗĪ“ĪæĻƒĪ·Ļ‚](https://github.com/TriliumNext/Trilium/releases/latest), Ī±Ļ€ĪæĻƒĻ…Ī¼Ļ€Ī¹Ī­ĻƒĻ„Īµ +το πακέτο και ĪµĪŗĻ„ĪµĪ»Ī­ĻƒĻ„Īµ το ĪµĪŗĻ„ĪµĪ»Ī­ĻƒĪ¹Ī¼Īæ αρχείο `trilium`. + +Το TriliumNext παρέχεται ĪµĻ€ĪÆĻƒĪ·Ļ‚ ως Flatpak, αλλά Γεν έχει ακόμη Ī“Ī·Ī¼ĪæĻƒĪ¹ĪµĻ…ĪøĪµĪÆ ĻƒĻ„Īæ +FlatHub. + +### Πρόγραμμα Ļ€ĪµĻĪ¹Ī®Ī³Ī·ĻƒĪ·Ļ‚ (οποιοΓήποτε Ī»ĪµĪ¹Ļ„ĪæĻ…ĻĪ³Ī¹ĪŗĻŒ ĻƒĻĻƒĻ„Ī·Ī¼Ī±) + +Εάν Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Īµ ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® (βλέπε παρακάτω), μπορείτε να έχετε +απευθείας Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ· ĻƒĻ„Īæ web interface (που είναι ĻƒĻ‡ĪµĪ“ĻŒĪ½ Ļ€Ī±Ī½ĪæĪ¼ĪæĪ¹ĻŒĻ„Ļ…Ļ€Ī· με την +εφαρμογή desktop). + +Επί του Ļ€Ī±ĻĻŒĪ½Ļ„ĪæĻ‚ Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¶ĪæĪ½Ļ„Ī±Ī¹ μόνο οι τελευταίες ĪµĪŗĪ“ĻŒĻƒĪµĪ¹Ļ‚ του Chrome & Firefox +(και ελέγχονται). + +### ĪšĪ¹Ī½Ī·Ļ„ĻŒ + +Για να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĻ„Īµ το TriliumNext σε ένα ĪŗĪ¹Ī½Ī·Ļ„ĻŒ, μπορείτε να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĻ„Īµ +ένα Ļ€ĻĻŒĪ³ĻĪ±Ī¼Ī¼Ī± Ļ€ĪµĻĪ¹Ī®Ī³Ī·ĻƒĪ·Ļ‚ του ĪŗĪ¹Ī½Ī·Ļ„ĪæĻ για να έχετε Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ· ĻƒĻ„Īæ interface μιας +ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·Ļ‚ Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® (βλέπε παρακάτω). + +Ανατρέξτε ĻƒĻ„Īæ https://github.com/TriliumNext/Trilium/issues/4962 για +Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪµĻ‚ πληροφορίες ĻƒĻ‡ĪµĻ„Ī¹ĪŗĪ¬ με την Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· για κινητά. + +Εάν προτιμάτε μια εγγενή εφαρμογή Android, μπορείτε να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĻ„Īµ το +[TriliumDroid]. Αναφέρετε ĻƒĻ†Ī¬Ī»Ī¼Ī±Ļ„Ī± και Ļ‡Ī±ĻĪ±ĪŗĻ„Ī·ĻĪ¹ĻƒĻ„Ī¹ĪŗĪ¬ που λείπουν ĻƒĻ„Īæ +[αποθετήριο τους](https://github.com/FliegendeWurst/TriliumDroid). Ī£Ī·Ī¼ĪµĪÆĻ‰ĻƒĪ·: +Είναι ĪŗĪ±Ī»ĻĻ„ĪµĻĪæ να Ī±Ļ€ĪµĪ½ĪµĻĪ³ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĻ„Īµ τις Ī±Ļ…Ļ„ĻŒĪ¼Ī±Ļ„ĪµĻ‚ ĪµĪ½Ī·Ī¼ĪµĻĻŽĻƒĪµĪ¹Ļ‚ ĻƒĻ„Ī·Ī½ ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· +ĻƒĻ„Īæ Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® ĻƒĪ±Ļ‚ (βλέπε παρακάτω) ĻŒĻ„Ī±Ī½ Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Īµ TriliumDroid, ΓεΓομένου +ĻŒĻ„Ī¹ Ī· έκΓοση ĻƒĻ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĪæĻ πρέπει να ταιριάζει Ī¼ĪµĻ„Ī±Ī¾Ļ Trilium και TriliumDroid. + +### Ī”Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī®Ļ‚ + +Για να ĪµĪ³ĪŗĪ±Ļ„Ī±ĻƒĻ„Ī®ĻƒĪµĻ„Īµ το TriliumNext ĻƒĻ„Īæ Γικό ĻƒĪ±Ļ‚ Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® (ĻƒĻ…Ī¼Ļ€ĪµĻĪ¹Ī»Ī±Ī¼Ī²Ī±Ī½ĪæĪ¼Ī­Ī½ĪæĻ… +Ī¼Ī­ĻƒĻ‰ Docker Ī±Ļ€ĻŒ το [Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) +Ī±ĪŗĪæĪ»ĪæĻ…ĪøĪ®ĻƒĻ„Īµ [τις οΓηγίες ĪµĪ³ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·Ļ‚ +Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī®](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Ī£Ļ…Ī½ĪµĪ¹ĻƒĻ†Ī­ĻĪµĻ„Īµ + +### ĪœĪµĻ„Ī±Ļ†ĻĪ¬ĻƒĪµĪ¹Ļ‚ + +Αν ĪµĪÆĻƒĻ„Īµ γηγενής ομιλητής, Ī²ĪæĪ·ĪøĪ®ĻƒĻ„Īµ μας να Ī¼ĪµĻ„Ī±Ļ†ĻĪ¬ĻƒĪæĻ…Ī¼Īµ το Trilium +ĪŗĪ±Ļ„ĪµĻ…ĪøĻ…Ī½ĻŒĪ¼ĪµĪ½ĪæĪ¹ προς την [σελίΓα +Weblate](https://hosted.weblate.org/engage/trilium/). + +Ī•Ī“ĻŽ είναι Ī· ĪŗĪ¬Ī»Ļ…ĻˆĪ· των Ī³Ī»Ļ‰ĻƒĻƒĻŽĪ½ που έχουμε μέχρι ĻƒĻ„Ī¹Ī³Ī¼Ī®Ļ‚: + +[Ī— ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· των +Ī¼ĪµĻ„Ī±Ļ†ĻĪ¬ĻƒĪµĻ‰Ī½](https://hosted.weblate.org/widget/trilium/multi-auto.svg) + +### ĪšĻŽĪ“Ī¹ĪŗĪ±Ļ‚ + +ĪšĪ±Ļ„ĪµĪ²Ī¬ĻƒĻ„Īµ το αποθετήριο, ĪµĪ³ĪŗĪ±Ļ„Ī±ĻƒĻ„Ī®ĻƒĻ„Īµ τα απαραίτητα αρχεία Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ το +`pnpm` και ĻƒĻ„Ī· ĻƒĻ…Ī½Ī­Ļ‡ĪµĪ¹Ī± ĪµĪŗĻ„ĪµĪ»Ī­ĻƒĻ„Īµ τον Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® (είναι Ī“Ī¹Ī±ĪøĪ­ĻƒĪ¹Ī¼ĪæĻ‚ ĻƒĻ„Īæ +http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Ī¤ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ· + +ĪšĪ±Ļ„ĪµĪ²Ī¬ĻƒĻ„Īµ το αποθετήριο, ĪµĪ³ĪŗĪ±Ļ„Ī±ĻƒĻ„Ī®ĻƒĻ„Īµ τα απαραίτητα αρχεία Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ το +`pnpm` και ĻƒĻ„Ī· ĻƒĻ…Ī½Ī­Ļ‡ĪµĪ¹Ī± ĪµĪŗĻ„ĪµĪ»Ī­ĻƒĻ„Īµ το περιβάλλον που απαιτείται για την +ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĪÆĪ± της Ļ„ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ·Ļ‚: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Δημιουργία του ĪµĪŗĻ„ĪµĪ»Ī­ĻƒĪ¹Ī¼ĪæĻ… αρχείου +ĪšĪ±Ļ„ĪµĪ²Ī¬ĻƒĻ„Īµ το αποθετήριο, ĪµĪ³ĪŗĪ±Ļ„Ī±ĻƒĻ„Ī®ĻƒĪµĻ„Īµ τα απαραίτητα αρχεία Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ +`pnpm ` και ĻƒĻ„Ī· ĻƒĻ…Ī½Ī­Ļ‡ĪµĪ¹Ī± Ī“Ī·Ī¼Ī¹ĪæĻ…ĻĪ³Ī®ĻƒĻ„Īµ την εφαρμογή desktop για Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Για Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪµĻ‚ λεπτομέρειες, ανατρέξτε ĻƒĻ„Ī± [έγγραφα +development](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer αρχεία + +Δείτε τον [οΓηγό +Ļ„ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ·Ļ‚](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +για λεπτομέρειες. Εάν έχετε Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪµĻ‚ ĪµĻĻ‰Ļ„Ī®ĻƒĪµĪ¹Ļ‚, μη Ī“Ī¹ĻƒĻ„Ī¬ĻƒĪµĻ„Īµ να +ĪµĻ€Ī¹ĪŗĪæĪ¹Ī½Ļ‰Ī½Ī®ĻƒĪµĻ„Īµ Ī¼Ī­ĻƒĻ‰ των ĻƒĻ…Ī½Ī“Ī­ĻƒĪ¼Ļ‰Ī½ που περιγράφονται ĻƒĻ„Ī·Ī½ ĪµĪ½ĻŒĻ„Ī·Ļ„Ī± Ā«Ī£Ļ…Ī¶Ī·Ļ„Ī®ĻƒĻ„Īµ μαζί +μας» παραπάνω. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) για την αρχική ιΓέα και Ļ…Ī»ĪæĻ€ĪæĪÆĪ·ĻƒĪ· της + εφαρμογής. +* [Sarah Hussein](https://github.com/Sarah-Hussein) για τη ĻƒĻ‡ĪµĪ“ĪÆĪ±ĻƒĪ· του + εικονιΓίου της εφαρμογής. +* [nriver](https://github.com/nriver) για το έργο του ĻƒĻ‡ĪµĻ„Ī¹ĪŗĪ¬ με τη + Ī“Ī¹ĪµĪøĪ½ĪæĻ€ĪæĪÆĪ·ĻƒĪ·. +* [Thomas Frei](https://github.com/thfrei) για το Ī±ĻĻ‡Ī¹ĪŗĻŒ έργο του ĻƒĻ„ĪæĪ½ Καμβά. +* [antoniotejada](https://github.com/nriver) για το Ī±ĻĻ‡Ī¹ĪŗĻŒ widget ĪµĻ€Ī¹ĻƒĪ®Ī¼Ī±Ī½ĻƒĪ·Ļ‚ + ĻƒĻĪ½Ļ„Ī±Ī¾Ī·Ļ‚. +* [Dosu](https://dosu.dev/) που μας παρέχει τις αυτοματοποιημένες Ī±Ļ€Ī±Ī½Ļ„Ī®ĻƒĪµĪ¹Ļ‚ σε + θέματα και ĻƒĻ…Ī¶Ī·Ļ„Ī®ĻƒĪµĪ¹Ļ‚ του GitHub. +* [Tabler Icons](https://tabler.io/icons) για τα εικονίΓια ĻƒĻ…ĻƒĻ„Ī®Ī¼Ī±Ļ„ĪæĻ‚. + +Το Trilium Γεν θα ήταν ĪµĻ†Ī¹ĪŗĻ„ĻŒ χωρίς τις τεχνολογίες Ļ€ĪÆĻƒĻ‰ Ī±Ļ€ĻŒ Ī±Ļ…Ļ„ĻŒ: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - Īæ ĪæĻ€Ļ„Ī¹ĪŗĻŒĻ‚ ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĻ„Ī®Ļ‚ + Ļ€ĪÆĻƒĻ‰ Ī±Ļ€ĻŒ τις ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ κειμένου. Ī•ĪÆĪ¼Ī±ĻƒĻ„Īµ ĪµĻ…Ī³Ī½ĻŽĪ¼ĪæĪ½ĪµĻ‚ που μας Ļ€ĻĪæĻƒĻ†Ī­ĻĪøĪ·ĪŗĪµ ένα + ĻƒĻĪ½ĪæĪ»Īæ Ī±Ļ€ĻŒ τα premium Ļ‡Ī±ĻĪ±ĪŗĻ„Ī·ĻĪ¹ĻƒĻ„Ī¹ĪŗĪ¬. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĻ„Ī®Ļ‚ ĪŗĻŽĪ“Ī¹ĪŗĪ± + με Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· για Ļ„ĪµĻĪ¬ĻƒĻ„Ī¹Īæ αριθμό Ī³Ī»Ļ‰ĻƒĻƒĻŽĪ½. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - Īæ άπειρος πίνακας που + Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Ī±Ī¹ ĻƒĻ„Ī¹Ļ‚ ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ του Καμβά. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - παροχή της + Ī»ĪµĪ¹Ļ„ĪæĻ…ĻĪ³Ī¹ĪŗĻŒĻ„Ī·Ļ„Ī±Ļ‚ του χάρτη Ī¼Ļ…Ī±Ī»ĪæĻ. +* [Leaflet](https://github.com/Leaflet/Leaflet) - για την Ī±Ļ€ĻŒĪ“ĪæĻƒĪ· Ī³ĪµĻ‰Ī³ĻĪ±Ļ†Ī¹ĪŗĻŽĪ½ + Ļ‡Ī±ĻĻ„ĻŽĪ½. +* [Tabulator](https://github.com/olifolkerd/tabulator) - για τον Ī“Ī¹Ī±Ī“ĻĪ±ĻƒĻ„Ī¹ĪŗĻŒ + πίνακα που Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Ī±Ī¹ ĻƒĻ„Ī¹Ļ‚ ĻƒĻ…Ī»Ī»ĪæĪ³Ī­Ļ‚. +* [FancyTree](https://github.com/mar10/fancytree) - Ļ€Ī»ĪæĻĻƒĪ¹Ī± βιβλιοθήκη Γέντρων + χωρίς Ļ€ĻĪ±Ī³Ī¼Ī±Ļ„Ī¹ĪŗĻŒ Ī±Ī½Ļ„Ī±Ī³Ļ‰Ī½Ī¹ĻƒĪ¼ĻŒ. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - βιβλιοθήκη οπτικής ĻƒĻĪ½Ī“ĪµĻƒĪ·Ļ‚. + Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Ī±Ī¹ σε [χάρτες + ĻƒĻ‡Ī­ĻƒĪµĻ‰Ī½](https://docs.triliumnotes.org/user-guide/note-types/relation-map) και + [χάρτες + ĻƒĻ…Ī½Ī“Ī­ĻƒĪ¼Ļ‰Ī½](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Ī„Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· + +Το Trilium Γημιουργείται και ĻƒĻ…Ī½Ļ„Ī·ĻĪµĪÆĻ„Ī±Ī¹ με [εκατοντάΓες ĻŽĻĪµĻ‚ +ĪµĻĪ³Ī±ĻƒĪÆĪ±Ļ‚](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Ī— +Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī® ĻƒĪ±Ļ‚ το Γιατηρεί Ī±Ī½ĪæĪ¹Ļ‡Ļ„ĪæĻ ĪŗĻŽĪ“Ī¹ĪŗĪ±, Ī²ĪµĪ»Ļ„Ī¹ĻŽĪ½ĪµĪ¹ τις Ī“Ļ…Ī½Ī±Ļ„ĻŒĻ„Ī·Ļ„ĪµĻ‚ και +ĪŗĪ±Ī»ĻĻ€Ļ„ĪµĪ¹ ĪŗĻŒĻƒĻ„Ī· ĻŒĻ€Ļ‰Ļ‚ Ī· φιλοξενία. + +Ī•Ī¾ĪµĻ„Ī¬ĻƒĻ„Īµ το ĪµĪ½Ī“ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ να Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¾ĪµĻ„Īµ τον ĪŗĻĻĪ¹Īæ Ļ€ĻĪæĪ³ĻĪ±Ī¼Ī¼Ī±Ļ„Ī¹ĻƒĻ„Ī® +([eliandoran](https://github.com/eliandoran)) της εφαρμογής Ī¼Ī­ĻƒĻ‰: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee] + +## šŸ”‘ ΆΓεια + +Copyright 2017-2025 zadam, Elian Doran και άλλοι ĻƒĻ…Ī½ĪµĪ¹ĻƒĻ†Ī­ĻĪæĪ½Ļ„ĪµĻ‚ + +Ī‘Ļ…Ļ„ĻŒ το Ļ€ĻĻŒĪ³ĻĪ±Ī¼Ī¼Ī± είναι Γωρεάν λογισμικό: μπορείτε να το αναΓιανέμετε Ī®/και να +το Ļ„ĻĪæĻ€ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĻ„Īµ Ļ…Ļ€ĻŒ τους ĻŒĻĪæĻ…Ļ‚ της GNU Affero Γενική ΆΓεια Ī”Ī·Ī¼ĻŒĻƒĪ¹Ī±Ļ‚ Ī§ĻĪ®ĻƒĪ·Ļ‚, +ĻŒĻ€Ļ‰Ļ‚ Ī“Ī·Ī¼ĪæĻƒĪ¹ĪµĻĪµĻ„Ī±Ī¹ Ī±Ļ€ĻŒ το ĪŠĪ“ĻĻ…Ī¼Ī± Ī•Ī»ĪµĻĪøĪµĻĪæĻ… Ī›ĪæĪ³Ī¹ĻƒĪ¼Ī¹ĪŗĪæĻ, είτε έκΓοση 3 της άΓειας, +είτε (κατ' επιλογή ĻƒĪ±Ļ‚) οποιαΓήποτε Ī¼ĪµĻ„Ī±Ī³ĪµĪ½Ī­ĻƒĻ„ĪµĻĪ· έκΓοση. diff --git a/docs/README-en_GB.md b/docs/README-en_GB.md new file mode 100644 index 0000000000..8a7d34c8a3 --- /dev/null +++ b/docs/README-en_GB.md @@ -0,0 +1,337 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking +application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation + directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalisation. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-es.md b/docs/README-es.md new file mode 100644 index 0000000000..48c4146884 --- /dev/null +++ b/docs/README-es.md @@ -0,0 +1,352 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![Patrocinadores en GitHub](https://img.shields.io/github/sponsors/eliandoran) +![Patrocinadores en +LiberaPay](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Descargas en Docker](https://img.shields.io/docker/pulls/triliumnext/trilium) +![Descargas en GitHub (todos los recursos, todas las +versiones)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Estado de la +traducción](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes es una aplicación gratuita, de código abierto y multiplataforma +para notas jerĆ”rquicas, orientada a crear amplias bases de conocimiento +personal. + +Trilium Screenshot + +## ā¬ Descargar +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + versión estable, recomendada para la mayorĆ­a de los usuarios. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly): + versión de desarrollo inestable, actualizada diariamente con las Ćŗltimas + funciones y correcciones. + +## šŸ“š Documentación + +**Accede a la documentación completa en +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +La documentación estĆ” disponible en varios formatos: +- **Documentación en lĆ­nea**: Consulta la documentación completa en + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Ayuda en la aplicación**: Presiona `F1` dentro de Trilium para acceder a la + misma documentación directamente en la aplicación +- **GitHub**: Navega por la [GuĆ­a del Usuario](./User%20Guide/User%20Guide/) en + este repositorio + +### Enlaces rĆ”pidos +- [GuĆ­a de inicio](https://docs.triliumnotes.org/) +- [Instrucciones de instalación](https://docs.triliumnotes.org/user-guide/setup) +- [Configuración de + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Actualización de + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Conceptos bĆ”sicos y + funciones](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patrones para una base de conocimiento + personal](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ CaracterĆ­sticas + +* Las notas se pueden organizar en un Ć”rbol de profundidad arbitraria. Una sola + nota puede colocarse en varios lugares del Ć”rbol (ver + [clonado](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Editor de notas WYSIWYG completo, que incluye, por ejemplo, tablas, imĆ”genes y + [matemĆ”ticas](https://docs.triliumnotes.org/user-guide/note-types/text) con + [autoformato](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) + en Markdown +* Soporte para editar [notas con código + fuente](https://docs.triliumnotes.org/user-guide/note-types/code), incluyendo + resaltado de sintaxis +* [Navegación entre + notas](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation) + rĆ”pida y sencilla, bĆŗsqueda de texto completo y [elevación de + notas](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Flujo continuo de [versionado de + notas](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Los + [atributos](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + de las notas se pueden usar para organización, consultas y + [scripting](https://docs.triliumnotes.org/user-guide/scripts) avanzado +* Interfaz disponible en inglĆ©s, alemĆ”n, espaƱol, francĆ©s, rumano y chino + (simplificado y tradicional) +* Integración directa de [OpenID y + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) para un + inicio de sesión mĆ”s seguro +* [Sincronización](https://docs.triliumnotes.org/user-guide/setup/synchronization) + con servidor de sincronización autohospedado + * existen [servicios de terceros para alojar servidores de + sincronización](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Compartir](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publicar) notas en Internet pĆŗblico +* Fuerte [cifrado de + notas](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + con granularidad por nota +* Esbozo de diagramas, basado en [Excalidraw](https://excalidraw.com/) (tipo de + nota "lienzo") +* [Mapas de + relaciones](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + y [mapas de + notas/enlaces](https://docs.triliumnotes.org/user-guide/note-types/note-map) + para visualizar notas y sus relaciones +* Mapas mentales, basados en [Mind Elixir](https://docs.mind-elixir.com/) +* [Mapas + geogrĆ”ficos](https://docs.triliumnotes.org/user-guide/collections/geomap) con + marcadores de ubicación y rutas GPX +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - ver [Casos de + uso + avanzados](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) para + automatización +* Escala bien tanto en usabilidad como en rendimiento, incluso con mĆ”s de + 100.000 notas +* [Interfaz + móvil](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) + optimizada para pantallas tĆ”ctiles, móviles y tabletas +* [Tema oscuro](https://docs.triliumnotes.org/user-guide/concepts/themes) + integrado, con soporte para temas personalizados +* Importación y exportación de + [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + y + [Markdown](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) para + guardar fĆ”cilmente contenido web +* Interfaz personalizable (botones de la barra lateral, widgets definidos por el + usuario, …) +* [MĆ©tricas](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + junto con un panel de control de Grafana. + +✨ Consulta los siguientes recursos y comunidades de terceros para obtener mĆ”s +contenido relacionado con TriliumNext: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) para acceder a + temas, scripts, complementos y otros recursos de terceros. +- [TriliumRocks!](https://trilium.rocks/) para tutoriales, guĆ­as y mucho mĆ”s. + +## ā“ĀæPor quĆ© TriliumNext? + +El desarrollador original de Trilium ([Zadam](https://github.com/zadam)) ha +cedido amablemente el repositorio de Trilium al proyecto comunitario, disponible +en https://github.com/TriliumNext + +### ā¬†ļø ĀæMigrando desde Zadam/Trilium? + +No se requieren pasos especiales para migrar de una instancia de Zadam/Trilium a +TriliumNext/Trilium. Simplemente [instala TriliumNext/Trilium](#-installation) +como de costumbre, y utilizarĆ” la base de datos existente. + +Las versiones hasta +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4), +inclusive, son compatibles con la Ćŗltima versión de Zadam/Trilium +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Las versiones +posteriores de TriliumNext/Trilium incrementan su versión de sincronización, lo +que impide migrar directamente. + +## šŸ’¬ Únete a la conversación + +SiĆ©ntete libre de unirte a nuestras conversaciones oficiales. Ā”Nos interesa +mucho conocer tus funciones favoritas, sugerencias o posibles incidencias! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Para discusiones + sĆ­ncronas.) + - La sala `General` de Matrix tambiĆ©n estĆ” enlazada con + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Discusiones de GitHub](https://github.com/TriliumNext/Trilium/discussions) + (para discusiones asincrónicas.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (para reportes + de errores y solicitudes de funciones.) + +## šŸ— Instalación + +### Windows / macOS + +Descarga la versión binaria para tu plataforma desde la [pĆ”gina de la Ćŗltima +versión](https://github.com/TriliumNext/Trilium/releases/latest), descomprime el +paquete y ejecuta el archivo `trilium`. + +### Linux + +Si tu distribución aparece en la siguiente tabla, utiliza el paquete +correspondiente a tu distribución. + +[![Estado del +paquete](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +TambiĆ©n puedes descargar la versión binaria para la plataforma correspondiente +desde la [pĆ”gina de la Ćŗltima +versión](https://github.com/TriliumNext/Trilium/releases/latest), descomprimir +el paquete y ejecutar el archivo `trilium`. + +TriliumNext tambiĆ©n estĆ” disponible como paquete Flatpak, aunque aĆŗn no se ha +publicado en FlatHub. + +### Navegador (cualquier sistema operativo) + +Si utilizas una instalación en servidor (ver mĆ”s abajo), puedes acceder +directamente a la interfaz web (que es prĆ”cticamente idĆ©ntica a la aplicación de +escritorio). + +Actualmente, solo se soportan (y han sido probadas) las Ćŗltimas versiones de +Chrome y Firefox. + +### Móvil + +Para usar TriliumNext en un dispositivo móvil, puedes utilizar un navegador web +móvil para acceder a la interfaz móvil de una instalación en servidor (ver mĆ”s +abajo). + +Consulta el issue https://github.com/TriliumNext/Trilium/issues/4962 para mĆ”s +información sobre el soporte de la aplicación móvil. + +Si prefieres una aplicación nativa para Android, puedes usar +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Puedes reportar errores y funciones faltantes en [su +repositorio](https://github.com/FliegendeWurst/TriliumDroid). Nota: al usar +TriliumDroid, es recomendable desactivar las actualizaciones automĆ”ticas en la +instalación del servidor (ver mĆ”s abajo), ya que la versión de sincronización +debe coincidir entre Trilium y TriliumDroid. + +### Servidor + +Para instalar TriliumNext en tu propio servidor (incluido mediante Docker desde +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)), sigue las +[instrucciones de instalación del +servidor](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribuir + +### Traducciones + +Si eres hablante nativo, puedes ayudar a traducir Trilium visitando nuestra +[pĆ”gina de Weblate](https://hosted.weblate.org/engage/trilium/). + +Cobertura de idiomas hasta el momento: + +[![Estado de la +traducción](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Código + +Descarga el repositorio, instala las dependencias usando `pnpm` y luego ejecuta +el servidor (disponible en http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentación + +Descarga el repositorio, instala las dependencias usando `pnpm` y luego ejecuta +el entorno necesario para editar la documentación: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Compilación del ejecutable +Descarga el repositorio, instala las dependencias usando `pnpm` y luego compila +la aplicación de escritorio para Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Para mĆ”s información, consulta la [documentación de +desarrollo](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Documentación para desarrolladores + +Consulta la [guĆ­a de +documentación](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +para mĆ”s información. Si tienes mĆ”s preguntas, siĆ©ntete libre de contactarnos a +travĆ©s de los enlaces de la sección "Únete a la conversación" mĆ”s arriba. + +## šŸ‘ Reconocimientos + +* [Zadam](https://github.com/zadam) por la idea original y la implementación de + la aplicación. +* [Sarah Hussein](https://github.com/Sarah-Hussein) por diseƱar el icono de la + aplicación. +* [nriver](https://github.com/nriver) por su trabajo en la internacionalización. +* [Thomas Frei](https://github.com/thfrei) por su trabajo original en el Canvas. +* [antoniotejada](https://github.com/nriver) por el widget original de resaltado + de sintaxis. +* [Dosu](https://dosu.dev/) por ofrecernos las respuestas automĆ”ticas para los + issues y discusiones de GitHub. +* [Tabler Icons](https://tabler.io/icons) por los iconos de la bandeja del + sistema. + +Trilium no serĆ­a posible sin las tecnologĆ­as que lo sustentan: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - el editor visual detrĆ”s + de las notas de texto. Agradecemos que se nos haya ofrecido un conjunto de + funciones premium. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - editor de código con + soporte para numerosos lenguajes. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - la pizarra infinita + utilizada en las notas tipo Canvas. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - proporciona la + funcionalidad de mapas mentales. +* [Leaflet](https://github.com/Leaflet/Leaflet) - para mostrar mapas + geogrĆ”ficos. +* [Tabulator](https://github.com/olifolkerd/tabulator) - para la tabla + interactiva utilizada en las colecciones. +* [FancyTree](https://github.com/mar10/fancytree) - biblioteca de Ć”rboles con + muchas funcionalidades y sin competencia destacable. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - biblioteca de conectividad + visual. Usada en [mapas de + relaciones](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + y [mapas de + enlaces](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Soporte + +Trilium se desarrolla y mantiene con [cientos de horas de +trabajo](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Tu +apoyo ayuda a mantenerlo de código abierto, mejorar sus funciones y cubrir +gastos como el alojamiento. + +Considera apoyar al desarrollador principal +([eliandoran](https://github.com/eliandoran)) de la aplicación a travĆ©s de: + +- [Patrocinadores de GitHub](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Compra un cafĆ©](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ Licencia + +Copyright 2017-2025 zadam, Elian Doran y otros colaboradores + +Este programa es software libre: puede redistribuirse, modificarse o ambas +acciones bajo los tĆ©rminos de la Licencia PĆŗblica General Affero de GNU, +publicada por la Free Software Foundation, ya sea la versión 3 de la licencia o, +a elección del usuario, cualquier versión posterior. diff --git a/docs/README-fa.md b/docs/README-fa.md new file mode 100644 index 0000000000..377fd486c3 --- /dev/null +++ b/docs/README-fa.md @@ -0,0 +1,327 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking +application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ ŲÆŲ§Ł†Ł„ŁˆŲÆ +- [Ų¢Ų®Ų±ŪŒŁ† انتؓار]{ā€ā€1} – نسخه پایدار، برای بیؓتر کاربران ā€Ž Ł¾ŪŒŲ“Ł†Ł‡Ų§ŲÆ Ł…ŪŒā€ŒŲ“ŁˆŲÆ. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š کتابچه راهنما + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +مستندات Ł…Ų§ ŲÆŲ± Ś†Ł†ŲÆŪŒŁ† قالب مختلف ŲÆŲ± ŲÆŲ³ŲŖŲ±Ų³ Ų§Ų³ŲŖ: +- مستندات Ų¢Ł†Ł„Ų§ŪŒŁ†: Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŪŒŲÆ نسخهٔ کامل مستندات Ų±Ų§ ŲÆŲ± + ā€Ž[docs.triliumnotes.org](https://docs.triliumnotes.org/)ā€Ž Ł…Ų±ŁˆŲ± Ś©Ł†ŪŒŲÆ +- ** In-App Help **: Press `F1 ` ŲÆŲ± Trilium برای دسترسی به همان اسناد به طور + Ł…Ų³ŲŖŁ‚ŪŒŁ… ŲÆŲ± برنامه +- ** GitHub **: Ų§Ų² Ų·Ų±ŪŒŁ‚ [Ų±Ų§Ł‡Ł†Ł…Ų§ŪŒ کاربر] ŲÆŲ± Ų§ŪŒŁ† مخزن حرکت Ś©Ł†ŪŒŲÆ + +### Ł„ŪŒŁ†Ś©ā€ŒŁ‡Ų§ŪŒ سریع +- Ų±Ų§Ł‡Ł†Ł…Ų§ŪŒ ؓروع کار +- ŲÆŲ³ŲŖŁˆŲ±Ų§Ł„Ų¹Ł…Ł„ā€ŒŁ‡Ų§ŪŒ نصب +- Ų±Ų§Ł‡ā€ŒŲ§Ł†ŲÆŲ§Ų²ŪŒ داکر +- Ų§Ų±ŲŖŁ‚Ų§ŪŒ TriliumNext +- Ł…ŁŲ§Ł‡ŪŒŁ… و ŁˆŪŒŚ˜ŚÆŪŒā€ŒŁ‡Ų§ŪŒ Ł¾Ų§ŪŒŁ‡ +- Ų§Ł„ŚÆŁˆŁ‡Ų§ŪŒ Ł¾Ų§ŪŒŚÆŲ§Ł‡ ŲÆŲ§Ł†Ų“ŪŒ ؓخصی + +## šŸŽ ŁˆŪŒŚ˜ŚÆŪŒā€ŒŁ‡Ų§ + +* ŪŒŲ§ŲÆŲÆŲ§Ų“ŲŖā€ŒŁ‡Ų§ Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†Ł†ŲÆ ŲÆŲ± یک ŲÆŲ±Ų®ŲŖ ŲØŲ§ عمق ŲÆŁ„Ų®ŁˆŲ§Ł‡ Ų³Ų§Ų²Ł…Ų§Ł†ā€ŒŲÆŁ‡ŪŒ Ų“ŁˆŁ†ŲÆ. یک یادداؓت + Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŲÆ ŲÆŲ± Ś†Ł†ŲÆŪŒŁ† نقطهٔ مختلف Ų§Ų² ŲÆŲ±Ų®ŲŖ قرار گیرد. +* ویرایؓگر یادداؓت ŲŗŁ†ŪŒ WYSIWYG Ų§Ų² جمله Ų¬ŲÆŲ§ŁˆŁ„ŲŒ تصاویر و [math] [1] ŲØŲ§ علامت گذاری + [autoformat] [2] +* Ł¾Ų“ŲŖŪŒŲØŲ§Ł†ŪŒ Ų§Ų² ویرایؓ [یادداؓت ŲØŲ§ کد منبع][Ū±]، Ų§Ų² جمله Ł†Ų­Łˆ برجسته +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* Ł…Ų­ŪŒŲ· کاربری به Ų²ŲØŲ§Ł†ā€ŒŁ‡Ų§ŪŒ Ų§Ł†ŚÆŪŒŁ„ŪŒŲ³ŪŒŲŒ Ų¢Ł„Ł…Ų§Ł†ŪŒŲŒ Ų§Ų³Ł¾Ų§Ł†ŪŒŲ§ŪŒŪŒŲŒ ŁŲ±Ų§Ł†Ų³ŁˆŪŒŲŒ Ų±ŁˆŁ…Ų§Ł†ŪŒŲ§ŪŒŪŒŲŒ و + Ś†ŪŒŁ†ŪŒ (Ų³Ų§ŲÆŁ‡ā€ŒŲ“ŲÆŁ‡ و Ų³Ł†ŲŖŪŒ) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-fi.md b/docs/README-fi.md new file mode 100644 index 0000000000..0da3a37bf9 --- /dev/null +++ b/docs/README-fi.md @@ -0,0 +1,337 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking +application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation + directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-fr.md b/docs/README-fr.md new file mode 100644 index 0000000000..241c9b5a97 --- /dev/null +++ b/docs/README-fr.md @@ -0,0 +1,355 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes est une application gratuite, open-source et multiplateforme de +prise de notes hiĆ©rarchique, conƧue pour crĆ©er et gĆ©rer de vastes bases de +connaissances personnelles. + +Trilium Screenshot + +## ā¬ TĆ©lĆ©charger +- [DerniĆØre version](https://github.com/TriliumNext/Trilium/releases/latest) – + version stable, recommandĆ©e pour la plupart des utilisateurs. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + version de dĆ©veloppement instable, mise Ć  jour quotidiennement avec les + derniĆØres fonctionnalitĆ©s et corrections. + +## šŸ“š Documentation + +**Visitez notre documentation complĆØte sur +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Notre documentation est disponible sous plusieurs formats : +- **Documentation en ligne**: Parcourez la documentation complĆØte sur + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Aide intĆ©grĆ©e**: Appuyez sur `F1` dans Trilium pour accĆ©der Ć  la mĆŖme + documentation directement dans l'application +- **GitHub**: Naviguer dans le [Guide utilisateur] + (./User%20Guide/User%20Guide/) dans ce dĆ©pĆ“t + +### Liens rapides +- [Guide de dĆ©marrage](https://docs.triliumnotes.org/) +- [Instructions d'installation](https://docs.triliumnotes.org/user-guide/setup) +- [Configuration + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Mise Ć  jour de TriliumNext] + (https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Concepts et fonctionnalitĆ©s de + base](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [ModĆØles de base de connaissances + personnelles](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ FonctionnalitĆ©s + +* Les notes peuvent ĆŖtre organisĆ©es selon une arborescence de profondeur + arbitraire. Une mĆŖme note peut ĆŖtre placĆ©e Ć  plusieurs endroits de + l'arborescence (voir + [clonage](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Ɖditeur de notes WYSIWYG enrichi comprenant par exemple des tableaux, des + images et [des formules + mathĆ©matiques](https://docs.triliumnotes.org/user-guide/note-types/text) avec + [formatage automatique en + Markdown](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Prise en charge de l'Ć©dition [de notes avec code + source](https://docs.triliumnotes.org/user-guide/note-types/code), incluant la + coloration syntaxique +* Navigation rapide et facile entre les + notes(https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + recherche en texte intĆ©gral et [focalisation de + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Gestion transparente des [versions de + notes](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Les [attributs] de + note(https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + peuvent ĆŖtre utilisĆ©s pour l'organisation, l'interrogation et les [scripts] + avancĆ©s(https://docs.triliumnotes.org/user-guide/scripts) +* Interface utilisateur disponible en anglais, allemand, espagnol, franƧais, + roumain et chinois (simplifiĆ© et traditionnel) +* [IntĆ©gration directe d'OpenID et + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) pour une + connexion plus sĆ©curisĆ©e +* [Synchronisation](https://docs.triliumnotes.org/user-guide/setup/synchronization) + avec un serveur de synchronisation auto-hĆ©bergĆ© + * Il existe des [services tiers pour hĆ©berger un serveur de + synchronisation](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Partage](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publication) de notes sur Internet +* [Cryptage de + note](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + fort avec granularitĆ© par note +* Diagrammes d'esquisse, basĆ©s sur [Excalidraw](https://excalidraw.com/) (type + de note "canvas")) +* [Cartes de + relations](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + et [cartes de + notes/liens](https://docs.triliumnotes.org/user-guide/note-types/note-map) + pour visualiser les notes et leurs liens +* Cartes mentales, basĆ©es sur [Mind Elixir] (https://docs.mind-elixir.com/) +* [Cartes + gĆ©ographiques](https://docs.triliumnotes.org/user-guide/collections/geomap) + avec repĆØres de localisation et pistes GPX +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - voir [Vitrines + avancĆ©es](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [API REST](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) pour + l'automatisation +* OptimisĆ© en termes d’ergonomie et de performances, mĆŖme au-delĆ  de 100 000 + notes +* [Interface + mobile](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) + optimisĆ©e pour le tactile sur smartphones et tablettes +* [ThĆØme sombre](https://docs.triliumnotes.org/user-guide/concepts/themes) + intĆ©grĆ©, prise en charge des thĆØmes utilisateur +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + et [Importation et exportation + Markdown](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) pour + une sauvegarde facile du contenu web +* Interface utilisateur personnalisable (boutons de la barre latĆ©rale, widgets + dĆ©finis par l'utilisateur, ...) +* [Statistiques](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + avec un tableau de bord Grafana. + +✨ Consultez les ressources/communautĆ©s tierces suivantes pour plus de +fonctionnalitĆ©s liĆ©es Ć  TriliumNext : + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) pour des thĆØmes, + scripts, plugins et plus encore tiers. +- [TriliumRocks!](https://trilium.rocks/) pour des tutoriels, des guides et bien + plus encore. + +## ā“Pourquoi TriliumNext ? + +Le dĆ©veloppeur original de Trilium ([Zadam](https://github.com/zadam)) a +gracieusement donnĆ© le rĆ©fĆ©rentiel Trilium au projet communautaire hĆ©bergĆ© sur +https://github.com/TriliumNext + +### ā¬†ļøMigration depuis Zadam/Trilium ? + +Il n'y a aucune Ć©tape de migration spĆ©cifique pour migrer d'une instance +zadam/Trilium vers une instance TriliumNext/Trilium. Installez simplement +TriliumNext/Trilium comme d'habitude et votre base de donnĆ©es existante sera +utilisĆ©e. + +Les versions jusqu'Ć  +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) incluses +sont compatibles avec la derniĆØre version de zadam/trilium +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Les versions +ultĆ©rieures de TriliumNext/Trilium voient leurs versions synchronisĆ©es +incrĆ©mentĆ©es, ce qui empĆŖche toute migration directe. + +## šŸ’¬ Discutez avec nous + +N'hĆ©sitez pas Ć  participer Ć  nos discussions officielles. Nous serions ravis de +connaĆ®tre vos idĆ©es, suggestions ou problĆØmes ! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Pour les discussions + synchrones.) + - L'espace Matrix `GĆ©nĆ©ral` est Ć©galement reliĆ©e Ć  + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Discussions Github](https://github.com/TriliumNext/Trilium/discussions) (Pour + les discussions asynchrones.) +- [ProblĆØmes Github](https://github.com/TriliumNext/Trilium/issues) (Pour les + rapports de bogues et les demandes de fonctionnalitĆ©s.) + +## šŸ— Installation + +### Windows / MacOS + +TĆ©lĆ©chargez la version binaire pour votre plateforme Ć  partir de la [derniĆØre +page de version](https://github.com/TriliumNext/Trilium/releases/latest), +dĆ©compressez le package et exĆ©cutez l'exĆ©cutable `trilium`. + +### Linux + +Si votre distribution est rĆ©pertoriĆ©e dans le tableau ci-dessous, utilisez le +package de votre distribution. + +[![Statut du +Packaging](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +Vous pouvez Ć©galement tĆ©lĆ©charger la version binaire pour votre plateforme Ć  +partir de la [derniĆØre page de +version](https://github.com/TriliumNext/Trilium/releases/latest), dĆ©compresser +le package et lancer l'exĆ©cutable `trilium`. + +TriliumNext est Ć©galement fourni sous forme de Flatpak, mais pas encore publiĆ© +sur FlatHub. + +### Navigateur (tout systĆØme d'exploitation) + +Si vous utilisez une installation serveur (voir ci-dessous), vous pouvez accĆ©der +directement Ć  l'interface Web (qui est presque identique Ć  l'application de +bureau). + +Actuellement, seules les derniĆØres versions de Chrome & Firefox sont supportĆ©es +(et testĆ©es). + +### Mobile + +Pour utiliser TriliumNext sur un appareil mobile, vous pouvez utiliser un +navigateur Web afin d' accĆ©der Ć  l'interface d'une installation serveur (voir +ci-dessous). + +Pour plus d’informations sur le support de l’application mobile, consultez le +ticket https://github.com/TriliumNext/Trilium/issues/4962. + +Si vous prĆ©fĆ©rez une application Android native, vous pouvez utiliser +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Signalez les bugs et les fonctionnalitĆ©s manquantes sur [leur +dĆ©pĆ“t](https://github.com/FliegendeWurst/TriliumDroid). Remarque : Il est +prĆ©fĆ©rable de dĆ©sactiver les mises Ć  jour automatiques sur votre serveur (voir +ci-dessous) lorsque vous utilisez TriliumDroid, car les versions doivent rester +synchronisĆ©es entre Trilium et TriliumDroid. + +### Serveur + +Pour installer TriliumNext sur votre propre serveur (y compris via Docker depuis +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)), suivez [les +documents d'installation du +serveur](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribuer + +### Traductions + +Si vous ĆŖtes un locuteur natif, aidez-nous Ć  traduire Trilium en vous rendant +sur notre [page Weblate](https://hosted.weblate.org/engage/trilium/). + +Voici la couverture linguistique dont nous disposons jusqu'Ć  prĆ©sent : + +[ ![Statut de la +traduction](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +TĆ©lĆ©chargez le rĆ©fĆ©rentiel, installez les dĆ©pendances Ć  l'aide de `pnpm` puis +exĆ©cutez le serveur (disponible sur http://localhost:8080) : +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +TĆ©lĆ©chargez le rĆ©fĆ©rentiel, installez les dĆ©pendances Ć  l'aide de `pnpm`, puis +exĆ©cutez l'environnement requis pour modifier la documentation : +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### GĆ©nĆ©rer l'exĆ©cutable +TĆ©lĆ©chargez le rĆ©fĆ©rentiel, installez les dĆ©pendances Ć  l'aide de `pnpm`, puis +crĆ©ez l'application de bureau pour Windows : +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Pour plus de dĆ©tails, consultez la [documentation de +dĆ©veloppement](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Documentation du dĆ©veloppeur + +Veuillez consulter le [guide de +documentation](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +pour plus de dĆ©tails. Pour toute question, n'hĆ©sitez pas Ć  nous contacter via +les liens dĆ©crits dans la section "Discuter avec nous" ci-dessus. + +## šŸ‘ DĆ©dicaces + +* [zadam](https://github.com/zadam) pour le concept original et la mise en œuvre + de l'application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) pour la conception de + l'icĆ“ne de l'application. +* [nriver](https://github.com/nriver) pour son travail sur + l’internationalisation. +* [Thomas Frei](https://github.com/thfrei) pour son travail original sur le + Canvas. +* [antoniotejada](https://github.com/nriver) pour le widget de coloration + syntaxique original. +* [Dosu](https://dosu.dev/) pour nous avoir fourni des rĆ©ponses automatisĆ©es aux + problĆØmes et aux discussions sur GitHub. +* [Tabler Icons](https://tabler.io/icons) pour les icĆ“nes de la barre d'Ć©tat + systĆØme. + +Trilium ne serait pas possible sans les technologies qui le sous-tendent : + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - est l’éditeur visuel + utilisĆ© pour les notes textuelles. Nous remercions l’équipe pour la mise Ć  + disposition d’un ensemble de fonctionnalitĆ©s premium. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - Ć©diteur de code + prenant en charge un grand nombre de langages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - le tableau blanc + infini utilisĆ© dans les notes Canvas. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - fournit la + fonctionnalitĆ© de carte mentale. +* [Leaflet](https://github.com/Leaflet/Leaflet) - pour le rendu des cartes + gĆ©ographiques. +* [Tabulator](https://github.com/olifolkerd/tabulator) - pour le tableau + interactif utilisĆ© dans les collections. +* [FancyTree](https://github.com/mar10/fancytree) - bibliothĆØque d'arborescence + riche en fonctionnalitĆ©s sans rĆ©elle concurrence. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - BibliothĆØque de connectivitĆ© + visuelle. UtilisĆ©e dans les [cartes de + relations](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + et les [cartes de + liens](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium est dĆ©veloppĆ© et maintenu grĆ¢ce Ć  [des centaines d'heures de +travail](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Votre +soutien permet son maintien en open-source, d'amĆ©liorer ses fonctionnalitĆ©s et +de couvrir des coĆ»ts tels que l'hĆ©bergement. + +Envisagez de soutenir le dĆ©veloppeur principal +([eliandoran](https://github.com/eliandoran)) de l'application via : + +- [Sponsors GitHub](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Offrez-moi un cafĆ©](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran et autres contributeurs + +Ce programme est un logiciel libre : vous pouvez le redistribuer et/ou le +modifier selon les termes de la licence publique gĆ©nĆ©rale GNU Affero telle que +publiĆ©e par la Free Software Foundation, soit la version 3 de la licence, soit +(Ć  votre choix) toute version ultĆ©rieure. diff --git a/docs/README-ga.md b/docs/README-ga.md new file mode 100644 index 0000000000..42d3ee6e1b --- /dev/null +++ b/docs/README-ga.md @@ -0,0 +1,355 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![UrraitheoirĆ­ GitHub](https://img.shields.io/github/sponsors/eliandoran) +![PĆ”trĆŗin LiberaPay](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![TarraingtĆ­ Docker](https://img.shields.io/docker/pulls/triliumnext/trilium) +![ƍoslódĆ”lacha GitHub (gach sócmhainn, gach +eisiĆŗint)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![StĆ”das +aistriĆŗchĆ”in](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Is feidhmchlĆ”r saor in aisce agus foinse oscailte, tras-ardĆ”n, ordlathach Ć© +Trilium Notes chun nótaĆ­ a thógĆ”il le fócas ar bhunachair mhóra eolais +phearsanta a thógĆ”il. + +Trilium Screenshot + +## ā¬ ƍoslódĆ”il +- [An leagan is dĆ©anaĆ­](https://github.com/TriliumNext/Trilium/releases/latest) + – leagan cobhsaĆ­, molta do fhormhór na n-ĆŗsĆ”ideoirĆ­. +- [TógĆ”il oĆ­che](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + leagan forbartha Ć©agobhsaĆ­, a nuashonraĆ­tear go laethĆŗil leis na gnĆ©ithe agus + na socruithe is dĆ©anaĆ­. + +## šŸ“š DoicimĆ©adĆŗ + +**Tabhair cuairt ar Ć”r ndoicimĆ©adacht chuimsitheach ag +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +TĆ” Ć”r ndoicimĆ©adacht ar fĆ”il i bhformĆ”idĆ­ Ć©agsĆŗla: +- **DoicimĆ©adacht Ar LĆ­ne**: BrabhsĆ”il an doicimĆ©adacht iomlĆ”n ag + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Cabhair san Aip**: BrĆŗigh `F1` laistigh de Trilium chun rochtain a fhĆ”il ar + an doicimĆ©adacht chĆ©anna go dĆ­reach san fheidhmchlĆ”r +- **GitHub**: NascleanĆŗint trĆ­d an [Treoir + ÚsĆ”ideora](./User%20Guide/User%20Guide/) sa stórlann seo + +### Naisc Thapa +- [Treoir Tosaithe](https://docs.triliumnotes.org/) +- [Treoracha SuiteĆ”la](https://docs.triliumnotes.org/user-guide/setup) +- [SocrĆŗ + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [UasghrĆ”dĆŗ + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Coincheapa agus GnĆ©ithe + BunĆŗsacha](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [PatrĆŗin de Bhunachar Eolais + Phearsanta](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ GnĆ©ithe + +* Is fĆ©idir nótaĆ­ a shocrĆŗ i gcrann domhain treallach. Is fĆ©idir nóta aonair a + chur in Ć”iteanna Ć©agsĆŗla sa chrann (fĆ©ach + [clónĆ”il](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Eagarthóir nótaĆ­ WYSIWYG saibhir lena n-Ć”irĆ­tear tĆ”blaĆ­, Ć­omhĆ”nna agus + [matamaitic](https://docs.triliumnotes.org/user-guide/note-types/text) le + marcĆ”il sĆ­os + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* TacaĆ­ocht le haghaidh eagarthóireacht [nótaĆ­ le cód + foinse](https://docs.triliumnotes.org/user-guide/note-types/code), lena + n-Ć”irĆ­tear aibhsiĆŗ comhrĆ©ire +* NascleanĆŗint thapa agus Ć©asca idir + nótaĆ­(https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + cuardach tĆ©acs iomlĆ”n agus [ardĆŗ + nótaĆ­](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Gan uaim [leaganĆŗ + nótaĆ­](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Is fĆ©idir nótaĆ­ + [trĆ©ithe](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + a ĆŗsĆ”id chun nótaĆ­ a eagrĆŗ, fiosrĆŗchĆ”in a dhĆ©anamh agus [scriptiĆŗ] + ardleibhĆ©il(https://docs.triliumnotes.org/user-guide/scripts) +* TĆ” an comhĆ©adan ĆŗsĆ”ideora ar fĆ”il i mBĆ©arla, i nGearmĆ”inis, i SpĆ”innis, i + bhFraincis, i RómĆ”inis, agus i SĆ­nis (simplithe agus traidisiĆŗnta) +* DĆ­reach [ComhthĆ”thĆŗ OpenID agus + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) le haghaidh + logĆ”il isteach nĆ­os slĆ”ine +* [SioncrónĆŗ](https://docs.triliumnotes.org/user-guide/setup/synchronization) le + freastalaĆ­ sioncrónaithe fĆ©inóstĆ”ilte + * tĆ” [seirbhĆ­sĆ­ trĆ­Ćŗ pĆ”irtĆ­ ann chun freastalaĆ­ sioncrónaithe a + óstĆ”il](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* NótaĆ­ [Ag + roinnt](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) (ag + foilsiĆŗ) ar an idirlĆ­on poiblĆ­ +* [CriptiĆŗ nótaĆ­] + lĆ”idir(https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + le mionsonraĆ­ in aghaidh an nóta +* LĆ©arĆ”idĆ­ sceitseĆ”la, bunaithe ar [Excalidraw](https://excalidraw.com/) + (tabhair faoi deara cineĆ”l "canbhĆ”s") +* [LĆ©arscĆ”ileanna + caidrimh](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + agus [lĆ©arscĆ”ileanna + nótaĆ­/naisc](https://docs.triliumnotes.org/user-guide/note-types/note-map) + chun nótaĆ­ agus a gcaidrimh a lĆ©irshamhlĆŗ +* LĆ©arscĆ”ileanna intinne, bunaithe ar [Mind + Elixir](https://docs.mind-elixir.com/) +* [LĆ©arscĆ”ileanna + geo](https://docs.triliumnotes.org/user-guide/collections/geomap) le biorĆ”in + suĆ­mh agus rianta GPX +* [ScriptiĆŗ](https://docs.triliumnotes.org/user-guide/scripts) - fĆ©ach + [TaispeĆ”ntais + ArdleibhĆ©il](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) le + haghaidh uathoibrithe +* ScĆ”lann go maith i dtĆ©armaĆ­ inĆŗsĆ”idteachta agus feidhmĆ­ochta araon os cionn + 100,000 nóta +* Tadhall-optamaithe [comhĆ©adan soghluaiste] + (https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) le haghaidh + fóin chliste agus tĆ”iblĆ©ad +* TĆ©ama dorcha + ionsuite(https://docs.triliumnotes.org/user-guide/concepts/themes), tacaĆ­ocht + do thĆ©amaĆ­ ĆŗsĆ”ideora +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + agus [IompórtĆ”il & EaspórtĆ”il + Markdown](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Gearrthóir + GrĆ©asĆ”in](https://docs.triliumnotes.org/user-guide/setup/web-clipper) le + haghaidh sĆ”bhĆ”il Ć©asca ar Ć”bhar grĆ©asĆ”in +* ComhĆ©adan ĆŗsĆ”ideora saincheaptha (cnaipĆ­ taobhbharra, giuirlĆ©idĆ­ sainithe ag + an ĆŗsĆ”ideoir, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + mar aon le PainĆ©al Grafana. + +✨ FĆ©ach ar na hacmhainnĆ­/pobail trĆ­Ćŗ pĆ”irtĆ­ seo a leanas le haghaidh tuilleadh +earraĆ­ gaolmhara le TriliumNext: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) le haghaidh + tĆ©amaĆ­, scripteanna, breiseĆ”in agus tuilleadh ó thrĆ­Ćŗ pĆ”irtithe. +- [TriliumRocks!](https://trilium.rocks/) le haghaidh ranganna teagaisc, + treoracha, agus i bhfad nĆ­os mó. + +## ā“CĆ©n fĆ”th TriliumNext? + +Bhronn forbróir bunaidh Trilium ([Zadam](https://github.com/zadam)) stórlann +Trilium go fial ar an tionscadal pobail atĆ” le fĆ”il ag +https://github.com/TriliumNext + +### ā¬†ļøAg dul ar imirce ó Zadam/Trilium? + +NĆ­l aon chĆ©imeanna imirce speisialta ann chun imirce ó shampla zadam/Trilium go +sampla TriliumNext/Trilium. NĆ­l le dĆ©anamh ach [TriliumNext/Trilium a +shuiteĆ”il](#-installation) mar is gnĆ”ch agus ĆŗsĆ”idfidh sĆ© do bhunachar sonraĆ­ +atĆ” ann cheana fĆ©in. + +TĆ” leaganacha suas go dtĆ­ agus lena n-Ć”irĆ­tear +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) +comhoiriĆŗnach leis an leagan is dĆ©anaĆ­ de zadam/trilium de +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). MĆ©adaĆ­tear +leaganacha sioncrónaithe aon leaganacha nĆ­os dĆ©anaĆ­ de TriliumNext/Trilium rud a +chuireann cosc ar aistriĆŗ dĆ­reach. + +## šŸ’¬ PlĆ©igh linn + +NĆ” bĆ­odh drogall ort pĆ”irt a ghlacadh inĆ”r gcomhrĆ”ite oifigiĆŗla. Ba bhreĆ” linn +cloisteĆ”il faoi na gnĆ©ithe, na moltaĆ­ nó na fadhbanna a d'fhĆ©adfadh a bheith +agat! + +- [MaitrĆ­s](https://matrix.to/#/#triliumnext:matrix.org) (Le haghaidh plĆ© + sioncrónach.) + - TĆ” droichead idir seomra an MhaitrĆ­s `GinearĆ”lta` agus + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) freisin +- [PlĆ© Github](https://github.com/TriliumNext/Trilium/discussions) (Le haghaidh + plĆ© neamhshioncrónach.) +- [Fadhbanna Github](https://github.com/TriliumNext/Trilium/issues) (Le haghaidh + tuairiscĆ­ fabhtanna agus iarratais ar ghnĆ©ithe.) + +## šŸ— SuiteĆ”il + +### Windows / MacOS + +ƍoslódĆ”il an scaoileadh dĆ©nĆ”rtha do d'ardĆ”n ón [leathanach scaoileadh is +dĆ©anaĆ­](https://github.com/TriliumNext/Trilium/releases/latest), dĆ­zipeĆ”il an +pacĆ”iste agus rith an comhad inrite `trilium`. + +### Linux + +MĆ”s liostaithe sa tĆ”bla thĆ­os atĆ” do dhĆ”ileadh, bain ĆŗsĆ”id as pacĆ”iste do +dhĆ”ilte. + +[![StĆ”das +pacĆ”istithe](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +FĆ©adfaidh tĆŗ an scaoileadh dĆ©nĆ”rtha do d'ardĆ”n a Ć­oslódĆ”il ón [leathanach +scaoileadh is dĆ©anaĆ­](https://github.com/TriliumNext/Trilium/releases/latest) +freisin, an pacĆ”iste a dhĆ­zipeĆ”il agus an comhad inrite `trilium` a rith. + +Cuirtear TriliumNext ar fĆ”il mar Flatpak freisin, ach nĆ­l sĆ© foilsithe ar +FlatHub go fóill. + +### BrabhsĆ”laĆ­ (aon chóras oibriĆŗchĆ”in) + +MĆ” ĆŗsĆ”ideann tĆŗ suiteĆ”il freastalaĆ­ (fĆ©ach thĆ­os), is fĆ©idir leat rochtain +dhĆ­reach a fhĆ”il ar an gcomhĆ©adan grĆ©asĆ”in (atĆ” beagnach mar an gcĆ©anna leis an +aip deisce). + +Faoi lĆ”thair nĆ­ thacaĆ­tear (agus dĆ©antar tĆ”stĆ”il ar) ach leis na leaganacha is +dĆ©anaĆ­ de Chrome agus Firefox. + +### Soghluaiste + +Chun TriliumNext a ĆŗsĆ”id ar ghlĆ©as soghluaiste, is fĆ©idir leat brabhsĆ”laĆ­ +grĆ©asĆ”in soghluaiste a ĆŗsĆ”id chun rochtain a fhĆ”il ar chomhĆ©adan soghluaiste +suiteĆ”la freastalaĆ­ (fĆ©ach thĆ­os). + +FĆ©ach ar an eagrĆ”n https://github.com/TriliumNext/Trilium/issues/4962 le +haghaidh tuilleadh eolais faoi thacaĆ­ocht d’aipeanna soghluaiste. + +MĆ”s fearr leat aip dhĆŗchasach Android, is fĆ©idir leat +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid) +a ĆŗsĆ”id. Tuairiscigh fabhtanna agus gnĆ©ithe atĆ” ar iarraidh ag [a +stór](https://github.com/FliegendeWurst/TriliumDroid). Tabhair faoi deara: Is +fearr nuashonruithe uathoibrĆ­ocha a dhĆ­chumasĆŗ ar do shuiteĆ”il freastalaĆ­ (fĆ©ach +thĆ­os) agus TriliumDroid in ĆŗsĆ”id agat ós rud Ć© go gcaithfidh an leagan +sioncrónaithe a bheith mar an gcĆ©anna idir Trilium agus TriliumDroid. + +### FreastalaĆ­ + +Chun TriliumNext a shuiteĆ”il ar do fhreastalaĆ­ fĆ©in (lena n-Ć”irĆ­tear trĆ­ Docker +ó [Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) lean [na doicimĆ©id +suiteĆ”la freastalaĆ­](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Cuir leis + +### AistriĆŗchĆ”in + +MĆ”s cainteoir dĆŗchais thĆŗ, cabhraigh linn Trilium a aistriĆŗ trĆ­ dhul chuig Ć”r +[leathanach Weblate](https://hosted.weblate.org/engage/trilium/). + +Seo an clĆŗdach teanga atĆ” againn go dtĆ­ seo: + +[![StĆ”das +aistriĆŗchĆ”in](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Cód + +ƍoslódĆ”il an stórlann, suiteĆ”il spleĆ”chais ag baint ĆŗsĆ”ide as `pnpm` agus ansin +rith an freastalaĆ­ (ar fĆ”il ag http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### DoicimĆ©adĆŗ + +ƍoslódĆ”il an stórlann, suiteĆ”il spleĆ”chais ag baint ĆŗsĆ”ide as `pnpm` agus ansin +rith an timpeallacht atĆ” riachtanach chun an doicimĆ©adĆŗ a chur in eagar: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Ag TógĆ”il an Inrite +ƍoslódĆ”il an stórlann, suiteĆ”il spleĆ”chais ag baint ĆŗsĆ”ide as `pnpm` agus ansin +tóg an aip deisce do Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Le haghaidh tuilleadh sonraĆ­, fĆ©ach ar na [doicimĆ©id +forbartha](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### DoicimĆ©adacht Forbróra + +FĆ©ach ar an [treoir +dhoicimĆ©adĆŗchĆ”in](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +le haghaidh tuilleadh sonraĆ­. MĆ” tĆ” tuilleadh ceisteanna agat, bĆ­odh leisce ort +teagmhĆ”il a dhĆ©anamh linn trĆ­ na naisc a bhfuil cur sĆ­os orthu sa chuid "PlĆ©igh +Linn" thuas. + +## šŸ‘ Glaonna amach + +* [zadam](https://github.com/zadam) as an gcoincheap bunaidh agus cur i bhfeidhm + an fheidhmchlĆ”ir. +* [Sarah Hussein](https://github.com/Sarah-Hussein) as dearadh dheilbhĆ­n an + fheidhmchlĆ”ir. +* [nriver](https://github.com/nriver) as a chuid oibre ar an idirnĆ”isiĆŗnĆŗ. +* [Thomas Frei](https://github.com/thfrei) as a shaothar bunaidh ar an ChanbhĆ”s. +* [antoniotejada](https://github.com/nriver) don ghiuirlĆ©id aibhsithe comhrĆ©ire + bunaidh. +* [Dosu](https://dosu.dev/) as na freagraĆ­ uathoibrithe a sholĆ”thar dĆŗinn ar + shaincheisteanna agus ar phlĆ© GitHub. +* [DeilbhĆ­nĆ­ TĆ”bla](https://tabler.io/icons) do na deilbhĆ­nĆ­ sa trĆ”idire córais. + +NĆ­ bheadh Trilium indĆ©anta gan na teicneolaĆ­ochtaĆ­ atĆ” taobh thiar de: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - an t-eagarthóir amhairc + atĆ” taobh thiar de nótaĆ­ tĆ©acs. TĆ”imid buĆ­och as sraith de na gnĆ©ithe prĆ©imhe + a bheith curtha ar fĆ”il dĆŗinn. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - eagarthóir cóid le + tacaĆ­ocht do lĆ­on ollmhór teangacha. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - an clĆ”r bĆ”n gan + teorainn a ĆŗsĆ”idtear i nótaĆ­ Canvas. +* [Intinn Elixir](https://github.com/SSShooter/mind-elixir-core) - ag solĆ”thar + feidhmiĆŗlacht lĆ©arscĆ”il intinne. +* [Bileog](https://github.com/Leaflet/Leaflet) - le haghaidh lĆ©arscĆ”ileanna + geografacha a lĆ©iriĆŗ. +* [TĆ”bla](https://github.com/olifolkerd/tabulator) - don tĆ”bla idirghnĆ­omhach a + ĆŗsĆ”idtear i mbailiĆŗchĆ”in. +* [FancyTree](https://github.com/mar10/fancytree) - leabharlann crann lĆ”n + gnĆ©ithe gan iomaĆ­ocht cheart. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - leabharlann nascachta amhairc. + ÚsĆ”idte i [lĆ©arscĆ”ileanna + caidrimh](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + agus [lĆ©arscĆ”ileanna + nasc](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ TacaĆ­ocht + +Tógtar agus cothaĆ­tear Trilium le [na cĆ©adta uair an chloig +oibre](https://github.com/TriliumNext/Trilium/graphs/commit-activity). CoinnĆ­onn +do thacaĆ­ocht Ć© foinse oscailte, feabhsaĆ­onn sĆ© gnĆ©ithe, agus clĆŗdaĆ­onn sĆ© +costais amhail óstĆ”il. + +Smaoinigh ar thacaĆ­ocht a thabhairt don phrĆ­omhfhorbróir +([eliantoran](https://github.com/eliandoran)) den fheidhmchlĆ”r trĆ­: + +- [UrraitheoirĆ­ GitHub](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Ceannaigh Caife Dom](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ CeadĆŗnas + +Cóipcheart 2017-2025 zadam, Elian Doran, agus rannphĆ”irtithe eile + +Is bogearraĆ­ saor in aisce an clĆ”r seo: is fĆ©idir leat Ć© a athdhĆ”ileadh agus/nó +a mhodhnĆŗ faoi thĆ©armaĆ­ CheadĆŗnas PoiblĆ­ GinearĆ”lta GNU Affero mar atĆ” foilsithe +ag an bhFondĆŗireacht BogearraĆ­ Saor in Aisce, cibĆ© acu leagan 3 den CheadĆŗnas, +nó (de rĆ©ir do rogha fĆ©in) aon leagan nĆ­os dĆ©anaĆ­. diff --git a/docs/README-hi.md b/docs/README-hi.md new file mode 100644 index 0000000000..b8e1901420 --- /dev/null +++ b/docs/README-hi.md @@ -0,0 +1,339 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# ą¤Ÿą„ą¤°ą¤æą¤²ą¤æą¤Æą¤® ą¤Øą„‹ą¤Ÿą„ą¤ø + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking +application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą„€ą¤œą¤æą¤ +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š ą¤”ą„‰ą¤•ą„ą¤Æą„‚ą¤®ą„‡ą¤‚ą¤Ÿą„‡ą¤¶ą¤Ø + +**ą¤¹ą¤®ą¤¾ą¤°ą„‡ ą¤µą¤æą¤øą„ą¤¤ą„ƒą¤¤ ą¤”ą„‰ą¤•ą„ą¤Æą„‚ą¤®ą„‡ą¤‚ą¤Ÿą„‡ą¤¶ą¤Ø ą¤•ą„‹ +[docs.triliumnotes.org](https://docs.triliumnotes.org/) पर ą¤¦ą„‡ą¤–ą„‡ą¤‚** + +हमारा ą¤”ą„‰ą¤•ą„ą¤Æą„‚ą¤®ą„‡ą¤‚ą¤Ÿą„‡ą¤¶ą¤Ø ą¤•ą¤ˆ ą¤«ą„‰ą¤°ą„ą¤®ą„‡ą¤Ÿą„ą¤ø ą¤®ą„‡ą¤‚ ą¤‰ą¤Ŗą¤²ą¤¬ą„ą¤§ ą¤¹ą„ˆ: +- **ऑनलाइन ą¤”ą„‰ą¤•ą„ą¤Æą„‚ą¤®ą„‡ą¤‚ą¤Ÿą„‡ą¤¶ą¤Ø**: + [docs.triliumnotes.org](https://docs.triliumnotes.org/) पर ą¤Ŗą„‚ą¤°ą¤¾ ą¤”ą„‰ą¤•ą„ą¤Æą„‚ą¤®ą„‡ą¤‚ą¤Ÿą„‡ą¤¶ą¤Ø + ą¤¦ą„‡ą¤–ą„‡ą¤‚ +- **इन-ऐप ą¤¹ą„‡ą¤²ą„ą¤Ŗ**: ą¤‰ą¤øą„€ ą¤”ą„‰ą¤•ą„ą¤Æą„‚ą¤®ą„‡ą¤‚ą¤Ÿą„‡ą¤¶ą¤Ø ą¤•ą„‹ ą¤øą„€ą¤§ą„‡ ऐप ą¤®ą„‡ą¤‚ ą¤ą¤•ą„ą¤øą„‡ą¤ø ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ÿą„ą¤°ą¤æą¤²ą¤æą¤Æą¤® + ą¤•ą„‡ अंदर `F1` ą¤¦ą¤¬ą¤¾ą¤ą¤ +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [ą¤”ą„‰ą¤•ą¤° + ą¤øą„‡ą¤Ÿą¤…ą¤Ŗ](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [TriliumNext ą¤•ą„‹ ą¤…ą¤Ŗą¤—ą„ą¤°ą„‡ą¤” + करना](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ ą¤–ą¤¾ą¤øą¤æą¤Æą¤¤ą„‡ą¤‚ + +* ą¤Øą„‹ą¤Ÿą„ą¤ø ą¤•ą„‹ ą¤®ą¤Øą¤šą¤¾ą¤¹ą„‡ ą¤—ą¤¹ą¤°ą„‡ ą¤Ÿą„ą¤°ą„€ (tree) ą¤øą„ą¤Ÿą„ą¤°ą¤•ą„ą¤šą¤° ą¤®ą„‡ą¤‚ ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ किया जा सकता ą¤¹ą„ˆą„¤ ą¤ą¤• + ą¤¹ą„€ ą¤Øą„‹ą¤Ÿ ą¤•ą„‹ ą¤Ÿą„ą¤°ą„€ ą¤®ą„‡ą¤‚ ą¤•ą¤ˆ ą¤œą¤—ą¤¹ą„‹ą¤‚ पर रखा जा सकता ą¤¹ą„ˆ (ą¤¦ą„‡ą¤–ą„‡ą¤‚ + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* ą¤¬ą„‡ą¤¹ą¤¤ą¤°ą„€ą¤Ø WYSIWYG ą¤Øą„‹ą¤Ÿ ą¤ą¤”ą¤æą¤Ÿą¤°, ą¤œą¤æą¤øą¤®ą„‡ą¤‚ ą¤Ÿą„‡ą¤¬ą¤², ą¤‡ą¤®ą„‡ą¤œ और + [math](https://docs.triliumnotes.org/user-guide/note-types/text) ą¤•ą„‡ साऄ-साऄ + ą¤®ą¤¾ą¤°ą„ą¤•ą¤”ą¤¾ą¤‰ą¤Ø + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) + ą¤•ą„€ ą¤øą„ą¤µą¤æą¤§ą¤¾ शामिल ą¤¹ą„ˆ +* [ą¤øą„‹ą¤°ą„ą¤ø ą¤•ą„‹ą¤” ą¤µą¤¾ą¤²ą„‡ + ą¤Øą„‹ą¤Ÿą„ą¤ø](https://docs.triliumnotes.org/user-guide/note-types/code) ą¤•ą„‹ ą¤ą¤”ą¤æą¤Ÿ ą¤•ą¤°ą¤Øą„‡ + ą¤•ą„€ ą¤øą„ą¤µą¤æą¤§ą¤¾, ą¤œą¤æą¤øą¤®ą„‡ą¤‚ ą¤øą¤æą¤‚ą¤Ÿą„ˆą¤•ą„ą¤ø ą¤¹ą¤¾ą¤‡ą¤²ą¤¾ą¤‡ą¤Ÿą¤æą¤‚ą¤— (syntax highlighting) ą¤­ą„€ शामिल ą¤¹ą„ˆ +* ą¤¤ą„‡ą¤œą¤¼ और आसान [ą¤Øą„‹ą¤Ÿą„ą¤ø ą¤•ą„‡ ą¤¬ą„€ą¤š + ą¤Øą„‡ą¤µą¤æą¤—ą„‡ą¤¶ą¤Ø](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + ą¤«ą„ą¤² ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤øą¤°ą„ą¤š और [ą¤Øą„‹ą¤Ÿ + ą¤¹ą„‹ą¤‡ą¤øą„ą¤Ÿą¤æą¤‚ą¤—](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* ą¤Ŗą„ą¤°ą¤¤ą¤æ-ą¤Øą„‹ą¤Ÿ granularity ą¤•ą„‡ साऄ ą¤®ą¤œą¤¬ą„‚ą¤¤ [ą¤Øą„‹ą¤Ÿ + ą¤ą¤Øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤¶ą¤Ø](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* [Mind Elixir](https://docs.mind-elixir.com/) पर आधारित माइंऔ ą¤®ą„ˆą¤Ŗą„ą¤ø +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* ą¤‘ą¤Ÿą„‹ą¤®ą„‡ą¤¶ą¤Ø ą¤•ą„‡ ą¤²ą¤æą¤ [REST + API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ ą¤¹ą¤®ą¤¾ą¤°ą„‡ साऄ ą¤šą¤°ą„ą¤šą¤¾ ą¤•ą¤°ą„‡ą¤‚ + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-hr.md b/docs/README-hr.md new file mode 100644 index 0000000000..0da3a37bf9 --- /dev/null +++ b/docs/README-hr.md @@ -0,0 +1,337 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking +application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation + directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-hu.md b/docs/README-hu.md new file mode 100644 index 0000000000..c69c56e8f0 --- /dev/null +++ b/docs/README-hu.md @@ -0,0 +1,338 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Jegyzetek + +![GitHub szponzorok](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay tĆ”mogatók](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker pull-ok](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub letƶltĆ©sek (ƶsszes tartalom, ƶsszes +kiadĆ”s)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![FordĆ­tĆ”s +Ć”llapota](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +A Trilium Notes egy ingyenes Ć©s nyĆ­lt forrĆ”skódĆŗ, platformfüggetlen hierarchikus +jegyzetelő alkalmazĆ”s, amely nagy szemĆ©lyes tudĆ”sbĆ”zisok Ć©pĆ­tĆ©sĆ©re ƶsszpontosĆ­t. + +Trilium Screenshot + +## ā¬ LetƶltĆ©s +- [LegĆŗjabb kiadĆ”s](https://github.com/TriliumNext/Trilium/releases/latest) – + stabil verzió, a legtƶbb felhasznĆ”ló szĆ”mĆ”ra ajĆ”nlott. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + instabil fejlesztői verzió, naponta frissül a legĆŗjabb funkciókkal Ć©s + javĆ­tĆ”sokkal. + +## šŸ“š DokumentĆ”ció + +**Tekintse meg Ć”tfogó dokumentĆ”ciónkat a [docs.triliumnotes.org] +cĆ­men(https://docs.triliumnotes.org/)** + +DokumentĆ”cióink tƶbbfĆ©le formĆ”tumban is elĆ©rhetők: +- **Online dokumentĆ”ció**: BƶngĆ©ssze a teljes dokumentĆ”ciót a + [docs.triliumnotes.org](https://docs.triliumnotes.org/) cĆ­men. +- **AlkalmazĆ”son belüli sĆŗgó**: Nyomja meg az `F1` billentyűt a Triliumon belül, + hogy ugyanazt a dokumentĆ”ciót kƶzvetlenül az alkalmazĆ”sban is elĆ©rje. +- **GitHub**: NavigĆ”lj a [FelhasznĆ”lói + Ćŗtmutatóban](./User%20Guide/User%20Guide/) ebben a repository-ban + +### Gyorslinkek +- [Kezdő lĆ©pĆ©sek Ćŗtmutatója](https://docs.triliumnotes.org/) +- [TelepĆ­tĆ©si utasĆ­tĆ”sok](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + beĆ”llĆ­tĆ”s](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [TriliumNext + FrissĆ­tĆ©se](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Alapfogalmak Ć©s + jellemzők](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [A szemĆ©lyes tudĆ”sbĆ”zis + mintĆ”i](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Jellemzők + +* A jegyzetek ƶnkĆ©nyesen mĆ©ly fĆ”ba rendezhetők. Egyetlen jegyzetet lehet + elhelyezni a tƶbbi fĆ”ba (lĆ”sd + [klónozĆ”s](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Gazdag WYSIWYG jegyzetszerkesztő, beleĆ©rtve pĆ©ldĆ”ul az asztalokat, kĆ©peket Ć©s + [math](https://docs.triliumnotes.org/user-guide/note-types/text) markdownt + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* SzerkesztĆ©s tĆ”mogatĆ”sa [jegyzetek + forrĆ”skóddal](https://docs.triliumnotes.org/user-guide/note-types/code), + beleĆ©rtve a szintaxis kiemelĆ©sĆ©t +* Gyors Ć©s egyszerű [navigĆ”ció a jegyzetek + kƶzƶtt](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + teljes szƶveges keresĆ©s Ć©s + [megjegyzĆ©s](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Zƶkkenőmentes + [jegyzetvĆ”ltozat](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* MegjegyzĆ©s + [attribĆŗtumok](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + hasznĆ”lható jegyzetszervezĆ©shez, lekĆ©rdezĆ©shez Ć©s speciĆ”lis + [szkriptelĆ©s](https://docs.triliumnotes.org/user-guide/scripts) +* UI elĆ©rhető angol, nĆ©met, spanyol, francia, romĆ”n Ć©s kĆ­nai (egyszerűsĆ­tett Ć©s + hagyomĆ”nyos) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* ElmetĆ©rkĆ©pek, [Mind Elixir](https://docs.mind-elixir.com/) alapjĆ”n +* [Geo tĆ©rkĆ©pek](https://docs.triliumnotes.org/user-guide/collections/geomap) + helymeghatĆ”rozó tűkkel Ć©s GPX nyomokkal +* [SzkriptelĆ©s](https://docs.triliumnotes.org/user-guide/scripts) - lĆ”sd: + [SpeciĆ”lis + bemutatók](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-id.md b/docs/README-id.md new file mode 100644 index 0000000000..54d2ace045 --- /dev/null +++ b/docs/README-id.md @@ -0,0 +1,341 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![Unduhan GitHub (semua aset, semua +rilis)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Status +terjemahan](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes adalah aplikasi pencatatan hierarkis lintas platform yang gratis +dan sumber terbuka dengan fokus untuk mengembangkan pengetahuan pribadi yang +luas. + +Trilium Screenshot + +## ā¬ Unduh +- [Rilis terbaru](https://github.com/TriliumNext/Trilium/releases/latest) – + versi stabil, direkomendasikan. +- [Rilis nightly](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + versi pengembangan, tidak stabil, diperbarui setiap hari dengan fitur dan + perbaikan terbaru. + +## šŸ“š Dokumentasi + +**Kunjungi dokumentasi lengkap kami di +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Dokumentasi kami tersedia dalam berbagai format: +- **Dokumentasi Online**: Telusuri dokumentasi lengkap di + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Bantuan Dalam Aplikasi**: Tekan `F1` di dalam Trilium untuk mengakses + dokumentasi yang sama langsung di aplikasi +- **GitHub**: Navigasi melalui [Panduan Pengguna](./User%20Guide/User%20Guide/) + di repositori ini + +### Tautan Cepat +- [Panduan Memulai](https://docs.triliumnotes.org/) +- [Petunjuk Instalasi](https://docs.triliumnotes.org/user-guide/setup) +- [Pengaturan + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Pembaharuan + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Konsep dan Fitur + Dasar](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Pola Basis Pengetahuan + Pribadi](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Fitur + +* Catatan dapat disusun menjadi cabang pohon manapun. Satu catatan dapat disusun + ke beberapa cabang di pohon + (lihat[cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Catatan bentuk Rich WYSIWYG dengan tabel, gambar, dan + [math](https://docs.triliumnotes.org/user-guide/note-types/text) dengan + markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Dukungan untuk peng-editan [catatan dengan kode + source](https://docs.triliumnotes.org/user-guide/note-types/code), termasuk + penyorotan sintaks +* Cepat dan mudah [navigasi antar + catatan](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + pencarian dengan teks dan [area + fokus](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Mulus [versi + catatan](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Catatan + [atribut](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + dapat digunakan untuk mengatur catatan, pencarian dan tingkat lanjut + [pemrograman](https://docs.triliumnotes.org/user-guide/scripts) +* Antarmuka pengguna tersedia dalam bahasa Inggris, Jerman, Spanyol, Prancis, + Rumania, dan Tionghoa (sederhana dan tradisional) +* Integrasi [OpenID dan TOTP + langsung](https://docs.triliumnotes.org/user-guide/setup/server/mfa) untuk + login yang lebih aman +* [Sinkronisasi](https://docs.triliumnotes.org/user-guide/setup/synchronization) + dengan server hostingan pribadi + * ada [servis pihak ke-3 untuk server hostingan + sinkronisasi](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Bagikan](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publikasi) catatan ke publik (internet) +* Kuat [enkripsi + catatan](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + dengan granularitas per catatan +* Membuat diagram, berdasarkan [Excalidraw](https://excalidraw.com/) (tipe + catatan "kanvas") +* [Peta + relasi](https://docs.triliumnotes.org/user-guide/note-types/relation-map) dan + [peta + catatan/link](https://docs.triliumnotes.org/user-guide/note-types/note-map) + untuk visualisasi relasi antar catatan +* Mind maps, berdasarkan [Mind Elixir](https://docs.mind-elixir.com/) +* [Peta geolokasi](https://docs.triliumnotes.org/user-guide/collections/geomap) + dengan titik lokasi dan jalur GPX +* [Pengunaan skrip](https://docs.triliumnotes.org/user-guide/scripts) - lihat + [Demo tingkat + lanjut](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) + untuk otomatisasi +* Performa dan Usabilitas tinggi, bahkan di atas 100 000 catatan +* Teroptimisasi untuk kontrol sentuh [frontend + mobile](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) untuk + hp dan tablet +* [tema gelap](https://docs.triliumnotes.org/user-guide/concepts/themes) bawaan, + dukungan untuk tema personal pengguna +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + dan [impor & ekspor + markdown](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Penyemat Web](https://docs.triliumnotes.org/user-guide/setup/web-clipper) + untuk memudahkan pencatatan konten web +* "UI yang dapat dikustomisasi (tombol sidebar, widget kustom, ...)" +* [Berbagai + Metrik](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics) yang + dipadukan dengan Dashboard Grafana. + +✨ Cek lebih lanjut sumber daya/komunitas pihak ke-tiga untuk menikmati lebih +lanjut TriliumNext: + +- [trilium-beken](https://github.com/Nriver/awesome-trilium) untuk banyak tema, + skrip, plugin pihak ke-3 dan lain-lain. +- [TriliumJaya!](https://trilium.rocks/) untuk tutorial, panduan dan lainnya. + +## ā“Mengapa TriliumNext? + +Pengembang asli Trilium ([Zadam](https://github.com/zadam)) dengan murah hati +telah memberikan repositori Trilium kepada proyek komunitas yang berada di +https://github.com/TriliumNext + +### ā¬†ļø Memindahkan dari Zadam/Trilium? + +Tidak ada langkah migrasi khusus untuk bermigrasi dari zadam/Trilium ke +TriliumNext/Trilium. Cukup [instal TriliumNext/Trilium](#-installation) seperti +biasa dan akan menggunakan basis data yang sudah ada. + +Versi hingga +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) +kompatibel dengan versi Zadam/Trilium terbaru yaitu +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Versi +TriliumNext/Trilium yang lebih baru memiliki versi sinkronisasi yang +ditingkatkan sehingga mencegah migrasi langsung. + +## šŸ’¬ Mari berdiskusi dengan kami + +Jangan ragu untuk bergabung dalam percakapan resmi kami. Kami ingin sekali +mendengar fitur, saran, atau masalah apa pun yang mungkin Anda miliki! + +- [Matriks](https://matrix.to/#/#triliumnext:matrix.org) (Untuk diskusi + sinkron.) + - Ruang Matriks `Umum` juga terhubung ke + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Diskusi Github](https://github.com/TriliumNext/Trilium/discussions) (Untuk + diskusi asinkron.) +- [Masalah GitHub](https://github.com/TriliumNext/Trilium/issues) (Untuk laporan + bug dan permintaan fitur.) + +## šŸ— Instalasi + +### Windows / MacOS + +Unduh rilis biner untuk platform Anda dari [halaman rilis +terbaru](https://github.com/TriliumNext/Trilium/releases/latest), ekstrak +package dan jalankan file executable `trilium`. + +### Linux + +Jika distribusi Anda tercantum dalam tabel di bawah ini, gunakan package dari +distribusi Anda tersebut. + +[![Status +packaging](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +Anda juga dapat mengunduh rilis biner untuk platform Anda dari [halaman rilis +terbaru](https://github.com/TriliumNext/Trilium/releases/latest), ekstrak +package-nya dan jalankan file executable `trilium`. + +TriliumNext juga tersedia sebagai Flatpak, namun belum dipublikasikan di +FlatHub. + +### Browser (OS apapun) + +Jika Anda menggunakan instalasi server (lihat di bawah), Anda dapat langsung +mengakses antarmuka web (yang hampir identik dengan aplikasi desktop). + +Saat ini hanya Chrome & Firefox versi terbaru yang didukung (dan telah diuji). + +### Ponsel + +Untuk menggunakan TriliumNext pada perangkat seluler, Anda dapat menggunakan +peramban web seluler untuk mengakses antarmuka seluler dari instalasi server +(lihat di bawah). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium tidak akan ada tanpa teknologi-teknologi di balik berikut: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - editor visual dibalik + catatan teks. Kami sangat berterima kasih diberikan fitur-fitur editor yang + premium. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - editor kode dengan + dukungan banyak bahasa pemrograman. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - area catatan tanpa + batas yang dipakai di catatan Kanvas. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - memberikan + fungsionalitas peta pikiran(mind map). +* [Leaflet](https://github.com/Leaflet/Leaflet) - untuk render peta geografikal. +* [Tabulator](https://github.com/olifolkerd/tabulator) - untuk tabel interaktif + yang dipakai di koleksi catatan. +* [FancyTree](https://github.com/mar10/fancytree) - library pohon yang kaya akan + fitur tanpa ada saingan. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - library konektivitas visual. + Dipakai di [peta + relasi](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [peta + hubungan](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Dukungan + +Trilium dibangun dan diperlihara oleh [banyak developer dan +waktu](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Dukungan +Anda yang membuat Trilium open-source, menambah dan mengembangkan fitur, juga +menutupi beban biaya hosting kami. + +Berikan dukungan ke developer utama +([eliandoran](https://github.com/eliandoran)) melalui: + +- [Sponsor-Sponsor GitHub](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-it.md b/docs/README-it.md new file mode 100644 index 0000000000..b47c8ae0e4 --- /dev/null +++ b/docs/README-it.md @@ -0,0 +1,352 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![Sponsor GitHub](https://img.shields.io/github/sponsors/eliandoran) +![Sostenitori LiberaPay](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Pull Docker](https://img.shields.io/docker/pulls/triliumnext/trilium) +![Download GitHub (tutte le risorse, tutte le +versioni)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Stato della +traduzione](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes ĆØ un'applicazione per appunti ad organizzazione gerarchica, +studiata per la costruzione di archivi di conoscenza personali di grandi +dimensioni. + +Trilium Screenshot + +## ā¬ Scarica +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + versione stabile, consigliata per la maggior parte degli utenti. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + versione di sviluppo instabile, aggiornata quotidianamente con le ultime + funzionalitĆ  e correzioni. + +## šŸ“š Documentazione + +**Vedi tutta la documentazione su +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +La nostra documentazione ĆØ disponibile in diversi formati: +- **Documentazione online**: consulta la documentazione completa all'indirizzo + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Guida in-app**: premi `F1` all'interno di Trilium per accedere alla stessa + documentazione direttamente nell'applicazione +- **GitHub**: consulta la [Guida utente](./User%20Guide/User%20Guide/) in questo + repository + +### Collegamenti rapidi +- [Guida introduttiva](https://docs.triliumnotes.org/) +- [Istruzioni per + l'installazione](https://docs.triliumnotes.org/user-guide/setup) +- [Configurazione + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Aggiornamento di + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Concetti e caratteristiche di + base](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Modelli di base di conoscenza + personale](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Caratteristiche + +* Le note possono essere organizzate in una struttura ad albero con profonditĆ  + arbitrarie. Una singola nota può essere inserita in più posizioni all'interno + della struttura (vedi + [clonazione](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Editor di note WYSIWYG avanzato che include, ad esempio, tabelle, immagini e + [math](https://docs.triliumnotes.org/user-guide/note-types/text) con markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Supporto per la modifica di [note con codice + sorgente](https://docs.triliumnotes.org/user-guide/note-types/code), inclusa + l'evidenziazione della sintassi +* Navigazione veloce e facile tra le note, ricerca full-text e ancoraggio delle + note +* Senza soluzione di continuitĆ  [nota + versione](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Nota + [attributi](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + può essere utilizzato per l'organizzazione delle note, l'esecuzione di query e + lo [scripting](https://docs.triliumnotes.org/user-guide/scripts) avanzato +* Interfaccia utente disponibile in inglese, tedesco, spagnolo, francese, rumeno + e cinese (semplificato e tradizionale) +* Integrazione diretta [OpenID e + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) per un + accesso più sicuro +* [Sincronizzazione](https://docs.triliumnotes.org/user-guide/setup/synchronization) + con server di sincronizzazione self-hosted + * esistono [servizi di terze parti per l'hosting del server di + sincronizzazione](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Condivisione](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (pubblicazione) di note su Internet pubblicamente +* Crittografia forte + [note](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + con granularitĆ  per singola nota +* Disegnare diagrammi, basati su [Excalidraw](https://excalidraw.com/) (tipo di + nota ā€œcanvasā€) +* [Mappe + relazionali](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + e [mappe + note/link](https://docs.triliumnotes.org/user-guide/note-types/note-map) per + visualizzare le note e le loro relazioni +* Mappe mentali, basate su [Mind Elixir](https://docs.mind-elixir.com/) +* [Mappe + geografiche](https://docs.triliumnotes.org/user-guide/collections/geomap) con + indicatori di posizione e tracciati GPX +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - vedi [Esempi + avanzati](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) per + l'automazione +* Ottima scalabilitĆ  sia in termini di usabilitĆ  che di prestazioni fino a oltre + 100.000 note +* Frontend mobile ottimizzato per il touch [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) per + smartphone e tablet +* Tema scuro integrato + (https://docs.triliumnotes.org/user-guide/concepts/themes), supporto per temi + utente +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + e [Importazione ed esportazione + Markdown](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) per + salvare facilmente i contenuti web +* Interfaccia utente personalizzabile (pulsanti della barra laterale, widget + definiti dall'utente, ...) +* [Metriche](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + insieme a una dashboard Grafana. + +✨ Dai un'occhiata alle seguenti risorse/comunitĆ  di terze parti per ulteriori +informazioni su TriliumNext: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) per temi, script, + plugin e altro di terze parti. +- [TriliumRocks!](https://trilium.rocks/) per tutorial, guide e molto altro + ancora. + +## ā“PerchĆ© TriliumNext? + +Lo sviluppatore originale di Trilium ([Zadam](https://github.com/zadam)) ha +gentilmente fornito il repository Trilium al progetto comunitario che risiede +all'indirizzo https://github.com/TriliumNext + +### ā¬†ļøMigrazione da Zadam/Trilium? + +Non sono necessarie procedure di migrazione particolari per passare da +un'istanza zadam/Trilium a un'istanza TriliumNext/Trilium. ƈ sufficiente +[installare TriliumNext/Trilium](#-installation) come di consueto e verrĆ  +utilizzato il database esistente. + +Le versioni fino alla +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) inclusa +sono compatibili con l'ultima versione zadam/trilium +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Tutte le +versioni successive di TriliumNext/Trilium hanno versioni di sincronizzazione +incrementate che impediscono la migrazione diretta. + +## šŸ’¬ Discuti con noi + +Non esitare a partecipare alle nostre conversazioni ufficiali. Ci piacerebbe +conoscere le tue opinioni su funzionalitĆ , suggerimenti o problemi! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Per discussioni + sincronizzate.) + - La stanza Matrix `Generale` ĆØ anche collegata a + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Discussioni su GitHub](https://github.com/TriliumNext/Trilium/discussions) + (Per discussioni asincrone.) +- [Problemi su GitHub](https://github.com/TriliumNext/Trilium/issues) (Per + segnalazioni di bug e richieste di funzionalitĆ .) + +## šŸ— Installazione + +### Windows / MacOS + +Scarica la versione binaria per la tua piattaforma dalla [pagina delle ultime +versioni](https://github.com/TriliumNext/Trilium/releases/latest), decomprimi il +pacchetto ed esegui il file eseguibile `trilium`. + +### Linux + +Se la tua distribuzione ĆØ elencata nella tabella sottostante, utilizza il +pacchetto della tua distribuzione. + +[![Stato del +Packaging](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +ƈ anche possibile scaricare la versione binaria per la propria piattaforma dalla +[pagina delle ultime +versioni](https://github.com/TriliumNext/Trilium/releases/latest), decomprimere +il pacchetto ed eseguire il file eseguibile `trilium`. + +TriliumNext ĆØ disponibile anche come Flatpak, ma non ĆØ ancora stato pubblicato +su FlatHub. + +### Browser (qualsiasi sistema operativo) + +Se utilizzi un'installazione server (vedi sotto), puoi accedere direttamente +all'interfaccia web (che ĆØ quasi identica all'applicazione desktop). + +Attualmente sono supportate (e testate) solo le ultime versioni di Chrome e +Firefox. + +### Cellulare + +Per utilizzare TriliumNext su un dispositivo mobile, ĆØ possibile utilizzare un +browser web mobile per accedere all'interfaccia mobile di un'installazione +server (vedere sotto). + +Per ulteriori informazioni sul supporto delle app mobili, consultare il numero +https://github.com/TriliumNext/Trilium/issues/4962. + +Se preferisci un'app Android nativa, puoi utilizzare +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Segnala bug e funzionalitĆ  mancanti al [loro +repository](https://github.com/FliegendeWurst/TriliumDroid). Nota: quando +utilizzi TriliumDroid, ĆØ consigliabile disabilitare gli aggiornamenti automatici +sull'installazione del server (vedi sotto), poichĆ© la versione di +sincronizzazione deve corrispondere tra Trilium e TriliumDroid. + +### Server + +Per installare TriliumNext sul proprio server (anche tramite Docker da +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)), seguire [le +istruzioni per l'installazione sul +server](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribuire + +### Traduzioni + +Se sei un madrelingua, aiutaci a tradurre Trilium visitando la nostra [pagina +Weblate](https://hosted.weblate.org/engage/trilium/). + +Ecco le lingue attualmente disponibili: + +[![Stato della +traduzione](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Codice + +Scarica il repository, installa le dipendenze utilizzando `pnpm` e quindi avvia +il server (disponibile all'indirizzo http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentazione + +Scarica il repository, installa le dipendenze utilizzando `pnpm` e quindi esegui +l'ambiente necessario per modificare la documentazione: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Compilare l'eseguibile +Scarica la repository, installa le dipendenze eseguendo `pnpm` e compila +l'applicazione desktop per Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Per più dettagli, consulta la [documentazione di +sviluppo](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Documentazione per sviluppatori + +Visualizza la [guida sulla +documentazione](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +per i dettagli. Se hai altre domande, sentiti libero di contattarci tramite i +collegamenti presenti nella precedente sezione "Discuti con noi". + +## šŸ‘ Riconoscimenti + +* [zadam](https://github.com/zadam) per l'idea originale e l'implementazione + della applicazione. +* [Sarah Hussein](https://github.com/Sarah-Hussein) per il design della icona + della applicazione. +* [nriver](https://github.com/nriver) per il suo lavoro + sull'internazionalizzazione. +* [Thomas Frei](https://github.com/thfrei) per il suo lavoro originale sul + canvas. +* [antoniotejada](https://github.com/nriver) per lo strumento originale di + colorazione della sintassi. +* [Dosu](https://dosu.dev/) per averci fornito le risposte automatiche alle + questioni e alle discussioni su GitHub. +* [Tabler Icons](https://tabler.io/icons) per le icone della barra delle + applicazioni. + +Trilium non sarebbe possibile senza le tecnologie che lo supportano: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - l'editor visivo dietro + le note di testo. Siamo grati per averci offerto una serie di funzionalitĆ  + premium. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - editor di codice con + supporto per un'ampia gamma di linguaggi. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - la lavagna infinita + utilizzata nelle note di Canvas. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - fornendo la + funzionalitĆ  di mappa mentale. +* [Leaflet](https://github.com/Leaflet/Leaflet) - per la rappresentazione di + mappe geografiche. +* [Tabulator](https://github.com/olifolkerd/tabulator) - per la tabella + interattiva utilizzata nelle raccolte. +* [FancyTree](https://github.com/mar10/fancytree) - libreria ad albero ricca di + funzionalitĆ  senza reale concorrenza. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - libreria di connettivitĆ  + visiva. Utilizzata in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) e + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Supporto + +Trilium ĆØ realizzato e gestito con [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Il tuo +sostegno contribuisce a mantenerlo open source, a migliorarne le funzionalitĆ  e +a coprire i costi, come quelli di hosting. + +Considera la possibilitĆ  di sostenere lo sviluppatore principale +([eliandoran](https://github.com/eliandoran)) dell'applicazione tramite: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ Licenza + +Copyright 2017-2025 zadam, Elian Doran, e altri collaboratori + +Questo programma ĆØ software libero: ĆØ possibile redistribuirlo e/o modificarlo +nei termini della GNU Affero General Public License come pubblicata dalla Free +Software Foundation, sia la versione 3 della Licenza, o (a propria scelta) +qualsiasi versione successiva. diff --git a/docs/README-ja.md b/docs/README-ja.md new file mode 100644 index 0000000000..6804c08b7c --- /dev/null +++ b/docs/README-ja.md @@ -0,0 +1,289 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ +(å…Øć‚¢ć‚»ćƒƒćƒˆć€å…ØćƒŖćƒŖćƒ¼ć‚¹)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![翻訳状況](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes +ćÆć€å¤§č¦ęØ”ćŖå€‹äŗŗēŸ„č­˜ćƒ™ćƒ¼ć‚¹ć®ę§‹ēÆ‰ć«é‡ē‚¹ć‚’ē½®ć„ćŸć€ē„”ę–™ć‹ć¤ć‚Ŗćƒ¼ćƒ—ćƒ³ć‚½ćƒ¼ć‚¹ć®ć‚Æćƒ­ć‚¹ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć®éšŽå±¤åž‹ćƒŽćƒ¼ćƒˆä½œęˆć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć§ć™ć€‚ + +Trilium Screenshot + +## ā¬ ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ +- [ęœ€ę–°ćƒŖćƒŖćƒ¼ć‚¹](https://github.com/TriliumNext/Trilium/releases/latest) – + å®‰å®šćƒćƒ¼ć‚øćƒ§ćƒ³ć€‚ć»ćØć‚“ć©ć®ćƒ¦ćƒ¼ć‚¶ćƒ¼ć«ęŽØå„Øć•ć‚Œć¾ć™ć€‚ +- [ćƒŠć‚¤ćƒˆćƒŖćƒ¼ćƒ“ćƒ«ćƒ‰](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + äøå®‰å®šćŖé–‹ē™ŗćƒćƒ¼ć‚øćƒ§ćƒ³ć€‚ęœ€ę–°ć®ę©Ÿčƒ½ćØäæ®ę­£ćŒęÆŽę—„ę›“ę–°ć•ć‚Œć¾ć™ć€‚ + +## šŸ“š ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ + +**åŒ…ę‹¬ēš„ćŖćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆćÆ [docs.triliumnotes.org](https://docs.triliumnotes.org/) ć§ć”č¦§ćć ć•ć„** + +å½“ē¤¾ć®ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆćÆč¤‡ę•°ć®å½¢å¼ć§ć”åˆ©ē”Øć„ćŸć ć‘ć¾ć™: +- **ć‚Ŗćƒ³ćƒ©ć‚¤ćƒ³ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ**: [docs.triliumnotes.org](https://docs.triliumnotes.org/) + ć§å®Œå…ØćŖćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’å‚ē…§ć—ć¦ćć ć•ć„ +- **ć‚¢ćƒ—ćƒŖå†…ćƒ˜ćƒ«ćƒ—**: Trilium内で `F1` ć‚­ćƒ¼ć‚’ęŠ¼ć™ćØć€ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³å†…ć§åŒć˜ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć«ē›“ęŽ„ć‚¢ć‚Æć‚»ć‚¹ć§ćć¾ć™ +- **GitHub**: ć“ć®ćƒŖćƒć‚øćƒˆćƒŖć® [ćƒ¦ćƒ¼ć‚¶ćƒ¼ć‚¬ć‚¤ćƒ‰](./User%20Guide/User%20Guide/) ć‚’å‚ē…§ć—ć¦ćć ć•ć„ + +### ć‚Æć‚¤ćƒƒć‚ÆćƒŖćƒ³ć‚Æ +- [ć‚¹ć‚æćƒ¼ćƒˆć‚¬ć‚¤ćƒ‰](https://docs.triliumnotes.org/) +- [ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ę‰‹é †](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + ć®ć‚»ćƒƒćƒˆć‚¢ćƒƒćƒ—](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [TriliumNext + ć®ć‚¢ćƒƒćƒ—ć‚°ćƒ¬ćƒ¼ćƒ‰](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [åŸŗęœ¬ę¦‚åæµćØę©Ÿčƒ½](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [å€‹äŗŗćƒŠćƒ¬ćƒƒć‚øćƒ™ćƒ¼ć‚¹ć®ćƒ‘ć‚æćƒ¼ćƒ³](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ 機能 + +* ćƒŽćƒ¼ćƒˆćÆä»»ę„ć®ę·±ć•ć®ćƒ„ćƒŖćƒ¼ć«é…ē½®ć§ćć¾ć™ć€‚1ć¤ć®ćƒŽćƒ¼ćƒˆć‚’ćƒ„ćƒŖćƒ¼å†…ć®č¤‡ę•°ć®å “ę‰€ć«é…ē½®ć§ćć¾ć™ļ¼ˆ[ć‚Æćƒ­ćƒ¼ćƒ³](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)ć‚’å‚ē…§ļ¼‰ +* 豊富な WYSIWYG ćƒŽćƒ¼ćƒˆć‚Øćƒ‡ć‚£ć‚æćƒ¼ 例: + č”Øć€ē”»åƒć€[ę•°å¼](https://docs.triliumnotes.org/user-guide/note-types/text) ćØćƒžćƒ¼ć‚Æćƒ€ć‚¦ćƒ³ + [č‡Ŗå‹•ćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆ](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) + など +* ę§‹ę–‡ćƒć‚¤ćƒ©ć‚¤ćƒˆč”Øē¤ŗć‚’å«ć‚€ + [ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ä»˜ććƒŽćƒ¼ćƒˆ](https://docs.triliumnotes.org/user-guide/note-types/code) + ć®ē·Øé›†ć‚’ć‚µćƒćƒ¼ćƒˆ +* [ćƒŽćƒ¼ćƒˆé–“ć®ćƒŠćƒ“ć‚²ćƒ¼ć‚·ćƒ§ćƒ³](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation)ć€å…Øę–‡ę¤œē“¢ć€[ćƒŽćƒ¼ćƒˆć®ćƒ›ć‚¤ć‚¹ćƒˆ](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) + ćŒé«˜é€Ÿć‹ć¤ē°”å˜ć«č”Œćˆć¾ć™ +* ć‚·ćƒ¼ćƒ ćƒ¬ć‚¹ćŖ + [ćƒŽćƒ¼ćƒˆć®ćƒćƒ¼ć‚øćƒ§ćƒ³ē®”ē†](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* ćƒŽćƒ¼ćƒˆ[å±žę€§](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + ćÆć€ćƒŽćƒ¼ćƒˆć®ę•“ē†ć€ć‚Æć‚ØćƒŖć€é«˜åŗ¦ćŖ [ć‚¹ć‚ÆćƒŖćƒ—ćƒˆ](https://docs.triliumnotes.org/user-guide/scripts) + ć«ä½æē”Øć§ćć¾ć™ +* UI ćÆč‹±čŖžć€ćƒ‰ć‚¤ćƒ„čŖžć€ć‚¹ćƒšć‚¤ćƒ³čŖžć€ćƒ•ćƒ©ćƒ³ć‚¹čŖžć€ćƒ«ćƒ¼ćƒžćƒ‹ć‚¢čŖžć€äø­å›½čŖžļ¼ˆē°”ä½“å­—ćŠć‚ˆć³ē¹ä½“å­—ļ¼‰ć§ć”åˆ©ē”Øć„ćŸć ć‘ć¾ć™ +* ć‚ˆć‚Šå®‰å…ØćŖćƒ­ć‚°ć‚¤ćƒ³ć®ćŸć‚ć®ē›“ęŽ„ēš„ćŖ + [OpenIDとTOTPの統合](https://docs.triliumnotes.org/user-guide/setup/server/mfa) +* ć‚»ćƒ«ćƒ•ćƒ›ć‚¹ćƒˆåŒęœŸć‚µćƒ¼ćƒćƒ¼ćØć® + [同期](https://docs.triliumnotes.org/user-guide/setup/synchronization) + * [åŒęœŸć‚µćƒ¼ćƒćƒ¼ć‚’ćƒ›ć‚¹ćƒˆć™ć‚‹ćŸć‚ć®ć‚µćƒ¼ćƒ‰ćƒ‘ćƒ¼ćƒ†ć‚£ć‚µćƒ¼ćƒ“ć‚¹](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting)ćŒć‚ć‚Šć¾ć™ +* ć‚¤ćƒ³ć‚æćƒ¼ćƒćƒƒćƒˆäøŠć§ćƒŽćƒ¼ćƒˆć® + [å…±ęœ‰](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing)ļ¼ˆå…¬é–‹ļ¼‰ +* ćƒŽćƒ¼ćƒˆć”ćØć«čŖæę•“åÆčƒ½ć§å¼·åŠ›ćŖ + [ćƒŽćƒ¼ćƒˆęš—å·åŒ–](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) +* [Excalidraw](https://excalidraw.com/) ć‚’ćƒ™ćƒ¼ć‚¹ć«ć—ćŸå›³ć®ć‚¹ć‚±ćƒƒćƒļ¼ˆćƒŽćƒ¼ćƒˆć‚æć‚¤ćƒ—ć€Œć‚­ćƒ£ćƒ³ćƒć‚¹ć€ļ¼‰ +* ćƒŽćƒ¼ćƒˆćØćć®é–¢äæ‚ć‚’č¦–č¦šåŒ–ć™ć‚‹ćŸć‚ć®[ćƒŖćƒ¬ćƒ¼ć‚·ćƒ§ćƒ³ćƒžćƒƒćƒ—](https://docs.triliumnotes.org/user-guide/note-types/relation-map)と[ćƒŽćƒ¼ćƒˆ/ćƒŖćƒ³ć‚Æćƒžćƒƒćƒ—](https://docs.triliumnotes.org/user-guide/note-types/note-map) +* [Mind Elixir](https://docs.mind-elixir.com/) ć‚’ćƒ™ćƒ¼ć‚¹ćØć—ćŸćƒžć‚¤ćƒ³ćƒ‰ćƒžćƒƒćƒ— +* ä½ē½®ćƒ”ćƒ³ćØ GPX ćƒˆćƒ©ćƒƒć‚Æä»˜ćć® + [ć‚øć‚Ŗćƒžćƒƒćƒ—](https://docs.triliumnotes.org/user-guide/collections/geomap) +* [ć‚¹ć‚ÆćƒŖćƒ—ćƒˆ](https://docs.triliumnotes.org/user-guide/scripts) - + [é«˜åŗ¦ćŖć‚·ćƒ§ćƒ¼ć‚±ćƒ¼ć‚¹](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) + ć‚’å‚ē…§ +* č‡Ŗå‹•åŒ–ć®ćŸć‚ć® [REST + API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) +* 10äø‡ä»¶ä»„äøŠć®ćƒŽćƒ¼ćƒˆć§ć‚‚ć€ä½æć„ć‚„ć™ć•ćØćƒ‘ćƒ•ć‚©ćƒ¼ćƒžćƒ³ć‚¹ć®äø”é¢ć«å„Ŗć‚ŒćŸę‹”å¼µę€§ć‚’å®Ÿē¾ +* ć‚¹ćƒžćƒ¼ćƒˆćƒ•ć‚©ćƒ³ćØć‚æćƒ–ćƒ¬ćƒƒćƒˆå‘ć‘ć«ć‚æćƒƒćƒę“ä½œć«ęœ€é©åŒ–ć•ć‚ŒćŸ + [ćƒ¢ćƒć‚¤ćƒ«ćƒ•ćƒ­ćƒ³ćƒˆć‚Øćƒ³ćƒ‰](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) +* 組み込みの + [ćƒ€ćƒ¼ć‚Æćƒ†ćƒ¼ćƒž](https://docs.triliumnotes.org/user-guide/concepts/themes)ć€ćƒ¦ćƒ¼ć‚¶ćƒ¼ćƒ†ćƒ¼ćƒžć®ć‚µćƒćƒ¼ćƒˆ +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + と [Markdown + ć®ć‚¤ćƒ³ćƒćƒ¼ćƒˆćØć‚Øć‚Æć‚¹ćƒćƒ¼ćƒˆ](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) 恧 + web ć‚³ćƒ³ćƒ†ćƒ³ćƒ„ć‚’ē°”å˜ć«äæå­˜ +* ć‚«ć‚¹ć‚æćƒžć‚¤ć‚ŗåÆčƒ½ćŖ UI (ć‚µć‚¤ćƒ‰ćƒćƒ¼ ćƒœć‚æćƒ³ć€ćƒ¦ćƒ¼ć‚¶ćƒ¼å®šē¾©ć®ć‚¦ć‚£ć‚øć‚§ćƒƒćƒˆćŖć©) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics) と + Grafana ćƒ€ćƒƒć‚·ćƒ„ćƒœćƒ¼ćƒ‰ć€‚ + +✨ TriliumNext é–¢é€£ć®ćć®ä»–ć®ęƒ…å ±ć«ć¤ć„ć¦ćÆć€ę¬”ć®ć‚µćƒ¼ćƒ‰ćƒ‘ćƒ¼ćƒ†ć‚£ć®ćƒŖć‚½ćƒ¼ć‚¹/ć‚³ćƒŸćƒ„ćƒ‹ćƒ†ć‚£ć‚’ć”č¦§ćć ć•ć„: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) + ć‚µćƒ¼ćƒ‰ćƒ‘ćƒ¼ćƒ†ć‚£ć®ćƒ†ćƒ¼ćƒžć€ć‚¹ć‚ÆćƒŖćƒ—ćƒˆć€ćƒ—ćƒ©ć‚°ć‚¤ćƒ³ćŖć©ć€‚ +- [TriliumRocks!](https://trilium.rocks/) ć§ćÆćƒćƒ„ćƒ¼ćƒˆćƒŖć‚¢ćƒ«ć‚„ć‚¬ć‚¤ćƒ‰ćŖć©ć€ćć®ä»–å¤šę•°ć€‚ + +## ā“ćŖćœTriliumNext ćŖć®ć‹ļ¼Ÿ + +ć‚ŖćƒŖć‚øćƒŠćƒ«ć® Trilium 開発者 ([Zadam](https://github.com/zadam)) +は、https://github.com/TriliumNext ć«ć‚ć‚‹ć‚³ćƒŸćƒ„ćƒ‹ćƒ†ć‚£ćƒ—ćƒ­ć‚øć‚§ć‚Æćƒˆć« Trilium ćƒŖćƒć‚øćƒˆćƒŖć‚’åæ«ćęä¾›ć—ć¦ćć‚Œć¾ć—ćŸ + +### ā¬†ļøZadam/Trilium ć‹ć‚‰ē§»č”Œć—ć¾ć™ć‹? + +zadam/Trilium ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć‹ć‚‰ TriliumNext/Trilium ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ćøć®ē§»č”Œć«ćÆē‰¹åˆ„ćŖę‰‹é †ćÆć‚ć‚Šć¾ć›ć‚“ć€‚é€šåøøé€šć‚Š +[TriliumNext/Triliumć‚’ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«](#-installation) ć™ć‚‹ć ć‘ć§ć€ę—¢å­˜ć®ćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ćŒä½æē”Øć•ć‚Œć¾ć™ć€‚ + +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) +ć¾ć§ć®ćƒćƒ¼ć‚øćƒ§ćƒ³ćÆć€ęœ€ę–°ć® zadam/trilium ćƒćƒ¼ć‚øćƒ§ćƒ³ +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7) +ćØäŗ’ę›ę€§ćŒć‚ć‚Šć¾ć™ć€‚ćć‚Œä»„é™ć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć® TriliumNext/Trilium ć§ćÆåŒęœŸćƒćƒ¼ć‚øćƒ§ćƒ³ćŒć‚¤ćƒ³ć‚ÆćƒŖćƒ”ćƒ³ćƒˆć•ć‚Œć‚‹ćŸć‚ć€ē›“ęŽ„ē§»č”Œć™ć‚‹ć“ćØćÆć§ćć¾ć›ć‚“ć€‚ + +## šŸ’¬ ē§ćŸć”ćØč­°č«–ć—ć¾ć—ć‚‡ć† + +ćœć²å…¬å¼ć®ä¼šč©±ć«ć”å‚åŠ ćć ć•ć„ć€‚ę©Ÿčƒ½ć«é–¢ć™ć‚‹ć”ę„č¦‹ć€ć”ęę”ˆć€å•é”ŒćŖć©ć€ćœć²ćŠčžć‹ć›ćć ć•ć„ļ¼ + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) ļ¼ˆåŒęœŸćƒ‡ć‚£ć‚¹ć‚«ćƒƒć‚·ćƒ§ćƒ³ē”Øļ¼‰ + - `General`ćƒžćƒˆćƒŖćƒƒć‚Æć‚¹ćƒ«ćƒ¼ćƒ ć‚‚ [XMPP](xmpp:discuss@trilium.thisgreat.party?join) + ć«ćƒ–ćƒŖćƒƒć‚øć•ć‚Œć¦ć„ć¾ć™ +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) + (éžåŒęœŸćƒ‡ć‚£ć‚¹ć‚«ćƒƒć‚·ćƒ§ćƒ³ē”Ø) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) + (ćƒć‚°ćƒ¬ćƒćƒ¼ćƒˆć‚„ę©Ÿčƒ½ćƒŖć‚Æć‚Øć‚¹ćƒˆē”Ø) + +## šŸ— ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ« + +### Windows / MacOS + +[ęœ€ę–°ćƒŖćƒŖćƒ¼ć‚¹ ćƒšćƒ¼ć‚ø](https://github.com/TriliumNext/Trilium/releases/latest) +ć‹ć‚‰ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ē”Øć®ćƒć‚¤ćƒŠćƒŖ ćƒŖćƒŖćƒ¼ć‚¹ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ć—ć€ćƒ‘ćƒƒć‚±ćƒ¼ć‚øć‚’č§£å‡ć—ć¦ `trilium` å®Ÿč”ŒåÆčƒ½ćƒ•ć‚”ć‚¤ćƒ«ć‚’å®Ÿč”Œć—ć¾ć™ć€‚ + +### Linux + +ćƒ‡ć‚£ć‚¹ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚·ćƒ§ćƒ³ćŒä»„äø‹ć®č”Øć«čØ˜č¼‰ć•ć‚Œć¦ć„ć‚‹å “åˆćÆć€ćƒ‡ć‚£ć‚¹ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚·ćƒ§ćƒ³ć®ćƒ‘ćƒƒć‚±ćƒ¼ć‚øć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +[ęœ€ę–°ćƒŖćƒŖćƒ¼ć‚¹ ćƒšćƒ¼ć‚ø](https://github.com/TriliumNext/Trilium/releases/latest) +ć‹ć‚‰ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ē”Øć®ćƒć‚¤ćƒŠćƒŖ ćƒŖćƒŖćƒ¼ć‚¹ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ć—ć€ćƒ‘ćƒƒć‚±ćƒ¼ć‚øć‚’č§£å‡ć—ć¦ `trilium` å®Ÿč”ŒåÆčƒ½ćƒ•ć‚”ć‚¤ćƒ«ć‚’å®Ÿč”Œć™ć‚‹ć“ćØć‚‚ć§ćć¾ć™ć€‚ + +TriliumNext は Flatpak ćØć—ć¦ć‚‚ęä¾›ć•ć‚Œć¦ć„ć¾ć™ćŒć€FlatHub ć§ćÆć¾ć å…¬é–‹ć•ć‚Œć¦ć„ć¾ć›ć‚“ć€‚ + +### ćƒ–ćƒ©ć‚¦ć‚¶ļ¼ˆć©ć®OSでも) + +ć‚µćƒ¼ćƒćƒ¼ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ« (äø‹čØ˜å‚ē…§) ć‚’ä½æē”Øć™ć‚‹å “åˆćÆć€web ć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ć‚¤ć‚¹ (ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć‚¢ćƒ—ćƒŖćØć»ć¼åŒć˜) ć«ē›“ęŽ„ć‚¢ć‚Æć‚»ć‚¹ć§ćć¾ć™ć€‚ + +ē¾åœØć€Chrome と Firefox ć®ęœ€ę–°ćƒćƒ¼ć‚øćƒ§ćƒ³ć®ćæćŒć‚µćƒćƒ¼ćƒˆ (ćŠć‚ˆć³ćƒ†ć‚¹ćƒˆ) ć•ć‚Œć¦ć„ć¾ć™ć€‚ + +### ćƒ¢ćƒć‚¤ćƒ« + +ćƒ¢ćƒć‚¤ćƒ«ćƒ‡ćƒć‚¤ć‚¹ć§ TriliumNext ć‚’ä½æē”Øć™ć‚‹ć«ćÆć€ćƒ¢ćƒć‚¤ćƒ« web +ćƒ–ćƒ©ć‚¦ć‚¶ćƒ¼ć‚’ä½æē”Øć—ć¦ć€ć‚µćƒ¼ćƒćƒ¼ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć®ćƒ¢ćƒć‚¤ćƒ«ć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ć‚¤ć‚¹ć«ć‚¢ć‚Æć‚»ć‚¹ć§ćć¾ć™ (ä»„äø‹ć‚’å‚ē…§)怂 + +ćƒ¢ćƒć‚¤ćƒ«ć‚¢ćƒ—ćƒŖć®ć‚µćƒćƒ¼ćƒˆć®č©³ē“°ć«ć¤ć„ć¦ćÆć€issue https://github.com/TriliumNext/Trilium/issues/4962 +ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ćƒć‚¤ćƒ†ć‚£ćƒ–Androidć‚¢ćƒ—ćƒŖć‚’ć”åøŒęœ›ć®å “åˆćÆć€[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid) +ć‚’ć”åˆ©ē”Øć„ćŸć ć‘ć¾ć™ć€‚ćƒć‚°ć‚„äøč¶³ć—ć¦ć„ć‚‹ę©Ÿčƒ½ćÆ [ćƒŖćƒć‚øćƒˆćƒŖ](https://github.com/FliegendeWurst/TriliumDroid) +ć§ć”å ±å‘Šćć ć•ć„ć€‚ę³Øļ¼šTriliumDroidć‚’ä½æē”Øć™ć‚‹å “åˆćÆć€TriliumとTriliumDroidć®åŒęœŸćƒćƒ¼ć‚øćƒ§ćƒ³ćŒäø€č‡“ć—ć¦ć„ć‚‹åæ…č¦ćŒć‚ć‚‹ćŸć‚ć€ć‚µćƒ¼ćƒćƒ¼ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć§č‡Ŗå‹•ę›“ę–°ć‚’ē„”åŠ¹ć«ć™ć‚‹ć“ćØć‚’ćŠå‹§ć‚ć—ć¾ć™ļ¼ˆäø‹čØ˜å‚ē…§ļ¼‰ć€‚ + +### ć‚µćƒ¼ćƒćƒ¼ + +ē‹¬č‡Ŗć®ć‚µćƒ¼ćƒćƒ¼ć« TriliumNext ć‚’ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć™ć‚‹ć«ćÆ +([Dockerhub](https://hub.docker.com/r/triliumnext/trilium) 恋悉 Docker +ēµŒē”±ć§ć‚‚å«ć‚€)态[ć‚µćƒ¼ćƒćƒ¼ć®ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ« +ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ](https://docs.triliumnotes.org/user-guide/setup/server) ć«å¾“ć£ć¦ćć ć•ć„ć€‚ + + +## šŸ’» č²¢ēŒ®ć™ć‚‹ + +### 翻訳 + +ćƒć‚¤ćƒ†ć‚£ćƒ–ć‚¹ćƒ”ćƒ¼ć‚«ćƒ¼ć®ę–¹ćÆć€[Weblate ćƒšćƒ¼ć‚ø](https://hosted.weblate.org/engage/trilium/) +にアクセスして、Trilium ć®ēæ»čØ³ć«ć”å”åŠ›ćć ć•ć„ć€‚ + +ć“ć‚Œć¾ć§ć«ć‚«ćƒćƒ¼ć•ć‚Œć¦ć„ć‚‹čØ€čŖžćÆę¬”ć®ćØćŠć‚Šć§ć™: + +[![翻訳状況](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### ć‚³ćƒ¼ćƒ‰ + +ćƒŖćƒć‚øćƒˆćƒŖć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ć—ć€`pnpm` ć‚’ä½æē”Øć—ć¦ä¾å­˜é–¢äæ‚ć‚’ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć—ć¦ć‹ć‚‰ć€ć‚µćƒ¼ćƒćƒ¼ć‚’å®Ÿč”Œć—ć¾ć™ (http://localhost:8080 +ć§åˆ©ē”ØåÆčƒ½): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ + +ćƒŖćƒć‚øćƒˆćƒŖć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ć—ć€`pnpm` ć‚’ä½æē”Øć—ć¦ä¾å­˜é–¢äæ‚ć‚’ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć—ć€ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’ē·Øé›†ć™ć‚‹ćŸć‚ć«åæ…č¦ćŖē’°å¢ƒć‚’å®Ÿč”Œć—ć¾ć™: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### å®Ÿč”Œćƒ•ć‚”ć‚¤ćƒ«ć®ę§‹ēÆ‰ +ćƒŖćƒć‚øćƒˆćƒŖć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ć—ć€`pnpm` ć‚’ä½æē”Øć—ć¦ä¾å­˜é–¢äæ‚ć‚’ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć—ć€Windows ē”Øć®ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć‚¢ćƒ—ćƒŖć‚’ćƒ“ćƒ«ćƒ‰ć—ć¾ć™: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +詳瓰については、[é–‹ē™ŗćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide) +ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +### é–‹ē™ŗč€…å‘ć‘ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ + +詳瓰については、[ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚¬ć‚¤ćƒ‰](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +ć‚’ć”č¦§ćć ć•ć„ć€‚ć”č³Ŗå•ćŒć”ć–ć„ć¾ć—ćŸć‚‰ć€äøŠčØ˜ć®ć€Œē§ćŸć”ćØč­°č«–ć—ć¾ć—ć‚‡ć†ć€ć‚»ć‚Æć‚·ćƒ§ćƒ³ć«čØ˜č¼‰ć•ć‚Œć¦ć„ć‚‹ćƒŖćƒ³ć‚Æć‹ć‚‰ćŠę°—č»½ć«ćŠå•ć„åˆć‚ć›ćć ć•ć„ć€‚ + +## šŸ‘ ć‚·ćƒ£ć‚¦ćƒˆć‚¢ć‚¦ćƒˆ + +* [zadam](https://github.com/zadam) ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć®ć‚ŖćƒŖć‚øćƒŠćƒ«ć®ć‚³ćƒ³ć‚»ćƒ—ćƒˆćØå®Ÿč£…ć«åÆ¾ć—ć¦ę„Ÿč¬ć—ć¾ć™ć€‚ +* [Sarah Hussein](https://github.com/Sarah-Hussein) ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚¢ć‚¤ć‚³ćƒ³ć‚’ćƒ‡ć‚¶ć‚¤ćƒ³ć€‚ +* [nriver](https://github.com/nriver) å›½éš›åŒ–ćøć®å–ć‚Šēµ„ćæć€‚ +* [Thomas Frei](https://github.com/thfrei) Canvasćøć®ć‚ŖćƒŖć‚øćƒŠćƒ«ćŖå–ć‚Šēµ„ćæć€‚ +* [antoniotejada](https://github.com/nriver) ć‚ŖćƒŖć‚øćƒŠćƒ«ć®ę§‹ę–‡ćƒć‚¤ćƒ©ć‚¤ćƒˆć‚¦ć‚£ć‚øć‚§ćƒƒćƒˆć€‚ +* [Dosu](https://dosu.dev/) GitHub ć®å•é”Œć‚„ćƒ‡ć‚£ć‚¹ć‚«ćƒƒć‚·ćƒ§ćƒ³ć«åÆ¾ć™ć‚‹č‡Ŗå‹•åæœē­”ć‚’ęä¾›ć—ć¦ćć‚Œć¾ć—ćŸć€‚ +* [Tabler Icons](https://tabler.io/icons) ć‚·ć‚¹ćƒ†ćƒ ćƒˆćƒ¬ć‚¤ć‚¢ć‚¤ć‚³ćƒ³ć€‚ + +Trilium ćÆć€ćć®åŸŗē›¤ćØćŖć‚‹ęŠ€č”“ćŖć—ć«ćÆå®Ÿē¾ć§ćć¾ć›ć‚“ć§ć—ćŸ: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - + ćƒ†ć‚­ć‚¹ćƒˆćƒŽćƒ¼ćƒˆć‚’č£œå®Œć™ć‚‹ćƒ“ć‚øćƒ„ć‚¢ćƒ«ć‚Øćƒ‡ć‚£ć‚æćƒ¼ć€‚ćƒ—ćƒ¬ćƒŸć‚¢ćƒ ę©Ÿčƒ½ć‚’ęä¾›ć—ć¦ć„ćŸć ćć€ę„Ÿč¬ć„ćŸć—ć¾ć™ć€‚ +* [CodeMirror](https://github.com/codemirror/CodeMirror) - + č†Øå¤§ćŖę•°ć®čØ€čŖžć‚’ć‚µćƒćƒ¼ćƒˆć™ć‚‹ć‚³ćƒ¼ćƒ‰ć‚Øćƒ‡ć‚£ć‚æćƒ¼ć€‚ +* [Excalidraw](https://github.com/excalidraw/excalidraw) - Canvas + ćƒŽćƒ¼ćƒˆć§ä½æē”Øć•ć‚Œć‚‹ē„”é™ć®ćƒ›ćƒÆć‚¤ćƒˆćƒœćƒ¼ćƒ‰ć€‚ +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - + ćƒžć‚¤ćƒ³ćƒ‰ćƒžćƒƒćƒ—ę©Ÿčƒ½ć‚’ęä¾›ć—ć¾ć™ć€‚ +* [Leaflet](https://github.com/Leaflet/Leaflet) - åœ°ē†ćƒžćƒƒćƒ—ć‚’ćƒ¬ćƒ³ćƒ€ćƒŖćƒ³ć‚°ć—ć¾ć™ć€‚ +* Tabulator](https://github.com/olifolkerd/tabulator) - + ć‚³ćƒ¬ć‚Æć‚·ćƒ§ćƒ³ć§ä½æē”Øć•ć‚Œć‚‹ć‚¤ćƒ³ć‚æćƒ©ć‚Æćƒ†ć‚£ćƒ–ćŖćƒ†ćƒ¼ćƒ–ćƒ«ć€‚ +* [FancyTree](https://github.com/mar10/fancytree) - ä»–ć«é”žć‚’č¦‹ćŖć„ę©Ÿčƒ½č±ŠåÆŒćŖćƒ„ćƒŖćƒ¼ćƒ©ć‚¤ćƒ–ćƒ©ćƒŖć€‚ +* [jsPlumb](https://github.com/jsplumb/jsplumb) - + č¦–č¦šēš„ćŖęŽ„ē¶šćƒ©ć‚¤ćƒ–ćƒ©ćƒŖć€‚[ćƒŖćƒ¬ćƒ¼ć‚·ćƒ§ćƒ³ćƒžćƒƒćƒ—](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + と + [ćƒŖćƒ³ć‚Æćƒžćƒƒćƒ—](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + ć§ä½æē”Øć•ć‚Œć¾ć™ + +## šŸ¤ ć‚µćƒćƒ¼ćƒˆ + +Triliumは +[ę•°ē™¾ę™‚é–“ć‚‚ć®ä½œę„­](https://github.com/TriliumNext/Trilium/graphs/commit-activity) +ć«ć‚ˆć£ć¦ę§‹ēÆ‰ćƒ»ē¶­ęŒć•ć‚Œć¦ć„ć¾ć™ć€‚ēš†ę§˜ć®ć”ę”Æę“ć«ć‚ˆć‚Šć€ć‚Ŗćƒ¼ćƒ—ćƒ³ć‚½ćƒ¼ć‚¹ćØć—ć¦ć®ē¶­ęŒć€ę©Ÿčƒ½ć®å‘äøŠć€ćƒ›ć‚¹ćƒ†ć‚£ćƒ³ć‚°ćŖć©ć®č²»ē”Øć‚’č³„ć†ć“ćØćŒć§ćć¾ć™ć€‚ + +ę¬”ć®ę–¹ę³•ć§ć€ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć®äø»ćŖé–‹ē™ŗč€… ([eliandoran](https://github.com/eliandoran)) +ć‚’ć‚µćƒćƒ¼ćƒˆć™ć‚‹ć“ćØć‚’ę¤œčØŽć—ć¦ćć ć•ć„: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ ćƒ©ć‚¤ć‚»ćƒ³ć‚¹ + +č‘—ä½œęØ© 2017-2025 zadam态Elian Doranć€ćć®ä»–åÆ„ēØæč€… + +ć“ć®ćƒ—ćƒ­ć‚°ćƒ©ćƒ ćÆćƒ•ćƒŖćƒ¼ć‚½ćƒ•ćƒˆć‚¦ć‚§ć‚¢ć§ć™: ćƒ•ćƒŖćƒ¼ć‚½ćƒ•ćƒˆć‚¦ć‚§ć‚¢č²”å›£(Software Foundation) ćŒē™ŗč”Œć™ć‚‹ GNU Affero +äø€čˆ¬å…¬č”†åˆ©ē”ØčØ±č«¾ę›ø(GNU Affero General Public License) ć®ćƒćƒ¼ć‚øćƒ§ćƒ³ 3ć€ć¾ćŸćÆ (éøęŠžć«ć‚ˆć‚Š) +ćć‚Œä»„é™ć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®č¦ē“„ć«å¾“ć£ć¦ć€ć“ć®ćƒ—ćƒ­ć‚°ćƒ©ćƒ ć‚’å†é…åøƒćŠć‚ˆć³/ć¾ćŸćÆę”¹å¤‰ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ diff --git a/docs/README-ko.md b/docs/README-ko.md new file mode 100644 index 0000000000..148072ba9e --- /dev/null +++ b/docs/README-ko.md @@ -0,0 +1,299 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# ķŠøė¦“ė¦¬ģ›€ ė…øķŠø + +![GitHub ģŠ¤ķ°ģ„œ](https://img.shields.io/github/sponsors/eliandoran) ![LiberaPay +ķ›„ģ›ģž](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (ėŖØė“  에셋, ėŖØė“  +릓리즈)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![ė²ˆģ—­ +상태](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium NotesėŠ” ėŒ€ź·œėŖØ ź°œģø ģ§€ģ‹ 기반 구축에 ģ¤‘ģ ģ„ ė‘” 묓료 ģ˜¤ķ”ˆ ģ†ŒģŠ¤ 크딜스 ķ”Œėž«ķ¼ 계층적 메모 ģž‘ģ„± ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ģž…ė‹ˆė‹¤. + +Trilium Screenshot + +## ā¬ ė‹¤ģš“ė”œė“œ +- [ģµœģ‹  릓리스](https://github.com/TriliumNext/Trilium/releases/latest) – ģ•ˆģ •ėœ ė²„ģ „ģœ¼ė”œ + ėŒ€ė¶€ė¶„ģ˜ ģ‚¬ģš©ģžģ—ź²Œ ź¶Œģž„ė©ė‹ˆė‹¤. +- [야간 ė¹Œė“œ](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – ė¶ˆģ•ˆģ •ķ•œ 개발 + ė²„ģ „ģœ¼ė”œ, ģµœģ‹  기늄과 ģˆ˜ģ • ģ‚¬ķ•­ģ“ ė§¤ģ¼ ģ—…ė°ģ“ķŠøė©ė‹ˆė‹¤. + +## šŸ“š ė¬øģ„œ + +**[docs.triliumnotes.org](https://docs.triliumnotes.org/)ģ—ģ„œ 전첓 ė¬øģ„œė„¼ ķ™•ģøķ•˜ģ„øģš”** + +ė¬øģ„œėŠ” ė‹¤ģ–‘ķ•œ ķ˜•ģ‹ģœ¼ė”œ ģ œź³µė©ė‹ˆė‹¤: +- **ģ˜Øė¼ģø ė¬øģ„œ**: [docs.triliumnotes.org](https://docs.triliumnotes.org/)ģ—ģ„œ ėŖØė“  ė¬øģ„œė„¼ + ė³“ģ—¬ģ¤ė‹ˆė‹¤ +- **ė„ģ›€ė§**: ķŠøė¦“ė¦¬ģ›€ ģ–“ķ”Œė¦¬ģ¼€ģ“ģ…˜ģ—ģ„œ `F1` ė²„ķŠ¼ģ„ 눌러 ź°™ģ€ ė¬øģ„œė„¼ 직접 ė³¼ 수 ģžˆģŠµė‹ˆė‹¤ +- **GitHub**: ģ“ ė ˆķ¬ģ§€ķ† ė¦¬ģ˜ [ģ‚¬ģš©ģž ź°€ģ“ė“œ](./User%20Guide/User%20Guide/)ģ—ģ„œ ķ™•ģøķ•  수 ģžˆģŠµė‹ˆė‹¤ + +### ė°”ė”œź°€źø° +- [ģ‹œģž‘ķ•˜źø° ź°€ģ“ė“œ](https://docs.triliumnotes.org/) +- [ģ„¤ģ¹˜ 방법](https://docs.triliumnotes.org/user-guide/setup) +- [ė„ģ»¤ + ģ„¤ģ¹˜](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [TriliumNext딜 ģ—…ź·øė ˆģ“ė“œ](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [źø°ė³ø ź°œė… ė° 기늄](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [ź°œģø ģ§€ģ‹ ė² ģ“ģŠ¤ģ˜ + ķŒØķ„“ė“¤](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ ģ£¼ģš” 기늄 + +* ė…øķŠøėŠ” ė‹¤ģ–‘ķ•œ ź¹Šģ“ģ˜ 트리딜 배엓될 수 ģžˆģœ¼ė©°, ķ•˜ė‚˜ģ˜ ė…øķŠøėŠ” ķŠøė¦¬ģ˜ ģ—¬ėŸ¬ ģœ„ģ¹˜ģ— ė‘˜ 수 ģžˆģŒ + ([cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning) + ģ°øź³ ) +* ė§ˆķ¬ė‹¤ģš“ + [ģžė™ģ„œģ‹](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting)ź³¼ + ķ•Øź»˜ ķ…Œģ“ėø”, ģ“ėÆøģ§€, 그리고 + [ģˆ˜ķ•™](https://docs.triliumnotes.org/user-guide/note-types/text) ė“±ģ˜ źø°ėŠ„ģ„ ķ¬ķ•Øķ•œ ė‹¤ģ–‘ķ•œ + źø°ėŠ„ģ˜ WYSIWYG ė…øķŠø ķŽøģ§‘źø° 제공 +* 구문 강씰넼 ķ¬ķ•Øķ•œ [ģ†ŒģŠ¤ģ½”ė“œ](https://docs.triliumnotes.org/user-guide/note-types/code) ķŽøģ§‘ + 기늄 +* 쉽고 빠넓게 ė…øķŠøė„¼ ģ°¾ģ„ 수 ģžˆėŠ” + [ė‚“ė¹„ź²Œģ“ģ…˜](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + 전첓 ķ…ģŠ¤ķŠø ź²€ģƒ‰ ė° [ė…øķŠø + ķ˜øģ“ģŠ¤ķŒ…](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* ģ›ķ™œķ•œ [ė…øķŠø 버전 + ꓀리](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* ė…øķŠøģ˜ [ģ†ģ„±](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes)ģ€ + ė…øķŠø 씰직화, 쿼리, 그리고 ź³ źø‰ źø°ėŠ„ģø + [ģŠ¤ķ¬ė¦½ķŒ…](https://docs.triliumnotes.org/user-guide/scripts)에 ģ‚¬ģš© +* ģ˜ģ–“, ė…ģ¼ģ–“, ģŠ¤ķŽ˜ģøģ–“, ķ”„ėž‘ģŠ¤ģ–“, ė£Øė§ˆė‹ˆģ•„ģ–“, 중국얓 (간첓, 번첓) UI 제공 +* ė”ģš± ģ•ˆģ „ķ•œ ė”œź·øģøģ„ ģœ„ķ•“ 직접 [OpenID ė° TOTP + 통합](https://docs.triliumnotes.org/user-guide/setup/server/mfa) +* self-hosted ė™źø°ķ™” ģ„œė²„ė„¼ ķ†µķ•œ + [ė™źø°ķ™”](https://docs.triliumnotes.org/user-guide/setup/synchronization) + * ė™źø°ķ™” ģ„œė²„ė„¼ ķ˜øģŠ¤ķŒ…ķ•˜ėŠ” [ķƒ€ģ‚¬ + ģ„œė¹„ģŠ¤](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting)ź°€ + ģžˆģŠµė‹ˆė‹¤ +* ė…øķŠøģ˜ ģøķ„°ė„· [공유](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (ķ¼ėø”ė¦¬ģ‹±) 기늄 +* ė…øķŠøė§ˆė‹¤ ģ„øė¶„ķ™”ėœ ź°•ė „ķ•œ [ė…øķŠø + ģ•”ķ˜øķ™”](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) +* [Excalidraw](https://excalidraw.com/) 기반 ģŠ¤ģ¼€ģ¹˜ ė‹¤ģ“ģ–“ź·øėžØ (ė…øķŠø ķƒ€ģž… "ģŗ”ė²„ģŠ¤") +* ė…øķŠøģ™€ ź·ø ꓀계넼 ģ‹œź°ķ™”ķ•˜źø° ģœ„ķ•œ [꓀계 + ė§µ](https://docs.triliumnotes.org/user-guide/note-types/relation-map) ė° [ė…øķŠø/링크 + ė§µ](https://docs.triliumnotes.org/user-guide/note-types/note-map) +* [Mind Elixir](https://docs.mind-elixir.com/) 기반 ė§ˆģøė“œė§µ +* ģœ„ģ¹˜ 핀과 GPX ķŠøėž™ģ“ ģžˆėŠ” + [ģ§€ģ˜¤ė§µ](https://docs.triliumnotes.org/user-guide/collections/geomap) +* [스크립트](https://docs.triliumnotes.org/user-guide/scripts) - [ź³ źø‰ + ģ‡¼ģ¼€ģ“ģŠ¤](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* ģžė™ķ™”ė„¼ ģœ„ķ•œ [REST + API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) +* 10만 개 ģ“ģƒģ˜ ė…øķŠøė„¼ ģ²˜ė¦¬ķ•“ė„ ģ‚¬ģš©ģ„±ź³¼ ģ„±ėŠ„ ė©“ģ—ģ„œ ė›°ģ–“ė‚œ ķ™•ģž„ģ„±ģ„ ģ‹¤ķ˜„ +* ģŠ¤ė§ˆķŠøķ° ė° ķƒœėø”ė¦æģš© ķ„°ģ¹˜ ģ”°ģž‘ģ— ģµœģ ķ™”ėœ [ėŖØė°”ģ¼ + ķ”„ėŸ°ķŠøģ—”ė“œ](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) +* źø°ė³ø 제공 [다크 ķ…Œė§ˆ](https://docs.triliumnotes.org/user-guide/concepts/themes), ģ‚¬ģš©ģž + ķ…Œė§ˆ 지원 +* [Evernote] + (https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) ė° + [Markdown ź°€ģ øģ˜¤źø° ė° 낓볓낓기] + (https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) 웹 + ģ½˜ķ…ģø ģ˜ ģ‰¬ģš“ ģ €ģž„ +* ģ‚¬ģš©ģž ģ •ģ˜ ź°€ėŠ„ķ•œ UI(ģ‚¬ģ“ė“œė°” ė²„ķŠ¼, ģ‚¬ģš©ģž ģ •ģ˜ ģœ„ģ Æ 등) +* [ė©”ķŠøė¦­](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics)ź³¼ + Grafana ėŒ€ģ‹œė³“ė“œź°€ ķ•Øź»˜ ģ œź³µė©ė‹ˆė‹¤. + +✨ TriliumNext ꓀련 ģœ ģš©ķ•œ 정볓넼 ė” ė³“ģ‹œė ¤ė©“ ģ•„ėž˜ģ˜ ģ„œė“œķŒŒķ‹° ė¦¬ģ†ŒģŠ¤/ģ»¤ė®¤ė‹ˆķ‹°ė„¼ ķ™•ģøķ•“ ė³“ģ„øģš”: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium)ģ€ ģ„œė“œķŒŒķ‹° ķ…Œė§ˆ, 스크립트, + ķ”ŒėŸ¬ź·øģø ė“±ģ„ ģœ„ķ•œ ź²ƒģž…ė‹ˆė‹¤. +- [TriliumRocks!](https://trilium.rocks/) ķŠœķ† ė¦¬ģ–¼, ź°€ģ“ė“œ ė° źø°ķƒ€ ģ—¬ėŸ¬ 가지넼 ķ™•ģøķ•˜ģ„øģš”. + +## ā“ģ™œ TriliumNextģ¼ź¹Œ? + +Triliumģ˜ 최쓈 ź°œė°œģž([Zadam](https://github.com/zadam))ėŠ” Trilium ģ €ģž„ģ†Œė„¼ ģ»¤ė®¤ė‹ˆķ‹° ķ”„ė”œģ ķŠøģ— ķ”ģ¾Œķžˆ +ģ œź³µķ–ˆģœ¼ė©°, 핓당 ģ €ģž„ģ†ŒėŠ” https://github.com/TriliumNext에 ģžˆģŠµė‹ˆė‹¤. + +### ā¬†ļøZadam/Triliumģ—ģ„œ ė§ˆģ“ź·øė ˆģ“ģ…˜ķ•˜ģ‹œė‚˜ģš”? + +zadam/Trilium ģøģŠ¤ķ„“ģŠ¤ģ—ģ„œ TriliumNext/Trilium ģøģŠ¤ķ„“ģŠ¤ė”œ ė§ˆģ“ź·øė ˆģ“ģ…˜ķ•˜ėŠ” ė° ķŠ¹ė³„ķ•œ ģ ˆģ°ØėŠ” ģ—†ģŠµė‹ˆė‹¤. ķ‰ģ†Œģ²˜ėŸ¼ +[TriliumNext/Trilium](#-installation)ģ„ ģ„¤ģ¹˜ķ•˜ė©“ 기씓 ė°ģ“ķ„°ė² ģ“ģŠ¤ė„¼ ģ‚¬ģš©ķ•˜ź²Œ ė©ė‹ˆė‹¤. + +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4)ź¹Œģ§€ģ˜ ė²„ģ „ģ€ +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7)ģ˜ ģµœģ‹  +zadam/trilium 버전과 ķ˜øķ™˜ė©ė‹ˆė‹¤. ģ“ķ›„ ė²„ģ „ģ˜ TriliumNext/Triliumģ€ ė™źø°ķ™” ė²„ģ „ģ“ ģ¦ź°€ė˜ģ–“ 직접 ė§ˆģ“ź·øė ˆģ“ģ…˜ģ“ +ė¶ˆź°€ėŠ„ķ•©ė‹ˆė‹¤. + +## šŸ’¬ ķ•Øź»˜ 토딠핓 ė³“ģ„øģš” + +ģ €ķ¬ ź³µģ‹ ėŒ€ķ™”ģ— ģžģœ ė”­ź²Œ 참여핓 ģ£¼ģ„øģš”. ģ–“ė–¤ 기늄, ģ œģ•ˆ ė˜ėŠ” ė¬øģ œģ ģ“ ģžˆģœ¼ģ‹œė©“ ģ–øģ œė“ ģ§€ ģ•Œė ¤ģ£¼ģ„øģš”! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (ė™źø°ģ‹ ķ† ė” ģš©) + - `General` 매트릭스 ė£øģ€ [XMPP](xmpp:discuss@trilium.thisgreat.party?join)ģ—ė„ ėøŒė¦¬ģ§€ė˜ģ–“ + ģžˆģŠµė‹ˆė‹¤ +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (ė¹„ė™źø° + ķ† ė” ģš©) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (버그 볓고 ė° 기늄 + ģš”ģ²­ģš©) + +## šŸ— ģ„¤ģ¹˜ + +### ģœˆė„ģš° / ė§„OS + +[ģµœģ‹  릓리스 ķŽ˜ģ“ģ§€](https://github.com/TriliumNext/Trilium/releases/latest)ģ—ģ„œ ķ”Œėž«ķ¼ģ— ķ•“ė‹¹ķ•˜ėŠ” +ė°”ģ“ė„ˆė¦¬ 릓리스넼 ė‹¤ģš“ė”œė“œķ•œ ė’¤, ķŒØķ‚¤ģ§€ģ˜ ģ••ģ¶•ģ„ 풀고 `trilium` 실행 ķŒŒģ¼ģ„ ģ‹¤ķ–‰ķ•˜ģ„øģš”. + +### Linux + +ģ‚¬ģš©ķ•˜ģ‹œėŠ” ė°°ķ¬ķŒģ“ ģ•„ėž˜ ķ‘œģ— ė‚˜ģ™€ ģžˆė‹¤ė©“ 핓당 ė°°ķ¬ķŒģ˜ ķŒØķ‚¤ģ§€ė„¼ ģ‚¬ģš©ķ•˜ģ‹­ģ‹œģ˜¤. + +[![ķŒØķ‚¤ģ§• +상태](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +ė˜ķ•œ [ģµœģ‹  릓리스 ķŽ˜ģ“ģ§€](https://github.com/TriliumNext/Trilium/releases/latest)ģ—ģ„œ 핓당 +ķ”Œėž«ķ¼ģš© ė°”ģ“ė„ˆė¦¬ 릓리스넼 ė‹¤ģš“ė”œė“œķ•˜ź³  ķŒØķ‚¤ģ§€ģ˜ ģ••ģ¶•ģ„ 풀고 `trilium` 실행 ķŒŒģ¼ģ„ 실행할 ģˆ˜ė„ ģžˆģŠµė‹ˆė‹¤. + +TriliumNextėŠ” Flatpakģœ¼ė”œė„ ģ œź³µė˜ģ§€ė§Œ, 아직 FlatHubģ—ėŠ” ź²Œģ‹œė˜ģ§€ ģ•Šģ•˜ģŠµė‹ˆė‹¤. + +### ėøŒė¼ģš°ģ € (ėŖØė“  욓영첓제) + +ģ„œė²„ ģ„¤ģ¹˜(ģ•„ėž˜ ģ°øģ”°)넼 ģ‚¬ģš©ķ•˜ėŠ” 경우 ė°ģŠ¤ķ¬ķ†± 앱과 ź±°ģ˜ ė™ģ¼ķ•œ 웹 ģøķ„°ķŽ˜ģ“ģŠ¤ģ— 직접 ģ•”ģ„øģŠ¤ķ•  수 ģžˆģŠµė‹ˆė‹¤. + +ķ˜„ģž¬ėŠ” 크딬과 ķŒŒģ“ģ–“ķ­ģŠ¤ģ˜ ģµœģ‹  ė²„ģ „ė§Œ 지원(ė° ķ…ŒģŠ¤ķŠø)ė©ė‹ˆė‹¤. + +### ėŖØė°”ģ¼ + +ėŖØė°”ģ¼ źø°źø°ģ—ģ„œ TriliumNext넼 ģ‚¬ģš©ķ•˜ė ¤ė©“, ėŖØė°”ģ¼ 웹 ėøŒė¼ģš°ģ €ė„¼ ģ‚¬ģš©ķ•˜ģ—¬ ģ„œė²„ ģ„¤ģ¹˜ģ˜ ėŖØė°”ģ¼ ģøķ„°ķŽ˜ģ“ģŠ¤ģ— ģ ‘ģ†ķ•˜ė©“ ė©ė‹ˆė‹¤(ģ•„ėž˜ ģ°øģ”°). + +ėŖØė°”ģ¼ 앱 지원에 ėŒ€ķ•œ ģžģ„øķ•œ ė‚“ģš©ģ€ https://github.com/TriliumNext/Trilium/issues/4962 ģ“ģŠˆė„¼ +ģ°øģ”°ķ•˜ģ„øģš”. + +ė„¤ģ“ķ‹°ėøŒ Android ģ•±ģ„ ģ„ ķ˜øķ•˜ėŠ” 경우 +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid)넼 +ģ‚¬ģš©ķ•  수 ģžˆģŠµė‹ˆė‹¤. 버그 ė° ėˆ„ė½ėœ źø°ėŠ„ģ€ [핓당 +ģ €ģž„ģ†Œ](https://github.com/FliegendeWurst/TriliumDroid)에 ė³“ź³ ķ•˜ģ‹­ģ‹œģ˜¤. ģ°øź³ : Triliumź³¼ +TriliumDroidģ˜ ė™źø°ķ™” ė²„ģ „ģ“ ģ¼ģ¹˜ķ•“ģ•¼ ķ•˜ėÆ€ė”œ TriliumDroid넼 ģ‚¬ģš©ķ•  ė•ŒėŠ” ģ„œė²„ ģ„¤ģ¹˜ģ—ģ„œ ģžė™ ģ—…ė°ģ“ķŠøė„¼ ė¹„ķ™œģ„±ķ™”ķ•˜ėŠ” ź²ƒģ“ +ģ¢‹ģŠµė‹ˆė‹¤(ģ•„ėž˜ ģ°øģ”°). + +### ģ„œė²„ + +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)ģ˜ Docker넼 통핓 +TriliumNext넼 ģžģ²“ ģ„œė²„ģ— ģ„¤ģ¹˜ķ•˜ė ¤ė©“ [ģ„œė²„ ģ„¤ģ¹˜ +ė¬øģ„œ](https://docs.triliumnotes.org/user-guide/setup/server)넼 ė”°ė„“ģ„øģš”. + + +## šŸ’» ģ°øģ—¬ķ•˜źø° + +### ė²ˆģ—­ + +ģ›ģ–“ėÆ¼ģ“ģ‹œė¼ė©“ [Weblate ķŽ˜ģ“ģ§€](https://hosted.weblate.org/engage/trilium/)딜 ģ“ė™ķ•˜ģ—¬ Trilium +ė²ˆģ—­ģ„ ė„ģ™€ģ£¼ģ„øģš”. + +ķ˜„ģž¬ź¹Œģ§€ ģ§€ģ›ė˜ėŠ” ģ–øģ–“ėŠ” ė‹¤ģŒź³¼ ź°™ģŠµė‹ˆė‹¤: + +[![ė²ˆģ—­ +상태](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### ģ½”ė“œ + +ģ €ģž„ģ†Œė„¼ ė‹¤ģš“ė”œė“œķ•˜ź³  `pnpm`ģ„ ģ‚¬ģš©ķ•˜ģ—¬ ģ¢…ģ†ģ„±ģ„ ģ„¤ģ¹˜ķ•œ ė‹¤ģŒ ģ„œė²„ė„¼ ģ‹¤ķ–‰ķ•˜ģ„øģš”(http://localhost:8080ģ—ģ„œ ģ ‘ģ† ź°€ėŠ„): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### ė¬øģ„œ + +ģ €ģž„ģ†Œė„¼ ė‹¤ģš“ė”œė“œķ•˜ź³  `pnpm`ģ„ ģ‚¬ģš©ķ•˜ģ—¬ ģ¢…ģ†ģ„±ģ„ ģ„¤ģ¹˜ķ•œ ė‹¤ģŒ ė¬øģ„œ ķŽøģ§‘ģ— ķ•„ģš”ķ•œ ķ™˜ź²½ģ„ ģ‹¤ķ–‰ķ•˜ģ„øģš”. +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### 실행 ķŒŒģ¼ ė¹Œė“œ +ģ €ģž„ģ†Œė„¼ ė‹¤ģš“ė”œė“œķ•˜ź³  `pnpm`ģ„ ģ‚¬ģš©ķ•˜ģ—¬ ģ¢…ģ†ģ„±ģ„ ģ„¤ģ¹˜ķ•œ ė‹¤ģŒ Windows용 ė°ģŠ¤ķ¬ķ†± ģ•±ģ„ ė¹Œė“œķ•˜ģ„øģš”. +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +ģžģ„øķ•œ ė‚“ģš©ģ€ [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide)넼 +ģ°øź³ ķ•˜ģ„øģš”. + +### ź°œė°œģž ė¬øģ„œ + +ģžģ„øķ•œ ė‚“ģš©ģ€ [ė¬øģ„œ +ź°€ģ“ė“œ](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md)넼 +ģ°øģ”°ķ•˜ģ‹­ģ‹œģ˜¤. 추가 ģ§ˆė¬øģ“ ģžˆģœ¼ģ‹œė©“ ģœ„ģ˜ "ė¬øģ˜ķ•˜źø°" ģ„¹ģ…˜ģ— ģ„¤ėŖ…ėœ 링크넼 통핓 ģ–øģ œė“ ģ§€ ė¬øģ˜ķ•“ ģ£¼ģ‹­ģ‹œģ˜¤. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam)ģ€ ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ģ˜ ģ›ėž˜ ź°œė…ź³¼ źµ¬ķ˜„ģ— ėŒ€ķ•œ 공딜넼 ģøģ •ė°›ģ•˜ģŠµė‹ˆė‹¤. +* [Sarah Hussein](https://github.com/Sarah-Hussein)ģ€ ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ ģ•„ģ“ģ½˜ģ„ ė””ģžģøķ–ˆģŠµė‹ˆė‹¤. +* [nriver](https://github.com/nriver) źµ­ģ œķ™”ģ— ź³µķ—Œ. +* [Thomas Frei](https://github.com/thfrei) ģŗ”ė²„ģŠ¤ģ— ėŒ€ķ•œ ė…ģ°½ģ ģø ģž‘ģ—…. +* [antoniotejada](https://github.com/nriver) 구문 ź°•ģ”° ģœ„ģ Æģ˜ 원본. +* [Dosu](https://dosu.dev/) GitHub ģ“ģŠˆ ė° 토딠에 ėŒ€ķ•œ ģžė™ ģ‘ė‹µģ„ 제공. +* [Tabler Icons](https://tabler.io/icons) ģ‹œģŠ¤ķ…œ ķŠøė ˆģ“ ģ•„ģ“ģ½˜. + +ķŠøė¦“ė¦¬ģ›€ģ€ ė‹¤ģŒģ˜ 기반 źø°ģˆ ė“¤ģ“ ģ—†ģ—ˆė‹¤ė©“ ė¶ˆź°€ėŠ„ķ–ˆģ„ ź²ƒģž…ė‹ˆė‹¤: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - ķ…ģŠ¤ķŠø ė…øķŠøģ˜ ģ‹œź°ģ  ķŽøģ§‘źø°ģž…ė‹ˆė‹¤. 프리미엄 + źø°ėŠ„ģ„ ģ œź³µķ•“ģ£¼ģ…”ģ„œ ź°ģ‚¬ķ•©ė‹ˆė‹¤. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - ģˆ˜ė§Žģ€ 언얓넼 ģ§€ģ›ķ•˜ėŠ” ģ½”ė“œ ķŽøģ§‘źø°. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - Canvas ė…øķŠøģ—ģ„œ ģ‚¬ģš©ė˜ėŠ” ė¬“ķ•œ + ķ™”ģ“ķŠøė³“ė“œģž…ė‹ˆė‹¤. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - ė§ˆģøė“œė§µ źø°ėŠ„ģ„ ģ œź³µķ•©ė‹ˆė‹¤. +* [Leaflet](https://github.com/Leaflet/Leaflet) - 지리 ģ§€ė„ė„¼ ė Œė”ė§ ķ•©ė‹ˆė‹¤. +* [Tabulator](https://github.com/olifolkerd/tabulator) - ģ»¬ė ‰ģ…˜ģ—ģ„œ ģ‚¬ģš©ė˜ėŠ” ģøķ„°ėž™ķ‹°ėøŒ + ķ…Œģ“ėø”ģž…ė‹ˆė‹¤. +* [FancyTree](https://github.com/mar10/fancytree) - ė…ė³“ģ ģœ¼ė”œ źø°ėŠ„ģ“ ķ’ė¶€ķ•œ 트리 ė¼ģ“ėøŒėŸ¬ė¦¬ģž…ė‹ˆė‹¤. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - ģ‹œź°ģ  ģ—°ź²° ė¼ģ“ėøŒėŸ¬ė¦¬ģž…ė‹ˆė‹¤. [꓀계 + ė§µ](https://docs.triliumnotes.org/user-guide/note-types/relation-map) ź³¼ [링크 + ė§µ](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map)에 + ģ‚¬ģš©ė©ė‹ˆė‹¤ + +## šŸ¤ 후원 + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ė¼ģ“ģ„¼ģŠ¤ + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-md.md b/docs/README-md.md new file mode 100644 index 0000000000..0da3a37bf9 --- /dev/null +++ b/docs/README-md.md @@ -0,0 +1,337 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking +application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation + directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-mr.md b/docs/README-mr.md new file mode 100644 index 0000000000..0da3a37bf9 --- /dev/null +++ b/docs/README-mr.md @@ -0,0 +1,337 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking +application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation + directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-nb_NO.md b/docs/README-nb_NO.md new file mode 100644 index 0000000000..43e29db665 --- /dev/null +++ b/docs/README-nb_NO.md @@ -0,0 +1,334 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![Sponsorer pĆ„ GitHub](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay bidragsytere](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![Nedlastinger pĆ„ GitHub(alle elementer, alle +utgivelser)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Oversettelsesstatus](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes er et gratis og Ć„pen kildekode-basert, plattformuavhengig +hierarkisk notatprogram med fokus pĆ„ Ć„ bygge store personlige kunnskapsbaser. + +Trilium Screenshot + +## ā¬ Last ned +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stabil versjon, anbefalt for de fleste brukere. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + ustabil utviklingsversjon, oppdateres daglig med de nyeste funksjonene og + feilfiksene. + +## šŸ“š Dokumentasjon + +**BesĆøk vĆ„r omfattende dokumentasjon pĆ„ +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +VĆ„r dokumentasjon er tilgjengelig i flere format: +- **Online Dokumentasjon**: Utforsk full dokumentasjon pĆ„ + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Hjelp i app**: Trykk`F1` i Trilium for Ć„ lese samme dokumentasjon direkte i + applikasjonen +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Hurtiglenker +- [Startveiledning](https://docs.triliumnotes.org/) +- [Installasjonsveiledning](https://docs.triliumnotes.org/user-guide/setup) +- [Oppsett med + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Oppgradere + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Grunnleggende konsepter og + funksjoner](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Modeller for personlig + kunnskapsbase](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Funksjoner + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Rask og enkel [navigering mellom + notater](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + fulltekstsĆøk og + [notat-fokusering](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* SĆømlĆøs + [notathistorikk](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Notaters + [attributter](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + kan brukes til Ć„ organisere notater, utfĆøre spĆørringer og avansert + [skripting](https://docs.triliumnotes.org/user-guide/scripts) +* Brukergrensesnitt tilgjengelig pĆ„ Engelsk, Tysk, Spansk, Fransk, Rumensk, og + Kinesisk (forenklet og tradisjonell) +* Direkte [OpenID og + TOTP-integrasjon](https://docs.triliumnotes.org/user-guide/setup/server/mfa) + for sikrere pĆ„logging +* [Synkronisering](https://docs.triliumnotes.org/user-guide/setup/synchronization) + med selv-hostet sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Skripting](https://docs.triliumnotes.org/user-guide/scripts) - se [Avanserte + bruksomrĆ„der](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automatisering +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Hvorfor TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrere fra Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬Diskuter med oss + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synkrone + diskusjoner.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installasjon + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Pakkestatus](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Nettleser (alle operativsystem) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobil + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Bidra + +### Oversettelser + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Oversettelsesstatus](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Kode + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Dokumentasjon + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Opprette kjĆørbar fil +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Utviklerdokumentasjon + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Takk + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ StĆøtte + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Spander en kaffe](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ Lisens + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-nl.md b/docs/README-nl.md new file mode 100644 index 0000000000..093ceaf4cf --- /dev/null +++ b/docs/README-nl.md @@ -0,0 +1,337 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsoren](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay supporters](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (alle bestanden, alle +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Vertaling +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trillium Notes is een gratis en open-source, platformonafhankelijke, +hiĆ«rarchische notitie-applicatie die zich richt op het opbouwen van grote +persoonlijke kennisbanken. + +Trilium Screenshot + +## Download +- [Laatse release](https://github.com/TriliumNext/Trilium/releases/latest) - + stabiele versie, aangeraden voor meeste gebruikers +- [Nachtige build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) + – unstabiele development versie, dagelijks geupdatet met de laatste functies + en oplossingen. + +## šŸ“š Documentatie + +**Bekijk onze beknopte documentatie op +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Onze documentatie is beschikbaar in meerdere formaten: +- **Online Documentatie**: Blader door de volledige documentatie op + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Toets`F1` binnen Trilium om dezelfde documentatie direct in + de applicatie te bekijken +- **GitHub**: Navigeer door de [User Guide](./User%20Guide/User%20Guide/) in + deze repository + +### Snelkoppelingen +- [Getting Started Gids](https://docs.triliumnotes.org/) +- [Installatie Instructies](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Installatie](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basis Concepten en + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patronen van Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Kenmerken + +* Notes kunnen in een diepe boomstructuur geplaatst worden. Een enkele note kan + op meerdere plekken in de boom geplaatst worden. (zie + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rijke WYSIWYG note editor inclusief e.g. tabellen, afbeeldingen en + [math](https://docs.triliumnotes.org/user-guide/note-types/text) met markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Ondersteuning voor bewerken van [notes met source + code](https://docs.triliumnotes.org/user-guide/note-types/code), inclusief + syntax highlighting +* Snelle en gemakkelijke [navigatie tussen + notities](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + uitgebreide text zoekopdrachten en [notities + promoveren](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Naadloze [notitie + versiegeschiedenis](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Notitie[-attributen](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + kunnen worden ingezet voor notitie-organisatie, queries en geavanceerd + [scripten](https://docs.triliumnotes.org/user-guide/scripts) +* Gebruikersinterface verkrijgbaar in het Engels, Duits, Spaans, Frans, Roemeens + en Chinees (versimpeld en traditioneel) +* Directe [OpenID en TOTP + integratie](https://docs.triliumnotes.org/user-guide/setup/server/mfa) voor + beter beveiligde aanmelding +* [Synchronisatie](https://docs.triliumnotes.org/user-guide/setup/synchronization) + met zelfgehoste synchronisatieserver + * er zijn [diensten van derden voor het hosten van de + synchronisatieserver](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-pl.md b/docs/README-pl.md new file mode 100644 index 0000000000..b00670d0f2 --- /dev/null +++ b/docs/README-pl.md @@ -0,0 +1,350 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes to darmowa i otwartoÅŗródłowa, wieloplatformowa aplikacja do +tworzenia notatek hierarchicznych, skupiona na budowaniu dużych osobistych baz +wiedzy. + +Trilium Screenshot + +## ā¬ Pobieranie +- [Ostatnie wydanie](https://github.com/TriliumNext/Trilium/releases/latest) – + stabilna wersja, polecane dla większości użytkowników. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) - + niestabilna wersja deweloperska, aktualizowana codziennie o najnowsze funkcje + i poprawki. + +## šŸ“šDokumentacja + +**OdwiedÅŗ naszą obszerną dokumentację na +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Nasza dokumentacja jest dostępna w wielu formatach: +- **Dokumentacja online**: Przeglądaj pełną dokumentację pod linkiem + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Pomoc w aplikacji**: Naciśnij `F1` w Trilium, aby uzyskać dostęp do tej + samej dokumentacji bezpośrednio w aplikacji +- **GitHub**: Poruszaj się po [Przewodniku + Użytkownika](./User%20Guide/User%20Guide/) w tym repozytorium + +### Szybkie linki +- [Poradnik dla początkujących](https://docs.triliumnotes.org/) +- [Instrukcja instalacji](https://docs.triliumnotes.org/user-guide/setup) +- [Instalacja + Dockera](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Aktualizacja + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Podstawowe koncepcje i + funkcjonalność](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Wzorce osobistej Bazy + Wiedzy](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Funkcjonalność + +* Notatki mogą być zorganizowane w drzewa dowolnej głębokości. Pojedyncza + notatka może być umieszczona w wielu miejscach w drzewie (patrz + [klonowanie](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Bogato wyposażony edytor notatek WYSIWYG, zawierający np. tabele, obrazy i + [matematykę](https://docs.triliumnotes.org/user-guide/note-types/text) z + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) + Markdown +* Wsparcie dla edycji [notatki z kodem + Åŗródłowym](https://docs.triliumnotes.org/user-guide/note-types/code), + zawierające podkreślanie kodu +* Szybkie i łatwe [poruszanie się po + notatkach](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + wyszukiwanie po pełnym tekście i[wyróżnienie + notatki](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Bezproblemowe [aktualizowanie wersji + notatki](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* [Atrybuty](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + notatki mogą być użyte dla jej organizacji, wyszukiwania i użycia + zaawansowanych [skryptów](https://docs.triliumnotes.org/user-guide/scripts) +* Interfejs użytkownika dostępny w językach: angielskim, niemieckim, + hiszpańskim, francuskim, rumuńskim oraz chińskim (uproszczonym i tradycyjnym) +* Bezpośrednia [integracja OpenID i + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) zapewniająca + bezpieczniejsze logowanie +* [Synchronizacja](https://docs.triliumnotes.org/user-guide/setup/synchronization) + z samodzielnie hostowanym serwerem synchronizacji + * Można skorzystać z [usług firm trzecich oferujących hosting serwera + synchronizacji](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Udostępnianie](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + i publikowanie notatek w Internecie +* Silne [szyfrowanie + notatek](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + z możliwością szyfrowania każdej notatki osobno +* Szkicowanie diagramów oparte na [Excalidraw](https://excalidraw.com/) (typ + notatki ā€žcanvasā€) +* [Mapy + relacji](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + oraz [mapy notatek i + linków](https://docs.triliumnotes.org/user-guide/note-types/note-map) do + wizualizacji notatek i ich relacji +* Mapy myśli z wykorzystaniem [Mind Elixir](https://docs.mind-elixir.com/) +* [Mapy + geograficzne](https://docs.triliumnotes.org/user-guide/collections/geomap) z + oznaczeniami lokalizacji i trasami GPX +* [Skrypty](https://docs.triliumnotes.org/user-guide/scripts) – patrz + [zaawansowane + przykłady](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) do + automatyzacji +* Dobrze skaluje się pod względem użyteczności i wydajności nawet przy ponad 100 + 000 notatek +* Zoptymalizowany pod kątem dotyku [mobilny + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) dla + smartfonów i tabletów +* Wbudowany [ciemny + motyw](https://docs.triliumnotes.org/user-guide/concepts/themes) i wsparcie + dla motywów użytkownika +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + oraz [import i eksport + Markdown](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) do + wygodnego zapisywania treści internetowych +* Konfigurowalny interfejs użytkownika (przyciski paska bocznego, widżety + definiowane przez użytkownika, …) +* [Metryki](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + wraz z panelem Grafana. + +✨ SprawdÅŗ poniższe zasoby i społeczności firm trzecich, aby znaleźć więcej +materiałów związanych z TriliumNext: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) — motywy, + skrypty, wtyczki i inne zasoby od firm trzecich. +- [TriliumRocks!](https://trilium.rocks/) — poradniki, przewodniki i wiele + więcej. + +## ā“Dlaczego TriliumNext? + +Pierwotny twórca Trilium ([Zadam](https://github.com/zadam)) uprzejmie przekazał +repozytorium Trilium społecznościowemu projektowi, który jest rozwijany pod +adresem https://github.com/TriliumNext + +### ā¬†ļøPrzechodzisz z Zadam/Trilium? + +Nie ma potrzeby wykonywania żadnych specjalnych kroków migracji podczas +przechodzenia z instancji zadam/Trilium na TriliumNext/Trilium. Po prostu +[zainstaluj TriliumNext/Trilium](#-installation) jak zwykle, a aplikacja +skorzysta z Twojej istniejącej bazy danych. + +Wersje do i łącznie z +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) są zgodne +z najnowszą wersją zadam/trilium +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Każda +późniejsza wersja TriliumNext/Trilium ma inną wersję synchronizacji, co +uniemożliwia migrację bezpośrednią. + +## šŸ’¬ Porozmawiaj z nami + +Zapraszamy do udziału w naszych oficjalnych dyskusjach. Z przyjemnością poznamy +Twoje pomysły, sugestie i problemy! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (do dyskusji w czasie + rzeczywistym) + - Pokój Matrix `General` jest również połączony mostem z + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [GitHub Discussions](https://github.com/TriliumNext/Trilium/discussions) (do + dyskusji niewymagających komunikacji w czasie rzeczywistym) +- [GitHub Issues](https://github.com/TriliumNext/Trilium/issues) (do + raportowania błędów i zgłaszania propozycji) + +## šŸ— Instalacja + +### Windows / MacOS + +Pobierz binarną wersję aplikacji dla swojej platformy z [najnowszej strony +wydań](https://github.com/TriliumNext/Trilium/releases/latest), rozpakuj +archiwum i uruchom plik wykonywalny `trilium`. + +### Linux + +Jeśli Twoja dystrybucja znajduje się w poniższej tabeli, skorzystaj z pakietu +przeznaczonego dla tej dystrybucji. + +[![Status +pakietów](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +Możesz również pobrać binarną wersję aplikacji dla swojej platformy z +[najnowszej strony +wydań](https://github.com/TriliumNext/Trilium/releases/latest), rozpakować +archiwum i uruchomić plik wykonywalny `trilium`. + +Dostępna jest również wersja Flatpak TriliumNext, lecz nie została jeszcze +opublikowana na FlatHub. + +### Przeglądarka (dowolny system operacyjny) + +W przypadku instalacji serwerowej (patrz niżej) możesz bezpośrednio korzystać z +interfejsu webowego, niemal identycznego z aplikacją desktopową. + +Aktualnie wspierane i testowane są tylko najnowsze wersje Chrome i Firefox. + +### Urządzenia mobilne + +Aby korzystać z TriliumNext na urządzeniu mobilnym, możesz użyć mobilnej +przeglądarki internetowej, aby uzyskać dostęp do mobilnego interfejsu instalacji +serwerowej (zobacz poniżej). + +Więcej informacji na temat wsparcia dla aplikacji mobilnej znajdziesz w +zgłoszeniu https://github.com/TriliumNext/Trilium/issues/4962. + +Jeśli preferujesz natywną aplikację na Androida, możesz skorzystać z +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Błędy oraz brakujące funkcje zgłaszaj w [ich +repozytorium](https://github.com/FliegendeWurst/TriliumDroid). Uwaga: podczas +korzystania z TriliumDroid najlepiej wyłączyć automatyczne aktualizacje +instalacji serwerowej (zobacz poniżej), ponieważ wersja synchronizacji musi być +zgodna między Trilium i TriliumDroid. + +### Serwer + +Aby zainstalować TriliumNext na własnym serwerze (w tym za pomocą Dockera z +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)), postępuj zgodnie z +[dokumentacją instalacji +serwerowej](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Dołącz do rozwoju projektu + +### Tłumaczenia + +Jeśli jesteś rodzimym użytkownikiem danego języka, pomóż nam w tłumaczeniu +Trilium, przechodząc na naszą stronę +[Weblate](https://hosted.weblate.org/engage/trilium/). + +Oto aktualny stan tłumaczeń na poszczególne języki: + +[![Status +tłumaczeń](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Kod + +Pobierz repozytorium, zainstaluj zależności za pomocą `pnpm`, a następnie +uruchom serwer (dostępny pod adresem http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Dokumentacja + +Pobierz repozytorium, zainstaluj zależności za pomocą `pnpm`, a następnie +uruchom środowisko wymagane do edycji dokumentacji: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Tworzenie pliku wykonywalnego +Pobierz repozytorium, zainstaluj zależności przy użyciu `pnpm`, a następnie +skompiluj aplikację desktopową dla Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Więcej szczegółów znajdziesz w [dokumentacji +deweloperskiej](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Dokumentacja Deweloperska + +Szczegóły znajdziesz w [przewodniku po +dokumentacji](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md). +W razie dodatkowych pytań możesz skorzystać z linków podanych w sekcji +ā€žPorozmawiaj z namiā€ powyżej. + +## šŸ‘ Podziękowania + +* [zadam](https://github.com/zadam) za stworzenie pierwotnej koncepcji i + implementację aplikacji. +* [Sarah Hussein](https://github.com/Sarah-Hussein) za zaprojektowanie ikony + aplikacji. +* [nriver](https://github.com/nriver) za prace nad wersjami językowymi. +* [Thomas Frei](https://github.com/thfrei) za pierwotne prace nad Canvas. +* [antoniotejada](https://github.com/nriver) za pierwotny widżet podświetlania + składni. +* [Dosu](https://dosu.dev/) za stworzenie rozwiązania umożliwiającego + automatyczne odpowiedzi w GitHub Issues i GitHub Discussions. +* [Tabler Icons](https://tabler.io/icons) za ikony zasobnika systemowego. + +Trilium nie byłoby możliwe bez technologii, które za nim stoją: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) — wizualny edytor stojący + za notatkami tekstowymi. Jesteśmy wdzięczni za udostępnienie nam zestawu + funkcji premium. +* [CodeMirror](https://github.com/codemirror/CodeMirror) — edytor kodu z obsługą + ogromnej liczby języków. +* [Excalidraw](https://github.com/excalidraw/excalidraw) — nieskończona tablica + wykorzystywana w notatkach typu Canvas. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) — biblioteka do + tworzenia map myśli. +* [Leaflet](https://github.com/Leaflet/Leaflet) — do renderowania map + geograficznych. +* [Tabulator](https://github.com/olifolkerd/tabulator) — do interaktywnych tabel + wykorzystywanych w kolekcjach. +* [FancyTree](https://github.com/mar10/fancytree) — bogata w funkcje biblioteka + drzew, praktycznie bez konkurencji. +* [jsPlumb](https://github.com/jsplumb/jsplumb) — biblioteka do wizualnego + łączenia elementów. Wykorzystywana w [mapach + relacji](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + oraz [mapach + linków](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Wsparcie + +Trilium powstaje i jest utrzymywane dzięki [setkom godzin +pracy](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Twoje +wsparcie pozwala nam rozwijać projekt open source i pokrywać koszty, takie jak +hosting. + +Jeśli chcesz wesprzeć głównego twórcę aplikacji +([eliandoran](https://github.com/eliandoran)), możesz to zrobić poprzez: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ Licencja + +Prawa autorskie 2017–2025 zadam, Elian Doran oraz pozostali współtwórcy + +Ten program jest ( open-source ) - możesz go redystrybuować i/lub modyfikować +zgodnie z postanowieniami licencji GNU Affero General Public License, +opublikowanej przez Free Software Foundation, w wersji 3 lub (według uznania) +dowolnej nowszej wersji. diff --git a/docs/README-pt.md b/docs/README-pt.md new file mode 100644 index 0000000000..ec5452b759 --- /dev/null +++ b/docs/README-pt.md @@ -0,0 +1,338 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes Ć© uma aplicação gratuita e de código aberto, multiplataforma, para +a criação hierĆ”rquica de notas, com foco na construção de grandes bases de +conhecimento pessoais. + +Trilium Screenshot + +## ā¬ Transferir +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š Documentação + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +A nossa documentação estĆ” disponĆ­vel em mĆŗltiplos formatos: +- **Online Documentation**: Browse the full documentation at + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation + directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Links rĆ”pidos +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-pt_BR.md b/docs/README-pt_BR.md new file mode 100644 index 0000000000..484b0bac82 --- /dev/null +++ b/docs/README-pt_BR.md @@ -0,0 +1,339 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![Patrocinadores +LiberaPay](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![Downloads no GitHub (todos os arquivos, todas as +versƵes)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Status da +tradução](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes Ć© uma aplicação de anotaƧƵes gratuita e de código aberto, +multiplataforma e hierĆ”rquica, com foco em construir grandes bases de +conhecimento pessoal. + +Trilium Screenshot + +## ā¬ Baixar +- [Último lanƧamento](https://github.com/TriliumNext/Trilium/releases/latest) - + versĆ£o estĆ”vel, recomendada para a maioria dos usuĆ”rios. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + versĆ£o de desenvolvimento instĆ”vel, atualizada diariamente com os recursos e + correƧƵes mais recentes. + +## šŸ“š Documentação + +**Visite nossa documentação completa em +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Nossa documentação estĆ” disponĆ­vel em vĆ”rios formatos: +- **Documentação online:** Navegue pela documentação completa em + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Ajuda no aplicativo**: Pressione `F1` dentro do Trilium para acessar a mesma + documentação diretamente no aplicativo +- **GitHub**: Navegue pelo [User Guide](./User%20Guide/User%20Guide/) neste + repositório + +### Links rĆ”pidos +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-ro.md b/docs/README-ro.md new file mode 100644 index 0000000000..f89f0d1822 --- /dev/null +++ b/docs/README-ro.md @@ -0,0 +1,345 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![Sponsori prin GitHub](https://img.shields.io/github/sponsors/eliandoran) +![Sponsori prin LiberaPay](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Descărcări pe Docker](https://img.shields.io/docker/pulls/triliumnext/trilium) +![Descărcări pe GitHub (toate variantele, toate +release-urile)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Starea +traducerilor](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes este o aplicație gratuită și open-source pentru notițe structurate +ierarhic cu scopul de a crea o bază de date de cunoștințe personală, de mari +dimensiuni. + +Trilium Screenshot + +## ā¬ Descarcă +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + versiune stabilă, recomandată pentru majoritatea utilizatorilor. +- [Versiune + periodică](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + versiune pentru dezvoltare și testare, actualizată zilnic și cu ultimele + funcționalități și buguri reparate. + +## šŸ“š Documentație + +**Vizitați documentația noastră detaliată la +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Documentația este disponibilă Ć®n mai multe formate: +- **Documentație online**: vizualizați Ć®ntreaga documentație la + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Ghid Ć®n aplicație**: Apăsați `F1` Ć®n Trilium pentru a accesa aceeași + documentație local, direct din aplicație +- **GitHub**: Navigați [ghidul de utilizator](./User%20Guide/User%20Guide/) + direct din acest repository + +### Linkuri rapide +- [Ghid rapid](https://docs.triliumnotes.org/) +- [Instrucțiuni de instalare](https://docs.triliumnotes.org/user-guide/setup) +- [Instalare prin + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Procesul de + actualizare](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Concepte de bază și + funcții](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Concepte pentru o bază de date de cunoștințe + personală](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Funcții + +* Notițele pot fi aranjate Ć®ntr-o structură ierarhică cu o adĆ¢ncime nelimitată. + O singură notiță poate fi plasată Ć®n mai multe locuri Ć®n abore (vedeți + [procesul de + clonare](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Editor vizual de notițe cu suport de tabele, imagini și [ecuații + matematice](https://docs.triliumnotes.org/user-guide/note-types/text) cu + [auto-formatare Ć®n stil + Markdown](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Suport for editarea [notițelor de tip cod + sursă](https://docs.triliumnotes.org/user-guide/note-types/code), inclusiv cu + evidențierea sintaxei +* [Navigare rapidă printre + notițe](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + căutare Ć®n conținutul notițelor și [focalizarea + notițelor](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Salvarea transparentă a [reviziilor + notițelor](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* [Attribute](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + pentru organizarea și căutarea notițelor, dar și posibilitatea de [script-uri + avansate](https://docs.triliumnotes.org/user-guide/scripts) +* Interfața grafică este disponibilă Ć®n mai multe limbi, dintre care și limba + romĆ¢nă +* [Integrare directă cu OpenID and + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) pentru o + autentificare mai sigură +* [Sincronizare](https://docs.triliumnotes.org/user-guide/setup/synchronization) + cu un server propriu + * există [servicii terțe pentru găzduirea unui server de + sincronizare](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Partajarea](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publicarea) notițelor pe Internet +* [Criptare + puternică](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + la nivel de notițe +* Desenare liberă, folosind [Excalidraw](https://excalidraw.com/) (notițe de tip + ā€žschiČ›Äƒā€) +* [Hărți ale + relaților](https://docs.triliumnotes.org/user-guide/note-types/relation-map) + și [hărți ale + notițelor/legăturilor](https://docs.triliumnotes.org/user-guide/note-types/note-map) + pentru vizualizarea notițelor și relaților acestora +* Hărți mentale, bazate pe [Mind Elixir](https://docs.mind-elixir.com/) +* [Hărți + geografice](https://docs.triliumnotes.org/user-guide/collections/geomap) cu + marcaje și trasee GPX +* [Scriptare](https://docs.triliumnotes.org/user-guide/scripts) - vedeți + [Prezentare + avansată](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [API-uri REST](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) + pentru automatizare +* Suportă peste 100 de mii de notițe fără impact de performanță +* [Interfață de mobil optimizată pentru touch + screen](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) pentru + telefoane mobile și tablete +* [Temă Ć®ntunecată](https://docs.triliumnotes.org/user-guide/concepts/themes) + predefinită, dar și suport pentru teme personalizate +* Import și export pentru + [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + și + [Markdown](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) + pentru salvarea rapidă a conținutului de pe Internet +* Interfață grafică personalizabilă (butoane, widget-uri definite de utilizator, + ...) +* [Metrice](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + Ć®mpreună cu un dashboard Grafana. + +✨ Consultați următoarele resurse din partea comunității Trilium: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) pentru teme + adiționale, script-uri, plugin-uri și altele. +- [TriliumRocks!](https://trilium.rocks/) pentru tutoriale, ghiduri și altele. + +## ā“De ce TriliumNext? + +Primul dezvoltator ([Zadam](https://github.com/zadam)) a oferit repository-ul +original către fork-ul TriliumNext aflat la https://github.com/TriliumNext + +### ā¬†ļø Migrare de la versiunea originală (Zadam/Trilium)? + +Nu există pași speciali de a migra de la o instanță de zadam/Trilium. Pur și +simplu [instalați TriliumNext/Trilium](#-installation) Ć®n mod obișnuit și va +utiliza baza de date existentă. + +Versiunile pĆ¢nă la +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) inclusiv +sunt compatibile cu ultima versiune zadam/trilium, anume +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Toate +versiunile mai noi au versiune de sincronizare mai mare, ce previn migrarea +directă. + +## šŸ’¬ Discută cu noi + +Participați la canalele noastre oficiale. Ne-ar plăcea să știm ce funcții, +sugestii sau probleme aveți! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (pentru discuții Ć®n timp + real.) + - Camera de chat `General` se partajează și prin + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Discuții pe GitHub](https://github.com/TriliumNext/Trilium/discussions) + (pentru discuții de tip forum) +- [GitHub Issues](https://github.com/TriliumNext/Trilium/issues) (pentru + rapoarte de bug-uri și cereri de funcționalități.) + +## šŸ— Procesul de instalare + +### Windows / macOS + +Descărcați release-ul binar pentru platforma dvs. de pe pagina [ultimului +release](https://github.com/TriliumNext/Trilium/releases/latest), dezarhivați și +rulați executabilul `trilium`. + +### Linux + +Dacă distribuția dvs. de Linux este listată Ć®n tabelul de mai jos, puteți folosi +pachetul specific acelei distribuții. + +[![Stare +Ć®mpachetare](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +De asemenea puteți descărca release-ul binar de pe [pagina ultimului +release](https://github.com/TriliumNext/Trilium/releases/latest), dezarhivați +pachetul și rulați executabilul `trilium`. + +Trilium vine și sub formă de Flatpak, dar nu este Ć®ncă publicată pe FlatHub. + +### Navigator web (orice sistem de operare) + +Dacă folosiți varianta de server (vedeți mai jos), puteți accesa direct +interfața web (care este aproape identică aplicației desktop). + +Doar ultimele versiuni de Chrome și Firefox sunt suportate și testate. + +### Mobil + +Pentru a putea folosi Trilium pe mobil, puteți folosi un navigator web pentru a +putea accesa interfața de mobil a unei instalări server (vedeți mai jos). + +Consultați https://github.com/TriliumNext/Trilium/issues/4962 pentru mai multe +informații despre suportul aplicației de mobil. + +Dacă preferați o aplicație nativă de Android, puteți folosi +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Bug-urile și cererile de funcționalități pentru această aplicație trebuie +reportate la [repository-ul +lor](https://github.com/FliegendeWurst/TriliumDroid). Notă: este recomandat să +se dezactiveze update-urile automatizate la server (vedeți mai jos) deoarece +versiunea de sincronizare uneori rămĆ¢ne Ć®n urmă la aplicația de mobil. + +### Server + +Pentru a instala Trilium pe server (inclusiv prin Docker din +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)), urmați [documentația +de instalare a +server-ului](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Moduri de a contribui + +### Traduceri + +Dacă sunteți un vorbitor experimentat al unei alte limbi, ne puteți ajuta să +traduceți Trilium prin intermediul +[Weblate](https://hosted.weblate.org/engage/trilium/). + +Aceasta este acoperirea traducerilor per limbă: + +[![Starea +traducerilor](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Cod + +Descărcați repository-ul, instalați dependențele folosind `pnpm` și apoi rulați +server-ul (disponibil la http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentație + +Descărcați repository-ul, instalați dependințele folosind `pnpm` și apoi rulați +mediul de editare a documentației: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Compilarea executabilului +Descărcați repository-ul, instalați dependințele utilizĆ¢nd `pnpm` și compilați +aplicația de desktop pentru Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Pentru mai multe detalii, vedeți [documentația pentru +dezvoltare](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Documentația pentru dezvoltatori + +Urmărți +[documentația](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +pentru mai multe detalii. Dacă aveți Ć®ntrebări, puteți să ne contactați folosind +legăturile descrise Ć®n secțiunea ā€žDiscutați cu noiā€ de mai sus. + +## šŸ‘ Mențiuni + +* [zadam](https://github.com/zadam) pentru conceptul și implementarea originală + a aplicației. +* [Sarah Hussein](https://github.com/Sarah-Hussein) pentru proiectarea + pictogramei aplicației. +* [nriver](https://github.com/nriver) pentru sistemul de internaționalizare. +* [Thomas Frei](https://github.com/thfrei) pentru munca sa originală pentru + notițele de tip schiță. +* [antoniotejada](https://github.com/nriver) pentru implementarea originală a + widget-ului de evidențiere al sintaxei. +* [Dosu](https://dosu.dev/) pentru răspunsurile automate la issue-urile de pe + GitHub și discuții. +* [Tabler Icons](https://tabler.io/icons) pentru iconițele din bara de sistem. + +Trilium nu ar fi fost posibil fără tehnologiile pe care este bazat: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - editorul vizual din + spatele notițelor de tip text. Suntem recunoscători pentru setul de + funcționalități premium. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - editorul de cod cu + suport pentru foarte multe limbaje de programare. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - tehnologia de + desenare folosită Ć®n notițele de tip schiță. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - pentru + funcționalitatea de tip hartă mentală. +* [Leaflet](https://github.com/Leaflet/Leaflet) - pentru randarea hărților + geografice. +* [Tabulator](https://github.com/olifolkerd/tabulator) - pentru tabele + interactive folosite Ć®n colecții. +* [FancyTree](https://github.com/mar10/fancytree) - bibliotecă pentru + vizualizare de tip arbore. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - bibliotecă de conectivitate + vizuală. Folosită Ć®n [hărți de tip + relație](https://docs.triliumnotes.org/user-guide/note-types/relation-map) și + [hărți de + legături](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Sprijiniți proiectul + +Trilium este construit și menținut prin efortul [a sute de ore de +muncă](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Sprijinul +dvs. permite să-l menținem open-source, să Ć®mbunătățim funcționalitățile și să +acoperim costuri suplimentare precum găzduirea. + +Considerați sprijinirea dezvoltatorului principal al aplicației +([eliandoran](https://github.com/eliandoran)) prin intermediul: + +- [Sponsori GitHub](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ Licență + +Copyright 2017-2025 zadam, Elian Doran și alți contribuitori + +Acest program este liber: se poate redistribui și se poate modifica sub termenii +licenței GNU Affero General Public License publicată de către Free Software +Foundation, fie versiunea 3 a licenței sau (Ć®n funcție de preferință) orice +versiune ulterioară. diff --git a/docs/README-ru.md b/docs/README-ru.md new file mode 100644 index 0000000000..500b7ed15c --- /dev/null +++ b/docs/README-ru.md @@ -0,0 +1,346 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![Дпонсоры GitHub](https://img.shields.io/github/sponsors/eliandoran) ![ŠœŠµŃ†ŠµŠ½Š°Ń‚Ń‹ +LiberaPay ](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Š—Š°Š³Ń€ŃƒŠ·Š¾Šŗ Docker](https://img.shields.io/docker/pulls/triliumnext/trilium) +![Š—Š°Š³Ń€ŃƒŠ·Š¾Šŗ GitHub (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![ŠŸŃ€Š¾Ń†ŠµŃŃ +перевоГа](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes – ŃŃ‚Š¾ приложение Š“Š»Ń заметок с иерархической ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š¾Š¹, +ориентированное на созГание Š±Š¾Š»ŃŒŃˆŠøŃ… ŠæŠµŃ€ŃŠ¾Š½Š°Š»ŃŒŠ½Ń‹Ń… баз знаний. + +Trilium Screenshot + +## ā¬ Š—Š°Š³Ń€ŃƒŠ·ŠŗŠ° +- [ПослеГний релиз](https://github.com/TriliumNext/Trilium/releases/latest) – + ŃŃ‚Š°Š±ŠøŠ»ŃŒŠ½Š°Ń Š²ŠµŃ€ŃŠøŃ, поГойГёт Š“Š»Ń Š±Š¾Š»ŃŒŃˆŠøŠ½ŃŃ‚Š²Š° ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŠµŠ¹. +- [ŠŠ¾Ń‡Š½Š¾Š¹ билГ](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + Š½ŠµŃŃ‚Š°Š±ŠøŠ»ŃŒŠ½Š°Ń Ń€Š°Š·Ń€Š°Š±Š°Ń‚Ń‹Š²Š°ŠµŠ¼Š°Ń Š²ŠµŃ€ŃŠøŃ, ежеГневно ŠæŠ¾Š»ŃƒŃ‡Š°ŠµŃ‚ новые Ń„ŃƒŠ½ŠŗŃ†ŠøŠø Šø + ŠøŃŠæŃ€Š°Š²Š»ŠµŠ½ŠøŃ. + +## šŸ“š Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃ + +**ŠŸŠ¾Š»Š½Š°Ń Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃ по Š°Š“Ń€ŠµŃŃƒ +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃ Š“Š¾ŃŃ‚ŃƒŠæŠ½Š° в Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøŃ… форматах: +- **ŠžŠ½Š»Š°Š¹Š½ Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃ**: ŠŸŠ¾Š»Š½Š°Ń Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃ Š“Š¾ŃŃ‚ŃƒŠæŠ½Š° по Š°Š“Ń€ŠµŃŃƒ: + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Дправка в приложении**: ŠŠ°Š¶Š¼ŠøŃ‚Šµ`F1` в Trilium Š“Š»Ń Š“Š¾ŃŃ‚ŃƒŠæŠ° Šŗ ŃŃ‚Š¾Š¹ + Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŠø ŠæŃ€ŃŠ¼Š¾ в приложении +- **GitHub**: ŠžŠ·Š½Š°ŠŗŠ¾Š¼ŃŒŃ‚ŠµŃŃŒ с [Š ŃƒŠŗŠ¾Š²Š¾Š“ŃŃ‚Š²Š¾Š¼ + ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń](./User%20Guide/User%20Guide/) в ŃŃ‚Š¾Š¼ репозитории + +### Важные Дсылки +- [Š ŃƒŠŗŠ¾Š²Š¾Š“ŃŃ‚Š²Š¾ по Š½Š°Ń‡Š°Š»Ńƒ работы](https://docs.triliumnotes.org/) +- [Š˜Š½ŃŃ‚Ń€ŃƒŠŗŃ†ŠøŃ по ŃƒŃŃ‚Š°Š½Š¾Š²ŠŗŠµ](https://docs.triliumnotes.org/user-guide/setup) +- [Установка + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [ŠžŠ±Š½Š¾Š²Š»ŠµŠ½ŠøŠµ + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [ŠžŃŠ½Š¾Š²Š½Ń‹Šµ иГеи Šø + возможности](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Шаблоны ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŃŒŠ½Ń‹Š¹ Базы + Знаний](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Возможности + +* Заметки можно Ń€Š°ŃŠæŠ¾Š»Š¾Š¶ŠøŃ‚ŃŒ в виГе Герева ŠæŃ€Š¾ŠøŠ·Š²Š¾Š»ŃŒŠ½Š¾Š¹ Š³Š»ŃƒŠ±ŠøŠ½Ń‹. ŠžŃ‚Š“ŠµŠ»ŃŒŠ½ŃƒŃŽ + Š·Š°Š¼ŠµŃ‚ŠŗŃƒ можно Ń€Š°Š·Š¼ŠµŃŃ‚ŠøŃ‚ŃŒ в Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøŃ… местах Герева (см. + [клонирование](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* ŠŸŃ€Š¾Š“Š²ŠøŠ½ŃƒŃ‚Ń‹Š¹ Š²ŠøŠ·ŃƒŠ°Š»ŃŒŠ½Ń‹Š¹ реГактор (WYSIWYG) ŠæŠ¾Š·Š²Š¾Š»ŃŠµŃ‚ Ń€Š°Š±Š¾Ń‚Š°Ń‚ŃŒ с таблицами, + ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃŠ¼Šø, + [Ń„Š¾Ń€Š¼ŃƒŠ»Š°Š¼Šø](https://docs.triliumnotes.org/user-guide/note-types/text) Šø + разметкой markdown, имеет + [автоформатирование](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* РеГактирование [заметок с исхоГным + коГом](https://docs.triliumnotes.org/user-guide/note-types/code), Š²ŠŗŠ»ŃŽŃ‡Š°Ń + ŠæŠ¾Š“ŃŠ²ŠµŃ‚ŠŗŃƒ синтаксиса +* Š‘Ń‹ŃŃ‚Ń€Š°Ń Šø ŠæŃ€Š¾ŃŃ‚Š°Ń [Š½Š°Š²ŠøŠ³Š°Ń†ŠøŃ межГу + заметками](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + полнотекстовый поиск Šø [режим Ń„Š¾ŠŗŃƒŃŠ° на + заметке](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Š‘ŠµŃŃˆŠ¾Š²Š½Š¾Šµ [версионирование + заметки](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Š”ŠæŠµŃ†ŠøŠ°Š»ŃŒŠ½Ń‹Šµ + [Š°Ń‚Ń€ŠøŠ±ŃƒŃ‚Ń‹](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + ŠæŠ¾Š·Š²Š¾Š»ŃŃŽŃ‚ гибко Š¾Ń€Š³Š°Š½ŠøŠ·Š¾Š²Š°Ń‚ŃŒ ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ńƒ, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃŽŃ‚ŃŃ Š“Š»Ń поиска Šø ŠæŃ€Š¾Š“Š²ŠøŠ½ŃƒŃ‚Š¾Š³Š¾ + [скриптинга](https://docs.triliumnotes.org/user-guide/scripts) +* Š˜Š½Ń‚ŠµŃ€Ń„ŠµŠ¹Ń Š“Š¾ŃŃ‚ŃƒŠæŠµŠ½ на Английском, ŠŠµŠ¼ŠµŃ†ŠŗŠ¾Š¼, Испанском, Š¤Ń€Š°Š½Ń†ŃƒŠ·ŃŠŗŠ¾Š¼, Š ŃƒŠ¼Ń‹Š½ŃŠŗŠ¾Š¼ + Šø ŠšŠøŃ‚Š°Š¹ŃŠŗŠ¾Š¼ (ŃƒŠæŃ€Š¾Ń‰Ń‘Š½Š½Š¾Š¼ Šø траГиционном) +* Š˜Š½Ń‚ŠµŠ³Ń€Š°Ń†ŠøŃ [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) Š“Š»Ń + более безопасного вхоГа +* [Š”ŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·Š°Ń†ŠøŃ](https://docs.triliumnotes.org/user-guide/setup/synchronization) + заметок со своим сервером + * ŃŃƒŃ‰ŠµŃŃ‚Š²ŃƒŃŽŃ‚ [сторонние сервисы Š“Š»Ń хостинга сервера + синхронизации](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [ŠŸŃƒŠ±Š»ŠøŠŗŠ°Ń†ŠøŃ](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + заметок в открытом Š“Š¾ŃŃ‚ŃƒŠæŠµ в Š˜Š½Ń‚ернете +* ŠŠ°Š“Ń‘Š¶Š½Š¾Šµ + [ŃˆŠøŃ„Ń€Š¾Š²Š°Š½ŠøŠµ](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + с Гетализацией по кажГой заметке +* Рисование Šø скетчинг Гиаграм, при помощи [Excalidraw](https://excalidraw.com/) + (тип заметки "холст") +* [ŠšŠ°Ń€Ń‚Ń‹ + ŃŠ²ŃŠ·ŠµŠ¹](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [карты заметок](https://docs.triliumnotes.org/user-guide/note-types/note-map) + Š“Š»Ń Š²ŠøŠ·ŃƒŠ°Š»ŠøŠ·Š°Ń†ŠøŠø заметок Šø ŠøŃ… ŃŠ²ŃŠ·ŠµŠ¹ +* Š˜Š½Ń‚ŠµŠ»Š»ŠµŠŗŃ‚-карты на основе [Mind Elixir](https://docs.mind-elixir.com/) +* [ŠšŠ°Ń€Ń‚Ń‹](https://docs.triliumnotes.org/user-guide/collections/geomap) с метками + Š“Š»Ń мест Šø треками GPX +* [Дкрипты](https://docs.triliumnotes.org/user-guide/scripts) - см. [ŠæŃ€Š¾Š“Š²ŠøŠ½ŃƒŃ‚Ń‹Šµ + примеры](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) Š“Š»Ń + автоматизации +* Š„Š¾Ń€Š¾ŃˆŠ¾ Š¼Š°ŃŃˆŃ‚Š°Š±ŠøŃ€ŃƒŠµŃ‚ŃŃ, как по ŃƒŠ“Š¾Š±ŃŃ‚Š²Ńƒ ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŃ, так Šø по + ŠæŃ€Š¾ŠøŠ·Š²Š¾Š“ŠøŃ‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚Šø Го 100000 заметок +* ŠžŠæŃ‚ŠøŠ¼ŠøŠ·ŠøŃ€Š¾Š²Š°Š½Š½Ń‹Š¹ [Š¼Š¾Š±ŠøŠ»ŃŒŠ½Ń‹Š¹ + фронтенГ](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) + смартфонов Šø ŠæŠ»Š°Š½ŃˆŠµŃ‚Š¾Š² +* [Š¢ŠµŠ¼Š½Š°Ń тема](https://docs.triliumnotes.org/user-guide/concepts/themes) +* Š˜Š¼ŠæŠ¾Ń€Ń‚ Šø ŃŠŗŠæŠ¾Ń€Ń‚ + [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + Šø Ганных в + [markdown](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) + формате +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) Š“Š»Ń + уГобного ŃŠ¾Ń…Ń€Š°Š½ŠµŠ½ŠøŃ веб-контента +* ŠŠ°ŃŃ‚Ń€Š°ŠøŠ²Š°ŠµŠ¼Ń‹Š¹ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹ интерфейс (кнопки боковой панели, + ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠµ виГжеты Šø т. Š“.) +* [ŠœŠµŃ‚Ń€ŠøŠŗŠø](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), а + также панель мониторинга Grafana. + +✨ ŠžŠ·Š½Š°ŠŗŠ¾Š¼ŃŒŃ‚ŠµŃŃŒ со ŃŠ»ŠµŠ“ŃƒŃŽŃ‰ŠøŠ¼Šø сторонними Ń€ŠµŃŃƒŃ€ŃŠ°Š¼Šø/сообществами, чтобы найти +больше полезной информации о TriliumNext: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) - сторонние темы, + скриптов, плагинов Šø многого Š“Ń€ŃƒŠ³Š¾Š³Š¾. +- [TriliumRocks!](https://trilium.rocks/) — Š¾Š±ŃƒŃ‡Š°ŃŽŃ‰ŠøŠµ материалы, Ń€ŃƒŠŗŠ¾Š²Š¾Š“ŃŃ‚Š²Š° Šø + многое Š“Ń€ŃƒŠ³Š¾Šµ. + +## ā“ŠŸŠ¾Ń‡ŠµŠ¼Ńƒ именно TriliumNext? + +ŠžŃ€ŠøŠ³ŠøŠ½Š°Š»ŃŒŠ½Ń‹Š¹ разработчик Trilium ([Zadam](https://github.com/zadam)) Š»ŃŽŠ±ŠµŠ·Š½Š¾ +преГоставил репозиторий Trilium ŠæŃ€Š¾ŠµŠŗŃ‚Ńƒ сообщества, который Š½Š°Ń…Š¾Š“ŠøŃ‚ŃŃ по Š°Š“Ń€ŠµŃŃƒ +https://github.com/TriliumNext + +### ā¬†ļøŠŸŠµŃ€ŠµŃ…Š¾Š“ŠøŃ‚Šµ с Zadam/Trilium? + +Š”Š»Ń миграции с ŃŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° zadam/Trilium на ŃŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€ TriliumNext/Trilium не +Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ŃŃ никаких Š“Š¾ŠæŠ¾Š»Š½ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Ń… шагов. ŠŸŃ€Š¾ŃŃ‚Š¾ [ŃƒŃŃ‚Š°Š½Š¾Š²ŠøŃ‚Šµ +TriliumNext/Trilium](#-installation) как обычно, Šø он Š±ŃƒŠ“ет ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ вашу +ŃŃƒŃ‰ŠµŃŃ‚Š²ŃƒŃŽŃ‰ŃƒŃŽ базу Ганных. + +Версии Го [v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) +Š²ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŠµŠ»ŃŒŠ½Š¾ совместимы с послеГней версией zadam/trilium +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Š’ более +позГних Š²ŠµŃ€ŃŠøŃŃ… TriliumNext/Trilium версии схемы Ганных Š¾Ń‚Š»ŠøŃ‡Š°ŃŽŃ‚ŃŃ сильнее, что +ŠæŃ€ŠµŠæŃŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ ŠæŃ€ŃŠ¼Š¾Š¹ миграции. + +## šŸ’¬ ŠžŠ±ŃŃƒŠ“ŠøŃ‚Šµ с нами + +ŠŸŃ€ŠøŠ³Š»Š°ŃˆŠ°ŠµŠ¼ вас ŠæŃ€ŠøŃŠ¾ŠµŠ“ŠøŠ½ŠøŃ‚ŃŒŃŃ Šŗ нашим Š¾Ń„ŠøŃ†ŠøŠ°Š»ŃŒŠ½Ń‹Š¼ Š¾Š±ŃŃƒŠ¶Š“ŠµŠ½ŠøŃŠ¼. ŠœŃ‹ буГем раГы +ŃƒŠ·Š½Š°Ń‚ŃŒ о Š²Š°ŃˆŠøŃ… ŠæŃ€ŠµŠ“Š»Š¾Š¶ŠµŠ½ŠøŃŃ… по ŃƒŠ»ŃƒŃ‡ŃˆŠµŠ½ŠøŃŽ, ŠøŠ“ŠµŃŃ… или проблемах! + +- [ŠœŠ°Ń‚Ń€ŠøŃ†Š°](https://matrix.to/#/#triliumnext:matrix.org) (Š”Š»Ń оперативной + ŠŗŠ¾Š¼Š¼ŃƒŠ½ŠøŠŗŠ°Ń†ŠøŠø.) + - ŠšŠ¾Š¼Š½Š°Ń‚Š° `General` в Matrix также ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Š° Šŗ + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [ŠžŠ±ŃŃƒŠ¶Š“ŠµŠ½ŠøŃ на Github](https://github.com/TriliumNext/Trilium/discussions) + (Š”Š»Ń асинхронных обсужГений.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (Š”Š»Ń сообщений + об Š¾ŃˆŠøŠ±ŠŗŠ°Ń… Šø запросов на Гобавление новых Ń„ŃƒŠ½ŠŗŃ†ŠøŠ¹.) + +## šŸ— Дборки + +### Windows / macOS + +Š—Š°Š³Ń€ŃƒŠ·ŠøŃ‚Šµ бинарный релиз Š“Š»Ń вашей платформы с [страницы послеГнего +релиза](https://github.com/TriliumNext/Trilium/releases/latest), Ń€Š°ŃŠæŠ°ŠŗŃƒŠ¹Ń‚Šµ +пакет Šø Š·Š°ŠæŃƒŃŃ‚ŠøŃ‚Šµ ŠøŃŠæŠ¾Š»Š½ŃŠµŠ¼Ń‹Š¹ файл `trilium`. + +### Linux + +Если ваш Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ² указан в таблице ниже, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ пакет, ŃŠ¾Š¾Ń‚Š²ŠµŃ‚ŃŃ‚Š²ŃƒŃŽŃ‰ŠøŠ¹ +вашему Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Ńƒ. + +[![Š”Š¾ŃŃ‚ŃƒŠæŠ½Š¾ŃŃ‚ŃŒ](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +Š’Ń‹ также можете Š·Š°Š³Ń€ŃƒŠ·ŠøŃ‚ŃŒ бинарный релиз Š“Š»Ń вашей платформы со [страницы +послеГнего релиза](https://github.com/TriliumNext/Trilium/releases/latest), +Ń€Š°ŃŠæŠ°ŠŗŠ¾Š²Š°Ń‚ŃŒ пакет Šø Š·Š°ŠæŃƒŃŃ‚ŠøŃ‚ŃŒ ŠøŃŠæŠ¾Š»Š½ŃŠµŠ¼Ń‹Š¹ файл `trilium`. + +TriliumNext также ŠæŃ€ŠµŠ“Š¾ŃŃ‚Š°Š²Š»ŃŠµŃ‚ŃŃ в виГе Flatpak-пакета, но пока не опубликован +на FlatHub. + +### Š‘Ń€Š°ŃƒŠ·ŠµŃ€ (Š»ŃŽŠ±Š°Ń ŠžŠ”) + +Если вы ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚Šµ ŃŠµŃ€Š²ŠµŃ€Š½ŃƒŃŽ ŃƒŃŃ‚Š°Š½Š¾Š²ŠŗŃƒ (см. ниже), вы можете ŠæŠ¾Š»ŃƒŃ‡ŠøŃ‚ŃŒ ŠæŃ€ŃŠ¼Š¾Š¹ +Š“Š¾ŃŃ‚ŃƒŠæ Šŗ веб-ŠøŠ½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŃƒ (который практически иГентичен Š½Š°ŃŃ‚Š¾Š»ŃŒŠ½Š¾Š¼Ńƒ ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃŽ). + +Š’ Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‚ŃŃ (Šø протестированы) Ń‚Š¾Š»ŃŒŠŗŠ¾ послеГние версии +Chrome Šø Firefox. + +### ŠœŠ¾Š±ŠøŠ»ŃŒŠ½Š°Ń Š²ŠµŃ€ŃŠøŃ + +Š”Š»Ń ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŃ TriliumNext на мобильном ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Šµ вы можете ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ +Š¼Š¾Š±ŠøŠ»ŃŒŠ½Ń‹Š¹ веб-Š±Ń€Š°ŃƒŠ·ŠµŃ€ Š“Š»Ń Š“Š¾ŃŃ‚ŃƒŠæŠ° Šŗ мобильному ŠøŠ½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŃƒ сервера (см. ниже). + +Š”Š¾ŠæŠ¾Š»Š½ŠøŃ‚ŠµŠ»ŃŒŠ½ŃƒŃŽ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃŽ о поГГержке Š¼Š¾Š±ŠøŠ»ŃŒŠ½Ń‹Ń… приложений см. в треГе +https://github.com/TriliumNext/Trilium/issues/4962. + +Если вы преГпочитаете нативное приложение Š“Š»Ń Android, вы можете ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Дообщайте об Š¾ŃˆŠøŠ±ŠŗŠ°Ń… Šø Š½ŠµŠ“Š¾ŃŃ‚Š°ŃŽŃ‰ŠøŃ… Ń„ŃƒŠ½ŠŗŃ†ŠøŃŃ… в [ŠøŃ… +репозитории](https://github.com/FliegendeWurst/TriliumDroid). ŠŸŃ€ŠøŠ¼ŠµŃ‡Š°Š½ŠøŠµ: при +использовании TriliumDroid Š»ŃƒŃ‡ŃˆŠµ Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ автоматические Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŃ на вашем +сервере (см. ниже), поскольку синхронизированные версии Голжны ŃŠ¾Š²ŠæŠ°Š“Š°Ń‚ŃŒ межГу +Trilium Šø TriliumDroid. + +### Дервер + +Чтобы ŃƒŃŃ‚Š°Š½Š¾Š²ŠøŃ‚ŃŒ TriliumNext на свой собственный сервер (в том числе через +Docker ŠøŠ· [Dockerhub](https://hub.docker.com/r/triliumnext/trilium)), ŃŠ»ŠµŠ“ŃƒŠ¹Ń‚Šµ +[Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŠø по ŃƒŃŃ‚Š°Š½Š¾Š²ŠŗŠµ +сервера](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Š£Ń‡Š°ŃŃ‚Š²ŃƒŠ¹Ń‚Šµ в разработке + +### ŠŸŠµŃ€ŠµŠ²Š¾Š“Ń‹ + +Если вы ŃŠ²Š»ŃŠµŃ‚ŠµŃŃŒ носителем ŃŠ·Ń‹ŠŗŠ°, помогите нам перевести Trilium, ŠæŠµŃ€ŠµŠ¹Š“Ń на +нашу [ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ Weblate](https://hosted.weblate.org/engage/trilium/). + +Что сГелано на Ганный момент: + +[![Š”Ń‚Š°Ń‚ŃƒŃ +перевоГа](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### КоГ + +Дкачайте репозиторий, ŃƒŃŃ‚Š°Š½Š¾Š²ŠøŃ‚Šµ зависимости с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ `pnpm`, затем Š·Š°ŠæŃƒŃŃ‚ите +сервер (Š“Š¾ŃŃ‚ŃƒŠæŠµŠ½ по Š°Š“Ń€ŠµŃŃƒ http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃ + +Дкачайте репозиторий, ŃƒŃŃ‚Š°Š½Š¾Š²ŠøŃ‚Šµ зависимости с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ `pnpm`, затем Š·Š°ŠæŃƒŃŃ‚ите +Š¾ŠŗŃ€ŃƒŠ¶ŠµŠ½ŠøŠµ, необхоГимое Š“Š»Ń реГактирование Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŠø: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Дборка ŠøŃŠæŠ¾Š»Š½ŃŠµŠ¼Š¾Š³Š¾ файла +Дкачайте репозиторий, ŃƒŃŃ‚Š°Š½Š¾Š²ŠøŃ‚Šµ зависимости с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ `pnpm`, затем соберите +приложение Š“Š»Ń Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Š”Š»Ń ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½ŠøŃ поГробностей, смотрите [Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ń‹ +разработки](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃ Š“Š»Ń разработчиков + +ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, Š¾Š·Š½Š°ŠŗŠ¾Š¼ŃŒŃ‚ŠµŃŃŒ с +[Ń€ŃƒŠŗŠ¾Š²Š¾Š“ŃŃ‚Š²Š¾Š¼](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +Š“Š»Ń ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½ŠøŃ поГробной информации. Если у вас Š²Š¾Š·Š½ŠøŠŗŠ½ŃƒŃ‚ Š“Š¾ŠæŠ¾Š»Š½ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Šµ вопросы, +вы можете ŃŠ²ŃŠ·Š°Ń‚ŃŒŃŃ с нами, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃ ссылки, ŃƒŠŗŠ°Š·Š°Š½Š½Ń‹Šµ в разГеле Ā«ŠžŠ±ŃŃƒŠ“ŠøŃ‚Šµ с +нами» Š²Ń‹ŃˆŠµ. + +## šŸ‘ БлагоГарности + +* [zadam](https://github.com/zadam) за Š¾Ń€ŠøŠ³ŠøŠ½Š°Š»ŃŒŠ½Ń‹Š¹ концепт Šø Ń€ŠµŠ°Š»ŠøŠ·Š°Ń†ŠøŃŽ + ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ. +* [Sarah Hussein](https://github.com/Sarah-Hussein) за созГание иконки + ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ. +* [nriver](https://github.com/nriver) за Ń€Š°Š±Š¾Ń‚Ńƒ по интернационализации. +* [Thomas Frei](https://github.com/thfrei) за его Š¾Ń€ŠøŠ³ŠøŠ½Š°Š»ŃŒŠ½ŃƒŃŽ Ń€Š°Š±Š¾Ń‚Ńƒ наГ + Єолстом. +* [antoniotejada](https://github.com/nriver) за Š¾Ń€ŠøŠ³ŠøŠ½Š°Š»ŃŒŠ½Ń‹Š¹ виГжет поГсветки + синтаксиса. +* [Dosu](https://dosu.dev/) за обеспечение автоматических ответов на вопросы Šø + Š¾Š±ŃŃƒŠ¶Š“ŠµŠ½ŠøŃ GitHub. +* [Tabler Icons](https://tabler.io/icons) за системные иконки. + +Trilium не ŃŃƒŃ‰ŠµŃŃ‚Š²Š¾Š²Š°Š» бы без технологий, лежащих в его основе: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - Š²ŠøŠ·ŃƒŠ°Š»ŃŒŠ½Ń‹Š¹ реГактор + текстовых заметок. ŠœŃ‹ благоГарны за преГоставленный нам набор Š“Š¾ŠæŠ¾Š»Š½ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Š¹ + Ń„ŃƒŠ½ŠŗŃ†ŠøŠ¹. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - реГактор коГа с + поГГержкой огромного количества ŃŠ·Ń‹ŠŗŠ¾Š². +* [Excalidraw](https://github.com/excalidraw/excalidraw) - Š±ŠµŃŠŗŠ¾Š½ŠµŃ‡Š½Š°Ń Š±ŠµŠ»Š°Ń + Госка, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŠ¼Š°Ń в заметках типа "Єолст". +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - обеспечивает + Ń„ŃƒŠ½ŠŗŃ†ŠøŠ¾Š½ŠøŃ€Š¾Š²Š°Š½ŠøŠµ Š¼ŠµŠ½Ń‚Š°Š»ŃŒŠ½Š¾Š¹ карты. +* [Leaflet](https://github.com/Leaflet/Leaflet) - отображение географических + карт. +* [Tabulator](https://github.com/olifolkerd/tabulator) - интерактивные таблицы, + ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŠ¼Ń‹Šµ в ŠŗŠ¾Š»Š»ŠµŠŗŃ†ŠøŃŃ…. +* [FancyTree](https://github.com/mar10/fancytree) - Š¼Š½Š¾Š³Š¾Ń„ŃƒŠ½ŠŗŃ†ŠøŠ¾Š½Š°Š»ŃŒŠ½Š°Ń + библиотека Š“ŠµŃ€ŠµŠ²ŃŒŠµŠ², не ŠøŠ¼ŠµŃŽŃ‰Š°Ń себе равных. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - библиотека Š²ŠøŠ·ŃƒŠ°Š»ŃŒŠ½Ń‹Ń… ŃŠ²ŃŠ·ŠµŠ¹. + Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ŃŃ в [картах + ŃŠ²ŃŠ·ŠµŠ¹](https://docs.triliumnotes.org/user-guide/note-types/relation-map) Šø + [картах + ссылок](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠŗŠ° + +ŠŠ° созГание Šø ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠŗŃƒ Trilium затрачены [сотни часов +работы](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Š’Š°ŃˆŠ° +поГГержка помогает ему Š¾ŃŃ‚Š°Š²Š°Ń‚ŃŒŃŃ open-source, ŃƒŠ»ŃƒŃ‡ŃˆŠ°ŠµŃ‚ Ń„ŃƒŠ½ŠŗŃ†ŠøŠø Šø покрывает +расхоГы, такие как хостинг. + +Š’Ń‹ также можете ŠæŠ¾Š“Š“ŠµŃ€Š¶Š°Ń‚ŃŒ главного разработчика ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ +([eliandoran](https://github.com/eliandoran)) с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ: + +- [Дпонсоры GitHub](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ Š›ŠøŃ†ŠµŠ½Š·ŠøŃ + +Copyright 2017-2025 zadam, Elian Doran Šø Š“Ń€ŃƒŠ³ŠøŠµ авторы + +Эта программа ŃŠ²Š»ŃŠµŃ‚ŃŃ бесплатным программным обеспечением: вы можете +Ń€Š°ŃŠæŃ€Š¾ŃŃ‚Ń€Š°Š½ŃŃ‚ŃŒ Šø/или ŠøŠ·Š¼ŠµŠ½ŃŃ‚ŃŒ ее в соответствии с ŃƒŃŠ»Š¾Š²ŠøŃŠ¼Šø GNU Affero General +Public License, опубликованной Free Software Foundation, либо версии 3 Лицензии, +либо (по вашему Š²Ń‹Š±Š¾Ń€Ńƒ) Š»ŃŽŠ±Š¾Š¹ более позГней версии. diff --git a/docs/README-sl.md b/docs/README-sl.md new file mode 100644 index 0000000000..0da3a37bf9 --- /dev/null +++ b/docs/README-sl.md @@ -0,0 +1,337 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking +application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation + directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-sr.md b/docs/README-sr.md new file mode 100644 index 0000000000..0da3a37bf9 --- /dev/null +++ b/docs/README-sr.md @@ -0,0 +1,337 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all +releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Translation +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking +application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + unstable development version, updated daily with the latest features and + fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation + directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in + this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and + Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-sv.md b/docs/README-sv.md new file mode 100644 index 0000000000..6fa0aea8a3 --- /dev/null +++ b/docs/README-sv.md @@ -0,0 +1,336 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsorer](https://img.shields.io/github/sponsors/eliandoran) +![LiberalPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Nedladdningar (alla resurser, alla +utgĆ„vor)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![ƖversƤttning +status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes Ƥr fritt med ƶppen kƤllkod, plattformsoberoende hierarkisk +antecknings app med fokus pĆ„ att bygga en stor personlig kunskapsbas. + +Trilium Screenshot + +## Ladda ner +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + stabil version, rekommenderas fƶr dom flesta anvƤndare. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) - + ostabil utvecklings version, uppdaterad dagligen med de senaste funktionerna + och fixarna. + +## šŸ“š Dokumentation + +**LƤs mer i vĆ„r omfattande dokumentation pĆ„ +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +VĆ„r dokumentation Ƥr tillgƤnglig i flera format: +- **Webb dokumentation**: LƤs hela dokumentationen pĆ„ + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **I-appen-hjƤlp**: Tryck `F1` i Trilium fƶr att lƤsa samma dokumentation inuti + programmet +- **GitHub**: LƤs [anvƤndarhandboken](./User%20Guide/User%20Guide/) i denna repo + +### SnabblƤnkar +- [Snabbstartsguide](https://docs.triliumnotes.org/) +- [Installationsanvisning](https://docs.triliumnotes.org/user-guide/setup) +- [Docker + Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Uppdaterar + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [GrundlƤggande koncept och + funktioner](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Modeller av personlig + kunskapsbas](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Funktioner + +* Anteckningar kan sorteras som en trƤdstruktur. En enskild anteckning kan + placeras pĆ„ fler Ƥn en plats i trƤdet (se + [kloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-tr.md b/docs/README-tr.md new file mode 100644 index 0000000000..9d9a7bc2db --- /dev/null +++ b/docs/README-tr.md @@ -0,0 +1,334 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notlar + +![GitHub Sponsorları](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay DestekƧileri](https://img.shields.io/liberapay/patrons/ElianDoran) \ +![Docker İndirme +Sayısı](https://img.shields.io/docker/pulls/triliumnext/trilium) ![GitHub +İndirmeleri (tüm varlıklar, tüm +sürümler)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Ƈeviri +Durumu](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes, büyük kişisel bilgi tabanları oluşturmaya odaklanmış, ücretsiz ve +aƧık kaynaklı, Ƨapraz platform hiyerarşik bir not alma uygulamasıdır. + +Trilium Screenshot + +## İndir +- [Son sürüm](https://github.com/TriliumNext/Trilium/releases/latest) – stabil + versiyon, standart kullanıcılar iƧin tavsiye edilir. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + kararsız geliştirme sürümü, son ƶzellikler ve iyileştirmelerle günlük olarak + güncellenir. + +## Dokümantasyon + +**Kapsamlı dokümanlarımızı [docs.triliumnotes.org] adresinden ziyaret +edin(https://docs.triliumnotes.org/)** + +Dokümantasyonumuz birden fazla formatta mevcuttur: +- **ƇevrimiƧi Dƶkümantasyon**: Tüm dƶkümantasyonu gƶrebilmek iƧin + [docs.triliumnotes.org](https://docs.triliumnotes.org/)'a uğrayın +- **Uygulama iƧi Yardım**: Aynı dƶkümantasyona ulaşmak iƧin Trillium + iƧerisindeyken `F1` tuşuna basın +- **Github**: Bu repodaki [Kullanıcı Rehberi] sayfasına yƶnelin + +### Hızlı linkler +- [BaşlangıƧ Kılavuzu](https://docs.triliumnotes.org/) +- Kurulum Klavuzu +- Docker kurulumu +- [TrilliumNext Güncelleme] +- Basit Kavramlar ve Ɩzellikler +- [Patterns of Personal Knowledge + Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Ɩzellikler + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed + into multiple places in the tree (see + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and + [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown + [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source + code](https://docs.triliumnotes.org/user-guide/note-types/code), including + syntax highlighting +* Fast and easy [navigation between + notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + full text search and [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note + versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note + [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + can be used for note organization, querying and advanced + [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese + (simplified and traditional) +* Direct [OpenID and TOTP + integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for + more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) + with self-hosted sync server + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (publishing) notes to public internet +* Strong [note + encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with + location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced + showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for + automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for + smartphones and tablets +* Built-in [dark + theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for + user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + and [Markdown import & + export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for + easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext +related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party + themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has +graciously given the Trilium repository to the community project which resides +at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to +a TriliumNext/Trilium instance. Simply [install +TriliumNext/Trilium](#-installation) as usual and it will use your existing +database. + +Versions up to and including +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are +compatible with the latest zadam/trilium version of +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later +versions of TriliumNext/Trilium have their sync versions incremented which +prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what +features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous + discussions.) + - The `General` Matrix room is also bridged to + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For + asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug + reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release +page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package +and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's +package. + +[![Packaging +status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README-uk.md b/docs/README-uk.md new file mode 100644 index 0000000000..9258684bdf --- /dev/null +++ b/docs/README-uk.md @@ -0,0 +1,347 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![Дпонсори GitHub](https://img.shields.io/github/sponsors/eliandoran) +![ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń– LiberaPay](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![Š—Š°Š²Š°Š½Ń‚Š°Š¶ŠµŠ½Š½Ń GitHub (всі Ń€ŠµŃŃƒŃ€ŃŠø, всі +релізи)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![Š”Ń‚Š°Ń‚ŃƒŃ +ŠæŠµŃ€ŠµŠŗŠ»Š°Š“Ńƒ](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes — це Š±ŠµŠ·ŠŗŠ¾ŃˆŃ‚овний кросплатформний ієрархічний ГоГаток Š“Š»Ń Š²ŠµŠ“ŠµŠ½Š½Ń +нотаток Š· віГкритим коГом, орієнтований на ŃŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń великих ŠæŠµŃ€ŃŠ¾Š½Š°Š»ŃŒŠ½ŠøŃ… баз +знань. + +Trilium Screenshot + +## ā¬ Завантажити +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – + ŃŃ‚Š°Š±Ń–Š»ŃŒŠ½Š° Š²ŠµŃ€ŃŃ–Ń, рекоменГована Š“Š»Ń Š±Ń–Š»ŃŒŃˆŠ¾ŃŃ‚Ń– ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š². +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – + Š½ŠµŃŃ‚Š°Š±Ń–Š»ŃŒŠ½Š° Š²ŠµŃ€ŃŃ–Ń Š“Š»Ń розробників, Ń‰Š¾Š“Š½Ń Š¾Š½Š¾Š²Š»ŃŽŃ”Ń‚ŃŒŃŃ Š½Š°Š¹Š½Š¾Š²Ń–ŃˆŠøŠ¼Šø Ń„ŃƒŠ½ŠŗŃ†Ń–ŃŠ¼Šø та + Š²ŠøŠæŃ€Š°Š²Š»ŠµŠ½Š½ŃŠ¼Šø. + +## šŸ“š Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń + +**ВіГвіГайте нашу Š²ŠøŃ‡ŠµŃ€ŠæŠ½Ńƒ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–ŃŽ за Š°Š“Ń€ŠµŃŠ¾ŃŽ +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +ŠŠ°ŃˆŠ° Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń Š“Š¾ŃŃ‚ŃƒŠæŠ½Š° в ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… форматах: +- **ŠžŠ½Š»Š°Š¹Š½-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń**: ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃŒŃ‚Šµ повну Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–ŃŽ на сайті + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **ДовіГка в Š“Š¾Š“Š°Ń‚ŠŗŃƒ**: ŠŠ°Ń‚ŠøŃŠ½Ń–Ń‚ŃŒ `F1` у Trilium, щоб отримати Š“Š¾ŃŃ‚ŃƒŠæ Го тієї ж + Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń— Š±ŠµŠ·ŠæŠ¾ŃŠµŃ€ŠµŠ“Š½ŃŒŠ¾ в Š“Š¾Š“Š°Ń‚ŠŗŃƒ +- **GitHub**: ŠŸŠµŃ€ŠµŠ³Š»ŃŠ“ [ŠŸŠ¾ŃŃ–Š±Š½ŠøŠŗŠ° ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°](./User%20Guide/User%20Guide/) у + Ń†ŃŒŠ¾Š¼Ńƒ репозиторії + +### ШвиГкі ŠæŠ¾ŃŠøŠ»Š°Š½Š½Ń +- [ŠŸŠ¾ŃŃ–Š±Š½ŠøŠŗ Ń–Š· ŠæŠ¾Ń‡Š°Ń‚ŠŗŃƒ роботи](https://docs.triliumnotes.org/) +- [Š†Š½ŃŃ‚Ń€ŃƒŠŗŃ†Ń–Ń— Š· Š²ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š½Ń](https://docs.triliumnotes.org/user-guide/setup) +- [ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [ŠžŠ½Š¾Š²Š»ŠµŠ½Š½Ń + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [ŠžŃŠ½Š¾Š²Š½Ń– ŠæŠ¾Š½ŃŃ‚Ń‚Ń та + Ń„ŃƒŠ½ŠŗŃ†Ń–Ń—](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Шаблони особистої бази + знань](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ ŠœŠ¾Š¶Š»ŠøŠ²Š¾ŃŃ‚Ń– + +* ŠŠ¾Ń‚Š°Ń‚ŠŗŠø можна Ń€Š¾Š·Ń‚Š°ŃˆŃƒŠ²Š°Ń‚Šø в Герево Š“Š¾Š²Ń–Š»ŃŒŠ½Š¾Ń— глибини. ŠžŠ“Š½Ńƒ Š½Š¾Ń‚Š°Ń‚ŠŗŃƒ можна + розмістити в ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… Š¼Ń–ŃŃ†ŃŃ… Герева (Гив. + [ŠŗŠ»Š¾Š½ŃƒŠ²Š°Š½Š½Ń](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Багатий WYSIWYG-реГактор нотаток, Š²ŠŗŠ»ŃŽŃ‡Š°ŃŽŃ‡Šø, наприклаГ, таблиці, Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń та + [Š¼Š°Ń‚ŠµŠ¼Š°Ń‚ŠøŠŗŃƒ](https://docs.triliumnotes.org/user-guide/note-types/text) Š· + markdown + [автоформат](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* ŠŸŃ–Š“Ń‚Ń€ŠøŠ¼ŠŗŠ° Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń [нотатки Š· вихіГним + коГом](https://docs.triliumnotes.org/user-guide/note-types/code), Š²ŠŗŠ»ŃŽŃ‡Š°ŃŽŃ‡Šø + ŠæŃ–Š“ŃŠ²Ń–Ń‡ŃƒŠ²Š°Š½Š½Ń ŃŠøŠ½Ń‚Š°ŠŗŃŠøŃŃƒ +* ШвиГка та проста [Š½Š°Š²Ń–Š³Š°Ń†Ń–Ń між + нотатками](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), + повнотекстовий пошук та [хостінг + нотаток](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Š‘ŠµŠ·ŃˆŠ¾Š²Š½Šµ [ŠŗŠµŃ€ŃƒŠ²Š°Š½Š½Ń Š²ŠµŃ€ŃŃ–ŃŠ¼Šø + нотаток](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* [ŠŃ‚Ń€ŠøŠ±ŃƒŃ‚Šø](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) + нотатки можна Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø Š“Š»Ń організації нотаток, запитів та Ń€Š¾Š·ŃˆŠøŃ€ŠµŠ½Š¾Š³Š¾ + [ŃŃ€ŠøŠæŃ‚Ń–Š½Š³Ńƒ](https://docs.triliumnotes.org/user-guide/scripts) +* Інтерфейс ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° Š“Š¾ŃŃ‚ŃƒŠæŠ½ŠøŠ¹ Š°Š½Š³Š»Ń–Š¹ŃŃŒŠŗŠ¾ŃŽ, Š½Ń–Š¼ŠµŃ†ŃŒŠŗŠ¾ŃŽ, Ń–ŃŠæŠ°Š½ŃŃŒŠŗŠ¾ŃŽ, + Ń„Ń€Š°Š½Ń†ŃƒŠ·ŃŒŠŗŠ¾ŃŽ, Ń€ŃƒŠ¼ŃƒŠ½ŃŃŒŠŗŠ¾ŃŽ та ŠŗŠøŃ‚Š°Š¹ŃŃŒŠŗŠ¾ŃŽ (ŃŠæŃ€Š¾Ń‰ŠµŠ½Š¾ŃŽ та Ń‚Ń€Š°Š“ŠøŃ†Ń–Š¹Š½Š¾ŃŽ) мовами +* ŠŸŃ€ŃŠ¼Š° [OpenID та TOTP + Ń–Š½Ń‚ŠµŠ³Ń€Š°Ń†Ń–Ń](https://docs.triliumnotes.org/user-guide/setup/server/mfa) Š“Š»Ń + Š±ŠµŠ·ŠæŠµŃ‡Š½Ń–ŃˆŠ¾Š³Š¾ Š²Ń…Š¾Š“Ńƒ +* [Š”ŠøŠ½Ń…Ń€Š¾Š½Ń–Š·Š°Ń†Ń–Ń](https://docs.triliumnotes.org/user-guide/setup/synchronization) + Ń–Š· власним сервером синхронізації + * Ń–ŃŠ½ŃƒŃŽŃ‚ŃŒ [сторонні сервіси Š“Š»Ń Ń€Š¾Š·Š¼Ń–Ń‰ŠµŠ½Š½Ń сервера + синхронізації](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Š”ŠæŃ–Š»ŃŒŠ½Šµ + Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (ŠæŃƒŠ±Š»Ń–ŠŗŠ°Ń†Ń–Ń) нотаток у Š·Š°Š³Š°Š»ŃŒŠ½Š¾Š“Š¾ŃŃ‚ŃƒŠæŠ½Š¾Š¼Ńƒ інтернеті +* ŠŠ°Š“Ń–Š¹Š½Šµ [ŃˆŠøŃ„Ń€ŃƒŠ²Š°Š½Š½Ń + нотаток](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + Š· Š“ŠµŃ‚Š°Š»Ń–Š·Š°Ń†Ń–Ń”ŃŽ Š“Š»Ń кожної нотатки +* Š”Ń‚Š²Š¾Ń€ŠµŠ½Š½Ń ескізних схем на основі [Excalidraw](https://excalidraw.com/) (тип + нотатки "полотно") +* [ŠšŠ°Ń€Ń‚Šø + зв'ŃŠ·ŠŗŃ–Š²](https://docs.triliumnotes.org/user-guide/note-types/relation-map) та + [карти + нотаток/посилань](https://docs.triliumnotes.org/user-guide/note-types/note-map) + Š“Š»Ń Š²Ń–Š·ŃƒŠ°Š»Ń–Š·Š°Ń†Ń–Ń— нотаток та їх зв'ŃŠ·ŠŗŃ–Š² +* Інтелект-карти, засновані на [Mind Elixir](https://docs.mind-elixir.com/) +* [Геокарти](https://docs.triliumnotes.org/user-guide/collections/geomap) Š· + географічними позначками та GPX-треками +* [Дценарії](https://docs.triliumnotes.org/user-guide/scripts) – Гив. [Š Š¾Š·ŃˆŠøŃ€ŠµŠ½Ń– + Гемонстрації](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) Š“Š»Ń + автоматизації +* Добре Š¼Š°ŃŃˆŃ‚Š°Š±ŃƒŃ”Ń‚ŃŒŃŃ ŃŠŗ за Š·Ń€ŃƒŃ‡Š½Ń–стю Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń, так і за ŠæŃ€Š¾Š“ŃƒŠŗŃ‚ŠøŠ²Š½Ń–ŃŃ‚ŃŽ Го + 100 000 нотаток +* ŠžŠæŃ‚ŠøŠ¼Ń–Š·Š¾Š²Š°Š½Š¾ Š“Š»Ń сенсорного ŠŗŠµŃ€ŃƒŠ²Š°Š½Š½Ń [Š¼Š¾Š±Ń–Š»ŃŒŠ½ŠøŠ¹ + інтерфейс](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) Š“Š»Ń + смартфонів і ŠæŠ»Š°Š½ŃˆŠµŃ‚Ń–Š² +* Š’Š±ŃƒŠ“Š¾Š²Š°Š½Š° [темна + тема](https://docs.triliumnotes.org/user-guide/concepts/themes), піГтримка тем + ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + та [Markdown імпорт & + експорт](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) Š“Š»Ń + легкого Š·Š±ŠµŃ€ŠµŠ¶ŠµŠ½Š½Ń веб-ŠŗŠ¾Š½Ń‚ŠµŠ½Ń‚Ńƒ +* ŠŠ°ŃŃ‚Ń€Š¾ŃŽŠ²Š°Š½ŠøŠ¹ інтерфейс ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° (кнопки бічної панелі, віГжети, що + Š²ŠøŠ·Š½Š°Ń‡Š°ŃŽŃ‚ŃŒŃŃ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ŠµŠ¼, ...) +* [ŠœŠµŃ‚Ń€ŠøŠŗŠø](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), а + також панель Ń–Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Ń–Š² Grafana. + +✨ ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃŒŃ‚Šµ Š½Š°ŃŃ‚ŃƒŠæŠ½Ń– сторонні Ń€ŠµŃŃƒŃ€ŃŠø/ŃŠæŃ–Š»ŃŒŠ½Š¾Ń‚Šø, щоб Š“Ń–Š·Š½Š°Ń‚ŠøŃŃ Š±Ń–Š»ŃŒŃˆŠµ про +TriliumNext: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) Š“Š»Ń тем, + скриптів, плагінів тощо віГ сторонніх розробників. +- [TriliumRocks!](https://trilium.rocks/) Š“Š»Ń Š½Š°Š²Ń‡Š°Š»ŃŒŠ½ŠøŃ… посібників, Ń–Š½ŃŃ‚Ń€ŃƒŠŗŃ†Ń–Š¹ + та багато Ń–Š½ŃˆŠ¾Š³Š¾. + +## ā“Š§Š¾Š¼Ńƒ TriliumNext? + +ŠžŃ€ŠøŠ³Ń–Š½Š°Š»ŃŒŠ½ŠøŠ¹ розробник Trilium ([Zadam](https://github.com/zadam)) Š»ŃŽŠ±'ŃŠ·Š½Š¾ +наГав репозиторій Trilium ŃŠæŃ–Š»ŃŒŠ½Š¾Ń‚Š½Š¾Š¼Ńƒ ŠæŃ€Š¾ŠµŠŗŃ‚Ńƒ, ŃŠŗŠøŠ¹ Š·Š½Š°Ń…Š¾Š“ŠøŃ‚ŃŒŃŃ за Š°Š“Ń€ŠµŃŠ¾ŃŽ +https://github.com/TriliumNext + +### ā¬†ļøŠŸŠµŃ€ŠµŃ…Š¾Š“ŠøŃ‚Šµ Ń–Š· Zadam/Trilium? + +ŠŠµŠ¼Š°Ń” жоГних ŃŠæŠµŃ†Ń–Š°Š»ŃŒŠ½ŠøŃ… кроків Š“Š»Ń міграції Š· ŠµŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° zadam/Trilium Го +ŠµŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€Š° TriliumNext/Trilium. ŠŸŃ€Š¾ŃŃ‚Š¾ [Š²ŃŃ‚Š°Š½Š¾Š²Ń–Ń‚ŃŒ +TriliumNext/Trilium](#-installation) ŃŠŗ завжГи, і він Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚ŠøŠ¼Šµ вашу +Ń–ŃŠ½ŃƒŃŽŃ‡Ńƒ базу Ганих. + +Версії Го [v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) +Š²ŠŗŠ»ŃŽŃ‡Š½Š¾ ŃŃƒŠ¼Ń–ŃŠ½Ń– Š· Š¾ŃŃ‚Š°Š½Š½ŃŒŠ¾ŃŽ Š²ŠµŃ€ŃŃ–Ń”ŃŽ zadam/trilium +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Š‘ŃƒŠ“ŃŒ-ŃŠŗŃ– +ŠæŃ–Š·Š½Ń–ŃˆŃ– версії TriliumNext/Trilium Š¼Š°ŃŽŃ‚ŃŒ Š·Š±Ń–Š»ŃŒŃˆŠµŠ½Ń– версії синхронізації, що +запобігає ŠæŃ€ŃŠ¼Ń–Š¹ міграції. + +## ŠžŠ±Š³Š¾Š²Š¾Ń€Ń–Ń‚ŃŒ це Š· нами + +ŠŠµ ŃŠ¾Ń€Š¾Š¼Ń‚ŠµŃŃ ŠæŃ€ŠøŃ”Š“Š½ŃƒŠ²Š°Ń‚ŠøŃŃ Го Š½Š°ŃˆŠøŃ… офіційних Š¾Š±Š³Š¾Š²Š¾Ń€ŠµŠ½ŃŒ. Ми буГемо раГі ŠæŠ¾Ń‡ŃƒŃ‚Šø +про Š²Š°ŃˆŃ– Ń„ŃƒŠ½ŠŗŃ†Ń–Ń—, пропозиції чи проблеми! + +- [ŠœŠ°Ń‚Ń€ŠøŃ†Ń](https://matrix.to/#/#triliumnext:matrix.org) (Š”Š»Ń синхронних + Š¾Š±Š³Š¾Š²Š¾Ń€ŠµŠ½ŃŒ.) + - ŠšŃ–Š¼Š½Š°Ń‚Š° матриці `Š—Š°Š³Š°Š»ŃŒŠ½Ń–` також ŠæŃ–Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Š° Го + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [ŠžŠ±Š³Š¾Š²Š¾Ń€ŠµŠ½Š½Ń на Github](https://github.com/TriliumNext/Trilium/discussions) + (Š”Š»Ń асинхронних Š¾Š±Š³Š¾Š²Š¾Ń€ŠµŠ½ŃŒ.) +- [ŠŸŃ€Š¾Š±Š»ŠµŠ¼Šø Github](https://github.com/TriliumNext/Trilium/issues) (Š”Š»Ń звітів + про помилки та запитів на нові Ń„ŃƒŠ½ŠŗŃ†Ń–Ń—.) + +## šŸ— Š’ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š½Ń + +### Windows / MacOS + +Завантажте бінарний реліз Š“Š»Ń Š²Š°ŃˆŠ¾Ń— платформи Š·Ń– сторінки [Š¾ŃŃ‚Š°Š½Š½ŃŒŠ¾Š³Š¾ +Ń€ŠµŠ»Ń–Š·Ńƒ](https://github.com/TriliumNext/Trilium/releases/latest), Ń€Š¾Š·ŠæŠ°ŠŗŃƒŠ¹Ń‚Šµ +пакет і Š·Š°ŠæŃƒŃŃ‚Ń–Ń‚ŃŒ виконуваний файл `trilium`. + +### Linux + +Якщо ваш Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ² зазначено в таблиці нижче, Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ¹Ń‚Šµ пакет вашого +Š“ŠøŃŃ‚Ń€ŠøŠ±ŃƒŃ‚ŠøŠ²Š°. + +[![Дтан +упаковки](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +Š’Šø також можете завантажити бінарний реліз Š“Š»Ń Š²Š°ŃˆŠ¾Ń— платформи Š·Ń– сторінки +[Š¾ŃŃ‚Š°Š½Š½ŃŒŠ¾Š³Š¾ Ń€ŠµŠ»Ń–Š·Ńƒ](https://github.com/TriliumNext/Trilium/releases/latest), +Ń€Š¾Š·ŠæŠ°ŠŗŃƒŠ²Š°Ń‚Šø пакет і Š·Š°ŠæŃƒŃŃ‚ŠøŃ‚Šø виконуваний файл `trilium`. + +TriliumNext також Š“Š¾ŃŃ‚ŃƒŠæŠ½ŠøŠ¹ у форматі Flatpak, але ще не Š¾ŠæŃƒŠ±Š»Ń–кований на +FlatHub. + +### Š‘Ń€Š°ŃƒŠ·ŠµŃ€ (буГь-ŃŠŗŠ° ŠžŠ”) + +Якщо ви Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚Šµ ŃŠµŃ€Š²ŠµŃ€Š½Ńƒ Ń–Š½ŃŃ‚Š°Š»ŃŃ†Ń–ŃŽ (Гив. нижче), ви можете отримати +безпосереГній Š“Š¾ŃŃ‚ŃƒŠæ Го веб-Ń–Š½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŃƒ (ŃŠŗŠøŠ¹ майже іГентичний Š“ŠµŃŠŗŃ‚Š¾ŠæŠ½Š¾Š¼Ńƒ +Š“Š¾Š“Š°Ń‚ŠŗŃƒ). + +ŠŠ°Ń€Š°Š·Ń– ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃŽŃ‚ŃŒŃŃ (і протестовані) лише Š½Š°Š¹Š½Š¾Š²Ń–ŃˆŃ– версії Chrome та Firefox. + +### ŠœŠ¾Š±Ń–Š»ŃŒŠ½ŠøŠ¹ + +Щоб Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø TriliumNext на Š¼Š¾Š±Ń–Š»ŃŒŠ½Š¾Š¼Ńƒ пристрої, ви можете ŃŠŗŠ¾Ń€ŠøŃŃ‚Š°Ń‚ŠøŃŃ +Š¼Š¾Š±Ń–Š»ŃŒŠ½ŠøŠ¼ веб-Š±Ń€Š°ŃƒŠ·ŠµŃ€Š¾Š¼ Š“Š»Ń Š“Š¾ŃŃ‚ŃƒŠæŃƒ Го Š¼Š¾Š±Ń–Š»ŃŒŠ½Š¾Š³Š¾ Ń–Š½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŃƒ серверної +Ń–Š½ŃŃ‚Š°Š»ŃŃ†Ń–Ń— (Гив. нижче). + +Див. випуск https://github.com/TriliumNext/Trilium/issues/4962 Š“Š»Ń Š¾Ń‚Ń€ŠøŠ¼Š°Š½Š½Ń +ГоГаткової інформації про ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŠŗŃƒ Š¼Š¾Š±Ń–Š»ŃŒŠ½ŠøŃ… ГоГатків. + +Якщо ви наГаєте ŠæŠµŃ€ŠµŠ²Š°Š³Ńƒ Ń€Ń–Š“Š½Š¾Š¼Ńƒ Š“Š¾Š“Š°Ń‚ŠŗŃƒ Š“Š»Ń Android, ви можете ŃŠŗŠ¾Ń€ŠøŃŃ‚Š°Ń‚ŠøŃŃ +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +ŠŸŠ¾Š²Ń–Š“Š¾Š¼Š»ŃŠ¹Ń‚Šµ про помилки та Š²Ń–Š“ŃŃƒŃ‚Š½Ń– Ń„ŃƒŠ½ŠŗŃ†Ń–Ń— на [Ń—Ń…Š½ŃŒŠ¾Š¼Ńƒ +репозиторії](https://github.com/FliegendeWurst/TriliumDroid). ŠŸŃ€ŠøŠ¼Ń–Ń‚ŠŗŠ°: ŠŠ°Š¹ŠŗŃ€Š°Ń‰Šµ +Š²ŠøŠ¼ŠŗŠ½ŃƒŃ‚Šø автоматичні Š¾Š½Š¾Š²Š»ŠµŠ½Š½Ń на вашому сервері (Гив. нижче) піГ час +Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń TriliumDroid, Š¾ŃŠŗŃ–Š»ŃŒŠŗŠø Š²ŠµŃ€ŃŃ–Ń синхронізації має Š·Š±Ń–Š³Š°Ń‚ŠøŃŃ між +Trilium та TriliumDroid. + +### Дервер + +Щоб встановити TriliumNext на власний сервер (зокрема через Docker Š· +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)), Š“Š¾Ń‚Ń€ŠøŠ¼ŃƒŠ¹Ń‚ŠµŃŃŒ +Ń–Š½ŃŃ‚Ń€ŃƒŠŗŃ†Ń–Š¹ [Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń— щоГо Š²ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š½Ń +сервера](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Š—Ń€Š¾Š±Ń–Ń‚ŃŒ свій внесок + +### ŠŸŠµŃ€ŠµŠŗŠ»Š°Š“Šø + +Якщо ви носій мови, Š“Š¾ŠæŠ¾Š¼Š¾Š¶Ń–Ń‚ŃŒ нам перекласти Trilium, ŠæŠµŃ€ŠµŠ¹ŃˆŠ¾Š²ŃˆŠø на нашу +[ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ Weblate](https://hosted.weblate.org/engage/trilium/). + +ŠžŃŃŒ мовне Š²ŠøŃŠ²Ń–Ń‚Š»ŠµŠ½Š½Ń, ŃŠŗŠµ ми маємо наразі: + +[![Дтан +ŠæŠµŃ€ŠµŠŗŠ»Š°Š“Ńƒ](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### КоГ + +Завантажте репозиторій, Š²ŃŃ‚Š°Š½Š¾Š²Ń–Ń‚ŃŒ залежності за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ `pnpm`, а потім +Š·Š°ŠæŃƒŃŃ‚Ń–Ń‚ŃŒ сервер (Š“Š¾ŃŃ‚ŃƒŠæŠ½ŠøŠ¹ за Š°Š“Ń€ŠµŃŠ¾ŃŽ http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń + +Завантажте репозиторій, Š²ŃŃ‚Š°Š½Š¾Š²Ń–Ń‚ŃŒ залежності за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ `pnpm`, а потім +Š·Š°ŠæŃƒŃŃ‚Ń–Ń‚ŃŒ сереГовище, необхіГне Š“Š»Ń Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń—: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Š”Ń‚Š²Š¾Ń€ŠµŠ½Š½Ń виконуваного Ń„Š°Š¹Š»Ńƒ +Завантажте репозиторій, Š²ŃŃ‚Š°Š½Š¾Š²Ń–Ń‚ŃŒ залежності за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ `pnpm`, а потім +Š·Š±ŠµŃ€Ń–Ń‚ŃŒ Š½Š°ŃŃ‚Ń–Š»ŃŒŠ½ŠøŠ¹ ГоГаток Š“Š»Ń Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +Š”Š»Ń Š¾Ń‚Ń€ŠøŠ¼Š°Š½Š½Ń ГоГаткової інформації Гив. [Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–ŃŽ +розробника](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń розробника + +Š‘ŃƒŠ“ŃŒ ласка, ŠæŠµŃ€ŠµŠ³Š»ŃŠ½ŃŒŃ‚Šµ +[Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–ŃŽ](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +Š“Š»Ń Š¾Ń‚Ń€ŠøŠ¼Š°Š½Š½Ń Š“ŠµŃ‚Š°Š»ŃŒŠ½Š¾Ń— інформації. Якщо у вас Š²ŠøŠ½ŠøŠŗŠ½ŃƒŃ‚ŃŒ ГоГаткові Š·Š°ŠæŠøŃ‚Š°Š½Š½Ń, +Š·Š²ŠµŃ€Ń‚Š°Š¹Ń‚ŠµŃŃ Го нас за ŠæŠ¾ŃŠøŠ»Š°Š½Š½ŃŠ¼Šø, описаними в розГілі Ā«ŠžŠ±Š³Š¾Š²Š¾Ń€Ń–Ń‚ŃŒ Š· нами» вище. + +## šŸ‘ ŠŸŃ€ŠøŠ²Ń–Ń‚Š°Š½Š½Ń + +* [zadam](https://github.com/zadam) за Š¾Ń€ŠøŠ³Ń–Š½Š°Š»ŃŒŠ½Ńƒ ŠŗŠ¾Š½Ń†ŠµŠæŃ†Ń–ŃŽ та Ń€ŠµŠ°Š»Ń–Š·Š°Ń†Ń–ŃŽ + Š·Š°ŃŃ‚Š¾ŃŃƒŠ½ŠŗŃƒ. +* [Sarah Hussein](https://github.com/Sarah-Hussein) за Ń€Š¾Š·Ń€Š¾Š±ŠŗŃƒ піктограми + програми. +* [nriver](https://github.com/nriver) за його Ń€Š¾Š±Š¾Ń‚Ńƒ Š· інтернаціоналізації. +* [Thomas Frei](https://github.com/thfrei) за його Š¾Ń€ŠøŠ³Ń–Š½Š°Š»ŃŒŠ½Ńƒ Ń€Š¾Š±Š¾Ń‚Ńƒ на Canvas. +* [antoniotejada](https://github.com/nriver) Š“Š»Ń Š¾Ń€ŠøŠ³Ń–Š½Š°Š»ŃŒŠ½Š¾Š³Š¾ віГжета + ŠæŃ–Š“ŃŠ²Ń–Ń‡ŃƒŠ²Š°Š½Š½Ń ŃŠøŠ½Ń‚Š°ŠŗŃŠøŃŃƒ. +* [Dosu](https://dosu.dev/) за Š½Š°Š“Š°Š½Š½Ń нам автоматичних віГповіГей на проблеми + та Š¾Š±Š³Š¾Š²Š¾Ń€ŠµŠ½Š½Ń GitHub. +* [Tabler Icons](https://tabler.io/icons) Š“Š»Ń значків у ŃŠøŃŃ‚ŠµŠ¼Š½Š¾Š¼Ńƒ треї. + +Trilium був би неможливим без технологій, що Š»ŠµŠ¶Š°Ń‚ŃŒ в його основі: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) – Š²Ń–Š·ŃƒŠ°Š»ŃŒŠ½ŠøŠ¹ реГактор + текстових нотаток. Ми Š²Š“ŃŃ‡Š½Ń– за те, що нам Š·Š°ŠæŃ€Š¾ŠæŠ¾Š½ŃƒŠ²Š°Š»Šø набір + ŠæŃ€ŠµŠ¼Ń–ŃƒŠ¼-Ń„ŃƒŠ½ŠŗŃ†Ń–Š¹. +* [CodeMirror](https://github.com/codemirror/CodeMirror) – реГактор коГу Š· + ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŠŗŠ¾ŃŽ величезної ŠŗŃ–Š»ŃŒŠŗŠ¾ŃŃ‚Ń– мов ŠæŃ€Š¾Š³Ń€Š°Š¼ŃƒŠ²Š°Š½Š½Ń. +* [Excalidraw](https://github.com/excalidraw/excalidraw) – нескінченна Гошка, що + Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚ŃŒŃŃ в нотатках Canvas. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) – Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŃƒŃ” + Ń„ŃƒŠ½ŠŗŃ†Ń–Š¾Š½Š°Š»ŃŒŠ½Ń–ŃŃ‚ŃŒ карти Ń€Š¾Š·ŃƒŠ¼Ńƒ. +* [Leaflet](https://github.com/Leaflet/Leaflet) – Š“Š»Ń Š²Ń–Š·ŃƒŠ°Š»Ń–Š·Š°Ń†Ń–Ń— географічних + карт. +* [Tabulator](https://github.com/olifolkerd/tabulator) – Š“Š»Ń інтерактивної + таблиці, що Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚ŃŒŃŃ в ŠŗŠ¾Š»ŠµŠŗŃ†Ń–ŃŃ…. +* [FancyTree](https://github.com/mar10/fancytree) – Š±Š°Š³Š°Ń‚Š¾Ń„ŃƒŠ½ŠŗŃ†Ń–Š¾Š½Š°Š»ŃŒŠ½Š° + бібліотека Герев без Ń€ŠµŠ°Š»ŃŒŠ½Š¾Ń— ŠŗŠ¾Š½ŠŗŃƒŃ€ŠµŠ½Ń†Ń–Ń—. +* [jsPlumb](https://github.com/jsplumb/jsplumb) – бібліотека Š²Ń–Š·ŃƒŠ°Š»ŃŒŠ½Š¾Ń— + Š·Š²ā€™ŃŠ·Š½Š¾ŃŃ‚Ń–. Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚ŃŒŃŃ в [картах + Š·Š²ā€™ŃŠ·ŠŗŃ–Š²](https://docs.triliumnotes.org/user-guide/note-types/relation-map) та + [картах + посилань](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ ŠŸŃ–Š“Ń‚Ń€ŠøŠ¼ŠŗŠ° + +Trilium створено та ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ”Ń‚ŃŒŃŃ [ŃŠ¾Ń‚Š½ŃŠ¼Šø гоГин +роботи](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Š’Š°ŃˆŠ° +піГтримка Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŃƒŃ” його віГкритий вихіГний коГ, ŠæŠ¾ŠŗŃ€Š°Ń‰ŃƒŃ” Ń„ŃƒŠ½ŠŗŃ†Ń–Ń— та покриває +витрати, такі ŃŠŗ хостинг. + +Š Š¾Š·Š³Š»ŃŠ½ŃŒŃ‚Šµ Š¼Š¾Š¶Š»ŠøŠ²Ń–ŃŃ‚ŃŒ піГтримки головного розробника +([eliandoran](https://github.com/eliandoran)) програми через: + +- [Дпонсори GitHub](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ Š›Ń–Ń†ŠµŠ½Š·Ń–Ń + +ŠŠ²Ń‚Š¾Ń€ŃŃŒŠŗŠµ право 2017-2025 Š½Š°Š»ŠµŠ¶ŠøŃ‚ŃŒ zadam, Elian Doran та Ń–Š½ŃˆŠøŠ¼ авторам + +Š¦Ń програма є Š²Ń–Š»ŃŒŠ½ŠøŠ¼ програмним Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŠµŠ½Š½ŃŠ¼: ви можете Ń€Š¾Š·ŠæŠ¾Š²ŃŃŽŠ“Š¶ŃƒŠ²Š°Ń‚Šø її +та/або Š·Š¼Ń–Š½ŃŽŠ²Š°Ń‚Šø віГповіГно Го умов Š—Š°Š³Š°Š»ŃŒŠ½Š¾Ń— ŠæŃƒŠ±Š»Ń–Ń‡Š½Š¾Ń— ліцензії GNU Affero, +Š¾ŠæŃƒŠ±Š»Ń–ŠŗŠ¾Š²Š°Š½Š¾Ń— ФонГом Š²Ń–Š»ŃŒŠ½Š¾Š³Š¾ програмного Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŠµŠ½Š½Ń, або версії 3 Ліцензії, +або (на ваш вибір) буГь-ŃŠŗŠ¾Ń— ŠæŃ–Š·Š½Ń–ŃˆŠ¾Ń— версії. diff --git a/docs/README-vi.md b/docs/README-vi.md new file mode 100644 index 0000000000..9149d450dd --- /dev/null +++ b/docs/README-vi.md @@ -0,0 +1,342 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) +![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran)\ +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (mį»i tĆ i nguyĆŖn, mį»i bįŗ£n phĆ”t +hĆ nh)](https://img.shields.io/github/downloads/triliumnext/trilium/total)\ +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) +[![TƬnh trįŗ”ng dịch +thuįŗ­t](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han +script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) +| [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) +| [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | +[Spanish](./README-es.md) + + +Trilium Notes lĆ  mį»™t ứng dỄng ghi chĆŗ phĆ¢n cįŗ„p miį»…n phĆ­, mĆ£ nguồn mở, đa nền +tįŗ£ng tįŗ­p trung vĆ o việc xĆ¢y dį»±ng cĘ” sở tri thức cĆ” nhĆ¢n lį»›n. + +Trilium Screenshot + +## ā¬ Tįŗ£i xuống +- [Bįŗ£n phĆ”t hĆ nh mį»›i + nhįŗ„t](https://github.com/TriliumNext/Trilium/releases/latest) – phiĆŖn bįŗ£n ổn + định, được khuyĆŖn dùng cho hįŗ§u hįŗæt ngĘ°į»i dùng. +- [Bįŗ£n dį»±ng + nightly](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – phiĆŖn + bįŗ£n phĆ”t triển kĆ©m ổn định, được cįŗ­p nhįŗ­t hĆ ng ngĆ y vį»›i cĆ”c tĆ­nh năng mį»›i nhįŗ„t + vĆ  sį»­a lį»—i. + +## šŸ“š TĆ i Liệu + +**Truy cįŗ­p tĆ i liệu toĆ n diện cį»§a chĆŗng tĆ“i tįŗ”i +[docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +TĆ i liệu cį»§a chĆŗng tĆ“i có sįŗµn ở nhiều định dįŗ”ng: +- **TĆ i liệu trį»±c tuyįŗæn**: Xem tĆ i liệu đầy đủ tįŗ”i + [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **Trợ giĆŗp trong ứng dỄng**: Nhįŗ„n `F1` trong Trilium Ä‘į»ƒ truy cįŗ­p tĆ i liệu + tʰʔng tį»± trį»±c tiįŗæp trong ứng dỄng +- **Github**: Đi đến [Hướng dįŗ«n sį»­ dỄng] trong kho lʰu trữ nĆ y + +### LiĆŖn Kįŗæt Nhanh +- [Hướng Dįŗ«n BįŗÆt Đầu](https://docs.triliumnotes.org/) +- [Hướng Dįŗ«n CĆ i Đặt](https://docs.triliumnotes.org/user-guide/setup) +- [Thiįŗæt Lįŗ­p + Docker](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Cįŗ­p Nhįŗ­t + TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [KhĆ”i Niệm VĆ  Chức Năng CĘ” + Bįŗ£n](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [CĆ”c Mįŗ«u CĘ” Sở Tri Thức CĆ” + NhĆ¢n](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Chức Năng + +* CĆ”c ghi chĆŗ có thể được sįŗÆp xįŗæp thĆ nh cĆ¢y có độ sĆ¢u bįŗ„t kỳ. Mį»™t ghi chĆŗ có thể + được đặt vĆ o nhiều nĘ”i trong cĆ¢y (xem + [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* TrƬnh soįŗ”n thįŗ£o ghi chĆŗ WYSIWYG đầy đủ tĆ­nh năng, hį»— trợ bįŗ£ng, hƬnh įŗ£nh, vĆ  + [toĆ”n hį»c](https://docs.triliumnotes.org/user-guide/note-types/text); đồng + thį»i [tį»± động định + dįŗ”ng](https://docs.triliumnotes.org/user-guide/note-types/text) sang markdown +* Hį»— trợ chỉnh sį»­a [ghi chĆŗ chứa mĆ£ + nguồn](https://docs.triliumnotes.org/user-guide/note-types/code), kĆØm tĆ“ sĆ”ng + cĆŗ phĆ”p +* [Điều hướng giữa cĆ”c ghi + chĆŗ](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation) + nhanh vĆ  dį»… dĆ ng, tƬm kiįŗæm toĆ n văn vĆ  [note + hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Quįŗ£n lý [phiĆŖn bįŗ£n ghi + chĆŗ](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) + mượt mĆ  +* [CĆ”c thuį»™c + tĆ­nh](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) ghi + chĆŗ có thể được dùng cho việc tổ chức, truy xuįŗ„t vĆ  [viįŗæt + script](https://docs.triliumnotes.org/user-guide/scripts) nĆ¢ng cao +* Giao diện sįŗµn có cho Tiįŗæng Anh, Tiįŗæng Đức, Tiįŗæng TĆ¢y Ban Nha, Tiįŗæng PhĆ”p, + Tiįŗæng Rumani, vĆ  Tiįŗæng Trung (giįŗ£n thể vĆ  phồn thể) +* [TĆ­ch hợp OpenID vĆ  + TOTP](https://docs.triliumnotes.org/user-guide/setup/server/mfa) trį»±c tiįŗæp Ä‘į»ƒ + đăng nhįŗ­p bįŗ£o mįŗ­t hĘ”n +* [Đồng bį»™ hóa](https://docs.triliumnotes.org/user-guide/setup/synchronization) + vį»›i mĆ”y chį»§ đồng bį»™ tį»± triển khai + * there are [3rd party services for hosting synchronisation + server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Chia sįŗ»](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) + (cĆ“ng bố) cĆ”c ghi chĆŗ lĆŖn mįŗ”ng Internet cĆ“ng cį»™ng +* [MĆ£ hóa ghi + chĆŗ](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) + mįŗ”nh mįŗ½ vį»›i mức chi tiįŗæt đến từng ghi chĆŗ +* PhĆ”c thįŗ£o sĘ” đồ, dį»±a trĆŖn [Excalidraw](https://excalidraw.com/) (loįŗ”i ghi chĆŗ + "canvas") +* [Relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) + for visualizing notes and their relations +* SĘ” đồ tʰ duy, dį»±a trĆŖn [Mind Elixir](https://docs.mind-elixir.com/) +* [Bįŗ£n đồ địa lý](https://docs.triliumnotes.org/user-guide/collections/geomap) + vį»›i cĆ”c chįŗ„m chỉ vị trĆ­ vĆ  cĆ”c Ä‘Ę°į»ng GPX +* [Viįŗæt script](https://docs.triliumnotes.org/user-guide/scripts) - xem [MỄc + trʰng bĆ y nĆ¢ng + cao](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) cho + tį»± động hóa +* Mở rį»™ng tốt về cįŗ£ khįŗ£ năng sį»­ dỄng vĆ  hiệu năng lĆŖn đến 100.000 ghi chĆŗ +* Tối ʰu hóa cįŗ£m ứng [mobile + frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) cho + điện thoįŗ”i thĆ“ng minh vĆ  mĆ”y tĆ­nh bįŗ£ng +* TĆ­ch hợp sįŗµn [giao diện + tối](https://docs.triliumnotes.org/user-guide/concepts/themes), hį»— trợ giao + diện do ngĘ°į»i dùng tùy chỉnh +* Hį»— trợ nhįŗ­p, xuįŗ„t cho + [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) + vĆ  + [Markdown](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) Ä‘į»ƒ + lʰu trữ nį»™i dung web dį»… dĆ ng +* Giao diện tùy biįŗæn (nĆŗt thanh bĆŖn, widget do ngĘ°į»i dùng tį»± tįŗ”o,...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), + along with a Grafana Dashboard. + +✨ HĆ£y xem thį»­ cĆ”c nguồn tĆ i nguyĆŖn/cį»™ng đồng bĆŖn thứ ba dưới đây Ä‘į»ƒ tƬm thĆŖm +nhiều tiện Ć­ch liĆŖn quan đến TriliumNext: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) cho cĆ”c chį»§ đề, + script, plugin vĆ  nhiều hĘ”n nữa. +- [TriliumRocks!](https://trilium.rocks/) cho những hướng dįŗ«n, vĆ  nhiều hĘ”n. + +## ā“Tįŗ”i sao lĆ  TriliumNext? + +NgĘ°į»i phĆ”t triển ban đầu cį»§a Trilium ([Zadam](https://github.com/zadam)) đã hĆ o +phóng tįŗ·ng kho lʰu trữ Trilium cho dį»± Ć”n cį»™ng đồng, hiện đang đặt tįŗ”i +https://github.com/TriliumNext + +### ā¬†ļø Chuyển từ Zadam/Trilium? + +KhĆ“ng cįŗ§n những bước chuyển đặc biệt nĆ o Ä‘į»ƒ chuyển từ zadam/Trilium sang +TriliumNext/Trilium. Đʔn giįŗ£n chỉ cįŗ§n [cĆ i đặt +TriliumNext/Trilium](#-installation) nhʰ thĆ“ng thĘ°į»ng vĆ  nó sįŗ½ sį»­ dỄng cĘ” sở dữ +liệu sįŗµn có cį»§a bįŗ”n. + +CĆ”c phiĆŖn bįŗ£n trước vĆ  bao gồm +[v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) đều tʰʔng +thĆ­ch vį»›i phiĆŖn bįŗ£n mį»›i nhįŗ„t cį»§a zadam/trilium +[v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). CĆ”c phiĆŖn bįŗ£n +sau đó cį»§a TriliumNext/Trilium đã tăng phiĆŖn bįŗ£n đồng bį»™, khiįŗæn việc chuyển sang +trį»±c tiįŗæp khĆ“ng còn khįŗ£ thi. + +## šŸ’¬ Thįŗ£o luįŗ­n cùng chĆŗng tĆ“i + +HĆ£y thoįŗ£i mĆ”i tham gia cĆ”c cuį»™c trò chuyện chĆ­nh thức. ChĆŗng tĆ“i luĆ“n muốn lįŗÆng +nghe cĆ”c tĆ­nh năng, đề xuįŗ„t hoįŗ·c vįŗ„n đề mĆ  bįŗ”n đʰa ra! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Cho những thįŗ£o luįŗ­n + đồng bį»™ thį»i gian thį»±c.) + - Phòng `General` trong Matrix cÅ©ng được kįŗæt nối tį»›i + [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (Cho + những thįŗ£o luįŗ­n khĆ“ng đồng bį»™.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (Cho việc bĆ”o + cĆ”o lį»—i vĆ  yĆŖu cįŗ§u tĆ­nh năng.) + +## šŸ— CĆ i Đặt + +### Windows / MacOS + +Tįŗ£i bįŗ£n phĆ”t hĆ nh nhị phĆ¢n cho nền tįŗ£ng cį»§a bįŗ”n từ [trang phĆ”t hĆ nh mį»›i +nhįŗ„t](https://github.com/TriliumNext/Trilium/releases/latest), giįŗ£i nĆ©n gói vĆ  +chįŗ”y tệp thį»±c thi `trilium`. + +### Linux + +Nįŗæu bįŗ£n phĆ¢n phối cį»§a bįŗ”n được liệt kĆŖ trong bįŗ£ng dưới đẄy, hĆ£y dùng gói cĆ i đặt +cį»§a nó. + +[![TƬnh trįŗ”ng đóng +gói](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest +release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the +package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web +interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and +tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to +access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more +information on mobile app support. + +If you prefer a native Android app, you can use +[TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their +repository](https://github.com/FliegendeWurst/TriliumDroid). Note: It is best to +disable automatic updates on your server installation (see below) when using +TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from +[Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server +installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our +[Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation +status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the +server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the +environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the +desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development +docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation +guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) +for details. If you have more questions, feel free to reach out via the links +described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation + of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the + application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight + widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to + GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind + text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with + support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite + whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the + mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical + maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive + table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library + without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. + Used in [relation + maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and + [link + maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of +work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your +support keeps it open-source, improves features, and covers costs such as +hosting. + +Consider supporting the main developer +([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU Affero General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. diff --git a/docs/README.es.md b/docs/README.es.md deleted file mode 100644 index 2d49db9cc2..0000000000 --- a/docs/README.es.md +++ /dev/null @@ -1,106 +0,0 @@ -# Trilium Notes - -[English](../README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) - -Trilium Notes es una aplicación de toma de notas jerĆ”rquicas multi-plataforma y de código libre con un enfoque en la construcción de grandes bases de conocimiento personal. - -Vea estas [capturas de pantalla](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) para un vistazo rĆ”pido: - -Trilium Screenshot - -## āš ļø ĀæPor quĆ© usar TriliumNext? - -[El proyecto Trilium original estĆ” en modo de mantenimiento](https://github.com/zadam/trilium/issues/4620) - -### ĀæCómo migrar desde Trilium? - -No hay pasos de migración especiales para migrar de una instancia de zadam/Trilium a una instancia de TriliumNext/Notes. Simplemente actualice su instancia de Trilium a la Ćŗltima versión e [instale TriliumNext/Notes como de costumbre](#-Instalación) - -## šŸ’¬ Discuta con nosotros - -SiĆ©ntase libre de unirse a nuestras conversaciones oficiales. Ā”Nos encantarĆ­a escuchar de las caracterĆ­sticas, sugerencias o problemas que pueda tener! - -- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Para discusiones sĆ­ncronas) - - La sala `General` es replicada a [XMPP](xmpp:discuss@trilium.thisgreat.party?join) -- [Discusiones de GitHub](https://github.com/TriliumNext/Notes/discussions) (Para discusiones asĆ­ncronas) -- [Wiki](https://triliumnext.github.io/Docs/) (Para preguntas frecuentes y guĆ­as de usuario) - -## šŸŽ CaracterĆ­sticas - -- Las notas pueden ser acomodadas en un Ć”rbol de profundidad arbitraria. Una sola nota puede ser colocada en mĆŗltiples lugares del Ć”rbol (vea [clonar](https://triliumnext.github.io/Docs/Wiki/cloning-notes) -- Edición de notas WYSIWYG enriquecida que incluye, por ejemplo, tablas, imĆ”genes y [matemĆ”ticas](https://triliumnext.github.io/Docs/Wiki/text-notes) con [autoformato](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) markdown -- Soporte para editar [notas con código fuente](https://triliumnext.github.io/Docs/Wiki/code-notes), incluyendo resaltado de sintaxis -- RĆ”pida y sencilla [navegación entre notas](https://triliumnext.github.io/Docs/Wiki/note-navigation), bĆŗsqueda de texto completo y [elevación de notas](https://triliumnext.github.io/Docs/Wiki/note-hoisting) -- [Versionado de notas](https://triliumnext.github.io/Docs/Wiki/note-revisions) sutil -- Los [atributos](https://triliumnext.github.io/Docs/Wiki/attributes) de las notas pueden utilizarse para organización, realizar consultas y [scripts](https://triliumnext.github.io/Docs/Wiki/scripts) avanzados -- [Sincronización](https://triliumnext.github.io/Docs/Wiki/synchronization) con servidor de sincronización propio - - existe un [servicio de terceros para alojar el servidor de sincronización](https://trilium.cc/paid-hosting) -- [Compartir](https://triliumnext.github.io/Docs/Wiki/sharing) (publicar) notas al Internet pĆŗblico -- Fuerte [encriptación de notas](https://triliumnext.github.io/Docs/Wiki/protected-notes) con granularidad para cada nota -- Esbozo de diagramas con Excalidraw incorporado (tipo de nota Ā«canvasĀ») -- [Mapas de relaciones]() y [mapas de enlaces](https://triliumnext.github.io/Docs/Wiki/link-map) para visualizar las notas y sus relaciones -- [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - vea [casos de uso avanzados](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) -- [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) para automatización -- Escala bien tanto en uso como en rendimiento a partir de 100,000 notas -- [Interfaz móvil](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) optimizada para telĆ©fonos inteligentes y tabletas -- [Tema nocturno](https://triliumnext.github.io/Docs/Wiki/themes) -- Importación y exportación de [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) y [Markdown](https://triliumnext.github.io/Docs/Wiki/markdown) -- [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) para guardar fĆ”cilmente contenido web - -✨ Consulte los/las siguientes recursos/comunidades de terceros para obtener mĆ”s información sobre complementos para TriliumNext: - -- [awesome-trilium](https://github.com/Nriver/awesome-trilium) para temas, scripts, plugins y mĆ”s de terceros. -- [TriliumRocks!](https://trilium.rocks/) para tutoriales, guĆ­as y mucho mĆ”s. - -## šŸ— Instalación - -### Escritorio - -Para usar TriliumNext en su mĆ”quina de escritorio (Linux, MacOS y Windows) tiene algunas opciones: - -- Descargue la versión binaria para su plataforma desde la [pĆ”gina de lanzamientos](https://github.com/TriliumNext/Notes/releases/latest), descomprima el paquete y ejecute el ejecutable `trilium`. -- Acceda a TriliumNext a travĆ©s de la interfaz web de una instalación de servidor (ver mĆ”s abajo) - - Actualmente solo las Ćŗltimas versiones de Chrome y Firefox son compatibles (y estĆ”n probadas). -- (Próximamente) TriliumNext tambiĆ©n se proporcionarĆ” como un Flatpak - -### Móvil - -Para usar TriliumNext en un dispositivo móvil: - -- Utilice un navegador web móvil para acceder a la interfaz móvil de una instalación de servidor (ver mĆ”s abajo) -- El uso de una aplicación móvil aĆŗn no estĆ” soportado ([vea aquĆ­](https://github.com/TriliumNext/Notes/issues/72)) para seguir las mejoras móviles. - -### Servidor - -Para instalar TriliumNext en su servidor (incluyendo vĆ­a Docker desde [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) siga la [documentación de instalación de servidor](https://triliumnext.github.io/Docs/Wiki/server-installation). - -## šŸ“ Documentación - -[Vea la Wiki para la lista completa de pĆ”ginas de documentación.](https://triliumnext.github.io/Docs) - -TambiĆ©n puede leer [Patrones para una base de conocimiento personal](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) para obtener un poco de inspiración de como podrĆ­a usar TriliumNext. - -## šŸ’» Contribuir - -Clone localmente y ejecute - -```shell -npm install -npm run server:start -``` - -## šŸ‘ Reconocimientos - -- [CKEditor 5](https://github.com/ckeditor/ckeditor5) - el mejor editor WYSIWYG en el mercado, equipo muy interactivo y atento -- [FancyTree](https://github.com/mar10/fancytree) - biblioteca de Ć”rbol muy rica en funciones sin competencia real. Trilium Notes no serĆ­a lo mismo sin esta. -- [CodeMirror](https://github.com/codemirror/CodeMirror) - editor de código con soporte para una gran cantidad de lenguajes -- [jsPlumb](https://github.com/jsplumb/jsplumb) - biblioteca de conectividad visual sin competencia. Usado en [mapas de relación](https://triliumnext.github.io/Docs/Wiki/Relation-map) y [mapas de enlace](https://triliumnext.github.io/Docs/Wiki/Link-map) - -## šŸ¤ Soporte - -Puede apoyar al desarrollador original de Trilium usando GitHub Sponsors, [PayPal](https://paypal.me/za4am) o Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). -Apoyo para la organización TriliumNext serĆ” posible en un futuro próximo. - -## šŸ”‘ Licencia - -Este programa es software libre: puede redistribuirlo y/o modificarlo bajo los tĆ©rminos de la Licencia PĆŗblica General de Affero GNU publicada por la Free Software Foundation, ya sea la versión 3 de la Licencia, o (a su elección) cualquier versión posterior. diff --git a/docs/README.it.md b/docs/README.it.md deleted file mode 100644 index 58c2806d74..0000000000 --- a/docs/README.it.md +++ /dev/null @@ -1,93 +0,0 @@ -# Trilium Notes - -[English](../README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) - -Trilium Notes ĆØ un'applicazione per appunti ad organizzazione gerarchica, studiata per la costruzione di archivi di conoscenza personali di grandi dimensioni. - -Vedi [fotografie](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) per una panoramica veloce: - -Trilium Screenshot - -## āš ļø PerchĆØ TriliumNext? -[Il progetto originale Trilium ĆØ in modalitĆ  di manutenzione](https://github.com/zadam/trilium/issues/4620) - -## šŸ—­ Discuti con noi -Sentiti libero di unirti alle nostre discussioni ufficiali e alla nostra comunitĆ . Siamo concentrati sullo sviluppo di Trilium e ci piacerebbe sapere quali funzioni, suggerimenti o eventuali problemi hai! - -- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Per discussioni sincrone) -- [Discussioni Github](https://github.com/TriliumNext/Notes/discussions) (Per discussioni asincrone) -- [Wiki](https://triliumnext.github.io/Docs/) (Per le domande più comuni e le guide per l'utente) - -Le due stanze linkate sopra sono connesse e contengono gli stessi messaggi, quindi puoi usare XMPP o Matrix da qualsiasi client tu preferisca, praticamente su qualsiasi piattaforma! -### ComunitĆ  non ufficiali - -[Trilium Rocks](https://discord.gg/aqdX9mXX4r) -## šŸŽ FunzionalitĆ  - -* Gli appunti possono essere organizzati in un albero di profonditĆ  arbitraria. Un singolo appunto può essere collocato in più posti nell'albero (vedi [clonazione](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) -* Ricco editor visuale (WYSIWYG), con supporto -tra l'altro- per tabelle, immagini ed [espressioni matematiche](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) e con [formattazione automatica](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) per markdown -* Supporto per la modifica di [appunti con codice sorgente](https://triliumnext.github.io/Docs/Wiki/code-notes), con evidenziazione della sintassi -* [Navigazione veloce](https://triliumnext.github.io/Docs/Wiki/note-navigation) tra gli appunti, ricerca testuale completa e [fissaggio degli appunti](https://triliumnext.github.io/Docs/Wiki/note-hoisting) -* Supporto integrato ed automatico per le [revisioni degli appunti](https://triliumnext.github.io/Docs/Wiki/note-revisions) -* Gli [attributi](https://triliumnext.github.io/Docs/Wiki/attributes) degli appunti possono essere utilizzati per l'organizzazione, per l'interrogazione e per lo scripting avanzato (prorgrammazione). -* [Sincronizzazione](https://triliumnext.github.io/Docs/Wiki/synchronization) con un server di sincronizzazione auto-ospitato - * c'ĆØ un [servizio di terze parti per ospitare server di sincronizzazione](https://trilium.cc/paid-hosting) -* [Condivisione](https://triliumnext.github.io/Docs/Wiki/sharing) (pubblicazione) di appunti sull'internet pubblico -* Robusta [crittografia](https://triliumnext.github.io/Docs/Wiki/protected-notes) configurabile singolarmente per ogni appunto -* Disegno di diagrammi con Excalidraw (tipo di appunto "canvas") -* [Mappe relazionali](https://triliumnext.github.io/Docs/Wiki/relation-map) e [mappe di collegamenti](https://triliumnext.github.io/Docs/Wiki/link-map) per visualizzare gli appunti e le loro relazioni -* [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - vedi [Esempi avanzati](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) -* [API REST](https://triliumnext.github.io/Docs/Wiki/etapi) per l'automazione -* Si adatta bene sia in termini di usabilitĆ  che di prestazioni fino ad oltre 100 000 appunti -* Interfaccia utente ottimizzata per il [mobile](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) (smartphone e tablet) -* [Tema Notturno](https://triliumnext.github.io/Docs/Wiki/themes) -* Supporto per importazione ed esportazione da e per [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) e [Markdown import](https://triliumnext.github.io/Docs/Wiki/markdown) -* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) per il salvataggio facile di contenuti web - -✨ Dai un'occhiata alle seguenti risorse di terze parti per scoprire altre bellezze legate a TriliumNext: - --[awesome-trilium](https://github.com/Nriver/awesome-trilium) per temi, script, plugin e altro di terze parti. -- [TriliumRocks!](https://trilium.rocks/) per tutorial, guide e molto altro. -## šŸ— Rilasci - - -Trilium ĆØ fornito come applicazione desktop (Linux e Windows) o come applicazione web ospitata sul tuo server (Linux). La versione desktop per Mac OS ĆØ disponibile, ma [non ĆØ supportata](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support). - -* Se vuoi usare Trilium sul tuo desktop, scarica il rilascio binario per la tua piattaforma dall'[ultimo rilascio](https://github.com/TriliumNext/Notes/releases/latest), decomprimi l'archivio e avvia l'eseguibile ```trilium```. -* Se vuoi installare Trilium su un server, segui [questa pagina](https://triliumnext.github.io/Docs/Wiki/server-installation). - * Per ora solo Chrome e Firefox sono i browser supportati (testati). - -TriliumNext sarĆ  fornito anche come Flatpak: - - - -## šŸ“ Documentazione - -[Vedi la wiki per una lista completa delle pagine di documentazione.](https://triliumnext.github.io/Docs/) - -Puoi anche leggere ["Patterns of personal knowledge base"](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) per avere un'ispirazione su come potresti utilizzare Trilium. - -## šŸ’» Contribuire - -Clona localmente ed esegui - -```shell -npm install -npm run server:start -``` - -## šŸ‘ Riconoscimenti - -* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - miglior editor visuale (WYSIWYG) sul mercato, squadra di sviluppo attenta e reattiva -* [FancyTree](https://github.com/mar10/fancytree) - libreria per alberi molto ricca di funzionalitĆ , senza pari. Trilium Notes non sarebbe lo stesso senza di essa. -* [CodeMirror](https://github.com/codemirror/CodeMirror) - editor di codice con supporto per un'enorme quantitĆ  di linguaggi. -* [jsPlumb](https://github.com/jsplumb/jsplumb) - libreria per la connettivitĆ  visuale senza pari. Utilizzata per [mappe relazionali](https://triliumnext.github.io/Docs/Wiki/relation-map) e [mappe di collegamenti](https://triliumnext.github.io/Docs/Wiki/link-map). - -## šŸ¤ Supporto - -Puoi sostenere lo sviluppatore originale di Trilium utilizzando gli sponsor di GitHub, [PayPal](https://paypal.me/za4am) o Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). -Il supporto all'organizzazione TriliumNext sarĆ  possibile nel prossimo futuro. - -## šŸ”‘ Licenza - -Questo programma ĆØ software libero: ĆØ possibile redistribuirlo e/o modificarlo nei termini della GNU Affero General Public License come pubblicata dalla Free Software Foundation, sia la versione 3 della Licenza, o (a propria scelta) qualsiasi versione successiva. diff --git a/docs/README.ja.md b/docs/README.ja.md deleted file mode 100644 index d1cb164b0e..0000000000 --- a/docs/README.ja.md +++ /dev/null @@ -1,73 +0,0 @@ -# Trilium Notes - -[English](../README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) - -Trilium Notes ćÆć€å¤§č¦ęØ”ćŖå€‹äŗŗēŸ„č­˜ćƒ™ćƒ¼ć‚¹ć®ę§‹ēÆ‰ć«ē„¦ē‚¹ć‚’å½“ć¦ćŸć€éšŽå±¤åž‹ćƒŽćƒ¼ćƒˆć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć§ć™ć€‚ę¦‚č¦ćÆ[ć‚¹ć‚ÆćƒŖćƒ¼ćƒ³ć‚·ćƒ§ćƒƒćƒˆ](https://triliumnext.github.io/Docs/Wiki/screenshot-tour)ć‚’ć”č¦§ćć ć•ć„ļ¼š - -Trilium Screenshot - -## šŸŽ 特従 - -* ćƒŽćƒ¼ćƒˆćÆć€ä»»ę„ć®ę·±ć•ć®ćƒ„ćƒŖćƒ¼ć«é…ē½®ć§ćć¾ć™ć€‚å˜äø€ć®ćƒŽćƒ¼ćƒˆć‚’ćƒ„ćƒŖćƒ¼å†…ć®č¤‡ę•°ć®å “ę‰€ć«é…ē½®ć§ćć¾ć™ ([cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes) ć‚’å‚ē…§) -* ćƒžćƒ¼ć‚Æćƒ€ć‚¦ćƒ³[ć‚Ŗćƒ¼ćƒˆćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆ](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)ć«ć‚ˆć‚‹ć€č”Øć€ē”»åƒć€[ę•°å­¦](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support)などの豊富な WYSIWYG ćƒŽćƒ¼ćƒˆē·Øé›†ę©Ÿčƒ½ -* ć‚·ćƒ³ć‚æćƒƒć‚Æć‚¹ćƒć‚¤ćƒ©ć‚¤ćƒˆć‚’å«ć‚€[ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ä»˜ććƒŽćƒ¼ćƒˆ](https://triliumnext.github.io/Docs/Wiki/code-notes)ć®ē·Øé›†ć‚’ć‚µćƒćƒ¼ćƒˆ -* [ćƒŽćƒ¼ćƒˆé–“ć®ćƒŠćƒ“ć‚²ćƒ¼ć‚·ćƒ§ćƒ³](https://triliumnext.github.io/Docs/Wiki/note-navigation)ć€å…Øę–‡ę¤œē“¢ć€[ćƒŽćƒ¼ćƒˆćƒ›ć‚¤ć‚¹ćƒˆ](https://triliumnext.github.io/Docs/Wiki/note-hoisting)ćŒé«˜é€Ÿć‹ć¤ē°”å˜ć«č”Œćˆć¾ć™ -* ć‚·ćƒ¼ćƒ ćƒ¬ć‚¹ćŖ[ćƒŽćƒ¼ćƒˆć®ćƒćƒ¼ć‚øćƒ§ćƒ³ē®”ē†](https://triliumnext.github.io/Docs/Wiki/note-revisions) -* ćƒŽćƒ¼ćƒˆ[å±žę€§](https://triliumnext.github.io/Docs/Wiki/Attributes)ćÆć€ćƒŽćƒ¼ćƒˆę•“ē†ć€ć‚Æć‚ØćƒŖć€é«˜åŗ¦ćŖ[ć‚¹ć‚ÆćƒŖćƒ—ćƒˆ](https://triliumnext.github.io/Docs/Wiki/scripts)ć«ä½æē”Øć§ćć¾ć™ -* č‡Ŗå·±ćƒ›ć‚¹ćƒˆåž‹åŒęœŸć‚µćƒ¼ćƒćƒ¼ćØć®[同期](https://triliumnext.github.io/Docs/Wiki/synchronization) - * [åŒęœŸć‚µćƒ¼ćƒćƒ¼ć‚’ćƒ›ć‚¹ćƒˆć™ć‚‹ć‚µćƒ¼ćƒ‰ćƒ‘ćƒ¼ćƒ†ć‚£ćƒ»ć‚µćƒ¼ćƒ“ć‚¹](https://trilium.cc/paid-hosting)ćŒć‚ć‚Šć¾ć™ -* å…¬é–‹ć‚¤ćƒ³ć‚æćƒ¼ćƒćƒƒćƒˆćøć®ćƒŽćƒ¼ćƒˆć®[å…±ęœ‰](https://triliumnext.github.io/Docs/Wiki/sharing)(公開) -* ćƒŽćƒ¼ćƒˆć”ćØć®ē²’åŗ¦ć‚’ęŒć¤å¼·åŠ›ćŖ[ćƒŽćƒ¼ćƒˆęš—å·åŒ–](https://triliumnext.github.io/Docs/Wiki/protected-notes) -* 組み込みの Excalidraw ć‚’ä½æē”Øć—ćŸå›³ć®ć‚¹ć‚±ćƒƒćƒ (ćƒŽćƒ¼ćƒˆ ć‚æć‚¤ćƒ—"ć‚­ćƒ£ćƒ³ćƒć‚¹") -* ćƒŽćƒ¼ćƒˆćØćć®é–¢äæ‚ć‚’åÆč¦–åŒ–ć™ć‚‹ćŸć‚ć®[関係図](https://triliumnext.github.io/Docs/Wiki/relation-map)と[ćƒŖćƒ³ć‚Æćƒžćƒƒćƒ—](https://triliumnext.github.io/Docs/Wiki/link-map) -* [ć‚¹ć‚ÆćƒŖćƒ—ćƒ†ć‚£ćƒ³ć‚°](https://triliumnext.github.io/Docs/Wiki/scripts) - [é«˜åŗ¦ćŖć‚·ćƒ§ćƒ¼ć‚±ćƒ¼ć‚¹](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)ć‚’å‚ē…§ -* č‡Ŗå‹•åŒ–ć®ćŸć‚ć® [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) -* ćƒ¦ćƒ¼ć‚¶ćƒ“ćƒŖćƒ†ć‚£ćØćƒ‘ćƒ•ć‚©ćƒ¼ćƒžćƒ³ć‚¹ć®äø”ę–¹ć§ 100 000 ćƒŽćƒ¼ćƒˆä»„äøŠć«ę‹”å¼µåÆčƒ½ -* ć‚¹ćƒžćƒ¼ćƒˆćƒ•ć‚©ćƒ³ćØć‚æćƒ–ćƒ¬ćƒƒćƒˆå‘ć‘ć®ć‚æćƒƒćƒęœ€é©åŒ–[ćƒ¢ćƒć‚¤ćƒ«ćƒ•ćƒ­ćƒ³ćƒˆć‚Øćƒ³ćƒ‰](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) -* [ćƒŠć‚¤ćƒˆćƒ†ćƒ¼ćƒž](https://triliumnext.github.io/Docs/Wiki/themes) -* [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) と [Markdown ć®ć‚¤ćƒ³ćƒćƒ¼ćƒˆćØć‚Øć‚Æć‚¹ćƒćƒ¼ćƒˆ](https://triliumnext.github.io/Docs/Wiki/Markdown) -* Web ć‚³ćƒ³ćƒ†ćƒ³ćƒ„ć‚’ē°”å˜ć«äæå­˜ć™ć‚‹ćŸć‚ć® [Web ć‚ÆćƒŖćƒƒćƒ‘ćƒ¼](https://triliumnext.github.io/Docs/Wiki/web-clipper) - -ć‚µćƒ¼ćƒ‰ćƒ‘ćƒ¼ćƒ†ć‚£ć®ćƒ†ćƒ¼ćƒžć€ć‚¹ć‚ÆćƒŖćƒ—ćƒˆć€ćƒ—ćƒ©ć‚°ć‚¤ćƒ³ćŖć©ćÆć€ [awesome-trilium](https://github.com/Nriver/awesome-trilium) ć‚’ćƒć‚§ćƒƒć‚Æć—ć¦ćć ć•ć„ć€‚ - -## šŸ— ćƒ“ćƒ«ćƒ‰ - -Trilium ćÆć€ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ļ¼ˆLinux态Windowsļ¼‰ć¾ćŸćÆć‚µćƒ¼ćƒćƒ¼äøŠć§ćƒ›ć‚¹ćƒˆć•ć‚Œć‚‹ć‚¦ć‚§ćƒ–ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ļ¼ˆLinuxļ¼‰ćØć—ć¦ęä¾›ć•ć‚Œć¾ć™ć€‚ Mac OS ć®ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ćƒ“ćƒ«ćƒ‰ć‚‚åˆ©ē”ØåÆčƒ½ć§ć™ćŒć€ [unsupported](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support) となっています。 - -* ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć§ Trilium ć‚’ä½æē”Øć—ćŸć„å “åˆćÆć€ [latest release](https://github.com/TriliumNext/Notes/releases/latest) ć‹ć‚‰ćŠä½æć„ć®ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć®ćƒć‚¤ćƒŠćƒŖćƒŖćƒŖćƒ¼ć‚¹ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ć—ć€ćƒ‘ćƒƒć‚±ćƒ¼ć‚øć‚’č§£å‡ć—ć¦ ``trilium`` ć®å®Ÿč”Œćƒ•ć‚”ć‚¤ćƒ«ć‚’å®Ÿč”Œć—ć¦ćć ć•ć„ć€‚ -* ć‚µćƒ¼ćƒćƒ¼ć« Trilium ć‚’ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć™ć‚‹å “åˆćÆć€[ć“ć®ćƒšćƒ¼ć‚ø](https://triliumnext.github.io/Docs/Wiki/server-installation)ć«å¾“ć£ć¦ćć ć•ć„ć€‚ - * ē¾åœØć€åÆ¾åæœļ¼ˆå‹•ä½œē¢ŗčŖļ¼‰ć—ć¦ć„ć‚‹ćƒ–ćƒ©ć‚¦ć‚¶ćÆć€ęœ€čæ‘ć® Chrome と Firefox のみです。 - -Trilium は Flatpak ćØć—ć¦ć‚‚ęä¾›ć•ć‚Œć¾ć™ļ¼š - -[](https://flathub.org/apps/details/com.github.zadam.trilium) - -## šŸ“ ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ - -[ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆćƒšćƒ¼ć‚øć®å…ØćƒŖć‚¹ćƒˆćÆwikić‚’ć”č¦§ćć ć•ć„ć€‚](https://triliumnext.github.io/Docs/) - -ć¾ćŸć€[å€‹äŗŗēš„ćŖēŸ„č­˜åŸŗē›¤ć®ćƒ‘ć‚æćƒ¼ćƒ³](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)を読むと、 Trilium ć®ä½æć„ę–¹ć®ćƒ’ćƒ³ćƒˆć‚’å¾—ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ - -## šŸ’» ć‚³ćƒ³ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ćƒˆ - -ć¾ćŸćÆć€ćƒ­ćƒ¼ć‚«ćƒ«ć«ć‚Æćƒ­ćƒ¼ćƒ³ć—ć¦å®Ÿč”Œ - -```shell -npm install -npm run server:start -``` - -## šŸ“¢ ć‚·ćƒ£ć‚¦ćƒˆć‚¢ć‚¦ćƒˆ - -* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - åø‚å “ć§ęœ€é«˜ć® WYSIWYG ć‚Øćƒ‡ć‚£ć‚æćƒ¼ć€éžåøøć«ć‚¤ćƒ³ć‚æćƒ©ć‚Æćƒ†ć‚£ćƒ–ć§čžćäøŠę‰‹ćŖćƒćƒ¼ćƒ  -* [FancyTree](https://github.com/mar10/fancytree) - ēœŸć®ē«¶äŗ‰ē›øę‰‹ćŒć„ćŖć„ć€éžåøøć«ę©Ÿčƒ½č±ŠåÆŒćŖćƒ„ćƒŖćƒ¼ćƒ©ć‚¤ćƒ–ćƒ©ćƒŖć§ć™ć€‚ Trilium Notes ćÆć€ć“ć‚ŒćŖć—ć§ćÆęˆć‚Šē«‹ćŸćŖć„ć§ć—ć‚‡ć†ć€‚ -* [CodeMirror](https://github.com/codemirror/CodeMirror) - č†Øå¤§ćŖę•°ć®čØ€čŖžć‚’ć‚µćƒćƒ¼ćƒˆć™ć‚‹ć‚³ćƒ¼ćƒ‰ć‚Øćƒ‡ć‚£ć‚æ -* [jsPlumb](https://github.com/jsplumb/jsplumb) - ē«¶åˆć®ćŖć„ćƒ“ć‚øćƒ„ć‚¢ćƒ«ć‚³ćƒć‚Æćƒ†ć‚£ćƒ“ćƒ†ć‚£ćƒ©ć‚¤ćƒ–ćƒ©ćƒŖć§ć™ć€‚[関係図](https://triliumnext.github.io/Docs/Wiki/relation-map)态[ćƒŖćƒ³ć‚Æå›³](https://triliumnext.github.io/Docs/Wiki/link-map)で使用。 - -## šŸ¤ ć‚µćƒćƒ¼ćƒˆ - -GitHub ć‚¹ćƒćƒ³ć‚µćƒ¼ć€[PayPal](https://paypal.me/za4am)ć‚‚ć—ććÆ Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2) 恫恦 Trilium ć‚’ć‚µćƒćƒ¼ćƒˆć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ - -## šŸ”‘ ćƒ©ć‚¤ć‚»ćƒ³ć‚¹ - -ć“ć®ćƒ—ćƒ­ć‚°ćƒ©ćƒ ćÆćƒ•ćƒŖćƒ¼ć‚½ćƒ•ćƒˆć‚¦ć‚§ć‚¢ć§ć™ļ¼šćƒ•ćƒŖćƒ¼ć‚½ćƒ•ćƒˆć‚¦ć‚§ć‚¢č²”å›£ćŒē™ŗč”Œć—ćŸ GNU Affero General Public License ć®ćƒćƒ¼ć‚øćƒ§ćƒ³3ć€ć¾ćŸćÆćć‚Œä»„é™ć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®ć„ćšć‚Œć‹ć«å¾“ć£ć¦ć€å†é…åøƒćŠć‚ˆć³/ć¾ćŸćÆę”¹å¤‰ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..692c672728 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,219 @@ +
    + Special thanks to:
    + + Warp sponsorship
    + Warp, built for coding with multiple AI agents
    +
    + Available for macOS, Linux and Windows +
    + +
    + +# Trilium Notes + +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) ![LiberaPay patrons](https://img.shields.io/liberapay/patrons/ElianDoran) +![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) +![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total) +[![RelativeCI](https://badges.relative-ci.com/badges/Di5q7dz9daNDZ9UXi0Bp?branch=develop)](https://app.relative-ci.com/projects/Di5q7dz9daNDZ9UXi0Bp) [![Translation status](https://hosted.weblate.org/widget/trilium/svg-badge.svg)](https://hosted.weblate.org/engage/trilium/) + + + +[Chinese (Simplified Han script)](./README-ZH_CN.md) | [Chinese (Traditional Han script)](./README-ZH_TW.md) | [English](../README.md) | [French](./README-fr.md) | [German](./README-de.md) | [Greek](./README-el.md) | [Italian](./README-it.md) | [Japanese](./README-ja.md) | [Romanian](./README-ro.md) | [Spanish](./README-es.md) + + +Trilium Notes is a free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases. + +Trilium Screenshot + +## ā¬ Download +- [Latest release](https://github.com/TriliumNext/Trilium/releases/latest) – stable version, recommended for most users. +- [Nightly build](https://github.com/TriliumNext/Trilium/releases/tag/nightly) – unstable development version, updated daily with the latest features and fixes. + +## šŸ“š Documentation + +**Visit our comprehensive documentation at [docs.triliumnotes.org](https://docs.triliumnotes.org/)** + +Our documentation is available in multiple formats: +- **Online Documentation**: Browse the full documentation at [docs.triliumnotes.org](https://docs.triliumnotes.org/) +- **In-App Help**: Press `F1` within Trilium to access the same documentation directly in the application +- **GitHub**: Navigate through the [User Guide](./User%20Guide/User%20Guide/) in this repository + +### Quick Links +- [Getting Started Guide](https://docs.triliumnotes.org/) +- [Installation Instructions](https://docs.triliumnotes.org/user-guide/setup) +- [Docker Setup](https://docs.triliumnotes.org/user-guide/setup/server/installation/docker) +- [Upgrading TriliumNext](https://docs.triliumnotes.org/user-guide/setup/upgrading) +- [Basic Concepts and Features](https://docs.triliumnotes.org/user-guide/concepts/notes) +- [Patterns of Personal Knowledge Base](https://docs.triliumnotes.org/user-guide/misc/patterns-of-personal-knowledge) + +## šŸŽ Features + +* Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)) +* Rich WYSIWYG note editor including e.g. tables, images and [math](https://docs.triliumnotes.org/user-guide/note-types/text) with markdown [autoformat](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) +* Support for editing [notes with source code](https://docs.triliumnotes.org/user-guide/note-types/code), including syntax highlighting +* Fast and easy [navigation between notes](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-navigation), full text search and [note hoisting](https://docs.triliumnotes.org/user-guide/concepts/navigation/note-hoisting) +* Seamless [note versioning](https://docs.triliumnotes.org/user-guide/concepts/notes/note-revisions) +* Note [attributes](https://docs.triliumnotes.org/user-guide/advanced-usage/attributes) can be used for note organization, querying and advanced [scripting](https://docs.triliumnotes.org/user-guide/scripts) +* UI available in English, German, Spanish, French, Romanian, and Chinese (simplified and traditional) +* Direct [OpenID and TOTP integration](https://docs.triliumnotes.org/user-guide/setup/server/mfa) for more secure login +* [Synchronization](https://docs.triliumnotes.org/user-guide/setup/synchronization) with self-hosted sync server + * there are [3rd party services for hosting synchronisation server](https://docs.triliumnotes.org/user-guide/setup/server/cloud-hosting) +* [Sharing](https://docs.triliumnotes.org/user-guide/advanced-usage/sharing) (publishing) notes to public internet +* Strong [note encryption](https://docs.triliumnotes.org/user-guide/concepts/notes/protected-notes) with per-note granularity +* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type "canvas") +* [Relation maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and [note/link maps](https://docs.triliumnotes.org/user-guide/note-types/note-map) for visualizing notes and their relations +* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/) +* [Geo maps](https://docs.triliumnotes.org/user-guide/collections/geomap) with location pins and GPX tracks +* [Scripting](https://docs.triliumnotes.org/user-guide/scripts) - see [Advanced showcases](https://docs.triliumnotes.org/user-guide/advanced-usage/advanced-showcases) +* [REST API](https://docs.triliumnotes.org/user-guide/advanced-usage/etapi) for automation +* Scales well in both usability and performance upwards of 100 000 notes +* Touch optimized [mobile frontend](https://docs.triliumnotes.org/user-guide/setup/mobile-frontend) for smartphones and tablets +* Built-in [dark theme](https://docs.triliumnotes.org/user-guide/concepts/themes), support for user themes +* [Evernote](https://docs.triliumnotes.org/user-guide/concepts/import-export/evernote) and [Markdown import & export](https://docs.triliumnotes.org/user-guide/concepts/import-export/markdown) +* [Web Clipper](https://docs.triliumnotes.org/user-guide/setup/web-clipper) for easy saving of web content +* Customizable UI (sidebar buttons, user-defined widgets, ...) +* [Metrics](https://docs.triliumnotes.org/user-guide/advanced-usage/metrics), along with a Grafana Dashboard. + +✨ Check out the following third-party resources/communities for more TriliumNext related goodies: + +- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party themes, scripts, plugins and more. +- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. + +## ā“Why TriliumNext? + +The original Trilium developer ([Zadam](https://github.com/zadam)) has graciously given the Trilium repository to the community project which resides at https://github.com/TriliumNext + +### ā¬†ļøMigrating from Zadam/Trilium? + +There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Trilium instance. Simply [install TriliumNext/Trilium](#-installation) as usual and it will use your existing database. + +Versions up to and including [v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are compatible with the latest zadam/trilium version of [v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later versions of TriliumNext/Trilium have their sync versions incremented which prevents direct migration. + +## šŸ’¬ Discuss with us + +Feel free to join our official conversations. We would love to hear what features, suggestions, or issues you may have! + +- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous discussions.) + - The `General` Matrix room is also bridged to [XMPP](xmpp:discuss@trilium.thisgreat.party?join) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For asynchronous discussions.) +- [Github Issues](https://github.com/TriliumNext/Trilium/issues) (For bug reports and feature requests.) + +## šŸ— Installation + +### Windows / MacOS + +Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package and run the `trilium` executable. + +### Linux + +If your distribution is listed in the table below, use your distribution's package. + +[![Packaging status](https://repology.org/badge/vertical-allrepos/triliumnext.svg)](https://repology.org/project/triliumnext/versions) + +You may also download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package and run the `trilium` executable. + +TriliumNext is also provided as a Flatpak, but not yet published on FlatHub. + +### Browser (any OS) + +If you use a server installation (see below), you can directly access the web interface (which is almost identical to the desktop app). + +Currently only the latest versions of Chrome & Firefox are supported (and tested). + +### Mobile + +To use TriliumNext on a mobile device, you can use a mobile web browser to access the mobile interface of a server installation (see below). + +See issue https://github.com/TriliumNext/Trilium/issues/4962 for more information on mobile app support. + +If you prefer a native Android app, you can use [TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). +Report bugs and missing features at [their repository](https://github.com/FliegendeWurst/TriliumDroid). +Note: It is best to disable automatic updates on your server installation (see below) when using TriliumDroid since the sync version must match between Trilium and TriliumDroid. + +### Server + +To install TriliumNext on your own server (including via Docker from [Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server installation docs](https://docs.triliumnotes.org/user-guide/setup/server). + + +## šŸ’» Contribute + +### Translations + +If you are a native speaker, help us translate Trilium by heading over to our [Weblate page](https://hosted.weblate.org/engage/trilium/). + +Here's the language coverage we have so far: + +[![Translation status](https://hosted.weblate.org/widget/trilium/multi-auto.svg)](https://hosted.weblate.org/engage/trilium/) + +### Code + +Download the repository, install dependencies using `pnpm` and then run the server (available at http://localhost:8080): +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run server:start +``` + +### Documentation + +Download the repository, install dependencies using `pnpm` and then run the environment required to edit the documentation: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm edit-docs:edit-docs +``` + +### Building the Executable +Download the repository, install dependencies using `pnpm` and then build the desktop app for Windows: +```shell +git clone https://github.com/TriliumNext/Trilium.git +cd Trilium +pnpm install +pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 +``` + +For more details, see the [development docs](https://github.com/TriliumNext/Trilium/tree/main/docs/Developer%20Guide/Developer%20Guide). + +### Developer Documentation + +Please view the [documentation guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) for details. If you have more questions, feel free to reach out via the links described in the "Discuss with us" section above. + +## šŸ‘ Shoutouts + +* [zadam](https://github.com/zadam) for the original concept and implementation of the application. +* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the application icon. +* [nriver](https://github.com/nriver) for his work on internationalization. +* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. +* [antoniotejada](https://github.com/nriver) for the original syntax highlight widget. +* [Dosu](https://dosu.dev/) for providing us with the automated responses to GitHub issues and discussions. +* [Tabler Icons](https://tabler.io/icons) for the system tray icons. + +Trilium would not be possible without the technologies behind it: + +* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - the visual editor behind text notes. We are grateful for being offered a set of the premium features. +* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages. +* [Excalidraw](https://github.com/excalidraw/excalidraw) - the infinite whiteboard used in Canvas notes. +* [Mind Elixir](https://github.com/SSShooter/mind-elixir-core) - providing the mind map functionality. +* [Leaflet](https://github.com/Leaflet/Leaflet) - for rendering geographical maps. +* [Tabulator](https://github.com/olifolkerd/tabulator) - for the interactive table used in collections. +* [FancyTree](https://github.com/mar10/fancytree) - feature-rich tree library without real competition. +* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library. Used in [relation maps](https://docs.triliumnotes.org/user-guide/note-types/relation-map) and [link maps](https://docs.triliumnotes.org/user-guide/advanced-usage/note-map#link-map) + +## šŸ¤ Support + +Trilium is built and maintained with [hundreds of hours of work](https://github.com/TriliumNext/Trilium/graphs/commit-activity). Your support keeps it open-source, improves features, and covers costs such as hosting. + +Consider supporting the main developer ([eliandoran](https://github.com/eliandoran)) of the application via: + +- [GitHub Sponsors](https://github.com/sponsors/eliandoran) +- [PayPal](https://paypal.me/eliandoran) +- [Buy Me a Coffee](https://buymeacoffee.com/eliandoran) + + +## šŸ”‘ License + +Copyright 2017-2025 zadam, Elian Doran, and other contributors + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. diff --git a/docs/README.ru.md b/docs/README.ru.md deleted file mode 100644 index ebf6240c53..0000000000 --- a/docs/README.ru.md +++ /dev/null @@ -1,59 +0,0 @@ -# Trilium Notes - -[English](../README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) - -Trilium Notes – ŃŃ‚Š¾ приложение Š“Š»Ń заметок с иерархической ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š¾Š¹, ориентированное на созГание Š±Š¾Š»ŃŒŃˆŠøŃ… ŠæŠµŃ€ŃŠ¾Š½Š°Š»ŃŒŠ½Ń‹Ń… баз знаний. Š”Š»Ń быстрого Š¾Š·Š½Š°ŠŗŠ¾Š¼Š»ŠµŠ½ŠøŃ посмотрите [ŃŠŗŃ€ŠøŠ½ŃˆŠ¾Ń‚-тур](https://triliumnext.github.io/Docs/Wiki/screenshot-tour): - -Trilium Screenshot - -## šŸŽ Возможности - -* Заметки можно Ń€Š°ŃŠæŠ¾Š»Š¾Š¶ŠøŃ‚ŃŒ в виГе Герева ŠæŃ€Š¾ŠøŠ·Š²Š¾Š»ŃŒŠ½Š¾Š¹ Š³Š»ŃƒŠ±ŠøŠ½Ń‹. ŠžŃ‚Š“ŠµŠ»ŃŒŠ½ŃƒŃŽ Š·Š°Š¼ŠµŃ‚ŠŗŃƒ можно Ń€Š°Š·Š¼ŠµŃŃ‚ŠøŃ‚ŃŒ в Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøŃ… местах Герева (см. [клонирование](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) -* ŠŸŃ€Š¾Š“Š²ŠøŠ½ŃƒŃ‚Ń‹Š¹ Š²ŠøŠ·ŃƒŠ°Š»ŃŒŠ½Ń‹Š¹ реГактор (WYSIWYG) ŠæŠ¾Š·Š²Š¾Š»ŃŠµŃ‚ Ń€Š°Š±Š¾Ń‚Š°Ń‚ŃŒ с таблицами, ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃŠ¼Šø, [Ń„Š¾Ń€Š¼ŃƒŠ»Š°Š¼Šø](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) Šø разметкой markdown, имеет [автоформатирование](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) -* РеГактирование [заметок с исхоГным коГом](https://triliumnext.github.io/Docs/Wiki/code-notes), Š²ŠŗŠ»ŃŽŃ‡Š°Ń ŠæŠ¾Š“ŃŠ²ŠµŃ‚ŠŗŃƒ синтаксиса -* Š‘Ń‹ŃŃ‚Ń€Š°Ń Šø ŠæŃ€Š¾ŃŃ‚Š°Ń [Š½Š°Š²ŠøŠ³Š°Ń†ŠøŃ межГу заметками](https://triliumnext.github.io/Docs/Wiki/note-navigation), полнотекстовый поиск Šø [выГеление заметок](https://triliumnext.github.io/Docs/Wiki/note-hoisting) в Š¾Ń‚Š“ŠµŠ»ŃŒŠ½Ń‹Š¹ блок -* Š‘ŠµŃŃˆŠ¾Š²Š½Š¾Šµ [версионирование заметки](https://triliumnext.github.io/Docs/Wiki/note-revisions) -* Š”ŠæŠµŃ†ŠøŠ°Š»ŃŒŠ½Ń‹Šµ [Š°Ń‚Ń€ŠøŠ±ŃƒŃ‚Ń‹](https://triliumnext.github.io/Docs/Wiki/attributes) ŠæŠ¾Š·Š²Š¾Š»ŃŃŽŃ‚ гибко Š¾Ń€Š³Š°Š½ŠøŠ·Š¾Š²Š°Ń‚ŃŒ ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ńƒ, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃŽŃ‚ŃŃ Š“Š»Ń поиска Šø ŠæŃ€Š¾Š“Š²ŠøŠ½ŃƒŃ‚Š¾Š³Š¾ [скриптинга](https://triliumnext.github.io/Docs/Wiki/scripts) -* [Š”ŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·Š°Ń†ŠøŃ](https://triliumnext.github.io/Docs/Wiki/synchronization) заметок со своим сервером -* ŠŠ°Š“Ń‘Š¶Š½Š¾Šµ [ŃˆŠøŃ„Ń€Š¾Š²Š°Š½ŠøŠµ](https://triliumnext.github.io/Docs/Wiki/protected-notes) с Гетализацией по кажГой заметке -* [ŠšŠ°Ń€Ń‚Ń‹ ŃŠ²ŃŠ·ŠµŠ¹](https://triliumnext.github.io/Docs/Wiki/relation-map) Šø [карты ссылок](https://triliumnext.github.io/Docs/Wiki/link-map) Š“Š»Ń Š²ŠøŠ·ŃƒŠ°Š»ŠøŠ·Š°Ń†ŠøŠø ŠøŃ… Š²Š·ŃŠøŠ¼Š¾ŃŠ²ŃŠ·ŠµŠ¹ -* [Дкрипты](https://triliumnext.github.io/Docs/Wiki/scripts) - см. [ŠæŃ€Š¾Š“Š²ŠøŠ½ŃƒŃ‚Ń‹Šµ примеры](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) -* Š„Š¾Ń€Š¾ŃˆŠ¾ Š¼Š°ŃŃˆŃ‚Š°Š±ŠøŃ€ŃƒŠµŃ‚ŃŃ, как по ŃƒŠ“Š¾Š±ŃŃ‚Š²Ńƒ ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŃ, так Šø по ŠæŃ€Š¾ŠøŠ·Š²Š¾Š“ŠøŃ‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚Šø Го 100000 заметок -* ŠžŠæŃ‚ŠøŠ¼ŠøŠ·ŠøŃ€Š¾Š²Š°Š½Š½Ń‹Š¹ [Š¼Š¾Š±ŠøŠ»ŃŒŠ½Ń‹Š¹ фронтенГ](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) смартфонов Šø ŠæŠ»Š°Š½ŃˆŠµŃ‚Š¾Š² -* [Š¢ŠµŠ¼Š½Š°Ń тема](https://triliumnext.github.io/Docs/Wiki/themes) -* Š˜Š¼ŠæŠ¾Ń€Ń‚ Šø ŃŠŗŠæŠ¾Ń€Ń‚ [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) Šø Ганных в [markdown](https://triliumnext.github.io/Docs/Wiki/markdown) формате -* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) Š“Š»Ń уГобного ŃŠ¾Ń…Ń€Š°Š½ŠµŠ½ŠøŃ веб-контента - -## šŸ— Дборки - -Trilium ŠæŃ€ŠµŠ“Š¾ŃŃ‚Š°Š²Š»ŃŠµŃ‚ŃŃ в виГе Гесктопного ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ (Linux Šø Windows) или веб-ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ, размещенного на вашем сервере (Linux). Š”Š¾ŃŃ‚ŃƒŠæŠ½Š° сборка Mac OS, но она [не ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ŃŃ](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support). - -* Если вы хотите ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ Trilium на Гесктопе, скачайте архив Š“Š»Ń своей платформы со страницы [релизов](https://github.com/TriliumNext/Notes/releases/latest), Ń€Š°ŃŠæŠ°ŠŗŃƒŠ¹Ń‚Šµ Šø Š·Š°ŠæŃƒŃŃ‚ŠøŃ‚Šµ ŠøŃŠæŠ¾Š»Š½ŃŠµŠ¼Ń‹Š¹ файл ```trilium```. -* Если вы хотите ŃƒŃŃ‚Š°Š½Š¾Š²ŠøŃ‚ŃŒ Trilium на сервере, ŃŠ»ŠµŠ“ŃƒŠ¹Ń‚Šµ ŃŃ‚Š¾Š¹ [ŠøŠ½ŃŃ‚Ń€ŃƒŠŗŃ†ŠøŠø](https://triliumnext.github.io/Docs/Wiki/server-installation). - * Š’ Ганный момент ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‚ŃŃ (протестированы) послеГние версии Š±Ń€Š°ŃƒŠ·ŠµŃ€Š¾Š² Chrome Šø Firefox. - -## šŸ“ Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃ - -[ŠŸŠ¾Š»Š½Ń‹Š¹ список страниц Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŠø Š“Š¾ŃŃ‚ŃƒŠæŠµŠ½ в Wiki.](https://triliumnext.github.io/Docs/) - -Š’Ń‹ также можете Š¾Š·Š½Š°ŠŗŠ¾Š¼ŠøŃ‚ŃŒŃŃ с [шаблонами ŠæŠµŃ€ŃŠ¾Š½Š°Š»ŃŒŠ½Ń‹Ń… баз знаний](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge), чтобы ŠæŠ¾Š»ŃƒŃ‡ŠøŃ‚ŃŒ преГставление о том, как можно ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ Trilium. - -## šŸ’» Š£Ń‡Š°ŃŃ‚Š²ŃƒŠ¹Ń‚Šµ в разработке - -Или ŃŠŗŠ»Š¾Š½ŠøŃ€ŃƒŠ¹Ń‚Šµ на своё ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾ Šø Š·Š°ŠæŃƒŃŃ‚ŠøŃ‚Šµ - -```shell -npm install -npm run server:start -``` - -## šŸ‘ БлагоГарности - -* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - Š»ŃƒŃ‡ŃˆŠøŠ¹ WYSIWYG реГактор, Š¾Ń‡ŠµŠ½ŃŒ Š°ŠŗŃ‚ŠøŠ²Š½Š°Ń Šø Š²Š½ŠøŠ¼Š°Ń‚ŠµŠ»ŃŒŠ½Š°Ń команГа. -* [FancyTree](https://github.com/mar10/fancytree) - Š¼Š½Š¾Š³Š¾Ń„ŃƒŠ½ŠŗŃ†ŠøŠ¾Š½Š°Š»ŃŒŠ½Š°Ń библиотека Š“Š»Ń ŃŠ¾Š·Š“Š°Š½ŠøŃ ГревовиГных ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€. Вне ŠŗŠ¾Š½ŠŗŃƒŃ€ŠµŠ½Ń†ŠøŠø. Без него Trilium Notes не были бы таким. -* [CodeMirror](https://github.com/codemirror/CodeMirror) - реГактор коГа с поГГержкой огромного количество ŃŠ·Ń‹ŠŗŠ¾Š². -* [jsPlumb](https://github.com/jsplumb/jsplumb) - библиотека Š“Š»Ń Š²ŠøŠ·ŃƒŠ°Š»ŠøŠ·Š°Ń†ŠøŠø ŃŠ²ŃŠ·ŠµŠ¹. Вне ŠŗŠ¾Š½ŠŗŃƒŃ€ŠµŠ½Ń†ŠøŠø. Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ŃŃ в [картах ŃŠ²ŃŠ·ŠµŠ¹](https://triliumnext.github.io/Docs/Wiki/relation-map) Šø [картах ссылок](https://triliumnext.github.io/Docs/Wiki/link-map). - -## šŸ”‘ Š›ŠøŃ†ŠµŠ½Š·ŠøŃ - -Эта программа ŃŠ²Š»ŃŠµŃ‚ŃŃ бесплатным программным обеспечением: вы можете Ń€Š°ŃŠæŃ€Š¾ŃŃ‚Ń€Š°Š½ŃŃ‚ŃŒ Šø/или ŠøŠ·Š¼ŠµŠ½ŃŃ‚ŃŒ ее в соответствии с ŃƒŃŠ»Š¾Š²ŠøŃŠ¼Šø GNU Affero General Public License, опубликованной Free Software Foundation, либо версии 3 Лицензии, либо (по вашему Š²Ń‹Š±Š¾Ń€Ńƒ) Š»ŃŽŠ±Š¾Š¹ более позГней версии. diff --git a/docs/Release Notes/!!!meta.json b/docs/Release Notes/!!!meta.json index d3407925fa..60744e69d0 100644 --- a/docs/Release Notes/!!!meta.json +++ b/docs/Release Notes/!!!meta.json @@ -1,6 +1,6 @@ { "formatVersion": 2, - "appVersion": "0.97.1", + "appVersion": "0.102.0", "files": [ { "isClone": false, @@ -61,6 +61,422 @@ "attachments": [], "dirFileName": "Release Notes", "children": [ + { + "isClone": false, + "noteId": "4FTGCuCiG7s7", + "notePath": [ + "hD3V4hiu2VW4", + "4FTGCuCiG7s7" + ], + "title": "v0.102.1", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.102.1.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "d582eD4RY4OM", + "notePath": [ + "hD3V4hiu2VW4", + "d582eD4RY4OM" + ], + "title": "v0.102.0", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.102.0.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "IlBzLeN3MJhw", + "notePath": [ + "hD3V4hiu2VW4", + "IlBzLeN3MJhw" + ], + "title": "v0.101.3", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.101.3.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "vcBthaXcwAm6", + "notePath": [ + "hD3V4hiu2VW4", + "vcBthaXcwAm6" + ], + "title": "v0.101.2", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.101.2.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "AgUcrU9nFXuW", + "notePath": [ + "hD3V4hiu2VW4", + "AgUcrU9nFXuW" + ], + "title": "v0.101.1", + "notePosition": 50, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.101.1.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "uYwlZ594eyJu", + "notePath": [ + "hD3V4hiu2VW4", + "uYwlZ594eyJu" + ], + "title": "v0.101.0", + "notePosition": 60, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.101.0.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "iPGKEk7pwJXK", + "notePath": [ + "hD3V4hiu2VW4", + "iPGKEk7pwJXK" + ], + "title": "v0.100.0", + "notePosition": 70, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.100.0.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "7HKMTjmopLcM", + "notePath": [ + "hD3V4hiu2VW4", + "7HKMTjmopLcM" + ], + "title": "v0.99.5", + "notePosition": 80, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.99.5.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "RMBaNYPsRpIr", + "notePath": [ + "hD3V4hiu2VW4", + "RMBaNYPsRpIr" + ], + "title": "v0.99.4", + "notePosition": 90, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.99.4.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "yuroLztFfpu5", + "notePath": [ + "hD3V4hiu2VW4", + "yuroLztFfpu5" + ], + "title": "v0.99.3", + "notePosition": 100, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.99.3.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "z207sehwMJ6C", + "notePath": [ + "hD3V4hiu2VW4", + "z207sehwMJ6C" + ], + "title": "v0.99.2", + "notePosition": 110, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.99.2.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "WGQsXq2jNyTi", + "notePath": [ + "hD3V4hiu2VW4", + "WGQsXq2jNyTi" + ], + "title": "v0.99.1", + "notePosition": 120, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.99.1.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "cyw2Yue9vXf3", + "notePath": [ + "hD3V4hiu2VW4", + "cyw2Yue9vXf3" + ], + "title": "v0.99.0", + "notePosition": 130, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.99.0.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "QOJwjruOUr4k", + "notePath": [ + "hD3V4hiu2VW4", + "QOJwjruOUr4k" + ], + "title": "v0.98.1", + "notePosition": 140, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.98.1.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "PLUoryywi0BC", + "notePath": [ + "hD3V4hiu2VW4", + "PLUoryywi0BC" + ], + "title": "v0.98.0", + "notePosition": 150, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.98.0.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "lvOuiWsLDv8F", + "notePath": [ + "hD3V4hiu2VW4", + "lvOuiWsLDv8F" + ], + "title": "v0.97.2", + "notePosition": 160, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.97.2.md", + "attachments": [] + }, { "isClone": false, "noteId": "OtFZ6Nd9vM3n", @@ -69,7 +485,7 @@ "OtFZ6Nd9vM3n" ], "title": "v0.97.1", - "notePosition": 10, + "notePosition": 170, "prefix": null, "isExpanded": false, "type": "text", @@ -95,7 +511,7 @@ "SJZ5PwfzHSQ1" ], "title": "v0.97.0", - "notePosition": 20, + "notePosition": 180, "prefix": null, "isExpanded": false, "type": "text", @@ -121,7 +537,7 @@ "mYXFde3LuNR7" ], "title": "v0.96.0", - "notePosition": 30, + "notePosition": 190, "prefix": null, "isExpanded": false, "type": "text", @@ -147,7 +563,7 @@ "jthwbL0FdaeU" ], "title": "v0.95.0", - "notePosition": 40, + "notePosition": 200, "prefix": null, "isExpanded": false, "type": "text", @@ -173,7 +589,7 @@ "7HGYsJbLuhnv" ], "title": "v0.94.1", - "notePosition": 50, + "notePosition": 210, "prefix": null, "isExpanded": false, "type": "text", @@ -199,7 +615,7 @@ "Neq53ujRGBqv" ], "title": "v0.94.0", - "notePosition": 60, + "notePosition": 220, "prefix": null, "isExpanded": false, "type": "text", @@ -225,7 +641,7 @@ "VN3xnce1vLkX" ], "title": "v0.93.0", - "notePosition": 70, + "notePosition": 230, "prefix": null, "isExpanded": false, "type": "text", @@ -243,7 +659,7 @@ "WRaBfQqPr6qo" ], "title": "v0.92.7", - "notePosition": 80, + "notePosition": 240, "prefix": null, "isExpanded": false, "type": "text", @@ -269,7 +685,7 @@ "a2rwfKNmUFU1" ], "title": "v0.92.6", - "notePosition": 90, + "notePosition": 250, "prefix": null, "isExpanded": false, "type": "text", @@ -287,7 +703,7 @@ "fEJ8qErr0BKL" ], "title": "v0.92.5-beta", - "notePosition": 100, + "notePosition": 260, "prefix": null, "isExpanded": false, "type": "text", @@ -305,7 +721,7 @@ "kkkZQQGSXjwy" ], "title": "v0.92.4", - "notePosition": 110, + "notePosition": 270, "prefix": null, "isExpanded": false, "type": "text", @@ -323,7 +739,7 @@ "vAroNixiezaH" ], "title": "v0.92.3-beta", - "notePosition": 120, + "notePosition": 280, "prefix": null, "isExpanded": false, "type": "text", @@ -341,7 +757,7 @@ "mHEq1wxAKNZd" ], "title": "v0.92.2-beta", - "notePosition": 130, + "notePosition": 290, "prefix": null, "isExpanded": false, "type": "text", @@ -359,7 +775,7 @@ "IykjoAmBpc61" ], "title": "v0.92.1-beta", - "notePosition": 140, + "notePosition": 300, "prefix": null, "isExpanded": false, "type": "text", @@ -377,7 +793,7 @@ "dq2AJ9vSBX4Y" ], "title": "v0.92.0-beta", - "notePosition": 150, + "notePosition": 310, "prefix": null, "isExpanded": false, "type": "text", @@ -395,7 +811,7 @@ "3a8aMe4jz4yM" ], "title": "v0.91.6", - "notePosition": 160, + "notePosition": 320, "prefix": null, "isExpanded": false, "type": "text", @@ -413,7 +829,7 @@ "8djQjkiDGESe" ], "title": "v0.91.5", - "notePosition": 170, + "notePosition": 330, "prefix": null, "isExpanded": false, "type": "text", @@ -431,7 +847,7 @@ "OylxVoVJqNmr" ], "title": "v0.91.4-beta", - "notePosition": 180, + "notePosition": 340, "prefix": null, "isExpanded": false, "type": "text", @@ -449,7 +865,7 @@ "tANGQDvnyhrj" ], "title": "v0.91.3-beta", - "notePosition": 190, + "notePosition": 350, "prefix": null, "isExpanded": false, "type": "text", @@ -467,7 +883,7 @@ "hMoBfwSoj1SC" ], "title": "v0.91.2-beta", - "notePosition": 200, + "notePosition": 360, "prefix": null, "isExpanded": false, "type": "text", @@ -485,7 +901,7 @@ "a2XMSKROCl9z" ], "title": "v0.91.1-beta", - "notePosition": 210, + "notePosition": 370, "prefix": null, "isExpanded": false, "type": "text", @@ -503,7 +919,7 @@ "yqXFvWbLkuMD" ], "title": "v0.90.12", - "notePosition": 220, + "notePosition": 380, "prefix": null, "isExpanded": false, "type": "text", @@ -521,7 +937,7 @@ "veS7pg311yJP" ], "title": "v0.90.11-beta", - "notePosition": 230, + "notePosition": 390, "prefix": null, "isExpanded": false, "type": "text", @@ -539,7 +955,7 @@ "sq5W9TQxRqMq" ], "title": "v0.90.10-beta", - "notePosition": 240, + "notePosition": 400, "prefix": null, "isExpanded": false, "type": "text", @@ -557,7 +973,7 @@ "yFEGVCUM9tPx" ], "title": "v0.90.9-beta", - "notePosition": 250, + "notePosition": 410, "prefix": null, "isExpanded": false, "type": "text", @@ -575,7 +991,7 @@ "o4wAGqOQuJtV" ], "title": "v0.90.8", - "notePosition": 260, + "notePosition": 420, "prefix": null, "isExpanded": false, "type": "text", @@ -608,7 +1024,7 @@ "i4A5g9iOg9I0" ], "title": "v0.90.7-beta", - "notePosition": 270, + "notePosition": 430, "prefix": null, "isExpanded": false, "type": "text", @@ -626,7 +1042,7 @@ "ThNf2GaKgXUs" ], "title": "v0.90.6-beta", - "notePosition": 280, + "notePosition": 440, "prefix": null, "isExpanded": false, "type": "text", @@ -644,7 +1060,7 @@ "G4PAi554kQUr" ], "title": "v0.90.5-beta", - "notePosition": 290, + "notePosition": 450, "prefix": null, "isExpanded": false, "type": "text", @@ -671,7 +1087,7 @@ "zATRobGRCmBn" ], "title": "v0.90.4", - "notePosition": 300, + "notePosition": 460, "prefix": null, "isExpanded": false, "type": "text", @@ -689,7 +1105,7 @@ "sCDLf8IKn3Iz" ], "title": "v0.90.3", - "notePosition": 310, + "notePosition": 470, "prefix": null, "isExpanded": false, "type": "text", @@ -707,7 +1123,7 @@ "VqqyBu4AuTjC" ], "title": "v0.90.2-beta", - "notePosition": 320, + "notePosition": 480, "prefix": null, "isExpanded": false, "type": "text", @@ -725,7 +1141,7 @@ "RX3Nl7wInLsA" ], "title": "v0.90.1-beta", - "notePosition": 330, + "notePosition": 490, "prefix": null, "isExpanded": false, "type": "text", @@ -743,7 +1159,7 @@ "GyueACukPWjk" ], "title": "v0.90.0-beta", - "notePosition": 340, + "notePosition": 500, "prefix": null, "isExpanded": false, "type": "text", @@ -753,6 +1169,73 @@ "dataFileName": "v0.90.0-beta.md", "attachments": [] }, + { + "isClone": false, + "noteId": "kzjHexDTTeVB", + "notePath": [ + "hD3V4hiu2VW4", + "kzjHexDTTeVB" + ], + "title": "v0.48", + "notePosition": 510, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wyurrlcDl416", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "v0.48.md", + "attachments": [ + { + "attachmentId": "645H74UA4xwf", + "title": "note-map.png", + "role": "image", + "mime": "image/jpg", + "position": 10, + "dataFileName": "v0.48_note-map.png" + }, + { + "attachmentId": "c74WFpjTo0p4", + "title": "screenshot.png", + "role": "image", + "mime": "image/jpg", + "position": 10, + "dataFileName": "v0.48_screenshot.png" + }, + { + "attachmentId": "szlnTmTJL4HL", + "title": "split.png", + "role": "image", + "mime": "image/jpg", + "position": 10, + "dataFileName": "v0.48_split.png" + }, + { + "attachmentId": "VQxrtpQTYmI6", + "title": "bookmarks.png", + "role": "image", + "mime": "image/jpg", + "position": 10, + "dataFileName": "v0.48_bookmarks.png" + }, + { + "attachmentId": "ZRyEqxAv1MTd", + "title": "mermaid.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "v0.48_mermaid.png" + } + ] + }, { "isClone": false, "noteId": "wyurrlcDl416", @@ -761,7 +1244,7 @@ "wyurrlcDl416" ], "title": "Release Template", - "notePosition": 350, + "notePosition": 520, "prefix": null, "isExpanded": false, "type": "text", diff --git a/docs/Release Notes/Release Notes/Release Template.md b/docs/Release Notes/Release Notes/Release Template.md index b6c59f4dcc..ff160444ca 100644 --- a/docs/Release Notes/Release Notes/Release Template.md +++ b/docs/Release Notes/Release Notes/Release Template.md @@ -1,14 +1,19 @@ # Release Template -> [!IMPORTANT] +> [!NOTE] > If you enjoyed this release, consider showing a token of appreciation by: > -> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Notes) (top-right). +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). > * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). +> * If you are interested in an [official mobile application](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/7447) Ā ([#7447](https://github.com/TriliumNext/Trilium/issues/7447)) or [multi-user support](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/4956) ([#4956](https://github.com/TriliumNext/Trilium/issues/4956)), consider offering financial support via IssueHunt (see links). ## šŸ’” Key highlights * \[…\] +## šŸ“± Mobile improvements + +* \[…\] + ## šŸž Bugfixes * \[…\] diff --git a/docs/Release Notes/Release Notes/v0.100.0.md b/docs/Release Notes/Release Notes/v0.100.0.md new file mode 100644 index 0000000000..2c4023cbf7 --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.100.0.md @@ -0,0 +1,161 @@ +# v0.100.0 +> [!NOTE] +> If you are interested in an [official mobile application](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/7447) Ā ([#7447](https://github.com/TriliumNext/Trilium/issues/7447)) or [multi-user support](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/4956) ([#4956](https://github.com/TriliumNext/Trilium/issues/4956)), consider offering financial support via IssueHunt (see links). + +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸ’” Key highlights + +* [Allow changing note color from tree](https://github.com/TriliumNext/Trilium/issues/4137) by @adoriandoran +* More Collection types can now be printed or exported to PDF: + * List collections which will render in a book-like fashion with all its children and preserving the note hierarchy, with functional table of contents and links (for PDFs). + * Table collections will now render a printable table. + * See [documentation](https://docs.triliumnotes.org/user-guide/concepts/notes/printing-and-pdf-export#printing-multiple-notes) for more info. +* Board view improvements + * The number of items in each column is now displayed. + * Attributes (labels & relations) can now be displayed for each note using promoted attributes, consult the documentation for information on how to do so. +* Mobile now has basic support for splits (maximum of two), laid out vertically for smartphones. +* **Breaking change**: `#calendar:color` was completely removed in favor of the global `#color` attribute. + +## šŸž Bugfixes + +* [Advanced search may return more results](https://github.com/TriliumNext/Trilium/issues/7706) by @perfectra1n +* [Fix enex import stores wrong format in database for dateCreated, dateModified](https://github.com/TriliumNext/Trilium/pull/7718) by @contributor +* [Custom Global Shortcut for Toggle System Tray Icon Fails to Show Window](https://github.com/TriliumNext/Trilium/issues/7730) by @contributor +* [Fix NoteLink component is unable to display path for root note](https://github.com/TriliumNext/Trilium/pull/7736) by @contributor +* [file: protocol not working on Linux](https://github.com/TriliumNext/Trilium/issues/6696) by @laundmo +* [Can't type proper value in font size inputbox in Appearance tab in Configuration](https://github.com/TriliumNext/Trilium/issues/7740) +* [#top/#bottom reversed when #sortDirection=desc](https://github.com/TriliumNext/Trilium/issues/7716) +* [Deleting note from journal not working](https://github.com/TriliumNext/Trilium/issues/7702) +* Fixes in the share functionality: + * [Inline mermaid diagrams not rendering](https://github.com/TriliumNext/Trilium/issues/7765) + * [Share url can be broken because of extra slash](https://github.com/TriliumNext/Trilium/pull/7779) by @contributor + * [Invalid code formatting caused by unescaped HTML](https://github.com/TriliumNext/Trilium/issues/7783) + * [`#shareHiddenFromTree` does not hide link in the footer](https://github.com/TriliumNext/Trilium/issues/7781) + * [Title of protected note is visible when linked into shared note](https://github.com/TriliumNext/Trilium/issues/4801) +* [Scripting: Right Pane Widget example produces error](https://github.com/TriliumNext/Trilium/issues/7778) +* [The WebView note type is not passed through template notes](https://github.com/TriliumNext/Trilium/issues/7557) +* [\[MIME type error\] Browser blocks loading print.css (application/json)](https://github.com/TriliumNext/Trilium/issues/7772) +* [Overly narrow empty tab layout on mobile](https://github.com/TriliumNext/Trilium/pull/7824) by @SiriusXT +* Printing: + * ā€œPrint job canceled" error message when dismissing. + * Included notes not rendered. +* Quick edit: + * Keyboard shortcuts not always working. + * [Quick view of dateNote in calendar doesn't respect readOnly status](https://github.com/TriliumNext/Trilium/issues/7715) +* Promoted attributes: some labels would redirect to the wrong input box. +* Attachments: + * [PDF viewer displays abnormally](https://github.com/TriliumNext/Trilium/issues/7847) + * Newly uploaded attachments don't display their size. +* [Search selected text in Trilium](https://github.com/TriliumNext/Trilium/pull/7859) by @contributor +* Collections + * [Collection/Table Breaks with Colon within Attribute Name](https://github.com/TriliumNext/Trilium/issues/7860) + * All descendant notes displayed in List/Grid when switching views. + * Geomap: + * Map not loading at the lowest zoom. + * [Markers are not colored](https://github.com/TriliumNext/Trilium/issues/7920). + * Infinite scroll is now disabled to avoid issues with markers disappearing. + * Board: + * Columns leaking when switching between two different collections of the same type. + * Unable to press Escape to dismiss adding a new column. + * Changing `board:groupBy` doesn't refresh the board. + * Calendar: events sometimes not refreshing. +* MacOS: + * [ForwardInNoteHistory and backInNoteHistory shortcuts clobber system functionality](https://github.com/TriliumNext/Trilium/issues/3708) + * [Unable to use CMD+UpArrow / CMD+DownArrow hotkeys within the note](https://github.com/TriliumNext/Trilium/issues/6964) +* Mobile: + * Some context menu would hide when tapping on submenus. + * Classic toolbar in Quick Edit would not open dropdowns properly. + * Keyboard shortcut + symbol shown in global menu +* Calendar in launch bar: + * The month popup would still be shown after changing the year. + * Clicking on the edges of the calendar would dismiss the popup. + * Tooltip showing over the calendar drop-down +* [Focus issues within split pane](https://github.com/TriliumNext/Trilium/pull/7877) by @SiriusXT +* Read-only bar displayed when accessing note attachments. +* [Edited Notes tab hidden by fixed formatting toolbar](https://github.com/TriliumNext/Trilium/issues/7900) +* Backlinks not refreshed after inserting a new link +* [Text color unreadable in the Calendar](https://github.com/TriliumNext/Trilium/issues/7569) by @adoriandoran +* [Math duplicates itself in code blocks](https://github.com/TriliumNext/Trilium/issues/7913) +* [Show 'import successful' when canceling markdown import](https://github.com/TriliumNext/Trilium/pull/7899) by @SiriusXT +* Switching an existing note (with children) to mindmap type will still display preview cards for its children. +* Clarify converting notes to attachments in tree context menu (better message, disable option when not supported). +* Note actions: some menu items disabled when switching note type. +* [Note map: map overflows when switching type in ribbon](https://github.com/TriliumNext/Trilium/pull/7939) by @SiriusXT + +## ✨ Improvements + +* Additional floating buttons + * Image notes now have a ā€œCopy reference to imageā€ but⁸ton + * Render notes have a ā€œRefreshā€ button. +* Render notes are now searchable. +* Mind map & canvas notes now support read-only mode. +* View source prettifies all JSON content. +* [Note info ribbon flex layout](https://github.com/TriliumNext/Trilium/pull/7678) Ā by @contributor +* ["Open note on server" menu item](https://github.com/TriliumNext/Trilium/pull/7477) by @contributor +* Board view: warn if trying to add a column that already exists. +* [Hide archived notes in classic collections](https://github.com/TriliumNext/Trilium/issues/7705) +* Next theme: a different background color on mobile (white on light theme). +* In-app-help: render reference links with icon. +* [Calendar: Ability to lock the calendar to a specific date](https://github.com/TriliumNext/Trilium/issues/7691) Ā by @dherrerace +* [Option to close any of the panes from 2 open panes](https://github.com/TriliumNext/Trilium/issues/4511) +* Presentation: display no children warning when empty. +* [Tree: Keep moved notes always visible](https://github.com/TriliumNext/Trilium/pull/7776) by @SiriusXT +* Share: display note icon in reference links. +* Printing improvements: + * Render inline Mermaid in Text notes. + * Display progress of printing and exporting to PDF when working with Presentation or List collections. +* [Strike Through Font on Completed To-do Items](https://github.com/TriliumNext/Trilium/issues/4269) +* Promoted attributes: + * Label auto-complete now works on mobile as well. + * Debouncing changes to avoid updating the server too many times while typing. +* [Configurable CORP (resource policy)](https://github.com/TriliumNext/Trilium/issues/7826) by @lzinga +* Code notes options: display a tooltip with the syntax highlighting support for each language. +* Quick edit: + * Improve the layout of code notes and Mermaid notes. + * Floating buttons are now displayed inside the popup. + * Smoothly reacts to changes in color. + * Button to open the note in full view (new tab). +* New MIME types supported (including syntax highlighting): + * [KDL](https://github.com/TriliumNext/Trilium/issues/7848) + * [SAP ABAP](https://github.com/TriliumNext/Trilium/issues/7851) +* [Option to expand n-level subnotes in list view](https://github.com/TriliumNext/Trilium/issues/7669) +* macOS: Tabs no longer leave a gap when full screen is enabled. +* [Format brush](https://github.com/TriliumNext/Trilium/issues/4848) by @SiriusXT +* Mobile: + * Context menus are bigger and easier to use. + * Improved the layout of the note revisions dialog. +* Calendar has a new design for the events that better supports colors by @adoriandoran +* Minor improvements to the list of attachments. +* Various UI improvements by @adoriandoran +* Scripting improvements: + * [Day.js `duration` plugin is now included](https://github.com/TriliumNext/Trilium/issues/4456) + * Both back-end and front-end plugins now share the same Day.js configuration, including plugins and locale. +* Promoted attributes not reacting to changes in inheritable attributes. +* [Disable spell-check on code-snippets](https://github.com/TriliumNext/Trilium/issues/7894) by @lzinga + +## šŸ“– Documentation + +* [Add Traefik configuration documentation](https://github.com/TriliumNext/Trilium/pull/7769) by @andreasntr + +## šŸŒ Internationalization + +* Text editor (CKEditor) now respects the user language. +* Canvas (Excalidraw) also respects user language. +* Mindmap notes also respect user notes. +* Two dialog messages not translated. +* Added English (United Kingdom). Mostly for the formatting, but translations are welcome (handling the differences between the base US translation and UK). +* Proper plural support for Backlinks. +* `dayjs` locale is now set on the client. + +## šŸ› ļø Technical updates + +* Type widgets (the code behind note types such as text, code) was rewritten in React. **Feel free to report any issues you may find**. +* [Add class name to content-header](https://github.com/TriliumNext/Trilium/pull/7713) by @SiriusXT +* Upgrade flake to Node 24 by @FliegendeWurst +* [better-sqlite3 error on nightly build](https://github.com/TriliumNext/Trilium/issues/7839) +* [Add comprehensive AI coding agent instructions for copilot-instructions](https://github.com/TriliumNext/Trilium/pull/7917) by @lzinga \ No newline at end of file diff --git a/docs/Release Notes/Release Notes/v0.101.0.md b/docs/Release Notes/Release Notes/v0.101.0.md new file mode 100644 index 0000000000..87c913e1bd --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.101.0.md @@ -0,0 +1,90 @@ +# v0.101.0 +> [!NOTE] +> This release marks the 8-year anniversary of Trilium, celebrating its [first public release](https://github.com/TriliumNext/Trilium/releases/tag/v0.0.9) on December 25th, 2017. Ā  + +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸ’” Key highlights + +* A new layout was introduced which heavily changes both existing UI elements, as well as adds some new ones (by @eliandoran and @adoriandoran, with special thanks for @rom1dep for the valuable suggestions). + * The goal of this new layout is to modernize the application and to make it more intuitive but at the same time to reduce clutter. + * See [documentation](https://docs.triliumnotes.org/user-guide/concepts/ui/new-layout) of the changes and the new UI elements. + * Notes can be more easily navigated across the hierarchy using the breadcrumbs displayed underneath the tab bar. + * The old layout can still be used, for now. Feedback is welcome. +* Near the tab bar now there are [built-in buttons to go the previous or the next note in history](https://github.com/TriliumNext/Trilium/pull/8003/files) (only if the back/forward buttons are not already placed in the launch bar). +* **Scripting overhaul:** Custom widgets and Render note can now be written in Preact using JSX instead of the legacy format (jQuery + custom component framework). For more information, see [documentation on Preact in Trilium](https://docs.triliumnotes.org/user-guide/scripts/frontend-basics/Preact). + +## šŸž Bugfixes + +* [Ctrl+F when a dialog is open opens different search dialog](https://github.com/TriliumNext/Trilium/issues/5735) +* Toast: Icon missing for error messages +* Launch bar calendar would jump to the wrong week note if it was in between years. +* Launch bar calendar month selector was wrongly positioned. +* Tooltips would sometimes be duplicated if an element is focused. +* Text notes: + * Missing padding in `
    ` without ``.
    +    *   [Content disappears when inserting code block via Markdown formatting](https://github.com/TriliumNext/Trilium/issues/5776)
    +    *   [Data loss for opened tabs after CKEditor crash](https://github.com/TriliumNext/Trilium/issues/7739)
    +*   [Mind Map export does not show text in links between nodes](https://github.com/TriliumNext/Trilium/issues/7829) by @lzinga
    +*   Webview: Layout issues when no source site is set.
    +*   Incorrect help button for content language.
    +*   Links in inherited attributes not underlined.
    +*   Mermaid preview did not render full-height if in read-only while in vertical layout.
    +*   Icons: `border-left` icon was missing.
    +*   Auto-complete shows empty name for hoisted note.
    +*   [Missing null check for canvas elements in fulltext search](https://github.com/TriliumNext/Trilium/pull/8090) by @Soein
    +*   Share badge would always indicate ā€œShared locallyā€ when accessing the server version.
    +*   Clicking in the outer area of a menu dismisses it.
    +*   Geomap: street names not rendering in vector maps.
    +*   In code options modal (ribbon), the tooltip is behind the modal.
    +*   [Archived deeply nested notes appear in classic collections without #includeArchived](https://github.com/TriliumNext/Trilium/issues/8127)
    +*   [Grid collection not displaying images properly](https://github.com/TriliumNext/Trilium/issues/7969)
    +*   Printing collections: skip protected notes (if they are not unlocked) and files.
    +*   [Attachment auto-deletion displayed time is off by a factor of 1000](https://github.com/TriliumNext/Trilium/issues/7987)
    +*   [Note title color for legacy themes](https://github.com/TriliumNext/Trilium/pull/7997) by @Nriver
    +*   [First input box of the promoted multi relation edits last relation](https://github.com/TriliumNext/Trilium/issues/7992)
    +
    +## ✨ Improvements
    +
    +*   Improved error handling for custom widgets.
    +*   Launch bar:
    +    *   The horizontal launch bar can now be scrolled simply by scrolling the mouse wheel.
    +    *   Tooltips are shown faster (no fade).
    +*   Improved error handling
    +    *   HTTP errors are now more user-friendly.
    +    *   Warn on Traefik request failures.
    +    *   CKEditor crashes are notified, including an easy way to provide information for error reports.
    +*   Hide ribbon in Options.
    +*   Removed margins and rounded corners for the code editor.
    +*   Backend logs: reduced extra padding & decrease font size for readability.
    +*   Improved error handling for custom widgets.
    +*   Code notes will now have a default icon based on the language (e.g. custom icon for JS code notes). Only a subset of languages have a dedicated icon.
    +*   Printing collections will now display a message if one or more notes are not printable.
    +*   UI improvements by @adoriandoran
    +
    +## šŸ“– Documentation
    +
    +*   [Wrong links in README](https://github.com/TriliumNext/Trilium/issues/7246)
    +*   [Improve organization of links](https://github.com/TriliumNext/Trilium/pull/8057)
    +*   Widget scripts are now better documented, in both the legacy (jQuery) and Preact/JSX format.
    +
    +## šŸŒ Internationalization
    +
    +*   Untranslated error message for custom widgets.
    +
    +## šŸ› ļø Technical updates
    +
    +*   Ported the following components to React. If you notice any issues with your launchers or the bar itself, feel free to report them.
    +    *   The launch bar and all its widgets.
    +    *   The toast/notification system.
    +*   [Add dev shell and direnv support](https://github.com/TriliumNext/Trilium/pull/8011) by @yzx9 and @contributor
    +*   **Minor breaking change**: custom widgets using the typo `node-detail-pane` will not be supported anymore. Use `note-detail-pane` instead.
    +*   [ETAPI OpenAPI: Add missing share format](https://github.com/TriliumNext/Trilium/pull/8125) by @kalbasit
    +
    +## šŸ”’ļø Security fixes
    +
    +*   A security vulnerability was reported by @sivaadityacoder and fixed by @perfectra1n. More information to be provided in around a month.
    \ No newline at end of file
    diff --git a/docs/Release Notes/Release Notes/v0.101.1.md b/docs/Release Notes/Release Notes/v0.101.1.md
    new file mode 100644
    index 0000000000..43f406d114
    --- /dev/null
    +++ b/docs/Release Notes/Release Notes/v0.101.1.md	
    @@ -0,0 +1,100 @@
    +# v0.101.1
    +> [!NOTE]
    +> This is a hotfix for yesterday's release, which marked the 8-year anniversary of Trilium, celebrating its [first public release](https://github.com/TriliumNext/Trilium/releases/tag/v0.0.9) on December 25th, 2017. Ā 
    +
    +> [!IMPORTANT]
    +> If you enjoyed this release, consider showing a token of appreciation by:
    +> 
    +> *   Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right).
    +> *   Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran).
    +
    +## šŸ’” Key highlights
    +
    +*   A new layout was introduced which heavily changes both existing UI elements, as well as adds some new ones (by @eliandoran and @adoriandoran, with special thanks for @rom1dep for the valuable suggestions).
    +    *   The goal of this new layout is to modernize the application and to make it more intuitive but at the same time to reduce clutter.
    +    *   See [documentation](https://docs.triliumnotes.org/user-guide/concepts/ui/new-layout) of the changes and the new UI elements.
    +    *   Notes can be more easily navigated across the hierarchy using the breadcrumbs displayed underneath the tab bar.
    +    *   The old layout can still be used, for now. Feedback is welcome.
    +*   Near the tab bar now there are [built-in buttons to go the previous or the next note in history](https://github.com/TriliumNext/Trilium/pull/8003/files) (only if the back/forward buttons are not already placed in the launch bar).
    +*   **Scripting overhaul:** Custom widgets and Render note can now be written in Preact using JSX instead of the legacy format (jQuery + custom component framework). For more information, see [documentation on Preact in Trilium](https://docs.triliumnotes.org/user-guide/scripts/frontend-basics/Preact).
    +
    +## šŸž New bugfixes in v0.101.1
    +
    +*   [Right pane toggle missing on macOS vertical layout](https://github.com/TriliumNext/Trilium/issues/8157)
    +*   [Launchpad Note Launcher hoisting no longer working](https://github.com/TriliumNext/Trilium/issues/8160)
    +*   Toggle right pane keyboard button not working on new layout
    +*   [Tabs do not appear when using vertical layout and legacy theme](https://github.com/TriliumNext/Trilium/issues/8170) by @adoriandoran
    +*   [Text in headings do not respond to being bolded](https://github.com/TriliumNext/Trilium/issues/8177) by @adoriandoran
    +*   Table of contents in new layout: not displaying correctly on first render.
    +*   [The text editor keeps crashing in non-HTTPS](https://github.com/TriliumNext/Trilium/issues/8165)
    +
    +## šŸž Bugfixes in v0.101.0
    +
    +*   [Ctrl+F when a dialog is open opens different search dialog](https://github.com/TriliumNext/Trilium/issues/5735)
    +*   Toast: Icon missing for error messages
    +*   Launch bar calendar would jump to the wrong week note if it was in between years.
    +*   Launch bar calendar month selector was wrongly positioned.
    +*   Tooltips would sometimes be duplicated if an element is focused.
    +*   Text notes:
    +    *   Missing padding in `
    ` without ``.
    +    *   [Content disappears when inserting code block via Markdown formatting](https://github.com/TriliumNext/Trilium/issues/5776)
    +    *   [Data loss for opened tabs after CKEditor crash](https://github.com/TriliumNext/Trilium/issues/7739)
    +*   [Mind Map export does not show text in links between nodes](https://github.com/TriliumNext/Trilium/issues/7829) by @lzinga
    +*   Webview: Layout issues when no source site is set.
    +*   Incorrect help button for content language.
    +*   Links in inherited attributes not underlined.
    +*   Mermaid preview did not render full-height if in read-only while in vertical layout.
    +*   Icons: `border-left` icon was missing.
    +*   Auto-complete shows empty name for hoisted note.
    +*   [Missing null check for canvas elements in fulltext search](https://github.com/TriliumNext/Trilium/pull/8090) by @Soein
    +*   Share badge would always indicate ā€œShared locallyā€ when accessing the server version.
    +*   Clicking in the outer area of a menu dismisses it.
    +*   Geomap: street names not rendering in vector maps.
    +*   In code options modal (ribbon), the tooltip is behind the modal.
    +*   [Archived deeply nested notes appear in classic collections without #includeArchived](https://github.com/TriliumNext/Trilium/issues/8127)
    +*   [Grid collection not displaying images properly](https://github.com/TriliumNext/Trilium/issues/7969)
    +*   Printing collections: skip protected notes (if they are not unlocked) and files.
    +*   [Attachment auto-deletion displayed time is off by a factor of 1000](https://github.com/TriliumNext/Trilium/issues/7987)
    +*   [Note title color for legacy themes](https://github.com/TriliumNext/Trilium/pull/7997) by @Nriver
    +*   [First input box of the promoted multi relation edits last relation](https://github.com/TriliumNext/Trilium/issues/7992)
    +
    +## ✨ Improvements
    +
    +*   Improved error handling for custom widgets.
    +*   Launch bar:
    +    *   The horizontal launch bar can now be scrolled simply by scrolling the mouse wheel.
    +    *   Tooltips are shown faster (no fade).
    +*   Improved error handling
    +    *   HTTP errors are now more user-friendly.
    +    *   Warn on Traefik request failures.
    +    *   CKEditor crashes are notified, including an easy way to provide information for error reports.
    +*   Hide ribbon in Options.
    +*   Removed margins and rounded corners for the code editor.
    +*   Backend logs: reduced extra padding & decrease font size for readability.
    +*   Improved error handling for custom widgets.
    +*   Code notes will now have a default icon based on the language (e.g. custom icon for JS code notes). Only a subset of languages have a dedicated icon.
    +*   Printing collections will now display a message if one or more notes are not printable.
    +*   UI improvements by @adoriandoran
    +
    +## šŸ“– Documentation
    +
    +*   [Wrong links in README](https://github.com/TriliumNext/Trilium/issues/7246)
    +*   [Improve organization of links](https://github.com/TriliumNext/Trilium/pull/8057)
    +*   Widget scripts are now better documented, in both the legacy (jQuery) and Preact/JSX format.
    +
    +## šŸŒ Internationalization
    +
    +*   Untranslated error message for custom widgets.
    +
    +## šŸ› ļø Technical updates
    +
    +*   Ported the following components to React. If you notice any issues with your launchers or the bar itself, feel free to report them.
    +    *   The launch bar and all its widgets.
    +    *   The toast/notification system.
    +*   [Add dev shell and direnv support](https://github.com/TriliumNext/Trilium/pull/8011) by @yzx9 and @contributor
    +*   **Minor breaking change**: custom widgets using the typo `node-detail-pane` will not be supported anymore. Use `note-detail-pane` instead.
    +*   [ETAPI OpenAPI: Add missing share format](https://github.com/TriliumNext/Trilium/pull/8125) by @kalbasit
    +
    +## šŸ”’ļø Security fixes
    +
    +*   A security vulnerability was reported by @sivaadityacoder and fixed by @perfectra1n. More information to be provided in around a month.
    \ No newline at end of file
    diff --git a/docs/Release Notes/Release Notes/v0.101.2.md b/docs/Release Notes/Release Notes/v0.101.2.md
    new file mode 100644
    index 0000000000..842f42c299
    --- /dev/null
    +++ b/docs/Release Notes/Release Notes/v0.101.2.md	
    @@ -0,0 +1,22 @@
    +# v0.101.2
    +> [!NOTE]
    +> If you are interested in an [official mobile application](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/7447) Ā ([#7447](https://github.com/TriliumNext/Trilium/issues/7447)) or [multi-user support](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/4956) ([#4956](https://github.com/TriliumNext/Trilium/issues/4956)), consider offering financial support via IssueHunt (see links).
    +
    +> [!IMPORTANT]
    +> If you enjoyed this release, consider showing a token of appreciation by:
    +> 
    +> *   Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right).
    +> *   Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran).
    +
    +## šŸž Bugfixes
    +
    +*   [SQL Console: cannot copy table data](https://github.com/TriliumNext/Trilium/pull/8268) by @SiriusXT
    +*   [Title is not selected when creating a note via the launcher](https://github.com/TriliumNext/Trilium/pull/8292) by @SiriusXT
    +*   [Popup editor closing after inserting a note link](https://github.com/TriliumNext/Trilium/pull/8224) by @SiriusXT
    +*   [New Mermaid diagrams do not save content](https://github.com/TriliumNext/Trilium/pull/8220) by @lzinga
    +*   [Can't scroll mermaid diagram code](https://github.com/TriliumNext/Trilium/issues/8299)
    +*   [Max content width is not respected when switching between note types in the same tab](https://github.com/TriliumNext/Trilium/issues/8065)
    +*   [Crash When a Note Includes Itself](https://github.com/TriliumNext/Trilium/issues/8294)
    +*   [Severe Performance Degradation and Crash Issues Due to Recursive Inclusion in Included Notes](https://github.com/TriliumNext/Trilium/issues/8017)
    +*   [is not a launcher even though it's in the launcher subtree](https://github.com/TriliumNext/Trilium/issues/8218)
    +*   [Archived subnotes of direct children appear in grid view without #includeArchived](https://github.com/TriliumNext/Trilium/issues/8184)
    \ No newline at end of file
    diff --git a/docs/Release Notes/Release Notes/v0.101.3.md b/docs/Release Notes/Release Notes/v0.101.3.md
    new file mode 100644
    index 0000000000..243034045c
    --- /dev/null
    +++ b/docs/Release Notes/Release Notes/v0.101.3.md	
    @@ -0,0 +1,24 @@
    +# v0.101.3
    +> [!NOTE]
    +> If you are interested in an [official mobile application](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/7447) Ā ([#7447](https://github.com/TriliumNext/Trilium/issues/7447)) or [multi-user support](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/4956) ([#4956](https://github.com/TriliumNext/Trilium/issues/4956)), consider offering financial support via IssueHunt (see links).
    +
    +> [!IMPORTANT]
    +> If you enjoyed this release, consider showing a token of appreciation by:
    +> 
    +> *   Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right).
    +> *   Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran).
    +
    +This is a re-release of v0.101.2, which had a cache invalidation issue.
    +
    +## šŸž Bugfixes
    +
    +*   [SQL Console: cannot copy table data](https://github.com/TriliumNext/Trilium/pull/8268) by @SiriusXT
    +*   [Title is not selected when creating a note via the launcher](https://github.com/TriliumNext/Trilium/pull/8292) by @SiriusXT
    +*   [Popup editor closing after inserting a note link](https://github.com/TriliumNext/Trilium/pull/8224) by @SiriusXT
    +*   [New Mermaid diagrams do not save content](https://github.com/TriliumNext/Trilium/pull/8220) by @lzinga
    +*   [Can't scroll mermaid diagram code](https://github.com/TriliumNext/Trilium/issues/8299)
    +*   [Max content width is not respected when switching between note types in the same tab](https://github.com/TriliumNext/Trilium/issues/8065)
    +*   [Crash When a Note Includes Itself](https://github.com/TriliumNext/Trilium/issues/8294)
    +*   [Severe Performance Degradation and Crash Issues Due to Recursive Inclusion in Included Notes](https://github.com/TriliumNext/Trilium/issues/8017)
    +*   [is not a launcher even though it's in the launcher subtree](https://github.com/TriliumNext/Trilium/issues/8218)
    +*   [Archived subnotes of direct children appear in grid view without #includeArchived](https://github.com/TriliumNext/Trilium/issues/8184)
    \ No newline at end of file
    diff --git a/docs/Release Notes/Release Notes/v0.102.0.md b/docs/Release Notes/Release Notes/v0.102.0.md
    new file mode 100644
    index 0000000000..fe554fe601
    --- /dev/null
    +++ b/docs/Release Notes/Release Notes/v0.102.0.md	
    @@ -0,0 +1,210 @@
    +# v0.102.0
    +> [!IMPORTANT]
    +> LLM integration was removed due to the complexity of maintaining this feature. For more information, see [#8797](https://github.com/orgs/TriliumNext/discussions/8797). This means that the database needs migration (downgrades will not be possible without restoring from backup), but it will not affect the sync with the server.
    +
    +> [!NOTE]
    +> If you enjoyed this release, consider showing a token of appreciation by:
    +> 
    +> *   Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right).
    +> *   Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran).
    +> *   If you are interested in an [official mobile application](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/7447) Ā ([#7447](https://github.com/TriliumNext/Trilium/issues/7447)) or [multi-user support](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/4956) ([#4956](https://github.com/TriliumNext/Trilium/issues/4956)), consider offering financial support via IssueHunt (see links).
    +
    +## šŸ’” Key highlights
    +
    +*   Trilium now has support for **custom icon packs** that can be used for note icons. See [Icon Packs - User Guide](https://docs.triliumnotes.org/user-guide/concepts/themes/icon-packs) for more info and a list of [official icon packs](https://triliumnotes.org/en/resources).
    +*   New layout now provides a save indicator near the note title.
    +*   Trilium now uses its own PDF renderer (based on PDF.js viewer from Mozilla). This allows for more features such as annotations, search (within the current file), filling forms as well as remembering last reading position. See [documentation](https://docs.triliumnotes.org/user-guide/note-types/file/pdf) for more info.
    +*   Some Collections will hide their children in the note tree by default. See [the documentation](https://docs.triliumnotes.org/user-guide/concepts/ui/note-tree/hiding-subtree) for details.
    +*   **jQuery has been updated to v4.0.0 which introduces breaking changes that could potentially affect your scripts.**
    +*   Desktop app: background effects (Vibrancy) are now available for macOS.
    +
    +## šŸ“± Mobile improvements
    +
    +*   Collections now show the ā€œCollection propertiesā€ toolbar, allowing to switch views and configure the collection.
    +*   The tab row was removed in favor of a more browser-like tab switcher, displayed as a modal with note preview.
    +*   The title row was significantly changed:
    +    *   The note icon is now displayed with the possibility of changing the icon.
    +    *   Inherited from the new layout on desktop: the note badges (read-only, shared), save indicator.
    +    *   Icons should now be easier to press.
    +    *   The inline title for text and code notes from new layout is now available.
    +*   The note actions menu (right of note title):
    +    *   All the features that are available on the desktop on the new layout are now available, allowing features such as search, toggling share/template/bookmark, changing note type/editability and even import/export/print.
    +    *   Some components from the status bar were also relocated here for mobile: backlinks, note paths, attachments, note info, similar notes and text/code language switchers.
    +    *   Custom note actions (note-specific) were also ported, with buttons such as ā€œRun active noteā€, ā€œToggle read-onlyā€, ā€œUpload new revisionā€.
    +*   Launch bar improvements
    +    *   [Custom mobile launchbar launcher](https://github.com/TriliumNext/Trilium/issues/8054)
    +    *   [Add Bookmarks launcher to mobile UI](https://github.com/TriliumNext/Trilium/issues/5464)
    +*   New split (empty tab): added button to close the split.
    +*   Promoted attributes are no longer fixed at the top and are part of the scrollable area, including a way to collapse it.
    +*   Background effects are now enforced to be disabled, to avoid performance issues. This also fixes grayish menus due to the black backdrop.
    +*   Virtual keyboard detection not working properly on iOS
    +*   Search for notes is now available for mobile, either via the launch bar or the global menu. The layout was optimized slightly for mobile.
    +*   Recent notes are also available, via the launch bar or a dedicated entry in the global menu.
    +*   [Editor format bar not visible after clicking button to edit 'readOnly' note in mobile view](https://github.com/TriliumNext/Trilium/issues/5368)
    +*   [Support Saved Search Notes on Mobile UI](https://github.com/TriliumNext/Trilium/issues/4022)
    +*   [Oversized note title and editor toolbar is cut off](https://github.com/TriliumNext/Trilium/issues/8205).
    +*   [Web clipper "save link with a note", cannot see the link in android mobile view](https://github.com/TriliumNext/Trilium/issues/5198)
    +*   [Add note attachment functionality to mobile web UI](https://github.com/TriliumNext/Trilium/issues/6490)
    +*   Improved the layout of Shortcut options page.
    +*   Added scroll padding to text and code notes (same as desktop).
    +*   Improved the fit of empty tab.
    +*   Fixed some usability issues with the side bar tree: too easy to close, tooltip remained stuck, sometimes cut at the bottom on some browsers.
    +*   Search in full text in Jump to note is overlapped by text
    +*   Keyboard shortcut plus symbol shown on some buttons
    +*   Virtual keyboard detection not working on Android
    +*   Toast not respecting safe area
    +*   iOS viewport shifting in split notes
    +*   Issues with formatting toolbar on iOS (Background, positioning, dragging)
    +
    +## šŸž Bugfixes
    +
    +*   Status bar: Attribute count counts internal links as well.
    +*   Various UI fixes by @adoriandoran
    +*   Boxicons: `border-right` icon missing.
    +*   Share export:
    +    *   ZIP attachments having wrong extension.
    +    *   JS frontend files having the wrong extension by @kalbasit
    +    *   [Prevent crashing if candidate note is null](https://github.com/TriliumNext/Trilium/pull/8164) by @kalbasit
    +*   PDF: clicking on the document doesn't focus the note in the note tree.
    +*   [Colors with upper case or invalid colors can cause a crash](https://github.com/TriliumNext/Trilium/issues/8232)
    +*   [New Layout performance issue: excessive calls to custom widget refresh/reload API](https://github.com/TriliumNext/Trilium/pull/8233) by @lzinga
    +*   [Exporting a note as a static website (format == share) should support ~shareJs](https://github.com/TriliumNext/Trilium/issues/8171) by @kalbasit
    +*   [Toggling right pane visibility incorrectly affects all windows](https://github.com/TriliumNext/Trilium/pull/8226) by @SiriusXT
    +*   Revisions not displaying meta info (mime and file size) for `file` types.
    +*   [Solved some performance issues](https://github.com/TriliumNext/Trilium/pull/8274) regarding the tree, especially if hoisted notes are involved:
    +    *   Tree is updated on content changes.
    +    *   Batch update causing a reduction in performance.
    +    *   Slow rendering of nodes.
    +*   [Keyboard combinations with Alt not working properly on macOS](https://github.com/TriliumNext/Trilium/pull/8369) by @chloelee767
    +*   Markdown export not preserving HTML entities correctly.
    +*   Error when printing presentations.
    +*   Syntax highlighting tooltip in Settings → Code Options not indicating correct information.
    +*   [Render notes not refreshing on attribute change](https://github.com/TriliumNext/Trilium/issues/8321)
    +*   [Promoted attributes: check boxes not displaying initial value correctly](https://github.com/TriliumNext/Trilium/issues/8062)
    +*   [Race condition in syntax highlight in the note list](https://github.com/TriliumNext/Trilium/issues/8464)
    +*   [Mermaid graphs only render once unlocked and relocked](https://github.com/TriliumNext/Trilium/issues/8419)
    +*   [Quick edit not working properly if ā€œKeep content centeredā€ is checked](https://github.com/TriliumNext/Trilium/issues/8371)
    +*   [Canvas background color is not saved](https://github.com/TriliumNext/Trilium/issues/8325)
    +*   [Calendar collection not respecting default formatting locale and casing](https://github.com/TriliumNext/Trilium/issues/8507)
    +*   [Missing "Note Paths" in new layout if note is partially in hidden notes](https://github.com/TriliumNext/Trilium/issues/8597)
    +*   New layout: Note type switcher shown in non-standard view modes (e.g. view source)
    +*   [Keep content centered does not center "Notes edited on this day"](https://github.com/TriliumNext/Trilium/issues/8334)
    +*   [Search error tooltips are not displayed in user interface](https://github.com/TriliumNext/Trilium/issues/8704)
    +*   [RelationMap crashes when switching an empty note to Map view (TypeError: Cannot read properties of undefined (reading 'map'))](https://github.com/TriliumNext/Trilium/issues/8702)
    +*   [Cannot select option in advanced sub-menu in some language](https://github.com/TriliumNext/Trilium/issues/8694)
    +*   [web-clipper page 404 on triliumnotes.org](https://github.com/TriliumNext/Trilium/issues/8596)
    +*   [web view note in second window does not load content](https://github.com/TriliumNext/Trilium/pull/8739) by @contributor
    +*   [Wrong sync status tooltip](https://github.com/TriliumNext/Trilium/issues/8266)
    +*   Code notes:
    +    *   Clicking at the bottom of a note would change the view port and affect all splits.
    +    *   Missing Node globals in linter for backend notes.
    +*   Breadcrumb would split on multiple lines when width is constrained.
    +*   Clicking on a web view would not activate the split.
    +*   [When using the legacy theme, the window cannot be dragged in vertical layout](https://github.com/TriliumNext/Trilium/issues/8402)
    +*   Fixed some issues with promoted attributes:
    +    *   Typing sometimes misses characters.
    +    *   Duplicate auto-complete instances.
    +    *   Flicker when applying autocomplete suggestion.
    +*   Potential refresh issue in inherited attribute list.
    +*   Calendar: creating a note in an unhoisted `#workspaceCalendarRoot` would create it in the `#calendarRoot` instead.
    +*   HTML static export: exporting root tree would show ā€œHidden Notesā€ in the tree.
    +*   [Breadcrumb not reacting to title updates](https://github.com/TriliumNext/Trilium/pull/8784) by @vedanshbodkhe21
    +*   Search:
    +    *   ā€œNo resultsā€ message not shown
    +    *   Double scroll bars
    +*   [Fix week note title error when cross year](https://github.com/TriliumNext/Trilium/pull/8431) by @JYC333
    +*   Text notes:
    +    *   [Tab and Shift+Tab select images, tables, etc instead of indenting](https://github.com/TriliumNext/Trilium/issues/7986) by @perfectra1n
    +    *   [Tab key (ā­¾) jumps to footnote instead of indenting text](https://github.com/TriliumNext/Trilium/issues/7476)
    +*   [Searching with orderby and parentheses](https://github.com/TriliumNext/Trilium/pull/8717) by @misch334
    +*   [After a protected note automatically re-enters protection mode, its status does not refresh automatically](https://github.com/TriliumNext/Trilium/issues/7761)
    +*   Help notes are renamable.
    +*   Canvas: not switching the dark mode at once with the system, remains in a messy state
    +*   Mindmap: when app is dark mode and the mindmap is light, the input fields has no longer visible text
    +
    +## ✨ Improvements
    +
    +*   Significant improvements to the icon selector.
    +    *   **Uses a virtual list pattern, allowing for 20k+ icons with little impact.**
    +    *   Placeholders and messages based on results.
    +    *   The icon categories feature was completely removed. This decision better aligns with support for multiple icon packs.
    +    *   Icons should now fit better (no unnecessary whitespace).
    +    *   Icons can be filtered by icon pack.
    +    *   ā€œReset to defaultā€ icon was converted to an icon near the filter button.
    +*   Attachments list: MIME type is now displayed as well.
    +*   [Note tree: Tooltips for share & clone icons](https://github.com/TriliumNext/Trilium/pull/8211) by @perfectra1n
    +*   Improvements to _Note Revisions_:
    +    *   Previews now displayed for the following _File_ types: audio, video, PDF.
    +    *   Reduced layout shrinking on desktop.
    +*   Markdown:
    +    *   Preserve HTML and JSX language tags in code blocks when importing.
    +    *   Add `spellcheck=false` to inline code.
    +*   [Add right-click context menu to note list](https://github.com/TriliumNext/Trilium/pull/8254) by @SiriusXT
    +*   [Visual math equation editor](https://github.com/TriliumNext/Trilium/pull/7842) by @Meinzzzz
    +*   [Add logseq to supported protocols](https://github.com/TriliumNext/Trilium/pull/8320) by @contributor
    +*   [Open notes in new window from tree](https://github.com/TriliumNext/Trilium/pull/8269) by @SiriusXT
    +*   [Add "latex" alias for math command](https://github.com/TriliumNext/Trilium/pull/8357) by @Atmois
    +*   [Show more helpful output when users encounter permissions issues within the data directory](https://github.com/TriliumNext/Trilium/pull/8273) by @perfectra1n
    +*   [Ensure that "folders first" ordering mode doesn't place folder notes on top of notes flagged as #top](https://github.com/TriliumNext/Trilium/pull/7878) by @rom1dep
    +*   Minor change in behavior for PDFs file notes:
    +    *   Dedicated default icon for PDF files.
    +    *   Remove extension from title for single PDF imports and replace underlines with space.
    +*   Major improvements to SQL console:
    +    *   Integrated a better table system for displaying results, with sorting, pagination and filtering.
    +    *   The query can be hidden by locking the note for editing, for saved SQL notes.
    +    *   See [documentation](https://docs.triliumnotes.org/user-guide/advanced-usage/database/manual-editing/sql-console) for more info.
    +*   Collections:
    +    *   Calendar: Slighter better performance and fewer glitches when adding, moving or deleting entries.
    +    *   The ā€œCollection propertiesā€ toolbar is now displayed on both the new and old layouts.
    +    *   Collection-specific buttons such as the calendar or geomap buttons are now directly integrated into ā€œCollection propertiesā€ to reduce vertical space usage.
    +    *   As such, some floating buttons were integrated into ā€œCollection propertiesā€.
    +    *   Geomap: Custom raster tiles are now supported by providing an URL, see documentation.
    +*   ETAPI
    +    *   [Add revisions route and "undelete" route](https://github.com/TriliumNext/Trilium/pull/8455) by @perfectra1n
    +    *   [Add attachments route](https://github.com/TriliumNext/Trilium/pull/8578) by @perfectra1n
    +*   Report printing/export to PDF errors on desktop.
    +*   Active content (widgets, scripts) now have a dedicated badge on new layout with options to configure and toggle them easily.
    +*   Setup screen for newly created web views by @adoriandoran
    +*   Setup screen for newly created render notes.
    +*   Warning screen for disabled web views & render notes.
    +*   Display errors when rendering notes.
    +*   [Improve card design](https://github.com/TriliumNext/Trilium/pull/8728/changes) by @adoriandoran
    +*   [Disable hover and nested background darkening in list view](https://github.com/TriliumNext/Trilium/issues/8267) by @adoriandoran
    +*   [List collections & search results: overhaul the list UI](https://github.com/TriliumNext/Trilium/pull/8705) by @adoriandoran
    +*   Improve list pagination by @adoriandoran
    +*   [Always show Note Paths in Status Bar](https://github.com/TriliumNext/Trilium/pull/8623) by @contributor
    +*   Search: Improved the design of the ā€œSearch not yet executedā€ and ā€œNo resultsā€ messages
    +*   Share:
    +    *   Add download icon to attachment links.
    +    *   [Align mobile/desktop UI with unified header](https://github.com/TriliumNext/Trilium/pull/8484) by @kalbasit
    +*   Improve styling of grid and list view by @adoriandoran
    +*   [Adopt MD060 compact style for table cells](https://github.com/TriliumNext/Trilium/pull/8840) by @yzx9
    +*   [PDF.js styling](https://github.com/TriliumNext/Trilium/pull/8857) by @adoriandoran
    +*   [Desktop: Copy as Markdown](https://github.com/TriliumNext/Trilium/pull/8808) by @yzx9
    +
    +## šŸ“– Documentation
    +
    +*   Importing from Evernote by @miljed
    +*   [Add subtreeHidden and map:\* attributes to labels documentation](https://github.com/TriliumNext/Trilium/pull/8594) & other documentation improvements by @hulmgulm
    +*   enhanced icon pack creation by @hulmgulm
    +
    +## šŸŒ Internationalization
    +
    +*   Added support for Polish.
    +*   Added support for Irish.
    +*   Added support for Hindi by @vedanshbodkhe21.
    +*   Many translation improvements.
    +
    +## šŸ› ļø Technical updates
    +
    +*   Change /calendar/weeks/{date} to use ISO week format by @openapphub
    +*   [Fix race condition in edit-docs Electron ready event](https://github.com/TriliumNext/Trilium/pull/8344) by @kalbasit
    +*   [Allow other projects to use edit-docs for their own documentation](https://github.com/TriliumNext/Trilium/issues/8343) by @kalbasit
    +*   CKEditor was updated, which should fix some stability issues.
    +*   The desktop client was upgraded to Electron v40.
    +*   Update Nix flake by @kalbasit
    +*   [Similar Notes style is hardcoded](https://github.com/TriliumNext/Trilium/issues/2137) by @adoriandoran
    +*   [Enhance build-docs utility with pnpm and Nix support](https://github.com/TriliumNext/Trilium/pull/8574) by @kalbasit
    +*   add generic debugging/dap launch.json for client, server and vitest by @misch334
    +*   [Theming: color scheme selectors](https://github.com/TriliumNext/Trilium/pull/8839) by @adoriandoran
    +*   [Theming: include the current theme ID as an attribute for the body element](https://github.com/TriliumNext/Trilium/pull/8842) by @adoriandoran
    \ No newline at end of file
    diff --git a/docs/Release Notes/Release Notes/v0.102.1.md b/docs/Release Notes/Release Notes/v0.102.1.md
    new file mode 100644
    index 0000000000..5552b54b37
    --- /dev/null
    +++ b/docs/Release Notes/Release Notes/v0.102.1.md	
    @@ -0,0 +1,22 @@
    +# v0.102.1
    +> [!NOTE]
    +> If you enjoyed this release, consider showing a token of appreciation by:
    +> 
    +> *   Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right).
    +> *   Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran).
    +> *   If you are interested in an [official mobile application](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/7447) Ā ([#7447](https://github.com/TriliumNext/Trilium/issues/7447)) or [multi-user support](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/4956) ([#4956](https://github.com/TriliumNext/Trilium/issues/4956)), consider offering financial support via IssueHunt (see links).
    +
    +> [!IMPORTANT]
    +> This is a hotfix of v0.102.0, addressing some blocking issues. For more information about the previous major version, see [v0.102.0 changelog](https://github.com/TriliumNext/Trilium/releases/tag/v0.102.0).
    +
    +## šŸž Bugfixes
    +
    +*   [Mind Map feature breaks rendering in v0.102.0](https://github.com/TriliumNext/Trilium/issues/8879)
    +*   Fixes for the PDF viewer:
    +    *   [PDF view is '403 Forbidden' on Nginx Proxy Manager](https://github.com/TriliumNext/Trilium/issues/8877)
    +    *   [PDF: address some layout issues](https://github.com/TriliumNext/Trilium/commit/8712e7dd160564f9a923a88bf5871e63c79d40f0) by @adoriandoran
    +    *   Cache not properly invalidated across versions.
    +
    +## šŸ› ļø Technical updates
    +
    +*   [Rework Docker infrastructure to use crane](https://github.com/TriliumNext/Trilium/pull/8869) by @perfectra1n
    \ No newline at end of file
    diff --git a/docs/Release Notes/Release Notes/v0.48.md b/docs/Release Notes/Release Notes/v0.48.md
    new file mode 100644
    index 0000000000..f1b5e5c3ba
    --- /dev/null
    +++ b/docs/Release Notes/Release Notes/v0.48.md	
    @@ -0,0 +1,121 @@
    +# v0.48
    +0.48 is a big release and contains many changes, some of them breaking:
    +
    +## Major frontend redesign
    +
    +
    +
    +*   right panel is no more, most of these widgets have been moved to the new ribbon-style widget under note title
    +    *   right panel is still possible to activate for scripts
    +*   Trilium has a new icon (there might be further color changes)
    +
    +## Vertical split window
    +
    +
    + +## Link map re-implemented + +Now supports also hierarchical view of the notes: + +
    + +## Mermaid diagrams + +Thanks to [@abitofevrything](https://github.com/abitofevrything) for this contribution! + +
    + +## Basic bookmark support + +
    + +## Other changes + +* persistence/entity layer in backend was largely refactored - "repository" and unified with note cache which should bring performance improvements for many operations +* search and SQL query notes now don't create ā€œsavedā€ notes by default +* added underline heading style and make it a default +* updated CKEditor to 30.0.0 + +## Migration + +### Backup restore + +Trilium v0.48 is currently in beta and may contain serious bugs. + +Before migration to 0.48 Trilium will make automatically backup into `~/trilium-data/backup/backup-before-migration.db`. In case of problems you can restore this backup with this guide: [https://github.com/zadam/trilium/wiki/Backup#restoring-backup](https://github.com/zadam/trilium/wiki/Backup#restoring-backup) + +### Direct upgrade only from 0.47.X + +Direct upgrade to 0.48 is possible only from 0.47.X. If you want to upgrade from an older version, you need to upgrade to 0.47.X first and only then to 0.48. This is caused by extensive backend refactoring which broke older migration scripts. + +### All backend script notes should avoid being async + +Backend operations were in older versions used async/await because of the SQLite driver. But Trilium recently migrated to the synchronous (and much faster) `better-sqlite3`. As a consequence backend script notes which are wrapped in a transaction should to be converted to the sync variant. + +e.g. old script looked like this: + +``` +const todayDateStr = api.formatDateISO(new Date()); + +const todayNote = await api.runOnBackend(async todayDateStr => { + const dateNote = await api.getDayNote(todayDateStr); + + ({note: logNote} = await api.createNote(dateNote.noteId, 'log')); +}, [todayDateStr]); + +api.activateNote(todayNote.noteId); +``` + +all the `await` (and `async`) should disappear from the backend code, but should remain when calling backend from frontend (that's still async): + +``` +const todayDateStr = api.formatDateISO(new Date()); + +const todayNote = await api.runOnBackend(todayDateStr => { + const dateNote = api.getDayNote(todayDateStr); + + ({note: logNote} = api.createNote(dateNote.noteId, 'log')); +}, [todayDateStr]); + +api.activateNote(todayNote.noteId); +``` + +### Migrate custom themes + +With the redesign you might need to adjust your custom themes - check the modified list of available CSS variables in the [default theme](https://github.com/zadam/trilium/blob/master/src/public/stylesheets/theme-light.css). If your theme also uses CSS selectors then that will probably have to be rewritten as well. + +Themes are annotated with `#appTheme` label, previously this label could but did not have to contain value - with this release the value is required so define the label as e.g. `#appTheme=my-theme-name`. + +Additionally, CSS themes are now loaded differently than before - previously all themes were loaded at the startup and which one was active was decided by the active CSS class. Themes were then prefixed like this: + +``` +body.theme-steel-blue { + --main-font-family: 'Raleway' !important; + --main-font-size: normal; + + --tree-font-family: inherit; + --tree-font-size: normal; + ... +} + +body.theme-steel-blue .note-detail-editable-text, body.theme-steel-blue .note-detail-readonly-text { + font-size: 120%; +} +``` + +This prefixing is not needed anymore (and also doesn't work anymore). Remove the prefixes like this: + +``` +:root { + --main-font-family: 'Raleway'; + --main-font-size: normal; + + --tree-font-family: 'Raleway'; + --tree-font-size: normal; + ... +} + +body .note-detail-editable-text, body .note-detail-readonly-text { + font-size: 120%; +} +``` \ No newline at end of file diff --git a/docs/Release Notes/Release Notes/v0.48_bookmarks.png b/docs/Release Notes/Release Notes/v0.48_bookmarks.png new file mode 100644 index 0000000000..2d78ee1a13 Binary files /dev/null and b/docs/Release Notes/Release Notes/v0.48_bookmarks.png differ diff --git a/docs/Release Notes/Release Notes/v0.48_mermaid.png b/docs/Release Notes/Release Notes/v0.48_mermaid.png new file mode 100644 index 0000000000..1c48d2aa6e Binary files /dev/null and b/docs/Release Notes/Release Notes/v0.48_mermaid.png differ diff --git a/docs/Release Notes/Release Notes/v0.48_note-map.png b/docs/Release Notes/Release Notes/v0.48_note-map.png new file mode 100644 index 0000000000..ee7ef932a9 Binary files /dev/null and b/docs/Release Notes/Release Notes/v0.48_note-map.png differ diff --git a/docs/Release Notes/Release Notes/v0.48_screenshot.png b/docs/Release Notes/Release Notes/v0.48_screenshot.png new file mode 100644 index 0000000000..78f589fd9c Binary files /dev/null and b/docs/Release Notes/Release Notes/v0.48_screenshot.png differ diff --git a/docs/Release Notes/Release Notes/v0.48_split.png b/docs/Release Notes/Release Notes/v0.48_split.png new file mode 100644 index 0000000000..bb58e18344 Binary files /dev/null and b/docs/Release Notes/Release Notes/v0.48_split.png differ diff --git a/docs/Release Notes/Release Notes/v0.97.2.md b/docs/Release Notes/Release Notes/v0.97.2.md new file mode 100644 index 0000000000..886ec75014 --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.97.2.md @@ -0,0 +1,61 @@ +# v0.97.2 +> [!NOTE] +> Translations are now easily editable online via Weblate. If you wish to contribute to Trilium by translating to your native language, head on over to [our Weblate page](https://hosted.weblate.org/engage/trilium/). + +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Notes) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸ’” Key highlights + +* A new collection type has been added: a board in which child notes are grouped in columns. +* Geo map now comes with a vector map by default. + * The vector styles will provide for a smoother experience, consult the documentation for more information. + * Apart from that, there are multiple styles to choose from in the _Collection properties_ section in the ribbon, including dark themes. + * Apart from that, added an option to display a scale on the map. +* Jump to note was enhanced to allow triggering commands (such as the ones that can have a keyboard shortcut assigned to them) quickly. + * Press Ctrl+Shift+J to test it out. + * The feature was renamed to simply ā€œJump toā€¦ā€ to better accommodate the new role. + * For more information, check the user guide for ā€œJump toā€¦ā€. + +## šŸž Bugfixes + +* [Shared note dark mode text doesn't change](https://github.com/TriliumNext/Trilium/issues/6427) +* [Markdown export of simple tables results in HTML, not Markdown](https://github.com/TriliumNext/Trilium/issues/6366) +* [Cannot edit ReadOnly note in quick edit](https://github.com/TriliumNext/Trilium/issues/6425) +* [Documentation for collections is empty](https://github.com/TriliumNext/Trilium/issues/6420) +* [Laggy "Mermaid Diagram" note type refresh during editing](https://github.com/TriliumNext/Trilium/issues/6443) +* Geomap not reacting to marker icon changes. +* [Checkbox Inputs (in Canvas Node > Export image...) have broken styling](https://github.com/TriliumNext/Trilium/issues/6463) +* [Rename Book note type to Collection](https://github.com/TriliumNext/Trilium/issues/6471) +* [Table view persistence not working in protected notes](https://github.com/TriliumNext/Trilium/issues/6473#issuecomment-3120029185) +* [Table caption print issue](https://github.com/TriliumNext/Trilium/issues/6483) +* [Commonmark import sub and sup tags not working](https://github.com/TriliumNext/Trilium/issues/4307) +* [Migration failing if there is a protected geomap](https://github.com/TriliumNext/Trilium/issues/6489) +* Window refreshing when sorting notes via the dialog. +* [Odd behavior in Safari on macOS (random refreshing+new note creation+user guide opens)](https://github.com/TriliumNext/Trilium/issues/6218) +* Note tooltip showing up in note list +* Copy to clipboard button also opening into note list + +## ✨ Improvements + +* [Show inline mermaid diagram in share view instead of mermaid diagram code](https://github.com/TriliumNext/Trilium/issues/5438) +* Canvas improvements: + * Add grid to canvas by @Papierkorb2292 + * Improve style of toolbars and dropdowns on the Next theme. +* New type for promoted attributes: color. +* Web view note preview (in note list): + * The `#webViewSrc` is now hidden + * Dedicated button to open the link externally. +* [User Guide pages should be searchable](https://github.com/TriliumNext/Trilium/issues/6515) + +## šŸŒ Internationalization + +* 100% translation coverage for Romanian. +* Spanish language improvements by @Aitanuqui + +## šŸ› ļø Technical updates + +* The shortcut keys management was completely rewritten as it was based on an older library. **Please raise any issues you might have with your keyboard shortcuts.** \ No newline at end of file diff --git a/docs/Release Notes/Release Notes/v0.98.0.md b/docs/Release Notes/Release Notes/v0.98.0.md new file mode 100644 index 0000000000..d4c5eb9aa4 --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.98.0.md @@ -0,0 +1,65 @@ +# v0.98.0 +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸ’” Key highlights + +* [Enhanced Search with Fuzzy Matching and Better UX](https://github.com/TriliumNext/Trilium/pull/6536) by @perfectra1n +* For Linux users, RPM packages are now GPG-signed. + * The keys must be imported once per device, before installation: `sudo rpm --import https://triliumnotes.org/RPM-GPG-KEY-trilium` + +## šŸž Bugfixes + +* The "chat with notes" icon re-appears on 0.97.2's Launchbar after update, even though the LLM feature was disabled before +* Board view: sub-children (recursive) not displayed. +* [Canvas: unable to open internal note path links](https://github.com/TriliumNext/Trilium/issues/6606) +* Delay when opening a Text note for the first time +* Search term is not highlighted in preview search result +* ETAPI: Save note revision if needed by @perfectra1n +* [No update notification in the global menu](https://github.com/TriliumNext/Trilium/pull/6657) by @SiriusXT + +## ✨ Improvements + +* Zen mode is now supported on mobile by @Papierkorb2292 +* Code notes: new Cobalt2 theme by @hulmgulm +* Existing users will be prompted with a message at the start of the application (and an option to dismiss it permanently): + * To enable background effects on Windows, since it has become stable. + * To use the TriliumNext theme. +* The built-in themes were renamed: + * TriliumNext themes become simply Trilium + * The Light/Dark/Auto themes become Legacy +* [Clean up old backend logs](https://github.com/TriliumNext/Trilium/pull/6609) by @perfectra1n + +## šŸ“– Documentation + +* update doc references from triliumnext/notes to triliumnext/trilium by @perfectra1n +* Simple Update/Autoupdate Script by @serossi +* Improve OIDC docs by @JYC333 +* Traditional Chinese README by @francistw +* README improvements by @meichthys + +## šŸŒ Internationalization + +* Improvements to multiple languages: + + * Chinese (Traditional) + * Spanish +* Some work started on new languages: + + Portuguese (Brazil), Japanese, Russian, Serbian, Italian, Greek, Catalan +* Added new languages: + + * Russian (translations by @questamor) + * Japanese language (translations by [acwr47](https://hosted.weblate.org/user/acwr47/))\[…\] + +## šŸ› ļø Technical updates + +* Add duplicateSubtree to backend API by @Geekswordsman +* Fixed CVE-2025-54798 in `tmp` dependency +* Remove unnecessary idea directory by @GrantZhu1001 +* Support getting an attribute value by ID in BNote by @Geekswordsman +* only run nightly.yml on TriliumNext/Trilium by @maphew +* All the dialogs have been converted to React/Preact for better maintainability. **If you notice any regressions, please report them.** \ No newline at end of file diff --git a/docs/Release Notes/Release Notes/v0.98.1.md b/docs/Release Notes/Release Notes/v0.98.1.md new file mode 100644 index 0000000000..9cdcb13333 --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.98.1.md @@ -0,0 +1,40 @@ +# v0.98.1 +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸž Bugfixes + +* [Keyboard shortcut catches QWERTY keys instead of owner's](https://github.com/TriliumNext/Trilium/issues/6547) +* [\`-character doesn't work in shortcuts](https://github.com/TriliumNext/Trilium/issues/6784) +* Quick search: attribute search no longer working +* Settings not fitting well on mobile. +* [Attributes/tags not showing up in search results](https://github.com/TriliumNext/Trilium/pull/6752) +* [Note links always follow note title](https://github.com/TriliumNext/Trilium/issues/6776) + +## ✨ Improvements + +* Quick search: format multi-line results better +* [Add UI performance-related settings](https://github.com/TriliumNext/Trilium/pull/6747) by @adoriandoran +* [Reduce or disable search animation](https://github.com/TriliumNext/Trilium/issues/6698) by @adoriandoran +* Fuzzy search should have a "non fuzzy" option by @perfectra1n + +## šŸ“– Documentation + +* [Swagger UI for the internal API](https://github.com/TriliumNext/Trilium/pull/6719) by @perfectra1n +* [Improve documentation on environment variables](https://github.com/TriliumNext/Trilium/pull/6727) by @perfectra1n + +## šŸŒ Internationalization + +* Thanks to our contributors on Weblate: +* Added support for the Ukrainian language. +* Increased coverage for most of the languages. + +## šŸ› ļø Technical updates + +* Mermaid diagrams: patch for CVE-2025-54880 +* The settings were ported to React. **If you notice any issues with the settings, let us know and we'll promptly fix them.** +* [Improve management for settings INI](https://github.com/TriliumNext/Trilium/pull/6726) by @perfectra1n +* Log same error message on API 401 as on login error to allow fail2ban blocking by @hulmgulm \ No newline at end of file diff --git a/docs/Release Notes/Release Notes/v0.99.0.md b/docs/Release Notes/Release Notes/v0.99.0.md new file mode 100644 index 0000000000..758c814a74 --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.99.0.md @@ -0,0 +1,87 @@ +# v0.99.0 +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸ’” Key highlights + +* The documentation is now available at [docs.triliumnotes.org](https://docs.triliumnotes.org/). (by @perfectra1n). + +## šŸž Bugfixes + +* Revisions show the wrong note. +* Revision list exiting out of bounds. +* Various minor fixes to settings & modals following the porting to React. +* [Newly created child note may not show-up when the tree has sorting overrides](https://github.com/TriliumNext/Trilium/issues/6820) by @rom1dep +* The context menu of history navigation buttons (back/next) for the desktop application didn't work. +* Background effects causing black background on Windows 10. +* [#cssClass isn't applied to note content in mobile layout](https://github.com/TriliumNext/Trilium/issues/6798) by @Papierkorb2292 +* [Hotkeys interfering with IME composition](https://github.com/TriliumNext/Trilium/issues/6846) by @perfectra1n +* [Right-clicking the note tree buttons triggered their action instead of context menu](https://github.com/TriliumNext/Trilium/pull/6903) by @SiriusXT +* [Include note size not taken into account](https://github.com/TriliumNext/Trilium/issues/6947) +* [Shrink images is always displayed when importing notes](https://github.com/TriliumNext/Trilium/issues/6930) +* [Redirect bare domain not working properly when two-factor authentication is on](https://github.com/TriliumNext/Trilium/pull/6961) by @EnBandit +* Importing files doesn't update collections +* Background effects breaking if native title bar is enabled. +* Promoting the note source tab to a new window, brings the note editor instead. +* PDF preview card: ā€œDownloadā€ and ā€œOpenā€ buttons would also open the note instead of just doing their action. +* ā€œGeo Mapā€ in the Trilium Demo section would not show up properly. +* Printing/exporting to PDF triggers twice. +* Desktop: ā€œPort is already usedā€ when opening multiple instances of Trilium. +* .deb for ARM is not opening by @linull24 +* Branch prefix initial value not shown +* Blur not working properly for the global menu. +* [Note content replaced by Excalidraw JSON when switching notes](https://github.com/TriliumNext/Trilium/issues/6788) + +## ✨ Improvements + +* In Basic Properties: + * Added a modal to easily configure the code note types from the note type dropdown, without going through settings. + * Added a modal to content languages to easily configure the languages, without going through settings. +* The list of text snippets now displays the actual note icon and color. +* Minor improvements to the API log. +* Improve window background effects by @adoriandoran +* Theme improvements by @adoriandoran +* Add an option to disable smooth scrolling for the Electron app by @adoriandoran +* [Revisions dialog can optionally display the source diff between revisions](https://github.com/TriliumNext/Trilium/pull/6887) by @SiriusXT +* Splits are now resizable by @SiriusXT +* Improvements to collections: + * Geomap: Add a notification if book is locked while dragging. + * Table: Disable insert at position if sorting. + * Board + * Improve dragging experience for both columns and notes. + * Adding notes has been reworked so that it doesn't add the note first. + * Pressing escape while adding a note will dismiss it instead of adding an empty note. + * Note titles can be edited directly from the board by hovering the card with the mouse and clicking the edit button next to them. + * When editing, the note titles will now be displayed multi-line, to better match the end result. + * Slight style improvements (smoother shadows, no shift). + * Context menu option to archive/unarchive current item. + * All the collections (geo map, calendar, board, table) now indicate archived notes by greying out the item. + * Added an option to display archived notes in collection via the Collection Properties tab in the ribbon. +* The note ID in the Note info tab is now shown in monospace font. +* Context menu option in the note tree to archive/unarchive a note. +* Improve performance of collapsing subtrees by @werererer +* Create a more seamless PWA top bar by @qwreey +* [Default to hiding file details when opening a PDF note](https://github.com/TriliumNext/Trilium/issues/6873) +* Disable bold and italic from the highlights list for new users. +* Slash commands can now be disabled from Options → Text Notes → Features. +* Added a description for the editor features in Text Note options. + +## šŸŒ Internationalization + +* Various translation updates. + +## šŸ› ļø Technical updates + +* We've made some changes to our development environment as **we moved away from NX**. If you are developer working on Trilium, check [the PR](https://github.com/TriliumNext/Trilium/pull/6842) for more information. +* Some important UI components such as the ribbon, note actions, floating buttons and the note title, SQL console, search results, some menus have been ported to React. **Please report any issues you might encounter.** +* [Fixed missing TOTP verification for /login/token](https://github.com/TriliumNext/Trilium/pull/6823) by @Nriver +* Improved the format of the server startup message. +* Thanks to @FliegendeWurst for helping with fixing the Nix flakes after we changed our development environment. + +## šŸ”’ļø Security fixes + +* [CVE-2025-58754](https://redirect.github.com/axios/axios/security/advisories/GHSA-4hjh-wcwx-xvwj) affecting Axios (currently only used for backend scripts). +* CVE-2025-58064 in the text editor (CKEditor) \ No newline at end of file diff --git a/docs/Release Notes/Release Notes/v0.99.1.md b/docs/Release Notes/Release Notes/v0.99.1.md new file mode 100644 index 0000000000..6c7d0d629c --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.99.1.md @@ -0,0 +1,37 @@ +# v0.99.1 +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸ’” Key highlights + +* Trilium now has an official homepage: [https://triliumnotes.org/](https://triliumnotes.org/). Suggestions and bug reports are welcome. + +## šŸž Bugfixes + +* Zen mode: note buttons visible in zen mode. +* Deleting a bulk action would execute all bulk actions +* [Focus resets to start of note after adding inline link](https://github.com/TriliumNext/Trilium/issues/7115) +* [Zen mode doesn't increase web view size](https://github.com/TriliumNext/Trilium/issues/6972) by @Papierkorb2292 +* [Shortcut keys without modifiers affecting normal usage](https://github.com/TriliumNext/Trilium/issues/7121) +* Missing ribbon widgets section in Appearance +* Split button visible while printing +* Unable to search in read-only code notes +* [LLM chat: conversation not visible on Firefox](https://github.com/TriliumNext/Trilium/issues/5762) +* [Mind map affecting the use of the space bar in the entire app](https://github.com/TriliumNext/Trilium/issues/7170) + +## ✨ Improvements + +* [Make splits resizable while in Zen Mode](https://github.com/TriliumNext/Trilium/issues/7093) +* [Use number sorting for number columns in Table view](https://github.com/TriliumNext/Trilium/pull/7094) by @Mystler +* Improvements to the display of the toast notifications. +* Websocket connection errors are now displayed as a toast. +* Math equations can be customised, in text size, text color and background color. + +## šŸ› ļø Technical updates + +* Update Electron to v38 +* Fixed an event leak in modals. +* Replace `jsdom` with `node-html-parser` \ No newline at end of file diff --git a/docs/Release Notes/Release Notes/v0.99.2.md b/docs/Release Notes/Release Notes/v0.99.2.md new file mode 100644 index 0000000000..34be5d0a65 --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.99.2.md @@ -0,0 +1,66 @@ +# v0.99.2 +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸ’” Key highlights + +* Presentations can now be created directly from within Trilium, including being able to present in full screen. + * Presentations are a new type of collections. + * For more information, consult the in-app documentation or the [online documentation](https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Collections/Presentation%20View.html). +* The whole printing mechanism was redesigned from ground up. + * This should translate to more stable printing or exporting to PDF across note types. + * The new Presentation collection can also be exported as PDF. + * For more information, consult the [documentation](https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes/Printing%20%2526%20Exporting%20as%20PDF.html). + +## šŸž Bugfixes + +* Relation map: floating buttons stuck when showing source. +* [Mobile formatting toolbar appears cut off.](https://github.com/TriliumNext/Trilium/issues/7206) +* [Table View Max nesting depth not working](https://github.com/TriliumNext/Trilium/issues/7204) +* [Expand and Collapse buttons only work on refresh](https://github.com/TriliumNext/Trilium/issues/7209) +* Enter not working on Quick Search. +* Modifying an equation would reset its size, foreground color and background color. +* [Instances of Built-in Templates inherit `#excludeFromNoteMap`](https://github.com/TriliumNext/Trilium/issues/7187) +* [Background effects on Windows 11 were affected by custom title bar selection.](https://github.com/TriliumNext/Trilium/commit/5d8f789791f699d06e49123e672b1ad62b1d7ee7#commitcomment-165811641) +* [When creating a new note in the calendar view, the default name is not selected by default](https://github.com/TriliumNext/Trilium/issues/7289) +* [Wrong focus in protected session dialog](https://github.com/TriliumNext/Trilium/issues/7251) +* [Title bar buttons not centered on macOS](https://github.com/TriliumNext/Trilium/issues/7257) +* [Notes with children in collection list view are displayed twice](https://github.com/TriliumNext/Trilium/issues/7301) +* [The background color of a table's header remains black](https://github.com/TriliumNext/Trilium/issues/7230) +* [Keep the color of the note titles even after selection in the new theme](https://github.com/TriliumNext/Trilium/issues/3634) by @adoriandoran +* Search results: + * Collection would appear twice. + * Infinite recursion issues due to nesting, when using collections such as table. + * [Note path was no longer displayed.](https://github.com/TriliumNext/Trilium/issues/7404) + * All collection types are now supported by the search. +* Importing notes without selection imports previous selection +* [Failed to connect to Wayland display: No such file or directory](https://github.com/TriliumNext/Trilium/issues/7208) + +## ✨ Improvements + +* Board view enhancements: + * Basic keyboard interaction using Tab and Shift+Tab (consult the User Guide). + * The column title is now visible even if the column is scrolled. +* Custom HTML snippets in shared pages by @kleutzinger +* Text notes: [Allow accessing `obsidian:` links](https://github.com/TriliumNext/Trilium/issues/7207) +* Allow any date for first day of the week by @werererer +* Searches now have the _Collection Properties_ tab, to change the display mode from a list to one of the collections. +* [Clarify importing .zip structures when importing notes](https://github.com/TriliumNext/Trilium/issues/7429) +* [Style overhaul for the Canvas note type](https://github.com/TriliumNext/Trilium/pull/7372) by @adoriandoran + +## šŸ“– Documentation + +* Various improvements and clarifications. + +## šŸŒ Internationalization + +* Support for Portuguese (Portugal). +* Support for Arabic. + +## šŸ› ļø Technical updates + +* Fixed Nix flake. +* Preliminary support for right-to-left languages for the UI. \ No newline at end of file diff --git a/docs/Release Notes/Release Notes/v0.99.3.md b/docs/Release Notes/Release Notes/v0.99.3.md new file mode 100644 index 0000000000..e82ddaf602 --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.99.3.md @@ -0,0 +1,36 @@ +# v0.99.3 +> [!NOTE] +> If you are interested in an [official mobile application](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/7447) Ā ([#7447](https://github.com/TriliumNext/Trilium/issues/7447)) or [multi-user support](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/4956) ([#4956](https://github.com/TriliumNext/Trilium/issues/4956)), consider offering financial support via IssueHunt (see links). + +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸž Bugfixes + +* [Issues with the ribbon and some about dialogs when formatting locale is set to Chinese](https://github.com/TriliumNext/Trilium/issues/7444) +* Incorrect date format for Chinese. +* Development locale appearing in production. +* Split reverted on right-to-left languages +* Fixes for the Flatpak installation method: + * [Flatpak Data Access Issue on install/update : permission issue](https://github.com/TriliumNext/Trilium/issues/7454) + * [flatpak doesn't launch after install, needs no-sandbox](https://github.com/TriliumNext/Trilium/issues/5516) + * Icon missing in Flatpak shortcut. +* [Trilium does not unlock after autolock](https://github.com/TriliumNext/Trilium/issues/7448) by @perfectra1n +* Note color not taken into consideration for reference links by @adoriandoran +* [Board view doesn't respond to Color tags](https://github.com/TriliumNext/Trilium/issues/7456) by @adoriandoran + +## šŸ“– Documentation + +* Improve links & starting page in demo note by @tredondo + +## šŸŒ Internationalization + +* Added support for Italian +* Various translation improvements. + +## šŸ› ļø Technical updates + +* Various dependency updates. \ No newline at end of file diff --git a/docs/Release Notes/Release Notes/v0.99.4.md b/docs/Release Notes/Release Notes/v0.99.4.md new file mode 100644 index 0000000000..8f11bbaf51 --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.99.4.md @@ -0,0 +1,79 @@ +# v0.99.4 +> [!NOTE] +> If you are interested in an [official mobile application](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/7447) Ā ([#7447](https://github.com/TriliumNext/Trilium/issues/7447)) or [multi-user support](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/4956) ([#4956](https://github.com/TriliumNext/Trilium/issues/4956)), consider offering financial support via IssueHunt (see links). + +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸ’” Key highlights + +* The [triliumnotes.org](https://triliumnotes.org/) website now has multi-language support. Consider contributing translations over on [Weblate](https://hosted.weblate.org/projects/trilium/website/). +* [docs.triliumnotes.org](https://docs.triliumnotes.org) has switched from mkdocs to our own export to static website solution based on the Share functionality. +* Developer documentation is now available at [docs.triliumnotes.org/developer-guide/](https://docs.triliumnotes.org/developer-guide/). + +## šŸž Bugfixes + +* [Excessive spacing in expanded empty children of a collection list view](https://github.com/TriliumNext/Trilium/issues/7319) +* [Share: headings with CJK characters had incorrect URLs.](https://github.com/TriliumNext/Trilium/issues/6430) +* Share: headings were displayed in ToC with their HTML tags escaped. +* Import/export was enabled in note context menu for help notes. +* [Image colors become muted on a canvas note when dark theme is enabled](https://github.com/TriliumNext/Trilium/issues/5708) +* [Edited notes list automatic updates to Hidden Notes](https://github.com/TriliumNext/Trilium/issues/5683) +* [Calendar tooltip is not correctly positioned](https://github.com/TriliumNext/Trilium/issues/5675) +* Some images not displayed properly when printing or exporting to PDF. +* [New tab in a freshly opened window does not show recent notes](https://github.com/TriliumNext/Trilium/issues/6881) by @SiriusXT +* [Overlapping note map button & fixed toolbar not shown in Zen Mode](https://github.com/TriliumNext/Trilium/pull/7543) by @SiriusXT +* ["Markdown import from clipboard" not working in "Quick edit"](https://github.com/TriliumNext/Trilium/issues/7520) by @SiriusXT +* [Note revisions not displaying the right date](https://github.com/TriliumNext/Trilium/pull/7544) by @contributor +* Bug fixes for the share theme: + * [Admonition icons not displayed](https://github.com/TriliumNext/Trilium/issues/6733) + * Light theme was not loaded in some circumstances. + * Flash of dark color when loading the light theme. + * Improved layout of the share theme to better fit and not zoom out on mobile devices such as tablets. +* [Reload not working on extra desktop windows](https://github.com/TriliumNext/Trilium/pull/7567) by @SiriusXT +* [Activate the nearest path when opening a cloned note](https://github.com/TriliumNext/Trilium/pull/7552) by @SiriusXT +* [Port-in-use dialog shown when opening a new window](https://github.com/TriliumNext/Trilium/pull/7595) by @SiriusXT +* [Enable Numpad Enter to trigger quick search](https://github.com/TriliumNext/Trilium/pull/7624) by @SiriusXT +* [Search with `=` no longer working](https://github.com/TriliumNext/Trilium/pull/7268) by @perfectra1n +* [Kanban template doesn't copy empty columns](https://github.com/TriliumNext/Trilium/issues/7612) +* [Picture references in HTML export pointing to non-existing files (affects duplicated, untouched notes)](https://github.com/TriliumNext/Trilium/issues/7471) & [Images not available for shared Duplicated note](https://github.com/TriliumNext/Trilium/issues/7642) +* [Cloned note in board view](https://github.com/TriliumNext/Trilium/issues/6786) +* [Ignore toggle tray command if tray is disabled](https://github.com/TriliumNext/Trilium/pull/7654) by @contributor +* Fixed formatting toolbar shown for read-only notes + +## ✨ Improvements + +* [Search results are now displayed on mobile, including the search definition.](https://github.com/TriliumNext/Trilium/issues/5655) +* [Add UI for #iconClass="bx bx-empty"](https://github.com/TriliumNext/Trilium/issues/7370) +* [Keyboard shortcut for Today Note button](https://github.com/TriliumNext/Trilium/issues/7472) by @contributor +* [Mermaid diagram notes: add link to docs](https://github.com/TriliumNext/Trilium/issues/5378) +* [Change the branch prefix of multiple notes simultaneously](https://github.com/TriliumNext/Trilium/issues/7571) by @Copilot +* [Custom CSS for printing is now possible again](https://github.com/TriliumNext/Trilium/issues/7608) +* [Send global shortcut to current window](https://github.com/TriliumNext/Trilium/pull/7645) +* The calendar collection now uses the ā€œDate & Number Formatā€. +* [Many UI improvements](https://github.com/TriliumNext/Trilium/pull/7655) by @adoriandoran + * **Zen Mode Overhaul** – improved the appearance and layout of the Zen Mode view. The content of text notes is now vertically aligned, with a slightly larger font size to enhance focus. The content width now follows the ā€œMax content widthā€ option. The formatting toolbar has been moved to the bottom and remains full-width even in split-note view. You can now activate editing mode for read-only notes directly from Zen Mode. A launcher for Zen Mode has also been added to the Launchbar (hidden by default, to add it to the Launchbar: right-click the toolbar, choose Configure Launchbar, then right-click Zen Mode and select Move to visible launchers). + * **ā€œMax content widthā€ option and content alignment improvements** – the internal behavior of the ā€œMax content widthā€ option has been rewritten. Content now aligns to the left by default (or to the right in RTL mode). To center the content instead, enable ā€œKeep content centeredā€ under Options → Appearance. The note title and ribbon now always span the full width, and the scrollbar stays aligned with the edge. Changing the width value no longer requires restarting the front-end. + * **Read-only note alert bar** – to better highlight that a note is read-only and make editing more intuitive, a message bar now appears at the top of the note with a button to enable editing. The floating pencil button used previously for this purpose has been removed. An ā€œEditā€ command has also been added to the note menu. + * **Quick Edit dialog background tinting** – the background tint of the Quick Edit dialog now reflects the note’s color attribute. + * **Extra Mica effect** – on Windows 11, the desktop app now applies the Mica background effect to settings pages, the right pane, and empty tabs. + +## šŸ“– Documentation + +* Moved Collections one level up. +* The API documentation has been moved online-only. +* The technical documentation has been restructured and brought up to date. +* Many improvements to the user guide as well. + +## šŸŒ Internationalization + +* Various translation updates. + +## šŸ› ļø Technical updates + +* [`trilium` batch files not running on Powershell 7](https://github.com/TriliumNext/Trilium/pull/7513) by @Ra2-IFV +* **Switched from Node.js 22 to Node.js 24 as it becomes the new LTS.** +* edited notes: remove comma for flexible styling by @contributor \ No newline at end of file diff --git a/docs/Release Notes/Release Notes/v0.99.5.md b/docs/Release Notes/Release Notes/v0.99.5.md new file mode 100644 index 0000000000..dbc6c11cee --- /dev/null +++ b/docs/Release Notes/Release Notes/v0.99.5.md @@ -0,0 +1,24 @@ +# v0.99.5 +> [!NOTE] +> If you are interested in an [official mobile application](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/7447) Ā ([#7447](https://github.com/TriliumNext/Trilium/issues/7447)) or [multi-user support](https://oss.issuehunt.io/r/TriliumNext/Trilium/issues/4956) ([#4956](https://github.com/TriliumNext/Trilium/issues/4956)), consider offering financial support via IssueHunt (see links). + +> [!IMPORTANT] +> If you enjoyed this release, consider showing a token of appreciation by: +> +> * Pressing the ā€œStarā€ button on [GitHub](https://github.com/TriliumNext/Trilium) (top-right). +> * Considering a one-time or recurrent donation to the [lead developer](https://github.com/eliandoran) via [GitHub Sponsors](https://github.com/sponsors/eliandoran) or [PayPal](https://paypal.me/eliandoran). + +## šŸž Bugfixes + +* [List view: weird animation + hard to toggle collapse/expand deeper nested subnotes](https://github.com/TriliumNext/Trilium/issues/7667) by @adoriandoran +* Code block ā€œCopy to clipboard buttonā€ visible while printing. +* Packaged server .zip build not working due to wrong Node.js version. +* Not all changed notes are displayed in day note by @contributor +* [Calendar view drag-and-drop issue](https://github.com/TriliumNext/Trilium/issues/7685) +* ["Open attribute list" shortcut does not focus the attribute list](https://github.com/TriliumNext/Trilium/issues/7463) +* [Global shortcuts and system tray icon sometimes not shown under Wayland in Flatpak](https://github.com/TriliumNext/Trilium/issues/7563) +* [Quick edit text drag indicator missing](https://github.com/TriliumNext/Trilium/issues/7686) + +## ✨ Improvements + +* [Show collections grid and list views in zen mode](https://github.com/TriliumNext/Trilium/issues/7668) by @adoriandoran \ No newline at end of file diff --git a/docs/Script API/media/README-ZH_CN.md b/docs/Script API/media/README-ZH_CN.md index 0fb87daa87..75704ace62 100644 --- a/docs/Script API/media/README-ZH_CN.md +++ b/docs/Script API/media/README-ZH_CN.md @@ -15,7 +15,7 @@ Trilium Notes ę˜Æäø€äøŖå±‚ę¬”åŒ–ēš„ē¬”č®°åŗ”ē”ØēØ‹åŗļ¼Œäø“ę³ØäŗŽå»ŗē«‹å¤§åž‹äøŖ ę¬¢čæŽåŠ å…„ęˆ‘ä»¬ēš„å®˜ę–¹č®Øč®ŗå’Œē¤¾åŒŗć€‚ęˆ‘ä»¬äø“ę³ØäŗŽTriliumēš„å¼€å‘ļ¼Œä¹äŗŽå¬å–ę‚ØåÆ¹åŠŸčƒ½ć€å»ŗč®®ęˆ–é—®é¢˜ēš„ę„č§ļ¼ - [Matrix](https://matrix.to/#/#triliumnext:matrix.org)ļ¼ˆē”ØäŗŽåŒę­„č®Øč®ŗļ¼‰ -- [Github Discussions](https://github.com/TriliumNext/Notes/discussions)ļ¼ˆē”ØäŗŽå¼‚ę­„č®Øč®ŗļ¼‰ +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions)ļ¼ˆē”ØäŗŽå¼‚ę­„č®Øč®ŗļ¼‰ - [Wiki](https://triliumnext.github.io/Docs/)ļ¼ˆē”ØäŗŽåøøč§ę“ä½œé—®é¢˜å’Œē”Øęˆ·ęŒ‡å—ļ¼‰ äøŠé¢é“¾ęŽ„ēš„äø¤äøŖęˆæé—“ę˜Æé•œåƒēš„ļ¼Œę‰€ä»„ę‚ØåÆä»„åœØä»»ę„å¹³å°äøŠä½æē”ØXMPPꈖ者Matrixę„å’Œęˆ‘ä»¬äŗ¤ęµć€‚ @@ -55,7 +55,7 @@ Trilium Notes ę˜Æäø€äøŖå±‚ę¬”åŒ–ēš„ē¬”č®°åŗ”ē”ØēØ‹åŗļ¼Œäø“ę³ØäŗŽå»ŗē«‹å¤§åž‹äøŖ Trilium åÆä»„ē”Øä½œę”Œé¢åŗ”ē”ØēØ‹åŗļ¼ˆLinux 和 Windowsļ¼‰ęˆ–ęœåŠ”å™Øļ¼ˆLinuxļ¼‰äøŠę‰˜ē®”ēš„ Web åŗ”ē”ØēØ‹åŗć€‚č™½ē„¶ęœ‰ macOS ē‰ˆęœ¬ēš„ę”Œé¢åŗ”ē”ØēØ‹åŗļ¼Œä½†å®ƒ[äøå—ę”ÆęŒ](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support)怂 -* å¦‚ęžœč¦åœØę”Œé¢äøŠä½æē”Ø Triliumļ¼ŒčÆ·ä»Ž[ęœ€ę–°ē‰ˆęœ¬](https://github.com/TriliumNext/Notes/releases/latest)äø‹č½½é€‚ē”ØäŗŽę‚Øå¹³å°ēš„äŗŒčæ›åˆ¶ē‰ˆęœ¬ļ¼Œč§£åŽ‹ē¼©čÆ„č½Æä»¶åŒ…å¹¶čæč”Œ`trilium`åÆę‰§č”Œę–‡ä»¶ć€‚ +* å¦‚ęžœč¦åœØę”Œé¢äøŠä½æē”Ø Triliumļ¼ŒčÆ·ä»Ž[ęœ€ę–°ē‰ˆęœ¬](https://github.com/TriliumNext/Trilium/releases/latest)äø‹č½½é€‚ē”ØäŗŽę‚Øå¹³å°ēš„äŗŒčæ›åˆ¶ē‰ˆęœ¬ļ¼Œč§£åŽ‹ē¼©čÆ„č½Æä»¶åŒ…å¹¶čæč”Œ`trilium`åÆę‰§č”Œę–‡ä»¶ć€‚ * å¦‚ęžœč¦åœØęœåŠ”å™ØäøŠå®‰č£… Triliumļ¼ŒčÆ·å‚č€ƒ[ę­¤é”µé¢](https://triliumnext.github.io/Docs/Wiki/server-installation)怂 * å½“å‰ä»…ę”ÆęŒļ¼ˆęµ‹čÆ•čæ‡ļ¼‰ęœ€čæ‘å‘åøƒēš„ Chrome 和 Firefox ęµč§ˆå™Øć€‚ diff --git a/docs/Script API/media/README.es.md b/docs/Script API/media/README.es.md index d57d656953..72736348bb 100644 --- a/docs/Script API/media/README.es.md +++ b/docs/Script API/media/README.es.md @@ -14,7 +14,7 @@ Vea estas [capturas de pantalla](https://triliumnext.github.io/Docs/Wiki/screens ### ĀæCómo migrar desde Trilium? -No hay pasos de migración especiales para migrar de una instancia de zadam/Trilium a una instancia de TriliumNext/Notes. Simplemente actualice su instancia de Trilium a la Ćŗltima versión e [instale TriliumNext/Notes como de costumbre](#-Instalación) +No hay pasos de migración especiales para migrar de una instancia de zadam/Trilium a una instancia de TriliumNext/Trilium. Simplemente actualice su instancia de Trilium a la Ćŗltima versión e [instale TriliumNext/Trilium como de costumbre](#-Instalación) ## šŸ’¬ Discuta con nosotros @@ -22,7 +22,7 @@ SiĆ©ntase libre de unirse a nuestras conversaciones oficiales. Ā”Nos encantarĆ­a - [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Para discusiones sĆ­ncronas) - La sala `General` es replicada a [XMPP](xmpp:discuss@trilium.thisgreat.party?join) -- [Discusiones de GitHub](https://github.com/TriliumNext/Notes/discussions) (Para discusiones asĆ­ncronas) +- [Discusiones de GitHub](https://github.com/TriliumNext/Trilium/discussions) (Para discusiones asĆ­ncronas) - [Wiki](https://triliumnext.github.io/Docs/) (Para preguntas frecuentes y guĆ­as de usuario) ## šŸŽ CaracterĆ­sticas @@ -58,7 +58,7 @@ SiĆ©ntase libre de unirse a nuestras conversaciones oficiales. Ā”Nos encantarĆ­a Para usar TriliumNext en su mĆ”quina de escritorio (Linux, MacOS y Windows) tiene algunas opciones: -- Descargue la versión binaria para su plataforma desde la [pĆ”gina de lanzamientos](https://github.com/TriliumNext/Notes/releases/latest), descomprima el paquete y ejecute el ejecutable `trilium`. +- Descargue la versión binaria para su plataforma desde la [pĆ”gina de lanzamientos](https://github.com/TriliumNext/Trilium/releases/latest), descomprima el paquete y ejecute el ejecutable `trilium`. - Acceda a TriliumNext a travĆ©s de la interfaz web de una instalación de servidor (ver mĆ”s abajo) - Actualmente solo las Ćŗltimas versiones de Chrome y Firefox son compatibles (y estĆ”n probadas). - (Próximamente) TriliumNext tambiĆ©n se proporcionarĆ” como un Flatpak @@ -68,11 +68,11 @@ Para usar TriliumNext en su mĆ”quina de escritorio (Linux, MacOS y Windows) tien Para usar TriliumNext en un dispositivo móvil: - Utilice un navegador web móvil para acceder a la interfaz móvil de una instalación de servidor (ver mĆ”s abajo) -- El uso de una aplicación móvil aĆŗn no estĆ” soportado ([vea aquĆ­](https://github.com/TriliumNext/Notes/issues/72)) para seguir las mejoras móviles. +- El uso de una aplicación móvil aĆŗn no estĆ” soportado ([vea aquĆ­](https://github.com/TriliumNext/Trilium/issues/72)) para seguir las mejoras móviles. ### Servidor -Para instalar TriliumNext en su servidor (incluyendo vĆ­a Docker desde [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) siga la [documentación de instalación de servidor](https://triliumnext.github.io/Docs/Wiki/server-installation). +Para instalar TriliumNext en su servidor (incluyendo vĆ­a Docker desde [Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) siga la [documentación de instalación de servidor](https://triliumnext.github.io/Docs/Wiki/server-installation). ## šŸ“ Documentación diff --git a/docs/Script API/media/README.it.md b/docs/Script API/media/README.it.md index 1c0bf99113..5fb3bb0a75 100644 --- a/docs/Script API/media/README.it.md +++ b/docs/Script API/media/README.it.md @@ -15,7 +15,7 @@ Vedi [fotografie](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) per u Sentiti libero di unirti alle nostre discussioni ufficiali e alla nostra comunitĆ . Siamo concentrati sullo sviluppo di Trilium e ci piacerebbe sapere quali funzioni, suggerimenti o eventuali problemi hai! - [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Per discussioni sincrone) -- [Discussioni Github](https://github.com/TriliumNext/Notes/discussions) (Per discussioni asincrone) +- [Discussioni Github](https://github.com/TriliumNext/Trilium/discussions) (Per discussioni asincrone) - [Wiki](https://triliumnext.github.io/Docs/) (Per le domande più comuni e le guide per l'utente) Le due stanze linkate sopra sono connesse e contengono gli stessi messaggi, quindi puoi usare XMPP o Matrix da qualsiasi client tu preferisca, praticamente su qualsiasi piattaforma! @@ -53,7 +53,7 @@ Le due stanze linkate sopra sono connesse e contengono gli stessi messaggi, quin Trilium ĆØ fornito come applicazione desktop (Linux e Windows) o come applicazione web ospitata sul tuo server (Linux). La versione desktop per Mac OS ĆØ disponibile, ma [non ĆØ supportata](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support). -* Se vuoi usare Trilium sul tuo desktop, scarica il rilascio binario per la tua piattaforma dall'[ultimo rilascio](https://github.com/TriliumNext/Notes/releases/latest), decomprimi l'archivio e avvia l'eseguibile ```trilium```. +* Se vuoi usare Trilium sul tuo desktop, scarica il rilascio binario per la tua piattaforma dall'[ultimo rilascio](https://github.com/TriliumNext/Trilium/releases/latest), decomprimi l'archivio e avvia l'eseguibile ```trilium```. * Se vuoi installare Trilium su un server, segui [questa pagina](https://triliumnext.github.io/Docs/Wiki/server-installation). * Per ora solo Chrome e Firefox sono i browser supportati (testati). diff --git a/docs/Script API/media/README.ja.md b/docs/Script API/media/README.ja.md index e16234dbd6..012f8c910c 100644 --- a/docs/Script API/media/README.ja.md +++ b/docs/Script API/media/README.ja.md @@ -34,7 +34,7 @@ Trilium Notes ćÆć€å¤§č¦ęØ”ćŖå€‹äŗŗēŸ„č­˜ćƒ™ćƒ¼ć‚¹ć®ę§‹ēÆ‰ć«ē„¦ē‚¹ć‚’å½“ć¦ Trilium ćÆć€ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ļ¼ˆLinux态Windowsļ¼‰ć¾ćŸćÆć‚µćƒ¼ćƒćƒ¼äøŠć§ćƒ›ć‚¹ćƒˆć•ć‚Œć‚‹ć‚¦ć‚§ćƒ–ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ļ¼ˆLinuxļ¼‰ćØć—ć¦ęä¾›ć•ć‚Œć¾ć™ć€‚ Mac OS ć®ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ćƒ“ćƒ«ćƒ‰ć‚‚åˆ©ē”ØåÆčƒ½ć§ć™ćŒć€ [unsupported](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support) となっています。 -* ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć§ Trilium ć‚’ä½æē”Øć—ćŸć„å “åˆćÆć€ [latest release](https://github.com/TriliumNext/Notes/releases/latest) ć‹ć‚‰ćŠä½æć„ć®ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć®ćƒć‚¤ćƒŠćƒŖćƒŖćƒŖćƒ¼ć‚¹ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ć—ć€ćƒ‘ćƒƒć‚±ćƒ¼ć‚øć‚’č§£å‡ć—ć¦ ``trilium`` ć®å®Ÿč”Œćƒ•ć‚”ć‚¤ćƒ«ć‚’å®Ÿč”Œć—ć¦ćć ć•ć„ć€‚ +* ćƒ‡ć‚¹ć‚Æćƒˆćƒƒćƒ—ć§ Trilium ć‚’ä½æē”Øć—ćŸć„å “åˆćÆć€ [latest release](https://github.com/TriliumNext/Trilium/releases/latest) ć‹ć‚‰ćŠä½æć„ć®ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć®ćƒć‚¤ćƒŠćƒŖćƒŖćƒŖćƒ¼ć‚¹ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ć—ć€ćƒ‘ćƒƒć‚±ćƒ¼ć‚øć‚’č§£å‡ć—ć¦ ``trilium`` ć®å®Ÿč”Œćƒ•ć‚”ć‚¤ćƒ«ć‚’å®Ÿč”Œć—ć¦ćć ć•ć„ć€‚ * ć‚µćƒ¼ćƒćƒ¼ć« Trilium ć‚’ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć™ć‚‹å “åˆćÆć€[ć“ć®ćƒšćƒ¼ć‚ø](https://triliumnext.github.io/Docs/Wiki/server-installation)ć«å¾“ć£ć¦ćć ć•ć„ć€‚ * ē¾åœØć€åÆ¾åæœļ¼ˆå‹•ä½œē¢ŗčŖļ¼‰ć—ć¦ć„ć‚‹ćƒ–ćƒ©ć‚¦ć‚¶ćÆć€ęœ€čæ‘ć® Chrome と Firefox のみです。 diff --git a/docs/Script API/media/README.md b/docs/Script API/media/README.md index a32ea2ba21..0aba72e2ea 100644 --- a/docs/Script API/media/README.md +++ b/docs/Script API/media/README.md @@ -1,6 +1,6 @@ # Trilium Notes -![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) ![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/notes) ![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/triliumnext/notes/total) +![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran) ![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/trilium) ![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/triliumnext/trilium/total) [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) @@ -16,9 +16,9 @@ See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for q ### Migrating from Trilium? -There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Notes instance. Just upgrade your Trilium instance to the latest version and [install TriliumNext/Notes as usual](#-installation) +There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Trilium instance. Just upgrade your Trilium instance to the latest version and [install TriliumNext/Trilium as usual](#-installation) -Versions up to and including [v0.90.4](https://github.com/TriliumNext/Notes/releases/tag/v0.90.4) are compatible with the latest zadam/trilium version of [v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later versions of TriliumNext have their sync versions incremented. +Versions up to and including [v0.90.4](https://github.com/TriliumNext/Trilium/releases/tag/v0.90.4) are compatible with the latest zadam/trilium version of [v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later versions of TriliumNext have their sync versions incremented. ## šŸ’¬ Discuss with us @@ -26,7 +26,7 @@ Feel free to join our official conversations. We would love to hear what feature - [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous discussions) - The `General` Matrix room is also bridged to [XMPP](xmpp:discuss@trilium.thisgreat.party?join) -- [Github Discussions](https://github.com/TriliumNext/Notes/discussions) (For Asynchronous discussions) +- [Github Discussions](https://github.com/TriliumNext/Trilium/discussions) (For Asynchronous discussions) - [Wiki](https://triliumnext.github.io/Docs/) (For common how-to questions and user guides) ## šŸŽ Features @@ -63,16 +63,16 @@ Feel free to join our official conversations. We would love to hear what feature To use TriliumNext on your desktop machine (Linux, MacOS, and Windows) you have a few options: -* Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Notes/releases/latest), unzip the package and run the ```trilium``` executable. +* Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Trilium/releases/latest), unzip the package and run the ```trilium``` executable. * Access TriliumNext via the web interface of a server installation (see below) * Currently only the latest versions of Chrome & Firefox are supported (and tested). * (Coming Soon) TriliumNext will also be provided as a Flatpak #### MacOS -Currently when running TriliumNext/Notes on MacOS, you may get the following error: +Currently when running TriliumNext/Trilium on MacOS, you may get the following error: > Apple could not verify "Trilium Notes" is free of malware and may harm your Mac or compromise your privacy. -You will need to run the command on your shell to resolve the error (documented [here](https://github.com/TriliumNext/Notes/issues/329#issuecomment-2287164137)): +You will need to run the command on your shell to resolve the error (documented [here](https://github.com/TriliumNext/Trilium/issues/329#issuecomment-2287164137)): ```bash xattr -c "/path/to/Trilium Next.app" @@ -84,11 +84,11 @@ To use TriliumNext on a mobile device, you can use a mobile web browser to acces If you prefer a native Android app, you can use [TriliumDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.fliegendewurst.triliumdroid). Report bugs and missing features at [their repository](https://github.com/FliegendeWurst/TriliumDroid). -See issue https://github.com/TriliumNext/Notes/issues/72 for more information on mobile app support. +See issue https://github.com/TriliumNext/Trilium/issues/72 for more information on mobile app support. ### Server -To install TriliumNext on your own server (including via Docker from [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) follow [the server installation docs](https://triliumnext.github.io/Docs/Wiki/server-installation). +To install TriliumNext on your own server (including via Docker from [Dockerhub](https://hub.docker.com/r/triliumnext/trilium)) follow [the server installation docs](https://triliumnext.github.io/Docs/Wiki/server-installation). ## šŸ“ Documentation @@ -101,17 +101,17 @@ You can also read [Patterns of personal knowledge base](https://triliumnext.gith ### Code ```shell -git clone https://github.com/TriliumNext/Notes.git +git clone https://github.com/TriliumNext/Trilium.git cd Notes npm install npm run server:start ``` -For more details, see the [development docs](https://github.com/TriliumNext/Notes/blob/develop/docs/Developer%20Guide/Developer%20Guide/Building%20and%20deployment/Running%20a%20development%20build.md). +For more details, see the [development docs](https://github.com/TriliumNext/Trilium/blob/develop/docs/Developer%20Guide/Developer%20Guide/Building%20and%20deployment/Running%20a%20development%20build.md). ### Documentation -See the [documentation guide](https://github.com/TriliumNext/Notes/blob/develop/docs/Developer%20Guide/Developer%20Guide/Documentation.md) for details. +See the [documentation guide](https://github.com/TriliumNext/Trilium/blob/develop/docs/Developer%20Guide/Developer%20Guide/Documentation.md) for details. ## šŸ‘ Shoutouts @@ -123,7 +123,7 @@ See the [documentation guide](https://github.com/TriliumNext/Notes/blob/develop/ ## šŸ¤ Support Support for the TriliumNext organization will be possible in the near future. For now, you can: -- Support continued development on TriliumNext by supporting our developers: [eliandoran](https://github.com/sponsors/eliandoran) (See the [repository insights]([developers]([url](https://github.com/TriliumNext/Notes/graphs/contributors))) for a full list) +- Support continued development on TriliumNext by supporting our developers: [eliandoran](https://github.com/sponsors/eliandoran) (See the [repository insights]([developers]([url](https://github.com/TriliumNext/Trilium/graphs/contributors))) for a full list) - Show a token of gratitude to the original Trilium developer ([zadam](https://github.com/sponsors/zadam)) via [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). diff --git a/docs/Script API/media/README.ru.md b/docs/Script API/media/README.ru.md index 03a319313b..3c13ccdcba 100644 --- a/docs/Script API/media/README.ru.md +++ b/docs/Script API/media/README.ru.md @@ -28,7 +28,7 @@ Trilium Notes – ŃŃ‚Š¾ приложение Š“Š»Ń заметок с иера Trilium ŠæŃ€ŠµŠ“Š¾ŃŃ‚Š°Š²Š»ŃŠµŃ‚ŃŃ в виГе Гесктопного ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ (Linux Šø Windows) или веб-ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ, размещенного на вашем сервере (Linux). Š”Š¾ŃŃ‚ŃƒŠæŠ½Š° сборка Mac OS, но она [не ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ŃŃ](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support). -* Если вы хотите ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ Trilium на Гесктопе, скачайте архив Š“Š»Ń своей платформы со страницы [релизов](https://github.com/TriliumNext/Notes/releases/latest), Ń€Š°ŃŠæŠ°ŠŗŃƒŠ¹Ń‚Šµ Šø Š·Š°ŠæŃƒŃŃ‚ŠøŃ‚Šµ ŠøŃŠæŠ¾Š»Š½ŃŠµŠ¼Ń‹Š¹ файл ```trilium```. +* Если вы хотите ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ Trilium на Гесктопе, скачайте архив Š“Š»Ń своей платформы со страницы [релизов](https://github.com/TriliumNext/Trilium/releases/latest), Ń€Š°ŃŠæŠ°ŠŗŃƒŠ¹Ń‚Šµ Šø Š·Š°ŠæŃƒŃŃ‚ŠøŃ‚Šµ ŠøŃŠæŠ¾Š»Š½ŃŠµŠ¼Ń‹Š¹ файл ```trilium```. * Если вы хотите ŃƒŃŃ‚Š°Š½Š¾Š²ŠøŃ‚ŃŒ Trilium на сервере, ŃŠ»ŠµŠ“ŃƒŠ¹Ń‚Šµ ŃŃ‚Š¾Š¹ [ŠøŠ½ŃŃ‚Ń€ŃƒŠŗŃ†ŠøŠø](https://triliumnext.github.io/Docs/Wiki/server-installation). * Š’ Ганный момент ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‚ŃŃ (протестированы) послеГние версии Š±Ń€Š°ŃƒŠ·ŠµŃ€Š¾Š² Chrome Šø Firefox. diff --git a/docs/User Guide/!!!meta.json b/docs/User Guide/!!!meta.json index 8620611a54..2a294ebda3 100644 --- a/docs/User Guide/!!!meta.json +++ b/docs/User Guide/!!!meta.json @@ -1,6 +1,6 @@ { "formatVersion": 2, - "appVersion": "0.97.1", + "appVersion": "0.102.1", "files": [ { "isClone": false, @@ -14,7 +14,92 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "s3YCWHBfmYuM", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "gh7bpGYxajRS", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "BFs8mudNFgCS", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GTwFsgaA0lCt", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "poXkQfguuA0U", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "WOcw2SLH6tbX", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Q2z6av6JZVWm", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "MEtfsqa5VwNi", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "9qPsTWBorUhQ", + "isInheritable": false, + "position": 90 + }, + { + "type": "label", + "name": "shareAlias", + "value": "user-guide", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "label:shareAlias", + "value": "promoted,alias=Slug,single,text", + "isInheritable": true, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-help-circle", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", "dataFileName": "User Guide.md", "attachments": [], @@ -37,121 +122,135 @@ { "type": "relation", "name": "internalLink", - "value": "ZjLYv08Rp3qC", + "value": "IjZS7iK5EXtb", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "R9pX4DGra2Vt", + "value": "I6p2a06hdnL6", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "LMAv4Uy3Wk6J", + "value": "GTwFsgaA0lCt", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "NRnIZmSMc5sj", + "value": "2FvYrpmOXm29", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "rC3pL2aptaRE", + "value": "ZjLYv08Rp3qC", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "GTwFsgaA0lCt", + "value": "iPIMuisry3hd", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "2FvYrpmOXm29", + "value": "ZlN4nump6EbW", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "iPIMuisry3hd", + "value": "pwc194wlRzcH", "isInheritable": false, "position": 80 }, { "type": "relation", "name": "internalLink", - "value": "ZlN4nump6EbW", + "value": "R9pX4DGra2Vt", "isInheritable": false, "position": 90 }, { "type": "relation", "name": "internalLink", - "value": "pwc194wlRzcH", + "value": "7DAiwaf8Z7Rz", "isInheritable": false, "position": 100 }, { "type": "relation", "name": "internalLink", - "value": "7DAiwaf8Z7Rz", + "value": "veGu4faJErEM", "isInheritable": false, "position": 110 }, { "type": "relation", "name": "internalLink", - "value": "veGu4faJErEM", + "value": "NRnIZmSMc5sj", "isInheritable": false, "position": 120 }, { "type": "relation", "name": "internalLink", - "value": "xWbu3jpNWapp", + "value": "rC3pL2aptaRE", "isInheritable": false, "position": 130 }, { "type": "relation", "name": "internalLink", - "value": "AgjCISero73a", + "value": "xWbu3jpNWapp", "isInheritable": false, "position": 140 }, { "type": "relation", "name": "internalLink", - "value": "81SGnPGMk7Xc", + "value": "AgjCISero73a", "isInheritable": false, "position": 150 }, { "type": "relation", "name": "internalLink", - "value": "gBbsAeiuUxI5", + "value": "81SGnPGMk7Xc", "isInheritable": false, "position": 160 }, + { + "type": "relation", + "name": "internalLink", + "value": "gBbsAeiuUxI5", + "isInheritable": false, + "position": 170 + }, { "type": "label", "name": "iconClass", "value": "bx bx-star", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "feature-highlights", + "isInheritable": false, + "position": 170 } ], "format": "markdown", @@ -178,6 +277,13 @@ "value": "bx bx-cog", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "setup", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -202,14 +308,14 @@ { "type": "relation", "name": "internalLink", - "value": "tAassRL4RSQL", + "value": "l2VkvOwUNfZj", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "l2VkvOwUNfZj", + "value": "tAassRL4RSQL", "isInheritable": false, "position": 20 }, @@ -223,14 +329,136 @@ { "type": "label", "name": "shareAlias", - "value": "desktop-installation", + "value": "desktop", "isInheritable": false, "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-desktop", + "isInheritable": false, + "position": 40 } ], "format": "markdown", "dataFileName": "Desktop Installation.md", - "attachments": [] + "attachments": [], + "dirFileName": "Desktop Installation", + "children": [ + { + "isClone": false, + "noteId": "nRqcgfTb97uV", + "notePath": [ + "pOsGYCXsbNQG", + "Otzi9La2YAUX", + "poXkQfguuA0U", + "nRqcgfTb97uV" + ], + "title": "Using the desktop application as a server", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "WOcw2SLH6tbX", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "x3i7MxGccDuM", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "desktop-as-server", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Using the desktop application .md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "Rp0q8bSP6Ayl", + "notePath": [ + "pOsGYCXsbNQG", + "Otzi9La2YAUX", + "poXkQfguuA0U", + "Rp0q8bSP6Ayl" + ], + "title": "System Requirements", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "system-requirements", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-chip", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "System Requirements.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "Un4wj2Mak2Ky", + "notePath": [ + "pOsGYCXsbNQG", + "Otzi9La2YAUX", + "poXkQfguuA0U", + "Un4wj2Mak2Ky" + ], + "title": "Nix flake", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "nix-flake", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxl-tux", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Nix flake.md", + "attachments": [] + } + ] }, { "isClone": false, @@ -341,9 +569,16 @@ { "type": "label", "name": "shareAlias", - "value": "server-installation", + "value": "server", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-server", + "isInheritable": false, + "position": 140 } ], "format": "markdown", @@ -366,7 +601,15 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "installation", + "isInheritable": false, + "position": 20 + } + ], "format": "markdown", "attachments": [], "dirFileName": "1. Installing the server", @@ -405,7 +648,7 @@ { "type": "label", "name": "shareAlias", - "value": "packaged-server-installation", + "value": "packaged-server", "isInheritable": false, "position": 10 }, @@ -452,10 +695,17 @@ "isInheritable": false, "position": 20 }, + { + "type": "relation", + "name": "internalLink", + "value": "Gzjqa934BdH4", + "isInheritable": false, + "position": 30 + }, { "type": "label", "name": "shareAlias", - "value": "docker-server-installation", + "value": "docker", "isInheritable": false, "position": 30 }, @@ -491,7 +741,7 @@ { "type": "label", "name": "shareAlias", - "value": "nixos-server-installation", + "value": "nixos", "isInheritable": false, "position": 10 }, @@ -548,7 +798,7 @@ { "type": "label", "name": "shareAlias", - "value": "manual-server-installation", + "value": "manual", "isInheritable": false, "position": 20 }, @@ -584,7 +834,7 @@ { "type": "label", "name": "shareAlias", - "value": "kubernetes-server-installation", + "value": "kubernetes", "isInheritable": false, "position": 10 }, @@ -620,21 +870,21 @@ { "type": "relation", "name": "internalLink", - "value": "J1Bb6lVlwU5T", + "value": "cbkrhQjrkKrh", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "cbkrhQjrkKrh", + "value": "3tW6mORuTHnB", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "3tW6mORuTHnB", + "value": "J1Bb6lVlwU5T", "isInheritable": false, "position": 30 }, @@ -658,6 +908,13 @@ "value": "bx bxs-user-account", "isInheritable": false, "position": 60 + }, + { + "type": "label", + "name": "shareAlias", + "value": "multiple-instances", + "isInheritable": false, + "position": 70 } ], "format": "markdown", @@ -681,7 +938,15 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "reverse-proxy", + "isInheritable": false, + "position": 20 + } + ], "format": "markdown", "attachments": [], "dirFileName": "2. Reverse proxy", @@ -703,10 +968,17 @@ "type": "text", "mime": "text/markdown", "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "LLzSMXACKhUs", + "isInheritable": false, + "position": 10 + }, { "type": "label", "name": "shareAlias", - "value": "nginx-proxy-setup", + "value": "nginx", "isInheritable": false, "position": 10 } @@ -725,23 +997,109 @@ "vcjrb3VVYPZI", "fDLvzOx29Pfg" ], - "title": "Apache", + "title": "Apache using Docker", "notePosition": 20, "prefix": null, "isExpanded": false, "type": "text", "mime": "text/markdown", "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "LLzSMXACKhUs", + "isInheritable": false, + "position": 10 + }, { "type": "label", "name": "shareAlias", - "value": "apache-proxy-setup", + "value": "apache", "isInheritable": false, "position": 10 } ], "format": "markdown", - "dataFileName": "Apache.md", + "dataFileName": "Apache using Docker.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "LLzSMXACKhUs", + "notePath": [ + "pOsGYCXsbNQG", + "Otzi9La2YAUX", + "WOcw2SLH6tbX", + "vcjrb3VVYPZI", + "LLzSMXACKhUs" + ], + "title": "Trusted proxy", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "vcjrb3VVYPZI", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Gzjqa934BdH4", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "trusted-proxy", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Trusted proxy.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "5ERVJb9s4FRD", + "notePath": [ + "pOsGYCXsbNQG", + "Otzi9La2YAUX", + "WOcw2SLH6tbX", + "vcjrb3VVYPZI", + "5ERVJb9s4FRD" + ], + "title": "Traefik", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "LLzSMXACKhUs", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "traefik", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Traefik.md", "attachments": [] } ] @@ -755,7 +1113,7 @@ "WOcw2SLH6tbX", "l2VkvOwUNfZj" ], - "title": "TLS Configuration", + "title": "HTTPS (TLS)", "notePosition": 100, "prefix": null, "isExpanded": false, @@ -772,27 +1130,41 @@ { "type": "relation", "name": "internalLink", - "value": "tAassRL4RSQL", + "value": "vcjrb3VVYPZI", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "Gzjqa934BdH4", + "value": "tAassRL4RSQL", "isInheritable": false, "position": 30 }, + { + "type": "relation", + "name": "internalLink", + "value": "Gzjqa934BdH4", + "isInheritable": false, + "position": 40 + }, { "type": "label", "name": "shareAlias", - "value": "tls-configuration", + "value": "https", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-lock-alt", + "isInheritable": false, + "position": 50 } ], "format": "markdown", - "dataFileName": "TLS Configuration.md", + "dataFileName": "HTTPS (TLS).md", "attachments": [] }, { @@ -814,30 +1186,37 @@ { "type": "relation", "name": "internalLink", - "value": "wX4HbRucYSDD", + "value": "7DAiwaf8Z7Rz", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "YKWqdJhzi2VY", + "value": "wX4HbRucYSDD", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "7DAiwaf8Z7Rz", + "value": "YKWqdJhzi2VY", "isInheritable": false, "position": 30 }, { "type": "label", "name": "iconClass", - "value": "bx bx-lock-alt", + "value": "bx bx-user", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "auth", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -870,7 +1249,7 @@ { "type": "label", "name": "shareAlias", - "value": "multi-factor-authentication", + "value": "mfa", "isInheritable": false, "position": 10 }, @@ -885,6 +1264,113 @@ "format": "markdown", "dataFileName": "Multi-Factor Authentication.md", "attachments": [] + }, + { + "isClone": true, + "noteId": "Un4wj2Mak2Ky", + "notePath": [ + "pOsGYCXsbNQG", + "Otzi9La2YAUX", + "WOcw2SLH6tbX", + "Un4wj2Mak2Ky" + ], + "title": "Nix flake", + "prefix": null, + "dataFileName": "Nix flake.clone.md", + "type": "text", + "format": "markdown", + "isExpanded": false + }, + { + "isClone": false, + "noteId": "yeEaYqosGLSh", + "notePath": [ + "pOsGYCXsbNQG", + "Otzi9La2YAUX", + "WOcw2SLH6tbX", + "yeEaYqosGLSh" + ], + "title": "Third-party cloud hosting", + "notePosition": 130, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "Dgg7bR3b6K9j", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "cbkrhQjrkKrh", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "poXkQfguuA0U", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-cloud", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "cloud-hosting", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Third-party cloud hosting.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "iGTnKjubbXkA", + "notePath": [ + "pOsGYCXsbNQG", + "Otzi9La2YAUX", + "WOcw2SLH6tbX", + "iGTnKjubbXkA" + ], + "title": "System Requirements", + "notePosition": 140, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "system-requirements", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-chip", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "System Requirements.md", + "attachments": [] } ] }, @@ -994,24 +1480,87 @@ { "type": "relation", "name": "internalLink", - "value": "bwg0e8ewQMak", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "WOcw2SLH6tbX", + "value": "YtSN43OrfzaA", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "CdNpE2pqjmI6", + "value": "Ms1nauBra7gq", "isInheritable": false, "position": 30 }, + { + "type": "relation", + "name": "internalLink", + "value": "eIg8jdvaoNNd", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "x3i7MxGccDuM", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "xYmIYSP6wE3F", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "3seOhtN8uLIY", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "luNhaphA37EO", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "IjZS7iK5EXtb", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "WOcw2SLH6tbX", + "isInheritable": false, + "position": 100 + }, + { + "type": "relation", + "name": "internalLink", + "value": "nRqcgfTb97uV", + "isInheritable": false, + "position": 110 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CdNpE2pqjmI6", + "isInheritable": false, + "position": 120 + }, { "type": "label", "name": "shareAlias", @@ -1031,20 +1580,12 @@ "dataFileName": "Mobile Frontend.md", "attachments": [ { - "attachmentId": "CyswsZZ3GwtQ", - "title": "mobile-tablet.png", + "attachmentId": "JRliU5bOLszn", + "title": "IMG_1765.PNG", "role": "image", "mime": "image/png", "position": 10, - "dataFileName": "Mobile Frontend_mobile-tab.png" - }, - { - "attachmentId": "txzBbmMtgsrx", - "title": "mobile-smartphone.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Mobile Frontend_mobile-sma.png" + "dataFileName": "Mobile Frontend_IMG_1765.PNG" } ] }, @@ -1090,6 +1631,13 @@ "value": "web-clipper", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-paperclip", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -1151,9 +1699,16 @@ { "type": "label", "name": "shareAlias", - "value": "upgrading-trilium", + "value": "upgrading", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-up-arrow-alt", + "isInheritable": false, + "position": 50 } ], "format": "markdown", @@ -1185,21 +1740,21 @@ { "type": "relation", "name": "internalLink", - "value": "Gzjqa934BdH4", + "value": "tAassRL4RSQL", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "tAassRL4RSQL", + "value": "cbkrhQjrkKrh", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "cbkrhQjrkKrh", + "value": "Gzjqa934BdH4", "isInheritable": false, "position": 40 }, @@ -1209,6 +1764,13 @@ "value": "backup", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-hdd", + "isInheritable": false, + "position": 50 } ], "format": "markdown", @@ -1244,6 +1806,27 @@ "isInheritable": false, "position": 20 }, + { + "type": "relation", + "name": "internalLink", + "value": "bnyigUA2UK7s", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "x59R8J8KV5Bp", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Gzjqa934BdH4", + "isInheritable": false, + "position": 50 + }, { "type": "label", "name": "shareAlias", @@ -1294,6 +1877,13 @@ "value": "bx bx-help-circle", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "concepts", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -1321,6 +1911,13 @@ "value": "bx bx-window-alt", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "ui", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -1384,6 +1981,13 @@ "value": "bx bxs-layout", "isInheritable": false, "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "layouts", + "isInheritable": false, + "position": 60 } ], "format": "markdown", @@ -1468,6 +2072,13 @@ "value": "bx bx-menu", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "global-menu", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -1530,7 +2141,7 @@ { "type": "label", "name": "shareAlias", - "value": "tree-manipulation", + "value": "note-tree", "isInheritable": false, "position": 20 }, @@ -1606,112 +2217,112 @@ { "type": "relation", "name": "internalLink", - "value": "OR8WJ7Iz9K4U", + "value": "3seOhtN8uLIY", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "KC1HB96bqqHX", + "value": "OR8WJ7Iz9K4U", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "bwg0e8ewQMak", + "value": "KSZ04uQ2D1St", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "IakOLONlIfGI", + "value": "KC1HB96bqqHX", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "mHbBMPDPkVV5", + "value": "bwg0e8ewQMak", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "eIg8jdvaoNNd", + "value": "IakOLONlIfGI", "isInheritable": false, "position": 80 }, { "type": "relation", "name": "internalLink", - "value": "ivYnonVFBxbQ", + "value": "MKmLg5x6xkor", "isInheritable": false, "position": 90 }, { "type": "relation", "name": "internalLink", - "value": "TBwsyfadTA18", + "value": "r5JGHN99bVKn", "isInheritable": false, "position": 100 }, { "type": "relation", "name": "internalLink", - "value": "0vhv7lsOLy82", + "value": "mHbBMPDPkVV5", "isInheritable": false, "position": 110 }, { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "eIg8jdvaoNNd", "isInheritable": false, "position": 120 }, { "type": "relation", "name": "internalLink", - "value": "aGlEvb9hyDhS", + "value": "ivYnonVFBxbQ", "isInheritable": false, "position": 130 }, { "type": "relation", "name": "internalLink", - "value": "wArbEsdSae6g", + "value": "TBwsyfadTA18", "isInheritable": false, "position": 140 }, { "type": "relation", "name": "internalLink", - "value": "3seOhtN8uLIY", + "value": "0vhv7lsOLy82", "isInheritable": false, "position": 150 }, { "type": "relation", "name": "internalLink", - "value": "KSZ04uQ2D1St", + "value": "W8vYD3Q1zjCR", "isInheritable": false, "position": 160 }, { "type": "relation", "name": "internalLink", - "value": "r5JGHN99bVKn", + "value": "zEY4DaJG4YT5", "isInheritable": false, "position": 170 }, { "type": "relation", "name": "internalLink", - "value": "W8vYD3Q1zjCR", + "value": "aGlEvb9hyDhS", "isInheritable": false, "position": 180 }, @@ -1722,12 +2333,26 @@ "isInheritable": false, "position": 190 }, + { + "type": "relation", + "name": "internalLink", + "value": "wArbEsdSae6g", + "isInheritable": false, + "position": 200 + }, { "type": "label", "name": "iconClass", "value": "bx bx-menu", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "context-menu", + "isInheritable": false, + "position": 210 } ], "format": "markdown", @@ -1781,6 +2406,13 @@ "value": "bx bx-list-plus", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "multiple-selection", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -1830,21 +2462,130 @@ { "type": "relation", "name": "internalLink", - "value": "yTjUdsOi4CIE", + "value": "IakOLONlIfGI", "isInheritable": false, "position": 30 }, + { + "type": "relation", + "name": "internalLink", + "value": "yTjUdsOi4CIE", + "isInheritable": false, + "position": 40 + }, { "type": "label", "name": "iconClass", "value": "bx bxs-keyboard", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "keyboard-shortcuts", + "isInheritable": false, + "position": 40 } ], "format": "markdown", "dataFileName": "Keyboard shortcuts.md", "attachments": [] + }, + { + "isClone": false, + "noteId": "wyaGBBQrl4i3", + "notePath": [ + "pOsGYCXsbNQG", + "gh7bpGYxajRS", + "Vc8PjrjAGuOp", + "oPVyFC7WL2Lp", + "wyaGBBQrl4i3" + ], + "title": "Hiding the subtree", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "GTwFsgaA0lCt", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "hrZ1D00cLbal", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "eIg8jdvaoNNd", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "TBwsyfadTA18", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CssoWBu8I7jF", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 60 + }, + { + "type": "label", + "name": "shareAlias", + "value": "hiding-subtree", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-hide", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Hiding the subtree.md", + "attachments": [ + { + "attachmentId": "d9Sq9avKDptU", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Hiding the subtree_image.png" + }, + { + "attachmentId": "VmRtx3vS97v1", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_Hiding the subtree_image.png" + } + ] } ] }, @@ -1874,149 +2615,163 @@ { "type": "relation", "name": "internalLink", - "value": "4FahAwuGTAwC", + "value": "nRhnJkTT8cPs", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "bwg0e8ewQMak", + "value": "KSZ04uQ2D1St", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "CoFPLs3dRlXc", + "value": "4FahAwuGTAwC", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "xYmIYSP6wE3F", + "value": "bwg0e8ewQMak", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "u3YFHC9tQlpm", + "value": "CoFPLs3dRlXc", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "R9pX4DGra2Vt", + "value": "xYmIYSP6wE3F", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "KC1HB96bqqHX", + "value": "u3YFHC9tQlpm", "isInheritable": false, "position": 80 }, { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "WOcw2SLH6tbX", "isInheritable": false, "position": 90 }, { "type": "relation", "name": "internalLink", - "value": "OFXdgB2nNk1F", + "value": "R9pX4DGra2Vt", "isInheritable": false, "position": 100 }, { "type": "relation", "name": "internalLink", - "value": "bwZpz2ajCEwO", + "value": "KC1HB96bqqHX", "isInheritable": false, "position": 110 }, { "type": "relation", "name": "internalLink", - "value": "oPVyFC7WL2Lp", + "value": "veGu4faJErEM", "isInheritable": false, "position": 120 }, { "type": "relation", "name": "internalLink", - "value": "IakOLONlIfGI", + "value": "zEY4DaJG4YT5", "isInheritable": false, "position": 130 }, { "type": "relation", "name": "internalLink", - "value": "xWtq5NUHOwql", + "value": "OFXdgB2nNk1F", "isInheritable": false, "position": 140 }, { "type": "relation", "name": "internalLink", - "value": "m1lbrzyKDaRB", + "value": "bwZpz2ajCEwO", "isInheritable": false, "position": 150 }, { "type": "relation", "name": "internalLink", - "value": "wX4HbRucYSDD", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 160 }, { "type": "relation", "name": "internalLink", - "value": "l0tKav7yLHGF", + "value": "IakOLONlIfGI", "isInheritable": false, "position": 170 }, { "type": "relation", "name": "internalLink", - "value": "nRhnJkTT8cPs", + "value": "xWtq5NUHOwql", "isInheritable": false, "position": 180 }, { "type": "relation", "name": "internalLink", - "value": "KSZ04uQ2D1St", + "value": "m1lbrzyKDaRB", "isInheritable": false, "position": 190 }, { "type": "relation", "name": "internalLink", - "value": "WOcw2SLH6tbX", + "value": "wX4HbRucYSDD", "isInheritable": false, "position": 200 }, { "type": "relation", "name": "internalLink", - "value": "veGu4faJErEM", + "value": "l0tKav7yLHGF", "isInheritable": false, "position": 210 }, + { + "type": "relation", + "name": "internalLink", + "value": "_optionsAppearance", + "isInheritable": false, + "position": 220 + }, { "type": "label", "name": "iconClass", "value": "bx bx-dots-horizontal", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "ribbon", + "isInheritable": false, + "position": 230 } ], "format": "markdown", @@ -2051,30 +2806,51 @@ { "type": "relation", "name": "internalLink", - "value": "oPVyFC7WL2Lp", + "value": "x0JgW8UqGXvq", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "luNhaphA37EO", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "x0JgW8UqGXvq", + "value": "luNhaphA37EO", "isInheritable": false, "position": 30 }, + { + "type": "relation", + "name": "internalLink", + "value": "RDslemsQ6gCp", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "xYmIYSP6wE3F", + "isInheritable": false, + "position": 50 + }, { "type": "label", "name": "iconClass", "value": "bx bx-dock-top", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "tabs", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -2103,6 +2879,14 @@ "mime": "image/png", "position": 10, "dataFileName": "2_Tabs_image.png" + }, + { + "attachmentId": "rFdKVhoVtsLA", + "title": "IMG_1767.PNG", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Tabs_IMG_1767.PNG" } ] }, @@ -2125,56 +2909,56 @@ { "type": "relation", "name": "internalLink", - "value": "x3i7MxGccDuM", + "value": "x0JgW8UqGXvq", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "p9kXRFAkwN4o", + "value": "x3i7MxGccDuM", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "OR8WJ7Iz9K4U", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "OFXdgB2nNk1F", + "value": "p9kXRFAkwN4o", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "x0JgW8UqGXvq", + "value": "OR8WJ7Iz9K4U", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "oPVyFC7WL2Lp", + "value": "CdNpE2pqjmI6", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "CdNpE2pqjmI6", + "value": "SynTBQiBsdYJ", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "SynTBQiBsdYJ", + "value": "OFXdgB2nNk1F", "isInheritable": false, "position": 80 }, @@ -2184,6 +2968,13 @@ "value": "bx bx-sidebar", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "launch-bar", + "isInheritable": false, + "position": 90 } ], "format": "markdown", @@ -2218,37 +3009,58 @@ { "type": "relation", "name": "internalLink", - "value": "vZWERwf8U3nx", + "value": "BlN9DFI679QC", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "4FahAwuGTAwC", + "value": "vZWERwf8U3nx", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "0vhv7lsOLy82", + "value": "4FahAwuGTAwC", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "BlN9DFI679QC", + "value": "0vhv7lsOLy82", "isInheritable": false, "position": 40 }, + { + "type": "relation", + "name": "internalLink", + "value": "IjZS7iK5EXtb", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "W8vYD3Q1zjCR", + "isInheritable": false, + "position": 60 + }, { "type": "label", "name": "iconClass", "value": "bx bx-dots-vertical-rounded", "isInheritable": false, "position": 50 + }, + { + "type": "label", + "name": "shareAlias", + "value": "note-buttons", + "isInheritable": false, + "position": 60 } ], "format": "markdown", @@ -2297,30 +3109,44 @@ { "type": "relation", "name": "internalLink", - "value": "oPVyFC7WL2Lp", + "value": "_options", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "3seOhtN8uLIY", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "cbkrhQjrkKrh", + "value": "3seOhtN8uLIY", "isInheritable": false, "position": 50 }, + { + "type": "relation", + "name": "internalLink", + "value": "cbkrhQjrkKrh", + "isInheritable": false, + "position": 60 + }, { "type": "label", "name": "iconClass", "value": "bx bx-cog", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "options", + "isInheritable": false, + "position": 70 } ], "format": "markdown", @@ -2363,21 +3189,21 @@ { "type": "relation", "name": "internalLink", - "value": "oPVyFC7WL2Lp", + "value": "3seOhtN8uLIY", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "OR8WJ7Iz9K4U", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "3seOhtN8uLIY", + "value": "OR8WJ7Iz9K4U", "isInheritable": false, "position": 30 }, @@ -2387,6 +3213,13 @@ "value": "bx bx-dock-right", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "split-view", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -2453,35 +3286,35 @@ { "type": "relation", "name": "internalLink", - "value": "CoFPLs3dRlXc", + "value": "BlN9DFI679QC", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "BlN9DFI679QC", + "value": "s1aBHPd79XYj", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "s1aBHPd79XYj", + "value": "grjYqerjn243", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "grjYqerjn243", + "value": "iPIMuisry3hd", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "iPIMuisry3hd", + "value": "CoFPLs3dRlXc", "isInheritable": false, "position": 50 }, @@ -2491,6 +3324,13 @@ "value": "bx bx-rectangle", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "floating-buttons", + "isInheritable": false, + "position": 60 } ], "format": "markdown", @@ -2556,6 +3396,13 @@ "value": "bx bxs-dock-right", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "right-sidebar", + "isInheritable": false, + "position": 50 } ], "format": "markdown", @@ -2621,6 +3468,13 @@ "value": "bx bx-history", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "recent-changes", + "isInheritable": false, + "position": 50 } ], "format": "markdown", @@ -2660,47 +3514,39 @@ "type": "text", "mime": "text/html", "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "x3i7MxGccDuM", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "4TIF1oA4VQRO", + "isInheritable": false, + "position": 20 + }, { "type": "label", "name": "iconClass", "value": "bx bx-zoom-in", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "zoom", + "isInheritable": false, + "position": 20 } ], "format": "markdown", "dataFileName": "Zoom.md", "attachments": [] }, - { - "isClone": false, - "noteId": "ZjLYv08Rp3qC", - "notePath": [ - "pOsGYCXsbNQG", - "gh7bpGYxajRS", - "Vc8PjrjAGuOp", - "ZjLYv08Rp3qC" - ], - "title": "Quick edit", - "notePosition": 200, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Quick edit.md", - "attachments": [ - { - "attachmentId": "EBOLwVGrA8bv", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Quick edit_image.png" - } - ] - }, { "isClone": false, "noteId": "lgKX7r3aL30x", @@ -2720,21 +3566,121 @@ { "type": "relation", "name": "internalLink", - "value": "ZjLYv08Rp3qC", + "value": "hrZ1D00cLbal", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "Cq5X6iKQop6R", + "value": "ZjLYv08Rp3qC", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "hrZ1D00cLbal", + "value": "iPIMuisry3hd", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GTwFsgaA0lCt", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "81SGnPGMk7Xc", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "xWbu3jpNWapp", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "2FvYrpmOXm29", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Cq5X6iKQop6R", + "isInheritable": false, + "position": 80 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-message-detail", + "isInheritable": false, + "position": 100 + }, + { + "type": "label", + "name": "shareAlias", + "value": "note-tooltip", + "isInheritable": false, + "position": 110 + } + ], + "format": "markdown", + "dataFileName": "Note Tooltip.md", + "attachments": [ + { + "attachmentId": "AHAT2uK9sy9d", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Note Tooltip_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "IjZS7iK5EXtb", + "notePath": [ + "pOsGYCXsbNQG", + "gh7bpGYxajRS", + "Vc8PjrjAGuOp", + "IjZS7iK5EXtb" + ], + "title": "New Layout", + "notePosition": 220, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "veGu4faJErEM", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "zEY4DaJG4YT5", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "AlJ73vBCjWDw", "isInheritable": false, "position": 30 }, @@ -2748,49 +3694,272 @@ { "type": "relation", "name": "internalLink", - "value": "GTwFsgaA0lCt", + "value": "6f9hih2hXXZk", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "81SGnPGMk7Xc", + "value": "grjYqerjn243", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "xWbu3jpNWapp", + "value": "KC1HB96bqqHX", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "2FvYrpmOXm29", + "value": "XpOYSgsLkTJy", "isInheritable": false, "position": 80 }, { - "type": "label", - "name": "iconClass", - "value": "bx bx-message-detail", + "type": "relation", + "name": "internalLink", + "value": "cbkrhQjrkKrh", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "MtPxeAWVAzMg", "isInheritable": false, "position": 100 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CdNpE2pqjmI6", + "isInheritable": false, + "position": 110 + }, + { + "type": "relation", + "name": "internalLink", + "value": "YKWqdJhzi2VY", + "isInheritable": false, + "position": 120 + }, + { + "type": "relation", + "name": "internalLink", + "value": "l0tKav7yLHGF", + "isInheritable": false, + "position": 130 + }, + { + "type": "relation", + "name": "internalLink", + "value": "4TIF1oA4VQRO", + "isInheritable": false, + "position": 140 + }, + { + "type": "relation", + "name": "internalLink", + "value": "eIg8jdvaoNNd", + "isInheritable": false, + "position": 150 + }, + { + "type": "relation", + "name": "internalLink", + "value": "m523cpzocqaD", + "isInheritable": false, + "position": 160 + }, + { + "type": "relation", + "name": "internalLink", + "value": "8YBEPzcpUgxw", + "isInheritable": false, + "position": 170 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 180 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-layout", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "new-layout", + "isInheritable": false, + "position": 190 } ], "format": "markdown", - "dataFileName": "Note Tooltip.md", + "dataFileName": "New Layout.md", "attachments": [ { - "attachmentId": "AHAT2uK9sy9d", + "attachmentId": "3DFGaMiTTHQ1", "title": "image.png", "role": "image", "mime": "image/png", "position": 10, - "dataFileName": "Note Tooltip_image.png" + "dataFileName": "New Layout_image.png" + }, + { + "attachmentId": "6iN5nrmdwG6z", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_New Layout_image.png" + }, + { + "attachmentId": "a7dHjn9Uqvsc", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "2_New Layout_image.png" + }, + { + "attachmentId": "KvNAEoJjRhyr", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "3_New Layout_image.png" + }, + { + "attachmentId": "lEKxf6dYMG6u", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "4_New Layout_image.png" + }, + { + "attachmentId": "SYOTVGCyx749", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "5_New Layout_image.png" + }, + { + "attachmentId": "wCwzwfGspejR", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "6_New Layout_image.png" + } + ], + "dirFileName": "New Layout", + "children": [ + { + "isClone": false, + "noteId": "I6p2a06hdnL6", + "notePath": [ + "pOsGYCXsbNQG", + "gh7bpGYxajRS", + "Vc8PjrjAGuOp", + "IjZS7iK5EXtb", + "I6p2a06hdnL6" + ], + "title": "Breadcrumb", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "AlJ73vBCjWDw", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-chevron-right", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "breadcrumb", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "Breadcrumb.md", + "attachments": [ + { + "attachmentId": "CjYmaJD0L1D4", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Breadcrumb_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "AlJ73vBCjWDw", + "notePath": [ + "pOsGYCXsbNQG", + "gh7bpGYxajRS", + "Vc8PjrjAGuOp", + "IjZS7iK5EXtb", + "AlJ73vBCjWDw" + ], + "title": "Status bar", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "I6p2a06hdnL6", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-dock-bottom", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "status-bar", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "Status bar.md", + "attachments": [] } ] } @@ -2884,7 +4053,7 @@ { "type": "label", "name": "shareAlias", - "value": "note", + "value": "notes", "isInheritable": false, "position": 30 }, @@ -2979,14 +4148,14 @@ { "type": "relation", "name": "internalLink", - "value": "R7abl2fc6Mxi", + "value": "CdNpE2pqjmI6", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "CdNpE2pqjmI6", + "value": "R7abl2fc6Mxi", "isInheritable": false, "position": 30 }, @@ -3056,7 +4225,7 @@ { "type": "label", "name": "shareAlias", - "value": "cloning-notes", + "value": "cloning", "isInheritable": false, "position": 20 }, @@ -3102,14 +4271,14 @@ { "type": "relation", "name": "internalLink", - "value": "IakOLONlIfGI", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "oPVyFC7WL2Lp", + "value": "IakOLONlIfGI", "isInheritable": false, "position": 20 }, @@ -3119,6 +4288,13 @@ "value": "bx bx-rename", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "branch-prefix", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -3320,14 +4496,14 @@ { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "oPVyFC7WL2Lp", + "value": "zEY4DaJG4YT5", "isInheritable": false, "position": 20 }, @@ -3359,7 +4535,7 @@ "BFs8mudNFgCS", "NRnIZmSMc5sj" ], - "title": "Export as PDF", + "title": "Printing & Exporting as PDF", "notePosition": 120, "prefix": null, "isExpanded": false, @@ -3369,34 +4545,132 @@ { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "wy8So3yZZlH9", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "wy8So3yZZlH9", + "value": "CohkqWQC1iBv", "isInheritable": false, "position": 20 }, + { + "type": "relation", + "name": "internalLink", + "value": "zEY4DaJG4YT5", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GTwFsgaA0lCt", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "mULW0Q3VojwY", + "isInheritable": false, + "position": 50 + }, { "type": "relation", "name": "internalLink", "value": "4TIF1oA4VQRO", "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "KSZ04uQ2D1St", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "zP3PMqaG71Ct", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "grjYqerjn243", + "isInheritable": false, + "position": 100 + }, + { + "type": "relation", + "name": "internalLink", + "value": "gBbsAeiuUxI5", + "isInheritable": false, + "position": 110 + }, + { + "type": "relation", + "name": "internalLink", + "value": "2FvYrpmOXm29", + "isInheritable": false, + "position": 120 + }, + { + "type": "relation", + "name": "internalLink", + "value": "AlhDUqhENtH7", + "isInheritable": false, + "position": 130 + }, + { + "type": "relation", + "name": "internalLink", + "value": "bwZpz2ajCEwO", + "isInheritable": false, + "position": 140 + }, + { + "type": "relation", + "name": "internalLink", + "value": "KC1HB96bqqHX", + "isInheritable": false, + "position": 150 + }, + { + "type": "relation", + "name": "internalLink", + "value": "0ESUbbAxVnoK", + "isInheritable": false, + "position": 160 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-printer", + "isInheritable": false, "position": 30 }, { "type": "label", - "name": "iconClass", - "value": "bx bxs-file-pdf", + "name": "shareAlias", + "value": "printing-and-pdf-export", "isInheritable": false, - "position": 30 + "position": 110 } ], "format": "markdown", - "dataFileName": "Export as PDF.md", + "dataFileName": "Printing & Exporting as PDF.md", "attachments": [ { "attachmentId": "NfSjRsArIQHy", @@ -3404,7 +4678,7 @@ "role": "image", "mime": "image/png", "position": 10, - "dataFileName": "Export as PDF_image.png" + "dataFileName": "Printing & Exporting as PD.png" }, { "attachmentId": "Om2EmdZr54vy", @@ -3412,7 +4686,7 @@ "role": "image", "mime": "image/png", "position": 10, - "dataFileName": "1_Export as PDF_image.png" + "dataFileName": "1_Printing & Exporting as PD.png" } ] }, @@ -3435,63 +4709,77 @@ { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "iPIMuisry3hd", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "iPIMuisry3hd", + "value": "6f9hih2hXXZk", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "6f9hih2hXXZk", + "value": "4TIF1oA4VQRO", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "4TIF1oA4VQRO", + "value": "_optionsTextNotes", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "BlN9DFI679QC", + "value": "_optionsCodeNotes", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "XpOYSgsLkTJy", + "value": "BlN9DFI679QC", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "s1aBHPd79XYj", + "value": "zEY4DaJG4YT5", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "81SGnPGMk7Xc", + "value": "XpOYSgsLkTJy", "isInheritable": false, "position": 80 }, + { + "type": "relation", + "name": "internalLink", + "value": "s1aBHPd79XYj", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "81SGnPGMk7Xc", + "isInheritable": false, + "position": 100 + }, { "type": "label", "name": "shareAlias", - "value": "read-only-note", + "value": "read-only-notes", "isInheritable": false, "position": 30 }, @@ -3559,6 +4847,13 @@ "value": "bx bxs-grid", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "note-list", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -3597,6 +4892,13 @@ "value": "bx bx-navigation", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "navigation", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -3722,14 +5024,14 @@ { "type": "relation", "name": "internalLink", - "value": "F1r9QtzQLZqm", + "value": "eIg8jdvaoNNd", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "eIg8jdvaoNNd", + "value": "F1r9QtzQLZqm", "isInheritable": false, "position": 20 }, @@ -3760,6 +5062,13 @@ "value": "bx bx-search-alt-2", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "quick-search", + "isInheritable": false, + "position": 60 } ], "format": "markdown", @@ -3798,6 +5107,13 @@ "isInheritable": false, "position": 10 }, + { + "type": "relation", + "name": "internalLink", + "value": "A9Oc6YKKc65v", + "isInheritable": false, + "position": 20 + }, { "type": "label", "name": "iconClass", @@ -3806,11 +5122,11 @@ "position": 10 }, { - "type": "relation", - "name": "internalLink", - "value": "A9Oc6YKKc65v", + "type": "label", + "name": "shareAlias", + "value": "jump-to", "isInheritable": false, - "position": 20 + "position": 30 } ], "format": "markdown", @@ -3868,77 +5184,77 @@ { "type": "relation", "name": "internalLink", - "value": "A9Oc6YKKc65v", + "value": "xYmIYSP6wE3F", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "OR8WJ7Iz9K4U", + "value": "YtSN43OrfzaA", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "wX4HbRucYSDD", + "value": "A9Oc6YKKc65v", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "ivYnonVFBxbQ", + "value": "OR8WJ7Iz9K4U", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "xYmIYSP6wE3F", + "value": "9sRHySam5fXb", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "YtSN43OrfzaA", + "value": "m523cpzocqaD", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "9sRHySam5fXb", + "value": "6f9hih2hXXZk", "isInheritable": false, "position": 80 }, { "type": "relation", "name": "internalLink", - "value": "m523cpzocqaD", + "value": "wX4HbRucYSDD", "isInheritable": false, "position": 90 }, { "type": "relation", "name": "internalLink", - "value": "6f9hih2hXXZk", + "value": "MKmLg5x6xkor", "isInheritable": false, "position": 100 }, { "type": "relation", "name": "internalLink", - "value": "MKmLg5x6xkor", + "value": "qzNzp9LYQyPT", "isInheritable": false, "position": 110 }, { "type": "relation", "name": "internalLink", - "value": "qzNzp9LYQyPT", + "value": "ivYnonVFBxbQ", "isInheritable": false, "position": 120 }, @@ -3993,6 +5309,20 @@ "type": "text", "mime": "text/markdown", "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "xYmIYSP6wE3F", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "x3i7MxGccDuM", + "isInheritable": false, + "position": 20 + }, { "type": "label", "name": "shareAlias", @@ -4010,24 +5340,7 @@ ], "format": "markdown", "dataFileName": "Bookmarks.md", - "attachments": [ - { - "attachmentId": "99dD0P74W8QJ", - "title": "bookmark-folder.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Bookmarks_bookmark-folder.png" - }, - { - "attachmentId": "9dX71aLlSl9R", - "title": "bookmarks.gif", - "role": "image", - "mime": "image/gif", - "position": 10, - "dataFileName": "Bookmarks_bookmarks.gif" - } - ] + "attachments": [] }, { "isClone": false, @@ -4088,7 +5401,7 @@ ] }, { - "isClone": true, + "isClone": false, "noteId": "ZjLYv08Rp3qC", "notePath": [ "pOsGYCXsbNQG", @@ -4097,11 +5410,130 @@ "ZjLYv08Rp3qC" ], "title": "Quick edit", + "notePosition": 90, "prefix": null, - "dataFileName": "Quick edit.clone.md", + "isExpanded": false, "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "3seOhtN8uLIY", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GTwFsgaA0lCt", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "0ESUbbAxVnoK", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "iPIMuisry3hd", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "nRhnJkTT8cPs", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "OFXdgB2nNk1F", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "hrZ1D00cLbal", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "lgKX7r3aL30x", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "xWbu3jpNWapp", + "isInheritable": false, + "position": 100 + }, + { + "type": "relation", + "name": "internalLink", + "value": "l0tKav7yLHGF", + "isInheritable": false, + "position": 110 + }, + { + "type": "relation", + "name": "internalLink", + "value": "81SGnPGMk7Xc", + "isInheritable": false, + "position": 120 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CoFPLs3dRlXc", + "isInheritable": false, + "position": 130 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-edit", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "quick-edit", + "isInheritable": false, + "position": 40 + } + ], "format": "markdown", - "isExpanded": false + "dataFileName": "Quick edit.md", + "attachments": [ + { + "attachmentId": "EBOLwVGrA8bv", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Quick edit_image.png" + } + ] }, { "isClone": false, @@ -4198,6 +5630,13 @@ "value": "bx bx-bar-chart", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "similar-notes", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -4232,21 +5671,21 @@ { "type": "relation", "name": "internalLink", - "value": "MI26XDLSAlCD", + "value": "iPIMuisry3hd", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "iPIMuisry3hd", + "value": "6f9hih2hXXZk", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "6f9hih2hXXZk", + "value": "MI26XDLSAlCD", "isInheritable": false, "position": 30 }, @@ -4263,6 +5702,13 @@ "value": "bx bx-search-alt-2", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "search-in-note", + "isInheritable": false, + "position": 50 } ], "format": "markdown", @@ -4298,7 +5744,7 @@ { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "DvdZhoQZY9Yd", "isInheritable": false, "position": 10 }, @@ -4312,38 +5758,45 @@ { "type": "relation", "name": "internalLink", - "value": "IakOLONlIfGI", + "value": "zEY4DaJG4YT5", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "iPIMuisry3hd", + "value": "TBwsyfadTA18", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "oiVPnW8QfnvS", + "value": "iPIMuisry3hd", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "QrtTYPmdd1qq", + "value": "oiVPnW8QfnvS", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "eIg8jdvaoNNd", + "value": "QrtTYPmdd1qq", "isInheritable": false, "position": 70 }, + { + "type": "relation", + "name": "internalLink", + "value": "eIg8jdvaoNNd", + "isInheritable": false, + "position": 80 + }, { "type": "label", "name": "shareAlias", @@ -4478,6 +5931,113 @@ "format": "markdown", "dataFileName": "Theme Gallery.md", "attachments": [] + }, + { + "isClone": false, + "noteId": "gOKqSJgXLcIj", + "notePath": [ + "pOsGYCXsbNQG", + "gh7bpGYxajRS", + "Wy267RK4M69c", + "gOKqSJgXLcIj" + ], + "title": "Icon Packs", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "s8alTXmpFR61", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "g1mlRoU8CsqC", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "bnyigUA2UK7s", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "HI6GBBIduIgv", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "bwg0e8ewQMak", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "R9pX4DGra2Vt", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "ycBFjKrrwE9p", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "eIg8jdvaoNNd", + "isInheritable": false, + "position": 90 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-package", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "icon-packs", + "isInheritable": false, + "position": 100 + } + ], + "format": "markdown", + "dataFileName": "Icon Packs.md", + "attachments": [ + { + "attachmentId": "CPieIjN3b77m", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Icon Packs_image.png" + } + ] } ] }, @@ -4496,15 +6056,58 @@ "type": "text", "mime": "text/html", "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "hrZ1D00cLbal", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Oau6X9rCuegd", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "rJ9grSgoExl9", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "syuSEKf2rUGr", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GnhlmrATVqcH", + "isInheritable": false, + "position": 50 + }, { "type": "label", "name": "iconClass", "value": "bx bx-import", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "import-export", + "isInheritable": false, + "position": 20 } ], "format": "markdown", + "dataFileName": "Import & Export.md", "attachments": [], "dirFileName": "Import & Export", "children": [ @@ -4607,6 +6210,13 @@ "value": "bx bx-code-alt", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "supported-syntax", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -4632,16 +6242,82 @@ "mime": "text/markdown", "attributes": [ { - "type": "label", - "name": "shareAlias", - "value": "evernote-import", + "type": "relation", + "name": "internalLink", + "value": "Gr6xFaF6ioJ5", "isInheritable": false, "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "WOcw2SLH6tbX", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "wy8So3yZZlH9", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "dj3j8dG4th4l", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "evernote", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-window-open", + "isInheritable": false, + "position": 30 } ], "format": "markdown", "dataFileName": "Evernote.md", - "attachments": [] + "attachments": [], + "dirFileName": "Evernote", + "children": [ + { + "isClone": false, + "noteId": "dj3j8dG4th4l", + "notePath": [ + "pOsGYCXsbNQG", + "gh7bpGYxajRS", + "mHbBMPDPkVV5", + "syuSEKf2rUGr", + "dj3j8dG4th4l" + ], + "title": "Process internal links by title", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "code", + "mime": "application/javascript;env=frontend", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "internal-links.js", + "isInheritable": false, + "position": 30 + } + ], + "dataFileName": "Process internal links by titl.js", + "attachments": [] + } + ] }, { "isClone": false, @@ -4665,6 +6341,13 @@ "value": "onenote", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-window-open", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -4694,6 +6377,13 @@ "value": "bx bxs-yin-yang", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "zen-mode", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -4732,6 +6422,131 @@ "dataFileName": "3_Zen mode_image.png" } ] + }, + { + "isClone": false, + "noteId": "YzMcWlCVeW09", + "notePath": [ + "pOsGYCXsbNQG", + "gh7bpGYxajRS", + "YzMcWlCVeW09" + ], + "title": "Active content", + "notePosition": 110, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "mHbBMPDPkVV5", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "MgibgPcfeuGz", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "HI6GBBIduIgv", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "64ZTlUPgEPtW", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "yIhgI5H7A2Sm", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "RnaPdbciOfeq", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "SPirpZypehBG", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "1vHRoWCEjj0L", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "HcABDtFCkbFN", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "AlhDUqhENtH7", + "isInheritable": false, + "position": 100 + }, + { + "type": "relation", + "name": "internalLink", + "value": "pKK96zzmvBGf", + "isInheritable": false, + "position": 110 + }, + { + "type": "relation", + "name": "internalLink", + "value": "gOKqSJgXLcIj", + "isInheritable": false, + "position": 120 + }, + { + "type": "relation", + "name": "internalLink", + "value": "IjZS7iK5EXtb", + "isInheritable": false, + "position": 130 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-widget", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "active-content", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Active content.md", + "attachments": [] } ] }, @@ -4773,10 +6588,17 @@ { "type": "relation", "name": "internalLink", - "value": "cbkrhQjrkKrh", + "value": "yeEaYqosGLSh", "isInheritable": false, "position": 40 }, + { + "type": "relation", + "name": "internalLink", + "value": "cbkrhQjrkKrh", + "isInheritable": false, + "position": 50 + }, { "type": "label", "name": "shareAlias", @@ -4813,59 +6635,66 @@ { "type": "relation", "name": "internalLink", - "value": "wX4HbRucYSDD", + "value": "wy8So3yZZlH9", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "IakOLONlIfGI", + "value": "CdNpE2pqjmI6", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "wX4HbRucYSDD", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "BCkXAVs63Ttv", + "value": "tAassRL4RSQL", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "wy8So3yZZlH9", + "value": "cbkrhQjrkKrh", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "CdNpE2pqjmI6", + "value": "IakOLONlIfGI", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "tAassRL4RSQL", + "value": "zEY4DaJG4YT5", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "cbkrhQjrkKrh", + "value": "BCkXAVs63Ttv", "isInheritable": false, "position": 80 }, + { + "type": "relation", + "name": "internalLink", + "value": "eIg8jdvaoNNd", + "isInheritable": false, + "position": 90 + }, { "type": "label", "name": "shareAlias", @@ -5031,6 +6860,13 @@ "value": "bx bx-edit", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "note-types", + "isInheritable": false, + "position": 190 } ], "format": "markdown", @@ -5184,35 +7020,42 @@ { "type": "relation", "name": "internalLink", - "value": "CoFPLs3dRlXc", + "value": "5wZallV2Qo1t", "isInheritable": false, "position": 180 }, { "type": "relation", "name": "internalLink", - "value": "A9Oc6YKKc65v", + "value": "CoFPLs3dRlXc", "isInheritable": false, "position": 190 }, { "type": "relation", "name": "internalLink", - "value": "QrtTYPmdd1qq", + "value": "A9Oc6YKKc65v", "isInheritable": false, "position": 200 }, { "type": "relation", "name": "internalLink", - "value": "MI26XDLSAlCD", + "value": "QrtTYPmdd1qq", "isInheritable": false, "position": 210 }, + { + "type": "relation", + "name": "internalLink", + "value": "MI26XDLSAlCD", + "isInheritable": false, + "position": 220 + }, { "type": "label", "name": "shareAlias", - "value": "text-notes", + "value": "text", "isInheritable": false, "position": 10 }, @@ -5287,14 +7130,14 @@ { "type": "relation", "name": "internalLink", - "value": "rJ9grSgoExl9", + "value": "nRhnJkTT8cPs", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "nRhnJkTT8cPs", + "value": "rJ9grSgoExl9", "isInheritable": false, "position": 20 }, @@ -5304,6 +7147,13 @@ "value": "bx bx-info-circle", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "blockquotes", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -5371,6 +7221,13 @@ "value": "bx bx-bookmark", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "bookmarks", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -5416,6 +7273,13 @@ "value": "bx bx-align-right", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "content-language", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -5453,6 +7317,13 @@ "value": "bx bx-cut", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "cut-to-subnote", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -5511,6 +7382,13 @@ "value": "bx bx-code-alt", "isInheritable": false, "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "developer-formatting", + "isInheritable": false, + "position": 50 } ], "format": "markdown", @@ -5602,21 +7480,21 @@ { "type": "relation", "name": "internalLink", - "value": "CoFPLs3dRlXc", + "value": "nRhnJkTT8cPs", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "4TIF1oA4VQRO", + "value": "CoFPLs3dRlXc", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "nRhnJkTT8cPs", + "value": "4TIF1oA4VQRO", "isInheritable": false, "position": 40 }, @@ -5633,6 +7511,13 @@ "value": "bx bx-code", "isInheritable": false, "position": 50 + }, + { + "type": "label", + "name": "shareAlias", + "value": "code-blocks", + "isInheritable": false, + "position": 60 } ], "format": "markdown", @@ -5688,6 +7573,13 @@ "value": "bx bx-bracket", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "footnotes", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -5737,16 +7629,30 @@ { "type": "relation", "name": "internalLink", - "value": "BlN9DFI679QC", + "value": "_optionsTextNotes", "isInheritable": false, "position": 20 }, + { + "type": "relation", + "name": "internalLink", + "value": "BlN9DFI679QC", + "isInheritable": false, + "position": 30 + }, { "type": "label", "name": "iconClass", "value": "bx bx-text", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "formatting-toolbar", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -5812,30 +7718,44 @@ { "type": "relation", "name": "internalLink", - "value": "Wy267RK4M69c", + "value": "YfYAtQBcfo5V", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "Oau6X9rCuegd", + "value": "Wy267RK4M69c", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "YfYAtQBcfo5V", + "value": "5wZallV2Qo1t", "isInheritable": false, "position": 40 }, + { + "type": "relation", + "name": "internalLink", + "value": "Oau6X9rCuegd", + "isInheritable": false, + "position": 50 + }, { "type": "label", "name": "iconClass", "value": "bx bx-bold", "isInheritable": false, "position": 50 + }, + { + "type": "label", + "name": "shareAlias", + "value": "general-formatting", + "isInheritable": false, + "position": 60 } ], "format": "markdown", @@ -5902,37 +7822,51 @@ { "type": "relation", "name": "internalLink", - "value": "RnaPdbciOfeq", + "value": "BFvAtE74rbP6", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "XpOYSgsLkTJy", + "value": "RnaPdbciOfeq", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "XpOYSgsLkTJy", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "BFvAtE74rbP6", + "value": "_optionsTextNotes", "isInheritable": false, "position": 40 }, + { + "type": "relation", + "name": "internalLink", + "value": "zEY4DaJG4YT5", + "isInheritable": false, + "position": 50 + }, { "type": "label", "name": "iconClass", "value": "bx bx-highlight", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "highlights-list", + "isInheritable": false, + "position": 60 } ], "format": "markdown", @@ -6173,6 +8107,13 @@ "value": "bx bxs-file-image", "isInheritable": false, "position": 80 + }, + { + "type": "label", + "name": "shareAlias", + "value": "image-references", + "isInheritable": false, + "position": 90 } ], "format": "markdown", @@ -6220,6 +8161,20 @@ "value": "nRhnJkTT8cPs", "isInheritable": false, "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "R9pX4DGra2Vt", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "include-note", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -6268,28 +8223,28 @@ { "type": "relation", "name": "internalLink", - "value": "s1aBHPd79XYj", + "value": "YfYAtQBcfo5V", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "nBAXQFj20hS1", + "value": "s1aBHPd79XYj", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "NRnIZmSMc5sj", + "value": "nBAXQFj20hS1", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "YfYAtQBcfo5V", + "value": "NRnIZmSMc5sj", "isInheritable": false, "position": 60 }, @@ -6299,6 +8254,13 @@ "value": "bx bx-plus", "isInheritable": false, "position": 60 + }, + { + "type": "label", + "name": "shareAlias", + "value": "insert-buttons", + "isInheritable": false, + "position": 70 } ], "format": "markdown", @@ -6413,28 +8375,28 @@ { "type": "relation", "name": "internalLink", - "value": "UYuUB1ZekNQU", + "value": "QEAPj01N5f7w", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "MI26XDLSAlCD", + "value": "UYuUB1ZekNQU", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "QEAPj01N5f7w", + "value": "YfYAtQBcfo5V", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "YfYAtQBcfo5V", + "value": "MI26XDLSAlCD", "isInheritable": false, "position": 40 }, @@ -6444,6 +8406,13 @@ "value": "bx bxs-keyboard", "isInheritable": false, "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "keyboard-shortcuts", + "isInheritable": false, + "position": 50 } ], "format": "markdown", @@ -6480,19 +8449,12 @@ "isInheritable": false, "position": 20 }, - { - "type": "relation", - "name": "internalLink", - "value": "oPVyFC7WL2Lp", - "isInheritable": false, - "position": 30 - }, { "type": "relation", "name": "internalLink", "value": "BCkXAVs63Ttv", "isInheritable": false, - "position": 40 + "position": 30 }, { "type": "label", @@ -6544,6 +8506,13 @@ "value": "bx bx-link-external", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "external-links", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -6599,12 +8568,26 @@ "isInheritable": false, "position": 10 }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 20 + }, { "type": "label", "name": "iconClass", "value": "bx bx-link", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "reference-links", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -6617,6 +8600,14 @@ "mime": "image/png", "position": 10, "dataFileName": "Internal (reference) links.png" + }, + { + "attachmentId": "VWmqBZtLxTJH", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_Internal (reference) links.png" } ] } @@ -6651,29 +8642,36 @@ "value": "bx bx-list-ul", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "lists", + "isInheritable": false, + "position": 20 } ], "format": "markdown", "dataFileName": "Lists.md", "attachments": [ { - "attachmentId": "5cmICTYfg13g", + "attachmentId": "1d3z8mz0JANE", "title": "image.png", "role": "image", - "mime": "image/jpg", + "mime": "image/png", "position": 10, "dataFileName": "Lists_image.png" }, { - "attachmentId": "6jl7tboJfutt", + "attachmentId": "7YtO7boIQcSu", "title": "image.png", "role": "image", - "mime": "image/jpg", + "mime": "image/png", "position": 10, "dataFileName": "1_Lists_image.png" }, { - "attachmentId": "7Ledf67P1S1b", + "attachmentId": "eCftcYsVKdAI", "title": "image.png", "role": "image", "mime": "image/png", @@ -6681,7 +8679,7 @@ "dataFileName": "2_Lists_image.png" }, { - "attachmentId": "d4XfLoK5srYZ", + "attachmentId": "fB3ZhdfysYC3", "title": "image.png", "role": "image", "mime": "image/jpg", @@ -6689,15 +8687,15 @@ "dataFileName": "3_Lists_image.png" }, { - "attachmentId": "eL11eZMPwpmH", + "attachmentId": "IZewdPx4evIx", "title": "image.png", "role": "image", - "mime": "image/jpg", + "mime": "image/png", "position": 10, "dataFileName": "4_Lists_image.png" }, { - "attachmentId": "EnkTpdeLJ6Ft", + "attachmentId": "JopMc0iA0dqA", "title": "image.png", "role": "image", "mime": "image/jpg", @@ -6705,7 +8703,7 @@ "dataFileName": "5_Lists_image.png" }, { - "attachmentId": "If3k6Tt5cPBt", + "attachmentId": "kZMYrJubac6T", "title": "image.png", "role": "image", "mime": "image/jpg", @@ -6713,7 +8711,7 @@ "dataFileName": "6_Lists_image.png" }, { - "attachmentId": "MxgVFEyXwRxo", + "attachmentId": "PGeVq8YAQBFA", "title": "image.png", "role": "image", "mime": "image/png", @@ -6721,26 +8719,26 @@ "dataFileName": "7_Lists_image.png" }, { - "attachmentId": "Te4LNZWv4ovM", + "attachmentId": "VgoG6BtlLYn7", "title": "image.png", "role": "image", - "mime": "image/png", + "mime": "image/jpg", "position": 10, "dataFileName": "8_Lists_image.png" }, { - "attachmentId": "tqeIwudL5QEY", + "attachmentId": "y0zFP6x0IRRf", "title": "image.png", "role": "image", - "mime": "image/png", + "mime": "image/jpg", "position": 10, "dataFileName": "9_Lists_image.png" }, { - "attachmentId": "zZGT8pbt2myS", + "attachmentId": "z8eVlXe2WKqr", "title": "image.png", "role": "image", - "mime": "image/png", + "mime": "image/jpg", "position": 10, "dataFileName": "10_Lists_image.png" } @@ -6772,49 +8770,49 @@ { "type": "relation", "name": "internalLink", - "value": "Oau6X9rCuegd", + "value": "dEHYtoWWi8ct", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "Gr6xFaF6ioJ5", + "value": "Oau6X9rCuegd", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "S6Xx8QIWTV66", + "value": "Gr6xFaF6ioJ5", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "NwBbFdNZ9h7O", + "value": "S6Xx8QIWTV66", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "QxEyIjRBizuC", + "value": "NwBbFdNZ9h7O", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "CohkqWQC1iBv", + "value": "QxEyIjRBizuC", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "dEHYtoWWi8ct", + "value": "CohkqWQC1iBv", "isInheritable": false, "position": 80 }, @@ -6824,6 +8822,13 @@ "value": "bx bxl-markdown", "isInheritable": false, "position": 70 + }, + { + "type": "label", + "name": "shareAlias", + "value": "markdown-formatting", + "isInheritable": false, + "position": 90 } ], "format": "markdown", @@ -6873,6 +8878,13 @@ "value": "bx bx-math", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "math-equations", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -6946,6 +8958,13 @@ "value": "bx bxs-grid", "isInheritable": false, "position": 50 + }, + { + "type": "label", + "name": "shareAlias", + "value": "other-features", + "isInheritable": false, + "position": 60 } ], "format": "markdown", @@ -7045,6 +9064,13 @@ "value": "bx bx-star", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "premium-features", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -7110,6 +9136,13 @@ "value": "bx bx-menu", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "slash-commands", + "isInheritable": false, + "position": 60 } ], "format": "markdown", @@ -7187,21 +9220,21 @@ { "type": "relation", "name": "internalLink", - "value": "9sRHySam5fXb", + "value": "s8alTXmpFR61", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "s8alTXmpFR61", + "value": "wy8So3yZZlH9", "isInheritable": false, "position": 80 }, { "type": "relation", "name": "internalLink", - "value": "wy8So3yZZlH9", + "value": "9sRHySam5fXb", "isInheritable": false, "position": 90 }, @@ -7211,6 +9244,13 @@ "value": "bx bx-align-left", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "text-snippets", + "isInheritable": false, + "position": 100 } ], "format": "markdown", @@ -7233,6 +9273,81 @@ "dataFileName": "1_Text Snippets_image.png" } ] + }, + { + "isClone": false, + "noteId": "5wZallV2Qo1t", + "notePath": [ + "pOsGYCXsbNQG", + "KSZ04uQ2D1St", + "iPIMuisry3hd", + "gLt3vA97tMcp", + "5wZallV2Qo1t" + ], + "title": "Format Painter", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "gLt3vA97tMcp", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "MI26XDLSAlCD", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "format-painter", + "isInheritable": false, + "position": 50 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-paint-roll", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "Format Painter.md", + "attachments": [ + { + "attachmentId": "OY9JmG8zdGm5", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Format Painter_image.png" + }, + { + "attachmentId": "qEJy5SJMsPUh", + "title": "e144e96df9.svg", + "role": "image", + "mime": "image/svg+xml", + "position": 10, + "dataFileName": "Format Painter_e144e96df9.svg" + }, + { + "attachmentId": "vZqf8QJ80XRF", + "title": "746436a2e1.svg", + "role": "image", + "mime": "image/svg+xml", + "position": 10, + "dataFileName": "Format Painter_746436a2e1.svg" + } + ] } ] }, @@ -7269,16 +9384,30 @@ { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "_optionsTextNotes", "isInheritable": false, "position": 30 }, + { + "type": "relation", + "name": "internalLink", + "value": "zEY4DaJG4YT5", + "isInheritable": false, + "position": 40 + }, { "type": "label", "name": "iconClass", "value": "bx bx-heading", "isInheritable": false, "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "table-of-contents", + "isInheritable": false, + "position": 50 } ], "format": "markdown", @@ -7330,6 +9459,13 @@ "value": "bx bx-table", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "tables", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -7408,7 +9544,7 @@ "dataFileName": "8_Tables_image.png" }, { - "attachmentId": "UdhsypjV4pzZ", + "attachmentId": "rrLM5BQCZ5ci", "title": "image.png", "role": "image", "mime": "image/png", @@ -7416,7 +9552,7 @@ "dataFileName": "9_Tables_image.png" }, { - "attachmentId": "VerzwlO9y6Na", + "attachmentId": "UdhsypjV4pzZ", "title": "image.png", "role": "image", "mime": "image/png", @@ -7424,7 +9560,7 @@ "dataFileName": "10_Tables_image.png" }, { - "attachmentId": "wYkQvargZlNF", + "attachmentId": "VerzwlO9y6Na", "title": "image.png", "role": "image", "mime": "image/png", @@ -7432,12 +9568,28 @@ "dataFileName": "11_Tables_image.png" }, { - "attachmentId": "YFGeAN41kvZY", + "attachmentId": "wYkQvargZlNF", "title": "image.png", "role": "image", "mime": "image/png", "position": 10, "dataFileName": "12_Tables_image.png" + }, + { + "attachmentId": "YFGeAN41kvZY", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "13_Tables_image.png" + }, + { + "attachmentId": "zRLxHrKJiK8N", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "14_Tables_image.png" } ] } @@ -7461,35 +9613,35 @@ { "type": "relation", "name": "internalLink", - "value": "BlN9DFI679QC", + "value": "CdNpE2pqjmI6", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "4TIF1oA4VQRO", + "value": "iPIMuisry3hd", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "CdNpE2pqjmI6", + "value": "QxEyIjRBizuC", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "iPIMuisry3hd", + "value": "BlN9DFI679QC", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "QxEyIjRBizuC", + "value": "4TIF1oA4VQRO", "isInheritable": false, "position": 50 }, @@ -7503,7 +9655,7 @@ { "type": "label", "name": "shareAlias", - "value": "code-notes", + "value": "code", "isInheritable": false, "position": 20 }, @@ -7604,38 +9756,52 @@ { "type": "relation", "name": "internalLink", - "value": "BFs8mudNFgCS", + "value": "zEY4DaJG4YT5", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "XpOYSgsLkTJy", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "OFXdgB2nNk1F", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "wX4HbRucYSDD", + "value": "yTjUdsOi4CIE", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "BCkXAVs63Ttv", + "value": "OFXdgB2nNk1F", "isInheritable": false, "position": 50 }, + { + "type": "relation", + "name": "internalLink", + "value": "wX4HbRucYSDD", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "bdUJEHsAPYQR", + "isInheritable": false, + "position": 70 + }, { "type": "label", "name": "shareAlias", @@ -7716,6 +9882,13 @@ "value": "bx bxs-network-chart", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "note-map", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -7749,51 +9922,79 @@ { "type": "relation", "name": "internalLink", - "value": "6f9hih2hXXZk", + "value": "yIhgI5H7A2Sm", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "HcABDtFCkbFN", + "value": "6f9hih2hXXZk", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "HcABDtFCkbFN", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "R7abl2fc6Mxi", + "value": "zEY4DaJG4YT5", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "6tZeKvSHEUiB", + "value": "CdNpE2pqjmI6", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "CdNpE2pqjmI6", + "value": "XpOYSgsLkTJy", "isInheritable": false, "position": 60 }, + { + "type": "relation", + "name": "internalLink", + "value": "A9Oc6YKKc65v", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "R7abl2fc6Mxi", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6tZeKvSHEUiB", + "isInheritable": false, + "position": 90 + }, { "type": "label", "name": "iconClass", "value": "bx bx-extension", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "render-note", + "isInheritable": false, + "position": 70 } ], "format": "markdown", @@ -7809,764 +10010,6 @@ } ] }, - { - "isClone": false, - "noteId": "GTwFsgaA0lCt", - "notePath": [ - "pOsGYCXsbNQG", - "KSZ04uQ2D1St", - "GTwFsgaA0lCt" - ], - "title": "Collections", - "notePosition": 130, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/markdown", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "8QqnMzx393bx", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "0ESUbbAxVnoK", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "mULW0Q3VojwY", - "isInheritable": false, - "position": 30 - }, - { - "type": "relation", - "name": "internalLink", - "value": "xWbu3jpNWapp", - "isInheritable": false, - "position": 40 - }, - { - "type": "relation", - "name": "internalLink", - "value": "81SGnPGMk7Xc", - "isInheritable": false, - "position": 50 - }, - { - "type": "relation", - "name": "internalLink", - "value": "2FvYrpmOXm29", - "isInheritable": false, - "position": 60 - }, - { - "type": "relation", - "name": "internalLink", - "value": "OFXdgB2nNk1F", - "isInheritable": false, - "position": 70 - }, - { - "type": "relation", - "name": "internalLink", - "value": "CtBQqbwXDx1w", - "isInheritable": false, - "position": 80 - }, - { - "type": "relation", - "name": "internalLink", - "value": "BlN9DFI679QC", - "isInheritable": false, - "position": 90 - }, - { - "type": "relation", - "name": "internalLink", - "value": "oPVyFC7WL2Lp", - "isInheritable": false, - "position": 100 - }, - { - "type": "relation", - "name": "internalLink", - "value": "m523cpzocqaD", - "isInheritable": false, - "position": 110 - }, - { - "type": "relation", - "name": "internalLink", - "value": "KC1HB96bqqHX", - "isInheritable": false, - "position": 120 - }, - { - "type": "relation", - "name": "internalLink", - "value": "2mUhVmZK8RF3", - "isInheritable": false, - "position": 130 - }, - { - "type": "label", - "name": "shareAlias", - "value": "book-note", - "isInheritable": false, - "position": 10 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-book", - "isInheritable": false, - "position": 20 - } - ], - "format": "markdown", - "dataFileName": "Collections.md", - "attachments": [], - "dirFileName": "Collections", - "children": [ - { - "isClone": false, - "noteId": "xWbu3jpNWapp", - "notePath": [ - "pOsGYCXsbNQG", - "KSZ04uQ2D1St", - "GTwFsgaA0lCt", - "xWbu3jpNWapp" - ], - "title": "Calendar View", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "ZjLYv08Rp3qC", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "BlN9DFI679QC", - "isInheritable": false, - "position": 20 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-calendar", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Calendar View.md", - "attachments": [ - { - "attachmentId": "37CfbqKYcOtd", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Calendar View_image.png" - }, - { - "attachmentId": "akAHcIEcGnWR", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Calendar View_image.png" - }, - { - "attachmentId": "AU7dnIevWPrz", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "2_Calendar View_image.png" - }, - { - "attachmentId": "COiR1tnE86i1", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "3_Calendar View_image.png" - }, - { - "attachmentId": "fOdCNTs2BuI0", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "4_Calendar View_image.png" - }, - { - "attachmentId": "HfBu0m3WXtn2", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "5_Calendar View_image.png" - }, - { - "attachmentId": "ho00OJTNrxVI", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "6_Calendar View_image.png" - }, - { - "attachmentId": "irfNX8n4159U", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "7_Calendar View_image.png" - }, - { - "attachmentId": "KF56rdNuOwWd", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "8_Calendar View_image.png" - }, - { - "attachmentId": "oBWr5GL6cUAZ", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "9_Calendar View_image.png" - }, - { - "attachmentId": "oS6yUoQtfhpg", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "10_Calendar View_image.png" - }, - { - "attachmentId": "u2c09UpZghff", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "11_Calendar View_image.png" - } - ] - }, - { - "isClone": false, - "noteId": "81SGnPGMk7Xc", - "notePath": [ - "pOsGYCXsbNQG", - "KSZ04uQ2D1St", - "GTwFsgaA0lCt", - "81SGnPGMk7Xc" - ], - "title": "Geo Map View", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "KSZ04uQ2D1St", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "0ESUbbAxVnoK", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "XpOYSgsLkTJy", - "isInheritable": false, - "position": 30 - }, - { - "type": "relation", - "name": "internalLink", - "value": "oPVyFC7WL2Lp", - "isInheritable": false, - "position": 40 - }, - { - "type": "relation", - "name": "internalLink", - "value": "IakOLONlIfGI", - "isInheritable": false, - "position": 50 - }, - { - "type": "relation", - "name": "internalLink", - "value": "lgKX7r3aL30x", - "isInheritable": false, - "position": 60 - }, - { - "type": "relation", - "name": "internalLink", - "value": "ZjLYv08Rp3qC", - "isInheritable": false, - "position": 70 - }, - { - "type": "relation", - "name": "internalLink", - "value": "BlN9DFI679QC", - "isInheritable": false, - "position": 80 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-map-alt", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Geo Map View.md", - "attachments": [ - { - "attachmentId": "1f07O0Z25ZRr", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Geo Map View_image.png" - }, - { - "attachmentId": "3oh61qhNLu7D", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Geo Map View_image.png" - }, - { - "attachmentId": "aCSNn9QlgHFi", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "2_Geo Map View_image.png" - }, - { - "attachmentId": "aCuXZY7WV4li", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "3_Geo Map View_image.png" - }, - { - "attachmentId": "agH6yREFgsoU", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "4_Geo Map View_image.png" - }, - { - "attachmentId": "AHyDUM6R5HeG", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "5_Geo Map View_image.png" - }, - { - "attachmentId": "CcjWLhE3KKfv", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "6_Geo Map View_image.png" - }, - { - "attachmentId": "fQy8R1vxKhwN", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "7_Geo Map View_image.png" - }, - { - "attachmentId": "gJ4Yz80jxcbn", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "8_Geo Map View_image.png" - }, - { - "attachmentId": "I39BinT2gsN9", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "9_Geo Map View_image.png" - }, - { - "attachmentId": "IeXU8SLZU7Oz", - "title": "image.jpg", - "role": "image", - "mime": "image/jpg", - "position": 10, - "dataFileName": "Geo Map View_image.jpg" - }, - { - "attachmentId": "Mb9kRm63MxjE", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "10_Geo Map View_image.png" - }, - { - "attachmentId": "Mx2xwNIk76ZS", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "11_Geo Map View_image.png" - }, - { - "attachmentId": "oaahbsMRbqd2", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "12_Geo Map View_image.png" - }, - { - "attachmentId": "pGf1p74KKGU4", - "title": "image.png", - "role": "image", - "mime": "image/jpg", - "position": 10, - "dataFileName": "13_Geo Map View_image.png" - }, - { - "attachmentId": "tfa1TRUatWEh", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "14_Geo Map View_image.png" - }, - { - "attachmentId": "tuNZ7Uk9WfX1", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "15_Geo Map View_image.png" - }, - { - "attachmentId": "x6yBLIsY2LSv", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "16_Geo Map View_image.png" - }, - { - "attachmentId": "yJMyBRYA3Kwi", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "17_Geo Map View_image.png" - }, - { - "attachmentId": "ZvTlu9WMd37z", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "18_Geo Map View_image.png" - } - ] - }, - { - "isClone": false, - "noteId": "8QqnMzx393bx", - "notePath": [ - "pOsGYCXsbNQG", - "KSZ04uQ2D1St", - "GTwFsgaA0lCt", - "8QqnMzx393bx" - ], - "title": "Grid View", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "6f9hih2hXXZk", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "0ESUbbAxVnoK", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "iPIMuisry3hd", - "isInheritable": false, - "position": 30 - }, - { - "type": "relation", - "name": "internalLink", - "value": "W8vYD3Q1zjCR", - "isInheritable": false, - "position": 40 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bxs-grid", - "isInheritable": false, - "position": 20 - } - ], - "format": "markdown", - "dataFileName": "Grid View.md", - "attachments": [ - { - "attachmentId": "al3KatZRq5TB", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Grid View_image.png" - } - ] - }, - { - "isClone": false, - "noteId": "mULW0Q3VojwY", - "notePath": [ - "pOsGYCXsbNQG", - "KSZ04uQ2D1St", - "GTwFsgaA0lCt", - "mULW0Q3VojwY" - ], - "title": "List View", - "notePosition": 40, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "8QqnMzx393bx", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "BlN9DFI679QC", - "isInheritable": false, - "position": 20 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-list-ul", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "List View.md", - "attachments": [ - { - "attachmentId": "igeOEpKp4ygW", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "List View_image.png" - } - ] - }, - { - "isClone": false, - "noteId": "2FvYrpmOXm29", - "notePath": [ - "pOsGYCXsbNQG", - "KSZ04uQ2D1St", - "GTwFsgaA0lCt", - "2FvYrpmOXm29" - ], - "title": "Table View", - "notePosition": 50, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "OFXdgB2nNk1F", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "m1lbrzyKDaRB", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "oPVyFC7WL2Lp", - "isInheritable": false, - "position": 30 - }, - { - "type": "relation", - "name": "internalLink", - "value": "BlN9DFI679QC", - "isInheritable": false, - "position": 40 - }, - { - "type": "relation", - "name": "internalLink", - "value": "eIg8jdvaoNNd", - "isInheritable": false, - "position": 50 - }, - { - "type": "relation", - "name": "internalLink", - "value": "CdNpE2pqjmI6", - "isInheritable": false, - "position": 60 - }, - { - "type": "relation", - "name": "internalLink", - "value": "m523cpzocqaD", - "isInheritable": false, - "position": 70 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-table", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Table View.md", - "attachments": [ - { - "attachmentId": "vJYUG9fLQ2Pd", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Table View_image.png" - } - ] - }, - { - "isClone": false, - "noteId": "CtBQqbwXDx1w", - "notePath": [ - "pOsGYCXsbNQG", - "KSZ04uQ2D1St", - "GTwFsgaA0lCt", - "CtBQqbwXDx1w" - ], - "title": "Board View", - "notePosition": 60, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "2FvYrpmOXm29", - "isInheritable": false, - "position": 10 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-columns", - "isInheritable": false, - "position": 10 - } - ], - "format": "markdown", - "dataFileName": "Board View.md", - "attachments": [ - { - "attachmentId": "usSSa0WI6dDK", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Board View_image.png" - } - ] - } - ] - }, { "isClone": false, "noteId": "s1aBHPd79XYj", @@ -8585,17 +10028,24 @@ { "type": "relation", "name": "internalLink", - "value": "XpOYSgsLkTJy", + "value": "WWgeUaBb7UfC", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "0Ofbk1aSuVRu", + "value": "XpOYSgsLkTJy", "isInheritable": false, "position": 20 }, + { + "type": "relation", + "name": "internalLink", + "value": "0Ofbk1aSuVRu", + "isInheritable": false, + "position": 30 + }, { "type": "label", "name": "shareAlias", @@ -8663,6 +10113,13 @@ "value": "bx bxs-network-chart", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "elk", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -8685,6 +10142,40 @@ "dataFileName": "ELK layout_ELK on.svg" } ] + }, + { + "isClone": false, + "noteId": "WWgeUaBb7UfC", + "notePath": [ + "pOsGYCXsbNQG", + "KSZ04uQ2D1St", + "s1aBHPd79XYj", + "WWgeUaBb7UfC" + ], + "title": "Syntax reference", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "webView", + "mime": "", + "attributes": [ + { + "type": "label", + "name": "webViewSrc", + "value": "https://mermaid.js.org/intro/syntax-reference.html", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "syntax-reference", + "isInheritable": false, + "position": 30 + } + ], + "dataFileName": "Syntax reference.dat", + "attachments": [] } ] }, @@ -8703,12 +10194,33 @@ "type": "text", "mime": "text/html", "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "CoFPLs3dRlXc", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "XpOYSgsLkTJy", + "isInheritable": false, + "position": 20 + }, { "type": "label", "name": "iconClass", "value": "bx bx-pen", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "canvas", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -8752,6 +10264,13 @@ "value": "bx bx-globe-alt", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "webview", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -8787,12 +10306,26 @@ "isInheritable": false, "position": 20 }, + { + "type": "relation", + "name": "internalLink", + "value": "CoFPLs3dRlXc", + "isInheritable": false, + "position": 30 + }, { "type": "label", "name": "iconClass", "value": "bx bx-sitemap", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "mindmap", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -8833,86 +10366,107 @@ { "type": "relation", "name": "internalLink", - "value": "wX4HbRucYSDD", + "value": "XJGJrpu7F9sh", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "ODY7qQn5m2FT", + "value": "iPIMuisry3hd", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "mHbBMPDPkVV5", + "value": "0Ofbk1aSuVRu", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "6f9hih2hXXZk", + "value": "XpOYSgsLkTJy", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "BlN9DFI679QC", + "value": "AjqEeiDUOzj4", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "0vhv7lsOLy82", + "value": "mHbBMPDPkVV5", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "8YBEPzcpUgxw", + "value": "6f9hih2hXXZk", "isInheritable": false, "position": 80 }, { "type": "relation", "name": "internalLink", - "value": "0ESUbbAxVnoK", + "value": "BlN9DFI679QC", "isInheritable": false, "position": 90 }, { "type": "relation", "name": "internalLink", - "value": "iPIMuisry3hd", + "value": "0vhv7lsOLy82", "isInheritable": false, "position": 100 }, { "type": "relation", "name": "internalLink", - "value": "0Ofbk1aSuVRu", + "value": "8YBEPzcpUgxw", "isInheritable": false, "position": 110 }, { "type": "relation", "name": "internalLink", - "value": "nBAXQFj20hS1", + "value": "0ESUbbAxVnoK", "isInheritable": false, "position": 120 + }, + { + "type": "relation", + "name": "internalLink", + "value": "nBAXQFj20hS1", + "isInheritable": false, + "position": 130 + }, + { + "type": "label", + "name": "shareAlias", + "value": "file", + "isInheritable": false, + "position": 130 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-file-blank", + "isInheritable": false, + "position": 140 } ], "format": "markdown", "dataFileName": "File.md", "attachments": [ { - "attachmentId": "82as0jgkDvVH", + "attachmentId": "fZ7VMfQJWuLQ", "title": "image.png", "role": "image", "mime": "image/png", @@ -8920,7 +10474,7 @@ "dataFileName": "File_image.png" }, { - "attachmentId": "FoEnowwOhzLT", + "attachmentId": "hddkgf7kr9g4", "title": "image.png", "role": "image", "mime": "image/png", @@ -8928,7 +10482,7 @@ "dataFileName": "1_File_image.png" }, { - "attachmentId": "fZ7VMfQJWuLQ", + "attachmentId": "hIg9g5pgsjS3", "title": "image.png", "role": "image", "mime": "image/png", @@ -8936,36 +10490,1340 @@ "dataFileName": "2_File_image.png" }, { - "attachmentId": "hddkgf7kr9g4", + "attachmentId": "IC0j8LFCOKka", "title": "image.png", "role": "image", "mime": "image/png", "position": 10, "dataFileName": "3_File_image.png" }, - { - "attachmentId": "hIg9g5pgsjS3", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "4_File_image.png" - }, - { - "attachmentId": "IC0j8LFCOKka", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "5_File_image.png" - }, { "attachmentId": "wNHX24feZRAl", "title": "image.png", "role": "image", "mime": "image/png", "position": 10, - "dataFileName": "6_File_image.png" + "dataFileName": "4_File_image.png" + } + ], + "dirFileName": "File", + "children": [ + { + "isClone": false, + "noteId": "XJGJrpu7F9sh", + "notePath": [ + "pOsGYCXsbNQG", + "KSZ04uQ2D1St", + "W8vYD3Q1zjCR", + "XJGJrpu7F9sh" + ], + "title": "PDFs", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "0vhv7lsOLy82", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "wy8So3yZZlH9", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "IjZS7iK5EXtb", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "RnaPdbciOfeq", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "R9pX4DGra2Vt", + "isInheritable": false, + "position": 50 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-file-pdf", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "pdf", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "PDFs.md", + "attachments": [ + { + "attachmentId": "6IIyelZjiGqC", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "PDFs_image.png" + }, + { + "attachmentId": "LT2iTknjYoZi", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_PDFs_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "AjqEeiDUOzj4", + "notePath": [ + "pOsGYCXsbNQG", + "KSZ04uQ2D1St", + "W8vYD3Q1zjCR", + "AjqEeiDUOzj4" + ], + "title": "Videos", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "wX4HbRucYSDD", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "ODY7qQn5m2FT", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-video", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "Videos.md", + "attachments": [ + { + "attachmentId": "649jtu5ELGa8", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Videos_image.png" + } + ] + } + ] + }, + { + "isClone": false, + "noteId": "GWHEkY4I4OE3", + "notePath": [ + "pOsGYCXsbNQG", + "KSZ04uQ2D1St", + "GWHEkY4I4OE3" + ], + "title": "Spreadsheets", + "notePosition": 220, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "2FvYrpmOXm29", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "iPIMuisry3hd", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "wy8So3yZZlH9", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Spreadsheets.md", + "attachments": [ + { + "attachmentId": "Eedn7QHJQbiV", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Spreadsheets_image.png" + } + ] + } + ] + }, + { + "isClone": false, + "noteId": "GTwFsgaA0lCt", + "notePath": [ + "pOsGYCXsbNQG", + "GTwFsgaA0lCt" + ], + "title": "Collections", + "notePosition": 250, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/markdown", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "xWbu3jpNWapp", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "2FvYrpmOXm29", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "OFXdgB2nNk1F", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CtBQqbwXDx1w", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "81SGnPGMk7Xc", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "zP3PMqaG71Ct", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "8QqnMzx393bx", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "0ESUbbAxVnoK", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "mULW0Q3VojwY", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 100 + }, + { + "type": "relation", + "name": "internalLink", + "value": "KSZ04uQ2D1St", + "isInheritable": false, + "position": 110 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CssoWBu8I7jF", + "isInheritable": false, + "position": 120 + }, + { + "type": "relation", + "name": "internalLink", + "value": "MKmLg5x6xkor", + "isInheritable": false, + "position": 130 + }, + { + "type": "relation", + "name": "internalLink", + "value": "eIg8jdvaoNNd", + "isInheritable": false, + "position": 140 + }, + { + "type": "relation", + "name": "internalLink", + "value": "BlN9DFI679QC", + "isInheritable": false, + "position": 150 + }, + { + "type": "relation", + "name": "internalLink", + "value": "m523cpzocqaD", + "isInheritable": false, + "position": 160 + }, + { + "type": "relation", + "name": "internalLink", + "value": "KC1HB96bqqHX", + "isInheritable": false, + "position": 170 + }, + { + "type": "relation", + "name": "internalLink", + "value": "2mUhVmZK8RF3", + "isInheritable": false, + "position": 180 + }, + { + "type": "label", + "name": "shareAlias", + "value": "collections", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-book", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Collections.md", + "attachments": [ + { + "attachmentId": "5NH7myDKSICZ", + "title": "collection_geomap.webp", + "role": "image", + "mime": "image/webp", + "position": 10, + "dataFileName": "Collections_collection_ge.webp" + }, + { + "attachmentId": "7gL9zNsbyY4Z", + "title": "collection_presentation.webp", + "role": "image", + "mime": "image/webp", + "position": 10, + "dataFileName": "Collections_collection_pr.webp" + }, + { + "attachmentId": "BA2BoJ7NuNrx", + "title": "collection_table.webp", + "role": "image", + "mime": "image/webp", + "position": 10, + "dataFileName": "Collections_collection_ta.webp" + }, + { + "attachmentId": "tgdna1b1s44A", + "title": "collection_calendar.webp", + "role": "image", + "mime": "image/webp", + "position": 10, + "dataFileName": "Collections_collection_ca.webp" + }, + { + "attachmentId": "vozq8xSO2HO7", + "title": "collection_board.webp", + "role": "image", + "mime": "image/webp", + "position": 10, + "dataFileName": "Collections_collection_bo.webp" + } + ], + "dirFileName": "Collections", + "children": [ + { + "isClone": false, + "noteId": "xWbu3jpNWapp", + "notePath": [ + "pOsGYCXsbNQG", + "GTwFsgaA0lCt", + "xWbu3jpNWapp" + ], + "title": "Calendar", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "ZjLYv08Rp3qC", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "BlN9DFI679QC", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-calendar", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "calendar", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Calendar.md", + "attachments": [ + { + "attachmentId": "37CfbqKYcOtd", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Calendar_image.png" + }, + { + "attachmentId": "akAHcIEcGnWR", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_Calendar_image.png" + }, + { + "attachmentId": "fOdCNTs2BuI0", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "2_Calendar_image.png" + }, + { + "attachmentId": "HfBu0m3WXtn2", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "3_Calendar_image.png" + }, + { + "attachmentId": "ho00OJTNrxVI", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "4_Calendar_image.png" + }, + { + "attachmentId": "irfNX8n4159U", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "5_Calendar_image.png" + }, + { + "attachmentId": "KF56rdNuOwWd", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "6_Calendar_image.png" + }, + { + "attachmentId": "oBWr5GL6cUAZ", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "7_Calendar_image.png" + }, + { + "attachmentId": "oS6yUoQtfhpg", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "8_Calendar_image.png" + }, + { + "attachmentId": "u2c09UpZghff", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "9_Calendar_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "2FvYrpmOXm29", + "notePath": [ + "pOsGYCXsbNQG", + "GTwFsgaA0lCt", + "2FvYrpmOXm29" + ], + "title": "Table", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "OFXdgB2nNk1F", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "m1lbrzyKDaRB", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CdNpE2pqjmI6", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CssoWBu8I7jF", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "m523cpzocqaD", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "eIg8jdvaoNNd", + "isInheritable": false, + "position": 70 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-table", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "table", + "isInheritable": false, + "position": 80 + } + ], + "format": "markdown", + "dataFileName": "Table.md", + "attachments": [ + { + "attachmentId": "vJYUG9fLQ2Pd", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Table_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "CtBQqbwXDx1w", + "notePath": [ + "pOsGYCXsbNQG", + "GTwFsgaA0lCt", + "CtBQqbwXDx1w" + ], + "title": "Kanban Board", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "2FvYrpmOXm29", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "IakOLONlIfGI", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "OFXdgB2nNk1F", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Cq5X6iKQop6R", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "bdUJEHsAPYQR", + "isInheritable": false, + "position": 60 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-columns", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "kanban-board", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Kanban Board.md", + "attachments": [ + { + "attachmentId": "3ze7RpkjIWdW", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Kanban Board_image.png" + }, + { + "attachmentId": "IrIeh59VGjHq", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_Kanban Board_image.png" + }, + { + "attachmentId": "usSSa0WI6dDK", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "2_Kanban Board_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "81SGnPGMk7Xc", + "notePath": [ + "pOsGYCXsbNQG", + "GTwFsgaA0lCt", + "81SGnPGMk7Xc" + ], + "title": "Geo Map", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "KSZ04uQ2D1St", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "0ESUbbAxVnoK", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "XpOYSgsLkTJy", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "IakOLONlIfGI", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "lgKX7r3aL30x", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "ZjLYv08Rp3qC", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CssoWBu8I7jF", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "HI6GBBIduIgv", + "isInheritable": false, + "position": 90 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-map-alt", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "geomap", + "isInheritable": false, + "position": 90 + } + ], + "format": "markdown", + "dataFileName": "Geo Map.md", + "attachments": [ + { + "attachmentId": "1f07O0Z25ZRr", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Geo Map_image.png" + }, + { + "attachmentId": "3oh61qhNLu7D", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_Geo Map_image.png" + }, + { + "attachmentId": "aCSNn9QlgHFi", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "2_Geo Map_image.png" + }, + { + "attachmentId": "aCuXZY7WV4li", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "3_Geo Map_image.png" + }, + { + "attachmentId": "agH6yREFgsoU", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "4_Geo Map_image.png" + }, + { + "attachmentId": "AHyDUM6R5HeG", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "5_Geo Map_image.png" + }, + { + "attachmentId": "CcjWLhE3KKfv", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "6_Geo Map_image.png" + }, + { + "attachmentId": "fQy8R1vxKhwN", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "7_Geo Map_image.png" + }, + { + "attachmentId": "I39BinT2gsN9", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "8_Geo Map_image.png" + }, + { + "attachmentId": "IeXU8SLZU7Oz", + "title": "image.jpg", + "role": "image", + "mime": "image/jpg", + "position": 10, + "dataFileName": "Geo Map_image.jpg" + }, + { + "attachmentId": "Mb9kRm63MxjE", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "9_Geo Map_image.png" + }, + { + "attachmentId": "Mx2xwNIk76ZS", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "10_Geo Map_image.png" + }, + { + "attachmentId": "oaahbsMRbqd2", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "11_Geo Map_image.png" + }, + { + "attachmentId": "pGf1p74KKGU4", + "title": "image.png", + "role": "image", + "mime": "image/jpg", + "position": 10, + "dataFileName": "12_Geo Map_image.png" + }, + { + "attachmentId": "tfa1TRUatWEh", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "13_Geo Map_image.png" + }, + { + "attachmentId": "x6yBLIsY2LSv", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "14_Geo Map_image.png" + }, + { + "attachmentId": "yJMyBRYA3Kwi", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "15_Geo Map_image.png" + }, + { + "attachmentId": "ZvTlu9WMd37z", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "16_Geo Map_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "zP3PMqaG71Ct", + "notePath": [ + "pOsGYCXsbNQG", + "GTwFsgaA0lCt", + "zP3PMqaG71Ct" + ], + "title": "Presentation", + "notePosition": 90, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CssoWBu8I7jF", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "AlhDUqhENtH7", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "OFXdgB2nNk1F", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "R9pX4DGra2Vt", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "0ESUbbAxVnoK", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "s1aBHPd79XYj", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "grjYqerjn243", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "gBbsAeiuUxI5", + "isInheritable": false, + "position": 90 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-slideshow", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "presentation", + "isInheritable": false, + "position": 90 + } + ], + "format": "markdown", + "dataFileName": "Presentation.md", + "attachments": [ + { + "attachmentId": "aJa7vIrYknDw", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Presentation_image.png" + }, + { + "attachmentId": "aPooMxP74PeA", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_Presentation_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "8QqnMzx393bx", + "notePath": [ + "pOsGYCXsbNQG", + "GTwFsgaA0lCt", + "8QqnMzx393bx" + ], + "title": "Grid View", + "notePosition": 100, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "iPIMuisry3hd", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "W8vYD3Q1zjCR", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "0ESUbbAxVnoK", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 50 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-grid", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "grid", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "Grid View.md", + "attachments": [ + { + "attachmentId": "al3KatZRq5TB", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Grid View_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "mULW0Q3VojwY", + "notePath": [ + "pOsGYCXsbNQG", + "GTwFsgaA0lCt", + "mULW0Q3VojwY" + ], + "title": "List View", + "notePosition": 110, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "8QqnMzx393bx", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "BlN9DFI679QC", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "NRnIZmSMc5sj", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CssoWBu8I7jF", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "HI6GBBIduIgv", + "isInheritable": false, + "position": 60 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-list-ul", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "list", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "List View.md", + "attachments": [ + { + "attachmentId": "igeOEpKp4ygW", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "List View_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "CssoWBu8I7jF", + "notePath": [ + "pOsGYCXsbNQG", + "GTwFsgaA0lCt", + "CssoWBu8I7jF" + ], + "title": "Collection Properties", + "notePosition": 120, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "GTwFsgaA0lCt", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "IjZS7iK5EXtb", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "BlN9DFI679QC", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "wyaGBBQrl4i3", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "MKmLg5x6xkor", + "isInheritable": false, + "position": 50 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-cog", + "isInheritable": false, + "position": 80 + } + ], + "format": "markdown", + "dataFileName": "Collection Properties.md", + "attachments": [ + { + "attachmentId": "xsJTD19tJm3X", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Collection Properties_imag.png" } ] } @@ -8979,7 +11837,7 @@ "BgmBlOIl72jZ" ], "title": "Troubleshooting", - "notePosition": 250, + "notePosition": 260, "prefix": null, "isExpanded": false, "type": "text", @@ -9061,7 +11919,22 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "reporting-issues", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-bug-alt", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", "dataFileName": "Reporting issues.md", "attachments": [] @@ -9101,6 +11974,13 @@ "value": "anonymized-database", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-low-vision", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -9134,44 +12014,42 @@ { "type": "relation", "name": "internalLink", - "value": "tAassRL4RSQL", + "value": "bnyigUA2UK7s", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "x59R8J8KV5Bp", + "value": "9yEHzMyFirZR", "isInheritable": false, "position": 20 }, + { + "type": "relation", + "name": "internalLink", + "value": "x59R8J8KV5Bp", + "isInheritable": false, + "position": 30 + }, { "type": "label", "name": "shareAlias", "value": "error-logs", "isInheritable": false, "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-comment-error", + "isInheritable": false, + "position": 60 } ], "format": "markdown", "dataFileName": "Error logs.md", "attachments": [ - { - "attachmentId": "8b6d0LUU1aMl", - "title": "image.png", - "role": "image", - "mime": "image/jpg", - "position": 10, - "dataFileName": "Error logs_image.png" - }, - { - "attachmentId": "krunYsa4JeyV", - "title": "error-logs-firefox-context-men.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Error logs_error-logs-fire.png" - }, { "attachmentId": "ReQzLPod6UtU", "title": "error-logs-export-subtree.png", @@ -9180,6 +12058,117 @@ "position": 10, "dataFileName": "Error logs_error-logs-expo.png" } + ], + "dirFileName": "Error logs", + "children": [ + { + "isClone": false, + "noteId": "bnyigUA2UK7s", + "notePath": [ + "pOsGYCXsbNQG", + "BgmBlOIl72jZ", + "qzNzp9LYQyPT", + "bnyigUA2UK7s" + ], + "title": "Backend (server) logs", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "x3i7MxGccDuM", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "tAassRL4RSQL", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Gzjqa934BdH4", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-server", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "backend-logs", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "Backend (server) logs.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "9yEHzMyFirZR", + "notePath": [ + "pOsGYCXsbNQG", + "BgmBlOIl72jZ", + "qzNzp9LYQyPT", + "9yEHzMyFirZR" + ], + "title": "Frontend logs", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-window-alt", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "frontend-logs", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Frontend logs.md", + "attachments": [ + { + "attachmentId": "vRup2YTDpWPM", + "title": "image.png", + "role": "image", + "mime": "image/jpg", + "position": 10, + "dataFileName": "Frontend logs_image.png" + }, + { + "attachmentId": "Y05WqmS4uMMt", + "title": "error-logs-firefox-context-men.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Frontend logs_error-logs-f.png" + } + ] + } ] }, { @@ -9203,6 +12192,20 @@ "value": "ud6MShXL4WpO", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "sync-timeout", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-error", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -9223,7 +12226,22 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "refreshing-app", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-refresh", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", "dataFileName": "Refreshing the application.md", "attachments": [] @@ -9238,7 +12256,7 @@ "pKK96zzmvBGf" ], "title": "Theme development", - "notePosition": 260, + "notePosition": 270, "prefix": null, "isExpanded": false, "type": "text", @@ -9250,6 +12268,13 @@ "value": "bx bx-palette", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "theme-development", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -9277,6 +12302,20 @@ "value": "WFGzWeUK6arS", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "creating-custom-theme", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-color", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -9346,7 +12385,22 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "customize-next-theme", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-news", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", "dataFileName": "Customize the Next theme.md", "attachments": [ @@ -9381,6 +12435,20 @@ "value": "d3fAXQ2diepH", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "reference", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-book-open", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -9401,7 +12469,50 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "NRnIZmSMc5sj", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "9sRHySam5fXb", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "zP3PMqaG71Ct", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "custom-appcss", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-file-css", + "isInheritable": false, + "position": 50 + } + ], "format": "markdown", "dataFileName": "Custom app-wide CSS.md", "attachments": [ @@ -9414,7 +12525,7 @@ "dataFileName": "Custom app-wide CSS_image.png" }, { - "attachmentId": "TIerrMjmeich", + "attachmentId": "qBzZ9Qpxwoba", "title": "image.png", "role": "image", "mime": "image/png", @@ -9422,14 +12533,91 @@ "dataFileName": "1_Custom app-wide CSS_image.png" }, { - "attachmentId": "YUrNq5vsCwHe", + "attachmentId": "TIerrMjmeich", "title": "image.png", "role": "image", "mime": "image/png", "position": 10, "dataFileName": "2_Custom app-wide CSS_image.png" + }, + { + "attachmentId": "YUrNq5vsCwHe", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "3_Custom app-wide CSS_image.png" } ] + }, + { + "isClone": false, + "noteId": "g1mlRoU8CsqC", + "notePath": [ + "pOsGYCXsbNQG", + "pKK96zzmvBGf", + "g1mlRoU8CsqC" + ], + "title": "Creating an icon pack", + "notePosition": 50, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "gOKqSJgXLcIj", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "bnyigUA2UK7s", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "0vhv7lsOLy82", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "s8alTXmpFR61", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "mHbBMPDPkVV5", + "isInheritable": false, + "position": 50 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-package", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "creating-icon-pack", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "Creating an icon pack.md", + "attachments": [] } ] }, @@ -9441,7 +12629,7 @@ "tC7s2alapj8V" ], "title": "Advanced Usage", - "notePosition": 320, + "notePosition": 330, "prefix": null, "isExpanded": false, "type": "text", @@ -9453,6 +12641,13 @@ "value": "bx bx-rocket", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "advanced-usage", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -9491,24 +12686,45 @@ { "type": "relation", "name": "internalLink", - "value": "BlN9DFI679QC", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "OFXdgB2nNk1F", + "value": "eIg8jdvaoNNd", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "bwZpz2ajCEwO", + "value": "CdNpE2pqjmI6", "isInheritable": false, "position": 50 }, + { + "type": "relation", + "name": "internalLink", + "value": "OFXdgB2nNk1F", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "BlN9DFI679QC", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "bwZpz2ajCEwO", + "isInheritable": false, + "position": 80 + }, { "type": "label", "name": "shareAlias", @@ -9564,42 +12780,42 @@ { "type": "relation", "name": "internalLink", - "value": "R7abl2fc6Mxi", + "value": "OFXdgB2nNk1F", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "bwZpz2ajCEwO", + "value": "R7abl2fc6Mxi", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "l0tKav7yLHGF", + "value": "BlN9DFI679QC", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "OFXdgB2nNk1F", + "value": "bwZpz2ajCEwO", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "BlN9DFI679QC", + "value": "vZWERwf8U3nx", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "vZWERwf8U3nx", + "value": "l0tKav7yLHGF", "isInheritable": false, "position": 70 }, @@ -9690,86 +12906,100 @@ { "type": "relation", "name": "internalLink", - "value": "u3YFHC9tQlpm", + "value": "_help_YKWqdJhzi2VY", "isInheritable": false, "position": 200 }, { "type": "relation", "name": "internalLink", - "value": "R9pX4DGra2Vt", + "value": "u3YFHC9tQlpm", "isInheritable": false, "position": 210 }, { "type": "relation", "name": "internalLink", - "value": "iRwzGnHPzonm", + "value": "R9pX4DGra2Vt", "isInheritable": false, "position": 220 }, { "type": "relation", "name": "internalLink", - "value": "BCkXAVs63Ttv", + "value": "iRwzGnHPzonm", "isInheritable": false, "position": 230 }, { "type": "relation", "name": "internalLink", - "value": "47ZrP6FNuoG8", + "value": "BCkXAVs63Ttv", "isInheritable": false, "position": 240 }, { "type": "relation", "name": "internalLink", - "value": "KC1HB96bqqHX", + "value": "47ZrP6FNuoG8", "isInheritable": false, "position": 250 }, { "type": "relation", "name": "internalLink", - "value": "BFvAtE74rbP6", + "value": "KC1HB96bqqHX", "isInheritable": false, "position": 260 }, { "type": "relation", "name": "internalLink", - "value": "bdUJEHsAPYQR", + "value": "BFvAtE74rbP6", "isInheritable": false, "position": 270 }, { "type": "relation", "name": "internalLink", - "value": "AxshuNRegLAv", + "value": "bdUJEHsAPYQR", "isInheritable": false, "position": 280 }, { "type": "relation", "name": "internalLink", - "value": "81SGnPGMk7Xc", + "value": "AxshuNRegLAv", "isInheritable": false, "position": 290 }, { "type": "relation", "name": "internalLink", - "value": "xWbu3jpNWapp", + "value": "81SGnPGMk7Xc", "isInheritable": false, "position": 300 }, + { + "type": "relation", + "name": "internalLink", + "value": "xWbu3jpNWapp", + "isInheritable": false, + "position": 310 + }, { "type": "label", "name": "iconClass", "value": "bx bx-hash", "isInheritable": false, "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "labels", + "isInheritable": false, + "position": 320 } ], "format": "markdown", @@ -9809,35 +13039,35 @@ { "type": "relation", "name": "internalLink", - "value": "bwZpz2ajCEwO", + "value": "HcABDtFCkbFN", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "HcABDtFCkbFN", + "value": "R9pX4DGra2Vt", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "R9pX4DGra2Vt", + "value": "KC1HB96bqqHX", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "KC1HB96bqqHX", + "value": "BlN9DFI679QC", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "BlN9DFI679QC", + "value": "bwZpz2ajCEwO", "isInheritable": false, "position": 70 }, @@ -9861,6 +13091,13 @@ "value": "bx bx-transfer", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "relations", + "isInheritable": false, + "position": 100 } ], "format": "markdown", @@ -9949,10 +13186,38 @@ { "type": "relation", "name": "internalLink", - "value": "bwZpz2ajCEwO", + "value": "BlN9DFI679QC", "isInheritable": false, "position": 20 }, + { + "type": "relation", + "name": "internalLink", + "value": "bwZpz2ajCEwO", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GTwFsgaA0lCt", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "zP3PMqaG71Ct", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "R9pX4DGra2Vt", + "isInheritable": false, + "position": 60 + }, { "type": "label", "name": "shareAlias", @@ -9965,27 +13230,43 @@ "name": "iconClass", "value": "bx bx-table", "isInheritable": false, - "position": 40 + "position": 20 } ], "format": "markdown", "dataFileName": "Promoted Attributes.md", "attachments": [ { - "attachmentId": "4EcBRWF9iCk2", + "attachmentId": "8ue55DaAJ82K", "title": "image.png", "role": "image", - "mime": "image/jpg", + "mime": "image/png", "position": 10, "dataFileName": "Promoted Attributes_image.png" }, { - "attachmentId": "Txf5Jdm2vqt2", - "title": "promoted-attributes.png", + "attachmentId": "bLMPNRtMAaKo", + "title": "image.png", "role": "image", "mime": "image/png", "position": 10, - "dataFileName": "Promoted Attributes_promot.png" + "dataFileName": "1_Promoted Attributes_image.png" + }, + { + "attachmentId": "FbNQB8xcY0Nu", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "2_Promoted Attributes_image.png" + }, + { + "attachmentId": "yBIe1DyxuL2e", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "3_Promoted Attributes_image.png" } ] } @@ -10023,42 +13304,42 @@ { "type": "relation", "name": "internalLink", - "value": "wX4HbRucYSDD", + "value": "9sRHySam5fXb", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "xYjQUYhpbUEW", + "value": "wX4HbRucYSDD", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "l0tKav7yLHGF", + "value": "iRwzGnHPzonm", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "47ZrP6FNuoG8", + "value": "xYjQUYhpbUEW", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "9sRHySam5fXb", + "value": "l0tKav7yLHGF", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "iRwzGnHPzonm", + "value": "47ZrP6FNuoG8", "isInheritable": false, "position": 80 }, @@ -10116,24 +13397,31 @@ { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "Cq5X6iKQop6R", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "bdUJEHsAPYQR", + "value": "hrZ1D00cLbal", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "iRwzGnHPzonm", + "value": "bdUJEHsAPYQR", "isInheritable": false, "position": 30 }, + { + "type": "relation", + "name": "internalLink", + "value": "iRwzGnHPzonm", + "isInheritable": false, + "position": 40 + }, { "type": "label", "name": "shareAlias", @@ -10195,115 +13483,157 @@ { "type": "relation", "name": "internalLink", - "value": "6f9hih2hXXZk", + "value": "nBAXQFj20hS1", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "m523cpzocqaD", + "value": "6f9hih2hXXZk", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "iRwzGnHPzonm", + "value": "m523cpzocqaD", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "bdUJEHsAPYQR", + "value": "iRwzGnHPzonm", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "HcABDtFCkbFN", + "value": "bdUJEHsAPYQR", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "GTwFsgaA0lCt", + "value": "HcABDtFCkbFN", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "s1aBHPd79XYj", + "value": "GTwFsgaA0lCt", "isInheritable": false, "position": 80 }, { "type": "relation", "name": "internalLink", - "value": "grjYqerjn243", + "value": "s1aBHPd79XYj", "isInheritable": false, "position": 90 }, { "type": "relation", "name": "internalLink", - "value": "1vHRoWCEjj0L", + "value": "grjYqerjn243", "isInheritable": false, "position": 100 }, { "type": "relation", "name": "internalLink", - "value": "gBbsAeiuUxI5", + "value": "1vHRoWCEjj0L", "isInheritable": false, "position": 110 }, { "type": "relation", "name": "internalLink", - "value": "81SGnPGMk7Xc", + "value": "gBbsAeiuUxI5", "isInheritable": false, "position": 120 }, { "type": "relation", "name": "internalLink", - "value": "W8vYD3Q1zjCR", + "value": "81SGnPGMk7Xc", "isInheritable": false, "position": 130 }, { "type": "relation", "name": "internalLink", - "value": "WOcw2SLH6tbX", + "value": "W8vYD3Q1zjCR", "isInheritable": false, "position": 140 }, { "type": "relation", "name": "internalLink", - "value": "bwZpz2ajCEwO", + "value": "WOcw2SLH6tbX", "isInheritable": false, "position": 150 }, { "type": "relation", "name": "internalLink", - "value": "Wy267RK4M69c", + "value": "x3i7MxGccDuM", "isInheritable": false, "position": 160 }, { "type": "relation", "name": "internalLink", - "value": "Qjt68inQ2bRj", + "value": "wX4HbRucYSDD", "isInheritable": false, "position": 170 }, + { + "type": "relation", + "name": "internalLink", + "value": "ycBFjKrrwE9p", + "isInheritable": false, + "position": 180 + }, + { + "type": "relation", + "name": "internalLink", + "value": "bwZpz2ajCEwO", + "isInheritable": false, + "position": 190 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Wy267RK4M69c", + "isInheritable": false, + "position": 200 + }, + { + "type": "relation", + "name": "internalLink", + "value": "eIg8jdvaoNNd", + "isInheritable": false, + "position": 210 + }, + { + "type": "relation", + "name": "internalLink", + "value": "OFXdgB2nNk1F", + "isInheritable": false, + "position": 220 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Qjt68inQ2bRj", + "isInheritable": false, + "position": 230 + }, { "type": "label", "name": "shareAlias", @@ -10322,14 +13652,6 @@ "format": "markdown", "dataFileName": "Sharing.md", "attachments": [ - { - "attachmentId": "2kLFcH6hel9i", - "title": "shared-list.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Sharing_shared-list.png" - }, { "attachmentId": "ibqWQUOCMhIE", "title": "image.png", @@ -10364,7 +13686,22 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "serving-raw", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-code", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", "dataFileName": "Serving directly the content o.md", "attachments": [ @@ -10385,6 +13722,90 @@ "dataFileName": "1_Serving directly the conte.png" } ] + }, + { + "isClone": false, + "noteId": "ycBFjKrrwE9p", + "notePath": [ + "pOsGYCXsbNQG", + "tC7s2alapj8V", + "R9pX4DGra2Vt", + "ycBFjKrrwE9p" + ], + "title": "Exporting static HTML for web publishing", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "R9pX4DGra2Vt", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "pgxEVkzLl1OP", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-file-html", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "static-html", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "Exporting static HTML for web .md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "sLIJ6f1dkJYW", + "notePath": [ + "pOsGYCXsbNQG", + "tC7s2alapj8V", + "R9pX4DGra2Vt", + "sLIJ6f1dkJYW" + ], + "title": "Reverse proxy configuration", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "reverse-proxy", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-world", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Reverse proxy configuration.md", + "attachments": [] } ] }, @@ -10458,6 +13879,13 @@ "value": "advanced-showcases", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-component", + "isInheritable": false, + "position": 80 } ], "format": "markdown", @@ -10578,35 +14006,35 @@ { "type": "relation", "name": "internalLink", - "value": "l0tKav7yLHGF", + "value": "GLks18SNjxmC", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "GLks18SNjxmC", + "value": "wX4HbRucYSDD", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "wX4HbRucYSDD", + "value": "OFXdgB2nNk1F", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "OFXdgB2nNk1F", + "value": "KC1HB96bqqHX", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "KC1HB96bqqHX", + "value": "l0tKav7yLHGF", "isInheritable": false, "position": 50 }, @@ -10637,6 +14065,13 @@ "value": "weight-tracker", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-line-chart", + "isInheritable": false, + "position": 90 } ], "format": "markdown", @@ -10671,28 +14106,28 @@ { "type": "relation", "name": "internalLink", - "value": "l0tKav7yLHGF", + "value": "OFXdgB2nNk1F", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "OFXdgB2nNk1F", + "value": "CdNpE2pqjmI6", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "CdNpE2pqjmI6", + "value": "wX4HbRucYSDD", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "wX4HbRucYSDD", + "value": "l0tKav7yLHGF", "isInheritable": false, "position": 40 }, @@ -10786,21 +14221,21 @@ { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "CdNpE2pqjmI6", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "CdNpE2pqjmI6", + "value": "6f9hih2hXXZk", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "6f9hih2hXXZk", + "value": "zEY4DaJG4YT5", "isInheritable": false, "position": 30 }, @@ -10824,6 +14259,13 @@ "value": "custom-request-handler", "isInheritable": false, "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-globe", + "isInheritable": false, + "position": 60 } ], "format": "markdown", @@ -10844,7 +14286,22 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "custom-resource-providers", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-file-plus", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", "dataFileName": "Custom Resource Providers.md", "attachments": [] @@ -10864,12 +14321,26 @@ "type": "text", "mime": "text/markdown", "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "9qPsTWBorUhQ", + "isInheritable": false, + "position": 10 + }, { "type": "label", "name": "shareAlias", "value": "etapi", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-extension", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -10896,9 +14367,16 @@ { "type": "label", "name": "webViewSrc", - "value": "/etapi/docs", + "value": "/rest-api/etapi/", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "api-reference", + "isInheritable": false, + "position": 20 } ], "dataFileName": "API Reference.dat", @@ -10948,6 +14426,13 @@ "value": "default-note-title", "isInheritable": false, "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-edit-alt", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -11046,6 +14531,20 @@ "value": "tAassRL4RSQL", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "manual-editing", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-edit", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -11082,23 +14581,44 @@ { "type": "relation", "name": "internalLink", - "value": "l0tKav7yLHGF", + "value": "x3i7MxGccDuM", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "Vc8PjrjAGuOp", + "value": "l0tKav7yLHGF", "isInheritable": false, "position": 20 }, + { + "type": "relation", + "name": "internalLink", + "value": "IjZS7iK5EXtb", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "XpOYSgsLkTJy", + "isInheritable": false, + "position": 40 + }, { "type": "label", "name": "iconClass", "value": "bx bx-data", "isInheritable": false, "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "sql-console", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -11112,29 +14632,21 @@ "position": 10, "dataFileName": "SQL Console_image.png" }, - { - "attachmentId": "827EgLgWhZWF", - "title": "image.png", - "role": "image", - "mime": "image/jpg", - "position": 10, - "dataFileName": "1_SQL Console_image.png" - }, { "attachmentId": "gIbK7NNLu3iZ", "title": "image.png", "role": "image", "mime": "image/png", "position": 10, - "dataFileName": "2_SQL Console_image.png" + "dataFileName": "1_SQL Console_image.png" }, { - "attachmentId": "pP87PB9ELjQn", + "attachmentId": "wdBs3e0MApgs", "title": "image.png", "role": "image", "mime": "image/png", "position": 10, - "dataFileName": "3_SQL Console_image.png" + "dataFileName": "2_SQL Console_image.png" } ] } @@ -11159,28 +14671,28 @@ { "type": "relation", "name": "internalLink", - "value": "l0tKav7yLHGF", + "value": "iRwzGnHPzonm", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "R7abl2fc6Mxi", + "value": "l0tKav7yLHGF", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "xYjQUYhpbUEW", + "value": "R7abl2fc6Mxi", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "iRwzGnHPzonm", + "value": "xYjQUYhpbUEW", "isInheritable": false, "position": 40 }, @@ -11197,6 +14709,13 @@ "value": "bx bx-package", "isInheritable": false, "position": 110 + }, + { + "type": "label", + "name": "shareAlias", + "value": "demo-notes", + "isInheritable": false, + "position": 120 } ], "format": "markdown", @@ -11220,12 +14739,26 @@ "type": "text", "mime": "text/markdown", "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "tAassRL4RSQL", + "isInheritable": false, + "position": 10 + }, { "type": "label", "name": "shareAlias", "value": "configuration", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-cog", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -11255,6 +14788,20 @@ "value": "cbkrhQjrkKrh", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "trilium-instance", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-windows", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -11276,7 +14823,22 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "cors", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-lock", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", "dataFileName": "Cross-Origin Resource Sharing .md", "attachments": [] @@ -11301,28 +14863,28 @@ { "type": "relation", "name": "internalLink", - "value": "HI6GBBIduIgv", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "Cq5X6iKQop6R", + "value": "yTjUdsOi4CIE", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "oPVyFC7WL2Lp", + "value": "HI6GBBIduIgv", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "yTjUdsOi4CIE", + "value": "Cq5X6iKQop6R", "isInheritable": false, "position": 40 }, @@ -11346,6 +14908,13 @@ "value": "bx bx-list-plus", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "bulk-actions", + "isInheritable": false, + "position": 70 } ], "format": "markdown", @@ -11459,6 +15028,13 @@ "value": "bx bx-code", "isInheritable": false, "position": 120 + }, + { + "type": "label", + "name": "shareAlias", + "value": "note-source", + "isInheritable": false, + "position": 130 } ], "format": "markdown", @@ -11499,9 +15075,16 @@ { "type": "label", "name": "iconClass", - "value": "bx bxs-component", + "value": "bx bx-pyramid", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "technologies", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -11566,6 +15149,20 @@ "value": "NwBbFdNZ9h7O", "isInheritable": false, "position": 60 + }, + { + "type": "label", + "name": "shareAlias", + "value": "ckeditor", + "isInheritable": false, + "position": 70 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-file", + "isInheritable": false, + "position": 80 } ], "format": "markdown", @@ -11594,6 +15191,20 @@ "value": "gBbsAeiuUxI5", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "mindelixir", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-sitemap", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -11622,6 +15233,20 @@ "value": "grjYqerjn243", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "excalidraw", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-pen", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -11650,6 +15275,20 @@ "value": "81SGnPGMk7Xc", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "leaflet", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-map-alt", + "isInheritable": false, + "position": 30 } ], "format": "markdown", @@ -11686,6 +15325,13 @@ "value": "bx bx-hash", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "note-id", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -11706,7 +15352,22 @@ "isExpanded": false, "type": "text", "mime": "text/html", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "internal-api", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-component", + "isInheritable": false, + "position": 30 + } + ], "format": "markdown", "attachments": [], "dirFileName": "Internal API", @@ -11730,9 +15391,16 @@ { "type": "label", "name": "webViewSrc", - "value": "/api/docs", + "value": "/rest-api/internal/", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "api-reference", + "isInheritable": false, + "position": 20 } ], "dataFileName": "API Reference.dat", @@ -11772,107 +15440,198 @@ { "type": "relation", "name": "internalLink", - "value": "wX4HbRucYSDD", + "value": "eIg8jdvaoNNd", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "YKWqdJhzi2VY", + "value": "QEAPj01N5f7w", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "ivYnonVFBxbQ", + "value": "wX4HbRucYSDD", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "eIg8jdvaoNNd", + "value": "m1lbrzyKDaRB", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "QEAPj01N5f7w", + "value": "x3i7MxGccDuM", "isInheritable": false, "position": 70 }, { "type": "relation", "name": "internalLink", - "value": "m1lbrzyKDaRB", + "value": "_globalNoteMap", "isInheritable": false, "position": 80 }, { "type": "relation", "name": "internalLink", - "value": "x3i7MxGccDuM", + "value": "bdUJEHsAPYQR", "isInheritable": false, "position": 90 }, { "type": "relation", "name": "internalLink", - "value": "bdUJEHsAPYQR", + "value": "xYmIYSP6wE3F", "isInheritable": false, "position": 100 }, { "type": "relation", "name": "internalLink", - "value": "xYmIYSP6wE3F", + "value": "u3YFHC9tQlpm", "isInheritable": false, "position": 110 }, { "type": "relation", "name": "internalLink", - "value": "u3YFHC9tQlpm", + "value": "_sqlConsole", "isInheritable": false, "position": 120 }, { "type": "relation", "name": "internalLink", - "value": "qzNzp9LYQyPT", + "value": "YKWqdJhzi2VY", "isInheritable": false, "position": 130 }, { "type": "relation", "name": "internalLink", - "value": "CdNpE2pqjmI6", + "value": "_search", "isInheritable": false, "position": 140 }, { "type": "relation", "name": "internalLink", - "value": "R9pX4DGra2Vt", + "value": "_bulkAction", "isInheritable": false, "position": 150 }, { "type": "relation", "name": "internalLink", - "value": "4TIF1oA4VQRO", + "value": "ivYnonVFBxbQ", "isInheritable": false, "position": 160 }, + { + "type": "relation", + "name": "internalLink", + "value": "_backendLog", + "isInheritable": false, + "position": 170 + }, + { + "type": "relation", + "name": "internalLink", + "value": "qzNzp9LYQyPT", + "isInheritable": false, + "position": 180 + }, + { + "type": "relation", + "name": "internalLink", + "value": "_userHidden", + "isInheritable": false, + "position": 190 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CdNpE2pqjmI6", + "isInheritable": false, + "position": 200 + }, + { + "type": "relation", + "name": "internalLink", + "value": "_lbTplRoot", + "isInheritable": false, + "position": 210 + }, + { + "type": "relation", + "name": "internalLink", + "value": "_share", + "isInheritable": false, + "position": 220 + }, + { + "type": "relation", + "name": "internalLink", + "value": "R9pX4DGra2Vt", + "isInheritable": false, + "position": 230 + }, + { + "type": "relation", + "name": "internalLink", + "value": "_lbRoot", + "isInheritable": false, + "position": 240 + }, + { + "type": "relation", + "name": "internalLink", + "value": "_options", + "isInheritable": false, + "position": 250 + }, + { + "type": "relation", + "name": "internalLink", + "value": "4TIF1oA4VQRO", + "isInheritable": false, + "position": 260 + }, + { + "type": "relation", + "name": "internalLink", + "value": "_lbMobileRoot", + "isInheritable": false, + "position": 270 + }, + { + "type": "relation", + "name": "internalLink", + "value": "_help", + "isInheritable": false, + "position": 280 + }, { "type": "label", "name": "iconClass", "value": "bx bx-hide", "isInheritable": false, "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "hidden-notes", + "isInheritable": false, + "position": 290 } ], "format": "markdown", @@ -11916,6 +15675,13 @@ "value": "bx bxs-data", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "metrics", + "isInheritable": false, + "position": 20 } ], "format": "markdown", @@ -11963,171 +15729,98 @@ "isExpanded": false, "type": "code", "mime": "application/json", - "attributes": [], + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "grafana-dashboard", + "isInheritable": false, + "position": 30 + } + ], "dataFileName": "grafana-dashboard.json", "attachments": [] } ] - } - ] - }, - { - "isClone": false, - "noteId": "LMAv4Uy3Wk6J", - "notePath": [ - "pOsGYCXsbNQG", - "LMAv4Uy3Wk6J" - ], - "title": "AI", - "notePosition": 330, - "prefix": null, - "isExpanded": false, - "type": "book", - "mime": "", - "attributes": [ - { - "type": "label", - "name": "iconClass", - "value": "bx bx-bot", - "isInheritable": false, - "position": 10 }, - { - "type": "label", - "name": "viewType", - "value": "list", - "isInheritable": false, - "position": 20 - }, - { - "type": "label", - "name": "expanded", - "value": "", - "isInheritable": false, - "position": 30 - } - ], - "attachments": [], - "dirFileName": "AI", - "children": [ { "isClone": false, - "noteId": "GBBMSlVSOIGP", + "noteId": "64ZTlUPgEPtW", "notePath": [ "pOsGYCXsbNQG", - "LMAv4Uy3Wk6J", - "GBBMSlVSOIGP" + "tC7s2alapj8V", + "64ZTlUPgEPtW" ], - "title": "Introduction", - "notePosition": 10, + "title": "Safe mode", + "notePosition": 250, "prefix": null, "isExpanded": false, "type": "text", "mime": "text/html", "attributes": [ { - "type": "relation", - "name": "internalLink", - "value": "vvUCN7FDkq7G", + "type": "label", + "name": "shareAlias", + "value": "safe-mode", "isInheritable": false, - "position": 10 + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-virus-block", + "isInheritable": false, + "position": 30 } ], "format": "markdown", - "dataFileName": "Introduction.md", - "attachments": [ - { - "attachmentId": "4UpXwA3WvbmA", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Introduction_image.png" - }, - { - "attachmentId": "8Bn5IsE3Bv1k", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Introduction_image.png" - }, - { - "attachmentId": "ABN1rFIIJ8no", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "2_Introduction_image.png" - }, - { - "attachmentId": "CK3z7sYw63XT", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "3_Introduction_image.png" - }, - { - "attachmentId": "E6Y09N2t7vyA", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "4_Introduction_image.png" - }, - { - "attachmentId": "JlIPeTtl5wlV", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "5_Introduction_image.png" - }, - { - "attachmentId": "ur4TDJeRqpUC", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "6_Introduction_image.png" - }, - { - "attachmentId": "UTH83LkQEA8u", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "7_Introduction_image.png" - }, - { - "attachmentId": "V68TCCTUdyl7", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "8_Introduction_image.png" - }, - { - "attachmentId": "YbWoNq58T9kB", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "9_Introduction_image.png" - } - ] + "dataFileName": "Safe mode.md", + "attachments": [] }, { "isClone": false, - "noteId": "WkM7gsEUyCXs", + "noteId": "HAIOFBoYIIdO", "notePath": [ "pOsGYCXsbNQG", - "LMAv4Uy3Wk6J", - "WkM7gsEUyCXs" + "tC7s2alapj8V", + "HAIOFBoYIIdO" ], - "title": "AI Provider Information", - "notePosition": 20, + "title": "Nightly release", + "notePosition": 260, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-moon", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "nightly-release", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Nightly release.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "ZmT9ln8XJX2o", + "notePath": [ + "pOsGYCXsbNQG", + "tC7s2alapj8V", + "ZmT9ln8XJX2o" + ], + "title": "Read-only database", + "notePosition": 270, "prefix": null, "isExpanded": false, "type": "text", @@ -12136,204 +15829,106 @@ { "type": "relation", "name": "internalLink", - "value": "7EdTxPADv95W", + "value": "wy8So3yZZlH9", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "ZavFigBX9AwP", + "value": "R9pX4DGra2Vt", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "e0lkirXEiSNc", + "value": "eIg8jdvaoNNd", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GTwFsgaA0lCt", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "KSZ04uQ2D1St", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Gzjqa934BdH4", + "isInheritable": false, + "position": 60 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-book-reader", "isInheritable": false, "position": 30 }, { "type": "label", - "name": "viewType", - "value": "list", + "name": "shareAlias", + "value": "read-only-db", "isInheritable": false, - "position": 10 + "position": 40 } ], "format": "markdown", - "dataFileName": "AI Provider Information.md", - "attachments": [ - { - "attachmentId": "BNN9Vv3JEf2X", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "AI Provider Information_im.png" - }, - { - "attachmentId": "diIollN3KEbn", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_AI Provider Information_im.png" - } - ], - "dirFileName": "AI Provider Information", - "children": [ - { - "isClone": false, - "noteId": "7EdTxPADv95W", - "notePath": [ - "pOsGYCXsbNQG", - "LMAv4Uy3Wk6J", - "WkM7gsEUyCXs", - "7EdTxPADv95W" - ], - "title": "Ollama", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "book", - "mime": "", - "attributes": [ - { - "type": "label", - "name": "viewType", - "value": "list", - "isInheritable": false, - "position": 10 - }, - { - "type": "label", - "name": "expanded", - "value": "", - "isInheritable": false, - "position": 20 - } - ], - "attachments": [], - "dirFileName": "Ollama", - "children": [ - { - "isClone": false, - "noteId": "vvUCN7FDkq7G", - "notePath": [ - "pOsGYCXsbNQG", - "LMAv4Uy3Wk6J", - "WkM7gsEUyCXs", - "7EdTxPADv95W", - "vvUCN7FDkq7G" - ], - "title": "Installing Ollama", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Installing Ollama.md", - "attachments": [ - { - "attachmentId": "CG9q2FfKuEsr", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Installing Ollama_image.png" - }, - { - "attachmentId": "GEcgXxUE1IDx", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Installing Ollama_image.png" - }, - { - "attachmentId": "OMGDDxjScXCl", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "2_Installing Ollama_image.png" - }, - { - "attachmentId": "Qacg7ibmEBkZ", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "3_Installing Ollama_image.png" - }, - { - "attachmentId": "vSjU929VnBm4", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "4_Installing Ollama_image.png" - }, - { - "attachmentId": "xGrxARTj79Gv", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "5_Installing Ollama_image.png" - } - ] - } - ] - }, - { - "isClone": false, - "noteId": "ZavFigBX9AwP", - "notePath": [ - "pOsGYCXsbNQG", - "LMAv4Uy3Wk6J", - "WkM7gsEUyCXs", - "ZavFigBX9AwP" - ], - "title": "OpenAI", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "OpenAI.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "e0lkirXEiSNc", - "notePath": [ - "pOsGYCXsbNQG", - "LMAv4Uy3Wk6J", - "WkM7gsEUyCXs", - "e0lkirXEiSNc" - ], - "title": "Anthropic", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Anthropic.md", - "attachments": [] - } - ] + "dataFileName": "Read-only database.md", + "attachments": [] } ] }, + { + "isClone": false, + "noteId": "GBBMSlVSOIGP", + "notePath": [ + "pOsGYCXsbNQG", + "GBBMSlVSOIGP" + ], + "title": "AI", + "notePosition": 340, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "llm", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-bot", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "AI.md", + "attachments": [] + }, { "isClone": false, "noteId": "CdNpE2pqjmI6", @@ -12342,7 +15937,7 @@ "CdNpE2pqjmI6" ], "title": "Scripting", - "notePosition": 340, + "notePosition": 360, "prefix": null, "isExpanded": false, "type": "text", @@ -12435,75 +16030,700 @@ { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "MgibgPcfeuGz", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "SynTBQiBsdYJ", + "value": "oPVyFC7WL2Lp", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "GLks18SNjxmC", + "value": "RnaPdbciOfeq", "isInheritable": false, "position": 30 }, + { + "type": "relation", + "name": "internalLink", + "value": "4Gn3psZKsfSm", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "xYmIYSP6wE3F", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "HcABDtFCkbFN", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "SPirpZypehBG", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "HI6GBBIduIgv", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GPERMystNGTB", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GhurYZjh8e1V", + "isInheritable": false, + "position": 100 + }, + { + "type": "relation", + "name": "internalLink", + "value": "M8IppdwVHSjG", + "isInheritable": false, + "position": 110 + }, + { + "type": "relation", + "name": "internalLink", + "value": "Q2z6av6JZVWm", + "isInheritable": false, + "position": 120 + }, + { + "type": "relation", + "name": "internalLink", + "value": "SynTBQiBsdYJ", + "isInheritable": false, + "position": 130 + }, { "type": "label", "name": "shareAlias", "value": "frontend-basics", "isInheritable": false, "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-window", + "isInheritable": false, + "position": 40 } ], "format": "markdown", "dataFileName": "Frontend Basics.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "es8OU2GuguFU", - "notePath": [ - "pOsGYCXsbNQG", - "CdNpE2pqjmI6", - "es8OU2GuguFU" - ], - "title": "Examples", - "notePosition": 50, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", "attachments": [], - "dirFileName": "Examples", + "dirFileName": "Frontend Basics", "children": [ { "isClone": false, - "noteId": "TjLYAo3JMO8X", + "noteId": "MgibgPcfeuGz", "notePath": [ "pOsGYCXsbNQG", "CdNpE2pqjmI6", - "es8OU2GuguFU", - "TjLYAo3JMO8X" + "yIhgI5H7A2Sm", + "MgibgPcfeuGz" ], - "title": "\"New Task\" launcher button", + "title": "Custom Widgets", "notePosition": 10, "prefix": null, "isExpanded": false, "type": "text", + "mime": "text/markdown", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "KLsqhjaqh1QW", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "gMkgcLJ6jBkg", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "HI6GBBIduIgv", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "s8alTXmpFR61", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GhurYZjh8e1V", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "RnaPdbciOfeq", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "M8IppdwVHSjG", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "xYmIYSP6wE3F", + "isInheritable": false, + "position": 100 + }, + { + "type": "relation", + "name": "internalLink", + "value": "4Gn3psZKsfSm", + "isInheritable": false, + "position": 110 + }, + { + "type": "label", + "name": "shareAlias", + "value": "custom-widget", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-widget", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Custom Widgets.md", + "attachments": [], + "dirFileName": "Custom Widgets", + "children": [ + { + "isClone": false, + "noteId": "SynTBQiBsdYJ", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "MgibgPcfeuGz", + "SynTBQiBsdYJ" + ], + "title": "Widget Basics", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/markdown", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "zEY4DaJG4YT5", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "BFs8mudNFgCS", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GLks18SNjxmC", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "MgibgPcfeuGz", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "s8alTXmpFR61", + "isInheritable": false, + "position": 50 + }, + { + "type": "label", + "name": "shareAlias", + "value": "widget-basics", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Widget Basics.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "GhurYZjh8e1V", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "MgibgPcfeuGz", + "GhurYZjh8e1V" + ], + "title": "Note context aware widget", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "note-context-aware-widget", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Note context aware widget.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "M8IppdwVHSjG", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "MgibgPcfeuGz", + "M8IppdwVHSjG" + ], + "title": "Right pane widget", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "IjZS7iK5EXtb", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "right-pane-widget", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Right pane widget.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "YNxAqkI5Kg1M", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "MgibgPcfeuGz", + "YNxAqkI5Kg1M" + ], + "title": "Word count widget", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "6tZeKvSHEUiB", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "s8alTXmpFR61", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "word-count", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Word count widget.md", + "attachments": [ + { + "attachmentId": "JhM9NWfebzPi", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Word count widget_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "VqGQnnPGnqAU", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "MgibgPcfeuGz", + "VqGQnnPGnqAU" + ], + "title": "CSS", + "notePosition": 70, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "Sg9GrCtyftZf", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "css", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "CSS.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "gMkgcLJ6jBkg", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "MgibgPcfeuGz", + "gMkgcLJ6jBkg" + ], + "title": "Troubleshooting", + "notePosition": 80, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "troubleshooting", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Troubleshooting.md", + "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "es8OU2GuguFU", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "es8OU2GuguFU" + ], + "title": "Examples", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "examples", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-code-alt", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "attachments": [], + "dirFileName": "Examples", + "children": [ + { + "isClone": false, + "noteId": "TjLYAo3JMO8X", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "es8OU2GuguFU", + "TjLYAo3JMO8X" + ], + "title": "\"New Task\" launcher button", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "xYjQUYhpbUEW", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "xYmIYSP6wE3F", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "zEY4DaJG4YT5", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "s8alTXmpFR61", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "yIhgI5H7A2Sm", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "m1lbrzyKDaRB", + "isInheritable": false, + "position": 70 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-task", + "isInheritable": false, + "position": 80 + }, + { + "type": "label", + "name": "shareAlias", + "value": "new-task-button", + "isInheritable": false, + "position": 90 + } + ], + "format": "markdown", + "dataFileName": "New Task launcher button.md", + "attachments": [ + { + "attachmentId": "9C2JA6tdtRpN", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "New Task launcher button_i.png" + } + ] + }, + { + "isClone": false, + "noteId": "7kZPMD0uFwkH", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "es8OU2GuguFU", + "7kZPMD0uFwkH" + ], + "title": "Downloading responses from Google Forms", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "responses-from-google-forms", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Downloading responses from Goo.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "DL92EjAaXT26", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "es8OU2GuguFU", + "DL92EjAaXT26" + ], + "title": "Using promoted attributes to configure scripts", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "promoted-attributes-config", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Using promoted attributes to c.md", + "attachments": [ + { + "attachmentId": "7P3jzVEa1mk7", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Using promoted attributes .png" + } + ] + } + ] + }, + { + "isClone": false, + "noteId": "4Gn3psZKsfSm", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "4Gn3psZKsfSm" + ], + "title": "Launch Bar Widgets", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", "mime": "text/html", "attributes": [ { "type": "relation", "name": "internalLink", - "value": "xYjQUYhpbUEW", + "value": "MgibgPcfeuGz", "isInheritable": false, "position": 10 }, @@ -12517,271 +16737,177 @@ { "type": "relation", "name": "internalLink", - "value": "6f9hih2hXXZk", + "value": "IPArqVfDQ4We", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "gcI7RPbaNSh3", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "m1lbrzyKDaRB", + "value": "x3i7MxGccDuM", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "s8alTXmpFR61", + "value": "OFXdgB2nNk1F", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "yIhgI5H7A2Sm", + "value": "s8alTXmpFR61", "isInheritable": false, "position": 70 }, { "type": "label", "name": "iconClass", - "value": "bx bx-task", - "isInheritable": false, - "position": 80 - } - ], - "format": "markdown", - "dataFileName": "New Task launcher button.md", - "attachments": [ - { - "attachmentId": "9C2JA6tdtRpN", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "New Task launcher button_i.png" - } - ] - }, - { - "isClone": false, - "noteId": "7kZPMD0uFwkH", - "notePath": [ - "pOsGYCXsbNQG", - "CdNpE2pqjmI6", - "es8OU2GuguFU", - "7kZPMD0uFwkH" - ], - "title": "Downloading responses from Google Forms", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Downloading responses from Goo.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "DL92EjAaXT26", - "notePath": [ - "pOsGYCXsbNQG", - "CdNpE2pqjmI6", - "es8OU2GuguFU", - "DL92EjAaXT26" - ], - "title": "Using promoted attributes to configure scripts", - "notePosition": 30, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [], - "format": "markdown", - "dataFileName": "Using promoted attributes to c.md", - "attachments": [ - { - "attachmentId": "7P3jzVEa1mk7", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Using promoted attributes .png" - } - ] - } - ] - }, - { - "isClone": false, - "noteId": "GPERMystNGTB", - "notePath": [ - "pOsGYCXsbNQG", - "CdNpE2pqjmI6", - "GPERMystNGTB" - ], - "title": "Events", - "notePosition": 70, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/markdown", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "CdNpE2pqjmI6", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "c5xB8m4g2IY6", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "zEY4DaJG4YT5", - "isInheritable": false, - "position": 30 - }, - { - "type": "label", - "name": "shareAlias", - "value": "events", - "isInheritable": false, - "position": 10 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-rss", - "isInheritable": false, - "position": 20 - } - ], - "format": "markdown", - "dataFileName": "Events.md", - "attachments": [] - }, - { - "isClone": false, - "noteId": "MgibgPcfeuGz", - "notePath": [ - "pOsGYCXsbNQG", - "CdNpE2pqjmI6", - "MgibgPcfeuGz" - ], - "title": "Custom Widgets", - "notePosition": 80, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/markdown", - "attributes": [ - { - "type": "label", - "name": "shareAlias", - "value": "custom-widget", - "isInheritable": false, - "position": 20 - } - ], - "format": "markdown", - "dataFileName": "Custom Widgets.md", - "attachments": [], - "dirFileName": "Custom Widgets", - "children": [ - { - "isClone": false, - "noteId": "YNxAqkI5Kg1M", - "notePath": [ - "pOsGYCXsbNQG", - "CdNpE2pqjmI6", - "MgibgPcfeuGz", - "YNxAqkI5Kg1M" - ], - "title": "Word count widget", - "notePosition": 10, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "6tZeKvSHEUiB", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "6f9hih2hXXZk", - "isInheritable": false, - "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "s8alTXmpFR61", + "value": "bx bx-dock-left", "isInheritable": false, "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "launch-bar-widgets", + "isInheritable": false, + "position": 40 } ], "format": "markdown", - "dataFileName": "Word count widget.md", - "attachments": [ + "dataFileName": "Launch Bar Widgets.md", + "attachments": [], + "dirFileName": "Launch Bar Widgets", + "children": [ { - "attachmentId": "JhM9NWfebzPi", - "title": "image.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Word count widget_image.png" + "isClone": false, + "noteId": "IPArqVfDQ4We", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "4Gn3psZKsfSm", + "IPArqVfDQ4We" + ], + "title": "Note Title Widget", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "x0JgW8UqGXvq", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "note-title", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "note-title-widget", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Note Title Widget.md", + "attachments": [ + { + "attachmentId": "hgXS32zcBfVp", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Note Title Widget_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "gcI7RPbaNSh3", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "4Gn3psZKsfSm", + "gcI7RPbaNSh3" + ], + "title": "Analog Watch", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "analog-watch", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Analog Watch.md", + "attachments": [ + { + "attachmentId": "49vpwjjOEAm7", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Analog Watch_image.png" + } + ] } ] }, { "isClone": false, - "noteId": "SynTBQiBsdYJ", + "noteId": "KLsqhjaqh1QW", "notePath": [ "pOsGYCXsbNQG", "CdNpE2pqjmI6", - "MgibgPcfeuGz", - "SynTBQiBsdYJ" + "yIhgI5H7A2Sm", + "KLsqhjaqh1QW" ], - "title": "Widget Basics", - "notePosition": 20, + "title": "Preact", + "notePosition": 40, "prefix": null, "isExpanded": false, "type": "text", - "mime": "text/markdown", + "mime": "text/html", "attributes": [ { "type": "relation", "name": "internalLink", - "value": "zEY4DaJG4YT5", + "value": "HcABDtFCkbFN", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "BFs8mudNFgCS", + "value": "MgibgPcfeuGz", "isInheritable": false, "position": 20 }, @@ -12792,16 +16918,550 @@ "isInheritable": false, "position": 30 }, + { + "type": "relation", + "name": "internalLink", + "value": "Bqde6BvPo05g", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "wy8So3yZZlH9", + "isInheritable": false, + "position": 50 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxl-react", + "isInheritable": false, + "position": 30 + }, { "type": "label", "name": "shareAlias", - "value": "widget-basics", + "value": "preac", + "isInheritable": false, + "position": 60 + }, + { + "type": "label", + "name": "shareAlias", + "value": "preact", + "isInheritable": false, + "position": 70 + } + ], + "format": "markdown", + "dataFileName": "Preact.md", + "attachments": [], + "dirFileName": "Preact", + "children": [ + { + "isClone": false, + "noteId": "Bqde6BvPo05g", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "KLsqhjaqh1QW", + "Bqde6BvPo05g" + ], + "title": "Component libraries", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "hA834UaHhSNn", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "HcABDtFCkbFN", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-component", + "isInheritable": false, + "position": 50 + }, + { + "type": "label", + "name": "shareAlias", + "value": "component-libraries", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "Component libraries.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "ykYtbM9k3a7B", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "KLsqhjaqh1QW", + "ykYtbM9k3a7B" + ], + "title": "Hooks", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "HcABDtFCkbFN", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GhurYZjh8e1V", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-question-mark", + "isInheritable": false, + "position": 60 + }, + { + "type": "label", + "name": "shareAlias", + "value": "hooks", + "isInheritable": false, + "position": 70 + } + ], + "format": "markdown", + "dataFileName": "Hooks.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "Sg9GrCtyftZf", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "KLsqhjaqh1QW", + "Sg9GrCtyftZf" + ], + "title": "CSS", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "AlhDUqhENtH7", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-file-css", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "shareAlias", + "value": "css", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "CSS.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "RSssb9S3xgSr", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "KLsqhjaqh1QW", + "RSssb9S3xgSr" + ], + "title": "Built-in components", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "MgibgPcfeuGz", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "HcABDtFCkbFN", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6tZeKvSHEUiB", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "i9B4IW7b6V6z", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bxs-component", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "builtin-components", + "isInheritable": false, + "position": 50 + } + ], + "format": "markdown", + "dataFileName": "Built-in components.md", + "attachments": [ + { + "attachmentId": "KtDChJYITDxC", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Built-in components_image.png" + } + ], + "dirFileName": "Built-in components", + "children": [ + { + "isClone": false, + "noteId": "i9B4IW7b6V6z", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "yIhgI5H7A2Sm", + "KLsqhjaqh1QW", + "RSssb9S3xgSr", + "i9B4IW7b6V6z" + ], + "title": "Widget showcase", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "code", + "mime": "text/jsx", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "widget-showcase", + "isInheritable": false, + "position": 30 + } + ], + "dataFileName": "Widget showcase.jsx", + "attachments": [] + } + ] + } + ] + } + ] + }, + { + "isClone": false, + "noteId": "SPirpZypehBG", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "SPirpZypehBG" + ], + "title": "Backend scripts", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "yIhgI5H7A2Sm", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "WOcw2SLH6tbX", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "poXkQfguuA0U", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "GPERMystNGTB", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "MEtfsqa5VwNi", + "isInheritable": false, + "position": 60 + }, + { + "type": "label", + "name": "shareAlias", + "value": "backend-basics", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-server", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Backend scripts.md", + "attachments": [], + "dirFileName": "Backend scripts", + "children": [ + { + "isClone": false, + "noteId": "fZ2IGYFXjkEy", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "SPirpZypehBG", + "fZ2IGYFXjkEy" + ], + "title": "Server-side imports", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "server-imports", "isInheritable": false, "position": 20 } ], "format": "markdown", - "dataFileName": "Widget Basics.md", + "dataFileName": "Server-side imports.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "GPERMystNGTB", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "SPirpZypehBG", + "GPERMystNGTB" + ], + "title": "Events", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/markdown", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "CdNpE2pqjmI6", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "c5xB8m4g2IY6", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "zEY4DaJG4YT5", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "events", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-rss", + "isInheritable": false, + "position": 20 + } + ], + "format": "markdown", + "dataFileName": "Events.md", + "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "wqXwKJl6VpNk", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "wqXwKJl6VpNk" + ], + "title": "Common concepts", + "notePosition": 40, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bxl-nodejs", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "common-concepts", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "attachments": [], + "dirFileName": "Common concepts", + "children": [ + { + "isClone": false, + "noteId": "hA834UaHhSNn", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "wqXwKJl6VpNk", + "hA834UaHhSNn" + ], + "title": "Script bundles", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "HcABDtFCkbFN", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "IakOLONlIfGI", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-package", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "bundles", + "isInheritable": false, + "position": 60 + } + ], + "format": "markdown", + "dataFileName": "Script bundles.md", "attachments": [] } ] @@ -12815,7 +17475,7 @@ "GLks18SNjxmC" ], "title": "Script API", - "notePosition": 90, + "notePosition": 110, "prefix": null, "isExpanded": false, "type": "text", @@ -12848,6 +17508,13 @@ "value": "script-api", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-code-curly", + "isInheritable": false, + "position": 40 } ], "format": "markdown", @@ -12874,9 +17541,16 @@ { "type": "label", "name": "webViewSrc", - "value": "https://triliumnext.github.io/Notes/Script%20API/interfaces/Frontend_Script_API.Api.html", + "value": "/script-api/frontend", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "frontend-api", + "isInheritable": false, + "position": 20 } ], "attachments": [], @@ -12902,9 +17576,16 @@ { "type": "label", "name": "webViewSrc", - "value": "https://triliumnext.github.io/Notes/Script%20API/classes/Frontend_Script_API.FNote.html", + "value": "/script-api/frontend/interfaces/FNote.html", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "fnote", + "isInheritable": false, + "position": 20 } ], "dataFileName": "FNote.dat", @@ -12931,13 +17612,300 @@ { "type": "label", "name": "webViewSrc", - "value": "https://triliumnext.github.io/Notes/Script%20API/interfaces/Backend_Script_API.Api.html", + "value": "/script-api/backend", "isInheritable": false, "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "backend-api", + "isInheritable": false, + "position": 20 } ], "dataFileName": "Backend API.dat", "attachments": [] + }, + { + "isClone": false, + "noteId": "ApVHZ8JY5ofC", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "GLks18SNjxmC", + "ApVHZ8JY5ofC" + ], + "title": "Day.js", + "notePosition": 30, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "day.js", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-calendar", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Day.js.md", + "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "vElnKeDNPSVl", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "vElnKeDNPSVl" + ], + "title": "Logging", + "notePosition": 120, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "bnyigUA2UK7s", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-terminal", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "shareAlias", + "value": "logging", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Logging.md", + "attachments": [ + { + "attachmentId": "OFVZwVeITJOR", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Logging_image.png" + } + ] + }, + { + "isClone": false, + "noteId": "cNpC0ITcfX0N", + "notePath": [ + "pOsGYCXsbNQG", + "CdNpE2pqjmI6", + "cNpC0ITcfX0N" + ], + "title": "Breaking changes", + "notePosition": 130, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-up-arrow-alt", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "shareAlias", + "value": "breaking-changes", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "dataFileName": "Breaking changes.md", + "attachments": [] + } + ] + }, + { + "isClone": false, + "noteId": "Fm0j45KqyHpU", + "notePath": [ + "pOsGYCXsbNQG", + "Fm0j45KqyHpU" + ], + "title": "Miscellaneous", + "notePosition": 370, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "misc", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-info-circle", + "isInheritable": false, + "position": 40 + } + ], + "format": "markdown", + "attachments": [], + "dirFileName": "Miscellaneous", + "children": [ + { + "isClone": false, + "noteId": "WFbFXrgnDyyU", + "notePath": [ + "pOsGYCXsbNQG", + "Fm0j45KqyHpU", + "WFbFXrgnDyyU" + ], + "title": "Privacy Policy", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "shareAlias", + "value": "privacy-policy", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Privacy Policy.md", + "attachments": [] + }, + { + "isClone": false, + "noteId": "NcsmUYZRWEW4", + "notePath": [ + "pOsGYCXsbNQG", + "Fm0j45KqyHpU", + "NcsmUYZRWEW4" + ], + "title": "Patterns of personal knowledge", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "xYjQUYhpbUEW", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "IakOLONlIfGI", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CdNpE2pqjmI6", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "R7abl2fc6Mxi", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "bwg0e8ewQMak", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "iRwzGnHPzonm", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "OFXdgB2nNk1F", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "cbkrhQjrkKrh", + "isInheritable": false, + "position": 90 + }, + { + "type": "label", + "name": "shareAlias", + "value": "patterns-of-personal-knowledge", + "isInheritable": false, + "position": 120 + } + ], + "format": "markdown", + "dataFileName": "Patterns of personal knowledge.md", + "attachments": [ + { + "attachmentId": "amErpd38VEdQ", + "title": "relation-map-family.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Patterns of personal knowl.png" } ] } diff --git a/docs/User Guide/User Guide.md b/docs/User Guide/User Guide.md index 509f4b7b57..ce5357b26e 100644 --- a/docs/User Guide/User Guide.md +++ b/docs/User Guide/User Guide.md @@ -1,2 +1,25 @@ # User Guide -The sub-children of this note are automatically synced. \ No newline at end of file +Trilium is an open-source solution for note-taking and organizing a personal knowledge base. Use it locally on your desktop, or sync it with your self-hosted server to keep your notes everywhere you go. + +> [!TIP] +> The same documentation can be accessed locally from within the Trilium Notes application by pressing F1. + +## Getting started + +1. SeeĀ Quick Start. +2. Go throughĀ Basic Concepts and Features. +3. UnderstandĀ Notes. +4. Browse throughĀ Collections. + +## Quick links + +* Desktop Installation +* Server Installation +* Frontend APIĀ orĀ [missing note] +* [ETAPI reference](User%20Guide/Advanced%20Usage/ETAPI%20\(REST%20API\)/API%20Reference.dat) + +## External links + +* The [Trilium Notes website](https://triliumnotes.org/), for a quick presentation of the application. +* [Developer Guide](https://docs.triliumnotes.org/developer-guide/), to understand the architecture and processes behind the development of Trilium Notes. +* [GitHub Repository (TriliumNext/Trilium)](https://github.com/TriliumNext/Trilium/) \ No newline at end of file diff --git a/docs/User Guide/User Guide/AI.md b/docs/User Guide/User Guide/AI.md new file mode 100644 index 0000000000..4ca2d07abd --- /dev/null +++ b/docs/User Guide/User Guide/AI.md @@ -0,0 +1,18 @@ +# AI +Starting with version v0.102.0, AI/LLM integration has been removed from the Trilium Notes core. + +While a significant amount of effort went into developing this feature, maintaining and supporting it long-term proved to be unsustainable. + +When upgrading to v0.102.0, your Chat notes will be preserved, but instead of the dedicated chat window they will be turned to a normalĀ CodeĀ note, revealing the underlying JSON of the conversation. + +## Alternative solutions (MCP) + +Given the recent advancements of the AI scene, MCP has grown to be more powerful and facilitates easier integrations with various application. + +As such, there are third-party solutions that integrate an MCP server that can be used with Trilium: + +* [tan-yong-sheng/triliumnext-mcp](https://github.com/tan-yong-sheng/triliumnext-mcp) +* [perfectra1n/triliumnext-mcp](https://github.com/perfectra1n/triliumnext-mcp) + +> [!IMPORTANT] +> These solutions are third-party and thus not endorsed or supported directly by the Trilium Notes team. Please address questions and issues on their corresponding repository instead. \ No newline at end of file diff --git a/docs/User Guide/User Guide/AI/1_AI Provider Information_im.png b/docs/User Guide/User Guide/AI/1_AI Provider Information_im.png deleted file mode 100644 index 80627e0b02..0000000000 Binary files a/docs/User Guide/User Guide/AI/1_AI Provider Information_im.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/1_Introduction_image.png b/docs/User Guide/User Guide/AI/1_Introduction_image.png deleted file mode 100644 index c0955f2bff..0000000000 Binary files a/docs/User Guide/User Guide/AI/1_Introduction_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/2_Introduction_image.png b/docs/User Guide/User Guide/AI/2_Introduction_image.png deleted file mode 100644 index 3908a5f48f..0000000000 Binary files a/docs/User Guide/User Guide/AI/2_Introduction_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/3_Introduction_image.png b/docs/User Guide/User Guide/AI/3_Introduction_image.png deleted file mode 100644 index 0fe0c81860..0000000000 Binary files a/docs/User Guide/User Guide/AI/3_Introduction_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/4_Introduction_image.png b/docs/User Guide/User Guide/AI/4_Introduction_image.png deleted file mode 100644 index ef2ad8a0f4..0000000000 Binary files a/docs/User Guide/User Guide/AI/4_Introduction_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/5_Introduction_image.png b/docs/User Guide/User Guide/AI/5_Introduction_image.png deleted file mode 100644 index ede9d6aaee..0000000000 Binary files a/docs/User Guide/User Guide/AI/5_Introduction_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/6_Introduction_image.png b/docs/User Guide/User Guide/AI/6_Introduction_image.png deleted file mode 100644 index e784df790b..0000000000 Binary files a/docs/User Guide/User Guide/AI/6_Introduction_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/7_Introduction_image.png b/docs/User Guide/User Guide/AI/7_Introduction_image.png deleted file mode 100644 index 96d56b39c5..0000000000 Binary files a/docs/User Guide/User Guide/AI/7_Introduction_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/8_Introduction_image.png b/docs/User Guide/User Guide/AI/8_Introduction_image.png deleted file mode 100644 index afb6653ca0..0000000000 Binary files a/docs/User Guide/User Guide/AI/8_Introduction_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/9_Introduction_image.png b/docs/User Guide/User Guide/AI/9_Introduction_image.png deleted file mode 100644 index f50f695536..0000000000 Binary files a/docs/User Guide/User Guide/AI/9_Introduction_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/AI Provider Information.md b/docs/User Guide/User Guide/AI/AI Provider Information.md deleted file mode 100644 index 333dcd184e..0000000000 --- a/docs/User Guide/User Guide/AI/AI Provider Information.md +++ /dev/null @@ -1,15 +0,0 @@ -# AI Provider Information -Currently, we support the following providers: - -* Ollama -* OpenAI -* Anthropic -* Voyage AI - -To set your preferred chat model, you'll want to enter the provider's name here: - -
    - -And to set your preferred embedding provider: - -
    \ No newline at end of file diff --git a/docs/User Guide/User Guide/AI/AI Provider Information/Anthropic.md b/docs/User Guide/User Guide/AI/AI Provider Information/Anthropic.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/1_Installing Ollama_image.png b/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/1_Installing Ollama_image.png deleted file mode 100644 index 821966b770..0000000000 Binary files a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/1_Installing Ollama_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/2_Installing Ollama_image.png b/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/2_Installing Ollama_image.png deleted file mode 100644 index 7e585a7513..0000000000 Binary files a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/2_Installing Ollama_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/3_Installing Ollama_image.png b/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/3_Installing Ollama_image.png deleted file mode 100644 index 0a239f35cb..0000000000 Binary files a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/3_Installing Ollama_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/4_Installing Ollama_image.png b/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/4_Installing Ollama_image.png deleted file mode 100644 index b5c4c2930d..0000000000 Binary files a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/4_Installing Ollama_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/5_Installing Ollama_image.png b/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/5_Installing Ollama_image.png deleted file mode 100644 index 0c02db50f9..0000000000 Binary files a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/5_Installing Ollama_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/Installing Ollama.md b/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/Installing Ollama.md deleted file mode 100644 index 650ac76e91..0000000000 --- a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/Installing Ollama.md +++ /dev/null @@ -1,25 +0,0 @@ -# Installing Ollama -[Ollama](https://ollama.com/) can be installed in a variety of ways, and even runs [within a Docker container](https://hub.docker.com/r/ollama/ollama). Ollama will be noticeably quicker when running on a GPU (Nvidia, AMD, Intel), but it can run on CPU and RAM. To install Ollama without any other prerequisites, you can follow their [installer](https://ollama.com/download): - -
    - -After their installer completes, if you're on Windows, you should see an entry in the start menu to run it: - -
    - -Also, you should have access to the `ollama` CLI via Powershell or CMD: - -
    - -After Ollama is installed, you can go ahead and `pull` the models you want to use and run. Here's a command to pull my favorite tool-compatible model and embedding model as of April 2025: - -``` -ollama pull llama3.1:8b -ollama pull mxbai-embed-large -``` - -Also, you can make sure it's running by going to [http://localhost:11434](http://localhost:11434) and you should get the following response (port 11434 being the ā€œnormalā€ Ollama port): - -
    - -Now that you have Ollama up and running, have a few models pulled, you're ready to go to go ahead and start using Ollama as both a chat provider, and embedding provider! \ No newline at end of file diff --git a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/Installing Ollama_image.png b/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/Installing Ollama_image.png deleted file mode 100644 index cf5ee38d4c..0000000000 Binary files a/docs/User Guide/User Guide/AI/AI Provider Information/Ollama/Installing Ollama_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/AI Provider Information/OpenAI.md b/docs/User Guide/User Guide/AI/AI Provider Information/OpenAI.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/User Guide/User Guide/AI/AI Provider Information_im.png b/docs/User Guide/User Guide/AI/AI Provider Information_im.png deleted file mode 100644 index aa19e949d8..0000000000 Binary files a/docs/User Guide/User Guide/AI/AI Provider Information_im.png and /dev/null differ diff --git a/docs/User Guide/User Guide/AI/Introduction.md b/docs/User Guide/User Guide/AI/Introduction.md deleted file mode 100644 index 5591e08343..0000000000 --- a/docs/User Guide/User Guide/AI/Introduction.md +++ /dev/null @@ -1,89 +0,0 @@ -# Introduction -
    An example chat with an LLM
    - -The AI / LLM features within Trilium Notes are designed to allow you to interact with your Notes in a variety of ways, using as many of the major providers as we can support.Ā  - -In addition to being able to send chats to LLM providers such as OpenAI, Anthropic, and Ollama - we also support agentic tool calling, and embeddings. - -The quickest way to get started is to navigate to the ā€œAI/LLMā€ settings: - -
    - -Enable the feature: - -
    - -## Embeddings - -**Embeddings** are important as it allows us to have an compact AI ā€œsummaryā€ (it's not human readable text) of each of your Notes, that we can then perform mathematical functions on (such as cosine similarity) to smartly figure out which Notes to send as context to the LLM when you're chatting, among other useful functions. - -You will then need to set up the AI ā€œproviderā€ that you wish to use to create the embeddings for your Notes. Currently OpenAI, Voyage AI, and Ollama are supported providers for embedding generation. - -In the following example, we're going to use our self-hosted Ollama instance to create the embeddings for our Notes. You can see additional documentation about installing your own Ollama locally inĀ Installing Ollama. - -To see what embedding models Ollama has available, you can check out [this search](https://ollama.com/search?c=embedding)on their website, and then `pull` whichever one you want to try out. As of 4/15/25, my personal favorite is `mxbai-embed-large`. - -First, we'll need to select the Ollama provider from the tabs of providers, then we will enter in the Base URL for our Ollama. Since our Ollama is running on our local machine, our Base URL is `http://localhost:11434`. We will then hit the ā€œrefreshā€ button to have it fetch our models: - -
    - -When selecting the dropdown for the ā€œEmbedding Modelā€, embedding models should be at the top of the list, separated by regular chat models with a horizontal line, as seen below: - -
    - -After selecting an embedding model, embeddings should automatically begin to be generated by checking the embedding statistics at the top of the ā€œAI/LLMā€ settings panel: - -
    - -If you don't see any embeddings being created, you will want to scroll to the bottom of the settings, and hit ā€œRecreate All Embeddingsā€: - -
    - -Creating the embeddings will take some time, and will be regenerated when a Note is created, updated, or deleted (removed). - -If for some reason you choose to change your embedding provider, or the model used, you'll need to recreate all embeddings. - -## Tools - -Tools are essentially functions that we provide to the various LLM providers, and then LLMs can respond in a specific format that tells us what tool function and parameters they would like to invoke. We then execute these tools, and provide it as additional context in the Chat conversation.Ā  - -These are the tools that currently exist, and will certainly be updated to be more effectively (and even more to be added!): - -* `search_notes` - * Semantic search -* `keyword_search` - * Keyword-based search -* `attribute_search` - * Attribute-specific search -* `search_suggestion` - * Search syntax helper -* `read_note` - * Read note content (helps the LLM read Notes) -* `create_note` - * Create a Note -* `update_note` - * Update a Note -* `manage_attributes` - * Manage attributes on a Note -* `manage_relationships` - * Manage the various relationships between Notes -* `extract_content` - * Used to smartly extract content from a Note -* `calendar_integration` - * Used to find date notes, create date notes, get the daily note, etc. - -When Tools are executed within your Chat, you'll see output like the following: - -
    - -You don't need to tell the LLM to execute a certain tool, it should ā€œsmartlyā€ call tools and automatically execute them as needed. - -## Overview - -Now that you know about embeddings and tools, you can just go ahead and use the ā€œChat with Notesā€ button, where you can go ahead and start chatting!: - -
    - -If you don't see the ā€œChat with Notesā€ button on your side launchbar, you might need to move it from the ā€œAvailable Launchersā€ section to the ā€œVisible Launchersā€ section: - -
    \ No newline at end of file diff --git a/docs/User Guide/User Guide/AI/Introduction_image.png b/docs/User Guide/User Guide/AI/Introduction_image.png deleted file mode 100644 index 5a8657faf8..0000000000 Binary files a/docs/User Guide/User Guide/AI/Introduction_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Advanced Usage/Advanced Showcases/Task Manager.md b/docs/User Guide/User Guide/Advanced Usage/Advanced Showcases/Task Manager.md index 20cf37c5ef..13a4a5d949 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Advanced Showcases/Task Manager.md +++ b/docs/User Guide/User Guide/Advanced Usage/Advanced Showcases/Task Manager.md @@ -15,7 +15,7 @@ New tasks are created in the TODO note which has `~child:template` [relation](.. ### Attributes -Task template defines several [promoted attributes](../Attributes/Promoted%20Attributes.md) - todoDate, doneDate, tags, location. Importantly it also defines `~runOnAttributeChange` relation - [event](../../Scripting/Events.md) handler which is run on attribute change. This [script](../../Scripting.md) handles when e.g. we fill out the doneDate attribute - meaning the task is done and should be moved to "Done" note and removed from TODO, locations and tags. +Task template defines several [promoted attributes](../Attributes/Promoted%20Attributes.md) - todoDate, doneDate, tags, location. Importantly it also defines `~runOnAttributeChange` relation - [event](../../Scripting/Backend%20scripts/Events.md) handler which is run on attribute change. This [script](../../Scripting.md) handles when e.g. we fill out the doneDate attribute - meaning the task is done and should be moved to "Done" note and removed from TODO, locations and tags. ### New task button diff --git a/docs/User Guide/User Guide/Advanced Usage/Attributes.md b/docs/User Guide/User Guide/Advanced Usage/Attributes.md index 1cfe040d87..22ca0c33f9 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Attributes.md +++ b/docs/User Guide/User Guide/Advanced Usage/Attributes.md @@ -3,14 +3,25 @@ In Trilium, attributes are key-value pairs assigned to notes, providing additional metadata or functionality. There are two primary types of attributes: -1. LabelsĀ can be used for a variety of purposes, such as storing metadata or configuring the behaviour of notes. Labels are also searchable, enhancing note retrieval. +1. LabelsĀ can be used for a variety of purposes, such as storing metadata or configuring the behavior of notes. Labels are also searchable, enhancing note retrieval. For more information, including predefined labels, seeĀ Labels. 2. RelationsĀ define connections between notes, similar to links. These can be used for metadata and scripting purposes. For more information, including a list of predefined relations, seeĀ Relations. -These attributes play a crucial role in organizing, categorising, and enhancing the functionality of notes. +These attributes play a crucial role in organizing, categorizing, and enhancing the functionality of notes. + +## Types of attributes + +Conceptually there are two types of attributes (applying to both labels and relations): + +1. **System attributes** + As the name suggest, these attributes have a special meaning since they are interpreted by Trilium. For example the `color` attribute will change the color of the note as displayed in theĀ Note TreeĀ and links, and `iconClass` will change the icon of a note. +2. **User-defined attributes** + These are free-form labels or relations that can be used by the user. They can be used purely for categorization purposes (especially if combined withĀ Search), or they can be given meaning through the use ofĀ Scripting. + +In practice, Trilium makes no direct distinction of whether an attribute is a system one or a user-defined one. A label or relation is considered a system attribute if it matches one of the built-in names (e.g. like the aforementioned `iconClass`). Keep this in mind when creating Ā Promoted AttributesĀ in order not to accidentally alter a system attribute (unless intended). ## Viewing the list of attributes @@ -18,13 +29,13 @@ Both the labels and relations for the current note are displayed in the _Owned A In the list of attributes, labels are prefixed with the `#` character whereas relations are prefixed with the `~` character. -## Multiplicity - -Attributes in Trilium can be "multi-valued", meaning multiple attributes with the same name can co-exist. - ## Attribute Definitions and Promoted Attributes -Special labels create "label/attribute" definitions, enhancing the organization and management of attributes. For more details, seeĀ Promoted Attributes. +Promoted AttributesĀ create a form-like editing experience for attributes, which makes it easy to enhancing the organization and management of attributes + +## Multiplicity + +Attributes in Trilium can be "multi-valued", meaning multiple attributes with the same name can co-exist. This can be combined withĀ Promoted AttributesĀ to easily add them. ## Attribute Inheritance diff --git a/docs/User Guide/User Guide/Advanced Usage/Attributes/1_Promoted Attributes_image.png b/docs/User Guide/User Guide/Advanced Usage/Attributes/1_Promoted Attributes_image.png new file mode 100644 index 0000000000..64863ded05 Binary files /dev/null and b/docs/User Guide/User Guide/Advanced Usage/Attributes/1_Promoted Attributes_image.png differ diff --git a/docs/User Guide/User Guide/Advanced Usage/Attributes/2_Promoted Attributes_image.png b/docs/User Guide/User Guide/Advanced Usage/Attributes/2_Promoted Attributes_image.png new file mode 100644 index 0000000000..c7510ca73b Binary files /dev/null and b/docs/User Guide/User Guide/Advanced Usage/Attributes/2_Promoted Attributes_image.png differ diff --git a/docs/User Guide/User Guide/Advanced Usage/Attributes/3_Promoted Attributes_image.png b/docs/User Guide/User Guide/Advanced Usage/Attributes/3_Promoted Attributes_image.png new file mode 100644 index 0000000000..f71526395d Binary files /dev/null and b/docs/User Guide/User Guide/Advanced Usage/Attributes/3_Promoted Attributes_image.png differ diff --git a/docs/User Guide/User Guide/Advanced Usage/Attributes/Labels.md b/docs/User Guide/User Guide/Advanced Usage/Attributes/Labels.md index 53307238fd..89f1445ecd 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Attributes/Labels.md +++ b/docs/User Guide/User Guide/Advanced Usage/Attributes/Labels.md @@ -39,4 +39,4 @@ This is a list of labels that Trilium natively supports. > [!TIP] > Some labels presented here end with a `*`. That means that there are multiple labels with the same prefix, consult the specific page linked in the description of that label for more information. -
    LabelDescription
    disableVersioningDisables automatic creation of Note Revisions for a particular note. Useful for e.g. large, but unimportant notes - e.g. large JS libraries used for scripting.
    versioningLimitLimits the maximum number of Note Revisions for a particular note, overriding the global settings.
    calendarRootMarks the note which should be used as root for Day Notes. Only one should be marked as such.
    archivedHides notes from default search results and dialogs. Archived notes can optionally be hidden in the Note Tree.
    excludeFromExportExcludes this note and its children when exporting.
    run, runOnInstance, runAtHourSee Events.
    disableInclusionScripts with this label won't be included into parent script execution.
    sorted

    Keeps child notes sorted by title alphabetically.

    When given a value, it will sort by the value of another label instead. If one of the child notes doesn't have the specified label, the title will be used for them instead.

    sortDirection

    If sorted is applied, specifies the direction of the sort:

    • ASC, ascending (default)
    • DESC, descending
    sortFoldersFirstIf sorted is applied, folders (notes with children) will be sorted as a group at the top, and the rest will be sorted.
    topIf sorted is applied to the parent note, keeps given note on top in its parent.
    hidePromotedAttributesHide Promoted Attributes on this note. Generally useful when defining inherited attributes, but the parent note doesn't need them.
    readOnlyMarks a note to be always be read-only, if it's a supported note (text, code, mermaid).
    autoReadOnlyDisabledDisables automatic read-only mode for the given note.
    appCssMarks CSS notes which are loaded into the Trilium application and can thus be used to modify Trilium's looks. See Custom app-wide CSS for more info.
    appThemeMarks CSS notes which are full Trilium themes and are thus available in Trilium options. See Theme development for more information.
    appThemeBaseSet to next, next-light, or next-dark to use the corresponding TriliumNext theme (auto, light or dark) as the base for a custom theme, instead of the legacy one. See Customize the Next theme for more information.
    cssClassValue of this label is then added as CSS class to the node representing given note in the Note Tree. This can be useful for advanced theming. Can be used in template notes.
    iconClassvalue of this label is added as a CSS class to the icon on the tree which can help visually distinguish the notes in the tree. Example might be bx bx-home - icons are taken from boxicons. Can be used in template notes.
    pageSizeSpecifies the number of items per page in Note List.
    customRequestHandlerSee Custom Request Handler.
    customResourceProviderSee Custom Resource Providers.
    widgetMarks this note as a custom widget which will be added to the Trilium component tree. See Custom Widgets for more information.
    searchHomeNew search notes will be created as children of this note (see Saved Search).
    workspace and related attributesSee Workspaces.
    inboxdefault inbox location for new notes - when you create a note using new note button in the sidebar, notes will be created as child notes in the note marked as with #inbox label.
    sqlConsoleHomeDefault location of SQL Console notes
    bookmarkedIndicates this note is a bookmark.
    bookmarkFolderNote with this label will appear in bookmarks as folder (allowing access to its children). See Bookmarks for more information.
    share*See the attribute reference in Sharing.
    displayRelations, hideRelationsComma delimited names of relations which should be displayed/hidden in a Relation Map (both the note type and the Note Map (Link map, Tree map) general functionality).
    titleTemplate

    Default title of notes created as children of this note. This value is evaluated as a JavaScript string and thus can be enriched with dynamic content via the injected now and parentNote variables.

    Examples:

    • \({parentNote.getLabel('authorName')}'s literary works
    • Log for \){now.format('YYYY-MM-DD HH:mm:ss')}
    • to mirror the parent's template.

    See Default Note Title for more info.

    templateThis note will appear in the selection of available template when creating new note. See Templates for more information.
    tocControls the display of the Table of contents for a given note. #toc or #toc=show to always display the table of contents, #toc=false to always hide it.
    colordefines color of the note in note tree, links etc. Use any valid CSS color value like 'red' or #a13d5f
    keyboardShortcutDefines a keyboard shortcut which will immediately jump to this note. Example: 'ctrl+alt+e'. Requires frontend reload for the change to take effect.
    keepCurrentHoistingOpening this link won't change hoisting even if the note is not displayable in the current hoisted subtree.
    executeButtonTitle of the button which will execute the current code note
    executeDescriptionLonger description of the current code note displayed together with the execute button
    excludeFromNoteMapNotes with this label will be hidden from the Note Map.
    newNotesOnTopNew notes will be created at the top of the parent note, not on the bottom.
    hideHighlightWidgetHides the Highlights list widget
    hideChildrenOverviewHides the Note List for that particular note.
    printLandscapeWhen exporting to PDF, changes the orientation of the page to landscape instead of portrait.
    printPageSizeWhen exporting to PDF, changes the size of the page. Supported values: A0, A1, A2, A3, A4, A5, A6, Legal, Letter, Tabloid, Ledger.
    geolocationIndicates the latitude and longitude of a note, to be displayed in a Geo Map.
    calendar:*Defines specific options for the Calendar View.
    viewTypeSets the view of child notes (e.g. grid or list). See Note List for more information.
    \ No newline at end of file +
    LabelDescription
    disableVersioningDisables automatic creation of Note Revisions for a particular note. Useful for e.g. large, but unimportant notes - e.g. large JS libraries used for scripting.
    versioningLimitLimits the maximum number of Note Revisions for a particular note, overriding the global settings.
    calendarRootMarks the note which should be used as root for Day Notes. Only one should be marked as such.
    archivedHides notes from default search results and dialogs. Archived notes can optionally be hidden in the Note Tree.
    excludeFromExportExcludes this note and its children when exporting.
    run, runOnInstance, runAtHourSee Events.
    disableInclusionScripts with this label won't be included into parent script execution.
    sorted

    Keeps child notes sorted by title alphabetically.

    When given a value, it will sort by the value of another label instead. If one of the child notes doesn't have the specified label, the title will be used for them instead.

    sortDirection

    If sorted is applied, specifies the direction of the sort:

    • ASC, ascending (default)
    • DESC, descending
    sortFoldersFirstIf sorted is applied, folders (notes with children) will be sorted as a group at the top, and the rest will be sorted.
    topIf sorted is applied to the parent note, keeps given note on top in its parent.
    hidePromotedAttributesHide Promoted Attributes on this note. Generally useful when defining inherited attributes, but the parent note doesn't need them.
    readOnlyMarks a note to be always be read-only, if it's a supported note (text, code, mermaid).
    autoReadOnlyDisabledDisables automatic read-only mode for the given note.
    appCssMarks CSS notes which are loaded into the Trilium application and can thus be used to modify Trilium's looks. See Custom app-wide CSS for more info.
    appThemeMarks CSS notes which are full Trilium themes and are thus available in Trilium options. See Theme development for more information.
    appThemeBaseSet to next, next-light, or next-dark to use the corresponding TriliumNext theme (auto, light or dark) as the base for a custom theme, instead of the legacy one. See Customize the Next theme for more information.
    cssClassValue of this label is then added as CSS class to the node representing given note in the Note Tree. This can be useful for advanced theming. Can be used in template notes.
    iconClassvalue of this label is added as a CSS class to the icon on the tree which can help visually distinguish the notes in the tree. Example might be bx bx-home - icons are taken from boxicons. Can be used in template notes.
    pageSizeSpecifies the number of items per page in Note List.
    customRequestHandlerSee Custom Request Handler.
    customResourceProviderSee Custom Resource Providers.
    widgetMarks this note as a custom widget which will be added to the Trilium component tree. See Custom Widgets for more information.
    searchHomeNew search notes will be created as children of this note (see Saved Search).
    workspace and related attributesSee Workspaces.
    inboxdefault inbox location for new notes - when you create a note using new note button in the sidebar, notes will be created as child notes in the note marked as with #inbox label.
    sqlConsoleHomeDefault location of SQL Console notes
    bookmarkedIndicates this note is a bookmark.
    bookmarkFolderNote with this label will appear in bookmarks as folder (allowing access to its children). See Bookmarks for more information.
    share*See the attribute reference in Sharing.
    displayRelations, hideRelationsComma delimited names of relations which should be displayed/hidden in a Relation Map (both the note type and the Note Map (Link map, Tree map) general functionality).
    titleTemplate

    Default title of notes created as children of this note. This value is evaluated as a JavaScript string and thus can be enriched with dynamic content via the injected now and parentNote variables.

    Examples:

    • \({parentNote.getLabel('authorName')}'s literary works
    • Log for \){now.format('YYYY-MM-DD HH:mm:ss')}
    • to mirror the parent's template.

    See Default Note Title for more info.

    templateThis note will appear in the selection of available template when creating new note. See Templates for more information.
    tocControls the display of the Table of contents for a given note. #toc or #toc=show to always display the table of contents, #toc=false to always hide it.
    colordefines color of the note in note tree, links etc. Use any valid CSS color value like 'red' or #a13d5f
    Note: this color may be automatically adjusted when displayed to ensure sufficient contrast with the background.
    keyboardShortcutDefines a keyboard shortcut which will immediately jump to this note. Example: 'ctrl+alt+e'. Requires frontend reload for the change to take effect.
    keepCurrentHoistingOpening this link won't change hoisting even if the note is not displayable in the current hoisted subtree.
    executeButtonTitle of the button which will execute the current code note
    executeDescriptionLonger description of the current code note displayed together with the execute button
    excludeFromNoteMapNotes with this label will be hidden from the Note Map.
    newNotesOnTopNew notes will be created at the top of the parent note, not on the bottom.
    hideHighlightWidgetHides the Highlights list widget
    hideChildrenOverviewHides the Note List for that particular note.
    subtreeHiddenHides all child notes of this note from the tree, displaying a badge with the count of hidden children. Children remain accessible via search or direct links.
    printLandscapeWhen exporting to PDF, changes the orientation of the page to landscape instead of portrait.
    printPageSizeWhen exporting to PDF, changes the size of the page. Supported values: A0, A1, A2, A3, A4, A5, A6, Legal, Letter, Tabloid, Ledger.
    geolocationIndicates the latitude and longitude of a note, to be displayed in a Geo Map.
    map:*Defines specific options for the Geo Map.
    calendar:*Defines specific options for the Calendar View.
    viewTypeSets the view of child notes (e.g. grid or list). See Note List for more information.
    \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes.md b/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes.md index dab0a80865..2759c21abc 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes.md +++ b/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes.md @@ -1,31 +1,74 @@ # Promoted Attributes -Promoted attributes are [attributes](../Attributes.md) which are considered important and thus are "promoted" onto the main note UI. See example below: +
    -![](Promoted%20Attributes_promot.png) +Promoted attributes are [attributes](../Attributes.md) which are displayed prominently in the UI which allow them to be easily viewed and edited. -You can see the note having kind of form with several fields. Each of these is just regular attribute, the only difference is that they appear on the note itself. +One way of seeing promoted attributes is as a kind of form with several fields. Each field is just regular attribute, the only difference is that they appear on the note itself. Attributes can be pretty useful since they allow for querying and script automation etc. but they are also inconveniently hidden. This allows you to select few of the important ones and push them to the front of the user. -Now, how do we make attribute to appear on the UI? - ## Attribute definition -Attribute is always name-value pair where both name and value are strings. +In order to have promoted attributes, there needs to be a way to define them. -_Attribute definition_ specifies how should this value be interpreted - is it just string, or is it a date? Should we allow multiple values or note? And importantly, should we _promote_ the attribute or not? +
    -![](Promoted%20Attributes_image.png) +Technically, attributes are only name-value pairs where both name and value are strings. -You can notice tag attribute definition. These "definition" attributes define how the "value" attributes should behave. +The _Attribute definition_ specifies how should this value be interpreted: -So there's one attribute for value and one for definition. But notice how definition attribute is [Inheritable](Attribute%20Inheritance.md), meaning that it's also applied to all descendant note. So in a way, this definition is used for the whole subtree while "value" attributes are applied only for this note. +* Is it just string, or is it a date? +* Should we allow multiple values or note? +* Should we _promote_ the attribute or not? + +## Creating a new promoted attribute definition + +To create a new promoted attribute: + +1. Go to a note. +2. Go to _Owned Attributes_ in theĀ Ribbon. +3. Press the + button. +4. Select either _Add new label definition_ or _Add new relation definition_. +5. Select the name which will be name of the label or relation that will be created when the promoted attribute is edited. +6. Ensure _Promoted_ is checked in order to display it at the top of notes. +7. Optionally, choose an _Alias_ which will be displayed next to the promoted attribute instead of the attribute name. Generally it's best to choose a ā€œuser-friendlyā€ name since it can contain spaces and other characters which are not supported as attribute names. +8. Check _Inheritable_ to apply it to this note and all its descendants. To keep it only for the current note, un-check it. +9. Press ā€œSave & Closeā€ to apply the changes. + +## How attribute definitions actually work + +When a new promoted attribute definition is created, it creates a corresponding label prefixed with either `label` or `relation`, depending on the definition type: + +``` +#label:myColor(inheritable)="promoted,alias=Color,multi,color" +``` + +The only purpose of the attribute definition is to set up a template. If the attribute was marked as promoted, then it's also displayed to the user for easy editing. + +| | | +| --- | --- | +|
    | Notice how the promoted attribute definition only creates a ā€œDue dateā€ box above the text content. | +|
    | Once a value is set by the user, a new label (or relation, depending on the type) is created. The name of the attribute matches one set when creating the promoted attribute. | + +So there's one attribute for value and one for definition. But notice how an definition attribute can be made [Inheritable](Attribute%20Inheritance.md), meaning that it's also applied to all descendant notes. In this case, the definition used for the whole sub-tree while "value" attributes are for each not individually. + +## Using system attributes + +It's possible to create promoted attributes out of system attributes, to be able to easily alter them. + +Here are a few practical examples: + +* CollectionsĀ already make use of this practice, for example: + * Calendars add ā€œStart Dateā€, ā€œEnd Dateā€, ā€œStart Timeā€ and ā€œEnd Timeā€ as promoted attributes. These map to system attributes such as `startDate` which are then interpreted by the calendar view. + * PresentationĀ adds a ā€œBackgroundā€ promoted attribute for each of the slide to easily be able to customize. +* The Trilium documentation (which is edited in Trilium) uses a promoted attribute to be able to easily edit the `#shareAlias` (seeĀ Sharing) in order to form clean URLs. +* If you always edit a particular system attribute such as `#color`, simply create a promoted attribute for it to make it easier. ### Inverse relation Some relations always occur in pairs - my favorite example is on the family. If you have a note representing husband and note representing wife, then there might be a relation between those two of `isPartnerOf`. This is bidirectional relationship - meaning that if a relation is pointing from husband to wife then there should be always another relation pointing from wife to husband. -Another example is with parent - child relationship. Again these always occur in pairs, but in this case it's not exact same relation - the one going from parent to child might be called `isParentOf` and the other one going from child to parent might be called `isChildOf`. +Another example is with parent-child relationship. Again these always occur in pairs, but in this case it's not exact same relation - the one going from parent to child might be called `isParentOf` and the other one going from child to parent might be called `isChildOf`. Relation definition allows you to specify such "inverse relation" - for the relation you just define you specify which is the inverse relation. Note that in the second example we should have two relation definitions - one for `isParentOf` which defines `isChildOf` as inverse relation and then second relation definition for `isChildOf` which defines `isParentOf` as inverse relation. diff --git a/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes_image.png b/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes_image.png index ecb5f2d6d7..148f98b8af 100644 Binary files a/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes_image.png and b/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes_image.png differ diff --git a/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes_promot.png b/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes_promot.png deleted file mode 100644 index cca8683201..0000000000 Binary files a/docs/User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes_promot.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Advanced Usage/Attributes/Relations.md b/docs/User Guide/User Guide/Advanced Usage/Attributes/Relations.md index 2916640ecb..6e1e9aa1fa 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Attributes/Relations.md +++ b/docs/User Guide/User Guide/Advanced Usage/Attributes/Relations.md @@ -43,12 +43,13 @@ These relations are supported and used internally by Trilium. | Label | Description | | --- | --- | -| `runOn*` | SeeĀ Events | +| `runOn*` | SeeĀ Events | | `template` | note's attributes will be inherited even without a parent-child relationship, note's content and subtree will be added to instance notes if empty. See documentation for details. | | `inherit` | note's attributes will be inherited even without a parent-child relationship. SeeĀ TemplatesĀ for a similar concept. SeeĀ Attribute InheritanceĀ in the documentation. | | `renderNote` | notes of typeĀ Render NoteĀ will be rendered using a code note (HTML or script) and it is necessary to point using this relation to which note should be rendered | | `widget_relation` | target of this relation will be executed and rendered as a widget in the sidebar | | `shareCss` | CSS note which will be injected into the share page. CSS note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree` and `share_omit_default_css` as well. | | `shareJs` | JavaScript note which will be injected into the share page. JS note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree`. | +| `shareHtml` | HTML note which will be injected into the share page at locations specified by the `shareHtmlLocation` label. HTML note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree`. | | `shareTemplate` | Embedded JavaScript note that will be used as the template for displaying the shared note. Falls back to the default template. Consider using `share_hidden_from_tree`. | | `shareFavicon` | Favicon note to be set in the shared page. Typically you want to set it to share root and make it inheritable. Favicon note must be in the shared sub-tree as well. Consider using `share_hidden_from_tree`. | \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/Configuration (config.ini or e.md b/docs/User Guide/User Guide/Advanced Usage/Configuration (config.ini or e.md index e8773f0e64..d91571622f 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Configuration (config.ini or e.md +++ b/docs/User Guide/User Guide/Advanced Usage/Configuration (config.ini or e.md @@ -1,30 +1,169 @@ # Configuration (config.ini or environment variables) -Trilium supports configuration via a file named `config.ini` and environment variables. Please review the file named [config-sample.ini](https://github.com/TriliumNext/Notes/blob/develop/apps/server/src/assets/config-sample.ini) in the [Notes](https://github.com/TriliumNext/Notes) repository to see what values are supported. +Trilium supports configuration via a file named `config.ini` and environment variables. This document provides a comprehensive reference for all configuration options. -You can provide the same values via environment variables instead of the `config.ini` file, and these environment variables use the following format: +## Location of the configuration file -1. Environment variables should be prefixed with `TRILIUM_` and use underscores to represent the INI section structure. -2. The format is: `TRILIUM_
    _=` -3. The environment variables will override any matching values from config.ini +The configuration file is not located in the same directory as the application. Instead, the `config.ini` is located in theĀ Data directory. As such, the configuration file is only available after starting the application and creating a database. -For example, if you have this in your config.ini: +## Configuration Precedence -``` -[Network] -host=localhost -port=8080 +Configuration values are loaded in the following order of precedence (highest to lowest): + +1. **Environment variables** (checked first) +2. **config.ini file values** +3. **Default values** + +## Environment Variable Patterns + +Trilium supports multiple environment variable patterns for flexibility. The primary pattern is: `TRILIUM_[SECTION]_[KEY]` + +Where: + +* `SECTION` is the INI section name in UPPERCASE +* `KEY` is the camelCase configuration key converted to UPPERCASE (e.g., `instanceName` → `INSTANCENAME`) + +Additionally, shorter aliases are available for common configurations (see Alternative Variables section below). + +## Environment Variable Reference + +### General Section + +| Environment Variable | Type | Default | Description | +| --- | --- | --- | --- | +| `TRILIUM_GENERAL_INSTANCENAME` | string | "" | Instance name for API identification | +| `TRILIUM_GENERAL_NOAUTHENTICATION` | boolean | false | Disable authentication (server only) | +| `TRILIUM_GENERAL_NOBACKUP` | boolean | false | Disable automatic backups | +| `TRILIUM_GENERAL_NODESKTOPICON` | boolean | false | Disable desktop icon creation | +| `TRILIUM_GENERAL_READONLY` | boolean | false | Enable read-only mode | + +### Network Section + +| Environment Variable | Type | Default | Description | +| --- | --- | --- | --- | +| `TRILIUM_NETWORK_HOST` | string | "0.0.0.0" | Server host binding | +| `TRILIUM_NETWORK_PORT` | string | "3000" | Server port | +| `TRILIUM_NETWORK_HTTPS` | boolean | false | Enable HTTPS | +| `TRILIUM_NETWORK_CERTPATH` | string | "" | SSL certificate path | +| `TRILIUM_NETWORK_KEYPATH` | string | "" | SSL key path | +| `TRILIUM_NETWORK_TRUSTEDREVERSEPROXY` | boolean/string | false | Reverse proxy trust settings | +| `TRILIUM_NETWORK_CORSALLOWORIGIN` | string | "" | CORS allowed origins | +| `TRILIUM_NETWORK_CORSALLOWMETHODS` | string | "" | CORS allowed methods | +| `TRILIUM_NETWORK_CORSALLOWHEADERS` | string | "" | CORS allowed headers | +| `TRILIUM_NETWORK_CORSRESOURCEPOLICY` | string | same-origin | CORS Resource Policy allows same-origin/same-site/cross-origin as values, will error if not | + +### Session Section + +| Environment Variable | Type | Default | Description | +| --- | --- | --- | --- | +| `TRILIUM_SESSION_COOKIEMAXAGE` | integer | 1814400 | Session cookie max age in seconds (21 days) | + +### Sync Section + +| Environment Variable | Type | Default | Description | +| --- | --- | --- | --- | +| `TRILIUM_SYNC_SYNCSERVERHOST` | string | "" | Sync server host URL | +| `TRILIUM_SYNC_SYNCSERVERTIMEOUT` | string | "120000" | Sync server timeout in milliseconds | +| `TRILIUM_SYNC_SYNCPROXY` | string | "" | Sync proxy URL | + +### MultiFactorAuthentication Section + +| Environment Variable | Type | Default | Description | +| --- | --- | --- | --- | +| `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHBASEURL` | string | "" | OAuth/OpenID base URL | +| `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHCLIENTID` | string | "" | OAuth client ID | +| `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHCLIENTSECRET` | string | "" | OAuth client secret | +| `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHISSUERBASEURL` | string | "[https://accounts.google.com](https://accounts.google.com)" | OAuth issuer base URL | +| `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHISSUERNAME` | string | "Google" | OAuth issuer display name | +| `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHISSUERICON` | string | "" | OAuth issuer icon URL | + +### Logging Section + +| Environment Variable | Type | Default | Description | +| --- | --- | --- | --- | +| `TRILIUM_LOGGING_RETENTIONDAYS` | integer | 90 | Number of days to retain log files | + +## Alternative Environment Variables + +The following alternative environment variable names are also supported and work identically to their longer counterparts: + +### Network CORS Variables + +* `TRILIUM_NETWORK_CORS_ALLOW_ORIGIN` (alternative to `TRILIUM_NETWORK_CORSALLOWORIGIN`) +* `TRILIUM_NETWORK_CORS_ALLOW_METHODS` (alternative to `TRILIUM_NETWORK_CORSALLOWMETHODS`) +* `TRILIUM_NETWORK_CORS_ALLOW_HEADERS` (alternative to `TRILIUM_NETWORK_CORSALLOWHEADERS`) +* `TRILIUM_NETWORK_CORS_RESOURCE_POLICY` (alternative to `TRILIUM_NETWORK_CORSRESOURCEPOLICY`) + +### Sync Variables + +* `TRILIUM_SYNC_SERVER_HOST` (alternative to `TRILIUM_SYNC_SYNCSERVERHOST`) +* `TRILIUM_SYNC_SERVER_TIMEOUT` (alternative to `TRILIUM_SYNC_SYNCSERVERTIMEOUT`) +* `TRILIUM_SYNC_SERVER_PROXY` (alternative to `TRILIUM_SYNC_SYNCPROXY`) + +### OAuth/MFA Variables + +* `TRILIUM_OAUTH_BASE_URL` (alternative to `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHBASEURL`) +* `TRILIUM_OAUTH_CLIENT_ID` (alternative to `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHCLIENTID`) +* `TRILIUM_OAUTH_CLIENT_SECRET` (alternative to `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHCLIENTSECRET`) +* `TRILIUM_OAUTH_ISSUER_BASE_URL` (alternative to `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHISSUERBASEURL`) +* `TRILIUM_OAUTH_ISSUER_NAME` (alternative to `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHISSUERNAME`) +* `TRILIUM_OAUTH_ISSUER_ICON` (alternative to `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHISSUERICON`) + +### Logging Variables + +* `TRILIUM_LOGGING_RETENTION_DAYS` (alternative to `TRILIUM_LOGGING_RETENTIONDAYS`) + +## Boolean Values + +Boolean environment variables accept the following values: + +* **True**: `"true"`, `"1"`, `1` +* **False**: `"false"`, `"0"`, `0` +* Any other value defaults to `false` + +## Using Environment Variables + +Both naming patterns are fully supported and can be used interchangeably: + +* The longer format follows the section/key pattern for consistency with the INI file structure +* The shorter alternatives provide convenience for common configurations +* You can use whichever format you prefer - both are equally valid + +## Examples + +### Docker Compose Example + +```yaml +services: + trilium: + image: triliumnext/trilium + environment: + # Using full format + TRILIUM_GENERAL_INSTANCENAME: "My Trilium Instance" + TRILIUM_NETWORK_PORT: "8080" + TRILIUM_NETWORK_CORSALLOWORIGIN: "https://myapp.com" + TRILIUM_SYNC_SYNCSERVERHOST: "https://sync.example.com" + TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHBASEURL: "https://auth.example.com" + + # Or using shorter alternatives (equally valid) + # TRILIUM_NETWORK_CORS_ALLOW_ORIGIN: "https://myapp.com" + # TRILIUM_SYNC_SERVER_HOST: "https://sync.example.com" + # TRILIUM_OAUTH_BASE_URL: "https://auth.example.com" ``` -You can override these values using environment variables: +### Shell Export Example ``` -TRILIUM_NETWORK_HOST=0.0.0.0 -TRILIUM_NETWORK_PORT=9000 +# Using either format +export TRILIUM_GENERAL_NOAUTHENTICATION=false +export TRILIUM_NETWORK_HTTPS=true +export TRILIUM_NETWORK_CERTPATH=/path/to/cert.pem +export TRILIUM_NETWORK_KEYPATH=/path/to/key.pem +export TRILIUM_LOGGING_RETENTIONDAYS=30 + +# Start Trilium +npm start ``` -The code will: +## config.ini Reference -1. First load the `config.ini` file as before -2. Then scan all environment variables for ones starting with `TRILIUM_` -3. Parse these variables into section/key pairs -4. Merge them with the config from the file, with environment variables taking precedence \ No newline at end of file +For the complete list of configuration options and their INI file format, please review the [config-sample.ini](https://github.com/TriliumNext/Trilium/blob/main/apps/server/src/assets/config-sample.ini) file in the Trilium repository \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/Custom Request Handler.md b/docs/User Guide/User Guide/Advanced Usage/Custom Request Handler.md index 52991f1360..6d2c1e7340 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Custom Request Handler.md +++ b/docs/User Guide/User Guide/Advanced Usage/Custom Request Handler.md @@ -14,7 +14,7 @@ const {secret, title, content} = req.body; if (req.method == 'POST' && secret === 'secret-password') { // notes must be saved somewhere in the tree hierarchy specified by a parent note. // This is defined by a relation from this code note to the "target" parent note - // alternetively you can just use constant noteId for simplicity (get that from "Note Info" dialog of the desired parent note) + // alternatively you can just use constant noteId for simplicity (get that from "Note Info" dialog of the desired parent note) const targetParentNoteId = api.currentNote.getRelationValue('targetNote'); const {note} = api.createTextNote(targetParentNoteId, title, content); @@ -37,7 +37,7 @@ This script note has also following two attributes: Let's test this by using an HTTP client to send a request: ``` -POST http://my.trilium.org/custom/create-note +POST http://your-trilium-server/custom/create-note Content-Type: application/json { @@ -70,7 +70,7 @@ For more information, seeĀ [Custom Resource Providers](Custom%20Resource%20Provi REST request paths often contain parameters in the URL, e.g.: ``` -http://my.trilium.org/custom/notes/123 +http://your-trilium-server/custom/notes/123 ``` The last part is dynamic so the matching of the URL must also be dynamic - for this reason the matching is done with regular expressions. Following `customRequestHandler` value would match it: @@ -85,4 +85,4 @@ Additionally, this also defines a matching group with the use of parenthesis whi const noteId = api.pathParams[0]; ``` -Often you also need query params (as in e.g. `http://my.trilium.org/custom/notes?noteId=123`), you can get those with standard express `req.query.noteId`. \ No newline at end of file +Often you also need query params (as in e.g. `http://your-trilium-server/custom/notes?noteId=123`), you can get those with standard express `req.query.noteId`. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/Database/Demo Notes.md b/docs/User Guide/User Guide/Advanced Usage/Database/Demo Notes.md index 895e8b9e89..df8af0f6f3 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Database/Demo Notes.md +++ b/docs/User Guide/User Guide/Advanced Usage/Database/Demo Notes.md @@ -13,7 +13,7 @@ There are some cases in which you may want to restore the original demo notes. F You can easily restore the demo notes by using Trilium's built-in import feature by importing them: -* Download [this .zip archive](https://github.com/TriliumNext/Notes/raw/develop/db/demo.zip) with the latest version of the demo notes +* Download [the .zip archive](https://github.com/TriliumNext/Trilium/raw/refs/heads/main/apps/server/src/assets/db/demo.zip) with the latest version of the demo notes * Right click on any note in your tree under which you would like the demo notes to be imported * Click "Import into note" * Select the .zip archive to import it \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/1_SQL Console_image.png b/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/1_SQL Console_image.png index 6f32f76ec9..1b1834ba1f 100644 Binary files a/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/1_SQL Console_image.png and b/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/1_SQL Console_image.png differ diff --git a/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/2_SQL Console_image.png b/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/2_SQL Console_image.png index 1b1834ba1f..a395a969b4 100644 Binary files a/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/2_SQL Console_image.png and b/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/2_SQL Console_image.png differ diff --git a/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/3_SQL Console_image.png b/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/3_SQL Console_image.png deleted file mode 100644 index ccef8f7aaf..0000000000 Binary files a/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/3_SQL Console_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/SQL Console.md b/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/SQL Console.md index f5139a269b..d9dfd8fb8f 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/SQL Console.md +++ b/docs/User Guide/User Guide/Advanced Usage/Database/Manually altering the database/SQL Console.md @@ -1,7 +1,7 @@ # SQL Console The SQL Console is Trilium's built-in database editor. -It can be accessed by going to the [global menu](../../../Basic%20Concepts%20and%20Features/UI%20Elements) → Advanced → Open SQL Console. +It can be accessed by going to theĀ Global menu → Advanced → Open SQL Console. ![](SQL%20Console_image.png) @@ -9,16 +9,26 @@ It can be accessed by going to the [global menu](../../../Basic%20Concepts%20and * Hovering the mouse over one of the tables listed at the top of the document will show the columns and their data type. * Only one SQL statement can be run at once. -* To run the statement, press the ![](3_SQL%20Console_image.png)icon. +* To run the statement, press the _Execute_ icon. * For queries that return a result, the data will displayed in a table. - - ![](1_SQL%20Console_image.png) +* For statements (e.g. `INSERT`, `UPDATE`), the number of affected rows is displayed. + +
    + +### Interacting with the table + +After executing a query, a table with the results will be displayed: + +* Clicking on a column allows sorting ascending or descending. +* Underneath each column there is an input field which allows filtering by text. +* Press Ctrl+C to copy the current cell to clipboard. +* Multiple cells can be selected by dragging or by holding Shift + arrow keys +* Results are paginated for performance reasons. The controls at the bottom of the table can be used to navigate through pages. ### Saved SQL console SQL queries or commands can be saved into a dedicated note. -To do so, simply write the query and press the ![](2_SQL%20Console_image.png)button. Once saved, the note will appear inĀ [Day Notes](../../Advanced%20Showcases/Day%20Notes.md). +To do so, simply write the query and press the ![](1_SQL%20Console_image.png) button. Once saved, the note will appear inĀ Day Notes. -* The SQL expression will not be displayed by default, but it can still be viewed by going to the note context menu and selecting _Note source_. -* The expression cannot be modified. If needed, recreate it by copying the statement back into the SQL console and then saving it again. \ No newline at end of file +The note can be locked for editing by pressing the _Lock_ button in the note actions section near the title bar (on theĀ New Layout, or in theĀ Floating buttonsĀ area if using the old layout). When editing is locked, the SQL statement is hidden from view. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/ETAPI (REST API).md b/docs/User Guide/User Guide/Advanced Usage/ETAPI (REST API).md index 2a27f565ed..c50694b731 100644 --- a/docs/User Guide/User Guide/Advanced Usage/ETAPI (REST API).md +++ b/docs/User Guide/User Guide/Advanced Usage/ETAPI (REST API).md @@ -1,7 +1,8 @@ # ETAPI (REST API) -ETAPI is Trilium's public/external REST API. It is available since Trilium v0.50. +> [!TIP] +> For a quick start, consult theĀ API Reference. -The documentation is in OpenAPI format, available [here](https://github.com/TriliumNext/Notes/blob/master/src/etapi/etapi.openapi.yaml). +ETAPI is Trilium's public/external REST API. It is available since Trilium v0.50. ## API clients @@ -11,7 +12,7 @@ As an alternative to calling the API directly, there are client libraries to sim ## Obtaining a token -All operations with the REST API have to be authenticated using a token. You can get this token either from Options -> ETAPI or programmatically using the `/auth/login` REST call (see the [spec](https://github.com/TriliumNext/Notes/blob/master/src/etapi/etapi.openapi.yaml)). +All operations with the REST API have to be authenticated using a token. You can get this token either from Options -> ETAPI or programmatically using the `/auth/login` REST call (see the [spec](https://github.com/TriliumNext/Trilium/blob/master/src/etapi/etapi.openapi.yaml)). ## Authentication @@ -61,4 +62,12 @@ Make sure to replace the values of: * `TOKEN` with your ETAPI token. * `SERVER` with the correct protocol, host name and port to your Trilium instance. -* `NOTE_ID` with an existing note ID to download. \ No newline at end of file +* `NOTE_ID` with an existing note ID to download. + +As another example, to obtain a .zip export of a note and place it in a directory called `out`, simply replace the last statement in the script with: + +``` +curl -H "Authorization: $TOKEN" \ + -X GET "$SERVER/etapi/notes/$NOTE_ID/export" \ + --output "out/$NOTE_ID.zip" +``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/Nightly release.md b/docs/User Guide/User Guide/Advanced Usage/Nightly release.md new file mode 100644 index 0000000000..3ef005cd57 --- /dev/null +++ b/docs/User Guide/User Guide/Advanced Usage/Nightly release.md @@ -0,0 +1,64 @@ +# Nightly release +Nightly releases are versions built every day, containing the latest improvements and bugfixes, directly from the main development branch. These versions are generally useful in preparation for a release, to ensure that there are no significant bugs that need to be addressed first, or they can be used to confirm whether a particular bug is fixed or feature is well implemented. + +## Regarding the stability + +Despite being on a development branch, generally the main branch is pretty stable since PRs are tested before they are merged. If you notice any issues, feel free to report them either via a ticket or via the Matrix. + +## Downloading the nightly release manually + +Go to [github.com/TriliumNext/Trilium/releases/tag/nightly](https://github.com/TriliumNext/Trilium/releases/tag/nightly) and look for the artifacts starting with `TriliumNotes-main`. Choose the appropriate one for your platform (e.g. `windows-x64.zip`). + +Depending on your use case, you can either test the portable version or even use the installer. + +> [!NOTE] +> If you choose the installable version (e.g. the .exe on Windows), it will replace your stable installation. + +> [!IMPORTANT] +> By default, the nightly uses the same database as the production version. Generally you could easily downgrade if needed. However, if there are changes to the database or sync version, it will not be possible to downgrade without having to restore from a backup. + +## Automatically download and install the latest nightly + +This is pretty useful if you are a beta tester that wants to periodically update their version: + +## On Ubuntu (Bash) + +```sh +#!/usr/bin/env bash + +name=TriliumNotes-linux-x64-nightly.deb +rm -f $name* +wget https://github.com/TriliumNext/Trilium/releases/download/nightly/$name +sudo apt-get install ./$name +rm $name +``` + +## On Windows (PowerShell) + +```powershell +if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { + $arch = "arm64"; +} else { + $arch = "x64"; +} + +$exeUrl = "https://github.com/TriliumNext/Trilium/releases/download/nightly/TriliumNotes-main-windows-$($arch).exe"; +Write-Host "Downloading $($exeUrl)" + +# Generate a unique path in the temp dir +$guid = [guid]::NewGuid().ToString() +$destination = Join-Path -Path $env:TEMP -ChildPath "$guid.exe" + +try { + $ProgressPreference = 'SilentlyContinue' + Invoke-WebRequest -Uri $exeUrl -OutFile $destination + $process = Start-Process -FilePath $destination +} catch { + Write-Error "An error occurred: $_" +} finally { + # Clean up + if (Test-Path $destination) { + Remove-Item -Path $destination -Force + } +} +``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/Note Map (Link map, Tree map).md b/docs/User Guide/User Guide/Advanced Usage/Note Map (Link map, Tree map).md index 67ad6dcf28..9b55f504e4 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Note Map (Link map, Tree map).md +++ b/docs/User Guide/User Guide/Advanced Usage/Note Map (Link map, Tree map).md @@ -10,7 +10,12 @@ There are two types of note map: ## Link Map -Shows [relations](Attributes.md) between notes: +The Link map is a visualization of links andĀ RelationsĀ incoming to and outgoing from a particular note. + +The map indicates the following types of relations: + +* Internal (reference) linksĀ between notes. +* Relations ![](1_Note%20Map%20\(Link%20map,%20Tree%20m.png) diff --git a/docs/User Guide/User Guide/Advanced Usage/Note source.md b/docs/User Guide/User Guide/Advanced Usage/Note source.md index 927f63ce11..bfb34912b3 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Note source.md +++ b/docs/User Guide/User Guide/Advanced Usage/Note source.md @@ -7,7 +7,7 @@ For example: * TextĀ notesĀ are represented internally as HTML, using theĀ CKEditorĀ representation. Note that due to the custom plugins, some HTML elements are specific to Trilium only, for example the admonitions. * CodeĀ notesĀ are plain text and are represented internally as-is. -* Geo MapĀ notes contain only minimal information (viewport, zoom) as a JSON. +* Geo MapĀ notes contain only minimal information (viewport, zoom) as a JSON. * CanvasĀ notes are represented as JSON, with Trilium's own information alongside withĀ Excalidraw's internal JSON representation format. * Mind MapĀ notes are represented as JSON, with the internal format ofĀ MindElixir. @@ -36,7 +36,7 @@ It is possible to view the source code of a note by pressing the contextual menu The source code will be displayed in a new tab. -For some note types, such as text notes, the source code is also formatted in order to be more easily readable. +For some note types, such as text notes and JSON notes, the source code is also formatted in order to be more easily readable. ## Modifying the source code diff --git a/docs/User Guide/User Guide/Advanced Usage/Read-only database.md b/docs/User Guide/User Guide/Advanced Usage/Read-only database.md new file mode 100644 index 0000000000..cacdc9675e --- /dev/null +++ b/docs/User Guide/User Guide/Advanced Usage/Read-only database.md @@ -0,0 +1,32 @@ +# Read-only database +> [!WARNING] +> This functionality is still in preview, expect possible issues or even the feature disappearing completely. +> Feel free to [report](../Troubleshooting/Reporting%20issues.md) any issues you might have. + +The read-only database is an alternative toĀ SharingĀ notes. Although the share functionality works pretty well to publish pages to the Internet in a wiki, blog-like format it does not offer the full functionality behind Trilium (such as the advancedĀ SearchĀ or the interactivity behindĀ CollectionsĀ or the variousĀ Note Types). + +When the database is in read-only mode, the Trilium application can be used as normal, but editing is disabled and changes are made in-memory only. + +## What it does + +* All notes are read-only, without the possibility of editing them. +* Features that would normally alter the database such as the list of recent notes are disabled. + +## Limitations + +* Some features might ā€œslip throughā€ and still end up creating a note, for example. + * However, the database is still read-only, so all modifications will be reset if the server is restarted. + * Whenever this occurs, `ERROR: read-only DB ignored` will be shown in the logs. + +## Setting a database as read-only + +First, make sure the database is initialized (e.g. the first set up is complete). Then modify the [config.ini](Configuration%20\(config.ini%20or%20e.md) by looking for the `[General]` section and adding a new `readOnly` field: + +``` +[General] +readOnly=true +``` + +If your server is already running, restart it to apply the changes. + +Similarly, to disable read-only remove the line or set it to `false`. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Safe mode.md b/docs/User Guide/User Guide/Advanced Usage/Safe mode.md similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Safe mode.md rename to docs/User Guide/User Guide/Advanced Usage/Safe mode.md diff --git a/docs/User Guide/User Guide/Advanced Usage/Sharing.md b/docs/User Guide/User Guide/Advanced Usage/Sharing.md index 64b5767ddb..5f87ce125f 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Sharing.md +++ b/docs/User Guide/User Guide/Advanced Usage/Sharing.md @@ -16,7 +16,7 @@ Trilium allows you to share selected notes as **publicly accessible** read-only ### By note type -
     Supported featuresLimitations
    Text
    • Table of contents.
    • Syntax highlight of code blocks, provided a language is selected (does not work if ā€œAuto-detectedā€ is enabled).
    • Rendering for math equations.
    • Including notes is not supported.
    • Inline Mermaid diagrams are not rendered.
    Code
    • Basic support (displaying the contents of the note in a monospace font).
    • No syntax highlight.
    Saved SearchNot supported. 
    Relation MapNot supported. 
    Note MapNot supported. 
    Render NoteNot supported. 
    Collections
    • The child notes are displayed in a fixed format. 
    • More advanced view types such as the calendar view are not supported.
    Mermaid Diagrams
    • The diagram is displayed as a vector image.
    • No further interaction supported.
    Canvas
    • The diagram is displayed as a vector image.
    • No further interaction supported.
    Web ViewNot supported. 
    Mind MapThe diagram is displayed as a vector image.
    • No further interaction supported.
    Geo Map ViewNot supported. 
    FileBasic interaction (downloading the file).
    • No further interaction supported.
    +
     Supported featuresLimitations
    Text
    • Table of contents.
    • Syntax highlight of code blocks, provided a language is selected (does not work if ā€œAuto-detectedā€ is enabled).
    • Rendering for math equations.
    • Including notes (only if the included notes are also shared).
    • Inline Mermaid diagrams are not rendered.
    Code
    • Basic support (displaying the contents of the note in a monospace font).
    • No syntax highlight.
    Saved SearchNot supported. 
    Relation MapNot supported. 
    Note MapNot supported. 
    Render NoteNot supported. 
    Collections
    • The child notes are displayed in a fixed format. 
    • More advanced view types such as the calendar view are not supported.
    Mermaid Diagrams
    • The diagram is displayed as a vector image.
    • No further interaction supported.
    Canvas
    • The diagram is displayed as a vector image.
    • No further interaction supported.
    Web ViewNot supported. 
    Mind MapThe diagram is displayed as a vector image.
    • No further interaction supported.
    Geo MapNot supported. 
    FileBasic interaction (downloading the file).
    • No further interaction supported.
    While the sharing feature is powerful, it has some limitations: @@ -31,32 +31,34 @@ Some of these limitations may be addressed in future updates. To use the sharing feature, you must have aĀ Server InstallationĀ of Trilium. This is necessary because the notes will be hosted from the server. -## How to Share a Note +## Sharing a note 1. **Enable Sharing**: To share a note, toggle the `Shared` switch within the note's interface. Once sharing is enabled, an URL will appear, which you can click to access the shared note. ![Share Note](Sharing_share-single-note.png) 2. **Access the Shared Note**: The link provided will open the note in your browser. If your server is not configured with a public IP, the URL will refer to `localhost (127.0.0.1)`. -## Sharing a Note Subtree +## Sharing a note subtree When you share a note, you actually share the entire subtree of notes beneath it. If the note has child notes, they will also be included in the shared content. For example, sharing the "Formatting" subtree will display a page with basic navigation for exploring all the notes within that subtree. -## Viewing All Shared Notes +## Viewing and managing shared notes -You can view a list of all shared notes by clicking on "Show Shared Notes Subtree." This allows you to manage and navigate through all the notes you have made public. +You can view a list of all shared notes by clicking on "Show Shared Notes Subtree" in theĀ Global menu. This allows you to manage and navigate through all the notes you have made public. -## Security Considerations +## Security considerations -Shared notes are published on the open internet and can be accessed by anyone with the URL. The URL's randomness does not provide security, so it is crucial not to share sensitive information through this feature. +* Shared notes are published on the open internet and can be accessed by anyone with the URL unless the notes are password-protected. +* The URL's randomness does not provide security, so it is crucial not to share sensitive information through this feature. +* Trilium takes precautions to protect your publicly shared instance from leaking information for non-shared notes, including opening a separate read-only connection to theĀ Database. Depending on your threat model, it might make more sense to useĀ Exporting HTML for web publishingĀ and use battle-tested web servers such as Nginx or Apache to serve static content. -### Password Protection +### Password protection To protect shared notes with a username and password, you can use the `#shareCredentials` attribute. Add this label to the note with the format `#shareCredentials="username:password"`. To protect an entire subtree, make sure the label is [inheritable](Attributes/Attribute%20Inheritance.md). -## Advanced Sharing Options +## Advanced sharing options -### Customizing the Appearance of Shared Notes +### Customizing the appearance of shared notes The default design should be a good starting point, but you can customize it using your own CSS: @@ -67,6 +69,25 @@ The default design should be a good starting point, but you can customize it usi You can inject custom JavaScript into the shared note using the `~shareJs` relation. This allows you to access note attributes or traverse the note tree using the `fetchNote()` API, which retrieves note data based on its ID. +### Adding custom HTML + +You can inject custom HTML snippets into specific locations of the shared page using the `~shareHtml` relation. The HTML note should contain the raw HTML content you want to inject, and you can control where it appears by adding the `#shareHtmlLocation` label to the HTML snippet note itself. + +The `#shareHtmlLocation` label accepts values in the format `location:position`: + +* **Locations**: `head`, `body`, `content` +* **Positions**: `start`, `end` + +For example: + +* `#shareHtmlLocation=head:start` - Injects HTML at the beginning of the `` section +* `#shareHtmlLocation=head:end` - Injects HTML at the end of the `` section (default) +* `#shareHtmlLocation=body:start` - Injects HTML at the beginning of the `` section +* `#shareHtmlLocation=content:start` - Injects HTML at the beginning of the content area +* `#shareHtmlLocation=content:end` - Injects HTML at the end of the content area + +If no location is specified, the HTML will be injected at `content:end` by default. + Example: ```javascript @@ -78,7 +99,7 @@ for (const attr of parentNote.attributes) { } ``` -### Creating Human-Readable URL Aliases +### Creating human-readable URL aliases Shared notes typically have URLs like `http://domain.tld/share/knvU8aJy4dJ7`, where the last part is the note's ID. You can make these URLs more user-friendly by adding the `#shareAlias` label to individual notes (e.g., `#shareAlias=highlighting`). This will change the URL to `http://domain.tld/share/highlighting`. @@ -87,23 +108,50 @@ Shared notes typically have URLs like `http://domain.tld/share/knvU8aJy4dJ7`, wh 1. Ensure that aliases are unique. 2. Using slashes (`/`) within aliases to create subpaths is not supported. -### Viewing and Managing Shared Notes +> [!TIP] +> * To easily identify pages that don't have a share alias, run aĀ SearchĀ with `#!shareAlias`. +> * To be able to enter the share alias faster, consider usingĀ Promoted AttributesĀ (for example `#label:shareAlias(inheritable)="promoted,alias=Slug,single,text"`). -All shared notes are grouped under an automatically managed "Shared Notes" section. From here, you can view, share, or unshare notes by moving or cloning them within this section. - -![Shared Notes List](Sharing_shared-list.png) - -### Setting a Custom Favicon +### Setting a custom favicon To customize the favicon for your shared pages, create a relation `~shareFavicon` pointing to a file note containing the favicon (e.g., in `.ico` format). -### Sharing a Note as the Root +### Sharing a note as the root -You can designate a specific note or folder as the root of your shared content by adding the `#shareRoot` label. This note will be linked when visiting `[http://domain.tld/share](http://domain/share)`, making it easier to use Trilium as a fully-fledged website. Consider combining this with the `#shareIndex` label, which will display a list of all shared notes. +You can designate a specific note or folder as the root of your shared content by adding the `#shareRoot` label. This note will be linked when visiting `[http://domain.tld/share](http://domain/share)`, making it easier to use Trilium as a fully-fledged website. + +> [!TIP] +> Consider combining this with the `#shareIndex` label, which will display a list of all shared notes. + +### Displaying an index of shared notes + +When accessing a share, the sub-notes will be displayed in a tree on the left. But since multiple note trees can be shared, it might be useful to display a list of all the different share trees. + +To do so, create a shared text note and apply the `shareIndex` label. When viewed, the list of shared roots will be displayed at the bottom of the note. ## Attribute reference -
    AttributeDescription
    shareHiddenFromTreethis note is hidden from left navigation tree, but still accessible with its URL
    shareExternalLinknote will act as a link to an external website in the share tree
    shareAliasdefine an alias using which the note will be available under https://your_trilium_host/share/[your_alias]
    shareOmitDefaultCssdefault share page CSS will be omitted. Use when you make extensive styling changes.
    shareRootmarks note which is served on /share root.
    shareDescriptiondefine text to be added to the HTML meta tag for description
    shareRawNote will be served in its raw format, without HTML wrapper. See also Serving directly the content of a note for an alternative method without setting an attribute.
    shareDisallowRobotIndexing

    Indicates to web crawlers that the page should not be indexed of this note by:

    • Setting the X-Robots-Tag: noindex HTTP header.
    • Setting the noindex, follow meta tag.
    shareCredentialsrequire credentials to access this shared note. Value is expected to be in format username:password. Don't forget to make this inheritable to apply to child-notes/images.
    shareIndexNote with this label will list all roots of shared notes.
    +
    AttributeDescription
    #shareHiddenFromTreethis note is hidden from left navigation tree, but still accessible with its URL
    #shareExternalLinknote will act as a link to an external website in the share tree
    #shareAliasdefine an alias using which the note will be available under https://your_trilium_host/share/[your_alias]
    #shareOmitDefaultCssdefault share page CSS will be omitted. Use when you make extensive styling changes.
    #shareRootmarks note which is served on /share root.
    #shareDescriptiondefine text to be added to the HTML meta tag for description
    #shareRawNote will be served in its raw format, without HTML wrapper. See also Serving directly the content of a note for an alternative method without setting an attribute.
    #shareDisallowRobotIndexing

    Indicates to web crawlers that the page should not be indexed of this note by:

    • Setting the X-Robots-Tag: noindex HTTP header.
    • Setting the noindex, follow meta tag.
    #shareCredentialsrequire credentials to access this shared note. Value is expected to be in format username:password. Don't forget to make this inheritable to apply to child-notes/images.
    #shareIndexNote with this label will list all roots of shared notes.
    #shareHtmlLocationdefines where custom HTML injected via ~shareHtml relation should be placed. Applied to the HTML snippet note itself. Format: location:position where location is head, body, or content and position is start or end. Defaults to content:end.
    + +### Customizing logo + +It's possible to adjust the logo which is displayed on the top-left of the left pane. + +| Attribute | Description | +| --- | --- | +| `~shareLogo` | Relation set to an image to use as logo. The image must be part of the share tree (it can be hidden if needed). | +| `#shareLogoWidth` | The width (in pixels, without unit) to set for the logo. Default is `53`. | +| `#shareLogoHeight` | The height (in pixels, without unit) to set for the logo. Default is `40`. | +| `#shareRootLink` | URL to navigate to when the logo is pressed. | + +### Customizing OpenGraph + +| Attribute | Description | +| --- | --- | +| `#shareOpenGraphColor` | This adjusts the `theme-color` meta-property. | +| `#shareOpenGraphURL` | This adjusts the `og:url` and `twitter:url` meta-properties. | +| `#shareOpenGraphDomain` | Adjusts the `twitter:domain` meta-property. | +| `#shareOpenGraphImage`
    `~shareOpenGraphImage` | Can be either a label, case in which the value is passed on as-is, or it can be a relation to an imageĀ File. This controls the `og:image` meta-property. | ## Credits diff --git a/docs/User Guide/User Guide/Advanced Usage/Sharing/Exporting static HTML for web .md b/docs/User Guide/User Guide/Advanced Usage/Sharing/Exporting static HTML for web .md new file mode 100644 index 0000000000..cc2e30825b --- /dev/null +++ b/docs/User Guide/User Guide/Advanced Usage/Sharing/Exporting static HTML for web .md @@ -0,0 +1,49 @@ +# Exporting static HTML for web publishing +As described inĀ Sharing, Trilium can act as a public server in which the shared notes are displayed in read-only mode. While this can work in most cases, it's generally not meant for high-traffic websites and since it's running on a Node.js server it can be potentially exploited. + +Another alternative is to generate static HTML files (just like other static site generators such as [MkDocs](https://www.mkdocs.org/)). Since the normal HTML ZIP export does not contain any styling or additional functionality, Trilium provides a way to export the same layout and style as theĀ SharingĀ function into static HTML files. + +Apart from the enhanced security, these HTML files are also easy to deploy on ā€œserverlessā€ deployments such as GitHub Pages or CloudFlare Pages and cache very easily. + +> [!TIP] +> Trilium's documentation, available at [docs.triliumnotes.org](https://docs.triliumnotes.org/) is built using this function of exporting to static HTML files which are then deployed automatically to CloudFlare Pages. +> +> The process is [automated](https://github.com/TriliumNext/Trilium/blob/main/apps/edit-docs/src/build-docs.ts) by importing the Markdown documentation and exporting it via a script to the static web format. + +## Differences from normal sharing + +Apart from normalĀ Sharing, exporting to static HTML files comes with a few subtle differences: + +* The URL structure is different. Where in normal sharing it's something along the way of `example.com/share/noteid`, the notes follow an hierarchical structure, such as `docs.triliumnotes.org/user-guide/concepts/navigation/tree-concepts`. +* The `favicon.ico` is not handled automatically, it needs to be manually added on the server after the export is generated. +* The ā€œLast updatedā€ for notes is not available. +* The search functionality works slightly different since the normal one requires an active API to work. In the static export, search still works but uses a different mechanism so results might be different. + +## Differences from normal .zip export + +* The name of the files/URLs will prefer `shareAlias` to allow for clean URLs. +* The export requires a functional web server as the pages will not render properly if accessed locally via a web browser due to the use of module scripts. +* The directory structure is also slightly different: + * A normal HTML export results in an index file and a single directory. + * Instead, for static exporting the top-root level becomes the index file and the child directories are on the root instead. + * This makes it possible to easily publish to a website, without forcing everything but the root note to be in a sub-directory. + +## Testing locally + +As mentioned previously, the exported static pages require a website to function. In order to test locally, a web server needs to be used. + +One example is to use the Node.js-based [`http-server`](https://www.npmjs.com/package/http-server) which can be installed via: + +``` +npm i -g http-server +``` + +Once installed simply: + +1. Extract the exported .zip file. +2. Inside the extracted directory, run `http-server`. +3. Access the indicated address (e.g. [http://localhost:8080](http://localhost:8080)). + +## Automation + +ETAPI (REST API)Ā could potentially be used to automate an export on a scheduled task. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/Sharing/Reverse proxy configuration.md b/docs/User Guide/User Guide/Advanced Usage/Sharing/Reverse proxy configuration.md new file mode 100644 index 0000000000..d485b6cb17 --- /dev/null +++ b/docs/User Guide/User Guide/Advanced Usage/Sharing/Reverse proxy configuration.md @@ -0,0 +1,18 @@ +# Reverse proxy configuration +It might be desirable to only expose the share functionality of Trilium to the Internet, and keep the application accessible only within a local network or via VPN. + +To do so, a reverse proxy is required. + +## Caddy + +``` +http://domain.com { + reverse_proxy /share http://localhost:8080/share +} +``` + +This is for newer versions where the share functionality is isolated, for older versions it's required to also include `/assets`.[1] + +1. ^ + + [https://github.com/orgs/TriliumNext/discussions/7341#discussioncomment-14679897](https://github.com/orgs/TriliumNext/discussions/7341#discussioncomment-14679897) \ No newline at end of file diff --git a/docs/User Guide/User Guide/Advanced Usage/Sharing_shared-list.png b/docs/User Guide/User Guide/Advanced Usage/Sharing_shared-list.png deleted file mode 100644 index 8002303f85..0000000000 Binary files a/docs/User Guide/User Guide/Advanced Usage/Sharing_shared-list.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Advanced Usage/Technologies used/Leaflet.md b/docs/User Guide/User Guide/Advanced Usage/Technologies used/Leaflet.md index 85f4dc9bb0..db1827e4c7 100644 --- a/docs/User Guide/User Guide/Advanced Usage/Technologies used/Leaflet.md +++ b/docs/User Guide/User Guide/Advanced Usage/Technologies used/Leaflet.md @@ -1,5 +1,5 @@ # Leaflet -Leaflet is the library behindĀ [Geo map](../../Note%20Types/Collections/Geo%20Map%20View.md)Ā notes. +Leaflet is the library behindĀ [Geo map](../../Collections/Geo%20Map.md)Ā notes. ## Plugins diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Active content.md b/docs/User Guide/User Guide/Basic Concepts and Features/Active content.md new file mode 100644 index 0000000000..a8ad72b286 --- /dev/null +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Active content.md @@ -0,0 +1,33 @@ +# Active content +_Active content_ is a generic name for powerful features in Trilium, these range from customizing the UI to advanced scripting that can alter your notes or even your PC. + +## Safe import + +Active content problem of safety, especially when this active content comes from a third-party such as if it is downloaded from a website and then imported into Trilium. + +When [importing](Import%20%26%20Export.md) .zip archives into Trilium, _safe mode_ is active by default which will try to prevent untrusted code from executing. For example, a [custom widget](../Scripting/Frontend%20Basics/Custom%20Widgets.md) needs the `#widget` [label](../Advanced%20Usage/Attributes/Labels.md) in order to function; safe import works by renaming that label to `#disabled:widget`. + +## Safe mode + +Sometimes active content can cause issues with the UI or the server, preventing it from functioning properly.Ā Safe modeĀ allows starting Trilium in such a way that active content is not loaded by default at start-up, allowing the user to fix the problematic scripts or widgets. + +## Types of active content + +These are the types of active content in Trilium, along with a few examples of what untrusted content of that type could cause: + +| Name | Disabled on a safe [import](Import%20%26%20Export.md) | Description | Potential risks of untrusted code | +| --- | --- | --- | --- | +| [Front-end scripts](../Scripting/Frontend%20Basics.md) | Yes | Allow running arbitrary code on the client (UI) of Trilium, which can alter the user interface. | A malicious script can execute server-side code, access un-encrypted notes or change their contents. | +| Custom Widgets | Yes | Can add new UI features to Trilium, for example by adding a new section in theĀ Right Sidebar. | The UI can be altered in such a way that it can be used to extract sensitive information or it can simply cause the application to crash. | +| Backend scripts | Yes | Can run custom code on the server of Trilium (Node.js environment), with full access to the notes and the database. | Has access to all the unencrypted notes, but with full access to the database it can completely destroy the data. It also has access to execute other applications or alter the files and folders on the server). | +| Web View | Yes | Displays a website inside a note. | Can point to a phishing website which can collect the data (for example on a log in page). | +| Render Note | Yes | Renders custom content inside a note, such as a dashboard or a new editor that is not officially supported by Trilium. | Can affect the UI similar to front-end scripts or custom widgets since the scripts are not completely encapsulated, or they can act similar to a web view where they can collect data entered by the user. | +| Custom app-wide CSS | No | Can alter the layout and style of the UI using CSS, applied regardless of theme. | Generally less problematic than the rest of active content, but a badly written CSS can affect the layout of the application, requiring the use ofĀ Safe modeĀ to be able to use the application. | +| [Custom themes](../Theme%20development) | No | Can change the style of the entire UI. | Similar to custom app-wide CSS. | +| Icon Packs | No | Introduces new icons that can be used for notes. | Generally are more contained and less prone to cause issues, but they can cause performance issues (for example if the icon pack has millions of icons in it). | + +## Active content badge + +Starting with v0.102.0, on theĀ New LayoutĀ a badge will be displayed near the note title, indicating that an active content is detected. Clicking the badge will reveal a menu with various options related to that content type, for example to open the documentation or to configure the execution of scripts. + +For some active content types, such as backend scripts with custom triggering conditions a toggle button will appear. This makes it possible to easily disable scripts or widgets, but also to re-enable them if an import was made with safe mode active. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Import & Export.md b/docs/User Guide/User Guide/Basic Concepts and Features/Import & Export.md new file mode 100644 index 0000000000..095a9739de --- /dev/null +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Import & Export.md @@ -0,0 +1,15 @@ +# Import & Export +Trilium natively supports the following formats for both import and export. + +* HTML: + * This is the main format used by Trilium, where standard tags are used to represent basic formatting and layout (e.g. ``, ``, `
    `).
    +    *   Note that HTML is not a standardized format so some more specific features such as admonitions orĀ Internal (reference) linksĀ might not be supported by other applications.
    +*   Markdown
    +    *   Most of the formatting is preserved, seeĀ Supported syntax.
    +*   OPML (Outliner Interchange Format)
    +    *   Supports both OPML v1.0 for plain text and v2.0 with HTML support.
    +
    +To import from other applications, see the dedicated pages:
    +
    +*   Evernote
    +*   OneNote
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote.md b/docs/User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote.md
    index bda28e61d3..19327abcee 100644
    --- a/docs/User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote.md	
    +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote.md	
    @@ -1,18 +1,60 @@
     # Evernote
    -Trilium can import ENEX files which are used by Evernote for backup/export. One ENEX file represents content (notes and resources) of one notebook.
    +Trilium can import ENEX files, which are used by Evernote for backup/export. One ENEX file represents the content (notes and resources) of one notebook.
     
     ## Export ENEX from Evernote
     
    -To export ENEX file, you need to have a _legacy_ desktop version of Evernote (i.e. not web/mobile). Right click on notebook and select export and follow the wizard.
    +To export ENEX files from Evernote, you can use:
    +
    +*   Evernote desktop application. See EvernoteĀ [documentation](https://help.evernote.com/hc/en-us/articles/209005557-Export-Notes-and-Notebooks-as-ENEX-or-HTML). Note that the limitation of this method is that you can only export 100 notes at a time or one notebook at a time.
    +*   A third-partyĀ [evernote-backup](https://github.com/vzhd1701/evernote-backup) CLI tool. This tool can export all of your notebooks in bulk.
     
     ## Import ENEX in Trilium
     
    -Once you have ENEX file, you can import it to Trilium. Right click on some note (to which you want to import the file), click on "Import" and select the ENEX file.
    +Once you have your ENEX files, do the following to import them in Trilium:
     
    -After importing the ENEX file, go over the imported notes and resources to be sure the import went well, and you didn't lose any data.
    +1.  In the Trilium note tree, right-click the note under which you want to import one or more of your ENEX files. The notes in the files will be imported as child notes of the selected note.
    +2.  ClickĀ Import into note.
    +3.  Choose your ENEX file or files and clickĀ Import.
    +4.  During the import, you will see "Import in progress" message. If the import is successful, the message will change to ā€œImport finished successfullyā€ and then disappear.
    +5.  We recommend you to check the imported notes and their attachments to verify that you haven’t lost any data.
    +
    +A non-exhaustive list of what the importer preserves:
    +
    +*   Attachments
    +*   The hierarchy of headings (these are shifted to start with H2 because H1 is reserved for note title, seeĀ [Headings](../../Note%20Types/Text/General%20formatting.md))
    +*   Tables
    +*   Bulleted lists
    +*   Numbered lists
    +*   Bold
    +*   Italics
    +*   Strikethrough
    +*   Highlights
    +*   Font colors
    +*   Soft line breaks
    +*   External links
    +
    +However, we do not guarantee that all of your formatting will be imported 100% correctly.
     
     ## Limitations
     
    -All resources (except for images) are created as note's attachments.
    +*   The size limit of one import is 250Mb. If the total size of your files is larger, you can increase theĀ [upload limit](../../Installation%20%26%20Setup/Server%20Installation.md), or divide your files, and run the import as many times as necessary.
    +*   All resources (except for images) are created as notes’ attachments.
    +*   If you have HTML inside ENEX files, the HTML formatting may be broken or lost after import in Trilium. SeeĀ Reporting issues.
     
    -HTML inside ENEX files is not exactly valid so some formatting maybe broken or lost. You can report major problems into [Trilium issue tracker](https://github.com/TriliumNext/Notes/issues).
    \ No newline at end of file
    +### Internal links
    +
    +The importer cannot transform Evernote internal links into Trilium internal links because Evernote internal note IDs are not preserved in ENEX files.
    +
    +If you want to restore the internal links in Trilium after you import all of your ENEX files, you can use or adapt this custom script:Ā Process internal links by title
    +
    +The script does the following:
    +
    +1.  It finds all Evernote internal links.
    +2.  For each one, it checks if its link text matches a note title, and if yes, it replaces the Evernote link with an internal Trilium link. If not, it leaves the Evernote link in place.
    +3.  If it finds more than one note with a matching note title, it leaves the Evernote link in place.
    +4.  It outputs the results in a log that you can see in the respective code note in Trilium.
    +
    +The script has the following limitations:
    +
    +*   It will not fix links to anchors and links to notes that you renamed in Evernote after you created the links.
    +*   Some note titles might not be well identified, even if they exist. This is especially the case if the note title contains some special characters. Should this be problematic, considerĀ Reporting issues.
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote/Process internal links by titl.js b/docs/User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote/Process internal links by titl.js
    new file mode 100644
    index 0000000000..03fba623ab
    --- /dev/null
    +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote/Process internal links by titl.js	
    @@ -0,0 +1,35 @@
    +const query = `note.type = "text" and note.content *=* "evernote:///view/"`;
    +const notes = api.searchForNotes(query);
    +
    +for (const note of notes) {
    +    api.log(`Processing note ${note.title}...`);
    +    
    +    const content = note.getContent();
    +    const $ = api.cheerio.load(content);
    +    
    +    $("a").each((i, el) => {
    +        const $el = $(el);
    +        
    +        const url = $el.attr("href");
    +        if (!url.startsWith("evernote:///")) return;
    +
    +        const text = $el.text();
    +        const matchingNotes = api.searchForNotes(`note.title = "${text}"`);
    +        if (matchingNotes.length === 0) {
    +            api.log(`No matching notes for "${text}..."`);
    +            return;
    +        }
    +
    +        if (matchingNotes.length > 1) {
    +            api.log(`Found multiple matching notes for "${text}". Skipping.`);
    +            return;
    +        }
    +
    +        const matchingNote = matchingNotes[0];
    +        
    +        api.log(`Found matching note: ${matchingNote.title} ${matchingNote.noteId}`);
    +        $el.attr("href", `#root/${matchingNote.noteId}`);
    +        $el.addClass("reference-link");
    +    });
    +    note.setContent($("body").html());   
    +}
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Keyboard Shortcuts.md b/docs/User Guide/User Guide/Basic Concepts and Features/Keyboard Shortcuts.md
    index 6b6ed97ca2..13259152fd 100644
    --- a/docs/User Guide/User Guide/Basic Concepts and Features/Keyboard Shortcuts.md	
    +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Keyboard Shortcuts.md	
    @@ -3,49 +3,38 @@ This is supposed to be a complete list of keyboard shortcuts. Note that some of
     
     It is also possible to configure most keyboard shortcuts in Options -> Keyboard shortcuts. Using `global:` prefix, you can assign a shortcut which will work even without Trilium being in focus (requires app restart to take effect).
     
    +## Tree
    +
    +See the corresponding section:Ā Keyboard shortcuts
    +
     ## Note navigation
     
    -*   ↑, ↓ - go up/down in the list of notes, Ctrl + Shift + ↑ and Ctrl + Shift + ↓ Ā work also from editor
    -*   ←, → - collapse/expand node
    -*   Alt + ←, Alt + → - go back / forwards in the history
    -*   Ctrl + J - show ["Jump to" dialog](Navigation/Note%20Navigation.md)
    -*   Ctrl + . - scroll to current note (useful when you scroll away from your note or your focus is currently in the editor)
    -*   Backspace - jumps to parent note
    -*   Alt + C - collapse whole note tree
    -*   Alt + - (alt with minus sign) - collapse subtree (if some subtree takes too much space on tree pane you can collapse it)
    +*   Alt + ←, Alt + → – go back / forwards in the history
    +*   Ctrl + J – show ["Jump to" dialog](Navigation/Note%20Navigation.md)
    +*   Ctrl + . – scroll to current note (useful when you scroll away from your note or your focus is currently in the editor)
    +*   Backspace – jumps to parent note
    +*   Alt + C – collapse whole note tree
    +*   Alt + - (alt with minus sign) – collapse subtree (if some subtree takes too much space on tree pane you can collapse it)
     *   you can define a [label](../Advanced%20Usage/Attributes.md) `#keyboardShortcut` with e.g. value Ctrl + I . Pressing this keyboard combination will then bring you to the note on which it is defined. Note that Trilium must be reloaded/restarted (Ctrl + R ) for changes to be in effect.
     
     See demo of some of these features in [note navigation](Navigation/Note%20Navigation.md).
     
     ## Tabs
     
    -*   Ctrl + šŸ–± Left click - (or middle mouse click) on note link opens note in a new tab
    +*   Ctrl + šŸ–± Left click – (or middle mouse click) on note link opens note in a new tab
     
     Only in desktop (electron build):
     
    -*   Ctrl + T - opens empty tab
    -*   Ctrl + W - closes active tab
    -*   Ctrl + Tab - activates next tab
    -*   Ctrl + Shift + Tab - activates previous tab
    +*   Ctrl + T – opens empty tab
    +*   Ctrl + W – closes active tab
    +*   Ctrl + Tab – activates next tab
    +*   Ctrl + Shift + Tab – activates previous tab
     
     ## Creating notes
     
    -*   `CTRL+O` - creates new note after the current note
    -*   `CTRL+P` - creates new sub-note into current note
    -*   `F2` - edit [prefix](Navigation/Note%20Navigation.md) of current note clone
    -
    -## Moving / cloning notes
    -
    -*   Ctrl + ↑ , Ctrl + ↓ - move note up/down in the note list
    -*   Ctrl + ← - move note up in the note tree
    -*   Ctrl+→ - move note down in the note tree
    -*   Shift+↑, Shift`+`↓ - multi-select note above/below
    -*   Ctrl+A - select all notes in the current level
    -*   Shift+šŸ–± Left click - multi select note which you clicked on
    -*   Ctrl+C - copies current note (or current selection) into clipboard (used for [cloning](Notes/Cloning%20Notes.md)
    -*   Ctrl+X - cuts current (or current selection) note into clipboard (used for moving notes)
    -*   Ctrl+V - pastes note(s) as sub-note into current note (which is either move or clone depending on whether it was copied or cut into clipboard)
    -*   Del - delete note / sub-tree
    +*   CTRL+O – creates new note after the current note
    +*   CTRL+P – creates new sub-note into current note
    +*   F2 – editĀ Branch prefixĀ of current note clone
     
     ## Editing notes
     
    @@ -53,22 +42,22 @@ Only in desktop (electron build):
     > For keyboard shortcuts specific toĀ TextĀ notes, refer toĀ Keyboard shortcutsĀ andĀ Markdown-like formatting.
     
     *   Enter in tree pane switches from tree pane into note title. Enter from note title switches focus to text editor. Ctrl+. switches back from editor to tree pane.
    -*   Ctrl+. - jump away from the editor to tree pane and scroll to current note
    +*   Ctrl+. – jump away from the editor to tree pane and scroll to current note
     
     ## Runtime shortcuts
     
     These are hooked in Electron to be similar to native browser keyboard shortcuts.
     
    -*   F5, Ctrl\-R - reloads Trilium front-end
    -*   Ctrl+Shift+I - show developer tools
    -*   Ctrl+F - show search dialog
    -*   Ctrl+- - zoom out
    -*   Ctrl+= - zoom in
    +*   F5, Ctrl+R – reloads Trilium front-end
    +*   Ctrl+Shift+I – show developer tools
    +*   Ctrl+F – show search dialog
    +*   Ctrl+- – zoom out
    +*   Ctrl+= – zoom in
     
     ## Other
     
    -*   Alt+O - show SQL console (use only if you know what you're doing)
    -*   Alt+M - distraction-free mode - display only note editor, everything else is hidden
    -*   F11 - toggle full screen
    -*   Ctrl + S - toggle [search](Navigation/Search.md) form in tree pane
    -*   Alt +A - show note [attributes](../Advanced%20Usage/Attributes.md) dialog
    \ No newline at end of file
    +*   Alt + O – show SQL console (use only if you know what you're doing)
    +*   Alt + M – distraction-free mode - display only note editor, everything else is hidden
    +*   F11 – toggle full screen
    +*   Ctrl + S – toggle [search](Navigation/Search.md) form in tree pane
    +*   Alt +A – show note [attributes](../Advanced%20Usage/Attributes.md) dialog
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks.md b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks.md
    index 79a61e4ad0..332ec24172 100644
    --- a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks.md	
    +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks.md	
    @@ -1,12 +1,18 @@
     # Bookmarks
    -To easily access selected notes, you can bookmark them. See demo:
    +Frequently used notes can be bookmarked, which will make them appear in theĀ Launch BarĀ for easy access.
     
    -![](Bookmarks_bookmarks.gif)
    +## Configuring the launch bar
    +
    +If bookmarks don't appear in the launch bar, then most likely the bookmark section has been hidden. Go to theĀ Launch BarĀ configuration from theĀ Global menuĀ and ensure _Bookmarks_ is in the _Visible Launchers_ section.
     
     ## Bookmark folder
     
     Space in the left panel is limited, and you might want to bookmark many items. One possible solution is to bookmark a folder, so it shows its children:
     
    -![](Bookmarks_bookmark-folder.png)
    +To do this, bookmark a folder and assign it the `#bookmarkFolder` label.
     
    -To do this, you need to add a `#bookmarkFolder` label to the note.
    \ No newline at end of file
    +## Mobile
    +
    +On mobile, bookmarks are only displayed starting with v0.102.0. Because of the more constrained screen size, the bookmarks are grouped under a single icon instead of displaying them as separate icons.
    +
    +When pressed, a menu will appear listing all the bookmarks. Bookmark folders are also supported and will appear as sub-menus.
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks_bookmark-folder.png b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks_bookmark-folder.png
    deleted file mode 100644
    index 48e9a4af59..0000000000
    Binary files a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks_bookmark-folder.png and /dev/null differ
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks_bookmarks.gif b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks_bookmarks.gif
    deleted file mode 100644
    index 20fca913f4..0000000000
    Binary files a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks_bookmarks.gif and /dev/null differ
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick edit.clone.md b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick edit.clone.md
    deleted file mode 100644
    index c769505f10..0000000000
    --- a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick edit.clone.md	
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -# Quick edit
    -This is a clone of a note. Go to its [primary location](../UI%20Elements/Quick%20edit.md).
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Quick edit.md b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick edit.md
    similarity index 52%
    rename from docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Quick edit.md
    rename to docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick edit.md
    index d844f74a1b..a9b27e7c82 100644
    --- a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Quick edit.md	
    +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick edit.md	
    @@ -3,31 +3,39 @@
     
     _Quick edit_ provides an alternative to the standard tab-based navigation and editing.
     
    -Instead of clicking on a note which switches theĀ Note TreeĀ to the newly selected note, or navigating between two differentĀ Tabs, the _Quick edit_ feature opens as a popup window that can be easily dismissed.
    +Instead of clicking on a note which switches theĀ Note TreeĀ to the newly selected note, or navigating between two differentĀ Tabs, the _Quick edit_ feature opens as a popup window that can be easily dismissed.
     
    -This feature is also well integrated withĀ CollectionsĀ such as the calendar view, which makes it easy to edit entries without having to go back and forth between the child note and the calendar.
    +This feature is also well integrated withĀ CollectionsĀ such as the calendar view, which makes it easy to edit entries without having to go back and forth between the child note and the calendar.
     
     ## Feature highlights
     
    -*   All note types are supported, includingĀ Collections.
    -*   Note that theĀ Note ListĀ will not be displayed, except for notes of typeĀ Collections.
    +*   All note types are supported, includingĀ Collections.
    +*   Note that theĀ Note ListĀ will not be displayed, except for notes of typeĀ Collections.
     *   ForĀ TextĀ notes, depending on user preference, both the floating and classic editors are supported. SeeĀ Formatting toolbar.
     *   The title and the note and the icon are editable, just like a normal tab.
     *   TheĀ Promoted AttributesĀ are also displayed.
    -    *   This integrates well withĀ CollectionsĀ where there are predefined attributes such as the _Start date_ and _End date_, allowing for easy editing.
    +    *   This integrates well withĀ CollectionsĀ where there are predefined attributes such as the _Start date_ and _End date_, allowing for easy editing.
     
     ## Accessing the quick edit
     
    -*   From theĀ Note Tree:
    +*   From theĀ Note Tree:
         *   Right click on a note and select _Quick edit_.
         *   or, press Ctrl+Right click on a note.
     *   OnĀ Internal (reference) links: 
         *   Right click and select _Quick edit_.
         *   or, press Ctrl+Right click on the link.
    -*   On aĀ Note Tooltip, press the quick edit icon.
    -*   InĀ Collections:
    -    *   ForĀ Calendar View:
    +*   On aĀ Note Tooltip, press the quick edit icon.
    +*   InĀ Collections:
    +    *   ForĀ Calendar:
             *   Clicking on an event will open that event for quick editing.
             *   If the calendar is for theĀ Day NotesĀ root, clicking on the day number will open the popup for that day note.
    -    *   ForĀ Geo Map View:
    -        *   Clicking on a marker will open that marker, but only if the map is in read-only mode.
    \ No newline at end of file
    +    *   ForĀ Geo Map:
    +        *   Clicking on a marker will open that marker, but only if the map is in read-only mode.
    +
    +## Handling of read-only notes
    +
    +The Quick edit feature has a unique behavior forĀ Read-Only Notes: 
    +
    +*   If the note is read-only due to performance reasons (auto read-only), then the note is made editable for quick editing.
    +*   If the note has been manually set to read-only, then the note is read-only to prevent accidental change.
    +    *   In this case, the note can still be edited by on-screen instructions.
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Quick edit_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick edit_image.png
    similarity index 100%
    rename from docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Quick edit_image.png
    rename to docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick edit_image.png
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick search.md b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick search.md
    index e233405cad..996cc0c467 100644
    --- a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick search.md	
    +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Quick search.md	
    @@ -5,11 +5,109 @@ The _Quick search_ function does a full-text search (that is, it searches throug
     
     The alternative to the quick search is theĀ SearchĀ function, which opens in a dedicated tab and has support for advanced queries.
     
    -For even faster navigation, it's possible to useĀ Jump to NoteĀ which will only search through the note titles instead of the content.
    +For even faster navigation, it's possible to useĀ Jump to...Ā which will only search through the note titles instead of the content.
     
     ## Layout
     
     Based on theĀ Vertical and horizontal layout, the quick search is placed:
     
     *   On the vertical layout, it is displayed right above theĀ Note Tree.
    -*   On the horizontal layout, it is displayed in theĀ Launch Bar, where it can be positioned just like any other icon.
    \ No newline at end of file
    +*   On the horizontal layout, it is displayed in theĀ Launch Bar, where it can be positioned just like any other icon.
    +
    +## Search Features
    +
    +Quick search includes the following features:
    +
    +### Content Previews
    +
    +Search results now display a 200-character preview of the note content below the note title. This preview shows the context where your search terms appear, making it easier to identify the right note without opening it.
    +
    +### Infinite Scrolling
    +
    +Results are loaded progressively as you scroll:
    +
    +*   Initial display shows 15 results
    +*   Scrolling near the bottom automatically loads 10 more results
    +*   Continue scrolling to load all matching notes
    +
    +### Visual Features
    +
    +*   **Highlighting**: Search terms appear in bold with accent colors
    +*   **Separation**: Results are separated with dividers
    +*   **Theme Support**: Highlighting colors adapt to light/dark themes
    +
    +### Search Behavior
    +
    +Quick search uses progressive search:
    +
    +1.  Shows exact matches first
    +2.  Includes fuzzy matches when exact results are fewer than 5
    +3.  Exact matches appear before fuzzy matches
    +
    +### Keyboard Navigation
    +
    +*   Press `Enter` to open the first result
    +*   Use arrow keys to navigate through results
    +*   Press `Escape` to close the quick search
    +
    +## Using Quick Search
    +
    +1.  **Typo tolerance**: Search finds results despite minor typos
    +2.  **Content previews**: 200-character snippets show match context
    +3.  **Infinite scrolling**: Additional results load on scroll
    +4.  **Specific terms**: Specific search terms return more focused results
    +5.  **Match locations**: Bold text indicates where matches occur
    +
    +## Quick Search - Exact Match Operator
    +
    +Quick Search now supports the exact match operator (`=`) at the beginning of your search query. This allows you to search for notes where the title or content exactly matches your search term, rather than just containing it.
    +
    +### Usage
    +
    +To use exact match in Quick Search:
    +
    +1.  Start your search query with the `=` operator
    +2.  Follow it immediately with your search term (no space after `=`)
    +
    +#### Examples
    +
    +*   `=example` - Finds notes with title exactly "example" or content exactly "example"
    +*   `=Project Plan` - Finds notes with title exactly "Project Plan" or content exactly "Project Plan"
    +*   `='hello world'` - Use quotes for multi-word exact matches
    +
    +#### Comparison with Regular Search
    +
    +| Query | Behavior |
    +| --- | --- |
    +| `example` | Finds all notes containing "example" anywhere in title or content |
    +| `=example` | Finds only notes where the title equals "example" or content equals "example" exactly |
    +
    +### Technical Details
    +
    +When you use the `=` operator:
    +
    +*   The search performs an exact match on note titles
    +*   For note content, it looks for exact matches of the entire content
    +*   Partial word matches are excluded
    +*   The search is case-insensitive
    +
    +### Limitations
    +
    +*   The `=` operator must be at the very beginning of the search query
    +*   Spaces after `=` will treat it as a regular search
    +*   Multiple `=` operators (like `==example`) are treated as regular text search
    +
    +### Use Cases
    +
    +This feature is particularly useful when:
    +
    +*   You know the exact title of a note
    +*   You want to find notes with specific, complete content
    +*   You need to distinguish between notes with similar but not identical titles
    +*   You want to avoid false positives from partial matches
    +
    +### Related Features
    +
    +*   For more complex exact matching queries, use the full [Search](Search.md) functionality
    +*   For fuzzy matching (finding results despite typos), use the `~=` operator in the full search
    +*   For partial matches with wildcards, use operators like `*=*`, `=*`, or `*=` in the full search
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Search.md b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Search.md
    index d8dae25c53..86d6ede755 100644
    --- a/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Search.md	
    +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Navigation/Search.md	
    @@ -13,7 +13,7 @@ Note search enables you to find notes by searching for text in the title, conten
     To search for notes, click on the magnifying glass icon on the toolbar or press the keyboard [shortcut](../Keyboard%20Shortcuts.md).
     
     1.  Set the text to search for in the _Search string_ field.
    -    1.  Apart from searching for words ad-literam, there is also the possibility to search for attributes or properties of notes.
    +    1.  Apart from searching for words literally, there is also the possibility to search for attributes or properties of notes.
         2.  See the examples below for more information.
     2.  To limit the search to a note and its sub-children, set a note in _Ancestor_.
         1.  This value is also pre-filled if the search is triggered from a [hoisted note](Note%20Hoisting.md) or a [workspace](Workspaces.md).
    @@ -66,11 +66,26 @@ The options available are:
     *   `#book #publicationYear = 1954`: Find notes with the "book" label and "publicationYear" set to 1954.
     *   `#genre *=* fan`: Find notes with the "genre" label containing the substring "fan". Additional operators include `*=*` for "contains", `=*` for "starts with", `*=` for "ends with", and `!=` for "is not equal to".
     *   `#book #publicationYear >= 1950 #publicationYear < 1960`: Use numeric operators to find all books published in the 1950s.
    -*   `#dateNote >= TODAY-30`: A "smart search" to find notes with the "dateNote" label within the last 30 days. Supported smart values include NOW +- seconds, TODAY +- days, MONTH +- months, YEAR +- years.
    +*   `#dateNote >= TODAY-30`: Find notes with the "dateNote" label within the last 30 days. Supported date values include NOW +- seconds, TODAY +- days, MONTH +- months, YEAR +- years.
     *   `~author.title *=* Tolkien`: Find notes related to an author whose title contains "Tolkien".
     *   `#publicationYear %= '19[0-9]{2}'`: Use the '%=' operator to match a regular expression (regex). This feature has been available since Trilium 0.52.
     *   `note.content %= '\\d{2}:\\d{2} (PM|AM)'`: Find notes that mention a time. Backslashes in a regex must be escaped.
     
    +### Fuzzy Search
    +
    +Trilium supports fuzzy search operators that find results with typos or spelling variations:
    +
    +*   `#title ~= trilim`: Fuzzy exact match - finds notes with titles like "Trilium" even if you typed "trilim" (with typo)
    +*   `#content ~* progra`: Fuzzy contains match - finds notes containing words like "program", "programmer", "programming" even with slight misspellings
    +*   `note.content ~* develpment`: Will find notes containing "development" despite the typo
    +
    +**Important notes about fuzzy search:**
    +
    +*   Fuzzy search requires at least 3 characters in the search term
    +*   Maximum edit distance is 2 characters (number of character changes needed)
    +*   Diacritics are normalized (e.g., "cafƩ" matches "cafe")
    +*   Fuzzy matches work best for finding content with minor typos or spelling variations
    +
     ### Advanced Use Cases
     
     *   `~author.relations.son.title = 'Christopher Tolkien'`: Search for notes with an "author" relation to a note that has a "son" relation to "Christopher Tolkien". This can be modeled with the following note structure:
    @@ -117,6 +132,31 @@ Some queries can only be expressed with negation:
     
     This query finds all book notes not in the "Tolkien" subtree.
     
    +## Progressive Search Strategy
    +
    +Trilium uses a progressive search strategy that performs exact matching first, then adds fuzzy matching when needed.
    +
    +### How Progressive Search Works
    +
    +1.  **Phase 1 - Exact Matching**: When you search, Trilium first looks for exact matches of your search terms. This handles the vast majority of searches (90%+) and returns results almost instantly.
    +2.  **Phase 2 - Fuzzy Fallback**: If Phase 1 doesn't find enough high-quality results (fewer than 5 results with good relevance scores), Trilium automatically adds fuzzy matching to find results with typos or spelling variations.
    +3.  **Result Ordering**: Exact matches always appear before fuzzy matches, regardless of individual scores. This ensures that when you search for "project", notes containing the exact word "project" will appear before notes containing similar words like "projects" or "projection".
    +
    +### Progressive Search Behavior
    +
    +*   **Speed**: Most searches complete using only exact matching
    +*   **Ordering**: Exact matches appear before fuzzy matches
    +*   **Fallback**: Fuzzy matching activates when exact matches return fewer than 5 results
    +*   **Identification**: Results indicate whether they are exact or fuzzy matches
    +
    +### Search Performance
    +
    +Search system specifications:
    +
    +*   Content size limit: 10MB per note (previously 50KB)
    +*   Edit distance calculations for fuzzy matching
    +*   Infinite scrolling in Quick Search
    +
     ## Under the Hood
     
     ### Label and Relation Shortcuts
    @@ -142,7 +182,7 @@ However, common label and relation searches have shortcut syntax:
     
     ### Separating Full-Text and Attribute Parts
     
    -Search syntax allows combining full-text search with attribute-based search seamlessly. For example, `tolkien #book` contains:
    +Search syntax allows combining full-text search with attribute-based search. For example, `tolkien #book` contains:
     
     1.  Full-text tokens - `tolkien`
     2.  Attribute expressions - `#book`
    @@ -181,4 +221,21 @@ This finds notes created in May 2019. Numeric operators like `#publicationYear >
     
     You can open Trilium and automatically trigger a search by including the search [url encoded](https://meyerweb.com/eric/tools/dencoder/) string in the URL:
     
    -`http://localhost:8080/#?searchString=abc`
    \ No newline at end of file
    +`http://localhost:8080/#?searchString=abc`
    +
    +## Search Configuration
    +
    +### Parameters
    +
    +| Parameter | Value | Description |
    +| --- | --- | --- |
    +| MIN\_FUZZY\_TOKEN\_LENGTH | 3 | Minimum characters for fuzzy matching |
    +| MAX\_EDIT\_DISTANCE | 2 | Maximum character changes allowed |
    +| RESULT\_SUFFICIENCY\_THRESHOLD | 5 | Minimum exact results before fuzzy fallback |
    +| MAX\_CONTENT\_SIZE | 10MB | Maximum note content size for search processing |
    +
    +### Limits
    +
    +*   Searched note content is limited to 10MB per note to prevent performance issues
    +*   Notes exceeding this limit will still be included in title and attribute searches
    +*   Fuzzy matching requires tokens of at least 3 characters
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes.md
    index 8cb069e53a..d461a3506a 100644
    --- a/docs/User Guide/User Guide/Basic Concepts and Features/Notes.md	
    +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes.md	
    @@ -25,7 +25,7 @@ When you delete a note in Trilium, it is actually only marked for deletion (soft
     
     Within (by default) 7 days, it is possible to undelete these soft-deleted notes - open theĀ Recent ChangesĀ dialog, and you will see a list of all modified notes including the deleted ones. Notes available for undeletion have a link to do so. This is kind of "trash can" functionality known from e.g. Windows.
     
    -Clicking an undelete will recover the note, it's content and attributes - note should be just as before being deleted. This action will also undelete note's children which have been deleted in the same action.
    +Clicking an undelete will recover the note, its content and attributes - note should be just as before being deleted. This action will also undelete note's children which have been deleted in the same action.
     
     To be able to undelete a note, it is necessary that deleted note's parent must be undeleted (otherwise there's no place where we can undelete it to). This might become a problem when you delete more notes in succession - the solution is then undelete in the reverse order of your deletion.
     
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/1_Export as PDF_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/1_Printing & Exporting as PD.png
    similarity index 100%
    rename from docs/User Guide/User Guide/Basic Concepts and Features/Notes/1_Export as PDF_image.png
    rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/1_Printing & Exporting as PD.png
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Export as PDF.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Export as PDF.md
    deleted file mode 100644
    index 20f5b73942..0000000000
    --- a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Export as PDF.md	
    +++ /dev/null
    @@ -1,38 +0,0 @@
    -# Export as PDF
    -![](Export%20as%20PDF_image.png)
    -
    -Screenshot of the note contextual menu indicating the ā€œExport as PDFā€ option.
    -
    -On the desktop application of Trilium it is possible to export a note as PDF. On the server or PWA (mobile), the option is not available due to technical constraints and it will be hidden.
    -
    -To print a note, select the ![](1_Export%20as%20PDF_image.png) button to the right of the note and select _Export as PDF_.
    -
    -Afterwards you will be prompted to select where to save the PDF file.
    -
    -## Automatic opening of the file
    -
    -When the PDF is exported, it is automatically opened with the system default application for easy preview.
    -
    -Note that if you are using Linux with the GNOME desktop environment, sometimes the default application might seem incorrect (such as opening in GIMP). This is because it uses Gnome's ā€œRecommended applicationsā€ list.
    -
    -To solve this, you can change the recommended application for PDFs via this command line. First, list the available applications via `gio mime application/pdf` and then set the desired one. For example to use GNOME's Evince:
    -
    -```
    -gio mime application/pdf
    -```
    -
    -## Reporting issues with the rendering
    -
    -Should you encounter any visual issues in the resulting PDF file (e.g. a table does not fit properly, there is cut off text, etc.) feel free to [report the issue](../../Troubleshooting/Reporting%20issues.md). In this case, it's best to offer a sample note (click on the ![](1_Export%20as%20PDF_image.png) button, select Export note → This note and all of its descendants → HTML in ZIP archive). Make sure not to accidentally leak any personal information.
    -
    -## Landscape mode
    -
    -When exporting to PDF, there are no customizable settings such as page orientation, size, etc. However, it is possible to specify a given note to be printed as a PDF in landscape mode by adding the `#printLandscape` attribute to it (seeĀ Attributes).
    -
    -## Page size
    -
    -By default, the resulting PDF will be in Letter format. It is possible to adjust it to another page size via the `#printPageSize` attribute, with one of the following values: `A0`, `A1`, `A2`, `A3`, `A4`, `A5`, `A6`, `Legal`, `Letter`, `Tabloid`, `Ledger`.
    -
    -## Keyboard shortcut
    -
    -It's possible to trigger the export to PDF from the keyboard by going toĀ _Keyboard shortcuts_Ā inĀ OptionsĀ and assigning a key combination for the `exportAsPdf` action.
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List.md
    index 1caff1801e..16b3caf280 100644
    --- a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List.md	
    +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Note List.md	
    @@ -12,4 +12,4 @@ When a note has one or more child notes, they will be listed at the end of the n
     
     The view types dictate how the child notes are represented. By default, the notes will be displayed in a grid, however there are also some other view types available.
     
    -Generally the view type can only be changed in aĀ CollectionsĀ note from theĀ Ribbon, but it can also be changed manually on any type of note using the `#viewType` attribute.
    \ No newline at end of file
    +Generally the view type can only be changed in aĀ CollectionsĀ note from theĀ Ribbon, but it can also be changed manually on any type of note using the `#viewType` attribute.
    \ No newline at end of file
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Export as PDF_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PD.png
    similarity index 100%
    rename from docs/User Guide/User Guide/Basic Concepts and Features/Notes/Export as PDF_image.png
    rename to docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PD.png
    diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md
    new file mode 100644
    index 0000000000..b110d09b03
    --- /dev/null
    +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md	
    @@ -0,0 +1,120 @@
    +# Printing & Exporting as PDF
    +
    Screenshot of the note contextual menu indicating the ā€œExport as PDFā€ option.
    + +## Printing + +This feature allows printing of notes. It works on both the desktop client, but also on the web. + +Note that not all note types are printable as of now. We do plan to increase the coverage of supported note types in the future. + +To print a note, select the button to the right of the note and select _Print note_. Depending on the size and type of the note, this can take up to a few seconds. Afterwards you will be redirected to the system/browser printing dialog. + +> [!NOTE] +> Printing and exporting as PDF are not perfect. Due to technical limitations, and sometimes even browser glitches the text might appear cut off in some circumstances.Ā  + +## Reporting issues with the rendering + +Should you encounter any visual issues in the resulting PDF file (e.g. a table does not fit properly, there is cut off text, etc.) feel free to [report the issue](../../Troubleshooting/Reporting%20issues.md). In this case, it's best to offer a sample note (click on the button, select Export note → This note and all of its descendants → HTML in ZIP archive). Make sure not to accidentally leak any personal information. + +Consider adjusting font sizes and using [page breaks](../../Note%20Types/Text/Insert%20buttons.md) to work around the layout. + +## Exporting as PDF + +On the desktop application of Trilium it is possible to export a note as PDF. On the server or PWA (mobile), the option is not available due to technical constraints and it will be hidden. + +To print a note, select the ![](1_Printing%20&%20Exporting%20as%20PD.png) button to the right of the note and select _Export as PDF_. Afterwards you will be prompted to select where to save the PDF file. + +> [!TIP] +> Although direct export as PDF is not available in the browser version of the application, it's still possible to generate a PDF by selecting the _Print_ option instead and selecting ā€œSave to PDFā€ as the printer (depending on the browser). Generally, Mozilla Firefox has better printing capabilities. + +### Automatic opening of the file + +When the PDF is exported, it is automatically opened with the system default application for easy preview. + +Note that if you are using Linux with the GNOME desktop environment, sometimes the default application might seem incorrect (such as opening in GIMP). This is because it uses Gnome's ā€œRecommended applicationsā€ list. + +To solve this, you can change the recommended application for PDFs via this command line. First, list the available applications via `gio mime application/pdf` and then set the desired one. For example to use GNOME's Evince: + +``` +gio mime application/pdf +``` + +### Customizing exporting as PDF + +When exporting to PDF, there are no customizable settings such as page orientation, size. However, there are a fewĀ AttributesĀ to adjust some of the settings: + +* To print in landscape mode instead of portrait (useful for big diagrams or slides), add `#printLandscape`. +* By default, the resulting PDF will be in Letter format. It is possible to adjust it to another page size via the `#printPageSize` attribute, with one of the following values: `A0`, `A1`, `A2`, `A3`, `A4`, `A5`, `A6`, `Legal`, `Letter`, `Tabloid`, `Ledger`. + +> [!NOTE] +> These options have no effect when used with the printing feature, since the user-defined settings are used instead. + +## Printing multiple notes + +Since v0.100.0, it is possible to print more than one note at the time by usingĀ Collections: + +1. First create a collection. +2. Configure it to useĀ List View. +3. Print the collection note normally. + +The resulting collection will contain all the children of the collection, while maintaining the hierarchy. + +> [!NOTE] +> Not all note types are supported when printing or exporting to PDF. When an unsupported note is encountered, it is skipped. At the end, if any of the notes were skipped, a message will be displayed with the possibility of viewing the full list of skipped notes. The same limitations as the ones described in _Constraints & limitations_ apply. + +## Keyboard shortcut + +It's possible to trigger both printing and export as PDF from the keyboard by going toĀ _Keyboard shortcuts_Ā inĀ OptionsĀ and assigning a key combination for: + +* _Print Active Note_ +* _Export Active Note as PDF_ + +## Constraints & limitations + +Not allĀ Note TypesĀ are supported when printing, in which case the _Print_ and _Export as PDF_ options will be disabled. + +* ForĀ CodeĀ notes: + * Line numbers are not printed. + * Syntax highlighting is enabled, however a default theme (Visual Studio) is enforced. +* ForĀ Collections, the following are supported: + * List View, allowing to print multiple notes at once while preserving hierarchy (similar to a book). + * Presentation, where each slide/sub-note is displayed. + * Most note types are supported, especially the ones that have an image representation such asĀ CanvasĀ andĀ Mind Map. + * Table, where the table is rendered in a print-friendly way. + * Tables that are too complex (especially if they have multiple columns) might not fit properly, however tables with a large number of rows are supported thanks to pagination. + * Consider printing in landscape mode, or using `#printLandscape` if exporting to PDF. + * The rest of the collections are not supported, but we plan to add support for all the collection types at some point. +* UsingĀ Custom app-wide CSSĀ for printing is no longer supported, instead a custom `printCss` relation needs to be used (see below). + +## Customizing the print CSS + +As an advanced use case, it's possible to customize the CSS used for printing such as adjusting the fonts, sizes or margins. Note thatĀ Custom app-wide CSSĀ will not work for printing. + +To do so: + +* Create a CSS [code note](../../Note%20Types/Code.md). +* On the note being printed, apply the `~printCss` relation to point to the newly created CSS code note. +* To apply the CSS to multiple notes, consider using [inheritable attributes](../../Advanced%20Usage/Attributes/Attribute%20Inheritance.md) orĀ Templates. + +For example, to change the font of the document from the one defined by the theme or the user to a serif one: + +``` +body { + --main-font-family: serif !important; + --detail-font-family: var(--main-font-family) !important; +} +``` + +To remark: + +* Multiple CSS notes can be add by using multiple `~printCss` relations. +* If the note pointing to the `printCss` doesn't have the right note type or mime type, it will be ignored. +* If migrating from a previous version whereĀ Custom app-wide CSS, there's no need for `@media print {`  since the style-sheet is used only for printing. + +## Under the hood + +Both printing and exporting as PDF use the same mechanism: a note is rendered individually in a separate webpage that is then sent to the browser or the Electron application either for printing or exporting as PDF. + +The webpage that renders a single note can actually be accessed in a web browser. For example `http://localhost:8080/#root/WWRGzqHUfRln/RRZsE9Al8AIZ?ntxId=0o4fzk` becomes `http://localhost:8080/?print#root/WWRGzqHUfRln/RRZsE9Al8AIZ`. + +Accessing the print note in a web browser allows for easy debugging to understand why a particular note doesn't render well. The mechanism for rendering is similar to the one used inĀ Note List. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.md index 0163c1b78b..36e265df98 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes.md @@ -40,4 +40,4 @@ When pressed, the note will become editable but will become read-only again afte Some note types have a special behavior based on whether the read-only mode is enabled: * Mermaid DiagramsĀ will hide the Mermaid source code and display the diagram preview in full-size. In this case, the read-only mode can be easily toggled on or off via a dedicated button in theĀ Floating buttonsĀ area. -* Geo Map ViewĀ will disallow all interaction that would otherwise change the map (dragging notes, adding new items). \ No newline at end of file +* Geo Map ViewĀ will disallow all interaction that would otherwise change the map (dragging notes, adding new items). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Sorting Notes.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Sorting Notes.md index 539f42ac07..7519e7be4d 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Sorting Notes.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Sorting Notes.md @@ -28,4 +28,4 @@ Sorting is done by comparing note properties or specific labels on child notes. * **Label Sorting**: If `#sorted` has any other value, this value is treated as the name of a child note's label, and sorting is based on the values of this label. For example, setting `#sorted=myOrder` on the parent note and using `#myOrder=001`, `#myOrder=002`, etc., on child notes. 4. **Alphabetical Sorting**: Used as a last resort when other criteria result in equality. -All comparisons are made string-wise (e.g., "1" < "2" or "2020-10-10" < "2021-01-15", but also "2" > "10"). \ No newline at end of file +All comparisons are made string-wise (e.g., "1" \< "2" or "2020-10-10" < "2021-01-15", but also "2" \> "10"). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Themes/Icon Packs.md b/docs/User Guide/User Guide/Basic Concepts and Features/Themes/Icon Packs.md new file mode 100644 index 0000000000..e493ce2fab --- /dev/null +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Themes/Icon Packs.md @@ -0,0 +1,61 @@ +# Icon Packs +> [!IMPORTANT] +> This feature is still in preview and is available only in the [nightly release](https://docs.triliumnotes.org/user-guide/advanced-usage/nightly-release). + +
    + +By default, Trilium comes with a set of icons called Boxicons v2. Since v0.102.0, custom icon packs allow a wider selection of icons for notes. + +Icon packs are specific to Trilium, so they must either be created from scratch (see below) or imported from a ZIP file from a third-party developer. + +## Sample icon packs + +The Trilium team maintains a few icon packs that are not shipped with Trilium. These icon packs can be found on the official website on the [Resources page](https://triliumnotes.org/resources). + +## Importing an existing icon pack + +> [!NOTE] +> **Icon packs are third-party content** +> +> Apart from the [sample icon packs](https://triliumnotes.org/resources), the Trilium maintainers are not responsible for keeping icon packs up to date. If you have an issue with a specific icon pack, then the issue must be reported to the third-party developer responsible for it, not the Trilium team. + +To import an icon pack: + +1. Ideally, create a dedicated spot in your note tree where to place the icon packs. +2. Right click the note where to put it and select _Import into note_. +3. Uncheck _Safe import_. +4. Select _Import_. +5. [Refresh the application](../../Troubleshooting/Refreshing%20the%20application.md). + +> [!WARNING] +> Since _Safe import_ is disabled, make sure you trust the source as it could contain dangerous third-party scripts. One good way to check if the icon pack is safe is to manually extract the .zip and inspect the file contents. Icon packs should only contain a font file and a JSON file. Other files (especially scripts) are to be considered harmful. + +## Creating an icon pack + +Creating an icon pack requires some scripting knowledge outside Trilium in order to generate the list of icons. For information, seeĀ Creating an icon pack. + +## Using an icon from an icon pack + +After [refreshing the application](../../Troubleshooting/Refreshing%20the%20application.md), the icon pack should be enabled by default. To test this, simply select an existing note or create a new one and try to change the note icon. + +There should be a _Filter_ button to the right of the search bar in the icon list. Clicking it allows filtering by icon pack and the newly imported icon pack should be displayed there. + +> [!NOTE] +> If the icon pack is missing from that list, then most likely there's something wrong with it. +> +> * Try checking theĀ Backend (server) logsĀ for clues and make sure that the icon pack has the `#iconPack` [label](../../Advanced%20Usage/Attributes/Labels.md) with a value assigned to it (a prefix). +> * Icon packs that are [protected](../Notes/Protected%20Notes.md) are ignored. + +## Integration with the share and export functionality + +Custom icon packs are also supported by theĀ SharingĀ feature, where they will be shown in the note tree. However, in order for an icon pack to be visible to the share function, the icon pack note must also be shared. + +If you are using a custom share theme, make sure it supports the `iconPackCss`, otherwise icons will not show up. Check the original share template source code for reference. + +Custom icon packs will also be preserved whenĀ Exporting static HTML for web publishing. In this case, there's no requirement to make the icon pack shared. + +## What happens if I remove an icon pack + +If an icon pack is removed or disabled (by removing or altering its `#iconPack` label), all the notes that use this icon pack will show in theĀ Note TreeĀ with no icon. This won't cause any issues apart from looking strange. + +The solution is to replace the icons with some else, try usingĀ SearchĀ which supports bulk actions, to identify the notes with the now deleted icon pack (by looking for the prefix) and changing or removing their `iconClass`. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Themes/Icon Packs_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/Themes/Icon Packs_image.png new file mode 100644 index 0000000000..2730befaa6 Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/Themes/Icon Packs_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Themes/Theme Gallery.md b/docs/User Guide/User Guide/Basic Concepts and Features/Themes/Theme Gallery.md index c78920694f..34a7811a05 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/Themes/Theme Gallery.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Themes/Theme Gallery.md @@ -27,4 +27,4 @@ These themes may or may not be compatible with the latest versions of TriliumNex | [Blue](https://github.com/SiriusXT/trilium-theme-blue) (dark) | [SiriusXT](https://github.com/SiriusXT) | > [!TIP] -> If you would like to add your theme to this gallery, write a new post in [šŸ‘ Show and tell](https://github.com/TriliumNext/Notes/discussions/categories/show-and-tell). \ No newline at end of file +> If you would like to add your theme to this gallery, write a new post in [šŸ‘ Show and tell](https://github.com/TriliumNext/Trilium/discussions/categories/show-and-tell). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/1_New Layout_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/1_New Layout_image.png new file mode 100644 index 0000000000..c9a85f7773 Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/1_New Layout_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/2_New Layout_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/2_New Layout_image.png new file mode 100644 index 0000000000..efd435a32d Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/2_New Layout_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/3_New Layout_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/3_New Layout_image.png new file mode 100644 index 0000000000..10676a08ef Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/3_New Layout_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/4_New Layout_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/4_New Layout_image.png new file mode 100644 index 0000000000..b4452f6952 Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/4_New Layout_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/5_New Layout_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/5_New Layout_image.png new file mode 100644 index 0000000000..4a2f36ae2e Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/5_New Layout_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/6_New Layout_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/6_New Layout_image.png new file mode 100644 index 0000000000..ca7593700b Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/6_New Layout_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Launch Bar.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Launch Bar.md index 795e026021..c47103ba70 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Launch Bar.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Launch Bar.md @@ -1,7 +1,11 @@ # Launch Bar ## Position of the Launch bar -Depending on the layout selected, the launcher bar will either be on the left side of the screen with buttons displayed vertically or at the top of the screen. SeeĀ [Vertical and horizontal layout](Vertical%20and%20horizontal%20layout.md)Ā for more information. +On desktop, depending on the layout selected, the launcher bar will either be on the left side of the screen with buttons displayed vertically or at the top of the screen. SeeĀ Vertical and horizontal layoutĀ for more information. + +On mobile, the launch bar will always be at the bottom. + +If there are too many items in the launch bar to fit the screen, it will become scrollable. ## Terminology @@ -9,30 +13,38 @@ Depending on the layout selected, the launcher bar will either be on the left si * **Available Launcher**: a launcher that is not displayed on the launch bar, but can be added. * **Visible Launcher**: a launcher that is currently displayed on the launch bar. -## Configuring the Launch bar +## Configuring the desktop Launch bar There are two ways to configure the launch bar: * Right click in the empty space between launchers on the launch bar and select _Configure Launchbar._ -* Click on theĀ [Global menu](Global%20menu.md)Ā and select _Configure Launchbar_. +* Click on theĀ Global menuĀ and select _Configure Launchbar_. -This will open a new tab with theĀ [Note Tree](Note%20Tree.md)Ā listing the launchers. +This will open a new tab with theĀ Note TreeĀ listing the launchers. ![](Launch%20Bar_image.png) Expanding _Available Launchers_ section will show the list of launchers that are not displayed on the launch bar. The _Visible Launchers_ will show the ones that are currently displayed. +## Configuring the mobile launch bar + +The launch bar on mobile uses a different configuration from the desktop one. The reasoning is that not all desktop icons are available on mobile, and fewer icons fit on a mobile screen. + +To configure the launch bar on mobile, go toĀ Global menuĀ and select _Configure Launchbar_. + +The configure the mobile launch bar while on the desktop (especially useful to configure more complicated launchers such as scripts or custom widgets), go toĀ Global menu → Advanced → Show Hidden Subtree and look for the _Mobile Launch Bar_ section. While in the hidden subtree, it's also possible to drag launchers between the _Mobile Launch Bar_ and (Desktop) _Launch Bar_ sections. + ### Adding/removing and reordering launchers To display a new launcher in the launch bar, first look for it in the _Available Launchers_ section. Then right click it and select _Move to visible launchers_. It is also possible to drag and drop the item manually. Similarly, to remove it from the launch bar, simply look for it in _Visible Launchers_ then right click it and select _Move to available launchers_ or use drag-and-drop. -Drag-and-drop the items in theĀ treeĀ in order to change their order. SeeĀ [Note Tree](Note%20Tree.md)Ā for more interaction options, including using keyboard shortcuts. +Drag-and-drop the items in theĀ treeĀ in order to change their order. SeeĀ Note TreeĀ for more interaction options, including using keyboard shortcuts. ## Customizing the launcher -* The icon of a launcher can be changed just like a normal note. SeeĀ [Note Icons](../Notes/Note%20Icons.md)Ā for more information. +* The icon of a launcher can be changed just like a normal note. SeeĀ Note IconsĀ for more information. * The title of the launcher can also be changed. ### Resetting @@ -47,17 +59,17 @@ Right click either the _Available launchers_ or _Visible launchers_ sections and A note launcher will simply navigate to a specified note. 1. Set the `target` promoted attribute to the note to navigate to. - 2. Optionally, set `hoistedNote` to hoist a particular note. SeeĀ [Note Hoisting](../Navigation/Note%20Hoisting.md)Ā for more information. + 2. Optionally, set `hoistedNote` to hoist a particular note. SeeĀ Note HoistingĀ for more information. 3. Optionally, set a `keyboardShortcut` to trigger the launcher. 2. **Script Launcher** - An advanced launcher which will run a script upon pressing. SeeĀ [Scripts](../../Scripting.md)Ā for more information. + An advanced launcher which will run a script upon pressing. SeeĀ ScriptingĀ for more information. 1. Set `script` to point to the desired script to run. 2. Optionally, set a `keyboardShortcut` to trigger the launcher. 3. **Custom Widget** - Allows defining a custom widget to be rendered inside the launcher. SeeĀ [Widget Basics](../../Scripting/Custom%20Widgets/Widget%20Basics.md)Ā for more information. + Allows defining a custom widget to be rendered inside the launcher. SeeĀ Widget BasicsĀ for more information. 4. **Spacers** Launchers that create some distance between other launchers for better visual distinction. -Launchers are configured via predefinedĀ [Promoted Attributes](../../Advanced%20Usage/Attributes/Promoted%20Attributes.md). \ No newline at end of file +Launchers are configured via predefinedĀ Promoted Attributes. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout.md new file mode 100644 index 0000000000..3f30c6ee55 --- /dev/null +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout.md @@ -0,0 +1,141 @@ +# New Layout +The _New layout_ is a series of UI/UX changes that were introduced in v0.101.0 that heavily change both existing UI elements, as well as adding some new ones. The goal of this new layout is to modernize the application and to make it more intuitive but at the same time to reduce clutter. + +## Newly introduced features + +### Status bar + +At the bottom of the window there is a new bar called the _Status bar_. This bar houses multiple items such as the Breadcrumb navigation and information and settings about the current note, such as the [content language](../../Note%20Types/Text/Content%20language%20%26%20Right-to-le.md) andĀ Attributes. + +For more information, consult the [dedicated page](New%20Layout/Status%20bar.md). + +
    + +### Inline title + +In previous versions of Trilium, the title bar was fixed at all times. In the new layout, there is both a fixed title bar and one that scrolls with the text. The newly introduced title is called the _Inline title_ and it displays the title in a larger font, while also displaying additional information such as the creation and the modification date. + +Whenever the title is scrolled past, the fixed title is shown instead. + +This only affectsĀ TextĀ andĀ CodeĀ notes. Note types that take the entirety of the screen such asĀ CanvasĀ will always have only the fixed title bar. + +Depending on the note type, the inline title will also present some more interactive options such as being able to switch the note type (see below). + +
    The Inline title, which is displayed at the top of the note and can be scrolled past.
    The fixed title bar. The title only appears after scrolling past the Inline title.
    + +### New note type switcher + +When a newĀ TextĀ orĀ CodeĀ note is created, a note type switcher will appear below the _Inline title_. Apart from changing the note type, it's also possible to apply a [template](../../Advanced%20Usage/Templates.md). + +The switcher will disappear as soon as a text is entered. + + + +### Note badges + +Note badges appear near the fixed note title and indicate important information about the note such as whether it is read-only. Some of the badges are also interactive. + +
    + +The following badges are available: + +* **Read-only badge**, which will be shown if the note is not editable due to either automatic read-only or manual read-only. Clicking on the badge will temporarily edit the note (similar to the Edit [floating button](Floating%20buttons.md)). +* **Share badge**, which will indicate that the current note is shared. The badge will also indicate if the share is on the local network (for the desktop application withoutĀ SynchronizationĀ set up) or publicly accessible (for the server). +* **Web clip badge**, which will indicate if the note was clipped using theĀ Web Clipper. The badge acts as a link, so it can be clicked on to navigate to the page or right clicked for more options. +* **Execute badge**, for [scripts](../../Scripting.md) or [saved SQL queries](../../Advanced%20Usage/Database/Manually%20altering%20the%20database/SQL%20Console.md) which have an execute button or a description. + +Some of these badges replace the dedicated panels at the top of the note. + +### Collapsible sections + +
    + +The following sections have been made collapsible: + +* _Promoted Attributes_ + * For full-height notes such asĀ Canvas, the promoted attributes are collapsed by default to make room. + * The keyboard shortcut previously used to trigger the promoted attributes ribbon tab (which was no longer working) has been repurposed to toggle the promoted attributes instead. +* _Edited Notes_, which appears forĀ Day NotesĀ is now shown underneath the title. + * Whether the section is collapsed or not depends on the choice inĀ Options → Appearance. +* _Search Properties_, which appears for the fullĀ SearchĀ andĀ Saved Search. + +### Save status indicator + +To the right of the note title, a temporary indicators appears after making a change to the document that indicates whether the document has been saved. + +It indicates the following states: + +* _Unsaved_, if the changes will be saved soon. +* _Saving_, if the changes are being saved. +* _Saved_, if all the changes were successfully saved to the server. +* _Error_, if the changes could not be saved, for example due to a communication server with the server. + +After all changes have been saved, the indicator will hide automatically after a few seconds. + +## Changing to the existing layout + +### Removal of the ribbon + +The most significant change is the removal of the ribbon. All the actions and options from the ribbon were integrated in other places in the application. + +Here's how all the different tabs that were once part of the ribbon are now available in the new layout: + +* ā€œFormatting toolbarā€ was relocated to the top of the page. + * Instead of having one per split, now there is a single formatting toolbar per tab. This allows more space for the toolbar items. +* ā€œOwned attributesā€ and ā€œInherited attributesā€ were merged and moved to the status bar region (displayed one above the other). +* ā€œBasic Propertiesā€ were integrated in theĀ Note buttonsĀ menu. + * The only exception here is the Language combo box which can now be found in the status bar (top-right of the screen). +* ā€œFileā€ and ā€œImageā€ tabs + * The buttons were moved to the right of the note title, as dedicated entries inĀ Note buttons. + * The info section has been merged into the _Note info_ section of the status bar. +* Edited notes + * Moved underneath the title, displayed under a collapsible area and the notes are represented as badges/chips. + * Whether the section is expanded or collapsed depends on the ā€œEdited Notes ribbon tab will automatically open on day notesā€ setting from Options → Appearance. +* Search definition tab + * Moved underneath the title under a collapsible area. + * Expanded by default for new searches, collapsed for saved searches. +* The Note map is now available in the Note actions menu. + * Instead of opening into a panel in the ribbon, the note map now opens in a side split (similar to the in-app help). +* ā€œNote infoā€ tab was moved to a small (i) icon in the status bar. +* ā€œSimilar notesā€ tab + * Moved to the status bar, by going to the ā€œNote infoā€ section and pressing the button to show similar notes. + * Displayed as a fixed panel, similar to the attributes. +* The Collection properties tab were relocated under the note title and grouped into: + * A combo box to quickly switch between views. + * Individual settings for the current view in a submenu. +* Some smaller ribbon tabs were converted to badges that appear near the note title in the breadcrumb section: + * Original URL indicator for clipped web pages (`#pageUrl`). + * SQL and script execute buttons. + +> [!NOTE] +> The ribbon keyboard shortcuts (e.g. `toggleRibbonTabClassicEditor`) have been repurposed to work on the new layout, where they will toggle the appropriate panel. + +### Removal of the floating buttons + +Most of the buttons were relocated to the right of the note title, in theĀ Note buttonsĀ area, with the exception of: + +* The Edit button is displayed near the note title, as a badge. +* _Backlinks_ is displayed in the status bar. When clicked, the same list of backlinks is displayed. +* Relation map zoom buttons are now part of the relation map itself. +* Export image to PNG/SVG are now in the Note actions menu, in the _Export as image_ option. + +### Changes to the sidebar + +The sidebar (also known as the right pane) also received some important changes. + +The previous iteration of the sidebar would appear contextually, depending on whether there are any items to be displayed. This caused occasional content shifts when moving between two panes in a split view. In the new layout, the sidebar acts more like theĀ Note TreeĀ pane, remaining visible even if there is nothing to display. + +In order to toggle the sidebar, there is a new button on the top-right side of the screen, near the window buttons (on Windows and Linux). + +Now each section of the sidebar (e.g. ā€œTable of Contentsā€, ā€œHighlights listā€) is individually collapsible and will remember whether it was collapsed. + +Some sidebar items also have a contextual menu, indicated by the three dots on the title. For example, the highlights filter can be adjusted directly from that menu.Ā  + +Custom widgets are still supported. For custom scripts, the three dots menu allows quick navigation to the corresponding script note. + +## How to toggle the new layout + +Starting with v0.101.0, this new layout is enabled by default. It is possible to fall back to the old layout by going toĀ Options → Appearance and selecting _Old layout_. + +> [!IMPORTANT] +> Since a new layout was introduced, this becomes the standard one. The _Old layout_ is considered deprecated and will not receive new features (for example, the breadcrumb) as we focus on the new one. At some point the old layout will be removed entirely, as maintaining two layouts with major differences creates a maintenance burden. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb.md new file mode 100644 index 0000000000..fb27f092a2 --- /dev/null +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb.md @@ -0,0 +1,26 @@ +# Breadcrumb +
    + +The breadcrumb allows quickly viewing the note hierarchy of the current note and navigating through it. + +It is part of theĀ Status bar, displayed in the bottom-left of the screen. + +## Layout and Interaction + +* If a note or workspace is hoisted, a badge will appear on the left-most side. + * Clicking on the badge will un-hoist the note/workspace. +* The left-most icon represents the root note, or the hoisted note or workspace. + * Clicking the icon will jump to the root note. + * Right clicking the icon will display a menu that allows opening the note in a new tab, split, etc. +* Each segment shows the title of a note in the current note hierarchy. + * Clicking the icon will jump to that note. + * Right clicking will open a menu with multiple options such as opening the note in a different tab/split/window, hoisting, moving/cloning the note, duplicating as well as changing the color of the note. +* Clicking the arrow next to each segment will reveal the child notes of the segment on the left. + * Clicking on an icon will navigate to that particular note. + * It's also possible to create a new child note from here. + * The menu can optionally hide the archived notes. +* If the current note is deep within a hierarchy, the segments will collapse into a \[…\] button in order not to occupy too much space. + * Clicking this button will display each collapsed entry as a menu item. Clicking on it will navigate to that particular note. +* Right clicking on an empty space to the right of the breadcrumb (before the other status bar items) will reveal another menu that allows: + * Toggling whether archived notes are displayed in the breadcrumb and in the note tree. + * Copying the current note path to clipboard. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb_image.png new file mode 100644 index 0000000000..4a2f36ae2e Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Status bar.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Status bar.md new file mode 100644 index 0000000000..f5c12d3a78 --- /dev/null +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Status bar.md @@ -0,0 +1,27 @@ +# Status bar +The status bar displays information about the current note and allows changing settings related to it such as configuring the language or attributes. + +## Layout and interaction + +On the left side, theĀ BreadcrumbĀ is displayed which indicates the current note as well as its parent notes and allows for quick navigation throughout the hierarchy. + +On the right side, specific sections will show depending on the type of the current note. + +1. For code notes, the language mode of the note is indicated (e.g. JavaScript, plain text), as well as allowing easy switching to another mode. +2. For text notes, the content language is displayed and can be changed, thus configuring the spell-check and the right-to-left support. + 1. Note that this applies to the entire note and not the selection, unlike some text editors. +3. If a note is placed in multiple places in the tree (cloned), the number of the note paths will be displayed. + 1. Clicking it will reveal the full list of note paths and a button to place it somewhere else. +4. If a note has attachments, their number will be displayed. + 1. Clicking on it will reveal the list of attachments in a new tab. +5. If a note is linked from other text notes (backlinks), the number of backlinks will be displayed. + 1. Clicking on it will show the list of notes that link to this note, as well as an excerpt of where the note is referenced. + +Regardless of note type, the following items will always be displayed if there is a note: + +1. Note info, which displays: + 1. The creation/modification date of the note. + 2. The type and MIME of the note. + 3. The note ID. + 4. An estimation of the note size of the note itself and its children. + 5. A button to show Similar notes. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout_image.png new file mode 100644 index 0000000000..12f5e0d5f0 Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tooltip.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tooltip.md index dbdf139e8e..dc0c702cda 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tooltip.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tooltip.md @@ -10,12 +10,12 @@ The following information is displayed: * Clicking on the title will open the note in the current tab. * Holding Ctrl pressed while clicking the title will open in a new tab instead of the current one. * A snippet of the content will be displayed as well. -* A button to [quickly edit](Quick%20edit.md) the note in a popup. +* A button to [quickly edit](../Navigation/Quick%20edit.md) the note in a popup. The tooltip can be found in multiple places, including: * InĀ TextĀ notes, when hovering overĀ Internal (reference) linksĀ . -* Collections:  - * Geo Map View, when hovering over a marker. - * Calendar View, when hovering over an event. - * Table View, when hovering over a note title, or over a [relation](../../Advanced%20Usage/Attributes/Relations.md). \ No newline at end of file +* Collections:  + * Geo Map View, when hovering over a marker. + * Calendar View, when hovering over an event. + * Table View, when hovering over a note title, or over a [relation](../../Advanced%20Usage/Attributes/Relations.md). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/1_Hiding the subtree_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/1_Hiding the subtree_image.png new file mode 100644 index 0000000000..44f0bbe515 Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/1_Hiding the subtree_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree.md new file mode 100644 index 0000000000..a2c3f26cc9 --- /dev/null +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree.md @@ -0,0 +1,51 @@ +# Hiding the subtree +
    An example of a collection with a relatively large number of children that are hidden from the tree.
    + +The tree works well when the notes are structured in a hierarchy so that the number of items stays small. When a note has a large number of notes (in the order of thousands or tens of thousands), two problems arise: + +* Navigating between notes becomes cumbersome and the tree itself gets cluttered with a large amount of notes. +* The large amount of notes can slow down the application considerably. + +Since v0.102.0, Trilium allows the tree to hide the child notes of particular notes. This works for bothĀ CollectionsĀ and normal notes. + +## Interaction + +When the subtree of a note is hidden, there are a few subtle changes: + +* To indicate that the subtree is hidden, the note will not have an expand button and it will display the number of children to the right. +* It's not possible to add a new note directly from the tree. + * ForĀ Collections, it's best to use the built-in mechanism to create notes (for example by creating a new point on a geo-map, or by adding a new row in a table). + * For normal notes, it's still possible to create children via other means such as using theĀ Internal (reference) linksĀ system. +* Notes can be dragged from outside the note, case in which they will be cloned into it. + * Instead of switching to the child notes that were copied, the parent note is highlighted instead. + * A notification will indicate this behavior. +* Similarly, features such as cut/copy and then paste into the note will also work. + +## Spotlighting + +
    + +Even if the subtree of a note is hidden, if a child note manages to become active, it will still appear inside the tree in a special state called _spotlighted_. + +During this state, the note remains under its normal hierarchy, so that its easy to tell its location. In addition, this means that: + +* The note position is clearly visible when using theĀ Search. +* The note can still be operated on from the tree, such as adding aĀ Branch prefixĀ or moving it outside the collection. + +The note appears in italics to indicate its temporary display. When switching to another note, the spotlighted note will disappear. + +> [!NOTE] +> Only one note can be highlighted at the time. When working with multiple notes such as dragging them into the collection, no note will be spotlighted. This is intentional to avoid displaying a partial state of the subtree. + +## Working with collections + +For large collections, it can be helpful to hide their child notes for performance reasons or de-cluttering the tree. + +To toggle this behavior: + +* Open the collection and inĀ Collection Properties, look for _Hide child notes in tree_. +* Right click the collection note in theĀ Note TreeĀ and select _Advanced_ → _Show subtree_. + +## Working with normal notes + +It's possible to hide the subtree for normal notes as well, not just collections. To do so, right click the note in theĀ Note TreeĀ and select _Advanced_ → _Hide subtree._ \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree_image.png b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree_image.png new file mode 100644 index 0000000000..7b75834e96 Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree_image.png differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Keyboard shortcuts.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Keyboard shortcuts.md index faec3ac7a5..89e5e72c8d 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Keyboard shortcuts.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Keyboard shortcuts.md @@ -1,17 +1,36 @@ # Keyboard shortcuts TheĀ Note TreeĀ comes with multiple keyboard shortcuts to make editing faster: -* Opening notes: - * Click to open the note in the current tab. - * Ctrl+Click or Middle click to open the note in a new tab. - * Ctrl+Right click to open the note inĀ Quick edit. -* Navigation within the tree: - * Up and Down to navigate between notes. - * Left to collapse a note, or Right to expand it. -* Clipboard management: - * Ctrl+C to copy a note. - * Ctrl+X to cut a note. - * Ctrl+V to paste it somewhere. -* ForĀ Multiple selection: - * Alt+Clickto add a single note to the current selection. - * Shift+Clickto select a range of notes, starting from the current note (the highlighted one) to the one that is being clicked. \ No newline at end of file +## Navigation within the tree + +* ↑ and ↑ to navigate between notes. +* ← to collapse a note with children, or → to expand it. +* ← on a note with no children to navigate to its parent. + +## Opening notes + +* Click to open the note in the current tab. +* Ctrl+Click or Middle click to open the note in a new tab. +* Ctrl+Right click to open the note inĀ Quick edit. + +## Clipboard management + +* Ctrl+C to copy one or more notes based on selection (seeĀ Cloning Notes). +* Ctrl+X to cut one or more notes (for moving them). +* Ctrl+V to paste them somewhere (which results in a copy or move based on the shortcut used). + +## Moving notes + +* Ctrl + ↑ , Ctrl + ↓ - move note up/down in the note list. +* Ctrl + ← - move note up in the note tree. +* Ctrl+→ - move note down in the note tree. +* Del - deletes note and optionally its subtree (asked in the dialog). + +## Multiple selection + +SeeĀ Multiple selectionĀ for more information about how selection works. + +* Alt+Click – add a single note to the current selection. +* Shift+Click – select a range of notes, starting from the current note (the highlighted one) to the one that is being clicked. +* Shift+↑, Shift+↓ – multi-select not above/below. +* Ctrl+A – select all notes in the current level \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu.md index 2df2536cf2..a5f3af5adb 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu.md @@ -52,15 +52,19 @@ The contextual menu can operate: * Creates a copy of the note and its descendants. * This process is different fromĀ Cloning NotesĀ since the duplicated note can be edited independently from the original. * An alternative to this, if done regularly, would beĀ Templates. +* **Archive/Unarchive** + * Marks a note as [archived](../../Notes/Archived%20Notes.md). + * If the note is already archived, it will be unarchived instead. + * Multiple notes can be selected as well. However, all the selected notes must be in the same state (archived or not), otherwise the option will be disabled. * **Delete** * Will delete the given notes, asking for confirmation first. * In the dialog, the following options can be configured: * _Delete also all clones_ to ensure that the note will be deleted everywhere if it has been placed into multiple locations (seeĀ Cloning Notes). * _Erase notes permanently_ will ensure that the note cannot be recovered fromĀ Recent Changes. * **Import into note** - * Opens the [import](../../Import%20%26%20Export) dialog and places the imported notes as child notes of the selected one. + * Opens the [import](../../Import%20%26%20Export.md) dialog and places the imported notes as child notes of the selected one. * **Export** - * Opens the [export](../../Import%20%26%20Export) dialog for the selected notes. + * Opens the [export](../../Import%20%26%20Export.md) dialog for the selected notes. * **Search in subtree** * Opens a fullĀ SearchĀ with it preconfigured to only look into this note and its descendants (the _Ancestor_ field). diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons.md index 3ec6426569..d7577945aa 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons.md @@ -2,4 +2,6 @@ To the right of theĀ [Ribbon](Ribbon.md)Ā there are a few more buttons: ![](Note%20buttons_image.png) * The Note Revisions button displays theĀ [Note Revisions](../Notes/Note%20Revisions.md)Ā for that particular note. -* The contextual menu offers commands for the note or its subtree, such as import, export, viewing theĀ [Note source code](../../Advanced%20Usage/Note%20source.md)Ā orĀ [Attachments](../Notes/Attachments.md). \ No newline at end of file +* The contextual menu offers commands for the note or its subtree, such as import, export, viewing theĀ [Note source code](../../Advanced%20Usage/Note%20source.md)Ā orĀ [Attachments](../Notes/Attachments.md). + +On theĀ New Layout, the button area is populated by some more buttons that are specific to the current note. For example, for Image andĀ FileĀ notes, the download and copy buttons were relocated there. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon.md index 8fd7e37d21..5cbfc0ff33 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon.md @@ -20,7 +20,7 @@ If you are using the _Fixed_ formatting toolbar, all the formatting buttons for * As a more advanced use, it's possible to change the note type in order to modify the [source code](../../Advanced%20Usage/Note%20source.md) of a note. * _**Protect the note**_ toggles whether the current note is encrypted and accessible only by entering the protected session. SeeĀ [Protected Notes](../Notes/Protected%20Notes.md)Ā for more information. * _**Editable**_ changes whether the current note: - * Enters [read-only mode](../Notes/Read-Only%20Notes.md) automatically if the note is too big (default behaviour). + * Enters [read-only mode](../Notes/Read-Only%20Notes.md) automatically if the note is too big (default behavior). * Is always in read-only mode (however it can still be edited temporarily). * Is always editable, regardless of its size. * _**Bookmark**_ toggles the display of the current note into theĀ [Launch Bar](Launch%20Bar.md)Ā for easy access. SeeĀ [Bookmarks](../Navigation/Bookmarks.md)Ā for more information. diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View.md index 0ea6832490..2fa9ea77ea 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View.md @@ -21,4 +21,22 @@ It is possible for each of the splits to have their ownĀ Mobile Frontend. + +Since v0.102.0, the tabs are displayed by pressing the dedicated tab switcher button in theĀ Launch Bar. In this view the tabs are laid out on a grid with a preview of the note content. + +The context menu button at the top-right of the popup allows creating a new tab, reopening the last closed tab and closing all the tabs. + +Split Views are also indicated in the tab switcher, with two titles displayed in a tab. + +> [!NOTE] +> Versions prior to v0.102.0 also supported tabs, but they were displayed directly above theĀ Launch Bar. The decision to use a more mobile-like tab switcher was taken because the original tab bar could not support many tabs at once and the new design better aligns with how mobile applications handle tabs. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs_IMG_1767.PNG b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs_IMG_1767.PNG new file mode 100644 index 0000000000..dd5a7ab1e5 Binary files /dev/null and b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs_IMG_1767.PNG differ diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom.md b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom.md index e69de29bb2..88404cac32 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom.md @@ -0,0 +1,10 @@ +# Zoom +Zoom applies to the entire UI, including text. + +On the desktop application, use theĀ Global menuĀ to zoom in/out. + +On both web browser and the desktop, the keyboard shortcuts Ctrl+Shift++ and Ctrl+Shift+- can be used. + +## Adjusting the text size instead + +As an alternative to the zoom, the text size can be individually adjusted by going toĀ Options → _Appearance_. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Collections.md b/docs/User Guide/User Guide/Collections.md new file mode 100644 index 0000000000..3d5938e399 --- /dev/null +++ b/docs/User Guide/User Guide/Collections.md @@ -0,0 +1,76 @@ +# Collections +Collections are a unique type of note that don't have content, but instead display their child notes in various presentation methods. + +## Main collections + +| | | +| --- | --- | +|
    | CalendarĀ 
    which displays a week, month or year calendar with the notes being shown as events. New events can be added easily by dragging across the calendar. | +|
    | TableĀ 
    displays each note as a row in a table, withĀ Promoted AttributesĀ being shown as well. This makes it easy to visualize attributes of notes, as well as making them easily editable. | +|
    | Kanban BoardĀ 
    displays notes in columns, grouped by the value of a label. Items and columns can easily be created or dragged around to change their status. | +|
    | Geo MapĀ 
    which displays a geographical map in which the notes are represented as markers/pins on the map. New events can be easily added by pointing on the map. | +|
    | PresentationĀ 
    which shows each note as a slide and can be presented full-screen with smooth transitions or exported to PDF for sharing. | + +## Classic collections + +Classic collections are read-only mode and compiles the contents of all child notes into one continuous view. This makes it ideal for reading extensive information broken into smaller, manageable segments. + +* Grid ViewĀ which is the default presentation method for child notes (seeĀ Note List), where the notes are displayed as tiles with their title and content being visible. +* List ViewĀ is similar toĀ Grid View, but it displays the notes one under the other with the content being expandable/collapsible, but also works recursively. + +## Creating a new collection + +To create a new collections, right click in theĀ Note TreeĀ and look for the _Collections_ entry and select the desired type. + +By default, collections come with a default configuration and sometimes even sample notes. To create a collection completely from scratch: + +1. Create a new note of type _Text_ (or any type). +2. Change the [note type](Note%20Types.md) to _Collection_. +3. InĀ Collection Properties, select the desired view type. +4. Consult the help page of the corresponding view type in order to understand how to configure them. + +## Configuration + +To change the configuration of a collection or even switch to a different collection (e.g. from Kanban Board to a Calendar), see theĀ Collection PropertiesĀ bar at the top of the note. + +## Archived notes + +By default, [archived notes](Basic%20Concepts%20and%20Features/Notes/Archived%20Notes.md) will not be shown in collections. This behavior can be changed by going toĀ Collection PropertiesĀ and checking _Show archived notes_. + +Archived notes will be generally indicated by being greyed out as opposed to the normal ones. + +## Hiding the child notes from the note tree + +For collections with a large number of items, it can be helpful to hide the items from the note tree for performance reasons and to reduce clutter. This is especially useful for standalone collections, such as a geomap or a task board. + +To do so, go toĀ Collection PropertiesĀ and select _Hide child notes in tree_. + +## Advanced use cases + +### Adding a description to a collection + +To add a text before the collection, for example to describe it: + +1. Create a new collection. +2. Change the [note type](Note%20Types.md) from _Collection_ to _Text_. + +Now the text will be displayed above while still maintaining the collection view. + +The only downside to this method is thatĀ Collection PropertiesĀ will not be shown anymore. In this case, modify the attributes manually or switch back temporarily to the _Collection_ type for configuration purposes. + +### Using saved search + +Collections, by default, only display the child notes. However, it is possible to use theĀ SearchĀ functionality to display notes all across the tree, with advanced querying functionality. + +To do so, simply start aĀ SearchĀ and go to the _Collection Properties_ tab in theĀ RibbonĀ and select a desired type of collection. To keep the search-based collection, use aĀ Saved Search. + +> [!IMPORTANT] +> While in search, none of the collections will not display the child notes of the search results. The reason is that the search might hit a note multiple times, causing an exponential rise in the number of results. + +## Under the hood + +Collections by themselves are simply notes with no content that rely on theĀ Note ListĀ mechanism (the one that lists the children notes at the bottom of a note) to display information. + +By default, new collections use predefinedĀ TemplatesĀ that are stored safely in theĀ Hidden NotesĀ to define some basic configuration such as the type of view, but also someĀ Promoted AttributesĀ to make editing easier. + +Collections don't store their configuration (e.g. the position on the map, the hidden columns in a table) in the content of the note itself, but as attachments. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections/11_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/10_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/11_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/10_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/12_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/11_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/12_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/11_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/13_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/12_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/13_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/12_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/14_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/13_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/14_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/13_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/16_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/14_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/16_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/14_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/17_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/15_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/17_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/15_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/18_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/16_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/18_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/16_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/1_Calendar View_image.png b/docs/User Guide/User Guide/Collections/1_Calendar_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/1_Calendar View_image.png rename to docs/User Guide/User Guide/Collections/1_Calendar_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/1_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/1_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/1_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/1_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Collections/1_Kanban Board_image.png b/docs/User Guide/User Guide/Collections/1_Kanban Board_image.png new file mode 100644 index 0000000000..1ccb0a3ccf Binary files /dev/null and b/docs/User Guide/User Guide/Collections/1_Kanban Board_image.png differ diff --git a/docs/User Guide/User Guide/Collections/1_Presentation_image.png b/docs/User Guide/User Guide/Collections/1_Presentation_image.png new file mode 100644 index 0000000000..83b0c01af7 Binary files /dev/null and b/docs/User Guide/User Guide/Collections/1_Presentation_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Collections/4_Calendar View_image.png b/docs/User Guide/User Guide/Collections/2_Calendar_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/4_Calendar View_image.png rename to docs/User Guide/User Guide/Collections/2_Calendar_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/2_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/2_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/2_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/2_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/Board View_image.png b/docs/User Guide/User Guide/Collections/2_Kanban Board_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/Board View_image.png rename to docs/User Guide/User Guide/Collections/2_Kanban Board_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/5_Calendar View_image.png b/docs/User Guide/User Guide/Collections/3_Calendar_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/5_Calendar View_image.png rename to docs/User Guide/User Guide/Collections/3_Calendar_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/3_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/3_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/3_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/3_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/6_Calendar View_image.png b/docs/User Guide/User Guide/Collections/4_Calendar_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/6_Calendar View_image.png rename to docs/User Guide/User Guide/Collections/4_Calendar_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/4_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/4_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/4_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/4_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/7_Calendar View_image.png b/docs/User Guide/User Guide/Collections/5_Calendar_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/7_Calendar View_image.png rename to docs/User Guide/User Guide/Collections/5_Calendar_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/5_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/5_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/5_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/5_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/8_Calendar View_image.png b/docs/User Guide/User Guide/Collections/6_Calendar_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/8_Calendar View_image.png rename to docs/User Guide/User Guide/Collections/6_Calendar_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/6_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/6_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/6_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/6_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/9_Calendar View_image.png b/docs/User Guide/User Guide/Collections/7_Calendar_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/9_Calendar View_image.png rename to docs/User Guide/User Guide/Collections/7_Calendar_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/7_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/7_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/7_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/7_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/10_Calendar View_image.png b/docs/User Guide/User Guide/Collections/8_Calendar_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/10_Calendar View_image.png rename to docs/User Guide/User Guide/Collections/8_Calendar_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/9_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/8_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/9_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/8_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/11_Calendar View_image.png b/docs/User Guide/User Guide/Collections/9_Calendar_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/11_Calendar View_image.png rename to docs/User Guide/User Guide/Collections/9_Calendar_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/10_Geo Map View_image.png b/docs/User Guide/User Guide/Collections/9_Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/10_Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/9_Geo Map_image.png diff --git a/docs/User Guide/User Guide/Note Types/Collections/Calendar View.md b/docs/User Guide/User Guide/Collections/Calendar.md similarity index 55% rename from docs/User Guide/User Guide/Note Types/Collections/Calendar View.md rename to docs/User Guide/User Guide/Collections/Calendar.md index cd0f860104..82bb59b5d8 100644 --- a/docs/User Guide/User Guide/Note Types/Collections/Calendar View.md +++ b/docs/User Guide/User Guide/Collections/Calendar.md @@ -1,5 +1,5 @@ -# Calendar View -
    +# Calendar +
    The Calendar view will display each child note in a calendar that has a start date and optionally an end date, as an event. @@ -14,32 +14,42 @@ Unlike other Collection view types, the Calendar view also allows some kind of i ## Creating a calendar -| | | | -| --- | --- | --- | -| 1 | ![](2_Calendar%20View_image.png) | The Calendar View works only for Collection note types. To create a new note, right click on the note tree on the left and select Insert note after, or Insert child note and then select _Collection_. | -| 2 | ![](3_Calendar%20View_image.png) | Once created, the ā€œView typeā€ of the Collection needs changed to ā€œCalendarā€, by selecting the ā€œCollection Propertiesā€ tab in the ribbon. | +Right click on an existing note in theĀ Note TreeĀ and select _Insert child note_ and look for _Calendar_. ## Creating a new event/note * Clicking on a day will create a new child note and assign it to that particular day. * You will be asked for the name of the new note. If the popup is dismissed by pressing the close button or escape, then the note will not be created. * It's possible to drag across multiple days to set both the start and end date of a particular note. - ![](Calendar%20View_image.png) + ![](Calendar_image.png) * Creating new notes from the calendar will respect the `~child:template` relation if set on the Collection note. ## Interacting with events * Hovering the mouse over an event will display information about the note. - ![](7_Calendar%20View_image.png) -* Left clicking the event will open aĀ Quick editĀ to edit the note in a popup while allowing easy return to the calendar by just dismissing the popup. + ![](5_Calendar_image.png) +* Left clicking the event will open aĀ Quick editĀ to edit the note in a popup while allowing easy return to the calendar by just dismissing the popup. * Middle clicking will open the note in a new tab. * Right click will offer more options including opening the note in a new split or window. * Drag and drop an event on the calendar to move it to another day. * The length of an event can be changed by placing the mouse to the right edge of the event and dragging the mouse around. +## Interaction on mobile + +When Trilium is on mobile, the interaction with the calendar is slightly different: + +* Clicking on an event triggers the contextual menu, including the option to open inĀ Quick edit. +* To insert a new event, touch and hold the empty space. When successful, the empty space will become colored to indicate the selection. + * Before releasing, drag across multiple spaces to create multi-day events. + * When released, a prompt will appear to enter the note title. +* To move an existing event, touch and hold the event until the empty space near it will become colored. + * At this point the event can be dragged across other days on the calendar. + * Or the event can be resized by tapping on the small circle to the right end of the event. + * To exit out of editing mode, simply tap the empty space anywhere on the calendar. + ## Configuring the calendar view -In the _Collections_ tab in theĀ Ribbon, it's possible to adjust the following: +In the _Collections_ tab in theĀ Ribbon, it's possible to adjust the following: * Hide weekends from the week view. * Display week numbers on the calendar. @@ -48,7 +58,7 @@ In the _Collections_ tab in theĀ #calendar:hideWeekends
    When present (regardless of value), it will hide Saturday and Sundays from the calendar.
    #calendar:weekNumbersWhen present (regardless of value), it will show the number of the week on the calendar.
    #calendar:initialDateChange the date the calendar opens on. When not present, the calendar opens on the current date.
    #calendar:view

    Which view to display in the calendar:

    • timeGridWeek for the week view;
    • dayGridMonth for the month view;
    • multiMonthYear for the year view;
    • listMonth for the list view.

    Any other value will be dismissed and the default view (month) will be used instead.

    The value of this label is automatically updated when changing the view using the UI buttons.

    ~child:templateDefines the template for newly created notes in the calendar (via dragging or clicking).
    In addition, the first day of the week can be either Sunday or Monday and can be adjusted from the application settings. @@ -62,11 +72,12 @@ For each note of the calendar, the following attributes can be used: | `#endDate` | Similar to `startDate`, mentions the end date if the event spans across multiple days. The date is inclusive, so the end day is also considered. The attribute can be missing for single-day events. | | `#startTime` | The time the event starts at. If this value is missing, then the event is considered a full-day event. The format is `HH:MM` (hours in 24-hour format and minutes). | | `#endTime` | Similar to `startTime`, it mentions the time at which the event ends (in relation with `endDate` if present, or `startDate`). | +| `#recurrence` | This is an optional CalDAV `RRULE` string that if present, determines whether a task should repeat or not. Note that it does not include the `DTSTART` attribute, which is derived from the `#startDate` and `#startTime` directly. For examples of valid `RRULE` strings see [https://icalendar.org/rrule-tool.html](https://icalendar.org/rrule-tool.html) | | `#color` | Displays the event with a specified color (named such as `red`, `gray` or hex such as `#FF0000`). This will also change the color of the note in other places such as the note tree. | -| `#calendar:color` | Similar to `#color`, but applies the color only for the event in the calendar and not for other places such as the note tree. | +| `#calendar:color` | **āŒļø Removed since v0.100.0. Use** `**#color**` **instead.**Ā Ā 

    Similar to `#color`, but applies the color only for the event in the calendar and not for other places such as the note tree. | | `#iconClass` | If present, the icon of the note will be displayed to the left of the event title. | | `#calendar:title` | Changes the title of an event to point to an attribute of the note other than the title, can either a label or a relation (without the `#` or `~` symbol). See _Use-cases_ for more information. | -| `#calendar:displayedAttributes` | Allows displaying the value of one or more attributes in the calendar like this:Ā Ā Ā Ā 

    ![](9_Calendar%20View_image.png) Ā Ā 

    `#weight="70" #Mood="Good" #calendar:displayedAttributes="weight,Mood"`Ā Ā 

    It can also be used with relations, case in which it will display the title of the target note:Ā Ā Ā 

    `~assignee=@My assignee #calendar:displayedAttributes="assignee"` | +| `#calendar:displayedAttributes` | Allows displaying the value of one or more attributes in the calendar like this:Ā Ā Ā Ā Ā Ā Ā 

    ![](7_Calendar_image.png) Ā Ā Ā Ā Ā 

    `#weight="70" #Mood="Good" #calendar:displayedAttributes="weight,Mood"`Ā Ā Ā Ā Ā 

    It can also be used with relations, case in which it will display the title of the target note:Ā Ā Ā Ā Ā Ā 

    `~assignee=@My assignee #calendar:displayedAttributes="assignee"` | | `#calendar:startDate` | Allows using a different label to represent the start date, other than `startDate` (e.g. `expiryDate`). The label name **must not be** prefixed with `#`. If the label is not defined for a note, the default will be used instead. | | `#calendar:endDate` | Similar to `#calendar:startDate`, allows changing the attribute which is being used to read the end date. | | `#calendar:startTime` | Similar to `#calendar:startDate`, allows changing the attribute which is being used to read the start time. | @@ -74,7 +85,7 @@ For each note of the calendar, the following attributes can be used: ## How the calendar works -![](11_Calendar%20View_image.png) +![](9_Calendar_image.png) The calendar displays all the child notes of the Collection that have a `#startDate`. An `#endDate` can optionally be added. @@ -88,10 +99,36 @@ If editing the start date and end date from the note itself is desirable, the fo This will result in: -![](10_Calendar%20View_image.png) +![](8_Calendar_image.png) When not used in a Journal, the calendar is recursive. That is, it will look for events not just in its child notes but also in the children of these child notes. +## Recurrence + +The built in calendar view also supports repeating tasks. If a child note of the calendar has a #recurrence label with a valid recurrence, that event will repeat on the calendar according to the recurrence string.Ā  + +For example, to make a note repeat on the calendar: + +* Every Day - `#recurrence="FREQ=DAILY;INTERVAL=1"` +* Every 3 days - `#recurrence="FREQ=DAILY;INTERVAL=3"` +* Every week - `#recurrence="FREQ=WEEKLY;INTERVAL=1"` +* Every 2 weeks on Monday, Wednesday and Friday - `#recurrence="FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FR"` +* Every 3 months - `#recurrence="FREQ=MONTHLY;INTERVAL=3"` +* Every 2 months on the First Sunday - `#recurrence="FREQ=MONTHLY;INTERVAL=2;BYDAY=1SU"` +* Every month on the Last Friday - `#recurrence="FREQ=MONTHLY;INTERVAL=1;BYDAY=-1FR"` +* And so on. + +For other examples of valid `RRULE` strings see [https://icalendar.org/rrule-tool.html](https://icalendar.org/rrule-tool.html) + +Note that the recurrence string does not include the `DTSTART` attribute as defined in the iCAL specifications. This is derived directly from the `startDate` and `startTime` attributes + +If you want to override the label the calendar uses to fetch the recurrence string, you can use the `#calendar:recurrence` attribute. For example, you can set `#calendar:recurrence=taskRepeats`. Then you can set your recurrence string like `#taskRepeats="FREQ=DAILY;INTERVAL=1"` + +Also note that the recurrence label can be made promoted as with the start and end dates.Ā  + +> [!WARNING] +> If the recurrence string is not valid, a toast will be shown with the note ID and title of the note with the erroneous recurrence message. This note will not be added to the calendar + ## Use-cases ### Using with the Journal / calendar @@ -105,7 +142,7 @@ Based on the `#calendarRoot` (or `#workspaceCalendarRoot`) attribute, the calend * Clicking on the empty space on a date will automatically open that day's note or create it if it does not exist. * Direct children of a day note will be displayed on the calendar despite not having a `dateNote` attribute. Children of the child notes will not be displayed. - + ### Using a different attribute as event title @@ -113,7 +150,7 @@ By default, events are displayed on the calendar by their note title. However, i To do so, assign `#calendar:title` to the child note (not the calendar/Collection note), with the value being `name` where `name` can be any label (make not to add the `#` prefix). The attribute can also come through inheritance such as a template attribute. If the note does not have the requested label, the title of the note will be used instead. -
      
    #startDate=2025-02-11 #endDate=2025-02-13 #name="My vacation" #calendar:title="name"

     

    +
      
    #startDate=2025-02-11 #endDate=2025-02-13 #name="My vacation" #calendar:title="name"

     

    ### Using a relation attribute as event title @@ -121,8 +158,8 @@ Similarly to using an attribute, use `#calendar:title` and set it to `name` wher Moreover, if there are more relations of the same name, they will be displayed as multiple events coming from the same note. -
      
    #startDate=2025-02-14 #endDate=2025-02-15 ~for=@John Smith ~for=@Jane Doe #calendar:title="for"
    +
      
    #startDate=2025-02-14 #endDate=2025-02-15 ~for=@John Smith ~for=@Jane Doe #calendar:title="for"
    Note that it's even possible to have a `#calendar:title` on the target note (e.g. ā€œJohn Smithā€) which will try to render an attribute of it. Note that it's not possible to use a relation here as well for safety reasons (an accidental recursion Ā of attributes could cause the application to loop infinitely). -
      
    #calendar:title="shortName" #shortName="John S."
    \ No newline at end of file +
      
    #calendar:title="shortName" #shortName="John S."
    \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections/Calendar View_image.png b/docs/User Guide/User Guide/Collections/Calendar_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/Calendar View_image.png rename to docs/User Guide/User Guide/Collections/Calendar_image.png diff --git a/docs/User Guide/User Guide/Collections/Collection Properties.md b/docs/User Guide/User Guide/Collections/Collection Properties.md new file mode 100644 index 0000000000..ba7ac09b0a --- /dev/null +++ b/docs/User Guide/User Guide/Collections/Collection Properties.md @@ -0,0 +1,14 @@ +# Collection Properties +
    + +The _Collection Properties_ is a toolbar that is displayed at the top of every [collection note](../Collections.md). + +For versions prior to v0.102.0, this feature was only available for theĀ 
    New Layout. Starting with this version, the collection properties are enabled for the Old layout as well, andĀ RibbonĀ no longer contains a dedicated tab for collection properties. + +The collection properties has: + +* A quick selector for the view type (e.g. grid, calendar, board). +* A settings button with: + * Settings for the current view, for example hiding the weekends in a calendar. + * Generic settings for the collection, such as [hiding the child notes](../Basic%20Concepts%20and%20Features/UI%20Elements/Note%20Tree/Hiding%20the%20subtree.md) or showing [archived notes](../Basic%20Concepts%20and%20Features/Notes/Archived%20Notes.md). +* Specific interactions for the current view, for example month selector and view switcher for the calendar. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Collections/Collection Properties_imag.png b/docs/User Guide/User Guide/Collections/Collection Properties_imag.png new file mode 100644 index 0000000000..c1955ce8b1 Binary files /dev/null and b/docs/User Guide/User Guide/Collections/Collection Properties_imag.png differ diff --git a/docs/User Guide/User Guide/Collections/Geo Map.md b/docs/User Guide/User Guide/Collections/Geo Map.md new file mode 100644 index 0000000000..1973a5c949 --- /dev/null +++ b/docs/User Guide/User Guide/Collections/Geo Map.md @@ -0,0 +1,192 @@ +# Geo Map +> [!IMPORTANT] +> Starting with Trilium v0.97.0, the geo map has been converted from a standalone [note type](../Note%20Types.md) to a type of view for theĀ Note List.Ā  + +
    + +This note type displays the children notes on a geographical map, based on an attribute. It is also possible to add new notes at a specific location using the built-in interface. + +## Creating a new geo map + +Right click on an existing note in theĀ Note TreeĀ and select _Geo Map_. + +By default the map will be empty and will show the entire world. + +## Repositioning the map + +* Click and drag the map in order to move across the map. +* Use the mouse wheel, two-finger gesture on a touchpad or the +/- buttons on the top-left to adjust the zoom. + +The position on the map and the zoom are saved inside the map note and restored when visiting again the note. + +## Adding a marker using the map + +### Adding a new note using the plus button + +| | | | +| --- | --- | --- | +| 1 | To create a marker, first navigate to the desired point on the map. Then press the ![](9_Geo%20Map_image.png) button in theĀ [Floating buttons](../Basic%20Concepts%20and%20Features/UI%20Elements/Floating%20buttons.md)Ā (top-right) area.Ā Ā Ā Ā Ā Ā 

    If the button is not visible, make sure the button section is visible by pressing the chevron button (![](15_Geo%20Map_image.png)) in the top-right of the map. | | +| 2 | | Once pressed, the map will enter in the insert mode, as illustrated by the notification.Ā Ā Ā Ā Ā Ā Ā Ā Ā 

    Simply click the point on the map where to place the marker, or the Escape key to cancel. | +| 3 | | Enter the name of the marker/note to be created. | +| 4 | | Once confirmed, the marker will show up on the map and it will also be displayed as a child note of the map. | + +### Adding a new note using the contextual menu + +1. Right click anywhere on the map, where to place the newly created marker (and corresponding note). +2. Select _Add a marker at this location_. +3. Enter the name of the neNote Treewly created note. +4. The map should be updated with the new marker. + +### Adding an existing note on note from the note tree + +1. Select the desired note in theĀ Note Tree. +2. Hold the mouse on the note and drag it to the map to the desired location. +3. The map should be updated with the new marker. + +This works for: + +* Notes that are not part of the geo map, case in which a [clone](../Basic%20Concepts%20and%20Features/Notes/Cloning%20Notes.md) will be created. +* Notes that are a child of the geo map but not yet positioned on the map. +* Notes that are a child of the geo map and also positioned, case in which the marker will be relocated to the new position. + +> [!NOTE] +> Dragging existing notes only works if the map is in editing mode. See the _Read-only_ section for more information. + +## How the location of the markers is stored + +The location of a marker is stored in the `#geolocation` attribute of the child notes: + + + +This value can be added manually if needed. The value of the attribute is made up of the latitude and longitude separated by a comma. + +## Repositioning markers + +It's possible to reposition existing markers by simply drag and dropping them to the new destination. + +As soon as the mouse is released, the new position is saved. + +If moved by mistake, there is currently no way to undo the change. If the mouse was not yet released, it's possible to force a refresh of the page (Ctrl+R ) to cancel it. + +## Interaction with the markers + +* Hovering over a marker will display aĀ Note TooltipĀ with the content of the note it belongs to. + * Clicking on the note title in the tooltip will navigate to the note in the current view. +* Middle-clicking the marker will open the note in a new tab. +* Right-clicking the marker will open a contextual menu (as described below). +* If the map is in read-only mode, clicking on a marker will open aĀ Quick editĀ popup for the corresponding note. + +## Contextual menu + +It's possible to press the right mouse button to display a contextual menu. + +1. If right-clicking an empty section of the map (not on a marker), it allows to: + 1. Displays the latitude and longitude. Clicking this option will copy them to the clipboard. + 2. Open the location using an external application (if the operating system supports it). + 3. Adding a new marker at that location. +2. If right-clicking on a marker, it allows to: + 1. Displays the latitude and longitude. Clicking this option will copy them to the clipboard. + 2. Open the location using an external application (if the operating system supports it). + 3. Open the note in a new tab, split or window. + 4. Remove the marker from the map, which will remove the `#geolocation` attribute of the note. To add it back again, the coordinates have to be manually added back in. + +## Icon and color of the markers + +
    image
    + +The markers will have the same icon as the note. + +It's possible to add a custom color to a marker by assigning them a `#color` attribute such as `#color=green`. + +## Adding the coordinates manually + +In a nutshell, create a child note and set the `#geolocation` attribute to the coordinates. + +The value of the attribute is made up of the latitude and longitude separated by a comma. + +### Adding from Google Maps + +| | | | +| --- | --- | --- | +| 1 |
    | Go to Google Maps on the web and look for a desired location, right click on it and a context menu will show up.Ā Ā Ā Ā Ā Ā Ā Ā Ā 

    Simply click on the first item displaying the coordinates and they will be copied to clipboard.Ā Ā Ā Ā Ā Ā Ā Ā Ā 

    Then paste the value inside the text box into the `#geolocation` attribute of a child note of the map (don't forget to surround the value with a `"` character). | +| 2 |
    | In Trilium, create a child note under the map. | +| 3 |
    | And then go to Owned Attributes and type `#geolocation="`, then paste from the clipboard as-is and then add the ending `"` character. Press Enter to confirm and the map should now be updated to contain the new note. | + +### Adding from OpenStreetMap + +Similarly to the Google Maps approach: + +| | | | +| --- | --- | --- | +| 1 | | Go to any location on openstreetmap.org and right click to bring up the context menu. Select the ā€œShow addressā€ item. | +| 2 | | The address will be visible in the top-left of the screen, in the place of the search bar.Ā Ā Ā Ā Ā Ā Ā Ā Ā 

    Select the coordinates and copy them into the clipboard. | +| 3 | | Simply paste the value inside the text box into the `#geolocation` attribute of a child note of the map and then it should be displayed on the map. | + +## Adding GPS tracks (.gpx) + +Trilium has basic support for displaying GPS tracks on the geo map. + +| | | | +| --- | --- | --- | +| 1 |
    | To add a track, simply drag & drop a .gpx file inside the geo map in the note tree. | +| 2 |
    | In order for the file to be recognized as a GPS track, it needs to show up as `application/gpx+xml` in the _File type_ field. | +| 3 |
    | When going back to the map, the track should now be visible.Ā Ā Ā Ā Ā Ā Ā Ā Ā 

    The start and end points of the track are indicated by the two blue markers. | + +> [!NOTE] +> The starting point of the track will be displayed as a marker, with the name of the note underneath. The start marker will also respect the icon and the `color` of the note. The end marker is displayed with a distinct icon. +> +> If the GPX contains waypoints, they will also be displayed. If they have a name, it is displayed when hovering over it with the mouse. + +## Read-only mode + +When a map is in read-only all editing features will be disabled such as: + +* The add button in theĀ Floating buttons. +* Dragging markers. +* Editing from the contextual menu (removing locations or adding new items). + +To enable read-only mode simply press the _Lock_ icon from theĀ Floating buttons. To disable it, press the button again. + +## Configuration + +### Map Style + +The styling of the map can be adjusted in theĀ Collection PropertiesĀ or manually via the `#map:style` attribute. + +The geo map comes with two different types of styles: + +* Raster styles + * For these styles the map is represented as a grid of images at different zoom levels. This is the traditional way OpenStreetMap used to work. + * Zoom is slightly restricted. + * Currently, the only raster theme is the original OpenStreetMap style. +* Vector styles + * Vector styles are not represented as images, but as geometrical shapes. This makes the rendering much smoother, especially when zooming and looking at the building edges, for example. + * The map can be zoomed in much further. + * These come both in a light and a dark version. + * The vector styles come from [VersaTiles](https://versatiles.org/), a free and open-source project providing map tiles based on OpenStreetMap. + +### Custom map style / tiles + +Starting with v0.102.0 it is possible to use custom tile sets, but only in raster format. + +To do so, manually set the `#map:style` [label](../Advanced%20Usage/Attributes/Labels.md) to the URL of the tile set. For example, to use Esri.NatGeoWorldMap, set the value to [`https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}`.](https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/%7Bz%7D/%7By%7D/%7Bx%7D.) + +> [!NOTE] +> For a list of tile sets, see the [Leaflet Providers preview](https://leaflet-extras.github.io/leaflet-providers/preview/) page. Select a desired tile set and just copy the URL from the _Plain JavaScript_ example. + +Custom vector map support is planned, but not yet implemented. + +### Other options + +The following options can be configured either via theĀ Collection Properties, by clicking on the settings (Gear icon). Alternatively, each of these options also have a corresponding [label](../Advanced%20Usage/Attributes/Labels.md) that can be set manually. + +* Scale, which illustrates the scale of the map in kilometers and miles in the bottom-left of the map. +* The name of the markers is displayed by default underneath the pin on the map. Since v0.102.0, it is possible to hide these labels which increases the performance and decreases clutter when there are many markers on the map. + +## Troubleshooting + +
    + +### Grid-like artifacts on the map + +This occurs if the application is not at 100% zoom which causes the pixels of the map to not render correctly due to fractional scaling. The only possible solution is to set the UI zoom at 100% (default keyboard shortcut is Ctrl+0). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections/Geo Map View_image.jpg b/docs/User Guide/User Guide/Collections/Geo Map_image.jpg similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/Geo Map View_image.jpg rename to docs/User Guide/User Guide/Collections/Geo Map_image.jpg diff --git a/docs/User Guide/User Guide/Note Types/Collections/Geo Map View_image.png b/docs/User Guide/User Guide/Collections/Geo Map_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/Geo Map View_image.png rename to docs/User Guide/User Guide/Collections/Geo Map_image.png diff --git a/docs/User Guide/User Guide/Collections/Grid View.md b/docs/User Guide/User Guide/Collections/Grid View.md new file mode 100644 index 0000000000..4b98b50454 --- /dev/null +++ b/docs/User Guide/User Guide/Collections/Grid View.md @@ -0,0 +1,27 @@ +# Grid View +
    + +This view presents the child notes in a grid format, allowing for a more visual navigation experience. + +Each tile contains: + +* The title of a note. +* A snippet of the content. +* For empty notes, the sub-children are also displayed, allowing for quick navigation. + +Depending on the type of note: + +* ForĀ TextĀ notes, the text can be slightly scrollable via the mouse wheel to reveal more context. +* ForĀ CodeĀ notes, syntax highlighting is applied. +* ForĀ FileĀ notes, a preview is made available for audio, video and PDF notes. +* If the note does not have a content, a list of its child notes will be displayed instead. + +The grid view is also used by default in theĀ Note ListĀ of every note, making it easy to navigate to children notes. + +### Creating a new table + +Right click on an existing note in theĀ Note TreeĀ and select _Insert child note_ and look for _Grid View_. + +## Configuration + +Unlike most other view types, the grid view is not actually configurable. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections/Grid View_image.png b/docs/User Guide/User Guide/Collections/Grid View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/Grid View_image.png rename to docs/User Guide/User Guide/Collections/Grid View_image.png diff --git a/docs/User Guide/User Guide/Collections/Kanban Board.md b/docs/User Guide/User Guide/Collections/Kanban Board.md new file mode 100644 index 0000000000..e3b772cd2f --- /dev/null +++ b/docs/User Guide/User Guide/Collections/Kanban Board.md @@ -0,0 +1,128 @@ +# Kanban Board +
    + +The Board view presents sub-notes in columns for a Kanban-like experience. Each column represents a possible value for a status label, which can be adjusted. + +## Creating a Kanban board + +Right click on an existing note in theĀ Note TreeĀ and select _Insert child note_ and look for _Kanban Board_. + +## How it works + +When first creating a collection of _Board_ type, a few subnotes will be created, each having a `#status` label set. The board then groups each note by the value of the status attribute. + +Notes are displayed recursively, so even the child notes of the child notes will be displayed. However, unlike theĀ Table, the notes are not displayed in a hierarchy. + +## Interaction + +### Working with columns + +* Create a new column by pressing _Add Column_ near the last column. + * Once pressed, a text box will be displayed to set the name of the column. Press Enter to confirm, or Escape to dismiss. +* To reorder a column, simply hold the mouse over the title and drag it to the desired position. +* To delete a column, right click on its title and select _Delete column_. +* To rename a column, click on the note title. + * Press Enter to confirm. + * Upon renaming a column, the corresponding status attribute of all its notes will be changed in bulk. +* If there are many columns, use the mouse wheel to scroll. + +### Working with notes + +* Create a new note in any column by pressing _New item_ + * Enter the name of the note and press Enter or click away. To dismiss the creation of a new note, simply press Escape or leave the name empty. + * Once created, the new note will have an attribute (`status` label by default) set to the name of the column. +* To open the note, simply click on it. +* To change the title of the note directly from the board, hover the mouse over its card and press the edit button on the right. +* To change the state of a note, simply drag a note from one column to the other to change its state. +* The order of the notes in each column corresponds to their position in the tree. + * It's possible to reorder notes simply by dragging them to the desired position within the same columns. + * It's also possible to drag notes across columns, at the desired position. +* For more options, right click on a note to display a context menu with the following options: + * Open the note in a new tab/split/window or quick edit. + * Move the note to any column. + * Insert a new note above/below the current one. + * Archive/unarchive the current note. + * Delete the current note. +* If there are many notes within the column, move the mouse over the column and use the mouse wheel to scroll. + +### Working with the note tree + +It's also possible to add items on the board using theĀ Note Tree. + +1. Select the desired note in theĀ Note Tree. +2. Hold the mouse on the note and drag it to the to the desired column. + +This works for: + +* Notes that are not children of the board, case in which a [clone](../Basic%20Concepts%20and%20Features/Notes/Cloning%20Notes.md) will be created. +* Notes that are children of the board, but not yet assigned on the board. +* Notes that are children of the board, case in which they will be moved to the new column. + +### Keyboard interaction + +The board view has mild support for keyboard-based navigation: + +* Use Tab and Shift+Tab to navigate between column titles, notes and the ā€œNew itemā€ button for each of the columns, in sequential order. +* To rename a column or a note, press F2 while it is focused. +* To open a specific note or create a new item, press Enter while it is focused. +* To dismiss a rename of a note or a column, press Escape. + +## Configuration + +### Displaying custom attributes + +
    + +Since v0.100.0, note attributes can be displayed on the board to enhance it with custom information such as adding a _Due date_ for your tasks. + +This feature works exclusively via attribute definitions (Promoted Attributes). The easiest way to add these is: + +1. Go to board note. +2. In the ribbon select _Owned Attributes_ → plus button → _Add new label/relation definition_. +3. Configure the attribute as desired. +4. Check _Inheritable_ to make it applicable to child notes automatically. + +After creating the attribute, click on a note and fill in the promoted attributes which should then reflect inside the board. + +Of note: + +* Both promoted and non-promoted attribute definitions are supported. The only difference is that non-promoted attributes don't have an ā€œAliasā€ for assigning a custom name. +* Both ā€œSingle valueā€ and ā€œMulti valueā€ attributes are supported. In case of multi-value, a badge is displayed for every instance of the attribute. +* All label types are supported, including dates, booleans and URLs. +* Relation attributes are also supported as well, showing a link with the target note title and icon. +* Currently, it's not possible to adjust which promoted attributes are displayed, since all promoted attributes will be displayed (except the `board:groupBy` one). There are plans to improve upon this being able to hide promoted attributes individually. + +### Grouping by another label + +By default, the label used to group the notes is `#status`. It is possible to use a different label if needed by defining a label named `#board:groupBy` with the value being the attribute to use (with or without `#` attribute prefix). + +### Grouping by relations + +
    + +A more advanced use-case is grouping by [Relations](../Advanced%20Usage/Attributes/Relations.md). + +During this mode: + +* The columns represent the _target notes_ of a relation. +* When creating a new column, a note is selected instead of a column name. +* The column icon will match the target note. +* Moving notes between columns will change its relation. +* Renaming an existing column will change the target note of all the notes in that column. + +Using relations instead of labels has some benefits: + +* The status/grouping of the notes is visible outside the Kanban board, for example on theĀ Note Map. +* Columns can have icons. +* Renaming columns is less intensive since it simply involves changing the note title of the target note instead of having to do a bulk rename. + +To do so: + +1. First, create a Kanban board from scratch and not a template: +2. Assign `#viewType=board #hidePromotedAttributes` to emulate the default template. +3. Set `#board:groupBy` to the name of a relation to group by, **including the** `~` **prefix** (e.g. `~status`). +4. Optionally, useĀ Promoted AttributesĀ for easy status change within the note: + + ``` + #relation:status(inheritable)="promoted,alias=Status,single" + ``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Collections/Kanban Board_image.png b/docs/User Guide/User Guide/Collections/Kanban Board_image.png new file mode 100644 index 0000000000..d2160e6b22 Binary files /dev/null and b/docs/User Guide/User Guide/Collections/Kanban Board_image.png differ diff --git a/docs/User Guide/User Guide/Collections/List View.md b/docs/User Guide/User Guide/Collections/List View.md new file mode 100644 index 0000000000..900fc92c19 --- /dev/null +++ b/docs/User Guide/User Guide/Collections/List View.md @@ -0,0 +1,40 @@ +# List View +
    + +List view is similar toĀ Grid View, but in the list view mode, each note is displayed in a single row with only the title and the icon of the note being visible by the default. By pressing the expand button it's possible to view the content of the note, as well as the children of the note (recursively). + +In the example above, the "Node.js" note on the left panel contains several child notes. The right panel displays the content of these child notes as a single continuous document. + +### Creating a new table + +Right click on an existing note in theĀ Note TreeĀ and select _Insert child note_ and look for _List View_. + +## Interaction + +* Each note can be expanded or collapsed by clicking on the arrow to the left of the title. +* In theĀ Ribbon, in the _Collection_ tab there are options to expand and to collapse all notes easily. + +## Printing and exporting to PDF + +Since v0.100.0, list collections can be [printed or exported to PDF](../Basic%20Concepts%20and%20Features/Notes/Printing%20%26%20Exporting%20as%20PDF.md). + +A printed list collection will print all the notes in the collection, in the right order and preserving the full hierarchy. + +If exported to PDF within the desktop application, there is additional functionality: + +* The table of contents of the PDF will reflect the structure of the notes. +* Reference and inline links to other notes within the same hierarchy will be functional (will jump to the corresponding page). If a link refers to a note that is not in the printed hierarchy, it will be unlinked. + +## Expanding and collapsing multiple notes at once + +Apart from individually expanding or collapsing notes, it's also possible to expand or collapse them all at once. To do so, go to theĀ Collection PropertiesĀ and look for the corresponding button. + +By default, the _Expand_ button will only expand the direct children (first level) of the collection. Starting with v0.100.0, it's possible to expand multiple levels of notes using the arrow button next to the button. + +Manually expanded notes will reset if the application/tab is closed and then the collection is visited again. Automatically expanded notes, using the ribbon configuration will persist. + +> [!TIP] +> By design, the UI provides only a handful of levels of depth for expanding notes (direct children, 2-5, all levels). It's also possible to specify any desired depth by manually setting the [corresponding label](../Advanced%20Usage/Attributes/Labels.md). For example: `#expanded=100` to expand up to 100 levels of depth. + +> [!NOTE] +> From a performance standpoint, the List collection is efficient since it does not load child notes unless the notes are actually expanded. Expanding the list for a significantly large hierarchy can cause slow-downs. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections/List View_image.png b/docs/User Guide/User Guide/Collections/List View_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/List View_image.png rename to docs/User Guide/User Guide/Collections/List View_image.png diff --git a/docs/User Guide/User Guide/Collections/Presentation.md b/docs/User Guide/User Guide/Collections/Presentation.md new file mode 100644 index 0000000000..adb7667ccc --- /dev/null +++ b/docs/User Guide/User Guide/Collections/Presentation.md @@ -0,0 +1,89 @@ +# Presentation +
    + +The Presentation view allows the creation of slideshows directly from within Trilium. + +### Creating a new presentation + +Right click on an existing note in theĀ Note TreeĀ and select _Insert child note_ and look for _Presentation_. + +## How it works + +* Each slide is a child note of the collection. +* The order of the child notes determines the order of the slides. +* Unlike traditional presentation software, slides can be laid out both horizontally and vertically (see belwo for more information). +* Direct children will be laid out horizontally and the children of those will be laid out vertically. Children deeper than two levels of nesting are ignored. + +## Interaction and navigation + +In the floating buttons section (top-right): + +* Edit button to go to the corresponding note of the current slide. +* Press Overview button (or the O key) to show a birds-eye view of the slides. Press the button again to disable it. +* Press the ā€œStart presentationā€ button to show the presentation in full-screen. + +The following keyboard shortcuts are supported: + +* Press ← and → (or H and L) to go to the slide on the left or on the right (horizontal). +* Press ↑ and ↓ Ā (or K and J) to go to the upward or downward slide (vertical). +* Press Space and Shift + Space or Ā to go to the next/previous slide in order. +* And a few more, press ? to display a popup with all the supported keyboard combinations. + +## Vertical slides and nesting + +Unlike traditional presentation software such as Microsoft PowerPoint, the slides in Trilium can be laid out horizontally or vertically in order to create depth or better organize the slides by topic. + +This horizontal/vertical organization affects transitions (especially on the ā€œslideā€ transition), however it is most noticeable in navigation. + +* Pressing ← and → will navigate through slides horizontally, thus skipping vertical notes under the current slide. This is useful to skip entire chapters/related slides. +* Pressing ↑ and ↓ will navigate through the vertical slides at the current level. +* Pressing Space and Shift + Space will go to the next/previous slide in order, regardless of the direction. This is generally the key combination to use when presenting. +* The arrows on the bottom-right of the slide will also reflect this navigation scheme. + +
    + +All direct children of the collection will be laid out horizontally. If a direct child also has children, those children will be placed as vertical slides. + +In the following example, the note structure is as follows: + +* Presentation collection + * Trilium Notes (demo page) + * ā€œIntroductionā€ slide + * ā€œThe challenge of personal knowledge managementā€ + * ā€œNote-taking structuresā€ + * ā€œDemo & Feature highlightsā€ slide + * ā€œReally fast installation processā€ + * Video slide + +## Customization + +At collection level, it's possible to adjust: + +* The theme of the entire presentation to one of the predefined themes by going to theĀ Collection PropertiesĀ and looking for the _Theme_ option. +* It's currently not possible to create custom themes, although it is planned. +* Note that it is note possible to alter the CSS viaĀ Custom app-wide CSSĀ because the slides are rendered isolated (in a shadow DOM). + +At slide level: + +* It's possible to adjust the background color of a slide by using the [predefined promoted attribute](../Advanced%20Usage/Attributes/Promoted%20Attributes.md) for the color or manually setting `#slide:background` to a hex color. +* More complex backgrounds can be achieved via gradients. There's no UI for it; it has to be set via `#slide:background` to a CSS gradient definition such as: `linear-gradient(to bottom, #283b95, #17b2c3)`. + +## Tips and tricks + +* Text notes generally respect the formatting (bold, italic, foreground and background colors) and font size. Code blocks and tables also work. +* Try using more than just text notes, the presentation uses the same mechanism as [shared notes](../Advanced%20Usage/Sharing.md) andĀ Note ListĀ so it should be able to displayĀ Mermaid Diagrams,Ā CanvasĀ andĀ Mind MapĀ in full-screen (without the interactivity). + * Consider using a transparent background forĀ Canvas, if the slides have a custom background (go to the hamburger menu in the Canvas, press the button select a custom color and write `transparent`). + * ForĀ Mermaid Diagrams, some of them have a predefined background which can be changed via the frontmatter. For example, for XY-charts: + + ``` + --- + config: + themeVariables: + xyChart: + backgroundColor: transparent + --- + ``` + +## Under the hood + +The Presentation view uses [Reveal.js](https://revealjs.com/) to handle the navigation and layout of the slides. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Collections/Presentation_image.png b/docs/User Guide/User Guide/Collections/Presentation_image.png new file mode 100644 index 0000000000..b87b47a4b5 Binary files /dev/null and b/docs/User Guide/User Guide/Collections/Presentation_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Collections/Table View.md b/docs/User Guide/User Guide/Collections/Table.md similarity index 73% rename from docs/User Guide/User Guide/Note Types/Collections/Table View.md rename to docs/User Guide/User Guide/Collections/Table.md index 0454b0a933..bf0366f408 100644 --- a/docs/User Guide/User Guide/Note Types/Collections/Table View.md +++ b/docs/User Guide/User Guide/Collections/Table.md @@ -1,7 +1,7 @@ -# Table View -
    +# Table +
    -The table view displays information in a grid, where the rows are individual notes and the columns areĀ Promoted Attributes. In addition, values are editable. +The table view displays information in a grid, where the rows are individual notes and the columns areĀ Promoted Attributes. In addition, values are editable. ## How it works @@ -9,7 +9,7 @@ The tabular structure is represented as such: * Each child note is a row in the table. * If child rows also have children, they will be displayed under an expander (nested notes). -* Each column is a [promoted attribute](../../Advanced%20Usage/Attributes/Promoted%20Attributes.md) that is defined on the Collection note. +* Each column is a [promoted attribute](../Advanced%20Usage/Attributes/Promoted%20Attributes.md) that is defined on the Collection note. * Actually, both promoted and unpromoted attributes are supported, but it's a requirement to use a label/relation definition. * The promoted attributes are usually defined as inheritable in order to show up in the child notes, but it's not a requirement. * If there are multiple attribute definitions with the same `name`, only one will be displayed. @@ -18,18 +18,18 @@ There are also a few predefined columns: * The current item number, identified by the `#` symbol. * This simply counts the note and is affected by sorting. -* Note ID, representing the unique ID used internally by Trilium +* Note ID, representing the unique ID used internally by Trilium * The title of the note. ## Interaction ### Creating a new table -Right click theĀ Note TreeĀ and select _Insert child note_ and look for the _Table item_. +Right click on an existing note in theĀ Note TreeĀ and select _Insert child note_ and look for _Table_. ### Adding columns -Each column is a [promoted or unpromoted attribute](../../Advanced%20Usage/Attributes/Promoted%20Attributes.md) that is defined on the Collection note. +Each column is a [promoted or unpromoted attribute](../Advanced%20Usage/Attributes/Promoted%20Attributes.md) that is defined on the Collection note. To create a new column, either: @@ -48,7 +48,7 @@ To create a new note, either: By default it will try to edit the title of the newly created note. -Alternatively, the note can be created from theĀ Note TreeĀ or [scripting](../../Scripting.md). +Alternatively, the note can be created from theĀ Note TreeĀ or [scripting](../Scripting.md). ### Context menu @@ -65,7 +65,8 @@ There are multiple menus: * Adding new columns. * Right clicking on a row, allows: * Opening the corresponding note of the row in a new tab, split, window or quick editing it. - * Inserting rows above, below or as a child note. + * Inserting a new note above or below the selected row. These options are only enabled if the table is not sorted. + * Inserting a new child note for the selected row. * Deleting the row. ### Editing data @@ -88,7 +89,7 @@ If the _Name_ field of a column is changed, this will trigger a batch operation ### Sorting by column -By default, the order of the notes matches the order in theĀ Note Tree. However, it is possible to sort the data by the values of a column: +By default, the order of the notes matches the order in theĀ Note Tree. However, it is possible to sort the data by the values of a column: * To do so, simply click on a column. * To switch between ascending or descending sort, simply click again on the same column. The arrow next to the column will indicate the direction of the sort. @@ -103,7 +104,7 @@ By default, the order of the notes matches the order in theĀ Note Tree. +This will also change the order of the note in theĀ Note Tree. Reordering does have some limitations: @@ -119,7 +120,7 @@ Next to the title of each element there will be a button to expand or collapse. Since nesting is not always desirable, it is possible to limit the nesting to a certain number of levels or even disable it completely. To do so, either: -* Go to _Collection Properties_ in theĀ RibbonĀ and look for the _Max nesting depth_ section. +* Go toĀ Collection PropertiesĀ and look for the _Max nesting depth_ section. * To disable nesting, type 0 and press Enter. * To limit to a certain depth, type in the desired number (e.g. 2 to only display children and sub-children). * To re-enable unlimited nesting, remove the number and press Enter. @@ -131,20 +132,20 @@ Limitations: ## Limitations -* Multi-value labels and relations are not supported. If aĀ Promoted AttributesĀ is defined with a _Multi value_ specificity, they will be ignored. +* Multi-value labels and relations are not supported. If aĀ Promoted AttributesĀ is defined with a _Multi value_ specificity, they will be ignored. * There is no support to filter the rows by a certain criteria. Consider using the table view in search for that use case. ## Use in search -The table view can be used in aĀ Saved SearchĀ by adding the `#viewType=table` attribute. +The table view can be used in aĀ Saved SearchĀ by adding the `#viewType=table` attribute. -Unlike when used in a Collection, saved searches are not limited to the sub-hierarchy of a note and allows for advanced queries thanks to the power of theĀ Search. +Unlike when used in a Collection, saved searches are not limited to the sub-hierarchy of a note and allows for advanced queries thanks to the power of theĀ Search. However, there are also some limitations: * It's not possible to reorder notes. * It's not possible to add a new row. -Columns are supported, by being defined asĀ Promoted AttributesĀ to theĀ Saved SearchĀ note. +Columns are supported, by being defined asĀ Promoted AttributesĀ to theĀ Saved SearchĀ note. Editing is also supported. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections/Table View_image.png b/docs/User Guide/User Guide/Collections/Table_image.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Collections/Table View_image.png rename to docs/User Guide/User Guide/Collections/Table_image.png diff --git a/docs/User Guide/User Guide/Collections_collection_bo.webp b/docs/User Guide/User Guide/Collections_collection_bo.webp new file mode 100644 index 0000000000..6ed49dd449 Binary files /dev/null and b/docs/User Guide/User Guide/Collections_collection_bo.webp differ diff --git a/docs/User Guide/User Guide/Collections_collection_ca.webp b/docs/User Guide/User Guide/Collections_collection_ca.webp new file mode 100644 index 0000000000..34b7961e0f Binary files /dev/null and b/docs/User Guide/User Guide/Collections_collection_ca.webp differ diff --git a/docs/User Guide/User Guide/Collections_collection_ge.webp b/docs/User Guide/User Guide/Collections_collection_ge.webp new file mode 100644 index 0000000000..e564fbfc6f Binary files /dev/null and b/docs/User Guide/User Guide/Collections_collection_ge.webp differ diff --git a/docs/User Guide/User Guide/Collections_collection_pr.webp b/docs/User Guide/User Guide/Collections_collection_pr.webp new file mode 100644 index 0000000000..f7ae75cc3a Binary files /dev/null and b/docs/User Guide/User Guide/Collections_collection_pr.webp differ diff --git a/docs/User Guide/User Guide/Collections_collection_ta.webp b/docs/User Guide/User Guide/Collections_collection_ta.webp new file mode 100644 index 0000000000..2113caf65f Binary files /dev/null and b/docs/User Guide/User Guide/Collections_collection_ta.webp differ diff --git a/docs/User Guide/User Guide/FAQ.md b/docs/User Guide/User Guide/FAQ.md index 14606e3e0d..48a79cf212 100644 --- a/docs/User Guide/User Guide/FAQ.md +++ b/docs/User Guide/User Guide/FAQ.md @@ -1,4 +1,13 @@ # FAQ +## Inspiration for the name ā€œTriliumā€ + +> Naming software is hard. I lived in Ontario when I first started the project and Trillium (the flower) is sort of a provincial logo, many institutions in Ontario are named "Trillium \[something\]". So I kept hearing/reading it almost everyday, I liked the sound of it and its nature motif, so I just reused it. +> +> _– Zadam (original Trilium maintainer)_ + +> [!NOTE] +> Despite the fact that the Trillium flower has two ā€œl"s, the Trilium application only has one. + ## macOS support Originally, Trilium Notes considered the macOS build unsupported. TriliumNext commits to make the experience on macOS as good as possible. @@ -23,7 +32,7 @@ Common request is to allow multiple users collaborate, share notes etc. So far I This is normally not supported - one Trilium process can open only a single instance of a [database](Advanced%20Usage/Database.md). However, you can run two Trilium processes (from one installation), each connected to a separate document. To achieve this, you need to set a location for the [data directory](Installation%20%26%20Setup/Data%20directory.md) in the `TRILIUM_DATA_DIR` environment variable and separate port on `TRILIUM_PORT` environment variable. How to do that depends on the platform, in Unix-based systems you can achieve that by running command such as this: -``` +```sh TRILIUM_DATA_DIR=/home/me/path/to/data/dir TRILIUM_PORT=12345 trilium ``` @@ -54,4 +63,28 @@ More detailed answer: * files are stored in no particular order and user can't change this * Trilium allows storing note [attributes](Advanced%20Usage/Attributes.md) which could be represented in extended user attributes but their support differs greatly among different filesystems / operating systems * Trilium makes links / relations between different notes which can be quickly retrieved / navigated (e.g. for [note map](Advanced%20Usage/Note%20Map%20\(Link%20map%2C%20Tree%20map\).md)). There's no such support in file systems which means these would have to be stored in some kind of side-car files (mini-databases). -* Filesystems are generally not transactional. While this is not completely required for a note-taking application, having transactions make it way easier to keep notes and their metadata in predictable and consistent state. \ No newline at end of file +* Filesystems are generally not transactional. While this is not completely required for a note-taking application, having transactions make it way easier to keep notes and their metadata in predictable and consistent state. + +## Search-related Questions + +### Why does search sometimes find results with typos? + +Trilium uses a progressive search strategy that includes fuzzy matching when exact matches return fewer than 5 results. This finds notes despite minor typos in your search query. You can use fuzzy search operators (`~=` for fuzzy exact match and `~*` for fuzzy contains). See theĀ SearchĀ documentation for details. + +### How can I search for notes when I'm not sure of the exact spelling? + +Use the fuzzy search operators: + +* `#title ~= "projct"` - finds notes with titles like "project" despite the typo +* `note.content ~* "algoritm"` - finds content containing "algorithm" or similar words + +### Why do some search results appear before others with lower scores? + +Trilium places exact matches before fuzzy matches. When you search for "project", notes containing exactly "project" appear before notes with variations like "projects" or "projection", regardless of other scoring factors. + +### How can I make my searches faster? + +1. Use the "Fast search" option to search only titles and attributes (not content) +2. Limit search scope using the "Ancestor" field +3. Set a result limit to prevent loading too many results +4. For large databases, consider archiving old notes to reduce search scope \ No newline at end of file diff --git a/docs/User Guide/User Guide/Feature Highlights.md b/docs/User Guide/User Guide/Feature Highlights.md index 7cedd84f1e..831e5c0a8e 100644 --- a/docs/User Guide/User Guide/Feature Highlights.md +++ b/docs/User Guide/User Guide/Feature Highlights.md @@ -1,10 +1,12 @@ # Feature Highlights This section presents the most important changes by version. For a full set of changes, please consult the change log of each release. For purposes of brevity, beta versions are skipped and the features gathered to the nearest stable version. +* v0.101.0: + * AĀ New LayoutĀ has been introduced, making significant modifications to the UI/UX such as integrating the ribbon and the floating buttons into other UI elements and introducing new functionality such as theĀ Breadcrumb. * v0.97.0: - * Books are nowĀ Collections. - * Table ViewĀ is a new collection type displaying notes and attributes in an editable grid. - * Quick editĀ is introduced, adding a new way to edit notes in a popup instead of opening a new tab. It also integrates well withĀ Collections. + * Books are nowĀ Collections. + * TableĀ is a new collection type displaying notes and attributes in an editable grid. + * Quick editĀ is introduced, adding a new way to edit notes in a popup instead of opening a new tab. It also integrates well withĀ Collections. * v0.96.0: * TextĀ gain premium features thanks to a collaboration with the CKEditor team: * Slash Commands @@ -12,21 +14,21 @@ This section presents the most important changes by version. For a full set of c * v0.95.0: * A more friendly theme was introduced forĀ Sharing, with search, expandable tree, night mode and more. * v0.94.0: - * Added integration withĀ AIĀ (using self-hosted LLMs such as Ollama or industry standards such as ChatGPT). + * Added integration withĀ [missing note]Ā (using self-hosted LLMs such as Ollama or industry standards such as ChatGPT). * v0.92.5: * Windows binaries are now signed. * Multi-Factor AuthenticationĀ was introduced. * v0.92.4: * macOS binaries are now signed. * TextĀ notes can now have adjustableĀ Content language & Right-to-left support. - * Export as PDF + * Printing & Exporting as PDF * Zen mode - * Calendar View, allowing notes to be displayed in a monthly grid based on start and end dates. + * Calendar, allowing notes to be displayed in a monthly grid based on start and end dates. * v0.91.5: * Significant improvements for mobile. * FootnotesĀ are now supported inĀ TextĀ notes. * Mermaid diagrams can now be inserted inline withinĀ TextĀ notes. * The TriliumNext theme is introduced, bringing a more modern design to the application. - * Geo Map View, displaying notes as markers on a geographical map for easy trip planning. + * Geo Map, displaying notes as markers on a geographical map for easy trip planning. * v0.90.8: * A new note type was introduced:Ā Mind Map \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Backup.md b/docs/User Guide/User Guide/Installation & Setup/Backup.md index 943185f3a0..699ca0e009 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Backup.md +++ b/docs/User Guide/User Guide/Installation & Setup/Backup.md @@ -40,4 +40,4 @@ noBackup=true You can also review the [configuration](../Advanced%20Usage/Configuration%20\(config.ini%20or%20e.md) file to provide all `config.ini` values as environment variables instead. -See [sample config](https://github.com/TriliumNext/Notes/blob/master/config-sample.ini). \ No newline at end of file +See [sample config](https://github.com/TriliumNext/Trilium/blob/master/config-sample.ini). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Data directory.md b/docs/User Guide/User Guide/Installation & Setup/Data directory.md index b4677c1c5b..3d66bafe90 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Data directory.md +++ b/docs/User Guide/User Guide/Installation & Setup/Data directory.md @@ -6,7 +6,7 @@ Data directory contains: * `backup` - contains automatically [backup](Backup.md) of documents * `log` - contains application log files -## Location +## Location of the data directory Easy way how to find out which data directory Trilium uses is to look at the "About Trilium Notes" dialog (from "Menu" in upper left corner): @@ -26,7 +26,17 @@ If you want to back up your Trilium data, just backup this single directory - it ### Changing the location of data directory -If you want to use some other location for the data directory than the default one, you may change it via TRILIUM\_DATA\_DIR environment variable to some other location: +If you want to use some other location for the data directory than the default one, you may change it via `TRILIUM_DATA_DIR` environment variable to some other location: + +### Windows + +1. Press the Windows key on your keyboard. +2. Search and select ā€œEdit the system variablesā€. +3. Press the ā€œEnvironment Variablesā€¦ā€ button in the bottom-right of the newly opened screen. +4. On the top section ("User variables for \[user\]"), press the ā€œNewā€¦ā€ button. +5. In the _Variable name_ field insert `TRILIUM_DATA_DIR`. +6. Press the _Browse Directory…_ button and select the new directory where to store the database. +7. Close all the windows by pressing the _OK_ button for each of them. #### Linux @@ -43,11 +53,6 @@ To load it manually, you need to use `launchctl setenv TRILIUM_DATA_DIR DatabaseĀ (storing all notes and metadata). | +| `TRILIUM_BACKUP_DIR` | `${TRILIUM_DATA_DIR}/backup` | Directory where automatedĀ BackupĀ databases are stored. | +| `TRILIUM_LOG_DIR` | `${TRILIUM_DATA_DIR}/log` | Directory where dailyĀ Backend (server) logsĀ are stored. | +| `TRILIUM_TMP_DIR` | `${TRILIUM_DATA_DIR}/tmp` | Directory where temporary files are stored (for example when opening in an external app). | +| `TRILIUM_ANONYMIZED_DB_DIR` | `${TRILIUM_DATA_DIR}/anonymized-db` | Directory where aĀ Anonymized DatabaseĀ is stored. | +| `TRILIUM_CONFIG_INI_PATH` | `${TRILIUM_DATA_DIR}/config.ini` | Path toĀ Configuration (config.ini or environment variables)Ā file. | \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Desktop Installation.md b/docs/User Guide/User Guide/Installation & Setup/Desktop Installation.md index 653e06d918..c8eb58ee57 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Desktop Installation.md +++ b/docs/User Guide/User Guide/Installation & Setup/Desktop Installation.md @@ -1,7 +1,7 @@ # Desktop Installation To install Trilium on your desktop, follow these steps: -1. **Download the Latest Release**: Obtain the appropriate binary release for your operating system from the [latest release page](https://github.com/TriliumNext/Notes/releases/latest) on GitHub. +1. **Download the Latest Release**: Obtain the appropriate binary release for your operating system from the [latest release page](https://github.com/TriliumNext/Trilium/releases/latest) on GitHub. 2. **Extract the Package**: Unzip the downloaded package to a location of your choice. 3. **Run the Application**: Launch Trilium by executing the `trilium` executable found within the unzipped folder. @@ -9,11 +9,11 @@ To install Trilium on your desktop, follow these steps: Trilium offers various startup scripts to customize your experience: -* `trilium-no-cert-check`: Starts Trilium without validating [TLS certificates](Server%20Installation/TLS%20Configuration.md), useful if connecting to a server with a self-signed certificate. +* `trilium-no-cert-check`: Starts Trilium without validating [TLS certificates](Server%20Installation/HTTPS%20\(TLS\).md), useful if connecting to a server with a self-signed certificate. * Alternatively, set the `NODE_TLS_REJECT_UNAUTHORIZED=0` environment variable before starting Trilium. * `trilium-portable`: Launches Trilium in portable mode, where the [data directory](Data%20directory.md) is created within the application's directory, making it easy to move the entire setup. * `trilium-safe-mode`: Boots Trilium in "safe mode," disabling any startup scripts that might cause the application to crash. ## Synchronization -For Trilium desktp users who wish to synchronize their data with a server instance, refer to theĀ SynchronizationĀ guide for detailed instructions. \ No newline at end of file +For Trilium desktop users who wish to synchronize their data with a server instance, refer to theĀ SynchronizationĀ guide for detailed instructions. \ No newline at end of file diff --git a/docs/Developer Guide/Developer Guide/Building and deployment/Nix flake.md b/docs/User Guide/User Guide/Installation & Setup/Desktop Installation/Nix flake.md similarity index 91% rename from docs/Developer Guide/Developer Guide/Building and deployment/Nix flake.md rename to docs/User Guide/User Guide/Installation & Setup/Desktop Installation/Nix flake.md index 9268eed6e4..b1bfb2ebba 100644 --- a/docs/Developer Guide/Developer Guide/Building and deployment/Nix flake.md +++ b/docs/User Guide/User Guide/Installation & Setup/Desktop Installation/Nix flake.md @@ -7,9 +7,9 @@ Installation of Nix on Mac or Linux ([download page](https://nixos.org/download/ ## Run directly -Using [nix run](https://nix.dev/manual/nix/stable/command-ref/new-cli/nix3-run.html), the desktop app can be started as: `nix run github:TriliumNext/Notes/v0.95.0` +Using [nix run](https://nix.dev/manual/nix/stable/command-ref/new-cli/nix3-run.html), the desktop app can be started as: `nix run github:TriliumNext/Trilium/v0.95.0` -Running the server requires explicitly specifying the desired package: `nix run github:TriliumNext/Notes/v0.95.0#server` +Running the server requires explicitly specifying the desired package: `nix run github:TriliumNext/Trilium/v0.95.0#server` Instead of a version (`v0.95.0` above), you can also specify a commit hash (or a branch name). This makes it easy to test development builds. @@ -22,7 +22,7 @@ Add to your `flake.nix`: inputs = { nixpkgs.url = # ...; trilium-notes = { - url = "github:TriliumNext/Notes/v0.95.0"; + url = "github:TriliumNext/Trilium/v0.95.0"; inputs.nixpkgs.follows = "nixpkgs"; }; }; diff --git a/docs/User Guide/User Guide/Installation & Setup/Desktop Installation/System Requirements.md b/docs/User Guide/User Guide/Installation & Setup/Desktop Installation/System Requirements.md new file mode 100644 index 0000000000..af28d059f1 --- /dev/null +++ b/docs/User Guide/User Guide/Installation & Setup/Desktop Installation/System Requirements.md @@ -0,0 +1,12 @@ +# System Requirements +The desktop version of Trilium supports all three main operating systems: + +* Windows + * Windows 11 is officially supported. + * Windows on ARM is also supported +* Linux: + * Most modern distributions are supported, including NixOS. + * ARM is supported in `aarch64` (no ARM v7 support). +* macOS + * Minimum supported operating system: macOS Monterey + * Both Intel and Apple Silicon devices are supported. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Desktop Installation/Using the desktop application .md b/docs/User Guide/User Guide/Installation & Setup/Desktop Installation/Using the desktop application .md new file mode 100644 index 0000000000..cfed42f6ba --- /dev/null +++ b/docs/User Guide/User Guide/Installation & Setup/Desktop Installation/Using the desktop application .md @@ -0,0 +1,25 @@ +# Using the desktop application as a server +Sometimes, setting up a [dedicated server installation](../Server%20Installation.md) is not feasible. The desktop application ships with a fully functional server instance by default. + +You can access this web interface locally by navigating to [http://localhost:37840/login](http://localhost:37840/login). + +> [!NOTE] +> The server embedded in the desktop application will only run as long as the desktop application itself is running. So closing the application will also close the server. To overcome this, you can try hiding the application in the system tray. + +## Mobile interface + +By default, this will display the desktop user interface, even on mobile. To switch to the mobile version, simply go to theĀ Global menuĀ and select ā€œSwitch to the mobile versionā€. + +## Allowing the port externally on Windows with Windows Defender Firewall + +First, find out the IP of your desktop server by running `ipconfig` in your local terminal. Then try accessing `http://:37840/login` on another device. If it doesn't work, then most likely the port is blocked by your operating system's firewall. + +If you use Windows Defender Firewall: + +1. Go to Windows's start menu and look for ā€œWindows Defender Firewall with Advanced Securityā€. +2. Go to ā€œInbound Rulesā€ on the left tree, and select ā€œNew Ruleā€ in the ā€œActionsā€ sidebar on the right. +3. Select ā€œPortā€ and press ā€œNextā€. +4. Type in `37840` in the ā€œSpecific local portsā€ section and then press ā€œNextā€. +5. Leave ā€œAllow the connectionā€ checked and press ā€œNextā€. +6. Configure the networks to apply to (check all if unsure) and then press ā€œNextā€. +7. Add an appropriate name to the rule (e.g. ā€œTrilium Notesā€) and press ā€œFinishā€. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend.md b/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend.md index 8785db7701..1629f95f91 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend.md +++ b/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend.md @@ -1,34 +1,85 @@ # Mobile Frontend -Trilium ([server edition](Server%20Installation.md)) has a mobile web frontend which is optimized for touch based devices - smartphones and tablets. It is activated automatically during login process based on browser detection. +
    -Mobile frontend is limited in features compared to full desktop frontend. See below for more details on this. +Trilium has a mobile web frontend which is optimized for touch based devices - smartphones and tablets. It is activated automatically during login process based on browser detection. -Note that this is not an Android/iOS app, this is just mobile friendly web page served on the [server edition](Server%20Installation.md). +Mobile frontend is limited in features compared to the full desktop version. See below for more details on this. -## Screenshots +## Layout basics -### Mobile phone +Unlike the desktop version, the mobile version has a slightly different UI meant to better fit the constrained screens of a mobile phone. -![](Mobile%20Frontend_mobile-sma.png) +Here is a non-exhaustive list of differences between the desktop version and the mobile one: -### Tablet +* TheĀ Note TreeĀ is displayed as a sidebar. To display the sidebar, press the button in the top-left of the screen. + + * There is also a swipe gesture that can be done from the left of the screen, but the browser's navigation gesture interferes with it most of the time (depending on the platform). + * Press and hold a note to display theĀ Note tree contextual menu. +* TheĀ Quick searchĀ bar is also displayed at the top of the note tree. +* The fullĀ SearchĀ function can be triggered either from either theĀ Global menuĀ or from theĀ Launch Bar, if configured. +* TheĀ Launch BarĀ is displayed at the bottom of the screen. + + * The launch bar uses a different configuration for icons than the desktop version. See the dedicated page for more information on how to configure it. +* Most of the note-related actions are grouped in the horizontal dots icon on the top-right of the note. +* TheĀ TabsĀ are grouped under a tab switcher in theĀ Launch Bar, where the tabs are displayed in a full-screen grid with preview for easy switching, as well as additional options such as reopening closed tabs. +* Since v0.100.0,Ā Split ViewĀ can also be used in mobile view, but with a maximum of two panes at once. The splits are displayed vertically instead of horizontally. +* Starting with v0.102.0, theĀ New LayoutĀ is enforced on mobile. This brings features such as the note badges, note type switcher or collection properties which would otherwise not be available. -![](Mobile%20Frontend_mobile-tab.png) +## Installing as a PWA -## Limitations +The mobile view can be set up as a PWA. While this does not offer any offline capabilities, it will display the application in full-screen and makes it easy to access via your mobile phone's home screen. -Mobile frontend provides only some of the features of the full desktop frontend: +### On iOS with Safari -* it is possible to browse the whole note tree, read and edit all types of notes, but you can create only text notes -* reading and editing [protected notes](../Basic%20Concepts%20and%20Features/Notes/Protected%20Notes.md) is possible, but creating them is not supported -* editing options is not supported -* cloning notes is not supported -* uploading file attachments is not supported +1. Open your default web browser and access your Trilium instance. +2. Login. +3. Press the \[…\] button in the bottom-right of the screen and select Share. +4. Scroll down to reveal the full list of items and choose ā€œAdd to Home Screenā€. +5. Press ā€œAddā€ and the web app will be available. + +### On Android with Google Chrome + +> [!IMPORTANT] +> Google Chrome requires the server to be served over HTTPS in order to display in full-screen. If using HTTP, the app will appear like a normal web page (similar to a bookmark). + +1. Open your default web browser and access your Trilium instance. +2. Login. +3. Press the three vertical dots icon in the top-right of the screen and select _Add to Home screen._ +4. Select the _Install_ option. +5. Select an appropriate name. +6. The web app will appear as an application, not on the home screen. + +### On Android with Brave + +> [!IMPORTANT] +> Brave requires the server to be served over HTTPS in order to display in full-screen. If using HTTP, the app will appear like a normal web page (similar to a bookmark). + +1. Open your default web browser and access your Trilium instance. +2. Login. +3. Press the three vertical dots icon in the bottom-right of the screen and select _Add to Home screen_. +4. Press the _Install_ option. +5. The web app will appear as an application, not on the home screen. + +### On Samsung Browser + +1. Open your default web browser and access your Trilium instance. +2. Login. +3. Press the hamburger menu in the bottom-right of the screen. +4. Select _Add to_, followed by _Home screen_. +5. Press _Add_ and the web app will appear on the home page. + +## Testing via the desktop application + +If you are running Trilium without a dedicated [server installation](Server%20Installation.md), you can still test the mobile application using the desktop application. For more information, seeĀ Using the desktop application as a server. To access it go to `http://:37840/login?mobile` . ## Forcing mobile/desktop frontend -Trilium decides automatically whether to use mobile or desktop frontend. If this is not appropriate, you can use `?mobile` or `?desktop` query param on **login** page (Note: you might need to log out). +Trilium decides automatically whether to use mobile or desktop front-end. If this is not appropriate, you can use `?mobile` or `?desktop` query param on **login** page (Note: you might need to log out). + +Alternatively, simply select _Switch to Mobile/Desktop Version_ in theĀ Global menu. ## Scripting -You can alter the behavior with [scripts](../Scripting.md) just like for normal frontend. For script notes to be executed, they need to have labeled `#run=mobileStartup`. \ No newline at end of file +You can alter the behavior withĀ Scripting, just like for normal frontend. For script notes to be executed, they need to have labeled `#run=mobileStartup`. + +CustomĀ Launch BarĀ widgets are also supported. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend_IMG_1765.PNG b/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend_IMG_1765.PNG new file mode 100644 index 0000000000..5536b5ffbd Binary files /dev/null and b/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend_IMG_1765.PNG differ diff --git a/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-sma.png b/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-sma.png deleted file mode 100644 index cd839420dd..0000000000 Binary files a/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-sma.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-tab.png b/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-tab.png deleted file mode 100644 index 6d890f90db..0000000000 Binary files a/docs/User Guide/User Guide/Installation & Setup/Mobile Frontend_mobile-tab.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation.md index 1282493496..ceae67f844 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Server Installation.md +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation.md @@ -18,7 +18,7 @@ The server installation includes both web and [mobile frontends](Mobile%20Fronte ## Configuration -After setting up your server installation, you may want to configure settings such as the port or enable [TLS](Server%20Installation/TLS%20Configuration.md). Configuration is managed via the Trilium `config.ini` file, which is located in the [data directory](Data%20directory.md) by default. To begin customizing your setup, copy the provided `config-sample.ini` file with default values to `config.ini`. +After setting up your server installation, you may want to configure settings such as the port or enable [TLS](Server%20Installation/HTTPS%20\(TLS\).md). Configuration is managed via the Trilium `config.ini` file, which is located in the [data directory](Data%20directory.md) by default. To begin customizing your setup, copy the provided `config-sample.ini` file with default values to `config.ini`. You can also review the [configuration](../Advanced%20Usage/Configuration%20\(config.ini%20or%20e.md) file to provide all `config.ini` values as environment variables instead. @@ -32,7 +32,7 @@ export TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data ### Disabling / Modifying the Upload Limit -If you're running into the 250MB limit imposed on the server by default, and you'd like to increase the upload limit, you can set the `TRILIUM_NO_UPLOAD_LIMIT` environment variable to `true` disable it completely: +If you're running into the 250MB limit imposed on the server by default, and you'd like to increase the upload limit, you can set the `TRILIUM_NO_UPLOAD_LIMIT` environment variable to `true` to disable it completely: ``` export TRILIUM_NO_UPLOAD_LIMIT=true @@ -76,4 +76,4 @@ client_max_body_size 0; ### Apache -For an Apache setup, refer to the [Apache proxy setup](Server%20Installation/2.%20Reverse%20proxy/Apache.md) guide. \ No newline at end of file +For an Apache setup, refer to the [Apache proxy setup](Server%20Installation/2.%20Reverse%20proxy/Apache%20using%20Docker.md) guide. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually.md index 404262525c..afc7661e6a 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually.md +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually.md @@ -26,12 +26,12 @@ sudo apt install libpng16-16 libpng-dev pkg-config autoconf libtool build-essent ### Download -You can either download source code zip/tar from [https://github.com/TriliumNext/Notes/releases/latest](https://github.com/TriliumNext/Notes/releases/latest). +You can either download source code zip/tar from [https://github.com/TriliumNext/Trilium/releases/latest](https://github.com/TriliumNext/Trilium/releases/latest). For the latest version including betas, clone Git repository **from** `main` **branch** with: ``` -git clone -b main https://github.com/triliumnext/notes.git +git clone -b main https://github.com/triliumnext/trilium.git ``` ## Installation @@ -62,4 +62,4 @@ The application by default starts up on port 8080, so you can open your browser ## TLS -Don't forget to [configure TLS](../TLS%20Configuration.md) which is required for secure usage! \ No newline at end of file +Don't forget to [configure TLS](../HTTPS%20\(TLS\).md) which is required for secure usage! \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux.md index 88386a9f39..39dcc85619 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux.md +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux.md @@ -4,7 +4,7 @@ This is essentially Trilium sources + node modules + node.js runtime packaged in ## Steps * SSH into your server -* use `wget` (or `curl`) to download latest `TriliumNotes-Server-[VERSION]-linux-x64.tar.xz` (copy link from [release page](https://github.com/TriliumNext/Notes/releases), notice `-Server` suffix) on your server. +* use `wget` (or `curl`) to download latest `TriliumNotes-Server-[VERSION]-linux-x64.tar.xz` (copy link from [release page](https://github.com/TriliumNext/Trilium/releases), notice `-Server` suffix) on your server. * unpack the archive, e.g. using `tar -xf -d TriliumNotes-Server-[VERSION]-linux-x64.tar.xz` * `cd trilium-linux-x64-server` * `./trilium.sh` @@ -61,6 +61,108 @@ sudo systemctl enable --now -q trilium * You can now open a browser to http://\[your-server-hostname\]:8080 and you should see the Trilium initialization page. +## Simple Autoupdate for Server + +Run as the same User Trilium runs + +if you run as root please remove 'sudo' from the commands + +requires "jq" `apt install jq` + +It will stop the service above, overwrite everything (i expect no config.ini), and start service It also creates a version file in the Trilium directory so it updates only with a newer Version + +``` +#!/bin/bash + +# Configuration +REPO="TriliumNext/Trilium" +PATTERN="TriliumNotes-Server-.*-linux-x64.tar.xz" +DOWNLOAD_DIR="/var/tmp/trilium_download" +OUTPUT_DIR="/opt/trilium" +SERVICE_NAME="trilium" +VERSION_FILE="$OUTPUT_DIR/version.txt" + +# Ensure dependencies are installed +command -v curl >/dev/null 2>&1 || { echo "Error: curl is required"; exit 1; } +command -v jq >/dev/null 2>&1 || { echo "Error: jq is required"; exit 1; } +command -v tar >/dev/null 2>&1 || { echo "Error: tar is required"; exit 1; } + +# Create download directory +mkdir -p "$DOWNLOAD_DIR" || { echo "Error: Cannot create $DOWNLOAD_DIR"; exit 1; } + +# Get the latest release version +LATEST_VERSION=$(curl -sL https://api.github.com/repos/$REPO/releases/latest | jq -r '.tag_name') +if [ -z "$LATEST_VERSION" ]; then + echo "Error: Could not fetch latest release version" + exit 1 +fi + +# Check current installed version (from version.txt or existing tarball) +CURRENT_VERSION="" +if [ -f "$VERSION_FILE" ]; then + CURRENT_VERSION=$(cat "$VERSION_FILE") +elif [ -f "$DOWNLOAD_DIR/TriliumNotes-Server-$LATEST_VERSION-linux-x64.tar.xz" ]; then + CURRENT_VERSION="$LATEST_VERSION" +fi + +# Compare versions +if [ "$CURRENT_VERSION" = "$LATEST_VERSION" ]; then + echo "Latest version ($LATEST_VERSION) is already installed" + exit 0 +fi + +# Download the latest release +LATEST_URL=$(curl -sL https://api.github.com/repos/$REPO/releases/latest | jq -r ".assets[] | select(.name | test(\"$PATTERN\")) | .browser_download_url") +if [ -z "$LATEST_URL" ]; then + echo "Error: No asset found matching pattern '$PATTERN'" + exit 1 +fi + +FILE_NAME=$(basename "$LATEST_URL") +FILE_PATH="$DOWNLOAD_DIR/$FILE_NAME" + +# Download if not already present +if [ -f "$FILE_PATH" ]; then + echo "Latest release $FILE_NAME already downloaded" +else + curl -LO --output-dir "$DOWNLOAD_DIR" "$LATEST_URL" || { echo "Error: Download failed"; exit 1; } + echo "Downloaded $FILE_NAME to $DOWNLOAD_DIR" +fi + +# Extract the tarball +EXTRACT_DIR="$DOWNLOAD_DIR/extracted" +mkdir -p "$EXTRACT_DIR" +tar -xJf "$FILE_PATH" -C "$EXTRACT_DIR" || { echo "Error: Extraction failed"; exit 1; } + +# Find the extracted directory (e.g., TriliumNotes-Server-0.97.2-linux-x64) +INNER_DIR=$(find "$EXTRACT_DIR" -maxdepth 1 -type d -name "TriliumNotes-Server-*-linux-x64" | head -n 1) +if [ -z "$INNER_DIR" ]; then + echo "Error: Could not find extracted directory matching TriliumNotes-Server-*-linux-x64" + exit 1 +fi + +# Stop the trilium-server service +if systemctl is-active --quiet "$SERVICE_NAME"; then + echo "Stopping $SERVICE_NAME service..." + sudo systemctl stop "$SERVICE_NAME" || { echo "Error: Failed to stop $SERVICE_NAME"; exit 1; } +fi + +# Copy contents to /opt/trilium, overwriting existing files +echo "Copying contents from $INNER_DIR to $OUTPUT_DIR..." +sudo mkdir -p "$OUTPUT_DIR" +sudo cp -r "$INNER_DIR"/* "$OUTPUT_DIR"/ || { echo "Error: Copy failed"; exit 1; } +echo "$LATEST_VERSION" | sudo tee "$VERSION_FILE" >/dev/null +echo "Files copied to $OUTPUT_DIR" + +# Start the trilium-server service +echo "Starting $SERVICE_NAME service..." +sudo systemctl start "$SERVICE_NAME" || { echo "Error: Failed to start $SERVICE_NAME"; exit 1; } + +# Clean up +rm -rf "$EXTRACT_DIR" +echo "Cleanup complete. Trilium updated to $LATEST_VERSION." +``` + ## Common issues ### Outdated glibc @@ -76,4 +178,4 @@ If you get an error like this, you need to either upgrade your glibc (typically ## TLS -Don't forget to [configure TLS](../TLS%20Configuration.md), which is required for secure usage! \ No newline at end of file +Don't forget to [configure TLS](../HTTPS%20\(TLS\).md), which is required for secure usage! \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.md index 0f711f89e2..5864a15837 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.md +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker.md @@ -1,5 +1,5 @@ # Using Docker -Official docker images are published on docker hub for **AMD64**, **ARMv7** and **ARM64/v8**: [https://hub.docker.com/r/triliumnext/notes/](https://hub.docker.com/r/triliumnext/notes/) +Official docker images are published on docker hub for **AMD64**, **ARMv7** and **ARM64/v8**: [https://hub.docker.com/r/triliumnext/trilium/](https://hub.docker.com/r/triliumnext/trilium/) ## Prerequisites @@ -17,7 +17,7 @@ If you need help installing Docker, reference the [Docker Installation Docs](htt ### Grab the latest docker-compose.yml: ``` -wget https://raw.githubusercontent.com/TriliumNext/Notes/master/docker-compose.yml +wget https://raw.githubusercontent.com/TriliumNext/Trilium/master/docker-compose.yml ``` Optionally, edit the `docker-compose.yml` file to configure the container settings prior to starting it. Unless configured otherwise, the data directory will be `~/trilium-data` and the container will be accessible at port 8080. @@ -34,10 +34,10 @@ docker compose up -d ### Pulling the Docker Image -To pull the image, use the following command, replacing `[VERSION]` with the desired version or tag, such as `v0.91.6` or just `latest`. (See published tag names at [https://hub.docker.com/r/triliumnext/notes/tags](https://hub.docker.com/r/triliumnext/notes/tags).): +To pull the image, use the following command, replacing `[VERSION]` with the desired version or tag, such as `v0.91.6` or just `latest`. (See published tag names at [https://hub.docker.com/r/triliumnext/trilium/tags](https://hub.docker.com/r/triliumnext/trilium/tags).): ``` -docker pull triliumnext/notes:v0.91.6 +docker pull triliumnext/trilium:v0.91.6 ``` **Warning:** Avoid using the "latest" tag, as it may automatically upgrade your instance to a new minor version, potentially disrupting sync setups or causing other issues. @@ -53,7 +53,7 @@ Trilium requires a directory on the host system to store its data. This director Run the container to make it accessible only from the localhost. This setup is suitable for testing or when using a proxy server like Nginx or Apache. ``` -sudo docker run -t -i -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:[VERSION] +sudo docker run -t -i -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/trilium:[VERSION] ``` 1. Verify the container is running using `docker ps`. @@ -70,13 +70,13 @@ docker network create -d macvlan -o parent=eth0 --subnet 192.168.2.0/24 --gatewa Then, run the container with the network settings: ``` -docker run --net=mynet -d -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:-latest +docker run --net=mynet -d -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/trilium:-latest ``` To set a different user ID (UID) and group ID (GID) for the saved data, use the `USER_UID` and `USER_GID` environment variables: ``` -docker run --net=mynet -d -p 127.0.0.1:8080:8080 -e "USER_UID=1001" -e "USER_GID=1001" -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:-latest +docker run --net=mynet -d -p 127.0.0.1:8080:8080 -e "USER_UID=1001" -e "USER_GID=1001" -v ~/trilium-data:/home/node/trilium-data triliumnext/trilium:-latest ``` Find the local IP address using `docker inspect [container_name]` and access the service from devices on the local network. @@ -91,7 +91,7 @@ docker inspect [container_name] To allow access from any IP address, run the container as follows: ``` -docker run -d -p 0.0.0.0:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:[VERSION] +docker run -d -p 0.0.0.0:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/trilium:[VERSION] ``` Stop the container with `docker stop `, where the container ID is obtained from `docker ps`. @@ -101,15 +101,15 @@ Stop the container with `docker stop `, where the container ID is For a custom data directory, use: ``` --v ~/YourOwnDirectory:/home/node/trilium-data triliumnext/notes:[VERSION] +-v ~/YourOwnDirectory:/home/node/trilium-data triliumnext/trilium:[VERSION] ``` -If you want to run your instance in a non-default way, please use the volume switch as follows: `-v ~/YourOwnDirectory:/home/node/trilium-data triliumnext/notes:`. It is important to be aware of how Docker works for volumes, with the first path being your own and the second the one to virtually bind to. [https://docs.docker.com/storage/volumes/](https://docs.docker.com/storage/volumes/) The path before the colon is the host directory, and the path after the colon is the container's path. More details can be found in the [Docker Volumes Documentation](https://docs.docker.com/storage/volumes/). +If you want to run your instance in a non-default way, please use the volume switch as follows: `-v ~/YourOwnDirectory:/home/node/trilium-data triliumnext/trilium:`. It is important to be aware of how Docker works for volumes, with the first path being your own and the second the one to virtually bind to. [https://docs.docker.com/storage/volumes/](https://docs.docker.com/storage/volumes/) The path before the colon is the host directory, and the path after the colon is the container's path. More details can be found in the [Docker Volumes Documentation](https://docs.docker.com/storage/volumes/). ## Reverse Proxy 1. [Nginx](../2.%20Reverse%20proxy/Nginx.md) -2. [Apache](../2.%20Reverse%20proxy/Apache.md) +2. [Apache](../2.%20Reverse%20proxy/Apache%20using%20Docker.md) ### Note on --user Directive @@ -132,10 +132,10 @@ Below are some commands to pull the rootless images: ``` # For Debian-based image -docker pull triliumnext/notes:rootless +docker pull triliumnext/trilium:rootless # For Alpine-based image -docker pull triliumnext/notes:rootless-alpine +docker pull triliumnext/trilium:rootless-alpine ``` ### Why Rootless? @@ -171,13 +171,13 @@ TRILIUM_DATA_DIR=/path/to/your/data TRILIUM_UID=$(id -u) TRILIUM_GID=$(id -g) do ``` # Build the image -docker build -t triliumnext/notes:rootless -f apps/server/Dockerfile.rootless . +docker build -t triliumnext/trilium:rootless -f apps/server/Dockerfile.rootless . # Run with default UID/GID (1000:1000) -docker run -d --name trilium -p 8080:8080 -v ~/trilium-data:/home/trilium/trilium-data triliumnext/notes:rootless +docker run -d --name trilium -p 8080:8080 -v ~/trilium-data:/home/trilium/trilium-data triliumnext/trilium:rootless # Run with custom UID/GID -docker run -d --name trilium -p 8080:8080 --user $(id -u):$(id -g) -v ~/trilium-data:/home/trilium/trilium-data triliumnext/notes:rootless +docker run -d --name trilium -p 8080:8080 --user $(id -u):$(id -g) -v ~/trilium-data:/home/trilium/trilium-data triliumnext/trilium:rootless ``` @@ -187,6 +187,8 @@ docker run -d --name trilium -p 8080:8080 --user $(id -u):$(id -g) -v ~/trilium- * `TRILIUM_GID`: GID to use for the container process (passed to Docker's `--user` flag) * `TRILIUM_DATA_DIR`: Path to the data directory inside the container (default: `/home/node/trilium-data`) +For a complete list of configuration environment variables (network settings, authentication, sync, etc.), seeĀ Configuration (config.ini or environment variables). + ### Volume Permissions If you encounter permission issues with the data volume, ensure that: @@ -224,11 +226,11 @@ If you would prefer, you can also customize the UID/GID at build time: ``` # For Debian-based image with custom UID/GID docker build --build-arg USER=myuser --build-arg UID=1001 --build-arg GID=1001 \ - -t triliumnext/notes:rootless-custom -f apps/server/Dockerfile.rootless . + -t triliumnext/trilium:rootless-custom -f apps/server/Dockerfile.rootless . # For Alpine-based image with custom UID/GID docker build --build-arg USER=myuser --build-arg UID=1001 --build-arg GID=1001 \ - -t triliumnext/notes:alpine-rootless-custom -f apps/server/Dockerfile.alpine.rootless . + -t triliumnext/trilium:alpine-rootless-custom -f apps/server/Dockerfile.alpine.rootless . ``` diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache using Docker.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache using Docker.md new file mode 100644 index 0000000000..12121d1225 --- /dev/null +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache using Docker.md @@ -0,0 +1,91 @@ +# Apache using Docker +This tutorial assumes that you have created a DNS A record for `trilium.yourdomain.com` that you want to use for your Trilium server. + +## Docker setup + +Download docker image and create container + +``` + docker pull triliumnext/trilium:[VERSION] + docker create --name trilium -t -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/trilium:[VERSION] +``` + +## Configuring the Apache proxy + +1. Enable apache proxy modules + + ``` + a2enmod ssl + a2enmod proxy + a2enmod proxy_http + a2enmod proxy_wstunnel + ``` +2. Create a new let's encrypt certificate + + ``` + sudo certbot certonly -d trilium.mydomain.com + ``` + + Choose standalone (2) and note the location of the created certificates (typically /etc/letsencrypt/live/...) +3. Create a new virtual host file for apache (you may want to use `apachectl -S` to determine the server root location, mine is /etc/apache2) + + ``` + sudo nano /etc/apache2/sites-available/trilium.yourdomain.com.conf + ``` + + Paste (and customize) the following text into the configuration file + + ``` + + ServerName http://trilium.yourdomain.com + RewriteEngine on + RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent] + + + ServerName https://trilium.yourdomain.com + RewriteEngine On + RewriteCond %{HTTP:Connection} Upgrade [NC] + RewriteCond %{HTTP:Upgrade} websocket [NC] + RewriteRule /(.*) ws://localhost:8080/$1 [P,L] + AllowEncodedSlashes NoDecode + ProxyPass / http://localhost:8080/ nocanon + ProxyPassReverse / http://localhost:8080/ + SSLCertificateFile /etc/letsencrypt/live/trilium.yourdomain.com/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/trilium.yourdomain.com/privkey.pem + Include /etc/letsencrypt/options-ssl-apache.conf + + ``` +4. Enable the virtual host with `sudo a2ensite trilium.yourdomain.com.conf` +5. Reload apache2 with `sudo systemctl reload apache2` + +## Configuring the trusted proxy + +After setting up a reverse proxy, make sure to configure theĀ Trusted proxy. + +## Setup the systemd service to start up the server + +Create and enable a systemd service to start the docker container on boot + +1. Create a new empty file called `/lib/systemd/system/trilium.service` with the contents + + ``` + [Unit] + Description=Trilium Server + Requires=docker.service + After=docker.service + + [Service] + Restart=always + ExecStart=/usr/bin/docker start -a trilium + ExecStop=/usr/bin/docker stop -t 2 trilium + + [Install] + WantedBy=local.target + ``` +2. Install, enable and start service + + ``` + sudo systemctl daemon-reload + sudo systemctl enable trilium.service + sudo systemctl start trilium.service + ``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache.md deleted file mode 100644 index 248775e6ee..0000000000 --- a/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache.md +++ /dev/null @@ -1,81 +0,0 @@ -# Apache -I've assumed you have created a DNS A record for `trilium.yourdomain.com` that you want to use for your Trilium server. - -1. Download docker image and create container - - ``` - docker pull triliumnext/notes:[VERSION] - docker create --name trilium -t -p 127.0.0.1:8080:8080 -v ~/trilium-data:/home/node/trilium-data triliumnext/notes:[VERSION] - ``` -2. Configure Apache proxy and websocket proxy - - 1. Enable apache proxy modules - - ``` - a2enmod ssl - a2enmod proxy - a2enmod proxy_http - a2enmod proxy_wstunnel - ``` - 2. Create a new let's encrypt certificate - - ``` - sudo certbot certonly -d trilium.mydomain.com - ``` - - Choose standalone (2) and note the location of the created certificates (typically /etc/letsencrypt/live/...) - 3. Create a new virtual host file for apache (you may want to use `apachectl -S` to determine the server root location, mine is /etc/apache2) - - ``` - sudo nano /etc/apache2/sites-available/trilium.yourdomain.com.conf - ``` - - Paste (and customize) the following text into the configuration file - - ``` - - ServerName http://trilium.yourdomain.com - RewriteEngine on - RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent] - - - ServerName https://trilium.yourdomain.com - RewriteEngine On - RewriteCond %{HTTP:Connection} Upgrade [NC] - RewriteCond %{HTTP:Upgrade} websocket [NC] - RewriteRule /(.*) ws://localhost:8080/$1 [P,L] - AllowEncodedSlashes NoDecode - ProxyPass / http://localhost:8080/ nocanon - ProxyPassReverse / http://localhost:8080/ - SSLCertificateFile /etc/letsencrypt/live/trilium.yourdomain.com/fullchain.pem - SSLCertificateKeyFile /etc/letsencrypt/live/trilium.yourdomain.com/privkey.pem - Include /etc/letsencrypt/options-ssl-apache.conf - - ``` - 4. Enable the virtual host with `sudo a2ensite trilium.yourdomain.com.conf` - 5. Reload apache2 with `sudo systemctl reload apache2` -3. Create and enable a systemd service to start the docker container on boot - - 1. Create a new empty file called `/lib/systemd/system/trilium.service` with the contents - - ``` - [Unit] - Description=Trilium Server - Requires=docker.service - After=docker.service - - [Service] - Restart=always - ExecStart=/usr/bin/docker start -a trilium - ExecStop=/usr/bin/docker stop -t 2 trilium - - [Install] - WantedBy=local.target - ``` - 2. Install, enable and start service - - ``` - sudo systemctl daemon-reload - sudo systemctl enable trilium.service - sudo systemctl start trilium.service - ``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx.md index 57f51b4e67..7bb33a9ef6 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx.md +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx.md @@ -1,19 +1,24 @@ # Nginx -Configure Nginx proxy and HTTPS. The operating system here is Ubuntu 18.04. +Configure Nginx proxy and HTTPS. The operating system here is Ubuntu. -1. Download Nginx and remove Apache2 - - ``` - sudo apt-get install nginx - sudo apt-get remove apache2 - ``` -2. Create configure file +## Installing Nginx + +Download Nginx and remove Apache2 + +``` +sudo apt-get install nginx +sudo apt-get remove apache2 +``` + +## Build the configuration file + +1. First, create the configuration file: ``` cd /etc/nginx/conf.d vim default.conf ``` -3. Fill the file with the context shown below, part of the setting show be changed. Then you can enjoy your web with HTTPS forced and proxy. +2. Fill the file with the context shown below, part of the setting show be changed. Then you can enjoy your web with HTTPS forced and proxy. ``` # This part configures, where your Trilium server is running @@ -54,23 +59,29 @@ Configure Nginx proxy and HTTPS. The operating system here is Ubuntu 18.04. return 301 https://$server_name$request_uri; } ``` -4. Alternatively if you want to serve the instance under a different path (useful e.g. if you want to serve multiple instances), update the location block like so: - - * update the location with your desired path (make sure to not leave a trailing slash "/", if your `proxy_pass` does not end on a slash as well) - * add the `proxy_cookie_path` directive with the same path: this allows you to stay logged in at multiple instances at the same time. - - ``` - location /trilium/instance-one { - rewrite /trilium/instance-one/(.*) /$1 break; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://trilium; - proxy_cookie_path / /trilium/instance-one - proxy_read_timeout 90; - } - - ``` \ No newline at end of file + +## Serving under a different path + +Alternatively if you want to serve the instance under a different path (useful e.g. if you want to serve multiple instances), update the location block like so: + +* update the location with your desired path (make sure to not leave a trailing slash "/", if your `proxy_pass` does not end on a slash as well) +* add the `proxy_cookie_path` directive with the same path: this allows you to stay logged in at multiple instances at the same time. + +``` + location /trilium/instance-one { + rewrite /trilium/instance-one/(.*) /$1 break; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_pass http://trilium; + proxy_cookie_path / /trilium/instance-one + proxy_read_timeout 90; + } +``` + +## Configuring the trusted proxy + +After setting up a reverse proxy, make sure to configure theĀ Trusted proxy. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik.md new file mode 100644 index 0000000000..6630185a58 --- /dev/null +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik.md @@ -0,0 +1,78 @@ +# Traefik +The goal of this article is to configure Traefik proxy and HTTPS. See [#7768](https://github.com/TriliumNext/Trilium/issues/7768#issuecomment-3539165814) for reference. + +## Breaking change in Traefik 3.6.4 + +Traefik 3.6.4 introduced a [breaking change](https://doc.traefik.io/traefik/migrate/v3/#encoded-characters-in-request-path) regarding how percent-encoded characters are handled in URLs. More specifically some URLs used by Trilium (such as `search/%23workspace%20%23!template`) are automatically rejected by Traefik, resulting in HTTP 400 errors. + +To solve this, the Traefik [**static** configuration](https://doc.traefik.io/traefik/getting-started/configuration-overview/#the-install-configuration) must be modified in order to allow those characters: + +```yaml +entryPoints: + web: + http: + encodedCharacters: + allowEncodedSlash: true + allowEncodedHash: true +``` + +> [!TIP] +> If you still have issues, depending on how Trilium is used (especially regarding search), you might need to enable more encoded character groups. For more information, see [the relevant GitHub issue](https://github.com/TriliumNext/Trilium/issues/7968); feel free to report your findings. + +### Build the docker-compose file + +Setting up Traefik as reverse proxy requires setting the following labels: + +```yaml + labels: + - traefik.enable=true + - traefik.http.routers.trilium.entrypoints=https + - traefik.http.routers.trilium.rule=Host(`trilium.mydomain.tld`) + - traefik.http.routers.trilium.tls=true + - traefik.http.routers.trilium.service=trilium + - traefik.http.services.trilium.loadbalancer.server.port=8080 + # scheme must be HTTP instead of the usual HTTPS because Trilium listens on HTTP internally + - traefik.http.services.trilium.loadbalancer.server.scheme=http + - traefik.docker.network=proxy + # forward HTTP to HTTPS + - traefik.http.routers.trilium.middlewares=trilium-headers@docker + - traefik.http.middlewares.trilium-headers.headers.customrequestheaders.X-Forwarded-Proto=https +``` + +### Setup needed environment variables + +After setting up a reverse proxy, make sure to configure theĀ Trusted proxy. + +### Example `docker-compose.yaml` + +```yaml +services: + trilium: + image: triliumnext/trilium + container_name: trilium + networks: + - traefik-proxy + environment: + - TRILIUM_NETWORK_TRUSTEDREVERSEPROXY=my-traefik-host-ip # e.g., 172.18.0.0/16 + volumes: + - /path/to/data:/home/node/trilium-data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + labels: + - traefik.enable=true + - traefik.http.routers.trilium.entrypoints=https + - traefik.http.routers.trilium.rule=Host(`trilium.mydomain.tld`) + - traefik.http.routers.trilium.tls=true + - traefik.http.routers.trilium.service=trilium + - traefik.http.services.trilium.loadbalancer.server.port=8080 + # scheme must be HTTP instead of the usual HTTPS because of how trilium works + - traefik.http.services.trilium.loadbalancer.server.scheme=http + - traefik.docker.network=traefik-proxy + # Tell Trilium the original request was HTTPS + - traefik.http.routers.trilium.middlewares=trilium-headers@docker + - traefik.http.middlewares.trilium-headers.headers.customrequestheaders.X-Forwarded-Proto=https + +networks: + traefik-proxy: + external: true +``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Trusted proxy.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Trusted proxy.md new file mode 100644 index 0000000000..9b8311d889 --- /dev/null +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Trusted proxy.md @@ -0,0 +1,17 @@ +# Trusted proxy +If you are running the Trilium server under a [reverse proxy](../2.%20Reverse%20proxy), it's important to configure it as a trusted proxy so that the application can correctly identify the real IP address of the clients (for authentication and rate limiting purposes). + +To do so, simply modifyĀ Configuration (config.ini or environment variables)Ā and set: + +``` +[Network] +trustedReverseProxy=true +``` + +This will use the left-most IP in the `X-Forwarded-For` header. Alternatively, instead of `true` use the IP address of the reverse proxy or Express.js shortcuts such as: + +``` +loopback(127.0.0.1/8, ::1/128), linklocal(169.254.0.0/16, fe80::/10), uniquelocal(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7) +``` + +For more information, consult [Express behind proxies](https://expressjs.com/en/guide/behind-proxies.html). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/TLS Configuration.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/HTTPS (TLS).md similarity index 79% rename from docs/User Guide/User Guide/Installation & Setup/Server Installation/TLS Configuration.md rename to docs/User Guide/User Guide/Installation & Setup/Server Installation/HTTPS (TLS).md index 67551f1155..1a4945db81 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Server Installation/TLS Configuration.md +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/HTTPS (TLS).md @@ -1,7 +1,8 @@ -# TLS Configuration +# HTTPS (TLS) Configuring TLS is essential for [server installation](../Server%20Installation.md) in Trilium. This guide details the steps to set up TLS within Trilium itself. -For a more robust solution, consider using TLS termination with a reverse proxy (recommended, e.g., Nginx). You can follow a [guide like this](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04) for such setups. +> [!TIP] +> While Trilium supports HTTPS on its own, it's generally a good idea to use a [reverse proxy](2.%20Reverse%20proxy) instead with TLS termination. You can follow a [guide like this](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04) for such setups. ## Obtaining a TLS Certificate @@ -25,7 +26,13 @@ certPath=/[username]/.acme.sh/[hostname]/fullchain.cer keyPath=/[username]/.acme.sh/[hostname]/example.com.key ``` -You can also review the [configuration](../../Advanced%20Usage/Configuration%20\(config.ini%20or%20e.md) file to provide all `config.ini` values as environment variables instead. +You can also review the [configuration](../../Advanced%20Usage/Configuration%20\(config.ini%20or%20e.md) file to provide all `config.ini` values as environment variables instead. For example, you can configure TLS using environment variables: + +``` +export TRILIUM_NETWORK_HTTPS=true +export TRILIUM_NETWORK_CERTPATH=/path/to/cert.pem +export TRILIUM_NETWORK_KEYPATH=/path/to/key.pem +``` The above example shows how this is set up in an environment where the certificate was generated using Let's Encrypt's ACME utility. Your paths may differ. For Docker installations, ensure these paths are within a volume or another directory accessible by the Docker container, such as `/home/node/trilium-data/[DIR IN DATA DIRECTORY]`. diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication.md index e76e1e2c21..5ef20f3ac9 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication.md +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication.md @@ -34,10 +34,13 @@ MFA can only be set up on a server instance. ### OpenID -In order to setup OpenID, you will need to setup a authentication provider. This requires a bit of extra setup. Follow [these instructions](https://developers.google.com/identity/openid-connect/openid-connect) to setup an OpenID service through google. +In order to setup OpenID, you will need to setup a authentication provider. This requires a bit of extra setup. Follow [these instructions](https://developers.google.com/identity/openid-connect/openid-connect) to setup an OpenID service through google. The Redirect URL of Trilium is `https:///callback`. 1. Set the `oauthBaseUrl`, `oauthClientId` and `oauthClientSecret` in the `config.ini` file (checkĀ Configuration (config.ini or environment variables)Ā for more information). - 1. You can also setup through environment variables (`TRILIUM_OAUTH_BASE_URL`, `TRILIUM_OAUTH_CLIENT_ID` and `TRILIUM_OAUTH_CLIENT_SECRET`). + 1. You can also setup through environment variables: + * Standard: `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHBASEURL`, `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHCLIENTID`, `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHCLIENTSECRET` + * Legacy (still supported): `TRILIUM_OAUTH_BASE_URL`, `TRILIUM_OAUTH_CLIENT_ID`, `TRILIUM_OAUTH_CLIENT_SECRET` + 2. `oauthBaseUrl` should be the link of your Trilium instance server, for example, `https://`. 2. Restart the server 3. Go to "Menu" -> "Options" -> "MFA" 4. Click the ā€œEnable Multi-Factor Authenticationā€ checkbox if not checked @@ -45,4 +48,20 @@ In order to setup OpenID, you will need to setup a authentication provider. This 6. Refresh the page and login through OpenID provider > [!NOTE] -> The default OAuth issuer is Google. To use other services such as Authentik or Auth0, you can configure the settings via `oauthIssuerBaseUrl`, `oauthIssuerName`, and `oauthIssuerIcon` in the `config.ini` file. Alternatively, these values can be set using environment variables: `TRILIUM_OAUTH_ISSUER_BASE_URL`, `TRILIUM_OAUTH_ISSUER_NAME`, and `TRILIUM_OAUTH_ISSUER_ICON`. `oauthIssuerName` and `oauthIssuerIcon` are required for displaying correct issuer information at the Login page. \ No newline at end of file +> The default OAuth issuer is Google. To use other services such as Authentik or Auth0, you can configure the settings via `oauthIssuerBaseUrl`, `oauthIssuerName`, and `oauthIssuerIcon` in the `config.ini` file. Alternatively, these values can be set using environment variables: +> +> * Standard: `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHISSUERBASEURL`, `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHISSUERNAME`, `TRILIUM_MULTIFACTORAUTHENTICATION_OAUTHISSUERICON` +> * Legacy (still supported): `TRILIUM_OAUTH_ISSUER_BASE_URL`, `TRILIUM_OAUTH_ISSUER_NAME`, `TRILIUM_OAUTH_ISSUER_ICON` +> +> `oauthIssuerName` and `oauthIssuerIcon` are required for displaying correct issuer information at the Login page. + +#### Authentik + +If you don’t already have a running Authentik instance, please follow [these instructions](https://docs.goauthentik.io/docs/install-config/install/docker-compose) to set one up. + +1. In the Authentik admin dashboard, create a new OAuth2 application by following [these steps](https://docs.goauthentik.io/docs/add-secure-apps/providers/oauth2/create-oauth2-provider). Make sure to set the Redirect URL to: `https:///callback`. +2. In your config.ini file, set the relevant OAuth variables: + 1. `oauthIssuerBaseUrl` → Use the `OpenID Configuration Issuer` URL from your application's overview page. + 2. `oauthIssuerName` and `oauthIssuerIcon` → Set these to customize the name and icon displayed on the login page. If omitted, Google’s name and icon will be shown by default. +3. Apply the changes by restarting your server. +4. Proceed with the remaining steps starting from Step 3 in the OpenID section. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/Nix flake.clone.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/Nix flake.clone.md new file mode 100644 index 0000000000..1ea9ad9977 --- /dev/null +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/Nix flake.clone.md @@ -0,0 +1,2 @@ +# Nix flake +This is a clone of a note. Go to its [primary location](../Desktop%20Installation/Nix%20flake.md). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/System Requirements.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/System Requirements.md new file mode 100644 index 0000000000..4b0221ee0c --- /dev/null +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/System Requirements.md @@ -0,0 +1,11 @@ +# System Requirements +* Using Docker, the server can be run on Windows, Linux and macOS devices. +* Native binaries are provided for Linux x64 and ARM (`aarch64`). + +## Legacy ARM support + +The Docker builds also provide `linux/arm/v7` and `linux/arm/v8` platforms. These platforms are considered legacy since Trilium uses Node.js version 24 which have [officially downgraded support](https://github.com/nodejs/node/commit/6682861d6f) for these platforms to ā€œexperimentalā€. + +As a result, Trilium needs to use Node.js 22 for these versions. As soon as soon Node.js 22 will no longer be compatible, support for `armv7` and `armv8` will be dropped entirely. + +Regardless of upstream support, these platforms are supported on a best-effort basis and are not officially supported by the Trilium development team. Bug reports are accepted but they will not be treated with priority; contributions are welcome. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Server Installation/Third-party cloud hosting.md b/docs/User Guide/User Guide/Installation & Setup/Server Installation/Third-party cloud hosting.md new file mode 100644 index 0000000000..ae7c7ef6c4 --- /dev/null +++ b/docs/User Guide/User Guide/Installation & Setup/Server Installation/Third-party cloud hosting.md @@ -0,0 +1,33 @@ +# Third-party cloud hosting +As an alternative to [hosting your own Trilium instance](1.%20Installing%20the%20server), there are two services out there that provide out of the box support for Trilium. + +> [!IMPORTANT] +> **Disclaimer**: The Trilium Notes project and maintainers are not directly affiliated with either of the projects. +> +> PikaPods have gracefully offered us free credits for testing purposes. + +## Cloud instance providers + +### PikaPods + +1. Go to [pikapods.com](https://www.pikapods.com) Ā and sign up. +2. In the ā€œAvailable Appsā€ section, look for "TriliumNext + Ā and select ā€œRun your ownā€. +3. Follow the on-screen instructions to set up your own cloud hosted instance. + +PikaPods generally updates their Trilium instances to the latest version within a two-week interval after a new version is released. + +### trilium.cc + +[Trilium.cc](https://trilium.cc/) is a cloud service dedicated to hosting a Trilium instance. + +> [!WARNING] +> Trilium.cc usually runs several versions behind Trilium releases. + +## Matching your version with the cloud instance + +Please note that once you set upĀ SynchronizationĀ between a cloud instance and [desktop](../Desktop%20Installation.md) clients, it's important that the version of the desktop application and the server match up. + +When setting up a cloud instance, it's best to check the version of the server by accessing it via a web browser and going to the _About_ section. It's best that both the desktop and the server have the same _App version_; however it's generally OK to update the desktop to a newer version than the server if it has the same _Sync version_. + +If the _Sync version_ between the server and the desktop application doesn't match, synchronization will not work. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Synchronization.md b/docs/User Guide/User Guide/Installation & Setup/Synchronization.md index 421b4458e8..76bcf96f5b 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Synchronization.md +++ b/docs/User Guide/User Guide/Installation & Setup/Synchronization.md @@ -9,7 +9,7 @@ In this setup, a central server (referred to as the _sync server_) and multiple ### Security Considerations -Setting up the server securely is critical and can be complex. It is crucial to use a valid [TLS certificate](Server%20Installation/TLS%20Configuration.md) (HTTPS) rather than an unencrypted HTTP connection to ensure security and avoid potential vulnerabilities. +Setting up the server securely is critical and can be complex. It is crucial to use a valid [TLS certificate](Server%20Installation/HTTPS%20\(TLS\).md) (HTTPS) rather than an unencrypted HTTP connection to ensure security and avoid potential vulnerabilities. ### Synchronizing a Desktop Instance with a Sync Server diff --git a/docs/User Guide/User Guide/Installation & Setup/Upgrading TriliumNext.md b/docs/User Guide/User Guide/Installation & Setup/Upgrading TriliumNext.md index e51a815868..a98917ba39 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Upgrading TriliumNext.md +++ b/docs/User Guide/User Guide/Installation & Setup/Upgrading TriliumNext.md @@ -6,7 +6,7 @@ This document outlines the steps required to upgrade Trilium to a new release ve Trilium does not support built-in automatic upgrades; all updates must be performed manually. The upgrade process varies depending on the installation method: * [**Docker Server Installation**](Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.md): Pull the new image and restart the container. -* **Other Installations**: Download the latest version from the [release page](https://github.com/TriliumNext/Notes/releases/latest) and replace the existing application files. +* **Other Installations**: Download the latest version from the [release page](https://github.com/TriliumNext/Trilium/releases/latest) and replace the existing application files. ## Database Compatibility and Migration diff --git a/docs/User Guide/User Guide/Installation & Setup/Web Clipper.md b/docs/User Guide/User Guide/Installation & Setup/Web Clipper.md index bd5731d34f..d054ba5247 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Web Clipper.md +++ b/docs/User Guide/User Guide/Installation & Setup/Web Clipper.md @@ -3,9 +3,19 @@ Trilium Web Clipper is a web browser extension which allows user to clip text, screenshots, whole pages and short notes and save them directly to Trilium Notes. -Project is hosted [here](https://github.com/TriliumNext/web-clipper). +## Supported browsers -Firefox and Chrome are supported browsers, but the chrome build should work on other chromium based browsers as well. +Trilium Web Clipper officially supports the following web browsers: + +* Mozilla Firefox, using Manifest v2. +* Google Chrome, using Manifest v3. Theoretically the extension should work on other Chromium-based browsers as well, but they are not officially supported. + +## Obtaining the extension + +> [!WARNING] +> The extension is currently under development. A preview with unsigned extensions is available on [GitHub Actions](https://github.com/TriliumNext/Trilium/actions/runs/21318809414). +> +> We have already submitted the extension to both Chrome and Firefox web stores, but they are pending validation. ## Functionality @@ -15,16 +25,29 @@ Firefox and Chrome are supported browsers, but the chrome build should work on o * save screenshot (with crop tool) from either popup or context menu * create short text note from popup +## Location of clippings + Trilium will save these clippings as a new child note under a "clipper inbox" note. By default, that's the [day note](../Advanced%20Usage/Advanced%20Showcases/Day%20Notes.md) but you can override that by setting the [label](../Advanced%20Usage/Attributes.md) `clipperInbox`, on any other note. If there's multiple clippings from the same page (and on the same day), then they will be added to the same note. -**Extension is available from:** +## Keyboard shortcuts -* [Project release page](https://github.com/TriliumNext/web-clipper/releases) - .xpi for Firefox and .zip for Chromium based browsers. -* [Chrome Web Store](https://chromewebstore.google.com/detail/trilium-web-clipper/dfhgmnfclbebfobmblelddiejjcijbjm) +Keyboard shortcuts are available for most functions: + +* Save selected text: Ctrl+Shift+S (Mac: ⌘+⇧+S) +* Save whole page: Alt+Shift+S (Mac: ⌄+⇧+S) +* Save screenshot: Ctrl+Shift+E (Mac: ⌘+⇧+E) + +To set custom shortcuts, follow the directions for your browser. + +* **Firefox**: `about:addons` → Gear icon āš™ļø → Manage extension shortcuts +* **Chrome**: `chrome://extensions/shortcuts` + +> [!NOTE] +> On Firefox, the default shortcuts interfere with some browser features. As such, the keyboard combinations will not trigger the Web Clipper action. To fix this, simply change the keyboard shortcut to something that works. The defaults will be adjusted in future versions. ## Configuration @@ -32,6 +55,36 @@ The extension needs to connect to a running Trilium instance. By default, it sca It's also possible to configure the [server](Server%20Installation.md) address if you don't run the desktop application, or want it to work without the desktop application running. -## Username +## Testing development versions -Older versions of Trilium (before 0.50) required username & password to authenticate, but this is no longer the case. You may enter anything in that field, it will not have any effect. \ No newline at end of file +Development versions are version pre-release versions, generally meant for testing purposes. These are not available in the Google or Firefox web stores, but can be downloaded from either: + +* [GitHub Releases](https://github.com/TriliumNext/Trilium/releases) by looking for releases starting with _Web Clipper._ +* Artifacts in GitHub Actions, by looking for the [_Deploy web clipper extension_ workflow](https://github.com/TriliumNext/Trilium/actions/workflows/web-clipper.yml). Once a workflow run is selected, the ZIP files are available in the _Artifacts_ section, under the name `web-clipper-extension`. + +### For Chrome + +1. Download `trilium-web-clipper-[x.y.z]-chrome.zip`. +2. Extract the archive. +3. In Chrome, navigate to `chrome://extensions/` +4. Toggle _Developer Mode_ in top-right of the page. +5. Press the _Load unpacked_ button near the header. +6. Point to the extracted directory from step (2). + +### For Firefox + +> [!WARNING] +> Firefox prevents installation of unsigned packages in the ā€œretailā€ version. To be able to install extensions from disk, consider using _Firefox Developer Edition_ or a non-branded version of Firefox (e.g. _GNU IceCat_). +> +> One time, go to `about:config` and change `xpinstall.signatures.required` to `false`. + +1. Navigate to `about:addons`. +2. Select _Extensions_ in the left-side navigation. +3. Press the _Gear_ icon on the right of the _Manage Your Extensions_ title. +4. Select _Install Add-on From File…_ +5. Point it to `trilium-web-clipper-[x.y.z]-firefox.zip`. +6. Press the _Add_ button to confirm. + +## Credits + +Some parts of the code are based on the [Joplin Notes browser extension](https://github.com/laurent22/joplin/tree/master/Clipper). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Miscellaneous/Patterns of personal knowl.png b/docs/User Guide/User Guide/Miscellaneous/Patterns of personal knowl.png new file mode 100644 index 0000000000..39788216a7 Binary files /dev/null and b/docs/User Guide/User Guide/Miscellaneous/Patterns of personal knowl.png differ diff --git a/docs/User Guide/User Guide/Miscellaneous/Patterns of personal knowledge.md b/docs/User Guide/User Guide/Miscellaneous/Patterns of personal knowledge.md new file mode 100644 index 0000000000..977c201a37 --- /dev/null +++ b/docs/User Guide/User Guide/Miscellaneous/Patterns of personal knowledge.md @@ -0,0 +1,157 @@ +# Patterns of personal knowledge +> [!NOTE] +> This article is a description of the original author of Trilium (zadam) in regards with his own knowledge base. + +This page contains description of some of the patterns I use to organize information in my knowledge base. This is meant to give some inspiration of how one might create and structure their knowledge base in general and also specifically in Trilium Notes. It also gives some background and justification for some of the design decisions. + +## Meta patterns + +Just to be clear, meta patterns are "patterns of patterns", i.e. patterns appearing in other patterns. + +### Hierarchical organization of information + +Basic meta pattern is that I sort notes (units of information) into a hierarchy - I have some "top level" notes which represent coarse grained organization, these then split into sub-notes defining finer grained organization and so on. I consider this hierarchical (tree) organization very efficient for organization of large amounts of information. A lot of note taking software (such as Evernote) are frustratingly limited in this regard which limits scalability of the software to large amounts of notes. + +#### Scalability + +It's important to frame the following (meta) patterns with some idea of how large amount of data are we talking about. + +My rule of thumb for estimation of size of personal knowledge base is that you can reasonably produce around 10 notes a day, which is 3650 in a year. I plan to use my knowledge base long term (with or without Trilium Notes), probably decades so you can easily get to number 100 000 or even more. Right now, my personal knowledge base has around 10 000 notes. + +100 000 is a number to which most note taking software doesn't scale well (in both performance and UI). Yet I don't think it's really very much considering a lifetime of knowledge. + +#### Lazy hierarchy + +My approach to creating the hierarchy is being lazy - I don't create the structure first and then fill it with notes, instead I create single note for some specific topic and start using this one note. Once the content starts to grow, and I see how _some_ parts could be split out, I move them out into separate sub notes. As an example I have a book review for _The Fellowship of the Ring_: + +* Book reviews + * The Fellowship of the Ring + +The note contains basic book info (author, publisher etc.), book highlights with the comments and then overall review. Now it turns out there's far too many book highlights and overall review is also rather long, so I want to change the structure to the following: + +* Book reviews + * The Fellowship of the Ring Ā  Ā  Ā Ā _(still contains basic info)_ + * Highlights + * Review + +If I used standard text file stored in a filesystem I would soon run into an annoying problem that in order to split out the Highlights and Review into sub-notes I would also have to convert _The Fellowship of the Ring_ from text file into directory and split out all sections of the note into sub-notes. Instead, Trilium treats all notes as equal - both leaf notes and inner notes can have both text content which allows me to sub-structure only content which needs it. + +### Sorting notes into multiple places in the hierarchy + +While organizing the notes into the hierarchy, you very quickly run into a dilemma - your note seem to belong to two places in the hierarchy equally. As an example - you want to make a note about [bash](https://en.wikipedia.org/wiki/Bash_\(Unix_shell\)) - does it belong to "OS / Linux" or "Programming / Scripting languages"? This is actually a false dichotomy forced down by the limits of the basic tree hierarchy - the answer is _of course it belongs to both_. This is the reason why Trilium doesn't use standard tree structure (which requires every note to have exactly one parent), but an extension which allows every note to have several parents, thus effectively allowing it to appear in multiple places in the hierarchy. For lack of better term I call this "cloning". The main problem with this term is that it suggests that each clone must have an original, but here all clones are completely equal - effectively there's no original. + +In tech lingo, it might be better to describe it as a [hard link](https://en.wikipedia.org/wiki/Hard_link) with an important difference that it is possible to hard link (clone) a directory (inner note). + +### Protected notes + +I have Trilium Notes opened non-stop. Sometimes I forget to lock my computer when going to the bathroom. Sometimes I let a friend or family member to use my computer for a minute without supervision. They might click on (running) Trilium and inadvertently see a note I really don't want anybody to see (personal diary, credentials). To cover this, Trilium has a concept of "[protected notes](https://github.com/zadam/trilium/wiki/Protected-notes)" - protected note is encrypted and on top of that requires the user to enter the password every 5 minutes which guarantees that such note can be in a readable state only for small amount of time. Working with ordinary (not protected) notes don't require password so you're not bothered by extra security when it's not needed. + +### Archiving notes + +Notes can lose relevancy with time - let's say I switch jobs - all the notes specific to the former employer immediately lose most of its import. This doesn't mean I want to delete these notes though - typically I just want them to somehow deprioritize - in Trilium I would do that by assigning an [inherited](https://github.com/zadam/trilium/wiki/Attribute-inheritance) [label](https://github.com/zadam/trilium/wiki/Attributes) `archived` to the company root note. The main effect of this label is that all the notes from this sub-tree are filtered out from search results (fast search via note autocomplete is my main [navigation approach](https://github.com/zadam/trilium/wiki/Note-navigation)). Apart from this, I also typically move such outdated notes to some less prominent place in the hierarchy. + +I use archivation also for notes which are not very relevant from their creation - an example might be automatically imported reddit comments. + +Sometimes there's no clear _category_ split between relevant and non-relevant notes, in that case I just create "_OLD_" note with `archived` label and move all irrelevant notes there. So my credentials note might look something like this: + +* Credentials + * Personal + * OLD Ā  Ā  Ā Ā _(contains a bunch of notes with credentials for services I don't use anymore)_ + * Gmail + * Github + * ... + +## Patterns + +### Day note + +Every day has its note which contains or references everything related to the given day. Structure looks like this: + +* 2018 + * 11 - November + * 26 - Monday + * 27 - Tuesday + * subnote 1 + +Day note serves as a workspace and note inbox at the same time - it's the default location to create a note when I don't have time to think about proper placement. At the end of the day I typically review my day note and clone the notes into suitable locations in the hierarchy. + +Trilium has this pattern partly built-in - Trilium understands and can create this Year / Month / Day structure semi-automatically (on API call). There's also global keyboard shortcut `CTRL-ALT-P` which will create new note in the day note. + +What notes do I keep under this day note? + +* TODO list for given day (this can be automated - seeĀ Task Manager) +* Personal diary +* [clones](../Basic%20Concepts%20and%20Features/Notes/Cloning%20Notes.md) of notes I created during this day (which kind of represents what I've been working on). +* I often clone notes (or sub-trees) of e.g. projects I'm working on at given day so they are at hand +* I have some [scripts](../Scripting.md) which allow me to track certain daily metrics (like weight). These are saved into one daily "data note" (actually JSON [code note](../Note%20Types/Code.md)). + * I have other scripts which then help me to visualize these data (see aĀ Weight TrackerĀ example) + * I have a script which automatically imports all my comments from reddit into the day note. + * People are sometimes wondering why. The answer is that I usually put some effort and thought into a comment and that's why I feel it's worth preserving, especially if it can be done automatically. + +For most notes, this day note placement is _secondary_ and their primary location is somewhere else (e.g. for a book review I've been working on it's _Book / Reviews_, not the day note). So for this pattern to work, ability to [clone](../Basic%20Concepts%20and%20Features/Notes/Cloning%20Notes.md) notes into multiple places is pretty fundamental. + +### Projects + +_Project_ is pretty self-explanatory, for me specifically it also means being long term (years) - an example of a project might be Trilium Notes or university studies. Given their longevity, projects can be large and deep, but their structure is very domain specific, and I don't see any common patterns. What's pretty clear is they are often widely interconnected with other parts of the knowledge base - e.g. university credentials are cloned from "Credentials / University" top level notes and Trilium related blog posts are in "Blog / \[Name of the blog\] / Trilium". + +_Epics_ are the same thing as projects, but differ in scope - they are typically several months long and as such are usually placed into a year note (e.g. _2018 / Epics_). Epics are often of work nature (also cloned into work note) and personal (e.g. currently I have large epic for moving to a different city). + +I don't have a term for short term projects (typically several days long), but continuing the scrum analogy I might call them _story_. These are often placed directly into day notes and manually moved from one day to another (or place into a month note, e.g. _2018 / 11 - November_). + +### Credentials + +I keep all my credentials in the knowledge base, they are sorted into categories - work related, project related, personal per country etc. These notes are of course [protected](../Basic%20Concepts%20and%20Features/Notes/Protected%20Notes.md) and are often cloned into other places (e.g. project credentials are cloned into the project itself). This is a pretty important advantage compared to traditional tools like KeePass - all the relevant information is centralized into one place without compromising security. + +### People profiles + +This might seem creepy to some, but I keep a profile on most people. It contains pretty standard things like date of birth, contacts, address, but also current and previous employments, their hobbies and worldviews and sometimes even important (IM/mail/meatspace) conversations. Just about everything I find notable. It helps to refresh some basic info before meeting people, especially if you haven't been in touch in a while. It gets pretty awkward to ask for the tenth time where do they work for example, because you keep forgetting it. + +Naturally I have a lot of (extended) family members, friends, acquaintances etc. so I need some way to sort them. My main method is to sort them by social circle (work, high school, sports club etc.), sometimes also by their town of residence. Family _circle_ is still too large so the further organization is by _clan_ (as in "Smiths"). Some people are members of several such circles, so they are just cloned into multiple places. + +For family specifically it's pretty useful to create [relation map](../Note%20Types/Relation%20Map.md) to visualize relationships: + +
    + +[missing note] + +### Books + +Of course, I keep standard "To read" list. I also keep a record on the books I've read - typically one book has one subtree where the root has some basic info like author, page count, publication date, date started, date finished (in the form ofĀ Promoted Attributes). I also write a (private) review and keep list of highlights from Kindle, optionally with some commentary, these are usually stored in sub notes (unless they are pretty short). + +To keep the list of books manageable, I sort them per year (of reading them), this also gives me some basic overview of "reading performance" for given year. I plan to create a [script](../Scripting.md) which would show some timeline chart visualizing book attributes `dateStarted` - `dateFinished` to have nicer view of my reading sprints and trends. + +Some specific authors also have their own note which contains cloned book reviews, links to interviews and other related resources. + +I have similar system for movies and TV shows, but not as sophisticated. + +### Personal diary + +This is a place to reflect on events, experiences, new findings etc. This can help you get deeper understanding of your inner self, clarify your thinking and make better decisions as a result. + +I sort personal diary notes directly under _day note_ (explained above), but it can be cloned also to e.g. "trip note" (if the diary note is about given trip) or to person's profile (if the person plays a role in the diary note). All my diary notes are [protected](../Basic%20Concepts%20and%20Features/Notes/Protected%20Notes.md) since they are usually pretty sensitive. + +### Documents + +I keep all my personal documents (ID, passport, education certificates ...) scanned in the knowledge base. They are [synchronized](../Installation%20%26%20Setup/Synchronization.md) across every PC which provides decent backup and makes them available everywhere. + +Advantage compared to e.g. keeping them in Dropbox or Google Drive is that they are not stored on some 3rd party server and they can be encrypted ([protected](../Basic%20Concepts%20and%20Features/Notes/Protected%20Notes.md)). + +### Inventory + +Inventory contains documents and other relevant importation for my important belongings - e.g. for car you can keep the registration card, maintenance record, related costs etc. I also keep inventory for some items personally important to me - mainly computers, phones, cameras and similar electronics. This can be practical at times but also provides sentimental value. + +### Topic knowledge base + +This where I store hard "knowledge" - summarized topics and findings from different domains. Topics can range from traditional sciences - physics, history, economy to philosophy, mental models, apps (notes about specific apps I use) etc. Of course this is very subjective - given what I do, my Physics sub-tree is pretty sparse compared to my Programming subtree. + +### Work knowledge base + +I usually keep top level note for the company I currently work at (past jobs are moved elsewhere). I track basic organization of the company (divisions, business units), who is who ([relation maps](../Note%20Types/Relation%20Map.md)) are again useful for visualization), projects I work at etc. + +There's a number of credentials to various company services I need to use. Companies usually have a bunch of complex processes and tools. I record meeting minutes, link to the company wiki (which is usually difficult to find relevant info). In general there's a lot of company specific information I need to know or need have them at hand in a nice structure I can understand. Often it's just copy pasting and reshuffling of existing information into something more understandable for me. + +From my experience, keeping this makes me more productive and even more importantly dramatically reduces frustration and stress. + +## Conclusion + +I could probably go on with more patterns (e.g. study notes, travelling), but I think you get the idea. Whatever is important in your life, it probably makes sense to document and track it. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Miscellaneous/Privacy Policy.md b/docs/User Guide/User Guide/Miscellaneous/Privacy Policy.md new file mode 100644 index 0000000000..fab3346c09 --- /dev/null +++ b/docs/User Guide/User Guide/Miscellaneous/Privacy Policy.md @@ -0,0 +1,17 @@ +# Privacy Policy +### Trilium Notes + +Trilium Notes does not collect/send any data from the user's installation, i.e. no analytics, no telemetry etc. The data flows only between user controlled / installed applications, without any intermediary. + +Automatic network activity consists of: + +* Trilium periodically queries URL [https://github.com/TriliumNext/Trilium/releases](https://github.com/TriliumNext/Trilium/releases) to see if there's a new stable version released. (check only, there's no automatic download and/or installation). +* Trilium will download spelling dictionaries automatically as needed based on language settings + +### Trilium Web Clipper + +Trilium Web Clipper does not collect/send any data from the user's installation, i.e. no analytics, no telemetry etc. The data flows only between user controlled / installed applications, without any intermediary. + +### Trilium Sender for Android + +Trilium Sender for Android does not collect/send any data from the user's installation, i.e. no analytics, no telemetry etc. The data flows only between user controlled / installed applications, without any intermediary. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types.md b/docs/User Guide/User Guide/Note Types.md index 9912d9fc74..71ac53e644 100644 --- a/docs/User Guide/User Guide/Note Types.md +++ b/docs/User Guide/User Guide/Note Types.md @@ -1,5 +1,5 @@ # Note Types -One core features of Trilium is that it supports multiple types of notes, depending on the need. +One of the core features of Trilium is that it supports multiple types of notes, depending on the need. ## Creating a new note with a different type via the note tree @@ -33,10 +33,10 @@ The following note types are supported by Trilium: | Relation Map | Allows easy creation of notes and relations between them. Can be used for mainly relational data such as a family tree. | | Note Map | Displays the relationships between the notes, whether via relations or their hierarchical structure. | | Render Note | Used inĀ Scripting, it displays the HTML content of another note. This allows displaying any kind of content, provided there is a script behind it to generate it. | -| Collections | Displays the children of the note either as a grid, a list, or for a more specialized case: a calendar.

    Generally useful for easy reading of short notes. | +| Collections | Displays the children of the note either as a grid, a list, or for a more specialized case: a calendar.Ā 

    Generally useful for easy reading of short notes. | | Mermaid Diagrams | Displays diagrams such as bar charts, flow charts, state diagrams, etc. Requires a bit of technical knowledge since the diagrams are written in a specialized format. | | Canvas | Allows easy drawing of sketches, diagrams, handwritten content. Uses the same technology behind [excalidraw.com](https://excalidraw.com). | | Web View | Displays the content of an external web page, similar to a browser. | | Mind Map | Easy for brainstorming ideas, by placing them in a hierarchical layout. | -| Geo Map View | Displays the children of the note as a geographical map, one use-case would be to plan vacations. It even has basic support for tracks. Notes can also be created from it. | +| Geo Map | Displays the children of the note as a geographical map, one use-case would be to plan vacations. It even has basic support for tracks. Notes can also be created from it. | | File | Represents an uploaded file such as PDFs, images, video or audio files. | \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/1_File_image.png b/docs/User Guide/User Guide/Note Types/1_File_image.png index 18ce5beff2..498813236b 100644 Binary files a/docs/User Guide/User Guide/Note Types/1_File_image.png and b/docs/User Guide/User Guide/Note Types/1_File_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/2_File_image.png b/docs/User Guide/User Guide/Note Types/2_File_image.png index 04478a3ada..3dd5cebb82 100644 Binary files a/docs/User Guide/User Guide/Note Types/2_File_image.png and b/docs/User Guide/User Guide/Note Types/2_File_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/3_File_image.png b/docs/User Guide/User Guide/Note Types/3_File_image.png index 498813236b..af5bdfd5b2 100644 Binary files a/docs/User Guide/User Guide/Note Types/3_File_image.png and b/docs/User Guide/User Guide/Note Types/3_File_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/4_File_image.png b/docs/User Guide/User Guide/Note Types/4_File_image.png index 3dd5cebb82..14044ba955 100644 Binary files a/docs/User Guide/User Guide/Note Types/4_File_image.png and b/docs/User Guide/User Guide/Note Types/4_File_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/5_File_image.png b/docs/User Guide/User Guide/Note Types/5_File_image.png deleted file mode 100644 index af5bdfd5b2..0000000000 Binary files a/docs/User Guide/User Guide/Note Types/5_File_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Note Types/6_File_image.png b/docs/User Guide/User Guide/Note Types/6_File_image.png deleted file mode 100644 index 14044ba955..0000000000 Binary files a/docs/User Guide/User Guide/Note Types/6_File_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Note Types/Canvas.md b/docs/User Guide/User Guide/Note Types/Canvas.md index b88e1e27c1..febd2bf655 100644 --- a/docs/User Guide/User Guide/Note Types/Canvas.md +++ b/docs/User Guide/User Guide/Note Types/Canvas.md @@ -1,6 +1,10 @@ # Canvas +
    grafik
    + Available since Trilium v0.52. Canvas notes use the Excalidraw library to allow handwritten notes with mouse, pen or touch on an infinite canvas. It also supports basic diagramming, text and graphics input. -![grafik](Canvas_image.png) \ No newline at end of file +## Interaction + +* The note can be togged [read-only](../Basic%20Concepts%20and%20Features/Notes/Read-Only%20Notes.md) from theĀ Floating buttonsĀ section. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections.md b/docs/User Guide/User Guide/Note Types/Collections.md deleted file mode 100644 index 81f177fd50..0000000000 --- a/docs/User Guide/User Guide/Note Types/Collections.md +++ /dev/null @@ -1,56 +0,0 @@ -# Collections -Collections are a unique type of notes that don't have a content, but instead display its child notes in various presentation methods. - -Classic collections are read-only mode and compiles the contents of all child notes into one continuous view. This makes it ideal for reading extensive information broken into smaller, manageable segments. - -* Grid ViewĀ which is the default presentation method for child notes (seeĀ Note List), where the notes are displayed as tiles with their title and content being visible. -* List ViewĀ is similar toĀ Grid View, but it displays the notes one under the other with the content being expandable/collapsible, but also works recursively. - -More specialized collections were introduced, such as the: - -* Calendar ViewĀ which displays a week, month or year calendar with the notes being shown as events. New events can be added easily by dragging across the calendar. -* Geo Map ViewĀ which displays a geographical map in which the notes are represented as markers/pins on the map. New events can be easily added by pointing on the map. -* Table ViewĀ displays each note as a row in a table, withĀ Promoted AttributesĀ being shown as well. This makes it easy to visualize attributes of notes, as well as making them easily editable. -* Board ViewĀ (Kanban) displays notes in columns, grouped by the value of a label. - -For a quick presentation of all the supported view types, see the child notes of this help page, including screenshots. - -## Configuration - -To adjust the view type, see the dedicated _Collections_ tab in theĀ Ribbon. - -## Use cases - -### Creating a new collection - -To create a new collections, right click in theĀ Note TreeĀ and look for the _Collections_ entry and select the desired type. - -### Adding a description to a collection - -To add a text before the collection, for example to describe it: - -1. Create a new collection. -2. In theĀ Ribbon, go to _Basic Properties_ and change the note type from _Collection_ to _Text_. - -Now the text will be displayed above while still maintaining the collection view. - -### Using saved search - -Since collections are based on theĀ Note ListĀ mechanism, it's possible to apply the same configuration toĀ Saved SearchĀ to do advanced querying and presenting the result in an adequate matter such as a calendar, a table or even a map. - -### Creating a collection from scratch - -By default, collections come with a default configuration and sometimes even sample notes. To create a collection completely from scratch: - -1. Create a new note of type _Text_ (or any type). -2. In theĀ Ribbon, go to _Basic Properties_ and select _Collection_ as the note type. -3. Still in the ribbon, go to _Collection Properties_ and select the desired view type. -4. Consult the help page of the corresponding view type in order to understand how to configure them. - -## Under the hood - -Collections by themselves are simply notes with no content that rely on theĀ Note ListĀ mechanism (the one that lists the children notes at the bottom of a note) to display information. - -By default, new collections use predefinedĀ TemplatesĀ that are stored safely in theĀ Hidden NotesĀ to define some basic configuration such as the type of view, but also someĀ Promoted AttributesĀ to make editing easier. - -Collections don't store their configuration (e.g. the position on the map, the hidden columns in a table) in the content of the note itself, but as attachments. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections/15_Geo Map View_image.png b/docs/User Guide/User Guide/Note Types/Collections/15_Geo Map View_image.png deleted file mode 100644 index 72dbb98617..0000000000 Binary files a/docs/User Guide/User Guide/Note Types/Collections/15_Geo Map View_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Note Types/Collections/2_Calendar View_image.png b/docs/User Guide/User Guide/Note Types/Collections/2_Calendar View_image.png deleted file mode 100644 index 2c17bb45a7..0000000000 Binary files a/docs/User Guide/User Guide/Note Types/Collections/2_Calendar View_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Note Types/Collections/3_Calendar View_image.png b/docs/User Guide/User Guide/Note Types/Collections/3_Calendar View_image.png deleted file mode 100644 index 3bf94720fe..0000000000 Binary files a/docs/User Guide/User Guide/Note Types/Collections/3_Calendar View_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Note Types/Collections/8_Geo Map View_image.png b/docs/User Guide/User Guide/Note Types/Collections/8_Geo Map View_image.png deleted file mode 100644 index c2317a878c..0000000000 Binary files a/docs/User Guide/User Guide/Note Types/Collections/8_Geo Map View_image.png and /dev/null differ diff --git a/docs/User Guide/User Guide/Note Types/Collections/Board View.md b/docs/User Guide/User Guide/Note Types/Collections/Board View.md deleted file mode 100644 index 6a631bd751..0000000000 --- a/docs/User Guide/User Guide/Note Types/Collections/Board View.md +++ /dev/null @@ -1,52 +0,0 @@ -# Board View -
    - -The Board view presents sub-notes in columns for a Kanban-like experience. Each column represents a possible value for a status label, which can be adjusted. - -## How it works - -When first creating a collection of _Board_ type, a few subnotes will be created, each having a `#status` label set. The board then groups each note by the value of the status attribute. - -Notes are displayed recursively, so even the child notes of the child notes will be displayed. However, unlike theĀ Table View, the notes are not displayed in a hierarchy. - -## Interaction with columns - -* Create a new column by pressing _Add Column_ near the last column. - * Once pressed, a text box will be displayed to set the name of the column. Press Enter to confirm. -* To reorder a column, simply hold the mouse over the title and drag it to the desired position. -* To delete a column, right click on its title and select _Delete column_. -* To rename a column, click on the note title. - * Press Enter to confirm. - * Upon renaming a column, the corresponding status attribute of all its notes will be changed in bulk. -* If there are many columns, use the mouse wheel to scroll. - -## Interaction with notes - -* Create a new note in any column by pressing _New item_ - * Enter the name of the note and press _Enter_. - * Doing so will create a new note. The new note will have an attribute (`status` label by default) set to the name of the column. -* To change the state of a note, simply drag a note from one column to the other to change its state. -* The order of the notes in each column corresponds to their position in the tree. - * It's possible to reorder notes simply by dragging them to the desired position within the same columns. - * It's also possible to drag notes across columns, at the desired position. -* For more options, right click on a note to display a context menu with the following options: - * Open the note in a new tab/split/window or quick edit. - * Move the note to any column. - * Insert a new note above/below the current one. - * Delete the current note. -* If there are many notes within the column, move the mouse over the column and use the mouse wheel to scroll. - -## Configuration - -### Grouping by another attribute - -By default, the label used to group the notes is `#status`. It is possible to use a different label if needed by defining a label named `#board:groupBy` with the value being the attribute to use (without `#` attribute prefix). - -> [!NOTE] -> It's currently not possible to set a relation as the grouping criteria. There are plans to add support for it. - -## Interaction - -## Limitations - -* It is not possible yet to use group by a relation, only by label. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections/Geo Map View.md b/docs/User Guide/User Guide/Note Types/Collections/Geo Map View.md deleted file mode 100644 index ae0be91ce0..0000000000 --- a/docs/User Guide/User Guide/Note Types/Collections/Geo Map View.md +++ /dev/null @@ -1,179 +0,0 @@ -# Geo Map View -> [!IMPORTANT] -> Starting with Trilium v0.97.0, the geo map has been converted from a standalone [note type](../../Note%20Types.md) to a type of view for theĀ Note List.Ā  - -
    - -This note type displays the children notes on a geographical map, based on an attribute. It is also possible to add new notes at a specific location using the built-in interface. - -## Creating a new geo map - -| | | | -| --- | --- | --- | -| 1 |
    | Right click on any note on the note tree and select _Insert child note_ → _Geo Map (beta)_. | -| 2 |
    | By default the map will be empty and will show the entire world. | - -## Repositioning the map - -* Click and drag the map in order to move across the map. -* Use the mouse wheel, two-finger gesture on a touchpad or the +/- buttons on the top-left to adjust the zoom. - -The position on the map and the zoom are saved inside the map note and restored when visiting again the note. - -## Adding a marker using the map - -### Adding a new note using the plus button - -| | | | -| --- | --- | --- | -| 1 | To create a marker, first navigate to the desired point on the map. Then press the ![](10_Geo%20Map%20View_image.png) button in theĀ [Floating buttons](../../Basic%20Concepts%20and%20Features/UI%20Elements/Floating%20buttons.md)Ā (top-right) area.Ā Ā 

    If the button is not visible, make sure the button section is visible by pressing the chevron button (![](17_Geo%20Map%20View_image.png)) in the top-right of the map. | | -| 2 | | Once pressed, the map will enter in the insert mode, as illustrated by the notification.Ā Ā Ā Ā Ā 

    Simply click the point on the map where to place the marker, or the Escape key to cancel. | -| 3 | | Enter the name of the marker/note to be created. | -| 4 | | Once confirmed, the marker will show up on the map and it will also be displayed as a child note of the map. | - -### Adding a new note using the contextual menu - -1. Right click anywhere on the map, where to place the newly created marker (and corresponding note). -2. Select _Add a marker at this location_. -3. Enter the name of the newly created note. -4. The map should be updated with the new marker. - -### Adding an existing note on note from the note tree - -1. Select the desired note in theĀ Note Tree. -2. Hold the mouse on the note and drag it to the map to the desired location. -3. The map should be updated with the new marker. - -This works for: - -* Notes that are not part of the geo map, case in which a [clone](../../Basic%20Concepts%20and%20Features/Notes/Cloning%20Notes.md) will be created. -* Notes that are a child of the geo map but not yet positioned on the map. -* Notes that are a child of the geo map and also positioned, case in which the marker will be relocated to the new position. - -## How the location of the markers is stored - -The location of a marker is stored in the `#geolocation` attribute of the child notes: - - - -This value can be added manually if needed. The value of the attribute is made up of the latitude and longitude separated by a comma. - -## Repositioning markers - -It's possible to reposition existing markers by simply drag and dropping them to the new destination. - -As soon as the mouse is released, the new position is saved. - -If moved by mistake, there is currently no way to undo the change. If the mouse was not yet released, it's possible to force a refresh of the page (Ctrl+R ) to cancel it. - -## Interaction with the markers - -* Hovering over a marker will display aĀ Note TooltipĀ with the content of the note it belongs to. - * Clicking on the note title in the tooltip will navigate to the note in the current view. -* Middle-clicking the marker will open the note in a new tab. -* Right-clicking the marker will open a contextual menu (as described below). -* If the map is in read-only mode, clicking on a marker will open aĀ Quick editĀ popup for the corresponding note. - -## Contextual menu - -It's possible to press the right mouse button to display a contextual menu. - -1. If right-clicking an empty section of the map (not on a marker), it allows to: - 1. Displays the latitude and longitude. Clicking this option will copy them to the clipboard. - 2. Open the location using an external application (if the operating system supports it). - 3. Adding a new marker at that location. -2. If right-clicking on a marker, it allows to: - 1. Displays the latitude and longitude. Clicking this option will copy them to the clipboard. - 2. Open the location using an external application (if the operating system supports it). - 3. Open the note in a new tab, split or window. - 4. Remove the marker from the map, which will remove the `#geolocation` attribute of the note. To add it back again, the coordinates have to be manually added back in. - -## Icon and color of the markers - -
    image
    - -The markers will have the same icon as the note. - -It's possible to add a custom color to a marker by assigning them a `#color` attribute such as `#color=green`. - -## Adding the coordinates manually - -In a nutshell, create a child note and set the `#geolocation` attribute to the coordinates. - -The value of the attribute is made up of the latitude and longitude separated by a comma. - -### Adding from Google Maps - -| | | | -| --- | --- | --- | -| 1 |
    | Go to Google Maps on the web and look for a desired location, right click on it and a context menu will show up.Ā Ā Ā Ā Ā 

    Simply click on the first item displaying the coordinates and they will be copied to clipboard.Ā Ā Ā Ā Ā 

    Then paste the value inside the text box into the `#geolocation` attribute of a child note of the map (don't forget to surround the value with a `"` character). | -| 2 |
    | In Trilium, create a child note under the map. | -| 3 |
    | And then go to Owned Attributes and type `#geolocation="`, then paste from the clipboard as-is and then add the ending `"` character. Press Enter to confirm and the map should now be updated to contain the new note. | - -### Adding from OpenStreetMap - -Similarly to the Google Maps approach: - -| | | | -| --- | --- | --- | -| 1 | | Go to any location on openstreetmap.org and right click to bring up the context menu. Select the ā€œShow addressā€ item. | -| 2 | | The address will be visible in the top-left of the screen, in the place of the search bar.Ā Ā Ā Ā Ā 

    Select the coordinates and copy them into the clipboard. | -| 3 | | Simply paste the value inside the text box into the `#geolocation` attribute of a child note of the map and then it should be displayed on the map. | - -## Adding GPS tracks (.gpx) - -Trilium has basic support for displaying GPS tracks on the geo map. - -| | | | -| --- | --- | --- | -| 1 |
    | To add a track, simply drag & drop a .gpx file inside the geo map in the note tree. | -| 2 |
    | In order for the file to be recognized as a GPS track, it needs to show up as `application/gpx+xml` in the _File type_ field. | -| 3 |
    | When going back to the map, the track should now be visible.Ā Ā Ā Ā Ā 

    The start and end points of the track are indicated by the two blue markers. | - -> [!NOTE] -> The starting point of the track will be displayed as a marker, with the name of the note underneath. The start marker will also respect the icon and the `color` of the note. The end marker is displayed with a distinct icon. -> -> If the GPX contains waypoints, they will also be displayed. If they have a name, it is displayed when hovering over it with the mouse. - -## Read-only mode - -When a map is in read-only all editing features will be disabled such as: - -* The add button in theĀ Floating buttons. -* Dragging markers. -* Editing from the contextual menu (removing locations or adding new items). - -To enable read-only mode simply press the _Lock_ icon from theĀ Floating buttons. To disable it, press the button again. - -## Configuration - -### Map Style - -The styling of the map can be adjusted in the _Collection Properties_ tab in theĀ RibbonĀ or manually via the `#map:style` attribute. - -The geo map comes with two different types of styles: - -* Raster styles - * For these styles the map is represented as a grid of images at different zoom levels. This is the traditional way OpenStreetMap used to work. - * Zoom is slightly restricted. - * Currently, the only raster theme is the original OpenStreetMap style. -* Vector styles - * Vector styles are not represented as images, but as geometrical shapes. This makes the rendering much smoother, especially when zooming and looking at the building edges, for example. - * The map can be zoomed in much further. - * These come both in a light and a dark version. - * The vector styles come from [VersaTiles](https://versatiles.org/), a free and open-source project providing map tiles based on OpenStreetMap. - -> [!NOTE] -> Currently it is not possible to use a custom map style. - -### Scale - -Activating this option via theĀ RibbonĀ or manually via `#map:scale` will display an indicator in the bottom-left of the scale of the map. - -## Troubleshooting - -
    - -### Grid-like artifacts on the map - -This occurs if the application is not at 100% zoom which causes the pixels of the map to not render correctly due to fractional scaling. The only possible solution is to set the UI zoom at 100% (default keyboard shortcut is Ctrl+0). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections/Grid View.md b/docs/User Guide/User Guide/Note Types/Collections/Grid View.md deleted file mode 100644 index 33f8870101..0000000000 --- a/docs/User Guide/User Guide/Note Types/Collections/Grid View.md +++ /dev/null @@ -1,23 +0,0 @@ -# Grid View -
    - -This view presents the child notes in a grid format, allowing for a more visual navigation experience. - -Each tile contains: - -* The title of a note. -* A snippet of the content. -* For empty notes, the sub-children are also displayed, allowing for quick navigation. - -Depending on the type of note: - -* ForĀ TextĀ notes, the text can be slightly scrollable via the mouse wheel to reveal more context. -* ForĀ CodeĀ notes, syntax highlighting is applied. -* ForĀ FileĀ notes, a preview is made available for audio, video and PDF notes. -* If the note does not have a content, a list of its child notes will be displayed instead. - -The grid view is also used by default in theĀ Note ListĀ of every note, making it easy to navigate to children notes. - -## Configuration - -Unlike most other view types, the grid view is not actually configurable. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Collections/List View.md b/docs/User Guide/User Guide/Note Types/Collections/List View.md deleted file mode 100644 index e6f07aa895..0000000000 --- a/docs/User Guide/User Guide/Note Types/Collections/List View.md +++ /dev/null @@ -1,11 +0,0 @@ -# List View -
    - -List view is similar toĀ Grid View, but in the list view mode, each note is displayed in a single row with only the title and the icon of the note being visible by the default. By pressing the expand button it's possible to view the content of the note, as well as the children of the note (recursively). - -In the example above, the "Node.js" note on the left panel contains several child notes. The right panel displays the content of these child notes as a single continuous document. - -## Interaction - -* Each note can be expanded or collapsed by clicking on the arrow to the left of the title. -* In theĀ Ribbon, in the _Collection_ tab there are options to expand and to collapse all notes easily. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/File.md b/docs/User Guide/User Guide/Note Types/File.md index e73fe55656..9e21f748e1 100644 --- a/docs/User Guide/User Guide/Note Types/File.md +++ b/docs/User Guide/User Guide/Note Types/File.md @@ -12,41 +12,25 @@ Since these files come from an external source, it is not possible to create a _ ### PDFs -
    - -PDFs can be browsed directly from Trilium. - -Interaction: - -* Press the menu icon at the top-left to see a preview (thumbnail) of all the pages, as well as a table of contents (if the PDF has this information). -* See or edit the page number at the top. -* Adjust the zoom using the buttons at the top or manually editing the value. -* Rotate the document if it's in the wrong orientation. -* In the contextual menu: - * View two pages at once (great for books). - * Toggle annotations (if present in the document). - * View document properties. +SeeĀ PDFs. ### Images -
    +
    Interaction: -* _Copy reference to clipboard_, for embedding the image withinĀ TextĀ notes. SeeĀ Image referencesĀ for more information. +* _Copy reference to clipboard_, for embedding the image withinĀ TextĀ notes. + * SeeĀ Image referencesĀ for more information. + * Alternatively, press the corresponding button from theĀ Floating buttons. ### Videos -
    - -Video files can be added in as well. The file is streamed directly, so when accessing the note from a server it doesn't have to download the entire video to start playing it. - -> [!CAUTION] -> Although Trilium offers support for videos, it is generally not meant to be used with very large files. Uploading large videos will cause theĀ DatabaseĀ to balloon as well as the anyĀ BackupĀ of it. In addition to that, there might be slowdowns when first uploading the files. Otherwise, a large database should not impact the general performance of Trilium significantly. +SeeĀ Videos. ### Audio -
    +
    Adding a supported audio file will reveal a basic audio player that can be used to play it. @@ -59,17 +43,17 @@ Interactions: ### Text files -
    +
    Files that are identified as containing text will show a preview of their content. One common use case for this type of file is to embed text files whose content is not necessarily of interest to the user, such as third-party libraries or generated content, that can then be downloaded if needed. -Note that generally text files will be [imported](../Basic%20Concepts%20and%20Features/Import%20%26%20Export) as eitherĀ TextĀ orĀ CodeĀ notes. To bypass this behavior and create a _File_ note type, use the _Import into note_ feature and uncheck _Import HTML, Markdown and TXT as text notes_, as well as _Import recognized code files as code notes_.Ā  +Note that generally text files will be [imported](../Basic%20Concepts%20and%20Features/Import%20%26%20Export.md) as eitherĀ TextĀ orĀ CodeĀ notes. To bypass this behavior and create a _File_ note type, use the _Import into note_ feature and uncheck _Import HTML, Markdown and TXT as text notes_, as well as _Import recognized code files as code notes_.Ā  Since one of the use cases for having files instead of notes is to display large files, the content preview is limited to a relatively small amount of characters. To view the full file, consider opening it in an external application. ### Unknown file types -
    +
    If the file could not be identified as any of the supported file types from above, it will be treated as an unknown file. In this case, all the default interactions will be available such as downloading or opening the file externally, but there will be no preview of the content. @@ -86,6 +70,6 @@ If the file could not be identified as any of the supported file types from abov * Files are also displayed in theĀ Note ListĀ based on their type: - + * Non-image files can be embedded into text notes as read-only widgets via theĀ Include NoteĀ functionality. * Image files can be embedded into text notes like normal images viaĀ Image references. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/File/1_PDFs_image.png b/docs/User Guide/User Guide/Note Types/File/1_PDFs_image.png new file mode 100644 index 0000000000..36e4fd6d82 Binary files /dev/null and b/docs/User Guide/User Guide/Note Types/File/1_PDFs_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/File/PDFs.md b/docs/User Guide/User Guide/Note Types/File/PDFs.md new file mode 100644 index 0000000000..ea97274e0e --- /dev/null +++ b/docs/User Guide/User Guide/Note Types/File/PDFs.md @@ -0,0 +1,86 @@ +# PDFs +
    + +PDFs file can be uploaded in Trilium, where they will be displayed without the need to download them first. + +Since v0.102.0, PDFs will be rendered using Trilium's built-in PDF viewer, which is a customization of [Mozilla's PDF.js viewer](https://mozilla.github.io/pdf.js/) (also built-in in the Mozilla Firefox browser). Versions prior to that render PDFs using the browser's default PDF viewer. + +## Storing last position and settings + +For every PDF, Trilium will remember the following information: + +* The current page. +* The scroll position, within the current page. +* The rotation of the page. + +This makes it useful when reading large documents since the position is remembered automatically. This happens in the background, however it's recorded only a few seconds after stopping any scroll actions. + +> [!TIP] +> Technically, the information about the scroll position and rotation is stored in theĀ AttachmentsĀ section, in a dedicated attachment called `pdfHistory.json`. + +## Annotations + +Since v0.102.0 it's possible to annotate PDFs. To do so, look for the annotation buttons on the right side of the PDF toolbar (). + +### Supported annotations + +The following annotation methods are supported: + +* **Highlight** + Allows highlighting text with one of the predefined colors. + * The thickness is also adjustable. + * It's also possible to highlight the blank space, turning the feature more into a thicker pen. +* **Text** + Allows adding arbitrary text, with a custom color and size. +* **Pen** + Allows free drawing on the document, with variable color, thickness and opacity. +* **Image** + Allows inserting images from outside Trilium directly into the document. + +### Editing existing annotations + +Although annotations are stored in the PDF itself, they can be edited. To edit an annotation, press one of the annotation buttons from the previous section to enter edit mode and click on an existing annotation. This will reveal a toolbar with options to customize the annotation (e.g. to change a color), as well as the possibility to remove it. + +### How are annotations stored + +Annotations are stored directly in the PDF. When modifications are made, Trilium will replace the PDF with the new one. + +Since modifications are automatically saved, there's no need to manually save the document after making modifications to the annotations. + +The benefit of ā€œbaked-in annotationsā€ is that they are also accessible if downloading (for external use outside Trilium) or sharing the note. + +The downside is that the entire PDF needs to be sent back to the server, which can slow down performance for larger documents. If you encounter any issues from this system, feel free to [report it](../../Troubleshooting/Reporting%20issues.md). + +## Filling out forms + +Similar to annotations, forms are also supported by Trilium since v0.102.0. If the document has fields that can be filled-in, they will be indicated with a colored background. + +Simply type text in the forms and they will be automatically saved. + +## Sidebar navigation + +> [!NOTE] +> This feature is only available ifĀ New LayoutĀ is enabled. If you are using the old layout, these features are still available by looking for a sidebar button in the PDF viewer toolbar. + +When a PDF file is opened in Trilium theĀ Right SidebarĀ is augmented with PDF-specific navigation, with the following features: + +* Table of contents/outline + * All the headings and ā€œbookmarksā€ will be displayed hierarchially. + * The heading on the current page is also highlighted (note that it can be slightly offset depending on how many headings are on the same page). + * Clicking on a heading will jump to the corresponding position in the PDF. +* Pages + * A preview of all the pages with a small thumbnail. + * Clicking on a page will automatically navigate to that page. +* Attachments + * If the PDF has its own attachments (not to be confused with Trilium'sĀ Attachments), they will be displayed in a list. + * Some information such as the name and size of the attachment are displayed. + * It's possible to download the attachment by clicking on the download button. +* Layers + * A less common feature, if the PDF has toggle-able layers, these layers will be displayed in a list here. + * It's possible to toggle the visibility for each individual layer. + +## Share functionality + +PDFs can also be shared using theĀ SharingĀ feature. This will also use Trilium's customized PDF viewer. + +If you are using a reverse proxy on your server with strict access limitations for the share functionality, make sure that `[host].com/pdfjs` directory is accessible. Note that this directory is outside the `/share` route as it's common with the rest of the application. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/File/PDFs_image.png b/docs/User Guide/User Guide/Note Types/File/PDFs_image.png new file mode 100644 index 0000000000..cf8d2c109b Binary files /dev/null and b/docs/User Guide/User Guide/Note Types/File/PDFs_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/File/Videos.md b/docs/User Guide/User Guide/Note Types/File/Videos.md new file mode 100644 index 0000000000..b65f44e4e6 --- /dev/null +++ b/docs/User Guide/User Guide/Note Types/File/Videos.md @@ -0,0 +1,63 @@ +# Videos +
    + +Starting with v0.103.0, Trilium has a custom video player which offers more features than the built-in video player. + +Versions prior to v0.103.0 also support videos, but using the built-in player. + +The file is streamed directly, so when accessing the note from a server it doesn't have to download the entire video to start playing it. + +## Note on large video files + +Although Trilium offers support for videos, it is generally not meant to be used with very large files. Uploading large videos will cause theĀ DatabaseĀ to balloon as well as the anyĀ BackupĀ of it. In addition to that, there might be slowdowns when first uploading the files. Otherwise, a large database should not impact the general performance of Trilium significantly. + +## Supported formats + +Trilium uses the built-in video decoding mechanism of the browser (or Electron/Chromium when running on the desktop). Starting with v0.103.0, a message will be displayed instead when a video format is not supported. + +## Interactions + +To play/pause the video, simply click anywhere on the video. + +The controls at the bottom will hide automatically after playing, simply move the mouse to show them again. + +The bottom bar has the following features: + +* A track bar to seek across the video. +* On the left of the track bar, the current time is indicated. +* On the right of the track bar, the remaining time is indicated. +* On the left side there are buttons to: + + * Adjust the playback speed (e.g. 0.5x, 1x). + * Rotate the video by 90 degrees. +* In the center: + + * Go back by 10s + * Play/pause + * Go forward by 30s + * Loop, which when enabled will restart the video once it reaches the end. +* On the right side: + + * Mute button + * Volume adjustment + * Full screen + * Zoom to fill, which will crop the video so that it fills the entire window. + * Picture-in-picture (if the browser supports it). + +## Keyboard shortcuts + +The following keyboard shortcuts are supported by the video player: + +| | | +| --- | --- | +| Space | Play/pause | +| Left arrow key | Go back by 10s | +| Right arrow key | Go forward by 10s | +| Ctrl + Left arrow key | Go back by 1 min | +| Ctrl + Right arrow key | Go right by 1 min | +| F | Toggle full-screen | +| M | Mute/unmute | +| Home | Go to the beginning of the video | +| End | Go to the end of the video | +| Up | Increase volume by 5% | +| Down | Decrease volume by 5% | \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/File/Videos_image.png b/docs/User Guide/User Guide/Note Types/File/Videos_image.png new file mode 100644 index 0000000000..29cfb5da79 Binary files /dev/null and b/docs/User Guide/User Guide/Note Types/File/Videos_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/File_image.png b/docs/User Guide/User Guide/Note Types/File_image.png index 0f01d19d96..04478a3ada 100644 Binary files a/docs/User Guide/User Guide/Note Types/File_image.png and b/docs/User Guide/User Guide/Note Types/File_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Mermaid Diagrams.md b/docs/User Guide/User Guide/Note Types/Mermaid Diagrams.md index 61cf0d515b..14b0729875 100644 --- a/docs/User Guide/User Guide/Note Types/Mermaid Diagrams.md +++ b/docs/User Guide/User Guide/Note Types/Mermaid Diagrams.md @@ -1,9 +1,17 @@ # Mermaid Diagrams +> [!TIP] +> For a quick understanding of the Mermaid syntax, seeĀ Syntax referenceĀ (official documentation). +
    +## Types of diagrams + Trilium supports Mermaid, which adds support for various diagrams such as flowchart, sequence diagram, class diagram, state diagram, pie charts, etc., all using a text description of the chart instead of manually drawing the diagram. -For the official documentation of Mermaid.js see [mermaid.js.org/intro/](https://mermaid.js.org/intro/). +Starting with v0.103.0, Mermaid diagrams no longer start with a sample flowchart, but instead a pane at the bottom will show all the supported diagrams with sample code for each: + +* Simply click on any of the samples to apply it. +* The pane will disappear as soon as something is typed in the code editor or a sample is selected. To make it appear again, simply remove the content of the note. ## Layouts diff --git a/docs/Developer Guide/Developer Guide/Development and architecture/Revisions.md b/docs/User Guide/User Guide/Note Types/Mermaid Diagrams/Syntax reference.dat similarity index 100% rename from docs/Developer Guide/Developer Guide/Development and architecture/Revisions.md rename to docs/User Guide/User Guide/Note Types/Mermaid Diagrams/Syntax reference.dat diff --git a/docs/User Guide/User Guide/Note Types/Mind Map.md b/docs/User Guide/User Guide/Note Types/Mind Map.md index b21edb6836..878a4f5447 100644 --- a/docs/User Guide/User Guide/Note Types/Mind Map.md +++ b/docs/User Guide/User Guide/Note Types/Mind Map.md @@ -21,4 +21,5 @@ The mindmap allows for easy jotting down of ideas and storing them in a hierarch * Use the buttons at the top-left to change the positioning of the nodes relative to the root node (to the left, to the right, or to both sides). * In theĀ Floating buttonsĀ area: * An [image reference](Text/Images/Image%20references.md) can be copied, to paste the mind map in a text note. - * The diagram can be exported either as SVG (vectorial) or PNG (raster). \ No newline at end of file + * The diagram can be exported either as SVG (vectorial) or PNG (raster). + * The note can be togged [read-only](../Basic%20Concepts%20and%20Features/Notes/Read-Only%20Notes.md). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Relation Map.md b/docs/User Guide/User Guide/Note Types/Relation Map.md index 23af215740..080c2f98e3 100644 --- a/docs/User Guide/User Guide/Note Types/Relation Map.md +++ b/docs/User Guide/User Guide/Note Types/Relation Map.md @@ -1,15 +1,31 @@ # Relation Map -Relation map is a type ofĀ [Note](../Basic%20Concepts%20and%20Features/Notes.md)Ā which visualizes notes and their [relations](../Advanced%20Usage/Attributes.md). See an example: +Relation map is a type ofĀ noteĀ which visualizes notes and their [relations](../Advanced%20Usage/Attributes.md). + +## Interaction + +* To create a new note and add it to the board, press the plus button in theĀ Floating buttons. + * Afterwards, click anywhere on the map to place it there. + * The note will be placed as a sub-child of the map. +* An existing note can also be dragged from theĀ Note Tree. It will be placed at the position it's dragged on. + * Multiple notes can also be dragged viaĀ Multiple selection. The notes will be positioned near the dragged position without overlapping. + * The dragged note can be a sub-child of the map, or it can be at any arbitrary position. +* To create a relationship, hold the mouse on the box on the right of a note and then: + * Drag it over another note to create a relationship pointing from the first note to the second one. + * Drag over the same note to create a self-referencing relationship (represented as a loop). + * Once dragged, enter the name of the relationship to create. To cancel, simply dismiss the dialog or press Esc. +* To open a note, either click on the note (opening it in the current view) or use the right click menu to open in a new tab. +* To edit the title of a note or to delete it (either from the map, or delete it completely), right click the note. +* To delete a relationship, right click it and select the corresponding option. ## Development process demo This is a basic example how you can create simple diagram using relation maps: -![](1_Relation%20Map_relation-map-.png) + And this is how you can create it: -![](1_Relation%20Map_relation-map-.gif) + We start completely from scratch by first creating new note called "Development process" and changing its type to "Relation map". After that we create new notes one by one and place them by clicking into the map. We also drag [relations](../Advanced%20Usage/Attributes.md)between notes and name them. That's all! @@ -19,21 +35,21 @@ Items on the map - "Specification", "Development", "Testing" and "Demo" are actu This is more complicated demo using some advanced concepts. Resulting diagram is here: -![](Relation%20Map_relation-map-.png) + This is how you get to it: -![](Relation%20Map_relation-map-.gif) + There are several steps here: -* we start with empty relation map and two existing notes representing Prince Philip and Queen Elizabeth II. These two notes already have "isPartnerOf" [relations](../Advanced%20Usage/Attributes.md)defined. +* we start with empty relation map and two existing notes representing Prince Philip and Queen Elizabeth II. These two notes already have `isPartnerOf` [relations](../Advanced%20Usage/Attributes.md)defined. * There are actually two "inverse" relations (one from Philip to Elizabeth and one from Elizabeth to Philip) -* we drag both notes to relation map and place to suitable position. Notice how the existing "isPartnerOf" relations are displayed. +* we drag both notes to relation map and place to suitable position. Notice how the existing `isPartnerOf` relations are displayed. * now we create new note - we name it "Prince Charles" and place it on the relation map by clicking on the desired position. The note is by default created under the relation map note (visible in the note tree on the left). -* we create two new relations "isChildOf" targeting both Philip and Elizabeth - * now there's something unexpected - we can also see the relation to display another "hasChild" relation. This is because there's a [relation definition](../Advanced%20Usage/Attributes/Promoted%20Attributes.md) which puts "isChildOf" as an "[inverse](../Advanced%20Usage/Attributes/Promoted%20Attributes.md)" relation of "hasChildOf" (and vice versa) and thus it is created automatically. -* we create another note for Princess Diana and create "isPartnerOf" relation from Charles. Again notice how the relation has arrows both ways - this is because "isPartnerOf" definition specifies its inverse relation as again "isPartnerOf" so the opposite relation is created automatically. +* we create two new relations `isChildOf` targeting both Philip and Elizabeth + * now there's something unexpected - we can also see the relation to display another `hasChild` relation. This is because there's a [relation definition](../Advanced%20Usage/Attributes/Promoted%20Attributes.md) which puts `isChildOf` as an "[inverse](../Advanced%20Usage/Attributes/Promoted%20Attributes.md)" relation of `hasChildOf` (and vice versa) and thus it is created automatically. +* we create another note for Princess Diana and create `isPartnerOf` relation from Charles. Again notice how the relation has arrows both ways - this is because `isPartnerOf` definition specifies its inverse relation as again "isPartnerOf" so the opposite relation is created automatically. * as the last step we pan & zoom the map to fit better to window dimensions. Relation definitions mentioned above come from "Person template" note which is assigned to any child of "My Family Tree" relation note. You can play with the whole thing in the [demo notes](../Advanced%20Usage/Database.md). @@ -46,4 +62,4 @@ Alternatively, you can specify comma delimited list of relation names in `hideRe ## See also -* [Note Map](../Advanced%20Usage/Note%20Map%20\(Link%20map%2C%20Tree%20map\).md)Ā is a similar concept \ No newline at end of file +* Note MapĀ is a similar concept. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Render Note.md b/docs/User Guide/User Guide/Note Types/Render Note.md index 74acf618d9..60387ce507 100644 --- a/docs/User Guide/User Guide/Note Types/Render Note.md +++ b/docs/User Guide/User Guide/Note Types/Render Note.md @@ -1,15 +1,19 @@ # Render Note
    -Render Note is used inĀ Scripting. It works by displaying the HTML of aĀ CodeĀ note, via an attribute. +Render Note is a special case of [front-end scripting](../Scripting/Frontend%20Basics.md) which allows rendering custom content inside a note. This makes it possible to create custom dashboards, or to use a custom note editor. + +The content can either be a vanilla HTML, or Preact JSX. ## Creating a render note -1. Create aĀ CodeĀ note with the HTML language, with what needs to be displayed (for example `

    Hello world.

    `). +1. Create aĀ CodeĀ note with the: + 1. HTML language for the legacy/vanilla method, with what needs to be displayed (for example `

    Hello world.

    `). + 2. JSX for the Preact-based approach (see below). 2. Create aĀ Render Note. 3. Assign the `renderNote` [relation](../Advanced%20Usage/Attributes.md) to point at the previously created code note. -## Dynamic content +## Legacy scripting using jQuery A static HTML is generally not enough forĀ Scripting. The next step is to automatically change parts of the note using JavaScript. @@ -17,14 +21,14 @@ For a simple example, we are going to create a render note that displays the cur To do so, first create an HTML code note with the following content: -``` +```html

    Current date & time

    The current date & time is ``` Now we need to add the script. Create anotherĀ Code, but this time of JavaScript (frontend) language. Make sure the newly created note is a direct child of the HTML note created previously; with the following content: -``` +```javascript const $dateEl = api.$container.find(".date"); $dateEl.text(new Date()); ``` @@ -34,6 +38,35 @@ Now create a render note at any place and set its `~renderNote` relation to poin > **Current date & time** > The current date & time is Sun Apr 06 2025 15:26:29 GMT+0300 (Eastern European Summer Time) +## Dynamic content using Preact & JSX + +As a more modern alternative to jQuery, it's possible to use Preact & JSX to render pages. Since JSX is a superset of JavaScript, there's no need to provide a HTML anymore. + +Here are the steps to creating a simple render note: + +1. Create a note of typeĀ Render Note. +2. Create a childĀ CodeĀ note with JSX as the language. + As an example, use the following content: + + ``` + export default function() { + return ( + <> +

    Hello world.

    + + ); + } + ``` +3. In the parent render note, define a `~renderNote` relation pointing to the newly created child. +4. Refresh the render note and it should display a ā€œHello worldā€ message. + +## Refreshing the note + +It's possible to refresh the note via: + +* The corresponding button inĀ Floating buttons. +* The ā€œRender active noteā€ [keyboard shortcut](../Basic%20Concepts%20and%20Features/Keyboard%20Shortcuts.md) (not assigned by default). + ## Examples * Weight TrackerĀ which is present in theĀ Demo Notes. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Spreadsheets.md b/docs/User Guide/User Guide/Note Types/Spreadsheets.md new file mode 100644 index 0000000000..70fa55a757 --- /dev/null +++ b/docs/User Guide/User Guide/Note Types/Spreadsheets.md @@ -0,0 +1,66 @@ +# Spreadsheets +
    + +> [!IMPORTANT] +> Spreadsheets are a new type of note introduced in v0.103.0 and are currently considered experimental/beta. As such, expect major changes to occur to this note type. + +Spreadsheets provide a familiar experience to Microsoft Excel or LibreOffice Calc, with support for formulas, data validation and text formatting. + +## Spreadsheets vs. collections + +There is a slight overlap between spreadsheets and theĀ TableĀ collection. In general the table collection is useful to track meta-information about notes (for example a collection of people and their birthdays), whereas spreadsheets are quite useful for calculations since they support formulas. + +Spreadsheets also benefit from a wider range of features such as data validation, formatting and can work on a relatively large dataset. + +## Important statement regarding data format + +For Trilium as a knowledge database, it is important that data is stored in a format that is easy to convert to something else. For example,Ā TextĀ notes can be exported to either HTML or Markdown, making it relatively easy to migrate to another software or simply to stand the test of time. + +For spreadsheets, Trilium uses a technology called [Univer Sheets](https://docs.univer.ai/), developed by DreamNum Co., Ltd. Although this software library is quite powerful and has a good track record (starting with Luckysheet from 2020, becoming Univer somewhere in 2023), it uses its own JSON format to store the sheets. + +As such, if Univer were to become unmaintained or incompatible for some reason, your data might become vendor locked-in. + +With that in mind, spreadsheets can be really useful for quick calculations, but it's important not to have critical information on it that you might not want to need in a few years time. + +## Regarding data export + +Currently, in Trilium there is no way to export the spreadsheets to CSV or Excel formats. We might manage to add support for it at some point, but currently this is not the case. + +## Supported features + +The spreadsheet has support for the following features: + +* Filtering +* Sorting +* Data validation +* Conditional formatting +* Notes / annotations +* Find / replace + +We might consider adding [other features](https://docs.univer.ai/guides/sheets/features/filter) from Univer at some point. If there is a particular feature that can be added easily, it can be discussed over [GitHub Issues](../Troubleshooting/Reporting%20issues.md). + +## Features not supported yet + +### Regarding Pro features + +Univer spreadsheets also feature a [Pro plan](https://univer.ai/pro) which adds quite a lot of functionality such as charts, printing, pivot tables, export, etc. + +As the Pro plan needs a license, Trilium does not support any of the premium features. Theoretically, pro features can be used in trial mode with some limitations, we might explore this direction at some point. + +### Planned features + +There are a few features that are already planned but are not supported yet: + +* Trilium-specific formulas (e.g. to obtain the title of a note). +* User-defined formulas +* Cross-workbook calculation + +If you would like us to work on these features, consider [supporting us](https://triliumnotes.org/en/support-us). + +## Known limitations + +* It is possible to share a spreadsheet, case in which a best-effort HTML rendering of the spreadsheet is done. + + * For more advanced use cases, this will most likely not work as intended. Feel free to [report issues](../Troubleshooting/Reporting%20issues.md), but keep in mind that we might not be able to have a complete feature parity with all the features of Univer. +* There is currently no export functionality, as stated previously. +* There is no dedicated mobile support. Mobile support is currently experimental in Univer and when it becomes stable, we could potentially integrate it into Trilium as well. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Spreadsheets_image.png b/docs/User Guide/User Guide/Note Types/Spreadsheets_image.png new file mode 100644 index 0000000000..6b957c220b Binary files /dev/null and b/docs/User Guide/User Guide/Note Types/Spreadsheets_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text.md b/docs/User Guide/User Guide/Note Types/Text.md index eb0cb76b12..3ffb18b6dc 100644 --- a/docs/User Guide/User Guide/Note Types/Text.md +++ b/docs/User Guide/User Guide/Note Types/Text.md @@ -16,7 +16,7 @@ Fore more information seeĀ General formatting
    • Headings (section titles, paragraph)
    • Font size
    • Bold, italic, underline, strike-through
    • Superscript, subscript
    • Font color & background color
    • Remove formatting
    Lists
    • Bulleted lists
    • Numbered lists
    • To-do lists
    Block quotes & admonitions
    • Block quotes
    • Admonitions
    Tables
    • Basic tables
    • Merging cells
    • Styling tables and cells.
    • Table captions
    Developer-specific formatting
    • Inline code
    • Code blocks
    • Keyboard shortcuts
    Footnotes
    • Footnotes
    Images
    • Images
    Links
    • External links
    • Internal Trilium links
    Include Note
    • Include note
    Insert buttonsOther featuresPremium features +
    Dedicated articleFeature
    General formatting
    • Headings (section titles, paragraph)
    • Font size
    • Bold, italic, underline, strike-through
    • Superscript, subscript
    • Font color & background color
    • Remove formatting
    Lists
    • Bulleted lists
    • Numbered lists
    • To-do lists
    Block quotes & admonitions
    • Block quotes
    • Admonitions
    Tables
    • Basic tables
    • Merging cells
    • Styling tables and cells.
    • Table captions
    Developer-specific formatting
    • Inline code
    • Code blocks
    • Keyboard shortcuts
    Footnotes
    • Footnotes
    Images
    • Images
    Links
    • External links
    • Internal Trilium links
    Include Note
    • Include note
    Insert buttons
    Other features
    Premium features
    ## Read-Only vs. Editing Mode diff --git a/docs/User Guide/User Guide/Note Types/Text/10_Lists_image.png b/docs/User Guide/User Guide/Note Types/Text/10_Lists_image.png index 1282f27ec0..fba0cc85c9 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/10_Lists_image.png and b/docs/User Guide/User Guide/Note Types/Text/10_Lists_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/10_Tables_image.png b/docs/User Guide/User Guide/Note Types/Text/10_Tables_image.png index 5cf2cc519c..099b253570 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/10_Tables_image.png and b/docs/User Guide/User Guide/Note Types/Text/10_Tables_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/11_Tables_image.png b/docs/User Guide/User Guide/Note Types/Text/11_Tables_image.png index cde63c9ac3..5cf2cc519c 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/11_Tables_image.png and b/docs/User Guide/User Guide/Note Types/Text/11_Tables_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/12_Tables_image.png b/docs/User Guide/User Guide/Note Types/Text/12_Tables_image.png index 9c512ee533..cde63c9ac3 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/12_Tables_image.png and b/docs/User Guide/User Guide/Note Types/Text/12_Tables_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/13_Tables_image.png b/docs/User Guide/User Guide/Note Types/Text/13_Tables_image.png new file mode 100644 index 0000000000..9c512ee533 Binary files /dev/null and b/docs/User Guide/User Guide/Note Types/Text/13_Tables_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/14_Tables_image.png b/docs/User Guide/User Guide/Note Types/Text/14_Tables_image.png new file mode 100644 index 0000000000..dd4becc162 Binary files /dev/null and b/docs/User Guide/User Guide/Note Types/Text/14_Tables_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/1_Lists_image.png b/docs/User Guide/User Guide/Note Types/Text/1_Lists_image.png index fba0cc85c9..4a17f481cc 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/1_Lists_image.png and b/docs/User Guide/User Guide/Note Types/Text/1_Lists_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/2_Lists_image.png b/docs/User Guide/User Guide/Note Types/Text/2_Lists_image.png index ee7a6bdead..2473cd3102 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/2_Lists_image.png and b/docs/User Guide/User Guide/Note Types/Text/2_Lists_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/4_Lists_image.png b/docs/User Guide/User Guide/Note Types/Text/4_Lists_image.png index 8369a03c61..3caf2d880c 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/4_Lists_image.png and b/docs/User Guide/User Guide/Note Types/Text/4_Lists_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/7_Lists_image.png b/docs/User Guide/User Guide/Note Types/Text/7_Lists_image.png index 3caf2d880c..ee7a6bdead 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/7_Lists_image.png and b/docs/User Guide/User Guide/Note Types/Text/7_Lists_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/8_Lists_image.png b/docs/User Guide/User Guide/Note Types/Text/8_Lists_image.png index 4a17f481cc..30a9511b08 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/8_Lists_image.png and b/docs/User Guide/User Guide/Note Types/Text/8_Lists_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/9_Lists_image.png b/docs/User Guide/User Guide/Note Types/Text/9_Lists_image.png index 2473cd3102..8369a03c61 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/9_Lists_image.png and b/docs/User Guide/User Guide/Note Types/Text/9_Lists_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/9_Tables_image.png b/docs/User Guide/User Guide/Note Types/Text/9_Tables_image.png index 099b253570..e802154768 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/9_Tables_image.png and b/docs/User Guide/User Guide/Note Types/Text/9_Tables_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks.md b/docs/User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks.md index 18960b3359..31ae3233eb 100644 --- a/docs/User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks.md +++ b/docs/User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks.md @@ -13,6 +13,14 @@ Note that this feature is meant for generally small snippets of code. For larger * Type ` ``` ` (as in Markdown). * Note that it's not possible to specify the language, as it will default to the last selected language. +## Exiting out of the code block + +* To exit out of a code block and enter a normal paragraph, move the cursor at the end of the code block and press Enter twice. +* Similarly, to insert a paragraph above the note block, move the cursor at the beginning of the code block and press Enter twice. + +> [!NOTE] +> If you've pasted a code block with a more complex HTML structure, exiting out of the code block by pressing Enter multiple times might not work. In that case the best approach is to delete the code block entirely and use Ctrl+Shift+V (paste as plain text). + ## Syntax highlighting & color schemes Since TriliumNext v0.90.12, Trilium will try to offer syntax highlighting to the code block. Note that the syntax highlighting mechanism is slightly different than the one inĀ CodeĀ notes as different technologies are involved. diff --git a/docs/User Guide/User Guide/Note Types/Text/General formatting.md b/docs/User Guide/User Guide/Note Types/Text/General formatting.md index e05d730aad..28ffb5f033 100644 --- a/docs/User Guide/User Guide/Note Types/Text/General formatting.md +++ b/docs/User Guide/User Guide/Note Types/Text/General formatting.md @@ -79,6 +79,10 @@ Note that heading styles are not taken into consideration, these must be manuall When pasting content that comes with undesired formatting, an alternative to pasting and then removing formatting is pasting as plain text via Ctrl+Shift+V. +## Format painter + +TheĀ Format PainterĀ allows users to copy the formatting of text (such as bold, italic, Strikethrough, etc.) and apply it to other parts of the document. It helps maintain consistent formatting and accelerates the creation of rich content. + ## Support for Markdown When exported toĀ Markdown, most of the general formatting is maintained such as headings, bold, italic, underline, etc. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Include Note.md b/docs/User Guide/User Guide/Note Types/Text/Include Note.md index 874bf70cab..8a3584f8b1 100644 --- a/docs/User Guide/User Guide/Note Types/Text/Include Note.md +++ b/docs/User Guide/User Guide/Note Types/Text/Include Note.md @@ -3,4 +3,10 @@ Text notes can "include" another note as a read-only widget. This can be useful ## Including a note -In theĀ Formatting toolbar, look for the ![](Include%20Note_image.png) button. There is also a keyboard shortcut defined for it but it is not allocated by default. \ No newline at end of file +In theĀ Formatting toolbar, look for the ![](Include%20Note_image.png) button. There is also a keyboard shortcut defined for it but it is not allocated by default. + +## Included notes in the share functionality + +If a [shared note](../../Advanced%20Usage/Sharing.md) contains one or more included notes, they will be displayed in the content of the note as if they were part of the note itself. + +For this to work, the included notes must also be shared, otherwise they will not be shown. However, the included notes can still be hidden from the note tree via `#shareHiddenFromTree`. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Insert buttons.md b/docs/User Guide/User Guide/Note Types/Text/Insert buttons.md index 6a161faddf..8d87e083c9 100644 --- a/docs/User Guide/User Guide/Note Types/Text/Insert buttons.md +++ b/docs/User Guide/User Guide/Note Types/Text/Insert buttons.md @@ -53,7 +53,7 @@ Alternatively, it's possible to insert a horizontal ruler by typing `---`.
    -Page breaks provide a way to force the next paragraph or block (table, image, etc.) to be displayed onto the next page when printing (either to a real printer to [when exporting to PDF](../../Basic%20Concepts%20and%20Features/Notes/Export%20as%20PDF.md)). +Page breaks provide a way to force the next paragraph or block (table, image, etc.) to be displayed onto the next page when printing (either to a real printer to [when exporting to PDF](../../Basic%20Concepts%20and%20Features/Notes/Printing%20%26%20Exporting%20as%20PDF.md)). Page breaks are marked in the editor with the words _Page break_, but they will not actually be shown when printed. diff --git a/docs/User Guide/User Guide/Note Types/Text/Keyboard shortcuts.md b/docs/User Guide/User Guide/Note Types/Text/Keyboard shortcuts.md index 84b6edc32e..ffda655b0b 100644 --- a/docs/User Guide/User Guide/Note Types/Text/Keyboard shortcuts.md +++ b/docs/User Guide/User Guide/Note Types/Text/Keyboard shortcuts.md @@ -1,7 +1,7 @@ # Keyboard shortcuts ## Trilium-specific shortcuts -| Action | PC | Mac | +| Action | PC | Mac | | --- | --- | --- | | Bring up inline formatting toolbar (arrow keys ←,→ to navigate, Enter to apply) | Alt+F10 | ⌄+F10 | | Bring up block formatting toolbar | Alt+F10 | ⌄+F10 | @@ -13,9 +13,9 @@ | Mark selected text as [keyboard shortcut](Developer-specific%20formatting.md) | Ctrl + Alt + K | ⌘\+ ⌄\+ K | | InsertĀ Math Equations | Ctrl + M | ⌘\+ M | | Move blocks (lists, paragraphs, etc.) up | Ctrl+↑ | ⌘+↑ | -| Alt+↑ | ⌄+↑ | | +| Alt+↑ | ⌄+↑ | | | Move blocks (lists, paragraphs, etc.) down | Ctrl+↑ | ⌘+↑ | -| Alt+↓ | ⌄+↓ | | +| Alt+↓ | ⌄+↓ | | ## Common shortcuts @@ -24,9 +24,9 @@ ### Content editing -| Action | PC | Mac | +| Action | PC | Mac | | --- | --- | --- | -| Insert a hard break (a new paragraph) | Enter | | +| Insert a hard break (a new paragraph) | Enter | | | Insert a soft break (a `
    ` element) | Shift+Enter | ⇧Enter | | Copy selected content | Ctrl+C | ⌘C | | Paste content | Ctrl+V | ⌘V | @@ -36,8 +36,8 @@ | Bold text | Ctrl+B | ⌘B | | Change text case | Shift+F3 | ⇧F3 (may require Fn) | | Create link | Ctrl+K | ⌘K | -| Move out of a link | ←←, →→ | | -| Move out of an inline code style | ←←, →→ | | +| Move out of a link | ←←, →→ | | +| Move out of an inline code style | ←←, →→ | | | Select all | Ctrl+A | ⌘A | | Find in the document | Ctrl+F | ⌘F | | Copy text formatting | Ctrl+Shift+C | āŒ˜ā‡§C | @@ -45,45 +45,45 @@ | Italic text | Ctrl+I | ⌘I | | Strikethrough text | Ctrl+Shift+X | āŒ˜ā‡§X | | Underline text | Ctrl+U | ⌘U | -| Revert autoformatting action | Backspace | | +| Revert autoformatting action | Backspace | | ### Interacting with blocks Blocks are images, tables, blockquotes, annotations. -| Action | PC | Mac | +| Action | PC | Mac | | --- | --- | --- | -| Insert a new paragraph directly after a widget | Enter | | +| Insert a new paragraph directly after a widget | Enter | | | Insert a new paragraph directly before a widget | Shift+Enter | ⇧Enter | -| Move the caret to allow typing directly before a widget | ↑, ← | | -| Move the caret to allow typing directly after a widget | ↓, → | | -| After entering a nested editable, move the selection to the closest ancestor widget. For example: move from an image caption to the whole image widget. | Tab then Esc | | +| Move the caret to allow typing directly before a widget | ↑, ← | | +| Move the caret to allow typing directly after a widget | ↓, → | | +| After entering a nested editable, move the selection to the closest ancestor widget. For example: move from an image caption to the whole image widget. | Tab then Esc | | Specifically for lists: -| Action | PC | Mac | +| Action | PC | Mac | | --- | --- | --- | -| Increase list item indent | ⇄ | | +| Increase list item indent | ⇄ | | | Decrease list item indent | Shift+⇄ | ⇧⇄ | In tables: -| Action | PC | Mac | +| Action | PC | Mac | | --- | --- | --- | -| Move the selection to the next cell | ⇄ | | +| Move the selection to the next cell | ⇄ | | | Move the selection to the previous cell | Shift+⇄ | ⇧⇄ | -| Insert a new table row (when in the last cell of a table) | ⇄ | | -| Navigate through the table | ↑, →, ↓, ← | | +| Insert a new table row (when in the last cell of a table) | ⇄ | | +| Navigate through the table | ↑, →, ↓, ← | | ### General UI shortcuts -| Action | PC | Mac | +| Action | PC | Mac | | --- | --- | --- | -| Close contextual balloons, dropdowns, and dialogs | Esc | | +| Close contextual balloons, dropdowns, and dialogs | Esc | | | Open the accessibility help dialog | Alt+0 | ⌄0 | | Move focus between form fields (inputs, buttons, etc.) | ⇄, Shift+⇄ | ⇄, ⇧⇄ | | Move focus to the toolbar, navigate between toolbars | Alt+F10 | ⌄F10 (may require Fn) | -| Navigate through the toolbar or menu bar | ↑, →, ↓, ← | | -| Navigate to the next focusable field or an element outside the editor | Tab, Shift+Tab | | -| Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content. | Enter, Space | | +| Navigate through the toolbar or menu bar | ↑, →, ↓, ← | | +| Navigate to the next focusable field or an element outside the editor | Tab, Shift+Tab | | +| Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content. | Enter, Space | | | Move focus in and out of an active dialog window | Ctrl+F6 | ⌘F6 (may require Fn) | \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Links.md b/docs/User Guide/User Guide/Note Types/Text/Links.md index 93d9bfcc96..e4db27f4fe 100644 --- a/docs/User Guide/User Guide/Note Types/Text/Links.md +++ b/docs/User Guide/User Guide/Note Types/Text/Links.md @@ -4,20 +4,6 @@ There are two types of links: * External links, for standard hyperlinks to websites or other resources. * Internal (reference) linksĀ for links to other notes within Trilium. -## Pasting links - -* For internal links (links to notes in Trilium), press Ctrl+C in theĀ Note Tree: - * Pasting directly in a text note will create a reference link (with an icon to the note and the actual note title). - * Pasting over an existing text will create a traditional link. -* For external links: - * Paste the raw URL directly and press space to turn it into a link. - * Select a text and paste the URL over it to turn that text into a link. - * If you are pasting a formatted link (e.g. from the a webpage in a browser), simply paste it and it will keep the original text and URL. - -## In-place linking - -Trilium also provides "inline" linking - type `@` and you'll see an autocomplete, just type few characters from the desired note title, press enter and you have a link. - ## Note map -Trilium provides a visualisation of incoming and outgoing links for a particular note. See [note map](../../Advanced%20Usage/Note%20Map%20\(Link%20map%2C%20Tree%20map\).md) for details. \ No newline at end of file +Trilium provides a visualization of incoming and outgoing links for a particular note. See [note map](../../Advanced%20Usage/Note%20Map%20\(Link%20map%2C%20Tree%20map\).md) for details. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Links/1_Internal (reference) links.png b/docs/User Guide/User Guide/Note Types/Text/Links/1_Internal (reference) links.png new file mode 100644 index 0000000000..614c755b29 Binary files /dev/null and b/docs/User Guide/User Guide/Note Types/Text/Links/1_Internal (reference) links.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/Links/Internal (reference) links.md b/docs/User Guide/User Guide/Note Types/Text/Links/Internal (reference) links.md index e45eb2cf1b..fdefca1949 100644 --- a/docs/User Guide/User Guide/Note Types/Text/Links/Internal (reference) links.md +++ b/docs/User Guide/User Guide/Note Types/Text/Links/Internal (reference) links.md @@ -1,20 +1,34 @@ # Internal (reference) links -Unlike external notes, internal links (links to other notes) can be created at the current position by : +Internal links are links to other notes within Trilium. -1. Pressing Ctrl + L or the button from theĀ Formatting toolbar. -2. Filling in the desired note to link. It's also possible to create notes from this dialog by typing a non-existing note title and selecting _Create and link child note_. +You can open an internal link by clicking it. You can also see a read-only preview of an internal link's contents by hovering over it. -There are two link types, adjustable when creating the link to the note: +## Inserting internal links -1. _link title mirrors the note's current title_ +Internal links can be created at the current position in a text note by: + +1. Pressing Ctrl + L or the button underneath the menu in theĀ Formatting toolbar. +2. Searching for the title of the desired note to link. It's also possible to create new notes from this dialog by typing a non-existing note title and selecting _Create and link child note_. + +There are two link types which you can select when creating the link to the note: + +1. _Link title mirrors the note's current title_ 1. This is sometimes also called "reference link". - 2. Title of such links cannot be changed, instead it is always mirroring the title of linked note. - 3. The icon of the note is also displayed. - 4. The link title will automatically update if the title of the note is changed. -2. _link title can be changed arbitrarily_ - 1. This is the traditional hyperlink, where the text of the link can be different to the note title. + 2. The title of this link cannot be changed. Instead, it will always show the current title of the linked note. + 3. The icon of the linked note will also be displayed. +2. _Link title can be changed arbitrarily_ + 1. This will create a traditional hyperlink, where the text of the link can be different from the note title. -Once an internal link is created: +## In-place linking -* You can follow the note link by double clicking it. -* Alternatively if you only wish to quickly preview the content, you can hover over the link and will see read only preview. \ No newline at end of file +You can also insert internal links ā€œinlineā€ by using the `@` symbol: + +1. Type `@` in a text note, which will open the note search menu. +2. Search for the desired note's title by typing a few characters. Use Up and Down to select the correct note, and press Enter or Tab to create the link. It's also possible to create new notes with this method by typing a non-existing note title and selecting _Create and link child note_. + +## Pasting internal links + +You can also insert internal links by copying a note from the note tree. + +1. In theĀ Note Tree, select a note and press Ctrl + C. +2. In a text note, paste the link by pressing Ctrl + V. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Lists.md b/docs/User Guide/User Guide/Note Types/Text/Lists.md index efa0c5a62d..93bcf0910f 100644 --- a/docs/User Guide/User Guide/Note Types/Text/Lists.md +++ b/docs/User Guide/User Guide/Note Types/Text/Lists.md @@ -1,35 +1,40 @@ # Lists There are three types of lists supported by text notes: -* Bulleted lists (also known as unordered lists). -* Numbered lists (or ordered lists). -* To-do lists +* Bulleted lists (also known as unordered lists). +* Numbered lists (or ordered lists). +* To-do lists -For bulleted and numbered lists, it's possible to configure an alternative marker such as squares or Roman numbering by pressing the icon. For numbered lists, it's also possible to specify the number to start at or whether to count in reverse order. +For bulleted and numbered lists, it's possible to configure an alternative marker such as squares or Roman numbering by pressing the icon. For numbered lists, it's also possible to specify the number to start at or whether to count in reverse order. ## Keyboard interaction * To create a new list: * Bulleted list: Start a line with `*` or `-` followed by a space; * Numbered list: Start a line with `1.` or `1)` followed by a space; - * To-do list: Start a line with `[ ]` for an unchecked item or `[x]` for a checked item. + * To-do list: Start a line with `- [ ]` for an unchecked item or `[x]` for a checked item. * To create a new item in the list, press Enter. * To create a blank line within a list item, press Shift+Enter. * To exit out of the list, press Enter twice. * To merge two lists, simply delete the gap between them. -* To create nested lists, simply use the button (see _Indentation_ inĀ Other features) or the Tab key. To decrease the nesting level for the current element, press Shift+Tab. +* To create nested lists, simply use the button (see _Indentation_ inĀ Other features) or the Tab key. To decrease the nesting level for the current element, press Shift+Tab. ## Headings, code blocks within lists It possible to add content-level blocks such as headings, code blocks, tables within lists, as follows: -| | | | +| | | | | --- | --- | --- | -| 1 | ![](6_Lists_image.png) | First, create a list. | -| 2 | ![](4_Lists_image.png) | Press Enter to create a new list item. | -| 3 | ![](5_Lists_image.png) | Press Backspace to get rid of the bullet point. Notice the cursor position. | -| 4 | | At this point, insert any desired block-level item such as a code block. | -| 5 | | To continue with a new bullet point, press Enter until the cursor moves to a new blank position. | -| 6 | | Press Enter once more to create the new bullet. | +| 1 | ![](6_Lists_image.png) | First, create a list. | +| 2 | ![](9_Lists_image.png) | Press Enter to create a new list item. | +| 3 | ![](5_Lists_image.png) | Press Backspace to get rid of the bullet point. Notice the cursor position. | +| 4 | | At this point, insert any desired block-level item such as a code block. | +| 5 | | To continue with a new bullet point, press Enter until the cursor moves to a new blank position. | +| 6 | | Press Enter once more to create the new bullet. | -The same principle applies to all three list types (bullet, numbered and to-do). \ No newline at end of file +The same principle applies to all three list types (bullet, numbered and to-do). + +## To-do lists + +* To insert a to-do list from the keyboard, type `- [ ]` for an unchecked item or `[x]` for a checked item while on an empty paragraph. +* To reorder the item under the cursor, press Alt+Up or Alt+Down. To reorder multiple items, select them first. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Lists_image.png b/docs/User Guide/User Guide/Note Types/Text/Lists_image.png index 30a9511b08..1282f27ec0 100644 Binary files a/docs/User Guide/User Guide/Note Types/Text/Lists_image.png and b/docs/User Guide/User Guide/Note Types/Text/Lists_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/Math Equations.md b/docs/User Guide/User Guide/Note Types/Text/Math Equations.md index 0bcb5af7ad..c8cfa94e5a 100644 --- a/docs/User Guide/User Guide/Note Types/Text/Math Equations.md +++ b/docs/User Guide/User Guide/Note Types/Text/Math Equations.md @@ -3,20 +3,26 @@ Within text notes, it's possible to enter mathematical equations using the button from theĀ Formatting toolbarĀ (generally found under theĀ Insert buttons). -If inserting equations frequently, using the Ctrl+M keyboard shortcut can be more comfortable. Alternatively, type `$$` or `\[` to trigger the popup directly. - -There is currently no quick way to insert an equation, such as surrounding it with `$` or pressing Ctrl+M on an already typed-out equation. - The mathematical expression must be written in the TeX format. There is no visual editor for the math equations, only a preview.Ā  Enabling _Display mode_ will render the equation slightly bigger (especially if using big operators such as summation, or fractions) and center it. Display mode equations will act as blocks (i.e. like paragraphs, or tables) and can be inserted for example in lists. Non-display equations can be part of the text. +## Keyboard shortcuts + +If inserting equations frequently, using the Ctrl+M keyboard shortcut can be more comfortable. Alternatively, type `$$` or `\[` to trigger the popup directly. + +There is currently no quick way to turn an already typed-out equation, such as surrounding it with `$` or pressing Ctrl+M. + ## Supported math features Technically we are using the KaTeX library which allows for a subset of the TeX format. To see the full list of supported features, consult the [Supported Functions](https://katex.org/docs/supported) and the [Support Table](https://katex.org/docs/support_table) from the official documentation. ## Markdown support -Math equations will be preserved when exporting to or importing from Markdown, surrounded by `\(` characters for inline math expressions, and `$\)` for display mode. +Math equations will be preserved when exporting to or importing from Markdown, surrounded by `$` characters for inline math expressions, and `$$` for display mode. -If you notice any issue with the Markdown import/export for equations, feel free to [report](../../Troubleshooting/Reporting%20issues.md) it while providing the equation that causes issues. \ No newline at end of file +If you notice any issue with the Markdown import/export for equations, feel free to [report](../../Troubleshooting/Reporting%20issues.md) it while providing the equation that causes issues. + +## Formatting the equation + +It is possible to customize the font size and foreground color for both inline and display-mode equations, just like any other text. For inline equations, the background color/highlight can also be adjusted. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter.md b/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter.md new file mode 100644 index 0000000000..8bc94c6f7c --- /dev/null +++ b/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter.md @@ -0,0 +1,20 @@ +# Format Painter +
    + +> [!NOTE] +> This is a premium feature of the editor we are using (CKEditor) and we benefit from it thanks to an written agreement with the team. See Ā Premium featuresĀ for more information. + +The Format Painter is a feature in text notes that allows users to copy the formatting of text (such as **bold**, _italic_, ~~Strikethrough~~, etc.) and apply it to other parts of the document. It helps maintain consistent formatting and accelerates the creation of rich content. + +## Usage Instructions + +Click the text that you want to copy the formatting from and use the paint formatting toolbar button (Format painter) to copy the style. Then select the target text with your mouse to apply the formatting. + +* **To copy the formatting**: Place the cursor inside a text with some formatting and click the paint formatting toolbar button. Notice that the mouse cursor changes to the Format painter text cursor. +* **To paint with the copied formatting**: Click any word in the document and the new formatting will be applied. Alternatively, instead of clicking a single word, you can select a text fragment (like an entire paragraph). Notice that the cursor will go back to the default one after the formatting is applied. +* **To keep painting using the same formatting**: Open the toolbar dropdown and enable the continuous painting mode. Once copied, the same formatting can be applied multiple times in different places until the paint formatting button is clicked (the cursor will then revert to the regular one). + +## Limitations + +1. Painting with block-level formatting (like headings or image styles) is not supported yet. This is because, inĀ CKEditor, they are considered a part of the content rather than text formatting. +2. When applying formatting to words, spaces or other Western punctuation are used as word boundaries, which prevents proper handling of languages that do not use space-based word segmentation. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_746436a2e1.svg b/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_746436a2e1.svg new file mode 100644 index 0000000000..77ad84f56b --- /dev/null +++ b/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_746436a2e1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_e144e96df9.svg b/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_e144e96df9.svg new file mode 100644 index 0000000000..06342b7c73 --- /dev/null +++ b/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_e144e96df9.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_image.png b/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_image.png new file mode 100644 index 0000000000..db5cbbbd11 Binary files /dev/null and b/docs/User Guide/User Guide/Note Types/Text/Premium features/Format Painter_image.png differ diff --git a/docs/User Guide/User Guide/Note Types/Text/Tables.md b/docs/User Guide/User Guide/Note Types/Text/Tables.md index 88003853e8..9944f4277f 100644 --- a/docs/User Guide/User Guide/Note Types/Text/Tables.md +++ b/docs/User Guide/User Guide/Note Types/Text/Tables.md @@ -9,13 +9,13 @@ To create a table, simply press the table button and select with the mouse the d When a table is selected, a special formatting toolbar will appear: - + ## Navigating a table * Using the mouse: * Click on a cell to focus it. - * Click the button at the top or the bottom of a table to insert an empty paragraph near it. + * Click the button at the top or the bottom of a table to insert an empty paragraph near it. * Click the button at the top-left of the table to select it entirely (for easy copy-pasting or cutting) or drag and drop it to relocate the table. * Using the keyboard: * Use the arrow keys on the keyboard to easily navigate between cells. @@ -48,7 +48,7 @@ More options are available by pressing the arrow next to it:
    -The table properties can be accessed via the button and allows for the following adjustments: +The table properties can be accessed via the button and allows for the following adjustments: * Border (not the border of the cells, but the outer rim of the table), which includes the style (single, double), color and width. * The background color, with none set by default. @@ -63,7 +63,7 @@ The table will immediately update to reflect the changes, but the _Save_ button
    -Similarly to table properties, the button opens a popup which adjusts the styling of one or more cells (based on the user's selection). +Similarly to table properties, the button opens a popup which adjusts the styling of one or more cells (based on the user's selection). The following options can be adjusted: @@ -79,7 +79,25 @@ The cell will immediately update to reflect the changes, but the _Save_ button m Press the button to insert a caption or a text description of the table, which is going to be displayed above the table. -## Tables with invisible borders +## Table borders + +By default, tables will come with a predefined gray border. + +To adjust the borders, follow these steps: + +1. Select the table. +2. In the floating panel, select the _Table properties_ option (). + 1. Look for the _Border_ section at the top of the newly opened panel. + 2. This will control the outer borders of the table. + 3. Select a style for the border. Generally _Single_ is the desirable option. + 4. Select a color for the border. + 5. Select a width for the border, expressed in pixels. +3. Select all the cells of the table and then press the _Cell properties_ option (). + 1. This will control the inner borders of the table, at cell level. + 2. Note that it's possible to change the borders individually by selecting one or more cells, case in which it will only change the borders that intersect these cells. + 3. Repeat the same steps as from step (2). + +### Tables with invisible borders Tables can be set to have invisible borders in order to allow for basic layouts (columns, grids) of text or [images](Images.md) without the distraction of their border: diff --git a/docs/User Guide/User Guide/Quick Start.md b/docs/User Guide/User Guide/Quick Start.md index 61ec6cd6b8..b94b0372e4 100644 --- a/docs/User Guide/User Guide/Quick Start.md +++ b/docs/User Guide/User Guide/Quick Start.md @@ -3,17 +3,17 @@ **Local only desktop/laptop** - Allows a single instance on a desktop and will save the notes locally on that desktop. -1. [Desktop installation](Installation%20%26%20Setup/Desktop%20Installation.md) +* Desktop Installation **Server with web only access** - Installs the application on the server and allows access from any web browser on any device, including mobile. -1. [Server installation](Installation%20%26%20Setup/Server%20Installation.md) -2. [Mobile frontend](Installation%20%26%20Setup/Mobile%20Frontend.md) (optional) -3. [PikaPods managed hosting](https://www.pikapods.com/pods?run=trilium-next) +1. Server Installation +2. Mobile FrontendĀ (optional) +3. Third-party cloud hosting **Combination of server and desktop/laptop** - Install the application on both a server, for web access and data synchronisation, and desktop instance(s). This allows all the data to be stored on the server and either accessed from the web browser, or the desktop application. The desktop application will sync and store the data locally so that it can be used when offline. -1. [Server installation](Installation%20%26%20Setup/Server%20Installation.md) -2. [Mobile frontend](Installation%20%26%20Setup/Mobile%20Frontend.md) (optional) -3. [Desktop installation](Installation%20%26%20Setup/Desktop%20Installation.md) -4. [Synchronization](Installation%20%26%20Setup/Synchronization.md) \ No newline at end of file +1. Server Installation +2. Mobile FrontendĀ (optional) +3. Desktop Installation +4. Synchronization \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting.md b/docs/User Guide/User Guide/Scripting.md index f5724f8a37..b7fad64dc1 100644 --- a/docs/User Guide/User Guide/Scripting.md +++ b/docs/User Guide/User Guide/Scripting.md @@ -1,18 +1,18 @@ # Scripting Trilium supports creatingĀ CodeĀ notes, i.e. notes which allow you to store some programming code and highlight it. Special case is JavaScript code notes which can also be executed inside Trilium which can in conjunction withĀ Script APIĀ provide extra functionality. -## Scripting +## Architecture Overview To go further I must explain basic architecture of Trilium - in its essence it is a classic web application - it has these two main components: * frontend running in the browser (using HTML, CSS, JavaScript) - this is mainly used to interact with the user, display notes etc. * backend running JavaScript code in node.js runtime - this is responsible for e.g. storing notes, encrypting them etc. -So we have frontend and backend, each with their own set of responsibilities, but their common feature is that they both run JavaScript code. Add to this the fact, that we're able to create JavaScript \[\[code notes\]\] and we're onto something. +So we have frontend and backend, each with their own set of responsibilities, but their common feature is that they both run JavaScript code. Add to this the fact, that we're able to create JavaScript code notes and we're onto something. ## Use cases -* "New Task" launcher button +* "New Task" launcher button ## Action handler @@ -34,7 +34,7 @@ You can see more scripting with explanation inĀ Events. +SeeĀ Events. ## Script API diff --git a/docs/User Guide/User Guide/Scripting/Backend scripts.md b/docs/User Guide/User Guide/Scripting/Backend scripts.md new file mode 100644 index 0000000000..7a6da5e3b7 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Backend scripts.md @@ -0,0 +1,24 @@ +# Backend scripts +Unlike [front-end scripts](Frontend%20Basics.md) which run on the client / browser-side, back-end scripts run directly on the Node.js environment of the Trilium server. + +Back-end scripts can be used both on aĀ Server InstallationĀ (where it will run on the device the server is running on), or on theĀ Desktop InstallationĀ (where it will run on the PC). + +## Advantages of backend scripts + +The benefit of backend scripts is that they can be pretty powerful, for example to have access to the underlying system, for example it can read files or execute processes. + +However, the main benefit of backend scripts is that they have easier access to the notes since the information about them is already loaded in memory. Whereas on the client, notes have to be manually loaded first. + +## Creating a backend script + +Create a newĀ CodeĀ note and select the language _JS backend_. + +## Running backend scripts + +Backend scripts can be either run manually (via the Execute button on the script page), or they can be triggered on certain events. + +In addition, scripts can be run automatically when the server starts up, on a fixed time interval or when a certain event occurs (such as an attribute being modified). For more information, see the dedicatedĀ EventsĀ page. + +## Script API + +Trilium exposes a set of APIs that can be directly consumed by scripts, under the `api` object. For a reference of this API, seeĀ Backend API. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Backend scripts/Events.md b/docs/User Guide/User Guide/Scripting/Backend scripts/Events.md new file mode 100644 index 0000000000..ff6f1973e4 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Backend scripts/Events.md @@ -0,0 +1,43 @@ +# Events +[Script](../../Scripting.md) notes can be triggered by events. Note that these are backend events and thus relation need to point to the "JS backend" code note. + +## Global events + +Global events are attached to the script note via label. Simply create e.g. "run" label with some of these values and script note will be executed once the event occurs. + +
    LabelDescription
    run

    Defines on which events script should run. Possible values are:

    • backendStartup - when Trilium backend starts up
    • hourly - run once an hour. You can use additional label runAtHour to specify at which hour, on the back-end.
    • daily - run once a day, on the back-end
    runOnInstanceSpecifies that the script should only run on a particular Trilium instance.
    runAtHourOn which hour should this run. Should be used together with #run=hourly. Can be defined multiple times for more runs during the day.
    + +## Entity events + +Other events are bound to some entity, these are defined as [relations](../../Advanced%20Usage/Attributes.md) - meaning that script is triggered only if note has this script attached to it through relations (or it can inherit it). + +| Relation | Trigger condition | Origin entity (see below) | +| --- | --- | --- | +| `runOnNoteCreation` | executes when note is created on backend. Use this relation if you want to run the script for all notes created under a specific subtree. In that case, create it on the subtree root note and make it inheritable. A new note created within the subtree (any depth) will trigger the script. | The `BNote` that got created. | +| `runOnChildNoteCreation` | executes when new note is created under the note where this relation is defined | The `BNote` of the child that got created. | +| `runOnNoteTitleChange` | executes when note title is changed (includes note creation as well) | The `BNote` of the note whose title got changed. | +| `runOnNoteContentChange` | executes when note content is changed (includes note creation as well). | The `BNote` of the note whose content got changed. | +| `runOnNoteChange` | executes when note is changed (includes note creation as well). Does not include content changes | The `BNote` of the note that got changed. | +| `runOnNoteDeletion` | executes when note is being deleted | The `BNote` of the note that got (soft) deleted. | +| `runOnBranchCreation` | executes when a branch is created. Branch is a link between parent note and child note and is created e.g. when cloning or moving note. | The `BBranch` that got created. | +| `runOnBranchChange` | executes when a branch is updated. (since v0.62) | The `BBranch` that got changed. | +| `runOnBranchDeletion` | executes when a branch is deleted. Branch is a link between parent note and child note and is deleted e.g. when moving note (old branch/link is deleted). | The `BBranch` that got (soft) deleted. | +| `runOnAttributeCreation` | executes when new attribute is created for the note which defines this relation | The `BAttribute` that got created. | +| `runOnAttributeChange` | executes when the attribute is changed of a note which defines this relation. This is triggered also when the attribute is deleted | The `BAttribute` that got changed. | + +## Origin entity + +When a script is run by an event such as the ones described above, `api.originEntity` will get populated with the note, branch or attribute that triggered the change. + +For example, here's a script with `~runOnAttributeChange` which automatically changes the color of a note based on the value of the `mycategory` label: + +```javascript +const attr = api.originEntity; +if (attr.name !== "mycategory") return; +const note = api.getNote(attr.noteId); +if (attr.value === "Health") { + note.setLabel("color", "green"); +} else { + note.removeLabel("color"); +} +``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Backend scripts/Server-side imports.md b/docs/User Guide/User Guide/Scripting/Backend scripts/Server-side imports.md new file mode 100644 index 0000000000..ddc795aa08 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Backend scripts/Server-side imports.md @@ -0,0 +1,11 @@ +# Server-side imports +Older versions of Trilium Notes allowed the use of Common.js module imports inside backend scripts, such as: + +``` +const isBetween = require('dayjs/plugin/isBetween') +api.dayjs.extend(isBetween) +``` + +For newer versions, Node.js imports are **not officially supported anymore**, since we've added a bundler which makes it more difficult to reuse dependencies. + +Theoretically it's still possible to use imports by manually setting up a `node_modules` in the server directory via `npm` or `pnpm`. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Breaking changes.md b/docs/User Guide/User Guide/Scripting/Breaking changes.md new file mode 100644 index 0000000000..8b887aab99 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Breaking changes.md @@ -0,0 +1,14 @@ +# Breaking changes +## v0.102.0: Upgrade to jQuery 4.0.0 + +jQuery 4 removes legacy browser support (such as IE11 support), but it also removes some APIs that are considered deprecated such as: + +> `jQuery.isArray`, `jQuery.parseJSON`, `jQuery.trim`, `jQuery.type`, `jQuery.now`, `jQuery.isNumeric`, `jQuery.isFunction`, `jQuery.isWindow`, `jQuery.camelCase`, `jQuery.nodeName`, `jQuery.cssNumber`, `jQuery.cssProps`, and `jQuery.fx.interval`. +> +> Use native equivalents like `Array.isArray()`, `JSON.parse()`, `String.prototype.trim()`, and `Date.now()` instead. + +This may affect custom scripts if they (or the custom jQuery libraries used) depend on the deprecated APIs. + +Note that Trilium polyfills `jQuery.isArray`, `isFunction` and `isPlainObject` because they were required by one of our dependencies (the autocomplete). + +For more information, consult [the official blog post](https://blog.jquery.com/2026/01/17/jquery-4-0-0/). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Common concepts/Script bundles.md b/docs/User Guide/User Guide/Scripting/Common concepts/Script bundles.md new file mode 100644 index 0000000000..241dff0b4d --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Common concepts/Script bundles.md @@ -0,0 +1,48 @@ +# Script bundles +For bothĀ Render NoteĀ and more complicated scripts, it's generally useful to split the code into multipleĀ CodeĀ notes. + +When a script is run, the sub-children of the script being run (or theĀ Render Note) are checked for children. If the children are Code notes of the corresponding type (front-end or backend) as the code being run, they will be evaluated as well. + +The collection of a script and its child notes is called a _bundle_. A child note inside a bundle is called a _module_. + +As a basic example of dependencies, consider the following note structure: + +* _Script with dependency_ + + ```javascript + api.log(MyMath.sum(2, 2)); + ``` + + * _MyMath_ + + ```javascript + module.exports = { + sum(a, b) { + return a + b; + } + }; + ``` + +When _Script with dependency_ is run, it will detect _MyMath_ as a submodule and provide the result of its `module.exports` object into a global object with the same name as the note. + +> [!NOTE] +> If the note contains spaces or special characters, they will be stripped. For example `My Nice Note!` becomes `MyNiceNote`. + +## Alternative syntax + +Instead of providing an object to `module.exports`, it's also possible to add fields individually: + +```javascript +module.exports.sum = (a, b) => a + b; +module.exports.subtract = (a, b) => a - b; +``` + +## Ignoring a code script from a bundle + +To ignore a script from being included in a bundle (e.g. if it's unrelated to the parent script note), apply the `#disableInclusion` label. + +## Sharing a module across multiple bundles + +Modules can be reused across multiple scripts by simply cloning the shared module between two modules (seeĀ Cloning Notes). + +Optionally, a separate note can be used to contain all the different reusable modules for an easy way to discover them. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Custom Widgets.md b/docs/User Guide/User Guide/Scripting/Custom Widgets.md deleted file mode 100644 index 152d2ec700..0000000000 --- a/docs/User Guide/User Guide/Scripting/Custom Widgets.md +++ /dev/null @@ -1,9 +0,0 @@ -# Custom Widgets -It's possible to create custom widget in three possible locations where you can display your custom content. - -Positions are: - -* `left-pane` -* `center-pane` -* `note-detail-pane` - located within `center-pane`, but specific to note (split) -* `right-pane` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Events.md b/docs/User Guide/User Guide/Scripting/Events.md deleted file mode 100644 index 6dbeeeba67..0000000000 --- a/docs/User Guide/User Guide/Scripting/Events.md +++ /dev/null @@ -1,26 +0,0 @@ -# Events -[Script](../Scripting.md) notes can be triggered by events. Note that these are backend events and thus relation need to point to the "JS backend" code note. - -## Global events - -Global events are attached to the script note via label. Simply create e.g. "run" label with some of these values and script note will be executed once the event occurs. - -
    LabelDescription
    run

    Defines on which events script should run. Possible values are:

    • frontendStartup - when Trilium frontend starts up (or is refreshed), but not on mobile.
    • mobileStartup - when Trilium frontend starts up (or is refreshed), on mobile.
    • backendStartup - when Trilium backend starts up
    • hourly - run once an hour. You can use additional label runAtHour to specify at which hour, on the back-end.
    • daily - run once a day, on the back-end
    runOnInstanceSpecifies that the script should only run on a particular Trilium instance.
    runAtHourOn which hour should this run. Should be used together with #run=hourly. Can be defined multiple times for more runs during the day.
    - -## Entity events - -Other events are bound to some entity, these are defined as [relations](../Advanced%20Usage/Attributes.md) - meaning that script is triggered only if note has this script attached to it through relations (or it can inherit it). - -| Relation | Description | -| --- | --- | -| `runOnNoteCreation` | executes when note is created on backend. Use this relation if you want to run the script for all notes created under a specific subtree. In that case, create it on the subtree root note and make it inheritable. A new note created within the subtree (any depth) will trigger the script. | -| `runOnChildNoteCreation` | executes when new note is created under the note where this relation is defined | -| `runOnNoteTitleChange` | executes when note title is changed (includes note creation as well) | -| `runOnNoteContentChange` | executes when note content is changed (includes note creation as well). | -| `runOnNoteChange` | executes when note is changed (includes note creation as well). Does not include content changes | -| `runOnNoteDeletion` | executes when note is being deleted | -| `runOnBranchCreation` | executes when a branch is created. Branch is a link between parent note and child note and is created e.g. when cloning or moving note. | -| `runOnBranchChange` | executes when a branch is updated. (since v0.62) | -| `runOnBranchDeletion` | executes when a branch is deleted. Branch is a link between parent note and child note and is deleted e.g. when moving note (old branch/link is deleted). | -| `runOnAttributeCreation` | executes when new attribute is created for the note which defines this relation | -| `runOnAttributeChange` | executes when the attribute is changed of a note which defines this relation. This is triggered also when the attribute is deleted | \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Examples/New Task launcher button.md b/docs/User Guide/User Guide/Scripting/Examples/New Task launcher button.md deleted file mode 100644 index 85e834b8b3..0000000000 --- a/docs/User Guide/User Guide/Scripting/Examples/New Task launcher button.md +++ /dev/null @@ -1,47 +0,0 @@ -# "New Task" launcher button -In this example we are going to extend the functionality ofĀ Task ManagerĀ showcase (which comes by default with Trilium) by adding a button in theĀ Launch BarĀ  (![](New%20Task%20launcher%20button_i.png)) to create a new task automatically and open it. - -## Creating the note - -1. First, create a newĀ CodeĀ note type with the _JS frontend_ language. -2. Define the `#run=frontendStartup` label inĀ Attributes. - -## Content of the script - -Copy-paste the following script: - -```javascript -api.addButtonToToolbar({ - title: "New task", - icon: "task", - shortcut: "alt+n", - action: async () => { - const taskNoteId = await api.runOnBackend(() => { - const todoRootNote = api.getNoteWithLabel("taskTodoRoot"); - const resp = api.createTextNote(todoRootNote.noteId, "New task", "") - return resp.note.noteId; - }); - - await api.waitUntilSynced(); - await api.activateNewNote(taskNoteId); - } -}); -``` - -## Testing the functionality - -Since we set the script to be run on start-up, all we need to do is to [refresh the application](../../Troubleshooting/Refreshing%20the%20application.md). - -## Understanding how the script works - -
    api.addButtonToToolbar({
    -	title: "New task",
    -    icon: "task",
    -    shortcut: "alt+n",
    -    action: async () => {
    -    	// [...]
    -    }
    -});

    This uses the Front-end API to create a icon in the Launch Bar, by specifying:

    • A title
    • A corresponding boxicons icon (without the bx- prefix).
    • Optionally, a keyboard shortcut to assign to it.
    • The action, which will be executed when the button is pressed.
    const taskNoteId = await api.runOnBackend(() => {
    -    // Shown below.           
    -    return resp.note.noteId;
    -});
    • This portion of code is actually executed on the server (backend) and not on the client (i.e. browser).
      • The reason is that the creating notes is the responsibility of the server.
    • Here we can also see that it is possible to return results from the server execution and read them in the client (taskNoteId).
    const todoRootNote = api.getNoteWithLabel("taskTodoRoot");
    • Here we identify a note with the label #taskTodoRoot. This is how the Task Manager showcase knows where to place all the different tasks.
    • Normally this might return a null value if no such note could be identified, but error handling is outside the scope of this example. 
    const resp = api.createTextNote(todoRootNote.noteId, "New task", "")
    • We create a new child note within the to-do root note (first argument) with the title ā€œNew task" (second argument) and no content by default (third argument).
    await api.waitUntilSynced();
    • Back on the client, since we created a new note on the server, we now need to wait for the change to be reflected in the client.
    await api.activateNewNote(taskNoteId);
    • Since we know the ID of the newly created note, all we have to do now is to show this note to the user.
    \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics.md b/docs/User Guide/User Guide/Scripting/Frontend Basics.md index 2557deed7f..30e9da2dad 100644 --- a/docs/User Guide/User Guide/Scripting/Frontend Basics.md +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics.md @@ -1,57 +1,40 @@ # Frontend Basics -## Frontend API +Front-end scripts are custom JavaScript notes that are run on the client (browser environment) -The frontend api supports two styles, regular scripts that are run with the current app and note context, and widgets that export an object to Trilium to be used in the UI. In both cases, the frontend api of Trilium is available to scripts running in the frontend context as global variable `api`. The members and methods of the api can be seen on the [Script API](Script%20API.md) page. +There are four flavors of front-end scripts: + +| | | +| --- | --- | +| Regular scripts | These are run with the current app and note context. These can be run either manually or automatically on start-up. | +| Custom Widgets | These can introduce new UI elements in various positions, such as near theĀ Note Tree, content area or even theĀ Right Sidebar. | +| Launch Bar Widgets | Similar toĀ Custom Widgets, but dedicated to theĀ Launch Bar. These can simply introduce new buttons or graphical elements to the bar. | +| Render Note | This allows rendering custom content inside a note, using either HTML or Preact JSX. | + +For more advanced behaviors that do not require a user interface (e.g. batch modifying notes), seeĀ Backend scripts. ## Scripts -Scripts don't have any special requirements. They can be run at will using the execute button in the UI or they can be configured to run at certain times using [Attributes](../Advanced%20Usage/Attributes.md) on the note containing the script. +Scripts don't have any special requirements. They can be run manually using the _Execute_ button on the code note or they can be run automatically; to do so, set the `run` [label](../Advanced%20Usage/Attributes/Labels.md) to either: -### Global Events +* `frontendStartup` - when Trilium frontend starts up (or is refreshed), but not on mobile. +* `mobileStartup` - when Trilium frontend starts up (or is refreshed), on mobile. -This attribute is called `#run` and it can have any of the following values: - -* `frontendStartup` - executes on frontend upon startup. -* `mobileStartup` - executes on mobile frontend upon startup. -* `backendStartup` - executes on backend upon startup. -* `hourly` - executes once an hour on backend. -* `daily` - executes once a day on backend. - -### Entity Events - -These events are triggered by certain [relations](../Advanced%20Usage/Attributes.md) to other notes. Meaning that the script is triggered only if the note has this script attached to it through relations (or it can inherit it). - -* `runOnNoteCreation` - executes when note is created on backend. -* `runOnNoteTitleChange` - executes when note title is changed (includes note creation as well). -* `runOnNoteContentChange` - executes when note content is changed (includes note creation as well). -* `runOnNoteChange` - executes when note is changed (includes note creation as well). -* `runOnNoteDeletion` - executes when note is being deleted. -* `runOnBranchCreation` - executes when a branch is created. Branch is a link between parent note and child note and is created e.g. when cloning or moving note. -* `runOnBranchDeletion` - executes when a branch is delete. Branch is a link between parent note and child note and is deleted e.g. when moving note (old branch/link is deleted). -* `runOnChildNoteCreation` - executes when new note is created under this note. -* `runOnAttributeCreation` - executes when new attribute is created under this note. -* `runOnAttributeChange` - executes when attribute is changed under this note. +> [!NOTE] +> Backend scripts have more powerful triggering conditions, for example they can run automatically on a hourly or daily basis, but also on events such as when a note is created or an attribute is modified. See the server-sideĀ EventsĀ for more information. ## Widgets -Conversely to scripts, widgets do have some specific requirements in order to work. A widget must: +Widgets require a certain format in order for Trilium to be able to integrate them into the UI. -* Extend [BasicWidget](https://triliumnext.github.io/Notes/frontend_api/BasicWidget.html) or one of it's subclasses. -* Create a new instance and assign it to `module.exports`. -* Define a `parentWidget` member to determine where it should be displayed. -* Define a `position` (integer) that determines the location via sort order. -* Have a `#widget` attribute on the containing note. -* Create, render, and return your element in the render function. - * For [BasicWidget](https://triliumnext.github.io/Notes/frontend_api/BasicWidget.html) and [NoteContextAwareWidget](https://triliumnext.github.io/Notes/frontend_api/NoteContextAwareWidget.html)you should create `this.$widget` and render it in `doRender()`. - * For [RightPanelWidget](https://triliumnext.github.io/Notes/frontend_api/RightPanelWidget.html) the `this.$widget` and `doRender()` are already handled and you should instead return the value in `doRenderBody()`. +* For legacy widgets, the script note must export a `BasicWidget` or a derived one (seeĀ Note context aware widgetĀ orĀ Right pane widget). +* For Preact widgets, a built-in helper called `defineWidget` needs to be used. -### parentWidget +For more information, seeĀ Custom Widgets. -* `left-pane` - This renders the widget on the left side of the screen where the note tree lives. -* `center-pane` - This renders the widget in the center of the layout in the same location that notes and splits appear. -* `note-detail-pane` - This renders the widget _with_ the note in the center pane. This means it can appear multiple times with splits. -* `right-pane` - This renders the widget to the right of any opened notes. +## Script API + +The front-end API of Trilium is available to all scripts running in the front-end context as global variable `api`. For a reference of the API, seeĀ Frontend API. ### Tutorial -For more information on building widgets, take a look at [Widget Basics](Custom%20Widgets/Widget%20Basics.md). \ No newline at end of file +For more information on building widgets, take a look at [Widget Basics](Frontend%20Basics/Custom%20Widgets/Widget%20Basics.md). \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets.md new file mode 100644 index 0000000000..9963e37c1b --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets.md @@ -0,0 +1,94 @@ +# Custom Widgets +Custom widgets are a special subset of scripts that render graphical elements in certain parts of the application. These can be used to add new functionality to the Trilium application. + +## Preact with JSX vs. vanilla jQuery + +In older versions of Trilium, custom widgets were exclusively written in a combination of jQuery with Trilium's internal widget architecture (e.g., `BasicWidget`, `NoteContextAwareWidget`). + +Starting with v0.101.0, custom widgets can also be written in JSX using theĀ PreactĀ framework. Both legacy and Preact widgets have the same capabilities, with a single difference: + +* Preact widgets are content-sized by default whereas legacy widgets need `this.contentSized()` applied in the constructor. For more information, see the corresponding section inĀ Troubleshooting. + +Wherever possible, widget examples will be both in the legacy and Preact format. + +## Creating a custom widget + +1. Create aĀ CodeĀ note. +2. Set the language to: + 1. JavaScript (frontend) for legacy widgets using jQuery. + 2. JSX for Preact widgets. You might need to go to Options → Code to enable the language first. +3. Apply the `#widget` [label](../../Advanced%20Usage/Attributes/Labels.md). + +## Getting started with a simple example + +Let's start by creating a widget that shows a message near the content area. Follow the previous section to create a code note, and use the following content. + +### Legacy version (jQuery) + +``` +class HelloCenterPane extends api.BasicWidget { + + constructor() { + super(); + this.contentSized(); + } + + get parentWidget() { return "center-pane" } + + doRender() { + this.$widget = $("Center pane"); + } + +} + +module.exports = new HelloCenterPane(); +``` + +[Refresh the application](../../Troubleshooting/Refreshing%20the%20application.md) and the widget should appear underneath the content area. + +### Preact version + +``` +import { defineWidget } from "trilium:preact"; + +export default defineWidget({ + parent: "center-pane", + render: () => Center pane from Preact. +}); +``` + +[Refresh the application](../../Troubleshooting/Refreshing%20the%20application.md) and the widget should appear underneath the content area. + +## Widget location (parent widget) + +A widget can be placed in one of the following sections of the applications: + +
    Value for parentWidgetDescriptionSample widgetSpecial requirements
    left-paneAppears within the same pane that holds the Note Tree.Same as above, with only a different parentWidget.None.
    center-paneIn the content area. If a split is open, the widget will span all of the splits.See example above.None.
    note-detail-pane

    In the content area, inside the note detail area. If a split is open, the widget will be contained inside the split.

    This is ideal if the widget is note-specific.

    Note context aware widget
    • The widget must export a class and not an instance of the class (e.g. no new) because it needs to be multiplied for each note, so that splits work correctly.
    • Since the class is exported instead of an instance, the parentWidget getter must be static, otherwise the widget is ignored.
    right-paneIn the Right Sidebar, as a dedicated section.Right pane widget
    • Although not mandatory, it's best to use a RightPanelWidget instead of a BasicWidget or a NoteContextAwareWidget.
    + +To position the widget somewhere else, just change the value passed to `get parentWidget()` for legacy widgets or the `parent` field for Preact. Do note that some positions such as `note-detail-pane` and `right-pane` have special requirements that need to be accounted for (see the table above). + +## Launch bar widgets + +Launch bar widgets are similar to _Custom widgets_ but are specific to theĀ Launch Bar. SeeĀ Launch Bar WidgetsĀ for more information. + +## Custom position + +The position of a custom widget is defined via a `position` integer. + +In legacy widgets: + +``` +class MyWidget extends api.BasicWidget { + // [.. + get position() { return 10; } +} +``` + +In Preact widgets: + +``` +export default defineWidget({ + // [...] + position: 10 +}); +``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/CSS.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/CSS.md new file mode 100644 index 0000000000..8d01dc238c --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/CSS.md @@ -0,0 +1,21 @@ +# CSS +## Classic widgets + +In `doRender()`:[1] + +``` +this.cssBlock(`#my-widget { + position: absolute; + bottom: 40px; + left: 60px; + z-index: 1; +}`); +``` + +## Preact widgets + +See the dedicated page:Ā CSS. + +1. ^ + + Reference: [https://trilium.rocks/X7pxYpiu0lgU](https://trilium.rocks/X7pxYpiu0lgU) \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Note context aware widget.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Note context aware widget.md new file mode 100644 index 0000000000..2ce223d9e5 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Note context aware widget.md @@ -0,0 +1,53 @@ +# Note context aware widget +Note context-aware widgets are a different type of widget which automatically react to changes in the current note. + +Important aspects: + +* The widget must export a `class` and not an instance of the class (e.g. `no new`) because it needs to be multiplied for each note, so that splits work correctly. +* Since the `class` is exported instead of an instance, the `parentWidget` getter must be `static`, otherwise the widget is ignored. + +## Example displaying the current note title + +This is a note context-aware widget that simply displays the name the current note.Ā  + +### Classic example + +``` +class HelloNoteDetail extends api.NoteContextAwareWidget { + + constructor() { + super(); + this.contentSized(); + } + + doRender() { + this.$widget = $("
    "); + } + + async refreshWithNote(note) { + this.$widget.text("Current note: " + note.title); + } + + static get parentWidget() { return "note-detail-pane" } + get position() { return 10 } + +} + +module.exports = HelloNoteDetail; +``` + +### Preact (v0.101.0+) + +``` +import { defineWidget, useNoteContext, useNoteProperty } from "trilium:preact"; + +export default defineWidget({ + parent: "note-detail-pane", + position: 10, + render: () => { + const { note } = useNoteContext(); + const title = useNoteProperty(note, "title"); + return Current note JSX: {title}; + } +}); +``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.md new file mode 100644 index 0000000000..2dbba6d218 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget.md @@ -0,0 +1,143 @@ +# Right pane widget +## Key highlights + +* `doRender` must not be overridden, instead `doRenderBody()` has to be overridden. + * `doRenderBody` can optionally be `async`. +* `parentWidget()` must be set to `ā€œrightPaneā€`. +* `widgetTitle()` getter can optionally be overriden, otherwise the widget will be displayed as ā€œUntitled widgetā€. + +## Example for new layout + +> [!IMPORTANT] +> This section addresses example that are tailored for theĀ New LayoutĀ (available starting with v0.101.0) where the right pane widget/sidebar is no longer shown or hidden based on the widgets it has.Ā  + +### Title widget + +This is an example of a context-aware widget which displays the title of the current note: + +``` +class NoteTitleWidget extends api.RightPanelWidget { + + get widgetTitle() { return "Note title"; } + get parentWidget() { return "right-pane" } + + doRenderBody() { + this.$body.empty(); + if (this.note) { + this.$body.append($("
    ").text(this.note.title)); + } + } + + async refreshWithNote() { + this.doRenderBody(); + } +} + +module.exports = new NoteTitleWidget(); +``` + +### Clock + +A simple widget which will show the current time, as an example on how to dynamically change the content of the widget periodically. + +### Legacy widget + +``` +const template = `
    `; + +class ToDoListWidget extends api.RightPanelWidget { + + get widgetTitle() { return "Clock"; } + get parentWidget() { return "right-pane" } + + async doRenderBody() { + if (!this.timer) { + this.timer = setInterval(() => { + this.$body.empty().append(`The time is: ${new Date().toLocaleString()}`); + }, 1000); + } + + this.$body.empty().append(`The time is: ${new Date().toLocaleString()}`); + } +} + +module.exports = new ToDoListWidget(); +``` + +### Preact widget + +``` +import { defineWidget, RightPanelWidget, useEffect, useState } from "trilium:preact"; + +export default defineWidget({ + parent: "right-pane", + position: 1, + render() { + const [ time, setTime ] = useState(); + useEffect(() => { + const interval = setInterval(() => { + setTime(new Date().toLocaleString()); + }, 1000); + return () => clearInterval(interval); + }); + return ( + +

    The time is: {time}

    +
    + ); + } +}); +``` + +## Example for old layout + +Here's a widget that displays a basic message ("Hi"): + +``` +const template = `
    Hi
    `; + +class HelloWorldWidget extends api.RightPanelWidget { + + get widgetTitle() { + return "Title goes here"; + } + + get parentWidget() { return "right-pane" } + + doRenderBody() { + this.$body.empty().append($(template)); + } + + async refreshWithNote(note) { + // Do something when the note changes. + } +} + +module.exports = new HelloWorldWidget(); +``` + +### Conditionally changing visibility + +In `refreshWithNote`: + +``` +const visible = true; // replace with your own visibility logic +this.toggleInt(visible); +this.triggerCommand("reEvaluateRightPaneVisibility"); +``` + +## Altering the position within the sidebar + +By default, the sidebar items are displayed in the order they are found by the application when searching for `#widget` notes. + +It is possible to make a widget appear higher or lower up, by adjusting its `position` property: + +``` +class MyWidget extends api.RightPanelWidget { + ++ get position() { return 20 }; + +} +``` + +Generally the default position starts from 10 and increases by 10 with each item, including the default Table of Contents and Highlights list. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Troubleshooting.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Troubleshooting.md new file mode 100644 index 0000000000..d613a8459e --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Troubleshooting.md @@ -0,0 +1,19 @@ +# Troubleshooting +## Why is my widget clipped by other UI elements + +For performance and layout reasons, the size of widgets in Trilium is independent from its children. At CSS level, this means that the widget container has `contain: size` applied to it. + +This works well if the widget has a fixed size (or based on its parent container), however to make a widget resize to fit its content, apply the following change: + +```diff +class MyWidget extends api.RightPanelWidget { + ++ constructor() { ++ super(); ++ this.contentSized(); ++ } + +} +``` + +Alternatively apply `contain: none` to its CSS. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Custom Widgets/Widget Basics.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Widget Basics.md similarity index 71% rename from docs/User Guide/User Guide/Scripting/Custom Widgets/Widget Basics.md rename to docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Widget Basics.md index b6e2a95ca1..2cac717a0a 100644 --- a/docs/User Guide/User Guide/Scripting/Custom Widgets/Widget Basics.md +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Widget Basics.md @@ -11,7 +11,7 @@ class MyWidget extends api.BasicWidget { get parentWidget() { return "left-pane"; } doRender() { - this.$widget = $(""); + this.$widget = $("
    "); return this.$widget; } } @@ -22,17 +22,17 @@ module.exports = new MyWidget(); To implement this widget: 1. Create a new `JS Frontend` note in Trilium and paste in the code above. -2. Assign the `#widget` [attribute](../../Advanced%20Usage/Attributes.md) to the [note](../../Basic%20Concepts%20and%20Features/Notes.md). +2. Assign the `#widget` [attribute](../../../Advanced%20Usage/Attributes.md) to the [note](../../../Basic%20Concepts%20and%20Features/Notes.md). 3. Restart Trilium or reload the window. -To verify that the widget is working, open the developer tools (`Cmd` + `Shift` + `I`) and run `document.querySelector("#my-widget")`. If the element is found, the widget is functioning correctly. If `undefined` is returned, double-check that the [note](../../Basic%20Concepts%20and%20Features/Notes.md) has the `#widget` [attribute](../../Advanced%20Usage/Attributes.md). +To verify that the widget is working, open the developer tools (Ctrl + Shift + I) and run `document.querySelector("#my-widget")`. If the element is found, the widget is functioning correctly. If `undefined` is returned, double-check that the [note](../../../Basic%20Concepts%20and%20Features/Notes.md) has the `#widget` [attribute](../../../Advanced%20Usage/Attributes.md). ### Step 2: Adding an UI Element Next, let's improve the widget by adding a button to it. ``` -const template = ``; +const template = `
    `; class MyWidget extends api.BasicWidget { get position() {return 1;} @@ -56,7 +56,7 @@ To make the button more visually appealing and position it correctly, we'll appl Here's the updated template: ``` -const template = ``; +const template = `
    `; ``` Next, we'll adjust the button's position using CSS: @@ -85,7 +85,7 @@ After reloading Trilium, the button should now appear at the bottom left of the ### Step 4: Adding User Interaction -Let’s make the button interactive by showing a message when it’s clicked. We'll use the `api.showMessage` method from the [Script API](../Script%20API.md). +Let’s make the button interactive by showing a message when it’s clicked. We'll use the `api.showMessage` method from the [Script API](../../Script%20API.md). ``` class MyWidget extends api.BasicWidget { @@ -108,4 +108,6 @@ class MyWidget extends api.BasicWidget { module.exports = new MyWidget(); ``` -Reload the application one last time. When you click the button, a "Hello World!" message should appear, confirming that your widget is fully functional. \ No newline at end of file +For the list of possible values for `parentWidget()`, seeĀ Custom Widgets.Ā  + +[Reload](../../../Troubleshooting/Refreshing%20the%20application.md) the application one last time. When you click the button, a "Hello World!" message should appear, confirming that your widget is fully functional. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Custom Widgets/Word count widget.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget.md similarity index 88% rename from docs/User Guide/User Guide/Scripting/Custom Widgets/Word count widget.md rename to docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget.md index ad8c1c351e..8b6be5684f 100644 --- a/docs/User Guide/User Guide/Scripting/Custom Widgets/Word count widget.md +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget.md @@ -1,8 +1,8 @@ # Word count widget > [!TIP] -> This widget is also present in new installations in theĀ Demo Notes. +> This widget is also present in new installations in theĀ Demo Notes. -Create aĀ CodeĀ note of type JS frontend and **give it a** `#widget` **label**. +Create aĀ CodeĀ note of type JS frontend and **give it a** `#widget` **label**. ``` /* @@ -82,7 +82,7 @@ class WordCountWidget extends api.NoteContextAwareWidget { module.exports = new WordCountWidget(); ``` -After you make changes it is necessary to [restart Trilium](../../Troubleshooting/Refreshing%20the%20application.md) so that the layout can be rebuilt. +After you make changes it is necessary to [restart Trilium](../../../Troubleshooting/Refreshing%20the%20application.md) so that the layout can be rebuilt. At the bottom of the note you can see the resulting widget: diff --git a/docs/User Guide/User Guide/Scripting/Custom Widgets/Word count widget_image.png b/docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget_image.png similarity index 100% rename from docs/User Guide/User Guide/Scripting/Custom Widgets/Word count widget_image.png rename to docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget_image.png diff --git a/docs/User Guide/User Guide/Scripting/Examples/Downloading responses from Goo.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/Downloading responses from Goo.md similarity index 100% rename from docs/User Guide/User Guide/Scripting/Examples/Downloading responses from Goo.md rename to docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/Downloading responses from Goo.md diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button.md new file mode 100644 index 0000000000..6740c047f7 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button.md @@ -0,0 +1,47 @@ +# "New Task" launcher button +In this example we are going to extend the functionality ofĀ Task ManagerĀ showcase (which comes by default with Trilium) by adding a button in theĀ Launch BarĀ  (![](New%20Task%20launcher%20button_i.png)) to create a new task automatically and open it. + +## Creating the note + +1. First, create a newĀ CodeĀ note type with the _JS frontend_ language. +2. Define the `#run=frontendStartup` label inĀ Attributes. + +## Content of the script + +Copy-paste the following script: + +```javascript +api.addButtonToToolbar({ + title: "New task", + icon: "task", + shortcut: "alt+n", + action: async () => { + const taskNoteId = await api.runOnBackend(() => { + const todoRootNote = api.getNoteWithLabel("taskTodoRoot"); + const resp = api.createTextNote(todoRootNote.noteId, "New task", "") + return resp.note.noteId; + }); + + await api.waitUntilSynced(); + await api.activateNewNote(taskNoteId); + } +}); +``` + +## Testing the functionality + +Since we set the script to be run on start-up, all we need to do is to [refresh the application](../../../Troubleshooting/Refreshing%20the%20application.md). + +## Understanding how the script works + +
    api.addButtonToToolbar({
    +	title: "New task",
    +    icon: "task",
    +    shortcut: "alt+n",
    +    action: async () => {
    +    	// [...]
    +    }
    +});

    This uses the Front-end API to create a icon in the Launch Bar, by specifying:

    • A title
    • A corresponding boxicons icon (without the bx- prefix).
    • Optionally, a keyboard shortcut to assign to it.
    • The action, which will be executed when the button is pressed.
    const taskNoteId = await api.runOnBackend(() => {
    +    // Shown below.           
    +    return resp.note.noteId;
    +});
    • This portion of code is actually executed on the server (backend) and not on the client (i.e. browser).
      • The reason is that the creating notes is the responsibility of the server.
    • Here we can also see that it is possible to return results from the server execution and read them in the client (taskNoteId).
    const todoRootNote = api.getNoteWithLabel("taskTodoRoot");
    • Here we identify a note with the label #taskTodoRoot. This is how the Task Manager showcase knows where to place all the different tasks.
    • Normally this might return a null value if no such note could be identified, but error handling is outside the scope of this example. 
    const resp = api.createTextNote(todoRootNote.noteId, "New task", "")
    • We create a new child note within the to-do root note (first argument) with the title ā€œNew task" (second argument) and no content by default (third argument).
    await api.waitUntilSynced();
    • Back on the client, since we created a new note on the server, we now need to wait for the change to be reflected in the client.
    await api.activateNewNote(taskNoteId);
    • Since we know the ID of the newly created note, all we have to do now is to show this note to the user.
    \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Examples/New Task launcher button_i.png b/docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button_i.png similarity index 100% rename from docs/User Guide/User Guide/Scripting/Examples/New Task launcher button_i.png rename to docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button_i.png diff --git a/docs/User Guide/User Guide/Scripting/Examples/Using promoted attributes .png b/docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes .png similarity index 100% rename from docs/User Guide/User Guide/Scripting/Examples/Using promoted attributes .png rename to docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes .png diff --git a/docs/User Guide/User Guide/Scripting/Examples/Using promoted attributes to c.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes to c.md similarity index 100% rename from docs/User Guide/User Guide/Scripting/Examples/Using promoted attributes to c.md rename to docs/User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes to c.md diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets.md new file mode 100644 index 0000000000..e5d25b0198 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets.md @@ -0,0 +1,16 @@ +# Launch Bar Widgets +Launch bar widgets are a subset ofĀ Custom WidgetsĀ that can be used to render custom buttons and widgets inside theĀ Launch Bar. + +## Creating a launch bar widget + +UnlikeĀ Custom Widgets, the process of setting up a launch bar widget is slightly different: + +1. Create a Code note of type _JavaScript (front-end)_ or JSX (for Preact-based widgets). + * The script itself uses the same concepts asĀ Custom Widgets, including the use of a `NoteContextAwareWidget` or a `BasicWidget` (according to needs). + * As examples in both legacy and Preact format, seeĀ Note Title WidgetĀ andĀ Analog Watch. +2. Don't set `#widget`, as that attribute is reserved forĀ Custom Widgets. +3. In theĀ Global menu, select _Configure launchbar_. +4. In the _Visible Launchers_ section, select _Add a custom widget_. +5. Give the newly created launcher a name (and optionally a name). +6. In theĀ Promoted AttributesĀ section, modify the _widget_ field to point to the newly created note. +7. [Refresh](../../Troubleshooting/Refreshing%20the%20application.md) the UI. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch.md new file mode 100644 index 0000000000..a162e52b95 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch.md @@ -0,0 +1,85 @@ +# Analog Watch +
    + +This is a more intricate example of a basic widget, which displays an analog watch in the launch bar. Unlike note-context aware widgets, basic widgets don't react to note navigation. + +```javascript +const TPL = ` +
    + +
    + + +
    + + +
    +
    +`; + +class AnalogWatchWidget extends api.BasicWidget { + doRender() { + this.$widget = $(TPL); + + const hourHand = this.$widget.find('.hand.hour')[0]; + const minuteHand = this.$widget.find('.hand.minute')[0]; + const secondHand = this.$widget.find('.hand.second')[0]; + + const update = () => { + const now = new Date(); + const sec = now.getSeconds(); + const min = now.getMinutes(); + const hour = now.getHours(); + + const secDeg = sec * 6; + const minDeg = min * 6 + sec * 0.1; + const hourDeg = (hour % 12) * 30 + min * 0.5; + + secondHand.style.transform = `translate(-50%, -100%) rotate(${secDeg}deg)`; + minuteHand.style.transform = `translate(-50%, -100%) rotate(${minDeg}deg)`; + hourHand.style.transform = `translate(-50%, -100%) rotate(${hourDeg}deg)`; + }; + + update(); + this._interval = setInterval(update, 1000); + } + + cleanup() { + if (this._interval) clearInterval(this._interval); + } +} + +module.exports = new AnalogWatchWidget(); +``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch_image.png b/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch_image.png new file mode 100644 index 0000000000..809488185c Binary files /dev/null and b/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch_image.png differ diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget.md new file mode 100644 index 0000000000..c892e33650 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget.md @@ -0,0 +1,54 @@ +# Note Title Widget +
    + +This is an example of a note context-aware widget, which reacts to the currently opened note and refreshes automatically as the user navigates through the notes. + +## Legacy widget + +In this example, the title of the note is displayed. It works best on the [horizontal layout](../../../Basic%20Concepts%20and%20Features/UI%20Elements/Vertical%20and%20horizontal%20layout.md). + +```javascript +const TPL = `\ +
    `; + +class NoteTitleWidget extends api.NoteContextAwareWidget { + doRender() { + this.$widget = $(TPL); + } + + async refreshWithNote(note) { + this.$widget.text(note.title); + } +} + +module.exports = new NoteTitleWidget(); +``` + +## Preact widget (v0.101.0+) + +```jsx +import { defineLauncherWidget, useActiveNoteContext } from "trilium:preact"; + +export default defineLauncherWidget({ + render: () => { + const { note } = useActiveNoteContext(); + return
    {note?.title}
    ; + } +}); +``` \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget_image.png b/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget_image.png new file mode 100644 index 0000000000..6320bd8f17 Binary files /dev/null and b/docs/User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget_image.png differ diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Preact.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Preact.md new file mode 100644 index 0000000000..6f05765fce --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Preact.md @@ -0,0 +1,65 @@ +# Preact +Since v0.101.0, Trilium integrates Preact for front-end scripting, including support for JSX. + +Preact can be used for: + +* Render Note, where a JSX code note is used instead of a HTML one. +* Custom Widgets, where JSX can be used to replace the old, jQuery-based mechanism. + +To get started, the first step is to enable JSX in the list of Code languages. Go to Options → Code Notes and check the ā€œJSXā€ language. Afterwards, proceed with the documentation in eitherĀ Render NoteĀ orĀ Custom Widgets, which will both have a section on how to use the new Preact integration. + +> [!IMPORTANT] +> The documentation assumes prior knowledge with React or Preact. As a starting point, consider the [FreeCodeCamp course on Front End Development Libraries](https://www.freecodecamp.org/learn/front-end-development-libraries-v9/) or the [Preact Tutorial](https://preactjs.com/tutorial/). + +## Import/exports + +When using Preact with JSX, there is a special syntax which provides ES-like imports. This `import` syntax makes way for a more intuitive that doesn't make use of global objects and paves the way for better auto-completion support that might be introduced in the future.Ā  + +### API imports + +Instead of: + +```jsx +api.showMessage("Hello"); +``` + +the JSX version looks like this: + +```jsx +import { showMessage } from "trilium:api"; +showMessage("hello"); +``` + +### Preact API imports (hooks, components) + +There's a newĀ Script APIĀ dedicated to Preact, which provides shared components that are also used by Trilium internally as well as hooks, for example. + +```jsx +import { useState } from "trilium:preact"; +const [ myState, setMyState ] = useState("Hi"); +``` + +### Exporting + +JSX notes can export a component for use inĀ Render NoteĀ or forĀ Component libraries:  + +```jsx +export default function() { + return ( + <> +

    Hello world.

    + + ); +} +``` + +### Import/export are not required + +These imports are syntactic sugar meant to replace the usage for the `api` global object (seeĀ Script API).Ā  + +> [!NOTE] +> The `import` and `export` syntax work only for JSX notes. Standard/jQuery code notes still need to use the `api` global and `module.exports`. + +## Under the hood + +Unlike JavaScript, JSX requires pre-processing to turn it into JavaScript (just like TypeScript). To do so, Trilium uses [Sucrase](https://github.com/alangpierce/sucrase), a JavaScript library which processes the JSX to pure JavaScript. The processing is done each time a script is run (for widgets this happens at every program startup). If you notice any performance degradation due to long compilation, consider [reporting the issue](../../Troubleshooting/Reporting%20issues.md) to us. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components.md b/docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components.md new file mode 100644 index 0000000000..db05c92555 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components.md @@ -0,0 +1,43 @@ +# Built-in components +
    A partial screenshot from the Widget showcase example (see below).
    + +Trilium comes with its own set of Preact components, some of which are also available toĀ Custom WidgetsĀ andĀ Render Note. + +To use these components, simply import them from `trilium:preact`: + +```jsx +import { ActionButton, Button, LinkButton } from "trilium:preact"; +``` + +and then use them: + +```jsx +export default function MyRenderNote() { + const onClick = () => showMessage("A button was pressed"); + + return ( + <> +

    Buttons

    +
    + +
    + + ) +} +``` + +## Widget showcase + +> [!TIP] +> Starting with v0.101.0, the widget showcase is also available in theĀ Demo Notes. + +This is aĀ Render NoteĀ example with JSX that shows most of the built-in components that are accessible to custom widgets and JSX render notes. + +To use it, simply: + +1. Create a render note. +2. Create a child code note of JSX type with the content of this file:Ā Widget showcase +3. Set the `~renderNote` relation of the parent note to the child note. +4. Refresh the render note to see the results. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components/Widget showcase.jsx b/docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components/Widget showcase.jsx new file mode 100644 index 0000000000..6da0b9a5b4 --- /dev/null +++ b/docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components/Widget showcase.jsx @@ -0,0 +1,189 @@ +import { + ActionButton, Button, LinkButton, + Admonition, Collapsible, + FormCheckbox, FormDropdownList, FormFileUploadButton, FormGroup, FormRadioGroup, FormTextArea, + FormTextBox, FormToggle, Slider, RawHtml, LoadingSpinner, Icon, + Dropdown, FormListItem, FormDropdownDivider, FormDropdownSubmenu, + NoteAutocomplete, NoteLink, Modal, + CKEditor, + useEffect, useState +} from "trilium:preact"; +import { showMessage } from "trilium:api"; + +export default function() { + const [ time, setTime ] = useState(); + const lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam accumsan eu odio non gravida. Pellentesque ornare, arcu condimentum molestie dignissim, nibh turpis ultrices elit, eget elementum nunc erat at erat. Maecenas vehicula consectetur elit, nec fermentum elit venenatis eu."; + useEffect(() => { + const interval = setInterval(() => setTime(new Date().toLocaleString()), 1000); + return () => clearInterval(interval); + }, []); + + return ( +
    +

    Widget showcase

    + + + + Admonition
    + {lorem} +
    + + + {lorem} + + + + + + +
    + ); +} + +function Buttons() { + const onClick = () => showMessage("A button was pressed"); + + return ( + <> +

    Buttons

    +
    + +
    + + ) +} + +function FormElements() { + const [ checkboxChecked, setCheckboxChecked ] = useState(false); + const [ dropdownValue, setDropdownValue ] = useState("key-1"); + const [ radioGroupValue, setRadioGroupValue ] = useState("key-1"); + const [ sliderValue, setSliderValue ] = useState(50); + + return ( + <> +

    Form elements

    +
    + + + + + + + + + + + + + + {}} + /> + + + {}} + /> + + + + + + { + const file = files?.[0]; + if (!file) return; + showMessage(`Got file "${file.name}" of size ${file.size} B and type ${file.type}.`); + }} + /> + + + + + + + + + + +
    + + ) +} + +function NoteElements() { + const [ noteId, setNoteId ] = useState(""); + + return ( +
    +

    Note elements

    + + + + + + + {noteId + ? + : Select a note first} + +
    + ); +} + +function ModalSample() { + const [ shown, setShown ] = useState(false); + + return ( + <> +

    Modal

    + + + + +
    +
    + + + +
    +
    + +
    + +
    +
    + + + + +
    +
    +
    +
    + +
    + +
    + + + +
    +
    +
    + + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    + + + +
    + +
    + +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + +
    + +
    + +
    +
    + +
    +
    + + +
    +
    + +
    + +

    -

    +
    +
    + +

    -

    +
    +
    +
    + +

    -

    +
    +
    + +

    -

    +
    +
    + +

    -

    +
    +
    + +

    -

    +
    +
    + +

    -

    +
    +
    + +

    -

    +
    +
    + +

    -

    +
    +
    +
    + +

    -

    +
    +
    + +

    -

    +
    +
    + +

    -

    +
    +
    + +

    -

    +
    +
    +
    + +

    -

    +
    +
    + +
    +
    + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    + + +
    + +
    +
    +
    +
    +
    +
    + + +
    + +
    +
    +
    + + + +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + + + +
    +
    + +
    +
    + + + +
    +
    +
    + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    + + + +
    +
    +
    +
    +
    + + + + + +
    + +
    +
    + + + + +
    +
    + +
    + + +
    +
    +
    +
    + + +
    +
    + +
    +
    +
    + + + + + +
    + +
    +
    + + +
    +
    +
    + + +
    +
    + +
    + +
    + + +
    +
    +
    + + +
    + +
    +
    + + 0% +
    +
    + +
    +
    +
    + + + + + + +
    + + diff --git a/packages/pdfjs-viewer/viewer/viewer.mjs b/packages/pdfjs-viewer/viewer/viewer.mjs new file mode 100644 index 0000000000..4b86468c59 --- /dev/null +++ b/packages/pdfjs-viewer/viewer/viewer.mjs @@ -0,0 +1,19835 @@ +/** + * @licstart The following is the entire license notice for the + * JavaScript code in this page + * + * Copyright 2024 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @licend The above is the entire license notice for the + * JavaScript code in this page + */ + +/** + * pdfjsVersion = 5.5.207 + * pdfjsBuild = 527964698 + */ +/******/ // The require scope +/******/ var __webpack_require__ = {}; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; + +;// ./web/pdfjs.js +const { + AbortException, + AnnotationEditorLayer, + AnnotationEditorParamsType, + AnnotationEditorType, + AnnotationEditorUIManager, + AnnotationLayer, + AnnotationMode, + AnnotationType, + applyOpacity, + build, + ColorPicker, + createValidAbsoluteUrl, + CSSConstants, + DOMSVGFactory, + DrawLayer, + FeatureTest, + fetchData, + findContrastColor, + getDocument, + getFilenameFromUrl, + getPdfFilenameFromUrl, + getRGB, + getUuid, + getXfaPageViewport, + GlobalWorkerOptions, + ImageKind, + InvalidPDFException, + isDataScheme, + isPdfFile, + isValidExplicitDest, + makeArr, + makeMap, + makeObj, + MathClamp, + noContextMenu, + normalizeUnicode, + OPS, + OutputScale, + PasswordResponses, + PDFDataRangeTransport, + PDFDateString, + PDFWorker, + PermissionFlag, + PixelsPerInch, + RenderingCancelledException, + renderRichText, + ResponseException, + setLayerDimensions, + shadow, + SignatureExtractor, + stopEvent, + SupportedImageMimeTypes, + TextLayer, + TouchManager, + updateUrlHash, + Util, + VerbosityLevel, + version, + XfaLayer +} = globalThis.pdfjsLib; + +;// ./web/ui_utils.js + +const DEFAULT_SCALE_VALUE = "auto"; +const DEFAULT_SCALE = 1.0; +const DEFAULT_SCALE_DELTA = 1.1; +const MIN_SCALE = 0.1; +const MAX_SCALE = 10.0; +const UNKNOWN_SCALE = 0; +const MAX_AUTO_SCALE = 1.25; +const SCROLLBAR_PADDING = 40; +const VERTICAL_PADDING = 5; +const PresentationModeState = { + UNKNOWN: 0, + NORMAL: 1, + CHANGING: 2, + FULLSCREEN: 3 +}; +const SidebarView = { + UNKNOWN: -1, + NONE: 0, + THUMBS: 1, + OUTLINE: 2, + ATTACHMENTS: 3, + LAYERS: 4 +}; +const TextLayerMode = { + DISABLE: 0, + ENABLE: 1, + ENABLE_PERMISSIONS: 2 +}; +const ScrollMode = { + UNKNOWN: -1, + VERTICAL: 0, + HORIZONTAL: 1, + WRAPPED: 2, + PAGE: 3 +}; +const SpreadMode = { + UNKNOWN: -1, + NONE: 0, + ODD: 1, + EVEN: 2 +}; +const CursorTool = { + SELECT: 0, + HAND: 1, + ZOOM: 2 +}; +const AutoPrintRegExp = /\bprint\s*\(/; +function scrollIntoView(element, spot, scrollMatches = false) { + let parent = element.offsetParent; + if (!parent) { + console.error("offsetParent is not set -- cannot scroll"); + return; + } + let offsetY = element.offsetTop + element.clientTop; + let offsetX = element.offsetLeft + element.clientLeft; + while (parent.clientHeight === parent.scrollHeight && parent.clientWidth === parent.scrollWidth || scrollMatches && (parent.classList.contains("markedContent") || getComputedStyle(parent).overflow === "hidden")) { + offsetY += parent.offsetTop; + offsetX += parent.offsetLeft; + parent = parent.offsetParent; + if (!parent) { + return; + } + } + if (spot) { + if (spot.top !== undefined) { + offsetY += spot.top; + } + if (spot.left !== undefined) { + if (scrollMatches) { + const elementWidth = element.getBoundingClientRect().width; + const padding = MathClamp((parent.clientWidth - elementWidth) / 2, 20, 400); + offsetX += spot.left - padding; + } else { + offsetX += spot.left; + } + parent.scrollLeft = offsetX; + } + } + parent.scrollTop = offsetY; +} +function watchScroll(viewAreaElement, callback, abortSignal = undefined) { + const debounceScroll = function (evt) { + if (rAF) { + return; + } + rAF = window.requestAnimationFrame(function viewAreaElementScrolled() { + rAF = null; + const currentX = viewAreaElement.scrollLeft; + const lastX = state.lastX; + if (currentX !== lastX) { + state.right = currentX > lastX; + } + state.lastX = currentX; + const currentY = viewAreaElement.scrollTop; + const lastY = state.lastY; + if (currentY !== lastY) { + state.down = currentY > lastY; + } + state.lastY = currentY; + callback(state); + }); + }; + const state = { + right: true, + down: true, + lastX: viewAreaElement.scrollLeft, + lastY: viewAreaElement.scrollTop, + _eventHandler: debounceScroll + }; + let rAF = null; + viewAreaElement.addEventListener("scroll", debounceScroll, { + useCapture: true, + signal: abortSignal + }); + abortSignal?.addEventListener("abort", () => window.cancelAnimationFrame(rAF), { + once: true + }); + return state; +} +function parseQueryString(query) { + const params = new Map(); + for (const [key, value] of new URLSearchParams(query)) { + params.set(key.toLowerCase(), value); + } + return params; +} +const InvisibleCharsRegExp = /[\x00-\x1F]/g; +function removeNullCharacters(str, replaceInvisible = false) { + if (!InvisibleCharsRegExp.test(str)) { + return str; + } + if (replaceInvisible) { + return str.replaceAll(InvisibleCharsRegExp, m => m === "\x00" ? "" : " "); + } + return str.replaceAll("\x00", ""); +} +function binarySearchFirstItem(items, condition, start = 0) { + let minIndex = start; + let maxIndex = items.length - 1; + if (maxIndex < 0 || !condition(items[maxIndex])) { + return items.length; + } + if (condition(items[minIndex])) { + return minIndex; + } + while (minIndex < maxIndex) { + const currentIndex = minIndex + maxIndex >> 1; + const currentItem = items[currentIndex]; + if (condition(currentItem)) { + maxIndex = currentIndex; + } else { + minIndex = currentIndex + 1; + } + } + return minIndex; +} +function approximateFraction(x) { + if (Math.floor(x) === x) { + return [x, 1]; + } + const xinv = 1 / x; + const limit = 8; + if (xinv > limit) { + return [1, limit]; + } else if (Math.floor(xinv) === xinv) { + return [1, xinv]; + } + const x_ = x > 1 ? xinv : x; + let a = 0, + b = 1, + c = 1, + d = 1; + while (true) { + const p = a + c, + q = b + d; + if (q > limit) { + break; + } + if (x_ <= p / q) { + c = p; + d = q; + } else { + a = p; + b = q; + } + } + let result; + if (x_ - a / b < c / d - x_) { + result = x_ === x ? [a, b] : [b, a]; + } else { + result = x_ === x ? [c, d] : [d, c]; + } + return result; +} +function floorToDivide(x, div) { + return x - x % div; +} +function getPageSizeInches({ + view, + userUnit, + rotate +}) { + const [x1, y1, x2, y2] = view; + const changeOrientation = rotate % 180 !== 0; + const width = (x2 - x1) / 72 * userUnit; + const height = (y2 - y1) / 72 * userUnit; + return { + width: changeOrientation ? height : width, + height: changeOrientation ? width : height + }; +} +function backtrackBeforeAllVisibleElements(index, views, top) { + if (index < 2) { + return index; + } + let elt = views[index].div; + let pageTop = elt.offsetTop + elt.clientTop; + if (pageTop >= top) { + elt = views[index - 1].div; + pageTop = elt.offsetTop + elt.clientTop; + } + for (let i = index - 2; i >= 0; --i) { + elt = views[i].div; + if (elt.offsetTop + elt.clientTop + elt.clientHeight <= pageTop) { + break; + } + index = i; + } + return index; +} +function getVisibleElements({ + scrollEl, + views, + sortByVisibility = false, + horizontal = false, + rtl = false +}) { + const top = scrollEl.scrollTop, + bottom = top + scrollEl.clientHeight; + const left = scrollEl.scrollLeft, + right = left + scrollEl.clientWidth; + function isElementBottomAfterViewTop(view) { + const element = view.div; + const elementBottom = element.offsetTop + element.clientTop + element.clientHeight; + return elementBottom > top; + } + function isElementNextAfterViewHorizontally(view) { + const element = view.div; + const elementLeft = element.offsetLeft + element.clientLeft; + const elementRight = elementLeft + element.clientWidth; + return rtl ? elementLeft < right : elementRight > left; + } + const visible = [], + ids = new Set(), + numViews = views.length; + let firstVisibleElementInd = binarySearchFirstItem(views, horizontal ? isElementNextAfterViewHorizontally : isElementBottomAfterViewTop); + if (firstVisibleElementInd > 0 && firstVisibleElementInd < numViews && !horizontal) { + firstVisibleElementInd = backtrackBeforeAllVisibleElements(firstVisibleElementInd, views, top); + } + let lastEdge = horizontal ? right : -1; + for (let i = firstVisibleElementInd; i < numViews; i++) { + const view = views[i], + element = view.div; + const currentWidth = element.offsetLeft + element.clientLeft; + const currentHeight = element.offsetTop + element.clientTop; + const viewWidth = element.clientWidth, + viewHeight = element.clientHeight; + const viewRight = currentWidth + viewWidth; + const viewBottom = currentHeight + viewHeight; + if (lastEdge === -1) { + if (viewBottom >= bottom) { + lastEdge = viewBottom; + } + } else if ((horizontal ? currentWidth : currentHeight) > lastEdge) { + break; + } + if (viewBottom <= top || currentHeight >= bottom || viewRight <= left || currentWidth >= right) { + continue; + } + const minY = Math.max(0, top - currentHeight); + const minX = Math.max(0, left - currentWidth); + const hiddenHeight = minY + Math.max(0, viewBottom - bottom); + const hiddenWidth = minX + Math.max(0, viewRight - right); + const fractionHeight = (viewHeight - hiddenHeight) / viewHeight, + fractionWidth = (viewWidth - hiddenWidth) / viewWidth; + const percent = fractionHeight * fractionWidth * 100 | 0; + visible.push({ + id: view.id, + x: currentWidth, + y: currentHeight, + visibleArea: percent === 100 ? null : { + minX, + minY, + maxX: Math.min(viewRight, right) - currentWidth, + maxY: Math.min(viewBottom, bottom) - currentHeight + }, + view, + percent, + widthPercent: fractionWidth * 100 | 0 + }); + ids.add(view.id); + } + const first = visible[0], + last = visible.at(-1); + if (sortByVisibility) { + visible.sort(function (a, b) { + const pc = a.percent - b.percent; + if (Math.abs(pc) > 0.001) { + return -pc; + } + return a.id - b.id; + }); + } + return { + first, + last, + views: visible, + ids + }; +} +function normalizeWheelEventDirection(evt) { + let delta = Math.hypot(evt.deltaX, evt.deltaY); + const angle = Math.atan2(evt.deltaY, evt.deltaX); + if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) { + delta = -delta; + } + return delta; +} +function normalizeWheelEventDelta(evt) { + const deltaMode = evt.deltaMode; + let delta = normalizeWheelEventDirection(evt); + const MOUSE_PIXELS_PER_LINE = 30; + const MOUSE_LINES_PER_PAGE = 30; + if (deltaMode === WheelEvent.DOM_DELTA_PIXEL) { + delta /= MOUSE_PIXELS_PER_LINE * MOUSE_LINES_PER_PAGE; + } else if (deltaMode === WheelEvent.DOM_DELTA_LINE) { + delta /= MOUSE_LINES_PER_PAGE; + } + return delta; +} +function isValidRotation(angle) { + return Number.isInteger(angle) && angle % 90 === 0; +} +function isValidScrollMode(mode) { + return Number.isInteger(mode) && Object.values(ScrollMode).includes(mode) && mode !== ScrollMode.UNKNOWN; +} +function isValidSpreadMode(mode) { + return Number.isInteger(mode) && Object.values(SpreadMode).includes(mode) && mode !== SpreadMode.UNKNOWN; +} +function isPortraitOrientation(size) { + return size.width <= size.height; +} +const animationStarted = new Promise(function (resolve) { + window.requestAnimationFrame(resolve); +}); +const docStyle = document.documentElement.style; +class ProgressBar { + #classList = null; + #disableAutoFetchTimeout = null; + #percent = 0; + #style = null; + #visible = true; + constructor(bar) { + this.#classList = bar.classList; + this.#style = bar.style; + } + get percent() { + return this.#percent; + } + set percent(val) { + this.#percent = val; + if (isNaN(val)) { + this.#classList.add("indeterminate"); + return; + } + this.#classList.remove("indeterminate"); + this.#style.setProperty("--progressBar-percent", `${this.#percent}%`); + } + setWidth(viewer) { + if (!viewer) { + return; + } + const container = viewer.parentNode; + const scrollbarWidth = container.offsetWidth - viewer.offsetWidth; + if (scrollbarWidth > 0) { + this.#style.setProperty("--progressBar-end-offset", `${scrollbarWidth}px`); + } + } + setDisableAutoFetch(delay = 5000) { + if (this.#percent === 100 || isNaN(this.#percent)) { + return; + } + if (this.#disableAutoFetchTimeout) { + clearTimeout(this.#disableAutoFetchTimeout); + } + this.show(); + this.#disableAutoFetchTimeout = setTimeout(() => { + this.#disableAutoFetchTimeout = null; + this.hide(); + }, delay); + } + hide() { + if (!this.#visible) { + return; + } + this.#visible = false; + this.#classList.add("hidden"); + } + show() { + if (this.#visible) { + return; + } + this.#visible = true; + this.#classList.remove("hidden"); + } +} +function getActiveOrFocusedElement() { + let curRoot = document; + let curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus"); + while (curActiveOrFocused?.shadowRoot) { + curRoot = curActiveOrFocused.shadowRoot; + curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus"); + } + return curActiveOrFocused; +} +function apiPageLayoutToViewerModes(layout) { + let scrollMode = ScrollMode.VERTICAL, + spreadMode = SpreadMode.NONE; + switch (layout) { + case "SinglePage": + scrollMode = ScrollMode.PAGE; + break; + case "OneColumn": + break; + case "TwoPageLeft": + scrollMode = ScrollMode.PAGE; + case "TwoColumnLeft": + spreadMode = SpreadMode.ODD; + break; + case "TwoPageRight": + scrollMode = ScrollMode.PAGE; + case "TwoColumnRight": + spreadMode = SpreadMode.EVEN; + break; + } + return { + scrollMode, + spreadMode + }; +} +function apiPageModeToSidebarView(mode) { + switch (mode) { + case "UseNone": + return SidebarView.NONE; + case "UseThumbs": + return SidebarView.THUMBS; + case "UseOutlines": + return SidebarView.OUTLINE; + case "UseAttachments": + return SidebarView.ATTACHMENTS; + case "UseOC": + return SidebarView.LAYERS; + } + return SidebarView.NONE; +} +function toggleCheckedBtn(button, toggle, view = null) { + button.classList.toggle("toggled", toggle); + button.setAttribute("aria-checked", toggle); + view?.classList.toggle("hidden", !toggle); +} +function toggleSelectedBtn(button, toggle, view = null) { + button.classList.toggle("selected", toggle); + button.setAttribute("aria-selected", toggle); + view?.classList.toggle("hidden", !toggle); +} +function toggleExpandedBtn(button, toggle, view = null) { + button.classList.toggle("toggled", toggle); + button.setAttribute("aria-expanded", toggle); + view?.classList.toggle("hidden", !toggle); +} +const calcRound = function () { + const e = document.createElement("div"); + e.style.width = "round(down, calc(1.6666666666666665 * 792px), 1px)"; + return e.style.width === "calc(1320px)" ? Math.fround : x => x; +}(); + +;// ./web/app_options.js +{ + var compatParams = new Map(); + const { + maxTouchPoints, + platform, + userAgent + } = navigator; + const isAndroid = /Android/.test(userAgent); + const isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent) || platform === "MacIntel" && maxTouchPoints > 1; + if (isIOS || isAndroid) { + compatParams.set("maxCanvasPixels", 5242880); + } + if (isAndroid) { + compatParams.set("useSystemFonts", false); + } +} +const OptionKind = { + BROWSER: 0x01, + VIEWER: 0x02, + API: 0x04, + WORKER: 0x08, + EVENT_DISPATCH: 0x10, + PREFERENCE: 0x80 +}; +const Type = { + BOOLEAN: 0x01, + NUMBER: 0x02, + OBJECT: 0x04, + STRING: 0x08, + UNDEFINED: 0x10 +}; +const defaultOptions = { + allowedGlobalEvents: { + value: null, + kind: OptionKind.BROWSER + }, + canvasMaxAreaInBytes: { + value: -1, + kind: OptionKind.BROWSER + OptionKind.API + }, + isInAutomation: { + value: false, + kind: OptionKind.BROWSER + }, + localeProperties: { + value: { + lang: navigator.language || "en-US" + }, + kind: OptionKind.BROWSER + }, + maxCanvasDim: { + value: 32767, + kind: OptionKind.BROWSER + OptionKind.VIEWER + }, + nimbusDataStr: { + value: "", + kind: OptionKind.BROWSER + }, + supportsCaretBrowsingMode: { + value: false, + kind: OptionKind.BROWSER + }, + supportsDocumentFonts: { + value: true, + kind: OptionKind.BROWSER + }, + supportsIntegratedFind: { + value: false, + kind: OptionKind.BROWSER + }, + supportsMouseWheelZoomCtrlKey: { + value: true, + kind: OptionKind.BROWSER + }, + supportsMouseWheelZoomMetaKey: { + value: true, + kind: OptionKind.BROWSER + }, + supportsPinchToZoom: { + value: true, + kind: OptionKind.BROWSER + }, + supportsPrinting: { + value: true, + kind: OptionKind.BROWSER + }, + toolbarDensity: { + value: 0, + kind: OptionKind.BROWSER + OptionKind.EVENT_DISPATCH + }, + altTextLearnMoreUrl: { + value: "", + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + annotationEditorMode: { + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + annotationMode: { + value: 2, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + capCanvasAreaFactor: { + value: 200, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + commentLearnMoreUrl: { + value: "", + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + cursorToolOnLoad: { + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + debuggerSrc: { + value: "./debugger.mjs", + kind: OptionKind.VIEWER + }, + defaultZoomDelay: { + value: 400, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + defaultZoomValue: { + value: "", + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + disableHistory: { + value: false, + kind: OptionKind.VIEWER + }, + disablePageLabels: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableAltText: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableAltTextModelDownload: { + value: true, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + OptionKind.EVENT_DISPATCH + }, + enableAutoLinking: { + value: true, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableComment: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableDetailCanvas: { + value: true, + kind: OptionKind.VIEWER + }, + enableGuessAltText: { + value: true, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + OptionKind.EVENT_DISPATCH + }, + enableHighlightFloatingButton: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableNewAltTextWhenAddingImage: { + value: true, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableOptimizedPartialRendering: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enablePermissions: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enablePrintAutoRotate: { + value: true, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableScripting: { + value: true, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableSignatureEditor: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableSplitMerge: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableUpdatedAddImage: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + externalLinkRel: { + value: "noopener noreferrer nofollow", + kind: OptionKind.VIEWER + }, + externalLinkTarget: { + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + highlightEditorColors: { + value: "yellow=#FFFF98,green=#53FFBC,blue=#80EBFF,pink=#FFCBE6,red=#FF4F5F," + "yellow_HCM=#FFFFCC,green_HCM=#53FFBC,blue_HCM=#80EBFF,pink_HCM=#F6B8FF,red_HCM=#C50043", + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + historyUpdateUrl: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + ignoreDestinationZoom: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + imageResourcesPath: { + value: "./images/", + kind: OptionKind.VIEWER + }, + maxCanvasPixels: { + value: 2 ** 25, + kind: OptionKind.VIEWER + }, + minDurationToUpdateCanvas: { + value: 500, + kind: OptionKind.VIEWER + }, + forcePageColors: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + pageColorsBackground: { + value: "Canvas", + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + pageColorsForeground: { + value: "CanvasText", + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + pdfBugEnabled: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + printResolution: { + value: 150, + kind: OptionKind.VIEWER + }, + sidebarViewOnLoad: { + value: -1, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + scrollModeOnLoad: { + value: -1, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + spreadModeOnLoad: { + value: -1, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + textLayerMode: { + value: 1, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + viewerCssTheme: { + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + viewOnLoad: { + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + cMapPacked: { + value: true, + kind: OptionKind.API + }, + cMapUrl: { + value: "../web/cmaps/", + kind: OptionKind.API + }, + disableAutoFetch: { + value: false, + kind: OptionKind.API + OptionKind.PREFERENCE + }, + disableFontFace: { + value: false, + kind: OptionKind.API + OptionKind.PREFERENCE + }, + disableRange: { + value: false, + kind: OptionKind.API + OptionKind.PREFERENCE + }, + disableStream: { + value: false, + kind: OptionKind.API + OptionKind.PREFERENCE + }, + docBaseUrl: { + value: "", + kind: OptionKind.API + }, + enableHWA: { + value: true, + kind: OptionKind.API + OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableXfa: { + value: true, + kind: OptionKind.API + OptionKind.PREFERENCE + }, + fontExtraProperties: { + value: false, + kind: OptionKind.API + }, + iccUrl: { + value: "../web/iccs/", + kind: OptionKind.API + }, + isEvalSupported: { + value: true, + kind: OptionKind.API + }, + isOffscreenCanvasSupported: { + value: true, + kind: OptionKind.API + }, + maxImageSize: { + value: -1, + kind: OptionKind.API + }, + pdfBug: { + value: false, + kind: OptionKind.API + }, + standardFontDataUrl: { + value: "../web/standard_fonts/", + kind: OptionKind.API + }, + useSystemFonts: { + value: undefined, + kind: OptionKind.API, + type: Type.BOOLEAN + Type.UNDEFINED + }, + verbosity: { + value: 1, + kind: OptionKind.API + }, + wasmUrl: { + value: "../web/wasm/", + kind: OptionKind.API + }, + workerPort: { + value: null, + kind: OptionKind.WORKER + }, + workerSrc: { + value: "../build/pdf.worker.mjs", + kind: OptionKind.WORKER + } +}; +{ + defaultOptions.defaultUrl = { + value: "compressed.tracemonkey-pldi-09.pdf", + kind: OptionKind.VIEWER + }; + defaultOptions.sandboxBundleSrc = { + value: "../build/pdf.sandbox.mjs", + kind: OptionKind.VIEWER + }; + defaultOptions.enableFakeMLManager = { + value: true, + kind: OptionKind.VIEWER + }; +} +{ + defaultOptions.disablePreferences = { + value: false, + kind: OptionKind.VIEWER + }; +} +class AppOptions { + static eventBus; + static #opts = new Map(); + static { + for (const name in defaultOptions) { + this.#opts.set(name, defaultOptions[name].value); + } + for (const [name, value] of compatParams) { + this.#opts.set(name, value); + } + this._hasInvokedSet = false; + this._checkDisablePreferences = () => { + if (this.get("disablePreferences")) { + return true; + } + if (this._hasInvokedSet) { + console.warn("The Preferences may override manually set AppOptions; " + 'please use the "disablePreferences"-option to prevent that.'); + } + return false; + }; + } + static get(name) { + return this.#opts.get(name); + } + static getAll(kind = null, defaultOnly = false) { + const options = Object.create(null); + for (const name in defaultOptions) { + const defaultOpt = defaultOptions[name]; + if (kind && !(kind & defaultOpt.kind)) { + continue; + } + options[name] = !defaultOnly ? this.#opts.get(name) : defaultOpt.value; + } + return options; + } + static set(name, value) { + this.setAll({ + [name]: value + }); + } + static setAll(options, prefs = false) { + this._hasInvokedSet ||= true; + let events; + for (const name in options) { + const defaultOpt = defaultOptions[name], + userOpt = options[name]; + if (!defaultOpt || !(typeof userOpt === typeof defaultOpt.value || Type[(typeof userOpt).toUpperCase()] & defaultOpt.type)) { + continue; + } + const { + kind + } = defaultOpt; + if (prefs && !(kind & OptionKind.BROWSER || kind & OptionKind.PREFERENCE)) { + continue; + } + if (this.eventBus && kind & OptionKind.EVENT_DISPATCH) { + (events ||= new Map()).set(name, userOpt); + } + this.#opts.set(name, userOpt); + } + if (events) { + for (const [name, value] of events) { + this.eventBus.dispatch(name.toLowerCase(), { + source: this, + value + }); + } + } + } +} + +;// ./web/pdf_link_service.js + + +const DEFAULT_LINK_REL = "noopener noreferrer nofollow"; +const LinkTarget = { + NONE: 0, + SELF: 1, + BLANK: 2, + PARENT: 3, + TOP: 4 +}; +class PDFLinkService { + externalLinkEnabled = true; + constructor({ + eventBus, + externalLinkTarget = null, + externalLinkRel = null, + ignoreDestinationZoom = false + } = {}) { + this.eventBus = eventBus; + this.externalLinkTarget = externalLinkTarget; + this.externalLinkRel = externalLinkRel; + this._ignoreDestinationZoom = ignoreDestinationZoom; + this.baseUrl = null; + this.pdfDocument = null; + this.pdfViewer = null; + this.pdfHistory = null; + } + setDocument(pdfDocument, baseUrl = null) { + this.baseUrl = baseUrl; + this.pdfDocument = pdfDocument; + } + setViewer(pdfViewer) { + this.pdfViewer = pdfViewer; + } + setHistory(pdfHistory) { + this.pdfHistory = pdfHistory; + } + get pagesCount() { + return this.pdfDocument?.pagesMapper.pagesNumber || 0; + } + get page() { + return this.pdfDocument ? this.pdfViewer.currentPageNumber : 1; + } + set page(value) { + if (this.pdfDocument) { + this.pdfViewer.currentPageNumber = value; + } + } + get rotation() { + return this.pdfDocument ? this.pdfViewer.pagesRotation : 0; + } + set rotation(value) { + if (this.pdfDocument) { + this.pdfViewer.pagesRotation = value; + } + } + get isInPresentationMode() { + return this.pdfDocument ? this.pdfViewer.isInPresentationMode : false; + } + async goToDestination(dest) { + if (!this.pdfDocument) { + return; + } + let namedDest, explicitDest, pageNumber; + if (typeof dest === "string") { + namedDest = dest; + explicitDest = await this.pdfDocument.getDestination(dest); + } else { + namedDest = null; + explicitDest = await dest; + } + if (!Array.isArray(explicitDest)) { + console.error(`goToDestination: "${explicitDest}" is not a valid destination array, for dest="${dest}".`); + return; + } + const [destRef] = explicitDest; + if (destRef && typeof destRef === "object") { + pageNumber = this.pdfDocument.cachedPageNumber(destRef); + if (!pageNumber) { + try { + pageNumber = (await this.pdfDocument.getPageIndex(destRef)) + 1; + } catch { + console.error(`goToDestination: "${destRef}" is not a valid page reference, for dest="${dest}".`); + return; + } + } + } else if (Number.isInteger(destRef)) { + pageNumber = destRef + 1; + } + if (!pageNumber || pageNumber < 1 || pageNumber > this.pagesCount) { + console.error(`goToDestination: "${pageNumber}" is not a valid page number, for dest="${dest}".`); + return; + } + if (this.pdfHistory) { + this.pdfHistory.pushCurrentPosition(); + this.pdfHistory.push({ + namedDest, + explicitDest, + pageNumber + }); + } + this.pdfViewer.scrollPageIntoView({ + pageNumber, + destArray: explicitDest, + ignoreDestinationZoom: this._ignoreDestinationZoom + }); + const ac = new AbortController(); + this.eventBus._on("textlayerrendered", evt => { + if (evt.pageNumber === pageNumber) { + evt.source.textLayer.div.focus(); + ac.abort(); + } + }, { + signal: ac.signal + }); + } + goToPage(val) { + if (!this.pdfDocument) { + return; + } + const pageNumber = typeof val === "string" && this.pdfViewer.pageLabelToPageNumber(val) || val | 0; + if (!(Number.isInteger(pageNumber) && pageNumber > 0 && pageNumber <= this.pagesCount)) { + console.error(`PDFLinkService.goToPage: "${val}" is not a valid page.`); + return; + } + if (this.pdfHistory) { + this.pdfHistory.pushCurrentPosition(); + this.pdfHistory.pushPage(pageNumber); + } + this.pdfViewer.scrollPageIntoView({ + pageNumber + }); + } + goToXY(pageNumber, x, y, options = {}) { + this.pdfViewer.scrollPageIntoView({ + pageNumber, + destArray: [null, { + name: "XYZ" + }, x, y], + ignoreDestinationZoom: true, + ...options + }); + } + addLinkAttributes(link, url, newWindow = false) { + if (!url || typeof url !== "string") { + throw new Error('A valid "url" parameter must provided.'); + } + const target = newWindow ? LinkTarget.BLANK : this.externalLinkTarget, + rel = this.externalLinkRel; + if (this.externalLinkEnabled) { + link.href = link.title = url; + } else { + link.href = ""; + link.title = `Disabled: ${url}`; + link.onclick = () => false; + } + let targetStr = ""; + switch (target) { + case LinkTarget.NONE: + break; + case LinkTarget.SELF: + targetStr = "_self"; + break; + case LinkTarget.BLANK: + targetStr = "_blank"; + break; + case LinkTarget.PARENT: + targetStr = "_parent"; + break; + case LinkTarget.TOP: + targetStr = "_top"; + break; + } + link.target = targetStr; + link.rel = typeof rel === "string" ? rel : DEFAULT_LINK_REL; + } + getDestinationHash(dest) { + if (typeof dest === "string") { + if (dest.length > 0) { + return this.getAnchorUrl("#" + escape(dest)); + } + } else if (Array.isArray(dest)) { + const str = JSON.stringify(dest); + if (str.length > 0) { + return this.getAnchorUrl("#" + escape(str)); + } + } + return this.getAnchorUrl(""); + } + getAnchorUrl(anchor) { + return this.baseUrl ? this.baseUrl + anchor : anchor; + } + setHash(hash) { + if (!this.pdfDocument) { + return; + } + let pageNumber, dest; + if (hash.includes("=")) { + const params = parseQueryString(hash); + if (params.has("search")) { + const query = params.get("search").replaceAll('"', ""), + phrase = params.get("phrase") === "true"; + this.eventBus.dispatch("findfromurlhash", { + source: this, + query: phrase ? query : query.match(/\S+/g) + }); + } + if (params.has("page")) { + pageNumber = params.get("page") | 0 || 1; + } + if (params.has("zoom")) { + const zoomArgs = params.get("zoom").split(","); + const zoomArg = zoomArgs[0]; + const zoomArgNumber = parseFloat(zoomArg); + if (!zoomArg.includes("Fit")) { + dest = [null, { + name: "XYZ" + }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null, zoomArgs.length > 2 ? zoomArgs[2] | 0 : null, zoomArgNumber ? zoomArgNumber / 100 : zoomArg]; + } else if (zoomArg === "Fit" || zoomArg === "FitB") { + dest = [null, { + name: zoomArg + }]; + } else if (zoomArg === "FitH" || zoomArg === "FitBH" || zoomArg === "FitV" || zoomArg === "FitBV") { + dest = [null, { + name: zoomArg + }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null]; + } else if (zoomArg === "FitR") { + if (zoomArgs.length !== 5) { + console.error('PDFLinkService.setHash: Not enough parameters for "FitR".'); + } else { + dest = [null, { + name: zoomArg + }, zoomArgs[1] | 0, zoomArgs[2] | 0, zoomArgs[3] | 0, zoomArgs[4] | 0]; + } + } else { + console.error(`PDFLinkService.setHash: "${zoomArg}" is not a valid zoom value.`); + } + } + if (dest) { + this.pdfViewer.scrollPageIntoView({ + pageNumber: pageNumber || this.page, + destArray: dest, + allowNegativeOffset: true + }); + } else if (pageNumber) { + this.page = pageNumber; + } + if (params.has("pagemode")) { + this.eventBus.dispatch("pagemode", { + source: this, + mode: params.get("pagemode") + }); + } + if (params.has("nameddest")) { + this.goToDestination(params.get("nameddest")); + } + return; + } + dest = unescape(hash); + try { + dest = JSON.parse(dest); + if (!Array.isArray(dest)) { + dest = dest.toString(); + } + } catch {} + if (typeof dest === "string" || isValidExplicitDest(dest)) { + this.goToDestination(dest); + return; + } + console.error(`PDFLinkService.setHash: "${unescape(hash)}" is not a valid destination.`); + } + executeNamedAction(action) { + if (!this.pdfDocument) { + return; + } + switch (action) { + case "GoBack": + this.pdfHistory?.back(); + break; + case "GoForward": + this.pdfHistory?.forward(); + break; + case "NextPage": + this.pdfViewer.nextPage(); + break; + case "PrevPage": + this.pdfViewer.previousPage(); + break; + case "LastPage": + this.page = this.pagesCount; + break; + case "FirstPage": + this.page = 1; + break; + default: + break; + } + this.eventBus.dispatch("namedaction", { + source: this, + action + }); + } + async executeSetOCGState(action) { + if (!this.pdfDocument) { + return; + } + const pdfDocument = this.pdfDocument, + optionalContentConfig = await this.pdfViewer.optionalContentConfigPromise; + if (pdfDocument !== this.pdfDocument) { + return; + } + optionalContentConfig.setOCGState(action); + this.pdfViewer.optionalContentConfigPromise = Promise.resolve(optionalContentConfig); + } +} +class SimpleLinkService extends PDFLinkService { + setDocument(pdfDocument, baseUrl = null) {} +} + +;// ./web/event_utils.js +const WaitOnType = { + EVENT: "event", + TIMEOUT: "timeout" +}; +async function waitOnEventOrTimeout({ + target, + name, + delay = 0 +}) { + if (typeof target !== "object" || !(name && typeof name === "string") || !(Number.isInteger(delay) && delay >= 0)) { + throw new Error("waitOnEventOrTimeout - invalid parameters."); + } + const { + promise, + resolve + } = Promise.withResolvers(); + const ac = new AbortController(); + function handler(type) { + ac.abort(); + clearTimeout(timeout); + resolve(type); + } + const evtMethod = target instanceof EventBus ? "_on" : "addEventListener"; + target[evtMethod](name, handler.bind(null, WaitOnType.EVENT), { + signal: ac.signal + }); + const timeout = setTimeout(handler.bind(null, WaitOnType.TIMEOUT), delay); + return promise; +} +class EventBus { + #listeners = Object.create(null); + on(eventName, listener, options = null) { + this._on(eventName, listener, { + external: true, + once: options?.once, + signal: options?.signal + }); + } + off(eventName, listener, options = null) { + this._off(eventName, listener); + } + dispatch(eventName, data) { + const eventListeners = this.#listeners[eventName]; + if (!eventListeners || eventListeners.length === 0) { + return; + } + let externalListeners; + for (const { + listener, + external, + once + } of eventListeners.slice(0)) { + if (once) { + this._off(eventName, listener); + } + if (external) { + (externalListeners ||= []).push(listener); + continue; + } + listener(data); + } + if (externalListeners) { + for (const listener of externalListeners) { + listener(data); + } + externalListeners = null; + } + } + _on(eventName, listener, options = null) { + let rmAbort = null; + if (options?.signal instanceof AbortSignal) { + const { + signal + } = options; + if (signal.aborted) { + console.error("Cannot use an `aborted` signal."); + return; + } + const onAbort = () => this._off(eventName, listener); + rmAbort = () => signal.removeEventListener("abort", onAbort); + signal.addEventListener("abort", onAbort); + } + const eventListeners = this.#listeners[eventName] ||= []; + eventListeners.push({ + listener, + external: options?.external === true, + once: options?.once === true, + rmAbort + }); + } + _off(eventName, listener, options = null) { + const eventListeners = this.#listeners[eventName]; + if (!eventListeners) { + return; + } + for (let i = 0, ii = eventListeners.length; i < ii; i++) { + const evt = eventListeners[i]; + if (evt.listener === listener) { + evt.rmAbort?.(); + eventListeners.splice(i, 1); + return; + } + } + } +} +class FirefoxEventBus extends EventBus { + #externalServices; + #globalEventNames; + #isInAutomation; + constructor(globalEventNames, externalServices, isInAutomation) { + super(); + this.#globalEventNames = globalEventNames; + this.#externalServices = externalServices; + this.#isInAutomation = isInAutomation; + } + dispatch(eventName, data) { + throw new Error("Not implemented: FirefoxEventBus.dispatch"); + } +} + +;// ./web/external_services.js +class BaseExternalServices { + updateFindControlState(data) {} + updateFindMatchesCount(data) {} + initPassiveLoading() {} + reportTelemetry(data) {} + reportText(data) {} + async createL10n() { + throw new Error("Not implemented: createL10n"); + } + createScripting() { + throw new Error("Not implemented: createScripting"); + } + createSignatureStorage() { + throw new Error("Not implemented: createSignatureStorage"); + } + updateEditorStates(data) { + throw new Error("Not implemented: updateEditorStates"); + } + dispatchGlobalEvent(_event) {} +} + +;// ./web/preferences.js + +class BasePreferences { + #defaults = Object.freeze(AppOptions.getAll(OptionKind.PREFERENCE, true)); + #initializedPromise = null; + constructor() { + this.#initializedPromise = this._readFromStorage(this.#defaults).then(({ + browserPrefs, + prefs + }) => { + if (AppOptions._checkDisablePreferences()) { + return; + } + AppOptions.setAll({ + ...browserPrefs, + ...prefs + }, true); + }); + } + async _writeToStorage(prefObj) { + throw new Error("Not implemented: _writeToStorage"); + } + async _readFromStorage(prefObj) { + throw new Error("Not implemented: _readFromStorage"); + } + async reset() { + await this.#initializedPromise; + AppOptions.setAll(this.#defaults, true); + await this._writeToStorage(this.#defaults); + } + async set(name, value) { + await this.#initializedPromise; + AppOptions.setAll({ + [name]: value + }, true); + await this._writeToStorage(AppOptions.getAll(OptionKind.PREFERENCE)); + } + async get(name) { + await this.#initializedPromise; + return AppOptions.get(name); + } + get defaults() { + return this.#defaults; + } + get initializedPromise() { + return this.#initializedPromise; + } +} + +;// ./node_modules/@fluent/bundle/esm/types.js +class FluentType { + constructor(value) { + this.value = value; + } + valueOf() { + return this.value; + } +} +class FluentNone extends FluentType { + constructor(value = "???") { + super(value); + } + toString(scope) { + return `{${this.value}}`; + } +} +class FluentNumber extends FluentType { + constructor(value, opts = {}) { + super(value); + this.opts = opts; + } + toString(scope) { + if (scope) { + try { + const nf = scope.memoizeIntlObject(Intl.NumberFormat, this.opts); + return nf.format(this.value); + } catch (err) { + scope.reportError(err); + } + } + return this.value.toString(10); + } +} +class FluentDateTime extends FluentType { + static supportsValue(value) { + if (typeof value === "number") return true; + if (value instanceof Date) return true; + if (value instanceof FluentType) return FluentDateTime.supportsValue(value.valueOf()); + if ("Temporal" in globalThis) { + const _Temporal = globalThis.Temporal; + if (value instanceof _Temporal.Instant || value instanceof _Temporal.PlainDateTime || value instanceof _Temporal.PlainDate || value instanceof _Temporal.PlainMonthDay || value instanceof _Temporal.PlainTime || value instanceof _Temporal.PlainYearMonth) { + return true; + } + } + return false; + } + constructor(value, opts = {}) { + if (value instanceof FluentDateTime) { + opts = { + ...value.opts, + ...opts + }; + value = value.value; + } else if (value instanceof FluentType) { + value = value.valueOf(); + } + if (typeof value === "object" && "calendarId" in value && opts.calendar === undefined) { + opts = { + ...opts, + calendar: value.calendarId + }; + } + super(value); + this.opts = opts; + } + [Symbol.toPrimitive](hint) { + return hint === "string" ? this.toString() : this.toNumber(); + } + toNumber() { + const value = this.value; + if (typeof value === "number") return value; + if (value instanceof Date) return value.getTime(); + if ("epochMilliseconds" in value) { + return value.epochMilliseconds; + } + if ("toZonedDateTime" in value) { + return value.toZonedDateTime("UTC").epochMilliseconds; + } + throw new TypeError("Unwrapping a non-number value as a number"); + } + toString(scope) { + if (scope) { + try { + const dtf = scope.memoizeIntlObject(Intl.DateTimeFormat, this.opts); + return dtf.format(this.value); + } catch (err) { + scope.reportError(err); + } + } + if (typeof this.value === "number" || this.value instanceof Date) { + return new Date(this.value).toISOString(); + } + return this.value.toString(); + } +} +;// ./node_modules/@fluent/bundle/esm/resolver.js + +const MAX_PLACEABLES = 100; +const FSI = "\u2068"; +const PDI = "\u2069"; +function match(scope, selector, key) { + if (key === selector) { + return true; + } + if (key instanceof FluentNumber && selector instanceof FluentNumber && key.value === selector.value) { + return true; + } + if (selector instanceof FluentNumber && typeof key === "string") { + let category = scope.memoizeIntlObject(Intl.PluralRules, selector.opts).select(selector.value); + if (key === category) { + return true; + } + } + return false; +} +function getDefault(scope, variants, star) { + if (variants[star]) { + return resolvePattern(scope, variants[star].value); + } + scope.reportError(new RangeError("No default")); + return new FluentNone(); +} +function getArguments(scope, args) { + const positional = []; + const named = Object.create(null); + for (const arg of args) { + if (arg.type === "narg") { + named[arg.name] = resolveExpression(scope, arg.value); + } else { + positional.push(resolveExpression(scope, arg)); + } + } + return { + positional, + named + }; +} +function resolveExpression(scope, expr) { + switch (expr.type) { + case "str": + return expr.value; + case "num": + return new FluentNumber(expr.value, { + minimumFractionDigits: expr.precision + }); + case "var": + return resolveVariableReference(scope, expr); + case "mesg": + return resolveMessageReference(scope, expr); + case "term": + return resolveTermReference(scope, expr); + case "func": + return resolveFunctionReference(scope, expr); + case "select": + return resolveSelectExpression(scope, expr); + default: + return new FluentNone(); + } +} +function resolveVariableReference(scope, { + name +}) { + let arg; + if (scope.params) { + if (Object.prototype.hasOwnProperty.call(scope.params, name)) { + arg = scope.params[name]; + } else { + return new FluentNone(`$${name}`); + } + } else if (scope.args && Object.prototype.hasOwnProperty.call(scope.args, name)) { + arg = scope.args[name]; + } else { + scope.reportError(new ReferenceError(`Unknown variable: $${name}`)); + return new FluentNone(`$${name}`); + } + if (arg instanceof FluentType) { + return arg; + } + switch (typeof arg) { + case "string": + return arg; + case "number": + return new FluentNumber(arg); + case "object": + if (FluentDateTime.supportsValue(arg)) { + return new FluentDateTime(arg); + } + default: + scope.reportError(new TypeError(`Variable type not supported: $${name}, ${typeof arg}`)); + return new FluentNone(`$${name}`); + } +} +function resolveMessageReference(scope, { + name, + attr +}) { + const message = scope.bundle._messages.get(name); + if (!message) { + scope.reportError(new ReferenceError(`Unknown message: ${name}`)); + return new FluentNone(name); + } + if (attr) { + const attribute = message.attributes[attr]; + if (attribute) { + return resolvePattern(scope, attribute); + } + scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`)); + return new FluentNone(`${name}.${attr}`); + } + if (message.value) { + return resolvePattern(scope, message.value); + } + scope.reportError(new ReferenceError(`No value: ${name}`)); + return new FluentNone(name); +} +function resolveTermReference(scope, { + name, + attr, + args +}) { + const id = `-${name}`; + const term = scope.bundle._terms.get(id); + if (!term) { + scope.reportError(new ReferenceError(`Unknown term: ${id}`)); + return new FluentNone(id); + } + if (attr) { + const attribute = term.attributes[attr]; + if (attribute) { + scope.params = getArguments(scope, args).named; + const resolved = resolvePattern(scope, attribute); + scope.params = null; + return resolved; + } + scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`)); + return new FluentNone(`${id}.${attr}`); + } + scope.params = getArguments(scope, args).named; + const resolved = resolvePattern(scope, term.value); + scope.params = null; + return resolved; +} +function resolveFunctionReference(scope, { + name, + args +}) { + let func = scope.bundle._functions[name]; + if (!func) { + scope.reportError(new ReferenceError(`Unknown function: ${name}()`)); + return new FluentNone(`${name}()`); + } + if (typeof func !== "function") { + scope.reportError(new TypeError(`Function ${name}() is not callable`)); + return new FluentNone(`${name}()`); + } + try { + let resolved = getArguments(scope, args); + return func(resolved.positional, resolved.named); + } catch (err) { + scope.reportError(err); + return new FluentNone(`${name}()`); + } +} +function resolveSelectExpression(scope, { + selector, + variants, + star +}) { + let sel = resolveExpression(scope, selector); + if (sel instanceof FluentNone) { + return getDefault(scope, variants, star); + } + for (const variant of variants) { + const key = resolveExpression(scope, variant.key); + if (match(scope, sel, key)) { + return resolvePattern(scope, variant.value); + } + } + return getDefault(scope, variants, star); +} +function resolveComplexPattern(scope, ptn) { + if (scope.dirty.has(ptn)) { + scope.reportError(new RangeError("Cyclic reference")); + return new FluentNone(); + } + scope.dirty.add(ptn); + const result = []; + const useIsolating = scope.bundle._useIsolating && ptn.length > 1; + for (const elem of ptn) { + if (typeof elem === "string") { + result.push(scope.bundle._transform(elem)); + continue; + } + scope.placeables++; + if (scope.placeables > MAX_PLACEABLES) { + scope.dirty.delete(ptn); + throw new RangeError(`Too many placeables expanded: ${scope.placeables}, ` + `max allowed is ${MAX_PLACEABLES}`); + } + if (useIsolating) { + result.push(FSI); + } + result.push(resolveExpression(scope, elem).toString(scope)); + if (useIsolating) { + result.push(PDI); + } + } + scope.dirty.delete(ptn); + return result.join(""); +} +function resolvePattern(scope, value) { + if (typeof value === "string") { + return scope.bundle._transform(value); + } + return resolveComplexPattern(scope, value); +} +;// ./node_modules/@fluent/bundle/esm/scope.js +class Scope { + constructor(bundle, errors, args) { + this.dirty = new WeakSet(); + this.params = null; + this.placeables = 0; + this.bundle = bundle; + this.errors = errors; + this.args = args; + } + reportError(error) { + if (!this.errors || !(error instanceof Error)) { + throw error; + } + this.errors.push(error); + } + memoizeIntlObject(ctor, opts) { + let cache = this.bundle._intls.get(ctor); + if (!cache) { + cache = {}; + this.bundle._intls.set(ctor, cache); + } + let id = JSON.stringify(opts); + if (!cache[id]) { + cache[id] = new ctor(this.bundle.locales, opts); + } + return cache[id]; + } +} +;// ./node_modules/@fluent/bundle/esm/builtins.js + +function values(opts, allowed) { + const unwrapped = Object.create(null); + for (const [name, opt] of Object.entries(opts)) { + if (allowed.includes(name)) { + unwrapped[name] = opt.valueOf(); + } + } + return unwrapped; +} +const NUMBER_ALLOWED = ["unitDisplay", "currencyDisplay", "useGrouping", "minimumIntegerDigits", "minimumFractionDigits", "maximumFractionDigits", "minimumSignificantDigits", "maximumSignificantDigits"]; +function NUMBER(args, opts) { + let arg = args[0]; + if (arg instanceof FluentNone) { + return new FluentNone(`NUMBER(${arg.valueOf()})`); + } + if (arg instanceof FluentNumber) { + return new FluentNumber(arg.valueOf(), { + ...arg.opts, + ...values(opts, NUMBER_ALLOWED) + }); + } + if (arg instanceof FluentDateTime) { + return new FluentNumber(arg.toNumber(), { + ...values(opts, NUMBER_ALLOWED) + }); + } + throw new TypeError("Invalid argument to NUMBER"); +} +const DATETIME_ALLOWED = ["dateStyle", "timeStyle", "fractionalSecondDigits", "dayPeriod", "hour12", "weekday", "era", "year", "month", "day", "hour", "minute", "second", "timeZoneName"]; +function DATETIME(args, opts) { + let arg = args[0]; + if (arg instanceof FluentNone) { + return new FluentNone(`DATETIME(${arg.valueOf()})`); + } + if (arg instanceof FluentDateTime || arg instanceof FluentNumber) { + return new FluentDateTime(arg, values(opts, DATETIME_ALLOWED)); + } + throw new TypeError("Invalid argument to DATETIME"); +} +;// ./node_modules/@fluent/bundle/esm/memoizer.js +const cache = new Map(); +function getMemoizerForLocale(locales) { + const stringLocale = Array.isArray(locales) ? locales.join(" ") : locales; + let memoizer = cache.get(stringLocale); + if (memoizer === undefined) { + memoizer = new Map(); + cache.set(stringLocale, memoizer); + } + return memoizer; +} +;// ./node_modules/@fluent/bundle/esm/bundle.js + + + + + +class FluentBundle { + constructor(locales, { + functions, + useIsolating = true, + transform = v => v + } = {}) { + this._terms = new Map(); + this._messages = new Map(); + this.locales = Array.isArray(locales) ? locales : [locales]; + this._functions = { + NUMBER: NUMBER, + DATETIME: DATETIME, + ...functions + }; + this._useIsolating = useIsolating; + this._transform = transform; + this._intls = getMemoizerForLocale(locales); + } + hasMessage(id) { + return this._messages.has(id); + } + getMessage(id) { + return this._messages.get(id); + } + addResource(res, { + allowOverrides = false + } = {}) { + const errors = []; + for (let i = 0; i < res.body.length; i++) { + let entry = res.body[i]; + if (entry.id.startsWith("-")) { + if (allowOverrides === false && this._terms.has(entry.id)) { + errors.push(new Error(`Attempt to override an existing term: "${entry.id}"`)); + continue; + } + this._terms.set(entry.id, entry); + } else { + if (allowOverrides === false && this._messages.has(entry.id)) { + errors.push(new Error(`Attempt to override an existing message: "${entry.id}"`)); + continue; + } + this._messages.set(entry.id, entry); + } + } + return errors; + } + formatPattern(pattern, args = null, errors = null) { + if (typeof pattern === "string") { + return this._transform(pattern); + } + let scope = new Scope(this, errors, args); + try { + let value = resolveComplexPattern(scope, pattern); + return value.toString(scope); + } catch (err) { + if (scope.errors && err instanceof Error) { + scope.errors.push(err); + return new FluentNone().toString(scope); + } + throw err; + } + } +} +;// ./node_modules/@fluent/bundle/esm/resource.js +const RE_MESSAGE_START = /^(-?[a-zA-Z][\w-]*) *= */gm; +const RE_ATTRIBUTE_START = /\.([a-zA-Z][\w-]*) *= */y; +const RE_VARIANT_START = /\*?\[/y; +const RE_NUMBER_LITERAL = /(-?[0-9]+(?:\.([0-9]+))?)/y; +const RE_IDENTIFIER = /([a-zA-Z][\w-]*)/y; +const RE_REFERENCE = /([$-])?([a-zA-Z][\w-]*)(?:\.([a-zA-Z][\w-]*))?/y; +const RE_FUNCTION_NAME = /^[A-Z][A-Z0-9_-]*$/; +const RE_TEXT_RUN = /([^{}\n\r]+)/y; +const RE_STRING_RUN = /([^\\"\n\r]*)/y; +const RE_STRING_ESCAPE = /\\([\\"])/y; +const RE_UNICODE_ESCAPE = /\\u([a-fA-F0-9]{4})|\\U([a-fA-F0-9]{6})/y; +const RE_LEADING_NEWLINES = /^\n+/; +const RE_TRAILING_SPACES = / +$/; +const RE_BLANK_LINES = / *\r?\n/g; +const RE_INDENT = /( *)$/; +const TOKEN_BRACE_OPEN = /{\s*/y; +const TOKEN_BRACE_CLOSE = /\s*}/y; +const TOKEN_BRACKET_OPEN = /\[\s*/y; +const TOKEN_BRACKET_CLOSE = /\s*] */y; +const TOKEN_PAREN_OPEN = /\s*\(\s*/y; +const TOKEN_ARROW = /\s*->\s*/y; +const TOKEN_COLON = /\s*:\s*/y; +const TOKEN_COMMA = /\s*,?\s*/y; +const TOKEN_BLANK = /\s+/y; +class FluentResource { + constructor(source) { + this.body = []; + RE_MESSAGE_START.lastIndex = 0; + let cursor = 0; + while (true) { + let next = RE_MESSAGE_START.exec(source); + if (next === null) { + break; + } + cursor = RE_MESSAGE_START.lastIndex; + try { + this.body.push(parseMessage(next[1])); + } catch (err) { + if (err instanceof SyntaxError) { + continue; + } + throw err; + } + } + function test(re) { + re.lastIndex = cursor; + return re.test(source); + } + function consumeChar(char, errorClass) { + if (source[cursor] === char) { + cursor++; + return true; + } + if (errorClass) { + throw new errorClass(`Expected ${char}`); + } + return false; + } + function consumeToken(re, errorClass) { + if (test(re)) { + cursor = re.lastIndex; + return true; + } + if (errorClass) { + throw new errorClass(`Expected ${re.toString()}`); + } + return false; + } + function match(re) { + re.lastIndex = cursor; + let result = re.exec(source); + if (result === null) { + throw new SyntaxError(`Expected ${re.toString()}`); + } + cursor = re.lastIndex; + return result; + } + function match1(re) { + return match(re)[1]; + } + function parseMessage(id) { + let value = parsePattern(); + let attributes = parseAttributes(); + if (value === null && Object.keys(attributes).length === 0) { + throw new SyntaxError("Expected message value or attributes"); + } + return { + id, + value, + attributes + }; + } + function parseAttributes() { + let attrs = Object.create(null); + while (test(RE_ATTRIBUTE_START)) { + let name = match1(RE_ATTRIBUTE_START); + let value = parsePattern(); + if (value === null) { + throw new SyntaxError("Expected attribute value"); + } + attrs[name] = value; + } + return attrs; + } + function parsePattern() { + let first; + if (test(RE_TEXT_RUN)) { + first = match1(RE_TEXT_RUN); + } + if (source[cursor] === "{" || source[cursor] === "}") { + return parsePatternElements(first ? [first] : [], Infinity); + } + let indent = parseIndent(); + if (indent) { + if (first) { + return parsePatternElements([first, indent], indent.length); + } + indent.value = trim(indent.value, RE_LEADING_NEWLINES); + return parsePatternElements([indent], indent.length); + } + if (first) { + return trim(first, RE_TRAILING_SPACES); + } + return null; + } + function parsePatternElements(elements = [], commonIndent) { + while (true) { + if (test(RE_TEXT_RUN)) { + elements.push(match1(RE_TEXT_RUN)); + continue; + } + if (source[cursor] === "{") { + elements.push(parsePlaceable()); + continue; + } + if (source[cursor] === "}") { + throw new SyntaxError("Unbalanced closing brace"); + } + let indent = parseIndent(); + if (indent) { + elements.push(indent); + commonIndent = Math.min(commonIndent, indent.length); + continue; + } + break; + } + let lastIndex = elements.length - 1; + let lastElement = elements[lastIndex]; + if (typeof lastElement === "string") { + elements[lastIndex] = trim(lastElement, RE_TRAILING_SPACES); + } + let baked = []; + for (let element of elements) { + if (element instanceof Indent) { + element = element.value.slice(0, element.value.length - commonIndent); + } + if (element) { + baked.push(element); + } + } + return baked; + } + function parsePlaceable() { + consumeToken(TOKEN_BRACE_OPEN, SyntaxError); + let selector = parseInlineExpression(); + if (consumeToken(TOKEN_BRACE_CLOSE)) { + return selector; + } + if (consumeToken(TOKEN_ARROW)) { + let variants = parseVariants(); + consumeToken(TOKEN_BRACE_CLOSE, SyntaxError); + return { + type: "select", + selector, + ...variants + }; + } + throw new SyntaxError("Unclosed placeable"); + } + function parseInlineExpression() { + if (source[cursor] === "{") { + return parsePlaceable(); + } + if (test(RE_REFERENCE)) { + let [, sigil, name, attr = null] = match(RE_REFERENCE); + if (sigil === "$") { + return { + type: "var", + name + }; + } + if (consumeToken(TOKEN_PAREN_OPEN)) { + let args = parseArguments(); + if (sigil === "-") { + return { + type: "term", + name, + attr, + args + }; + } + if (RE_FUNCTION_NAME.test(name)) { + return { + type: "func", + name, + args + }; + } + throw new SyntaxError("Function names must be all upper-case"); + } + if (sigil === "-") { + return { + type: "term", + name, + attr, + args: [] + }; + } + return { + type: "mesg", + name, + attr + }; + } + return parseLiteral(); + } + function parseArguments() { + let args = []; + while (true) { + switch (source[cursor]) { + case ")": + cursor++; + return args; + case undefined: + throw new SyntaxError("Unclosed argument list"); + } + args.push(parseArgument()); + consumeToken(TOKEN_COMMA); + } + } + function parseArgument() { + let expr = parseInlineExpression(); + if (expr.type !== "mesg") { + return expr; + } + if (consumeToken(TOKEN_COLON)) { + return { + type: "narg", + name: expr.name, + value: parseLiteral() + }; + } + return expr; + } + function parseVariants() { + let variants = []; + let count = 0; + let star; + while (test(RE_VARIANT_START)) { + if (consumeChar("*")) { + star = count; + } + let key = parseVariantKey(); + let value = parsePattern(); + if (value === null) { + throw new SyntaxError("Expected variant value"); + } + variants[count++] = { + key, + value + }; + } + if (count === 0) { + return null; + } + if (star === undefined) { + throw new SyntaxError("Expected default variant"); + } + return { + variants, + star + }; + } + function parseVariantKey() { + consumeToken(TOKEN_BRACKET_OPEN, SyntaxError); + let key; + if (test(RE_NUMBER_LITERAL)) { + key = parseNumberLiteral(); + } else { + key = { + type: "str", + value: match1(RE_IDENTIFIER) + }; + } + consumeToken(TOKEN_BRACKET_CLOSE, SyntaxError); + return key; + } + function parseLiteral() { + if (test(RE_NUMBER_LITERAL)) { + return parseNumberLiteral(); + } + if (source[cursor] === '"') { + return parseStringLiteral(); + } + throw new SyntaxError("Invalid expression"); + } + function parseNumberLiteral() { + let [, value, fraction = ""] = match(RE_NUMBER_LITERAL); + let precision = fraction.length; + return { + type: "num", + value: parseFloat(value), + precision + }; + } + function parseStringLiteral() { + consumeChar('"', SyntaxError); + let value = ""; + while (true) { + value += match1(RE_STRING_RUN); + if (source[cursor] === "\\") { + value += parseEscapeSequence(); + continue; + } + if (consumeChar('"')) { + return { + type: "str", + value + }; + } + throw new SyntaxError("Unclosed string literal"); + } + } + function parseEscapeSequence() { + if (test(RE_STRING_ESCAPE)) { + return match1(RE_STRING_ESCAPE); + } + if (test(RE_UNICODE_ESCAPE)) { + let [, codepoint4, codepoint6] = match(RE_UNICODE_ESCAPE); + let codepoint = parseInt(codepoint4 || codepoint6, 16); + return codepoint <= 0xd7ff || 0xe000 <= codepoint ? String.fromCodePoint(codepoint) : "ļæ½"; + } + throw new SyntaxError("Unknown escape sequence"); + } + function parseIndent() { + let start = cursor; + consumeToken(TOKEN_BLANK); + switch (source[cursor]) { + case ".": + case "[": + case "*": + case "}": + case undefined: + return false; + case "{": + return makeIndent(source.slice(start, cursor)); + } + if (source[cursor - 1] === " ") { + return makeIndent(source.slice(start, cursor)); + } + return false; + } + function trim(text, re) { + return text.replace(re, ""); + } + function makeIndent(blank) { + let value = blank.replace(RE_BLANK_LINES, "\n"); + let length = RE_INDENT.exec(blank)[1].length; + return new Indent(value, length); + } + } +} +class Indent { + constructor(value, length) { + this.value = value; + this.length = length; + } +} +;// ./node_modules/@fluent/bundle/esm/index.js + + + +;// ./node_modules/@fluent/dom/esm/overlay.js +const reOverlay = /<|&#?\w+;/; +const TEXT_LEVEL_ELEMENTS = { + "http://www.w3.org/1999/xhtml": ["em", "strong", "small", "s", "cite", "q", "dfn", "abbr", "data", "time", "code", "var", "samp", "kbd", "sub", "sup", "i", "b", "u", "mark", "bdi", "bdo", "span", "br", "wbr"] +}; +const LOCALIZABLE_ATTRIBUTES = { + "http://www.w3.org/1999/xhtml": { + global: ["title", "aria-description", "aria-label", "aria-valuetext"], + a: ["download"], + area: ["download", "alt"], + input: ["alt", "placeholder"], + menuitem: ["label"], + menu: ["label"], + optgroup: ["label"], + option: ["label"], + track: ["label"], + img: ["alt"], + textarea: ["placeholder"], + th: ["abbr"] + }, + "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul": { + global: ["accesskey", "aria-label", "aria-valuetext", "label", "title", "tooltiptext"], + description: ["value"], + key: ["key", "keycode"], + label: ["value"], + textbox: ["placeholder", "value"] + } +}; +function translateElement(element, translation) { + const { + value + } = translation; + if (typeof value === "string") { + if (element.localName === "title" && element.namespaceURI === "http://www.w3.org/1999/xhtml") { + element.textContent = value; + } else if (!reOverlay.test(value)) { + element.textContent = value; + } else { + const templateElement = element.ownerDocument.createElementNS("http://www.w3.org/1999/xhtml", "template"); + templateElement.innerHTML = value; + overlayChildNodes(templateElement.content, element); + } + } + overlayAttributes(translation, element); +} +function overlayChildNodes(fromFragment, toElement) { + for (const childNode of fromFragment.childNodes) { + if (childNode.nodeType === childNode.TEXT_NODE) { + continue; + } + if (childNode.hasAttribute("data-l10n-name")) { + const sanitized = getNodeForNamedElement(toElement, childNode); + fromFragment.replaceChild(sanitized, childNode); + continue; + } + if (isElementAllowed(childNode)) { + const sanitized = createSanitizedElement(childNode); + fromFragment.replaceChild(sanitized, childNode); + continue; + } + console.warn(`An element of forbidden type "${childNode.localName}" was found in ` + "the translation. Only safe text-level elements and elements with " + "data-l10n-name are allowed."); + fromFragment.replaceChild(createTextNodeFromTextContent(childNode), childNode); + } + toElement.textContent = ""; + toElement.appendChild(fromFragment); +} +function hasAttribute(attributes, name) { + if (!attributes) { + return false; + } + for (let attr of attributes) { + if (attr.name === name) { + return true; + } + } + return false; +} +function overlayAttributes(fromElement, toElement) { + const explicitlyAllowed = toElement.hasAttribute("data-l10n-attrs") ? toElement.getAttribute("data-l10n-attrs").split(",").map(i => i.trim()) : null; + for (const attr of Array.from(toElement.attributes)) { + if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) && !hasAttribute(fromElement.attributes, attr.name)) { + toElement.removeAttribute(attr.name); + } + } + if (!fromElement.attributes) { + return; + } + for (const attr of Array.from(fromElement.attributes)) { + if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) && toElement.getAttribute(attr.name) !== attr.value) { + toElement.setAttribute(attr.name, attr.value); + } + } +} +function getNodeForNamedElement(sourceElement, translatedChild) { + const childName = translatedChild.getAttribute("data-l10n-name"); + const sourceChild = sourceElement.querySelector(`[data-l10n-name="${childName}"]`); + if (!sourceChild) { + console.warn(`An element named "${childName}" wasn't found in the source.`); + return createTextNodeFromTextContent(translatedChild); + } + if (sourceChild.localName !== translatedChild.localName) { + console.warn(`An element named "${childName}" was found in the translation ` + `but its type ${translatedChild.localName} didn't match the ` + `element found in the source (${sourceChild.localName}).`); + return createTextNodeFromTextContent(translatedChild); + } + sourceElement.removeChild(sourceChild); + const clone = sourceChild.cloneNode(false); + return shallowPopulateUsing(translatedChild, clone); +} +function createSanitizedElement(element) { + const clone = element.ownerDocument.createElement(element.localName); + return shallowPopulateUsing(element, clone); +} +function createTextNodeFromTextContent(element) { + return element.ownerDocument.createTextNode(element.textContent); +} +function isElementAllowed(element) { + const allowed = TEXT_LEVEL_ELEMENTS[element.namespaceURI]; + return allowed && allowed.includes(element.localName); +} +function isAttrNameLocalizable(name, element, explicitlyAllowed = null) { + if (explicitlyAllowed && explicitlyAllowed.includes(name)) { + return true; + } + const allowed = LOCALIZABLE_ATTRIBUTES[element.namespaceURI]; + if (!allowed) { + return false; + } + const attrName = name.toLowerCase(); + const elemName = element.localName; + if (allowed.global.includes(attrName)) { + return true; + } + if (!allowed[elemName]) { + return false; + } + if (allowed[elemName].includes(attrName)) { + return true; + } + if (element.namespaceURI === "http://www.w3.org/1999/xhtml" && elemName === "input" && attrName === "value") { + const type = element.type.toLowerCase(); + if (type === "submit" || type === "button" || type === "reset") { + return true; + } + } + return false; +} +function shallowPopulateUsing(fromElement, toElement) { + toElement.textContent = fromElement.textContent; + overlayAttributes(fromElement, toElement); + return toElement; +} +;// ./node_modules/cached-iterable/src/cached_iterable.mjs +class CachedIterable extends Array { + static from(iterable) { + if (iterable instanceof this) { + return iterable; + } + return new this(iterable); + } +} +;// ./node_modules/cached-iterable/src/cached_sync_iterable.mjs + +class CachedSyncIterable extends CachedIterable { + constructor(iterable) { + super(); + if (Symbol.iterator in Object(iterable)) { + this.iterator = iterable[Symbol.iterator](); + } else { + throw new TypeError("Argument must implement the iteration protocol."); + } + } + [Symbol.iterator]() { + const cached = this; + let cur = 0; + return { + next() { + if (cached.length <= cur) { + cached.push(cached.iterator.next()); + } + return cached[cur++]; + } + }; + } + touchNext(count = 1) { + let idx = 0; + while (idx++ < count) { + const last = this[this.length - 1]; + if (last && last.done) { + break; + } + this.push(this.iterator.next()); + } + return this[this.length - 1]; + } +} +;// ./node_modules/cached-iterable/src/cached_async_iterable.mjs + +class CachedAsyncIterable extends CachedIterable { + constructor(iterable) { + super(); + if (Symbol.asyncIterator in Object(iterable)) { + this.iterator = iterable[Symbol.asyncIterator](); + } else if (Symbol.iterator in Object(iterable)) { + this.iterator = iterable[Symbol.iterator](); + } else { + throw new TypeError("Argument must implement the iteration protocol."); + } + } + [Symbol.asyncIterator]() { + const cached = this; + let cur = 0; + return { + async next() { + if (cached.length <= cur) { + cached.push(cached.iterator.next()); + } + return cached[cur++]; + } + }; + } + async touchNext(count = 1) { + let idx = 0; + while (idx++ < count) { + const last = this[this.length - 1]; + if (last && (await last).done) { + break; + } + this.push(this.iterator.next()); + } + return this[this.length - 1]; + } +} +;// ./node_modules/cached-iterable/src/index.mjs + + +;// ./node_modules/@fluent/dom/esm/localization.js + +class Localization { + constructor(resourceIds = [], generateBundles) { + this.resourceIds = resourceIds; + this.generateBundles = generateBundles; + this.onChange(true); + } + addResourceIds(resourceIds, eager = false) { + this.resourceIds.push(...resourceIds); + this.onChange(eager); + return this.resourceIds.length; + } + removeResourceIds(resourceIds) { + this.resourceIds = this.resourceIds.filter(r => !resourceIds.includes(r)); + this.onChange(); + return this.resourceIds.length; + } + async formatWithFallback(keys, method) { + const translations = []; + let hasAtLeastOneBundle = false; + for await (const bundle of this.bundles) { + hasAtLeastOneBundle = true; + const missingIds = keysFromBundle(method, bundle, keys, translations); + if (missingIds.size === 0) { + break; + } + if (typeof console !== "undefined") { + const locale = bundle.locales[0]; + const ids = Array.from(missingIds).join(", "); + console.warn(`[fluent] Missing translations in ${locale}: ${ids}`); + } + } + if (!hasAtLeastOneBundle && typeof console !== "undefined") { + console.warn(`[fluent] Request for keys failed because no resource bundles got generated. + keys: ${JSON.stringify(keys)}. + resourceIds: ${JSON.stringify(this.resourceIds)}.`); + } + return translations; + } + formatMessages(keys) { + return this.formatWithFallback(keys, messageFromBundle); + } + formatValues(keys) { + return this.formatWithFallback(keys, valueFromBundle); + } + async formatValue(id, args) { + const [val] = await this.formatValues([{ + id, + args + }]); + return val; + } + handleEvent() { + this.onChange(); + } + onChange(eager = false) { + this.bundles = CachedAsyncIterable.from(this.generateBundles(this.resourceIds)); + if (eager) { + this.bundles.touchNext(2); + } + } +} +function valueFromBundle(bundle, errors, message, args) { + if (message.value) { + return bundle.formatPattern(message.value, args, errors); + } + return null; +} +function messageFromBundle(bundle, errors, message, args) { + const formatted = { + value: null, + attributes: null + }; + if (message.value) { + formatted.value = bundle.formatPattern(message.value, args, errors); + } + let attrNames = Object.keys(message.attributes); + if (attrNames.length > 0) { + formatted.attributes = new Array(attrNames.length); + for (let [i, name] of attrNames.entries()) { + let value = bundle.formatPattern(message.attributes[name], args, errors); + formatted.attributes[i] = { + name, + value + }; + } + } + return formatted; +} +function keysFromBundle(method, bundle, keys, translations) { + const messageErrors = []; + const missingIds = new Set(); + keys.forEach(({ + id, + args + }, i) => { + if (translations[i] !== undefined) { + return; + } + let message = bundle.getMessage(id); + if (message) { + messageErrors.length = 0; + translations[i] = method(bundle, messageErrors, message, args); + if (messageErrors.length > 0 && typeof console !== "undefined") { + const locale = bundle.locales[0]; + const errors = messageErrors.join(", "); + console.warn(`[fluent][resolver] errors in ${locale}/${id}: ${errors}.`); + } + } else { + missingIds.add(id); + } + }); + return missingIds; +} +;// ./node_modules/@fluent/dom/esm/dom_localization.js + + +const L10NID_ATTR_NAME = "data-l10n-id"; +const L10NARGS_ATTR_NAME = "data-l10n-args"; +const L10N_ELEMENT_QUERY = `[${L10NID_ATTR_NAME}]`; +class DOMLocalization extends Localization { + constructor(resourceIds, generateBundles) { + super(resourceIds, generateBundles); + this.roots = new Set(); + this.pendingrAF = null; + this.pendingElements = new Set(); + this.windowElement = null; + this.mutationObserver = null; + this.observerConfig = { + attributes: true, + characterData: false, + childList: true, + subtree: true, + attributeFilter: [L10NID_ATTR_NAME, L10NARGS_ATTR_NAME] + }; + } + onChange(eager = false) { + super.onChange(eager); + if (this.roots) { + this.translateRoots(); + } + } + setAttributes(element, id, args) { + element.setAttribute(L10NID_ATTR_NAME, id); + if (args) { + element.setAttribute(L10NARGS_ATTR_NAME, JSON.stringify(args)); + } else { + element.removeAttribute(L10NARGS_ATTR_NAME); + } + return element; + } + getAttributes(element) { + return { + id: element.getAttribute(L10NID_ATTR_NAME), + args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null) + }; + } + connectRoot(newRoot) { + for (const root of this.roots) { + if (root === newRoot || root.contains(newRoot) || newRoot.contains(root)) { + throw new Error("Cannot add a root that overlaps with existing root."); + } + } + if (this.windowElement) { + if (this.windowElement !== newRoot.ownerDocument.defaultView) { + throw new Error(`Cannot connect a root: + DOMLocalization already has a root from a different window.`); + } + } else { + this.windowElement = newRoot.ownerDocument.defaultView; + this.mutationObserver = new this.windowElement.MutationObserver(mutations => this.translateMutations(mutations)); + } + this.roots.add(newRoot); + this.mutationObserver.observe(newRoot, this.observerConfig); + } + disconnectRoot(root) { + this.roots.delete(root); + this.pauseObserving(); + if (this.roots.size === 0) { + this.mutationObserver = null; + if (this.windowElement && this.pendingrAF) { + this.windowElement.cancelAnimationFrame(this.pendingrAF); + } + this.windowElement = null; + this.pendingrAF = null; + this.pendingElements.clear(); + return true; + } + this.resumeObserving(); + return false; + } + translateRoots() { + const roots = Array.from(this.roots); + return Promise.all(roots.map(root => this.translateFragment(root))); + } + pauseObserving() { + if (!this.mutationObserver) { + return; + } + this.translateMutations(this.mutationObserver.takeRecords()); + this.mutationObserver.disconnect(); + } + resumeObserving() { + if (!this.mutationObserver) { + return; + } + for (const root of this.roots) { + this.mutationObserver.observe(root, this.observerConfig); + } + } + translateMutations(mutations) { + for (const mutation of mutations) { + switch (mutation.type) { + case "attributes": + if (mutation.target.hasAttribute("data-l10n-id")) { + this.pendingElements.add(mutation.target); + } + break; + case "childList": + for (const addedNode of mutation.addedNodes) { + if (addedNode.nodeType === addedNode.ELEMENT_NODE) { + if (addedNode.childElementCount) { + for (const element of this.getTranslatables(addedNode)) { + this.pendingElements.add(element); + } + } else if (addedNode.hasAttribute(L10NID_ATTR_NAME)) { + this.pendingElements.add(addedNode); + } + } + } + break; + } + } + if (this.pendingElements.size > 0) { + if (this.pendingrAF === null) { + this.pendingrAF = this.windowElement.requestAnimationFrame(() => { + this.translateElements(Array.from(this.pendingElements)); + this.pendingElements.clear(); + this.pendingrAF = null; + }); + } + } + } + translateFragment(frag) { + return this.translateElements(this.getTranslatables(frag)); + } + async translateElements(elements) { + if (!elements.length) { + return undefined; + } + const keys = elements.map(this.getKeysForElement); + const translations = await this.formatMessages(keys); + return this.applyTranslations(elements, translations); + } + applyTranslations(elements, translations) { + this.pauseObserving(); + for (let i = 0; i < elements.length; i++) { + if (translations[i] !== undefined) { + translateElement(elements[i], translations[i]); + } + } + this.resumeObserving(); + } + getTranslatables(element) { + const nodes = Array.from(element.querySelectorAll(L10N_ELEMENT_QUERY)); + if (typeof element.hasAttribute === "function" && element.hasAttribute(L10NID_ATTR_NAME)) { + nodes.push(element); + } + return nodes; + } + getKeysForElement(element) { + return { + id: element.getAttribute(L10NID_ATTR_NAME), + args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null) + }; + } +} +;// ./node_modules/@fluent/dom/esm/index.js + + +;// ./web/l10n.js +class L10n { + #dir; + #elements; + #lang; + #l10n; + constructor({ + lang, + isRTL + }, l10n = null) { + this.#lang = L10n.#fixupLangCode(lang); + this.#l10n = l10n; + this.#dir = isRTL ?? L10n.#isRTL(this.#lang) ? "rtl" : "ltr"; + } + _setL10n(l10n) { + this.#l10n = l10n; + } + getLanguage() { + return this.#lang; + } + getDirection() { + return this.#dir; + } + async get(ids, args = null, fallback) { + if (Array.isArray(ids)) { + ids = ids.map(id => ({ + id + })); + const messages = await this.#l10n.formatMessages(ids); + return messages.map(message => message.value); + } + const messages = await this.#l10n.formatMessages([{ + id: ids, + args + }]); + return messages[0]?.value || fallback; + } + async translate(element) { + (this.#elements ||= new Set()).add(element); + try { + this.#l10n.connectRoot(element); + await this.#l10n.translateRoots(); + } catch {} + } + async translateOnce(element) { + try { + await this.#l10n.translateElements([element]); + } catch (ex) { + console.error("translateOnce:", ex); + } + } + async destroy() { + if (this.#elements) { + for (const element of this.#elements) { + this.#l10n.disconnectRoot(element); + } + this.#elements.clear(); + this.#elements = null; + } + this.#l10n.pauseObserving(); + } + pause() { + this.#l10n.pauseObserving(); + } + resume() { + this.#l10n.resumeObserving(); + } + static #fixupLangCode(langCode) { + langCode = langCode?.toLowerCase() || "en-us"; + const PARTIAL_LANG_CODES = { + en: "en-us", + es: "es-es", + fy: "fy-nl", + ga: "ga-ie", + gu: "gu-in", + hi: "hi-in", + hy: "hy-am", + nb: "nb-no", + ne: "ne-np", + nn: "nn-no", + pa: "pa-in", + pt: "pt-pt", + sv: "sv-se", + zh: "zh-cn" + }; + return PARTIAL_LANG_CODES[langCode] || langCode; + } + static #isRTL(lang) { + const shortCode = lang.split("-", 1)[0]; + return ["ar", "he", "fa", "ps", "ur"].includes(shortCode); + } +} +const GenericL10n = null; + +;// ./web/genericl10n.js + + + + +function PLATFORM() { + const { + isAndroid, + isLinux, + isMac, + isWindows + } = FeatureTest.platform; + if (isLinux) { + return "linux"; + } + if (isWindows) { + return "windows"; + } + if (isMac) { + return "macos"; + } + if (isAndroid) { + return "android"; + } + return "other"; +} +function createBundle(lang, text) { + const resource = new FluentResource(text); + const bundle = new FluentBundle(lang, { + functions: { + PLATFORM + } + }); + const errors = bundle.addResource(resource); + if (errors.length) { + console.error("L10n errors", errors); + } + return bundle; +} +class genericl10n_GenericL10n extends L10n { + constructor(lang) { + super({ + lang + }); + const generateBundles = !lang ? genericl10n_GenericL10n.#generateBundlesFallback.bind(genericl10n_GenericL10n, this.getLanguage()) : genericl10n_GenericL10n.#generateBundles.bind(genericl10n_GenericL10n, "en-us", this.getLanguage()); + this._setL10n(new DOMLocalization([], generateBundles)); + } + static async *#generateBundles(defaultLang, baseLang) { + const { + baseURL, + paths + } = await this.#getPaths(); + const langs = [baseLang]; + if (defaultLang !== baseLang) { + const shortLang = baseLang.split("-", 1)[0]; + if (shortLang !== baseLang) { + langs.push(shortLang); + } + langs.push(defaultLang); + } + const bundles = langs.map(lang => [lang, this.#createBundle(lang, baseURL, paths)]); + for (const [lang, bundlePromise] of bundles) { + const bundle = await bundlePromise; + if (bundle) { + yield bundle; + } else if (lang === "en-us") { + yield this.#createBundleFallback(lang); + } + } + } + static async #createBundle(lang, baseURL, paths) { + const path = paths[lang]; + if (!path) { + return null; + } + const url = new URL(path, baseURL); + const text = await fetchData(url, "text"); + return createBundle(lang, text); + } + static async #getPaths() { + try { + const { + href + } = document.querySelector(`link[type="application/l10n"]`); + const paths = await fetchData(href, "json"); + return { + baseURL: href.substring(0, href.lastIndexOf("/") + 1) || "./", + paths + }; + } catch {} + return { + baseURL: "./", + paths: Object.create(null) + }; + } + static async *#generateBundlesFallback(lang) { + yield this.#createBundleFallback(lang); + } + static async #createBundleFallback(lang) { + const text = "pdfjs-previous-button =\n .title = Previous Page\npdfjs-previous-button-label = Previous\npdfjs-next-button =\n .title = Next Page\npdfjs-next-button-label = Next\npdfjs-page-input =\n .title = Page\npdfjs-of-pages = of { $pagesCount }\npdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })\npdfjs-zoom-out-button =\n .title = Zoom Out\npdfjs-zoom-out-button-label = Zoom Out\npdfjs-zoom-in-button =\n .title = Zoom In\npdfjs-zoom-in-button-label = Zoom In\npdfjs-zoom-select =\n .title = Zoom\npdfjs-presentation-mode-button =\n .title = Switch to Presentation Mode\npdfjs-presentation-mode-button-label = Presentation Mode\npdfjs-open-file-button =\n .title = Open File\npdfjs-open-file-button-label = Open\npdfjs-print-button =\n .title = Print\npdfjs-print-button-label = Print\npdfjs-save-button =\n .title = Save\npdfjs-save-button-label = Save\npdfjs-download-button =\n .title = Download\npdfjs-download-button-label = Download\npdfjs-bookmark-button =\n .title = Current Page (View URL from Current Page)\npdfjs-bookmark-button-label = Current Page\npdfjs-tools-button =\n .title = Tools\npdfjs-tools-button-label = Tools\npdfjs-first-page-button =\n .title = Go to First Page\npdfjs-first-page-button-label = Go to First Page\npdfjs-last-page-button =\n .title = Go to Last Page\npdfjs-last-page-button-label = Go to Last Page\npdfjs-page-rotate-cw-button =\n .title = Rotate Clockwise\npdfjs-page-rotate-cw-button-label = Rotate Clockwise\npdfjs-page-rotate-ccw-button =\n .title = Rotate Counterclockwise\npdfjs-page-rotate-ccw-button-label = Rotate Counterclockwise\npdfjs-cursor-text-select-tool-button =\n .title = Enable Text Selection Tool\npdfjs-cursor-text-select-tool-button-label = Text Selection Tool\npdfjs-cursor-hand-tool-button =\n .title = Enable Hand Tool\npdfjs-cursor-hand-tool-button-label = Hand Tool\npdfjs-scroll-page-button =\n .title = Use Page Scrolling\npdfjs-scroll-page-button-label = Page Scrolling\npdfjs-scroll-vertical-button =\n .title = Use Vertical Scrolling\npdfjs-scroll-vertical-button-label = Vertical Scrolling\npdfjs-scroll-horizontal-button =\n .title = Use Horizontal Scrolling\npdfjs-scroll-horizontal-button-label = Horizontal Scrolling\npdfjs-scroll-wrapped-button =\n .title = Use Wrapped Scrolling\npdfjs-scroll-wrapped-button-label = Wrapped Scrolling\npdfjs-spread-none-button =\n .title = Do not join page spreads\npdfjs-spread-none-button-label = No Spreads\npdfjs-spread-odd-button =\n .title = Join page spreads starting with odd-numbered pages\npdfjs-spread-odd-button-label = Odd Spreads\npdfjs-spread-even-button =\n .title = Join page spreads starting with even-numbered pages\npdfjs-spread-even-button-label = Even Spreads\npdfjs-document-properties-button =\n .title = Document Properties\u2026\npdfjs-document-properties-button-label = Document Properties\u2026\npdfjs-document-properties-file-name = File name:\npdfjs-document-properties-file-size = File size:\npdfjs-document-properties-size-kb = { NUMBER($kb, maximumSignificantDigits: 3) } KB ({ $b } bytes)\npdfjs-document-properties-size-mb = { NUMBER($mb, maximumSignificantDigits: 3) } MB ({ $b } bytes)\npdfjs-document-properties-title = Title:\npdfjs-document-properties-author = Author:\npdfjs-document-properties-subject = Subject:\npdfjs-document-properties-keywords = Keywords:\npdfjs-document-properties-creation-date = Creation Date:\npdfjs-document-properties-modification-date = Modification Date:\npdfjs-document-properties-date-time-string = { DATETIME($dateObj, dateStyle: \"short\", timeStyle: \"medium\") }\npdfjs-document-properties-creator = Creator:\npdfjs-document-properties-producer = PDF Producer:\npdfjs-document-properties-version = PDF Version:\npdfjs-document-properties-page-count = Page Count:\npdfjs-document-properties-page-size = Page Size:\npdfjs-document-properties-page-size-unit-inches = in\npdfjs-document-properties-page-size-unit-millimeters = mm\npdfjs-document-properties-page-size-orientation-portrait = portrait\npdfjs-document-properties-page-size-orientation-landscape = landscape\npdfjs-document-properties-page-size-name-a-three = A3\npdfjs-document-properties-page-size-name-a-four = A4\npdfjs-document-properties-page-size-name-letter = Letter\npdfjs-document-properties-page-size-name-legal = Legal\npdfjs-document-properties-page-size-dimension-string = { $width } \xD7 { $height } { $unit } ({ $orientation })\npdfjs-document-properties-page-size-dimension-name-string = { $width } \xD7 { $height } { $unit } ({ $name }, { $orientation })\npdfjs-document-properties-linearized = Fast Web View:\npdfjs-document-properties-linearized-yes = Yes\npdfjs-document-properties-linearized-no = No\npdfjs-document-properties-close-button = Close\npdfjs-print-progress-message = Preparing document for printing\u2026\npdfjs-print-progress-percent = { $progress }%\npdfjs-print-progress-close-button = Cancel\npdfjs-printing-not-supported = Warning: Printing is not fully supported by this browser.\npdfjs-printing-not-ready = Warning: The PDF is not fully loaded for printing.\npdfjs-current-outline-item-button =\n .title = Find Current Outline Item\npdfjs-current-outline-item-button-label = Current Outline Item\npdfjs-findbar-button =\n .title = Find in Document\npdfjs-findbar-button-label = Find\npdfjs-additional-layers = Additional Layers\npdfjs-thumb-page-title1 =\n .title = Page { $page } of { $total }\npdfjs-thumb-page-canvas =\n .aria-label = Thumbnail of Page { $page }\npdfjs-thumb-page-checkbox1 =\n .title = Select page { $page }\npdfjs-find-input =\n .title = Find\n .placeholder = Find in document\u2026\npdfjs-find-previous-button =\n .title = Find the previous occurrence of the phrase\npdfjs-find-previous-button-label = Previous\npdfjs-find-next-button =\n .title = Find the next occurrence of the phrase\npdfjs-find-next-button-label = Next\npdfjs-find-highlight-checkbox = Highlight All\npdfjs-find-match-case-checkbox-label = Match Case\npdfjs-find-match-diacritics-checkbox-label = Match Diacritics\npdfjs-find-entire-word-checkbox-label = Whole Words\npdfjs-find-reached-top = Reached top of document, continued from bottom\npdfjs-find-reached-bottom = Reached end of document, continued from top\npdfjs-find-match-count =\n { $total ->\n [one] { $current } of { $total } match\n *[other] { $current } of { $total } matches\n }\npdfjs-find-match-count-limit =\n { $limit ->\n [one] More than { $limit } match\n *[other] More than { $limit } matches\n }\npdfjs-find-not-found = Phrase not found\npdfjs-page-scale-width = Page Width\npdfjs-page-scale-fit = Page Fit\npdfjs-page-scale-auto = Automatic Zoom\npdfjs-page-scale-actual = Actual Size\npdfjs-page-scale-percent = { $scale }%\npdfjs-page-landmark =\n .aria-label = Page { $page }\npdfjs-loading-error = An error occurred while loading the PDF.\npdfjs-invalid-file-error = Invalid or corrupted PDF file.\npdfjs-missing-file-error = Missing PDF file.\npdfjs-unexpected-response-error = Unexpected server response.\npdfjs-rendering-error = An error occurred while rendering the page.\npdfjs-annotation-date-time-string = { DATETIME($dateObj, dateStyle: \"short\", timeStyle: \"medium\") }\npdfjs-text-annotation-type =\n .alt = [{ $type } Annotation]\npdfjs-password-label = Enter the password to open this PDF file.\npdfjs-password-invalid = Invalid password. Please try again.\npdfjs-password-ok-button = OK\npdfjs-password-cancel-button = Cancel\npdfjs-web-fonts-disabled = Web fonts are disabled: unable to use embedded PDF fonts.\npdfjs-editor-free-text-button =\n .title = Text\npdfjs-editor-color-picker-free-text-input =\n .title = Change text color\npdfjs-editor-free-text-button-label = Text\npdfjs-editor-ink-button =\n .title = Draw\npdfjs-editor-color-picker-ink-input =\n .title = Change drawing color\npdfjs-editor-ink-button-label = Draw\npdfjs-editor-stamp-button =\n .title = Add or edit images\npdfjs-editor-stamp-button-label = Add or edit images\npdfjs-editor-highlight-button =\n .title = Highlight\npdfjs-editor-highlight-button-label = Highlight\npdfjs-highlight-floating-button1 =\n .title = Highlight\n .aria-label = Highlight\npdfjs-highlight-floating-button-label = Highlight\npdfjs-comment-floating-button =\n .title = Comment\n .aria-label = Comment\npdfjs-comment-floating-button-label = Comment\npdfjs-editor-comment-button =\n .title = Comment\n .aria-label = Comment\npdfjs-editor-comment-button-label = Comment\npdfjs-editor-signature-button =\n .title = Add signature\npdfjs-editor-signature-button-label = Add signature\npdfjs-editor-highlight-editor =\n .aria-label = Highlight editor\npdfjs-editor-ink-editor =\n .aria-label = Drawing editor\npdfjs-editor-signature-editor1 =\n .aria-description = Signature editor: { $description }\npdfjs-editor-stamp-editor =\n .aria-label = Image editor\npdfjs-editor-remove-ink-button =\n .title = Remove drawing\npdfjs-editor-remove-freetext-button =\n .title = Remove text\npdfjs-editor-remove-stamp-button =\n .title = Remove image\npdfjs-editor-remove-highlight-button =\n .title = Remove highlight\npdfjs-editor-remove-signature-button =\n .title = Remove signature\npdfjs-editor-free-text-color-input = Color\npdfjs-editor-free-text-size-input = Size\npdfjs-editor-ink-color-input = Color\npdfjs-editor-ink-thickness-input = Thickness\npdfjs-editor-ink-opacity-input = Opacity\npdfjs-editor-stamp-add-image-button =\n .title = Add image\npdfjs-editor-stamp-add-image-button-label = Add image\npdfjs-editor-free-highlight-thickness-input = Thickness\npdfjs-editor-free-highlight-thickness-title =\n .title = Change thickness when highlighting items other than text\npdfjs-editor-add-signature-container =\n .aria-label = Signature controls and saved signatures\npdfjs-editor-signature-add-signature-button =\n .title = Add new signature\npdfjs-editor-signature-add-signature-button-label = Add new signature\npdfjs-editor-add-saved-signature-button =\n .title = Saved signature: { $description }\npdfjs-free-text2 =\n .aria-label = Text Editor\n .default-content = Start typing\u2026\npdfjs-editor-comments-sidebar-title =\n { $count ->\n [one] Comment\n *[other] Comments\n }\npdfjs-editor-comments-sidebar-close-button =\n .title = Close the sidebar\n .aria-label = Close the sidebar\npdfjs-editor-comments-sidebar-close-button-label = Close the sidebar\npdfjs-editor-comments-sidebar-no-comments1 = See something noteworthy? Highlight it and leave a comment.\npdfjs-editor-comments-sidebar-no-comments-link = Learn more\npdfjs-editor-alt-text-button =\n .aria-label = Alt text\npdfjs-editor-alt-text-button-label = Alt text\npdfjs-editor-alt-text-edit-button =\n .aria-label = Edit alt text\npdfjs-editor-alt-text-dialog-label = Choose an option\npdfjs-editor-alt-text-dialog-description = Alt text (alternative text) helps when people can\u2019t see the image or when it doesn\u2019t load.\npdfjs-editor-alt-text-add-description-label = Add a description\npdfjs-editor-alt-text-add-description-description = Aim for 1-2 sentences that describe the subject, setting, or actions.\npdfjs-editor-alt-text-mark-decorative-label = Mark as decorative\npdfjs-editor-alt-text-mark-decorative-description = This is used for ornamental images, like borders or watermarks.\npdfjs-editor-alt-text-cancel-button = Cancel\npdfjs-editor-alt-text-save-button = Save\npdfjs-editor-alt-text-decorative-tooltip = Marked as decorative\npdfjs-editor-alt-text-textarea =\n .placeholder = For example, \u201CA young man sits down at a table to eat a meal\u201D\npdfjs-editor-resizer-top-left =\n .aria-label = Top left corner \u2014 resize\npdfjs-editor-resizer-top-middle =\n .aria-label = Top middle \u2014 resize\npdfjs-editor-resizer-top-right =\n .aria-label = Top right corner \u2014 resize\npdfjs-editor-resizer-middle-right =\n .aria-label = Middle right \u2014 resize\npdfjs-editor-resizer-bottom-right =\n .aria-label = Bottom right corner \u2014 resize\npdfjs-editor-resizer-bottom-middle =\n .aria-label = Bottom middle \u2014 resize\npdfjs-editor-resizer-bottom-left =\n .aria-label = Bottom left corner \u2014 resize\npdfjs-editor-resizer-middle-left =\n .aria-label = Middle left \u2014 resize\npdfjs-editor-highlight-colorpicker-label = Highlight color\npdfjs-editor-colorpicker-button =\n .title = Change color\npdfjs-editor-colorpicker-dropdown =\n .aria-label = Color choices\npdfjs-editor-colorpicker-yellow =\n .title = Yellow\npdfjs-editor-colorpicker-green =\n .title = Green\npdfjs-editor-colorpicker-blue =\n .title = Blue\npdfjs-editor-colorpicker-pink =\n .title = Pink\npdfjs-editor-colorpicker-red =\n .title = Red\npdfjs-editor-highlight-show-all-button-label = Show all\npdfjs-editor-highlight-show-all-button =\n .title = Show all\npdfjs-editor-new-alt-text-dialog-edit-label = Edit alt text (image description)\npdfjs-editor-new-alt-text-dialog-add-label = Add alt text (image description)\npdfjs-editor-new-alt-text-textarea =\n .placeholder = Write your description here\u2026\npdfjs-editor-new-alt-text-description = Short description for people who can\u2019t see the image or when the image doesn\u2019t load.\npdfjs-editor-new-alt-text-disclaimer1 = This alt text was created automatically and may be inaccurate.\npdfjs-editor-new-alt-text-disclaimer-learn-more-url = Learn more\npdfjs-editor-new-alt-text-create-automatically-button-label = Create alt text automatically\npdfjs-editor-new-alt-text-not-now-button = Not now\npdfjs-editor-new-alt-text-error-title = Couldn\u2019t create alt text automatically\npdfjs-editor-new-alt-text-error-description = Please write your own alt text or try again later.\npdfjs-editor-new-alt-text-error-close-button = Close\npdfjs-editor-new-alt-text-ai-model-downloading-progress = Downloading alt text AI model ({ $downloadedSize } of { $totalSize } MB)\n .aria-valuetext = Downloading alt text AI model ({ $downloadedSize } of { $totalSize } MB)\npdfjs-editor-new-alt-text-added-button =\n .aria-label = Alt text added\npdfjs-editor-new-alt-text-added-button-label = Alt text added\npdfjs-editor-new-alt-text-missing-button =\n .aria-label = Missing alt text\npdfjs-editor-new-alt-text-missing-button-label = Missing alt text\npdfjs-editor-new-alt-text-to-review-button =\n .aria-label = Review alt text\npdfjs-editor-new-alt-text-to-review-button-label = Review alt text\npdfjs-editor-new-alt-text-generated-alt-text-with-disclaimer = Created automatically: { $generatedAltText }\npdfjs-image-alt-text-settings-button =\n .title = Image alt text settings\npdfjs-image-alt-text-settings-button-label = Image alt text settings\npdfjs-editor-alt-text-settings-dialog-label = Image alt text settings\npdfjs-editor-alt-text-settings-automatic-title = Automatic alt text\npdfjs-editor-alt-text-settings-create-model-button-label = Create alt text automatically\npdfjs-editor-alt-text-settings-create-model-description = Suggests descriptions to help people who can\u2019t see the image or when the image doesn\u2019t load.\npdfjs-editor-alt-text-settings-editor-title = Alt text editor\npdfjs-editor-alt-text-settings-show-dialog-button-label = Show alt text editor right away when adding an image\npdfjs-editor-alt-text-settings-show-dialog-description = Helps you make sure all your images have alt text.\npdfjs-editor-alt-text-settings-close-button = Close\npdfjs-editor-highlight-added-alert = Highlight added\npdfjs-editor-freetext-added-alert = Text added\npdfjs-editor-ink-added-alert = Drawing added\npdfjs-editor-stamp-added-alert = Image added\npdfjs-editor-signature-added-alert = Signature added\npdfjs-editor-undo-bar-message-highlight = Highlight removed\npdfjs-editor-undo-bar-message-freetext = Text removed\npdfjs-editor-undo-bar-message-ink = Drawing removed\npdfjs-editor-undo-bar-message-stamp = Image removed\npdfjs-editor-undo-bar-message-signature = Signature removed\npdfjs-editor-undo-bar-message-comment = Comment removed\npdfjs-editor-undo-bar-message-multiple =\n { $count ->\n [one] { $count } annotation removed\n *[other] { $count } annotations removed\n }\npdfjs-editor-undo-bar-undo-button =\n .title = Undo\npdfjs-editor-undo-bar-undo-button-label = Undo\npdfjs-editor-undo-bar-close-button =\n .title = Close\npdfjs-editor-undo-bar-close-button-label = Close\npdfjs-editor-add-signature-dialog-label = This modal allows the user to create a signature to add to a PDF document. The user can edit the name (which also serves as the alt text), and optionally save the signature for repeated use.\npdfjs-editor-add-signature-dialog-title = Add a signature\npdfjs-editor-add-signature-type-button = Type\n .title = Type\npdfjs-editor-add-signature-draw-button = Draw\n .title = Draw\npdfjs-editor-add-signature-image-button = Image\n .title = Image\npdfjs-editor-add-signature-type-input =\n .aria-label = Type your signature\n .placeholder = Type your signature\npdfjs-editor-add-signature-draw-placeholder = Draw your signature\npdfjs-editor-add-signature-draw-thickness-range-label = Thickness\npdfjs-editor-add-signature-draw-thickness-range =\n .title = Drawing thickness: { $thickness }\npdfjs-editor-add-signature-image-placeholder = Drag a file here to upload\npdfjs-editor-add-signature-image-browse-link =\n { PLATFORM() ->\n [macos] Or choose image files\n *[other] Or browse image files\n }\npdfjs-editor-add-signature-description-label = Description (alt text)\npdfjs-editor-add-signature-description-input =\n .title = Description (alt text)\npdfjs-editor-add-signature-description-default-when-drawing = Signature\npdfjs-editor-add-signature-clear-button-label = Clear signature\npdfjs-editor-add-signature-clear-button =\n .title = Clear signature\npdfjs-editor-add-signature-save-checkbox = Save signature\npdfjs-editor-add-signature-save-warning-message = You\u2019ve reached the limit of 5 saved signatures. Remove one to save more.\npdfjs-editor-add-signature-image-upload-error-title = Couldn\u2019t upload image\npdfjs-editor-add-signature-image-upload-error-description = Check your network connection or try another image.\npdfjs-editor-add-signature-image-no-data-error-title = Can\u2019t convert this image into a signature\npdfjs-editor-add-signature-image-no-data-error-description = Please try uploading a different image.\npdfjs-editor-add-signature-error-close-button = Close\npdfjs-editor-add-signature-cancel-button = Cancel\npdfjs-editor-add-signature-add-button = Add\npdfjs-editor-delete-signature-button1 =\n .title = Remove saved signature\npdfjs-editor-delete-signature-button-label1 = Remove saved signature\npdfjs-editor-add-signature-edit-button-label = Edit description\npdfjs-editor-edit-signature-dialog-title = Edit description\npdfjs-editor-edit-signature-update-button = Update\npdfjs-show-comment-button =\n .title = Show comment\npdfjs-editor-edit-comment-popup-button-label = Edit comment\npdfjs-editor-edit-comment-popup-button =\n .title = Edit comment\npdfjs-editor-delete-comment-popup-button-label = Remove comment\npdfjs-editor-delete-comment-popup-button =\n .title = Remove comment\npdfjs-editor-edit-comment-dialog-title-when-editing = Edit comment\npdfjs-editor-edit-comment-dialog-save-button-when-editing = Update\npdfjs-editor-edit-comment-dialog-title-when-adding = Add comment\npdfjs-editor-edit-comment-dialog-save-button-when-adding = Add\npdfjs-editor-edit-comment-dialog-text-input =\n .placeholder = Start typing\u2026\npdfjs-editor-edit-comment-dialog-cancel-button = Cancel\npdfjs-editor-add-comment-button =\n .title = Add comment\npdfjs-toggle-views-manager-button1 =\n .title = Manage pages\npdfjs-toggle-views-manager-notification-button =\n .title = Toggle Sidebar (document contains thumbnails/outline/attachments/layers)\npdfjs-toggle-views-manager-button1-label = Manage pages\npdfjs-views-manager-sidebar =\n .aria-label = Sidebar\npdfjs-views-manager-sidebar-resizer =\n .aria-label = Sidebar resizer\npdfjs-views-manager-view-selector-button =\n .title = Views\npdfjs-views-manager-view-selector-button-label = Views\npdfjs-views-manager-pages-title = Pages\npdfjs-views-manager-outlines-title = Document outline\npdfjs-views-manager-attachments-title = Attachments\npdfjs-views-manager-layers-title = Layers\npdfjs-views-manager-pages-option-label = Pages\npdfjs-views-manager-outlines-option-label = Document outline\npdfjs-views-manager-attachments-option-label = Attachments\npdfjs-views-manager-layers-option-label = Layers\npdfjs-views-manager-add-file-button =\n .title = Add file\npdfjs-views-manager-add-file-button-label = Add file\npdfjs-views-manager-pages-status-action-label =\n { $count ->\n [one] { $count } selected\n *[other] { $count } selected\n }\npdfjs-views-manager-pages-status-none-action-label = Select pages\npdfjs-views-manager-pages-status-action-button-label = Manage\npdfjs-views-manager-pages-status-copy-button-label = Copy\npdfjs-views-manager-pages-status-cut-button-label = Cut\npdfjs-views-manager-pages-status-delete-button-label = Delete\npdfjs-views-manager-pages-status-save-as-button-label = Save as\u2026\npdfjs-views-manager-status-undo-cut-label =\n { $count ->\n [one] 1 page cut\n *[other] { $count } pages cut\n }\npdfjs-views-manager-pages-status-undo-copy-label =\n { $count ->\n [one] 1 page copied\n *[other] { $count } pages copied\n }\npdfjs-views-manager-pages-status-undo-delete-label =\n { $count ->\n [one] 1 page deleted\n *[other] { $count } pages deleted\n }\npdfjs-views-manager-pages-status-waiting-ready-label = Getting your file ready\u2026\npdfjs-views-manager-pages-status-waiting-uploading-label = Uploading file\u2026\npdfjs-views-manager-status-warning-cut-label = Couldn\u2019t cut. Refresh page and try again.\npdfjs-views-manager-status-warning-copy-label = Couldn\u2019t copy. Refresh page and try again.\npdfjs-views-manager-status-warning-delete-label = Couldn\u2019t delete. Refresh page and try again.\npdfjs-views-manager-status-warning-save-label = Couldn\u2019t save. Refresh page and try again.\npdfjs-views-manager-status-undo-button-label = Undo\npdfjs-views-manager-status-close-button =\n .title = Close\npdfjs-views-manager-status-close-button-label = Close\npdfjs-views-manager-paste-button-label = Paste"; + return createBundle(lang, text); + } +} + +;// ./web/generic_scripting.js +/* unused harmony import specifier */ var generic_scripting_getPdfFilenameFromUrl; + +async function docProperties(pdfDocument) { + const url = "", + baseUrl = ""; + const { + info, + metadata, + contentDispositionFilename, + contentLength + } = await pdfDocument.getMetadata(); + return { + ...info, + baseURL: baseUrl, + filesize: contentLength || (await pdfDocument.getDownloadInfo()).length, + filename: contentDispositionFilename || generic_scripting_getPdfFilenameFromUrl(url), + metadata: metadata?.getRaw(), + authors: metadata?.get("dc:creator"), + numPages: pdfDocument.numPages, + URL: url + }; +} +class GenericScripting { + constructor(sandboxBundleSrc) { + this._ready = new Promise((resolve, reject) => { + const sandbox = import( + /*webpackIgnore: true*/ + /*@vite-ignore*/ + sandboxBundleSrc); + sandbox.then(pdfjsSandbox => { + resolve(pdfjsSandbox.QuickJSSandbox()); + }).catch(reject); + }); + } + async createSandbox(data) { + const sandbox = await this._ready; + sandbox.create(data); + } + async dispatchEventInSandbox(event) { + const sandbox = await this._ready; + setTimeout(() => sandbox.dispatchEvent(event), 0); + } + async destroySandbox() { + const sandbox = await this._ready; + sandbox.nukeSandbox(); + } +} + +;// ./web/generic_signature_storage.js + +const KEY_STORAGE = "pdfjs.signature"; +class SignatureStorage { + #eventBus; + #signatures = null; + #signal = null; + constructor(eventBus, signal) { + this.#eventBus = eventBus; + this.#signal = signal; + } + #save() { + localStorage.setItem(KEY_STORAGE, JSON.stringify(Object.fromEntries(this.#signatures))); + } + async getAll() { + if (this.#signal) { + window.addEventListener("storage", ({ + key + }) => { + if (key === KEY_STORAGE) { + this.#signatures = null; + this.#eventBus?.dispatch("storedsignatureschanged", { + source: this + }); + } + }, { + signal: this.#signal + }); + this.#signal = null; + } + if (!this.#signatures) { + this.#signatures = new Map(); + const data = localStorage.getItem(KEY_STORAGE); + if (data) { + for (const [key, value] of Object.entries(JSON.parse(data))) { + this.#signatures.set(key, value); + } + } + } + return this.#signatures; + } + async isFull() { + return (await this.size()) === 5; + } + async size() { + return (await this.getAll()).size; + } + async create(data) { + if (await this.isFull()) { + return null; + } + const uuid = getUuid(); + this.#signatures.set(uuid, data); + this.#save(); + return uuid; + } + async delete(uuid) { + const signatures = await this.getAll(); + if (!signatures.has(uuid)) { + return false; + } + signatures.delete(uuid); + this.#save(); + return true; + } +} + +;// ./web/genericcom.js + + + + + + +function initCom(app) {} +class Preferences extends BasePreferences { + async _writeToStorage(prefObj) { + localStorage.setItem("pdfjs.preferences", JSON.stringify(prefObj)); + } + async _readFromStorage(prefObj) { + return { + prefs: JSON.parse(localStorage.getItem("pdfjs.preferences")) + }; + } +} +class ExternalServices extends BaseExternalServices { + async createL10n() { + return new genericl10n_GenericL10n(AppOptions.get("localeProperties")?.lang); + } + createScripting() { + return new GenericScripting(AppOptions.get("sandboxBundleSrc")); + } + createSignatureStorage(eventBus, signal) { + return new SignatureStorage(eventBus, signal); + } +} +class MLManager { + async isEnabledFor(_name) { + return false; + } + async deleteModel(_service) { + return null; + } + isReady(_name) { + return false; + } + guess(_data) {} + toggleService(_name, _enabled) {} +} + +;// ./web/new_alt_text_manager.js + +class NewAltTextManager { + #boundCancel = this.#cancel.bind(this); + #createAutomaticallyButton; + #currentEditor = null; + #cancelButton; + #descriptionContainer; + #dialog; + #disclaimer; + #downloadModel; + #downloadModelDescription; + #eventBus; + #firstTime = false; + #guessedAltText; + #hasAI = null; + #isEditing = null; + #imagePreview; + #imageData; + #isAILoading = false; + #wasAILoading = false; + #learnMore; + #notNowButton; + #overlayManager; + #textarea; + #title; + #uiManager; + #previousAltText = null; + constructor({ + descriptionContainer, + dialog, + imagePreview, + cancelButton, + disclaimer, + notNowButton, + saveButton, + textarea, + learnMore, + errorCloseButton, + createAutomaticallyButton, + downloadModel, + downloadModelDescription, + title + }, overlayManager, eventBus) { + this.#cancelButton = cancelButton; + this.#createAutomaticallyButton = createAutomaticallyButton; + this.#descriptionContainer = descriptionContainer; + this.#dialog = dialog; + this.#disclaimer = disclaimer; + this.#notNowButton = notNowButton; + this.#imagePreview = imagePreview; + this.#textarea = textarea; + this.#learnMore = learnMore; + this.#title = title; + this.#downloadModel = downloadModel; + this.#downloadModelDescription = downloadModelDescription; + this.#overlayManager = overlayManager; + this.#eventBus = eventBus; + dialog.addEventListener("close", this.#close.bind(this)); + dialog.addEventListener("contextmenu", event => { + if (event.target !== this.#textarea) { + event.preventDefault(); + } + }); + cancelButton.addEventListener("click", this.#boundCancel); + notNowButton.addEventListener("click", this.#boundCancel); + saveButton.addEventListener("click", this.#save.bind(this)); + errorCloseButton.addEventListener("click", () => { + this.#toggleError(false); + }); + createAutomaticallyButton.addEventListener("click", async () => { + const checked = createAutomaticallyButton.getAttribute("aria-pressed") !== "true"; + this.#currentEditor._reportTelemetry({ + action: "pdfjs.image.alt_text.ai_generation_check", + data: { + status: checked + } + }); + if (this.#uiManager) { + const isAltTextEnabled = await this.#uiManager.mlManager.isEnabledFor("altText"); + this.#createAutomaticallyButton.disabled = true; + if (checked && !isAltTextEnabled) { + this.#textarea.value = ""; + this.#setProgress(); + this.#uiManager.setPreference("enableGuessAltText", true); + await this.#uiManager.mlManager.downloadModel("altText"); + this.#setPref("enableAltTextModelDownload", true); + } else if (!checked && isAltTextEnabled) { + this.#uiManager.setPreference("enableGuessAltText", false); + await this.#uiManager.mlManager.deleteModel("altText"); + this.#setPref("enableAltTextModelDownload", false); + } + this.#createAutomaticallyButton.disabled = false; + await this.#uiManager.mlManager.toggleService("altText", checked); + } + this.#toggleGuessAltText(checked, false); + }); + textarea.addEventListener("focus", () => { + this.#wasAILoading = this.#isAILoading; + this.#toggleLoading(false); + this.#toggleTitleAndDisclaimer(); + }); + textarea.addEventListener("blur", () => { + if (!textarea.value) { + this.#toggleLoading(this.#wasAILoading); + } + this.#toggleTitleAndDisclaimer(); + }); + textarea.addEventListener("input", () => { + this.#toggleTitleAndDisclaimer(); + }); + textarea.addEventListener("keydown", e => { + if ((e.ctrlKey || e.metaKey) && e.key === "Enter" && !saveButton.disabled) { + this.#save(); + } + }); + eventBus._on("enableguessalttext", ({ + value + }) => { + this.#toggleGuessAltText(value, false); + }); + this.#overlayManager.register(dialog); + this.#learnMore.addEventListener("click", () => { + this.#currentEditor._reportTelemetry({ + action: "pdfjs.image.alt_text.info", + data: { + topic: "alt_text" + } + }); + }); + } + #setPref(name, value) { + this.#eventBus.dispatch("setpreference", { + source: this, + name, + value + }); + } + #toggleLoading(value) { + if (!this.#uiManager || this.#isAILoading === value) { + return; + } + this.#isAILoading = value; + this.#descriptionContainer.classList.toggle("loading", value); + } + #toggleError(value) { + if (!this.#uiManager) { + return; + } + this.#dialog.classList.toggle("error", value); + } + async #toggleGuessAltText(value, isInitial) { + if (!this.#uiManager) { + return; + } + this.#dialog.classList.toggle("aiDisabled", !value); + this.#createAutomaticallyButton.setAttribute("aria-pressed", value); + if (value) { + const { + altTextLearnMoreUrl + } = this.#uiManager.mlManager; + if (altTextLearnMoreUrl) { + this.#learnMore.href = altTextLearnMoreUrl; + } + this.#mlGuessAltText(isInitial); + } else { + this.#toggleLoading(false); + this.#isAILoading = false; + this.#toggleTitleAndDisclaimer(); + } + } + #toggleNotNow() { + this.#notNowButton.classList.toggle("hidden", !this.#firstTime); + this.#cancelButton.classList.toggle("hidden", this.#firstTime); + } + #toggleAI(value) { + if (!this.#uiManager || this.#hasAI === value) { + return; + } + this.#hasAI = value; + this.#dialog.classList.toggle("noAi", !value); + this.#toggleTitleAndDisclaimer(); + } + #toggleTitleAndDisclaimer() { + const visible = this.#isAILoading || this.#guessedAltText && this.#guessedAltText === this.#textarea.value; + this.#disclaimer.hidden = !visible; + const isEditing = this.#isAILoading || !!this.#textarea.value; + if (this.#isEditing === isEditing) { + return; + } + this.#isEditing = isEditing; + this.#title.setAttribute("data-l10n-id", isEditing ? "pdfjs-editor-new-alt-text-dialog-edit-label" : "pdfjs-editor-new-alt-text-dialog-add-label"); + } + async #mlGuessAltText(isInitial) { + if (this.#isAILoading) { + return; + } + if (this.#textarea.value) { + return; + } + if (isInitial && this.#previousAltText !== null) { + return; + } + this.#guessedAltText = this.#currentEditor.guessedAltText; + if (this.#previousAltText === null && this.#guessedAltText) { + this.#addAltText(this.#guessedAltText); + return; + } + this.#toggleLoading(true); + this.#toggleTitleAndDisclaimer(); + let hasError = false; + try { + const altText = await this.#currentEditor.mlGuessAltText(this.#imageData, false); + if (altText) { + this.#guessedAltText = altText; + this.#wasAILoading = this.#isAILoading; + if (this.#isAILoading) { + this.#addAltText(altText); + } + } + } catch (e) { + console.error(e); + hasError = true; + } + this.#toggleLoading(false); + this.#toggleTitleAndDisclaimer(); + if (hasError && this.#uiManager) { + this.#toggleError(true); + } + } + #addAltText(altText) { + if (!this.#uiManager || this.#textarea.value) { + return; + } + this.#textarea.value = altText; + this.#toggleTitleAndDisclaimer(); + } + #setProgress() { + this.#downloadModel.classList.toggle("hidden", false); + const callback = async ({ + detail: { + finished, + total, + totalLoaded + } + }) => { + const ONE_MEGA_BYTES = 1e6; + totalLoaded = Math.min(0.99 * total, totalLoaded); + const totalSize = this.#downloadModelDescription.ariaValueMax = Math.round(total / ONE_MEGA_BYTES); + const downloadedSize = this.#downloadModelDescription.ariaValueNow = Math.round(totalLoaded / ONE_MEGA_BYTES); + this.#downloadModelDescription.setAttribute("data-l10n-args", JSON.stringify({ + totalSize, + downloadedSize + })); + if (!finished) { + return; + } + this.#eventBus._off("loadaiengineprogress", callback); + this.#downloadModel.classList.toggle("hidden", true); + this.#toggleAI(true); + if (!this.#uiManager) { + return; + } + const { + mlManager + } = this.#uiManager; + mlManager.toggleService("altText", true); + this.#toggleGuessAltText(await mlManager.isEnabledFor("altText"), true); + }; + this.#eventBus._on("loadaiengineprogress", callback); + } + async editAltText(uiManager, editor, firstTime) { + if (this.#currentEditor || !editor) { + return; + } + if (firstTime && editor.hasAltTextData()) { + editor.altTextFinish(); + return; + } + this.#firstTime = firstTime; + const { + mlManager + } = uiManager; + const hasAI = !!mlManager; + this.#toggleTitleAndDisclaimer(); + if (mlManager && !mlManager.isReady("altText")) { + if (mlManager.hasProgress) { + this.#setProgress(); + } else { + this.#createAutomaticallyButton.setAttribute("aria-pressed", false); + } + } else { + this.#downloadModel.classList.toggle("hidden", true); + } + const isAltTextEnabledPromise = mlManager?.isEnabledFor("altText"); + this.#currentEditor = editor; + this.#uiManager = uiManager; + this.#uiManager.removeEditListeners(); + ({ + altText: this.#previousAltText + } = editor.altTextData); + this.#textarea.value = this.#previousAltText ?? ""; + const AI_MAX_IMAGE_DIMENSION = 224; + const MAX_PREVIEW_DIMENSION = 180; + let canvas, width, height; + if (mlManager) { + ({ + canvas, + width, + height, + imageData: this.#imageData + } = editor.copyCanvas(AI_MAX_IMAGE_DIMENSION, MAX_PREVIEW_DIMENSION, true)); + if (hasAI) { + this.#toggleGuessAltText(await isAltTextEnabledPromise, true); + } + } else { + ({ + canvas, + width, + height + } = editor.copyCanvas(AI_MAX_IMAGE_DIMENSION, MAX_PREVIEW_DIMENSION, false)); + } + canvas.setAttribute("role", "presentation"); + const { + style + } = canvas; + style.width = `${width}px`; + style.height = `${height}px`; + this.#imagePreview.append(canvas); + this.#toggleNotNow(); + this.#toggleAI(hasAI); + this.#toggleError(false); + try { + await this.#overlayManager.open(this.#dialog); + } catch (ex) { + this.#close(); + throw ex; + } + } + #cancel() { + this.#currentEditor.altTextData = { + cancel: true + }; + const altText = this.#textarea.value.trim(); + this.#currentEditor._reportTelemetry({ + action: "pdfjs.image.alt_text.dismiss", + data: { + alt_text_type: altText ? "present" : "empty", + flow: this.#firstTime ? "image_add" : "alt_text_edit" + } + }); + this.#currentEditor._reportTelemetry({ + action: "pdfjs.image.image_added", + data: { + alt_text_modal: true, + alt_text_type: "skipped" + } + }); + this.#finish(); + } + #finish() { + this.#overlayManager.closeIfActive(this.#dialog); + } + #close() { + const canvas = this.#imagePreview.firstElementChild; + canvas.remove(); + canvas.width = canvas.height = 0; + this.#imageData = null; + this.#toggleLoading(false); + this.#uiManager?.addEditListeners(); + this.#currentEditor.altTextFinish(); + this.#uiManager?.setSelected(this.#currentEditor); + this.#currentEditor = null; + this.#uiManager = null; + } + #extractWords(text) { + return new Set(text.toLowerCase().split(/[^\p{L}\p{N}]+/gu).filter(x => !!x)); + } + #save() { + const altText = this.#textarea.value.trim(); + this.#currentEditor.altTextData = { + altText, + decorative: false + }; + this.#currentEditor.altTextData.guessedAltText = this.#guessedAltText; + if (this.#guessedAltText && this.#guessedAltText !== altText) { + const guessedWords = this.#extractWords(this.#guessedAltText); + const words = this.#extractWords(altText); + this.#currentEditor._reportTelemetry({ + action: "pdfjs.image.alt_text.user_edit", + data: { + total_words: guessedWords.size, + words_removed: guessedWords.difference(words).size, + words_added: words.difference(guessedWords).size + } + }); + } + this.#currentEditor._reportTelemetry({ + action: "pdfjs.image.image_added", + data: { + alt_text_modal: true, + alt_text_type: altText ? "present" : "empty" + } + }); + this.#currentEditor._reportTelemetry({ + action: "pdfjs.image.alt_text.save", + data: { + alt_text_type: altText ? "present" : "empty", + flow: this.#firstTime ? "image_add" : "alt_text_edit" + } + }); + this.#finish(); + } + destroy() { + this.#uiManager = null; + this.#finish(); + } +} +class ImageAltTextSettings { + #createModelButton; + #dialog; + #eventBus; + #mlManager; + #overlayManager; + #showAltTextDialogButton; + constructor({ + dialog, + createModelButton, + learnMore, + closeButton, + showAltTextDialogButton + }, overlayManager, eventBus, mlManager) { + this.#dialog = dialog; + this.#createModelButton = createModelButton; + this.#showAltTextDialogButton = showAltTextDialogButton; + this.#overlayManager = overlayManager; + this.#eventBus = eventBus; + this.#mlManager = mlManager; + const { + altTextLearnMoreUrl + } = mlManager; + if (altTextLearnMoreUrl) { + learnMore.href = altTextLearnMoreUrl; + } + dialog.addEventListener("contextmenu", noContextMenu); + createModelButton.addEventListener("click", async e => { + const checked = this.#togglePref("enableGuessAltText", e); + await (checked ? this.#download(true) : this.#delete(true)); + await mlManager.toggleService("altText", checked); + this.#reportTelemetry({ + type: "stamp", + action: "pdfjs.image.alt_text.settings_ai_generation_check", + data: { + status: checked + } + }); + }); + showAltTextDialogButton.addEventListener("click", e => { + const checked = this.#togglePref("enableNewAltTextWhenAddingImage", e); + this.#reportTelemetry({ + type: "stamp", + action: "pdfjs.image.alt_text.settings_edit_alt_text_check", + data: { + status: checked + } + }); + }); + closeButton.addEventListener("click", this.#finish.bind(this)); + learnMore.addEventListener("click", () => { + this.#reportTelemetry({ + type: "stamp", + action: "pdfjs.image.alt_text.info", + data: { + topic: "ai_generation" + } + }); + }); + eventBus._on("enablealttextmodeldownload", ({ + value + }) => { + if (value) { + this.#download(false); + } else { + this.#delete(false); + } + }); + this.#overlayManager.register(dialog); + } + #reportTelemetry(data) { + this.#eventBus.dispatch("reporttelemetry", { + source: this, + details: { + type: "editing", + data + } + }); + } + async #download(isFromUI = false) { + if (isFromUI) { + await this.#mlManager.downloadModel("altText"); + this.#setPref("enableGuessAltText", true); + this.#mlManager.toggleService("altText", true); + this.#setPref("enableAltTextModelDownload", true); + } + } + async #delete(isFromUI = false) { + if (isFromUI) { + await this.#mlManager.deleteModel("altText"); + this.#setPref("enableGuessAltText", false); + this.#setPref("enableAltTextModelDownload", false); + } + this.#createModelButton.setAttribute("aria-pressed", false); + } + async open({ + enableGuessAltText, + enableNewAltTextWhenAddingImage + }) { + const { + enableAltTextModelDownload + } = this.#mlManager; + this.#createModelButton.setAttribute("aria-pressed", enableAltTextModelDownload && enableGuessAltText); + this.#showAltTextDialogButton.setAttribute("aria-pressed", enableNewAltTextWhenAddingImage); + await this.#overlayManager.open(this.#dialog); + this.#reportTelemetry({ + type: "stamp", + action: "pdfjs.image.alt_text.settings_displayed" + }); + } + #togglePref(name, { + target + }) { + const checked = target.getAttribute("aria-pressed") !== "true"; + this.#setPref(name, checked); + target.setAttribute("aria-pressed", checked); + return checked; + } + #setPref(name, value) { + this.#eventBus.dispatch("setpreference", { + source: this, + name, + value + }); + } + #finish() { + this.#overlayManager.closeIfActive(this.#dialog); + } +} + +;// ./web/alt_text_manager.js + +class AltTextManager { + #clickAC = null; + #currentEditor = null; + #cancelButton; + #dialog; + #eventBus; + #hasUsedPointer = false; + #optionDescription; + #optionDecorative; + #overlayManager; + #saveButton; + #textarea; + #uiManager; + #previousAltText = null; + #resizeAC = null; + #svgElement = null; + #rectElement = null; + #container; + #telemetryData = null; + constructor({ + dialog, + optionDescription, + optionDecorative, + textarea, + cancelButton, + saveButton + }, container, overlayManager, eventBus) { + this.#dialog = dialog; + this.#optionDescription = optionDescription; + this.#optionDecorative = optionDecorative; + this.#textarea = textarea; + this.#cancelButton = cancelButton; + this.#saveButton = saveButton; + this.#overlayManager = overlayManager; + this.#eventBus = eventBus; + this.#container = container; + const onUpdateUIState = this.#updateUIState.bind(this); + dialog.addEventListener("close", this.#close.bind(this)); + dialog.addEventListener("contextmenu", event => { + if (event.target !== this.#textarea) { + event.preventDefault(); + } + }); + cancelButton.addEventListener("click", this.#finish.bind(this)); + saveButton.addEventListener("click", this.#save.bind(this)); + optionDescription.addEventListener("change", onUpdateUIState); + optionDecorative.addEventListener("change", onUpdateUIState); + textarea.addEventListener("keydown", e => { + if ((e.ctrlKey || e.metaKey) && e.key === "Enter" && !saveButton.disabled) { + this.#save(); + } + }); + this.#overlayManager.register(dialog); + } + #createSVGElement() { + if (this.#svgElement) { + return; + } + const svgFactory = new DOMSVGFactory(); + const svg = this.#svgElement = svgFactory.createElement("svg"); + svg.setAttribute("width", "0"); + svg.setAttribute("height", "0"); + const defs = svgFactory.createElement("defs"); + svg.append(defs); + const mask = svgFactory.createElement("mask"); + defs.append(mask); + mask.setAttribute("id", "alttext-manager-mask"); + mask.setAttribute("maskContentUnits", "objectBoundingBox"); + let rect = svgFactory.createElement("rect"); + mask.append(rect); + rect.setAttribute("fill", "white"); + rect.setAttribute("width", "1"); + rect.setAttribute("height", "1"); + rect.setAttribute("x", "0"); + rect.setAttribute("y", "0"); + rect = this.#rectElement = svgFactory.createElement("rect"); + mask.append(rect); + rect.setAttribute("fill", "black"); + this.#dialog.append(svg); + } + async editAltText(uiManager, editor) { + if (this.#currentEditor || !editor) { + return; + } + this.#createSVGElement(); + this.#hasUsedPointer = false; + this.#clickAC = new AbortController(); + const clickOpts = { + signal: this.#clickAC.signal + }, + onClick = this.#onClick.bind(this); + for (const element of [this.#optionDescription, this.#optionDecorative, this.#textarea, this.#saveButton, this.#cancelButton]) { + element.addEventListener("click", onClick, clickOpts); + } + const { + altText, + decorative + } = editor.altTextData; + if (decorative === true) { + this.#optionDecorative.checked = true; + this.#optionDescription.checked = false; + } else { + this.#optionDecorative.checked = false; + this.#optionDescription.checked = true; + } + this.#previousAltText = this.#textarea.value = altText?.trim() || ""; + this.#updateUIState(); + this.#currentEditor = editor; + this.#uiManager = uiManager; + this.#uiManager.removeEditListeners(); + this.#resizeAC = new AbortController(); + this.#eventBus._on("resize", this.#setPosition.bind(this), { + signal: this.#resizeAC.signal + }); + try { + await this.#overlayManager.open(this.#dialog); + this.#setPosition(); + } catch (ex) { + this.#close(); + throw ex; + } + } + #setPosition() { + if (!this.#currentEditor) { + return; + } + const dialog = this.#dialog; + const { + style + } = dialog; + const { + x: containerX, + y: containerY, + width: containerW, + height: containerH + } = this.#container.getBoundingClientRect(); + const { + innerWidth: windowW, + innerHeight: windowH + } = window; + const { + width: dialogW, + height: dialogH + } = dialog.getBoundingClientRect(); + const { + x, + y, + width, + height + } = this.#currentEditor.getClientDimensions(); + const MARGIN = 10; + const isLTR = this.#uiManager.direction === "ltr"; + const xs = Math.max(x, containerX); + const xe = Math.min(x + width, containerX + containerW); + const ys = Math.max(y, containerY); + const ye = Math.min(y + height, containerY + containerH); + this.#rectElement.setAttribute("width", `${(xe - xs) / windowW}`); + this.#rectElement.setAttribute("height", `${(ye - ys) / windowH}`); + this.#rectElement.setAttribute("x", `${xs / windowW}`); + this.#rectElement.setAttribute("y", `${ys / windowH}`); + let left = null; + let top = Math.max(y, 0); + top += Math.min(windowH - (top + dialogH), 0); + if (isLTR) { + if (x + width + MARGIN + dialogW < windowW) { + left = x + width + MARGIN; + } else if (x > dialogW + MARGIN) { + left = x - dialogW - MARGIN; + } + } else if (x > dialogW + MARGIN) { + left = x - dialogW - MARGIN; + } else if (x + width + MARGIN + dialogW < windowW) { + left = x + width + MARGIN; + } + if (left === null) { + top = null; + left = Math.max(x, 0); + left += Math.min(windowW - (left + dialogW), 0); + if (y > dialogH + MARGIN) { + top = y - dialogH - MARGIN; + } else if (y + height + MARGIN + dialogH < windowH) { + top = y + height + MARGIN; + } + } + if (top !== null) { + dialog.classList.add("positioned"); + if (isLTR) { + style.left = `${left}px`; + } else { + style.right = `${windowW - left - dialogW}px`; + } + style.top = `${top}px`; + } else { + dialog.classList.remove("positioned"); + style.left = ""; + style.top = ""; + } + } + #finish() { + this.#overlayManager.closeIfActive(this.#dialog); + } + #close() { + this.#currentEditor._reportTelemetry(this.#telemetryData || { + action: "alt_text_cancel", + alt_text_keyboard: !this.#hasUsedPointer + }); + this.#telemetryData = null; + this.#removeOnClickListeners(); + this.#uiManager?.addEditListeners(); + this.#resizeAC?.abort(); + this.#resizeAC = null; + this.#currentEditor.altTextFinish(); + this.#currentEditor = null; + this.#uiManager = null; + } + #updateUIState() { + this.#textarea.disabled = this.#optionDecorative.checked; + } + #save() { + const altText = this.#textarea.value.trim(); + const decorative = this.#optionDecorative.checked; + this.#currentEditor.altTextData = { + altText, + decorative + }; + this.#telemetryData = { + action: "alt_text_save", + alt_text_description: !!altText, + alt_text_edit: !!this.#previousAltText && this.#previousAltText !== altText, + alt_text_decorative: decorative, + alt_text_keyboard: !this.#hasUsedPointer + }; + this.#finish(); + } + #onClick(evt) { + if (evt.detail === 0) { + return; + } + this.#hasUsedPointer = true; + this.#removeOnClickListeners(); + } + #removeOnClickListeners() { + this.#clickAC?.abort(); + this.#clickAC = null; + } + destroy() { + this.#uiManager = null; + this.#finish(); + this.#svgElement?.remove(); + this.#svgElement = this.#rectElement = null; + } +} + +;// ./web/annotation_editor_params.js + +class AnnotationEditorParams { + constructor(options, eventBus) { + this.eventBus = eventBus; + this.#bindListeners(options); + } + #bindListeners({ + editorFreeTextFontSize, + editorFreeTextColor, + editorInkColor, + editorInkThickness, + editorInkOpacity, + editorStampAddImage, + editorFreeHighlightThickness, + editorHighlightShowAll, + editorSignatureAddSignature + }) { + const { + eventBus + } = this; + const dispatchEvent = (typeStr, value) => { + eventBus.dispatch("switchannotationeditorparams", { + source: this, + type: AnnotationEditorParamsType[typeStr], + value + }); + }; + editorFreeTextFontSize.addEventListener("input", function () { + dispatchEvent("FREETEXT_SIZE", this.valueAsNumber); + }); + editorFreeTextColor.addEventListener("input", function () { + dispatchEvent("FREETEXT_COLOR", this.value); + }); + editorInkColor.addEventListener("input", function () { + dispatchEvent("INK_COLOR", this.value); + }); + editorInkThickness.addEventListener("input", function () { + dispatchEvent("INK_THICKNESS", this.valueAsNumber); + }); + editorInkOpacity.addEventListener("input", function () { + dispatchEvent("INK_OPACITY", this.valueAsNumber); + }); + editorStampAddImage.addEventListener("click", () => { + eventBus.dispatch("reporttelemetry", { + source: this, + details: { + type: "editing", + data: { + action: "pdfjs.image.add_image_click" + } + } + }); + dispatchEvent("CREATE"); + }); + editorFreeHighlightThickness.addEventListener("input", function () { + dispatchEvent("HIGHLIGHT_THICKNESS", this.valueAsNumber); + }); + editorHighlightShowAll.addEventListener("click", function () { + const checked = this.getAttribute("aria-pressed") === "true"; + this.setAttribute("aria-pressed", !checked); + dispatchEvent("HIGHLIGHT_SHOW_ALL", !checked); + }); + editorSignatureAddSignature.addEventListener("click", () => { + dispatchEvent("CREATE"); + }); + eventBus._on("annotationeditorparamschanged", evt => { + for (const [type, value] of evt.details) { + switch (type) { + case AnnotationEditorParamsType.FREETEXT_SIZE: + editorFreeTextFontSize.value = value; + break; + case AnnotationEditorParamsType.FREETEXT_COLOR: + editorFreeTextColor.value = value; + break; + case AnnotationEditorParamsType.INK_COLOR: + editorInkColor.value = value; + break; + case AnnotationEditorParamsType.INK_THICKNESS: + editorInkThickness.value = value; + break; + case AnnotationEditorParamsType.INK_OPACITY: + editorInkOpacity.value = value; + break; + case AnnotationEditorParamsType.HIGHLIGHT_COLOR: + eventBus.dispatch("mainhighlightcolorpickerupdatecolor", { + source: this, + value + }); + break; + case AnnotationEditorParamsType.HIGHLIGHT_THICKNESS: + editorFreeHighlightThickness.value = value; + break; + case AnnotationEditorParamsType.HIGHLIGHT_FREE: + editorFreeHighlightThickness.disabled = !value; + break; + case AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL: + editorHighlightShowAll.setAttribute("aria-pressed", value); + break; + } + } + }); + } +} + +;// ./web/caret_browsing.js +const PRECISION = 1e-1; +class CaretBrowsingMode { + #mainContainer; + #toolBarHeight = 0; + #viewerContainer; + constructor(abortSignal, mainContainer, viewerContainer, toolbarContainer) { + this.#mainContainer = mainContainer; + this.#viewerContainer = viewerContainer; + if (!toolbarContainer) { + return; + } + this.#toolBarHeight = toolbarContainer.getBoundingClientRect().height; + const toolbarObserver = new ResizeObserver(entries => { + for (const entry of entries) { + if (entry.target === toolbarContainer) { + this.#toolBarHeight = Math.floor(entry.borderBoxSize[0].blockSize); + break; + } + } + }); + toolbarObserver.observe(toolbarContainer); + abortSignal.addEventListener("abort", () => toolbarObserver.disconnect(), { + once: true + }); + } + #isOnSameLine(rect1, rect2) { + const top1 = rect1.y; + const bot1 = rect1.bottom; + const mid1 = rect1.y + rect1.height / 2; + const top2 = rect2.y; + const bot2 = rect2.bottom; + const mid2 = rect2.y + rect2.height / 2; + return top1 <= mid2 && mid2 <= bot1 || top2 <= mid1 && mid1 <= bot2; + } + #isUnderOver(rect, x, y, isUp) { + const midY = rect.y + rect.height / 2; + return (isUp ? y >= midY : y <= midY) && rect.x - PRECISION <= x && x <= rect.right + PRECISION; + } + #isVisible(rect) { + return rect.top >= this.#toolBarHeight && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth); + } + #getCaretPosition(selection, isUp) { + const { + focusNode, + focusOffset + } = selection; + const range = document.createRange(); + range.setStart(focusNode, focusOffset); + range.setEnd(focusNode, focusOffset); + const rect = range.getBoundingClientRect(); + return [rect.x, isUp ? rect.top : rect.bottom]; + } + static #caretPositionFromPoint(x, y) { + if (!document.caretPositionFromPoint) { + const { + startContainer: offsetNode, + startOffset: offset + } = document.caretRangeFromPoint(x, y); + return { + offsetNode, + offset + }; + } + return document.caretPositionFromPoint(x, y); + } + #setCaretPositionHelper(selection, caretX, select, element, rect) { + rect ||= element.getBoundingClientRect(); + if (caretX <= rect.x + PRECISION) { + if (select) { + selection.extend(element.firstChild, 0); + } else { + selection.setPosition(element.firstChild, 0); + } + return; + } + if (rect.right - PRECISION <= caretX) { + const { + lastChild + } = element; + if (select) { + selection.extend(lastChild, lastChild.length); + } else { + selection.setPosition(lastChild, lastChild.length); + } + return; + } + const midY = rect.y + rect.height / 2; + let caretPosition = CaretBrowsingMode.#caretPositionFromPoint(caretX, midY); + let parentElement = caretPosition.offsetNode?.parentElement; + if (parentElement && parentElement !== element) { + const elementsAtPoint = document.elementsFromPoint(caretX, midY); + const savedVisibilities = []; + for (const el of elementsAtPoint) { + if (el === element) { + break; + } + const { + style + } = el; + savedVisibilities.push([el, style.visibility]); + style.visibility = "hidden"; + } + caretPosition = CaretBrowsingMode.#caretPositionFromPoint(caretX, midY); + parentElement = caretPosition.offsetNode?.parentElement; + for (const [el, visibility] of savedVisibilities) { + el.style.visibility = visibility; + } + } + if (parentElement !== element) { + if (select) { + selection.extend(element.firstChild, 0); + } else { + selection.setPosition(element.firstChild, 0); + } + return; + } + if (select) { + selection.extend(caretPosition.offsetNode, caretPosition.offset); + } else { + selection.setPosition(caretPosition.offsetNode, caretPosition.offset); + } + } + #setCaretPosition(select, selection, newLineElement, newLineElementRect, caretX) { + if (this.#isVisible(newLineElementRect)) { + this.#setCaretPositionHelper(selection, caretX, select, newLineElement, newLineElementRect); + return; + } + this.#mainContainer.addEventListener("scrollend", this.#setCaretPositionHelper.bind(this, selection, caretX, select, newLineElement, null), { + once: true + }); + newLineElement.scrollIntoView(); + } + #getNodeOnNextPage(textLayer, isUp) { + while (true) { + const page = textLayer.closest(".page"); + const pageNumber = parseInt(page.getAttribute("data-page-number")); + const nextPage = isUp ? pageNumber - 1 : pageNumber + 1; + textLayer = this.#viewerContainer.querySelector(`.page[data-page-number="${nextPage}"] .textLayer`); + if (!textLayer) { + return null; + } + const walker = document.createTreeWalker(textLayer, NodeFilter.SHOW_TEXT); + const node = isUp ? walker.lastChild() : walker.firstChild(); + if (node) { + return node; + } + } + } + moveCaret(isUp, select) { + const selection = document.getSelection(); + if (selection.rangeCount === 0) { + return; + } + const { + focusNode + } = selection; + const focusElement = focusNode.nodeType !== Node.ELEMENT_NODE ? focusNode.parentElement : focusNode; + const root = focusElement.closest(".textLayer"); + if (!root) { + return; + } + const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT); + walker.currentNode = focusNode; + const focusRect = focusElement.getBoundingClientRect(); + let newLineElement = null; + const nodeIterator = (isUp ? walker.previousSibling : walker.nextSibling).bind(walker); + while (nodeIterator()) { + const element = walker.currentNode.parentElement; + if (!this.#isOnSameLine(focusRect, element.getBoundingClientRect())) { + newLineElement = element; + break; + } + } + if (!newLineElement) { + const node = this.#getNodeOnNextPage(root, isUp); + if (!node) { + return; + } + if (select) { + const lastNode = (isUp ? walker.firstChild() : walker.lastChild()) || focusNode; + selection.extend(lastNode, isUp ? 0 : lastNode.length); + const range = document.createRange(); + range.setStart(node, isUp ? node.length : 0); + range.setEnd(node, isUp ? node.length : 0); + selection.addRange(range); + return; + } + const [caretX] = this.#getCaretPosition(selection, isUp); + const { + parentElement + } = node; + this.#setCaretPosition(select, selection, parentElement, parentElement.getBoundingClientRect(), caretX); + return; + } + const [caretX, caretY] = this.#getCaretPosition(selection, isUp); + const newLineElementRect = newLineElement.getBoundingClientRect(); + if (this.#isUnderOver(newLineElementRect, caretX, caretY, isUp)) { + this.#setCaretPosition(select, selection, newLineElement, newLineElementRect, caretX); + return; + } + while (nodeIterator()) { + const element = walker.currentNode.parentElement; + const elementRect = element.getBoundingClientRect(); + if (!this.#isOnSameLine(newLineElementRect, elementRect)) { + break; + } + if (this.#isUnderOver(elementRect, caretX, caretY, isUp)) { + this.#setCaretPosition(select, selection, element, elementRect, caretX); + return; + } + } + this.#setCaretPosition(select, selection, newLineElement, newLineElementRect, caretX); + } +} + +;// ./web/sidebar.js + +const RESIZE_TIMEOUT = 400; +class Sidebar { + #initialWidth = 0; + #width = 0; + #coefficient; + #resizeTimeout = null; + #resizer; + #isResizerOnTheLeft; + #isKeyboardResizing = false; + #resizeObserver; + #prevX = 0; + constructor({ + sidebar, + resizer, + toggleButton + }, ltr, isResizerOnTheLeft) { + this._sidebar = sidebar; + this.#coefficient = ltr === isResizerOnTheLeft ? -1 : 1; + this.#resizer = resizer; + this.#isResizerOnTheLeft = isResizerOnTheLeft; + const style = window.getComputedStyle(sidebar); + this.#initialWidth = this.#width = parseFloat(style.getPropertyValue("--sidebar-width")); + resizer.ariaValueMin = parseFloat(style.getPropertyValue("--sidebar-min-width")) || 0; + resizer.ariaValueMax = parseFloat(style.getPropertyValue("--sidebar-max-width")) || Infinity; + resizer.ariaValueNow = this.#width; + this.#makeSidebarResizable(); + toggleButton.addEventListener("click", this.toggle.bind(this)); + this._isOpen = false; + sidebar.hidden = true; + this.#resizeObserver = new ResizeObserver(([{ + borderBoxSize: [{ + inlineSize + }] + }]) => { + if (!isNaN(this.#prevX)) { + this.#prevX += this.#coefficient * (inlineSize - this.#width); + } + this.#setWidth(inlineSize); + }); + this.#resizeObserver.observe(sidebar); + } + #makeSidebarResizable() { + const sidebarStyle = this._sidebar.style; + let pointerMoveAC; + const cancelResize = () => { + this.#resizeTimeout = null; + this._sidebar.classList.remove("resizing"); + pointerMoveAC?.abort(); + pointerMoveAC = null; + this.#isKeyboardResizing = false; + this.onStopResizing(); + this.#prevX = NaN; + }; + this.#resizer.addEventListener("pointerdown", e => { + if (pointerMoveAC) { + cancelResize(); + return; + } + this.onStartResizing(); + const { + clientX + } = e; + stopEvent(e); + this.#prevX = clientX; + pointerMoveAC = new AbortController(); + const { + signal + } = pointerMoveAC; + const sidebar = this._sidebar; + sidebar.classList.add("resizing"); + const parentStyle = sidebar.parentElement.style; + parentStyle.minWidth = 0; + window.addEventListener("contextmenu", noContextMenu, { + signal + }); + window.addEventListener("pointermove", ev => { + if (!pointerMoveAC || Math.abs(ev.clientX - this.#prevX) < 1) { + return; + } + stopEvent(ev); + sidebarStyle.width = `${Math.round(this.#width + this.#coefficient * (ev.clientX - this.#prevX))}px`; + }, { + signal, + capture: true + }); + window.addEventListener("blur", cancelResize, { + signal + }); + window.addEventListener("pointerup", ev => { + if (pointerMoveAC) { + cancelResize(); + stopEvent(ev); + } + }, { + signal + }); + }); + this.#resizer.addEventListener("keydown", e => { + const { + key + } = e; + const isArrowLeft = key === "ArrowLeft"; + if (isArrowLeft || key === "ArrowRight") { + if (!this.#isKeyboardResizing) { + this._sidebar.classList.add("resizing"); + this.#isKeyboardResizing = true; + this.onStartResizing(); + } + const base = e.ctrlKey || e.metaKey ? 10 : 1; + const dx = base * (isArrowLeft ? -1 : 1); + clearTimeout(this.#resizeTimeout); + this.#resizeTimeout = setTimeout(cancelResize, RESIZE_TIMEOUT); + sidebarStyle.width = `${Math.round(this.#width + this.#coefficient * dx)}px`; + stopEvent(e); + } + }); + } + #setWidth(newWidth) { + this.#width = newWidth; + this.#resizer.ariaValueNow = Math.round(newWidth); + if (this.#isResizerOnTheLeft) { + this._sidebar.parentElement.style.insetInlineStart = `${(this.#initialWidth - newWidth).toFixed(3)}px`; + } + this.onResizing(newWidth); + } + get width() { + return this.#width; + } + set width(newWidth) { + this._sidebar.style.width = `${newWidth}px`; + } + onStartResizing() {} + onStopResizing() {} + onResizing(_newWidth) {} + toggle(visibility = !this._isOpen) { + this._sidebar.hidden = !(this._isOpen = visibility); + } + destroy() { + this.#resizeObserver?.disconnect(); + this.#resizeObserver = null; + } +} + +;// ./web/comment_manager.js + + + +class CommentManager { + #dialog; + #popup; + #sidebar; + static #hasForcedColors = null; + constructor(commentDialog, sidebar, eventBus, linkService, overlayManager, ltr, hasForcedColors) { + const dateFormat = new Intl.DateTimeFormat(undefined, { + dateStyle: "long" + }); + this.dialogElement = commentDialog.dialog; + this.#dialog = new CommentDialog(commentDialog, overlayManager, eventBus, ltr); + this.#popup = new CommentPopup(eventBus, dateFormat, ltr, this.dialogElement); + this.#sidebar = new CommentSidebar(sidebar, eventBus, linkService, this.#popup, dateFormat, ltr); + this.#popup.sidebar = this.#sidebar; + CommentManager.#hasForcedColors = hasForcedColors; + } + setSidebarUiManager(uiManager) { + this.#sidebar.setUIManager(uiManager); + } + showSidebar(annotations) { + this.#sidebar.show(annotations); + } + hideSidebar() { + this.#sidebar.hide(); + } + removeComments(ids) { + this.#sidebar.removeComments(ids); + } + selectComment(id) { + this.#sidebar.selectComment(null, id); + } + addComment(annotation) { + this.#sidebar.addComment(annotation); + } + updateComment(annotation) { + this.#sidebar.updateComment(annotation); + } + toggleCommentPopup(editor, isSelected, visibility, isEditable) { + if (isSelected) { + this.selectComment(editor.uid); + } + this.#popup.toggle(editor, isSelected, visibility, isEditable); + } + destroyPopup() { + this.#popup.destroy(); + } + updatePopupColor(editor) { + this.#popup.updateColor(editor); + } + showDialog(uiManager, editor, posX, posY, options) { + return this.#dialog.open(uiManager, editor, posX, posY, options); + } + makeCommentColor(color, opacity) { + return CommentManager._makeCommentColor(color, opacity); + } + static _makeCommentColor(color, opacity) { + return this.#hasForcedColors ? null : findContrastColor(applyOpacity(...color, opacity ?? 1), CSSConstants.commentForegroundColor); + } + destroy() { + this.#dialog.destroy(); + this.#sidebar.hide(); + this.#popup.destroy(); + } +} +class CommentSidebar extends Sidebar { + #annotations = null; + #eventBus; + #boundCommentClick = this.#commentClick.bind(this); + #boundCommentKeydown = this.#commentKeydown.bind(this); + #closeButton; + #commentsList; + #commentCount; + #dateFormat; + #sidebarTitle; + #learnMoreUrl; + #linkService; + #popup; + #elementsToAnnotations = null; + #idsToElements = null; + #uiManager = null; + constructor({ + learnMoreUrl, + sidebar, + sidebarResizer, + commentsList, + commentCount, + sidebarTitle, + closeButton, + commentToolbarButton + }, eventBus, linkService, popup, dateFormat, ltr) { + super({ + sidebar, + resizer: sidebarResizer, + toggleButton: commentToolbarButton + }, ltr, true); + this.#sidebarTitle = sidebarTitle; + this.#commentsList = commentsList; + this.#commentCount = commentCount; + this.#learnMoreUrl = learnMoreUrl; + this.#linkService = linkService; + this.#closeButton = closeButton; + this.#popup = popup; + this.#dateFormat = dateFormat; + this.#eventBus = eventBus; + closeButton.addEventListener("click", () => { + eventBus.dispatch("switchannotationeditormode", { + source: this, + mode: AnnotationEditorType.NONE + }); + }); + const keyDownCallback = e => { + if (e.key === "ArrowDown" || e.key === "Home" || e.key === "F6") { + this.#commentsList.firstElementChild.focus(); + stopEvent(e); + } else if (e.key === "ArrowUp" || e.key === "End") { + this.#commentsList.lastElementChild.focus(); + stopEvent(e); + } + }; + commentToolbarButton.addEventListener("keydown", keyDownCallback); + sidebar.addEventListener("keydown", keyDownCallback); + } + setUIManager(uiManager) { + this.#uiManager = uiManager; + } + show(annotations) { + this.#elementsToAnnotations = new WeakMap(); + this.#idsToElements = new Map(); + this.#annotations = annotations; + annotations.sort(this.#sortComments.bind(this)); + if (annotations.length !== 0) { + const fragment = document.createDocumentFragment(); + for (const annotation of annotations) { + fragment.append(this.#createCommentElement(annotation)); + } + this.#setCommentsCount(fragment); + this.#commentsList.append(fragment); + } else { + this.#setCommentsCount(); + } + this._sidebar.hidden = false; + this.#eventBus.dispatch("reporttelemetry", { + source: this, + details: { + type: "commentSidebar", + data: { + numberOfAnnotations: annotations.length + } + } + }); + } + hide() { + this._sidebar.hidden = true; + this.#commentsList.replaceChildren(); + this.#elementsToAnnotations = null; + this.#idsToElements = null; + this.#annotations = null; + } + removeComments(ids) { + if (ids.length === 0 || !this.#idsToElements) { + return; + } + if (new Set(this.#idsToElements.keys()).difference(new Set(ids)).size === 0) { + this.#removeAll(); + return; + } + for (const id of ids) { + this.#removeComment(id); + } + } + focusComment(id) { + const element = this.#idsToElements.get(id); + if (!element) { + return; + } + this._sidebar.scrollTop = element.offsetTop - this._sidebar.offsetTop; + for (const el of this.#commentsList.children) { + el.classList.toggle("selected", el === element); + } + } + updateComment(annotation) { + if (!this.#idsToElements) { + return; + } + const { + id, + creationDate, + modificationDate, + richText, + contentsObj, + popupRef + } = annotation; + if (!popupRef || !richText && !contentsObj?.str) { + this.#removeComment(id); + } + const element = this.#idsToElements.get(id); + if (!element) { + return; + } + const prevAnnotation = this.#elementsToAnnotations.get(element); + let index = binarySearchFirstItem(this.#annotations, a => this.#sortComments(a, prevAnnotation) >= 0); + if (index >= this.#annotations.length) { + return; + } + this.#setDate(element.firstElementChild, modificationDate || creationDate); + this.#setText(element.lastElementChild, richText, contentsObj); + this.#annotations.splice(index, 1); + index = binarySearchFirstItem(this.#annotations, a => this.#sortComments(a, annotation) >= 0); + this.#annotations.splice(index, 0, annotation); + if (index >= this.#commentsList.children.length) { + this.#commentsList.append(element); + } else { + this.#commentsList.insertBefore(element, this.#commentsList.children[index]); + } + } + #removeComment(id) { + const element = this.#idsToElements?.get(id); + if (!element) { + return; + } + const annotation = this.#elementsToAnnotations.get(element); + const index = binarySearchFirstItem(this.#annotations, a => this.#sortComments(a, annotation) >= 0); + if (index >= this.#annotations.length) { + return; + } + this.#annotations.splice(index, 1); + element.remove(); + this.#idsToElements.delete(id); + this.#setCommentsCount(); + } + #removeAll() { + this.#commentsList.replaceChildren(); + this.#elementsToAnnotations = new WeakMap(); + this.#idsToElements.clear(); + this.#annotations.length = 0; + this.#setCommentsCount(); + } + selectComment(element, id = null) { + if (!this.#idsToElements) { + return; + } + const hasNoElement = !element; + element ||= this.#idsToElements.get(id); + for (const el of this.#commentsList.children) { + el.classList.toggle("selected", el === element); + } + if (hasNoElement) { + element?.scrollIntoView({ + behavior: "instant", + block: "center" + }); + } + } + addComment(annotation) { + if (this.#idsToElements?.has(annotation.id)) { + return; + } + const { + popupRef, + contentsObj + } = annotation; + if (!popupRef || !contentsObj?.str) { + return; + } + const commentItem = this.#createCommentElement(annotation); + if (this.#annotations.length === 0) { + this.#commentsList.replaceChildren(commentItem); + this.#annotations.push(annotation); + this.#setCommentsCount(); + return; + } + const index = binarySearchFirstItem(this.#annotations, a => this.#sortComments(a, annotation) >= 0); + this.#annotations.splice(index, 0, annotation); + if (index >= this.#commentsList.children.length) { + this.#commentsList.append(commentItem); + } else { + this.#commentsList.insertBefore(commentItem, this.#commentsList.children[index]); + } + this.#setCommentsCount(); + } + #setCommentsCount(container = this.#commentsList) { + const count = this.#idsToElements.size; + this.#sidebarTitle.setAttribute("data-l10n-args", JSON.stringify({ + count + })); + this.#commentCount.textContent = count; + if (count === 0) { + container.append(this.#createZeroCommentElement()); + } + } + #createZeroCommentElement() { + const commentItem = document.createElement("li"); + commentItem.classList.add("sidebarComment", "noComments"); + const textDiv = document.createElement("div"); + textDiv.className = "sidebarCommentText"; + textDiv.setAttribute("data-l10n-id", "pdfjs-editor-comments-sidebar-no-comments1"); + commentItem.append(textDiv); + if (this.#learnMoreUrl) { + const a = document.createElement("a"); + a.setAttribute("data-l10n-id", "pdfjs-editor-comments-sidebar-no-comments-link"); + a.href = this.#learnMoreUrl; + a.target = "_blank"; + a.rel = "noopener noreferrer"; + commentItem.append(a); + } + return commentItem; + } + #setDate(element, date) { + date = PDFDateString.toDateObject(date); + element.dateTime = date.toISOString(); + element.textContent = this.#dateFormat.format(date); + } + #setText(element, richText, contentsObj) { + element.replaceChildren(); + const html = richText?.str && (!contentsObj?.str || richText.str === contentsObj.str) ? richText.html : contentsObj?.str; + renderRichText({ + html, + dir: contentsObj?.dir || "auto", + className: "richText" + }, element); + } + #createCommentElement(annotation) { + const { + id, + creationDate, + modificationDate, + richText, + contentsObj, + color, + opacity + } = annotation; + const commentItem = document.createElement("li"); + commentItem.role = "button"; + commentItem.className = "sidebarComment"; + commentItem.tabIndex = -1; + commentItem.style.backgroundColor = color && CommentManager._makeCommentColor(color, opacity) || ""; + const dateDiv = document.createElement("time"); + this.#setDate(dateDiv, modificationDate || creationDate); + const textDiv = document.createElement("div"); + textDiv.className = "sidebarCommentText"; + this.#setText(textDiv, richText, contentsObj); + commentItem.append(dateDiv, textDiv); + commentItem.addEventListener("click", this.#boundCommentClick); + commentItem.addEventListener("keydown", this.#boundCommentKeydown); + this.#elementsToAnnotations.set(commentItem, annotation); + this.#idsToElements.set(id, commentItem); + return commentItem; + } + async #commentClick({ + currentTarget + }) { + if (currentTarget.classList.contains("selected")) { + currentTarget.classList.remove("selected"); + this.#popup._hide(); + return; + } + const annotation = this.#elementsToAnnotations.get(currentTarget); + if (!annotation) { + return; + } + this.#popup._hide(); + const { + id, + pageIndex, + rect + } = annotation; + const pageNumber = pageIndex + 1; + const pageVisiblePromise = this.#uiManager?.waitForEditorsRendered(pageNumber); + this.#linkService?.goToXY(pageNumber, rect[0], rect[3], { + center: "both" + }); + this.selectComment(currentTarget); + await pageVisiblePromise; + this.#uiManager?.selectComment(pageIndex, id); + } + #commentKeydown(e) { + const { + key, + currentTarget + } = e; + switch (key) { + case "ArrowDown": + (currentTarget.nextElementSibling || this.#commentsList.firstElementChild).focus(); + stopEvent(e); + break; + case "ArrowUp": + (currentTarget.previousElementSibling || this.#commentsList.lastElementChild).focus(); + stopEvent(e); + break; + case "Home": + this.#commentsList.firstElementChild.focus(); + stopEvent(e); + break; + case "End": + this.#commentsList.lastElementChild.focus(); + stopEvent(e); + break; + case "Enter": + case " ": + this.#commentClick(e); + stopEvent(e); + break; + case "ShiftTab": + this.#closeButton.focus(); + stopEvent(e); + break; + } + } + #sortComments(a, b) { + const dateA = PDFDateString.toDateObject(a.modificationDate || a.creationDate); + const dateB = PDFDateString.toDateObject(b.modificationDate || b.creationDate); + if (dateA !== dateB) { + if (dateA !== null && dateB !== null) { + return dateB - dateA; + } + return dateA !== null ? -1 : 1; + } + if (a.pageIndex !== b.pageIndex) { + return a.pageIndex - b.pageIndex; + } + if (a.rect[3] !== b.rect[3]) { + return b.rect[3] - a.rect[3]; + } + if (a.rect[0] !== b.rect[0]) { + return a.rect[0] - b.rect[0]; + } + if (a.rect[1] !== b.rect[1]) { + return b.rect[1] - a.rect[1]; + } + if (a.rect[2] !== b.rect[2]) { + return a.rect[2] - b.rect[2]; + } + return a.id.localeCompare(b.id); + } +} +class CommentDialog { + #dialog; + #editor; + #overlayManager; + #previousText = ""; + #commentText = ""; + #textInput; + #title; + #saveButton; + #uiManager; + #prevDragX = 0; + #prevDragY = 0; + #dialogX = 0; + #dialogY = 0; + #isLTR; + #eventBus; + constructor({ + dialog, + toolbar, + title, + textInput, + cancelButton, + saveButton + }, overlayManager, eventBus, ltr) { + this.#dialog = dialog; + this.#textInput = textInput; + this.#overlayManager = overlayManager; + this.#eventBus = eventBus; + this.#saveButton = saveButton; + this.#title = title; + this.#isLTR = ltr; + const finishBound = this.#finish.bind(this); + dialog.addEventListener("close", finishBound); + dialog.addEventListener("contextmenu", e => { + if (e.target !== this.#textInput) { + e.preventDefault(); + } + }); + cancelButton.addEventListener("click", finishBound); + saveButton.addEventListener("click", this.#save.bind(this)); + textInput.addEventListener("input", () => { + saveButton.disabled = textInput.value === this.#previousText; + }); + textInput.addEventListener("keydown", e => { + if ((e.ctrlKey || e.metaKey) && e.key === "Enter" && !saveButton.disabled) { + this.#save(); + } + }); + let pointerMoveAC; + const cancelDrag = () => { + dialog.classList.remove("dragging"); + pointerMoveAC?.abort(); + pointerMoveAC = null; + }; + toolbar.addEventListener("pointerdown", e => { + if (pointerMoveAC) { + cancelDrag(); + return; + } + const { + clientX, + clientY + } = e; + stopEvent(e); + this.#prevDragX = clientX; + this.#prevDragY = clientY; + pointerMoveAC = new AbortController(); + const { + signal + } = pointerMoveAC; + const { + innerHeight, + innerWidth + } = window; + dialog.classList.add("dragging"); + window.addEventListener("pointermove", ev => { + if (!pointerMoveAC) { + return; + } + const { + clientX: x, + clientY: y + } = ev; + this.#setPosition(this.#dialogX + (x - this.#prevDragX) / innerWidth, this.#dialogY + (y - this.#prevDragY) / innerHeight); + this.#prevDragX = x; + this.#prevDragY = y; + stopEvent(ev); + }, { + signal + }); + window.addEventListener("blur", cancelDrag, { + signal + }); + window.addEventListener("pointerup", ev => { + if (pointerMoveAC) { + cancelDrag(); + stopEvent(ev); + } + }, { + signal + }); + }); + overlayManager.register(dialog); + } + async open(uiManager, editor, posX, posY, options) { + if (editor) { + this.#uiManager = uiManager; + this.#editor = editor; + } + const { + contentsObj: { + str + }, + color, + opacity + } = editor.getData(); + const { + style: dialogStyle + } = this.#dialog; + if (color) { + dialogStyle.backgroundColor = CommentManager._makeCommentColor(color, opacity); + dialogStyle.borderColor = Util.makeHexColor(...color); + } else { + dialogStyle.backgroundColor = dialogStyle.borderColor = ""; + } + this.#commentText = str || ""; + const textInput = this.#textInput; + textInput.value = this.#previousText = this.#commentText; + if (str) { + this.#title.setAttribute("data-l10n-id", "pdfjs-editor-edit-comment-dialog-title-when-editing"); + this.#saveButton.setAttribute("data-l10n-id", "pdfjs-editor-edit-comment-dialog-save-button-when-editing"); + } else { + this.#title.setAttribute("data-l10n-id", "pdfjs-editor-edit-comment-dialog-title-when-adding"); + this.#saveButton.setAttribute("data-l10n-id", "pdfjs-editor-edit-comment-dialog-save-button-when-adding"); + } + if (options?.height) { + textInput.style.height = `${options.height}px`; + } + this.#uiManager?.removeEditListeners(); + this.#saveButton.disabled = true; + const parentDimensions = options?.parentDimensions; + const { + innerHeight, + innerWidth + } = window; + if (editor.hasDefaultPopupPosition()) { + const { + dialogWidth, + dialogHeight + } = this._dialogDimensions; + if (parentDimensions) { + if (this.#isLTR && posX + dialogWidth > Math.min(parentDimensions.x + parentDimensions.width, innerWidth)) { + const buttonWidth = this.#editor.commentButtonWidth; + posX -= dialogWidth - buttonWidth * parentDimensions.width; + } else if (!this.#isLTR) { + const buttonWidth = this.#editor.commentButtonWidth * parentDimensions.width; + if (posX - dialogWidth < Math.max(0, parentDimensions.x)) { + posX = Math.max(0, posX); + } else { + posX -= dialogWidth - buttonWidth; + } + } + } + const height = Math.max(dialogHeight, options?.height || 0); + if (posY + height > innerHeight) { + posY = innerHeight - height; + } + if (posY < 0) { + posY = 0; + } + } + posX = MathClamp(posX / innerWidth, 0, 1); + posY = MathClamp(posY / innerHeight, 0, 1); + this.#setPosition(posX, posY); + await this.#overlayManager.open(this.#dialog); + textInput.focus(); + } + async #save() { + this.#editor.comment = this.#textInput.value; + this.#finish(); + } + get _dialogDimensions() { + const dialog = this.#dialog; + const { + style + } = dialog; + style.opacity = "0"; + style.display = "block"; + const { + width, + height + } = dialog.getBoundingClientRect(); + style.opacity = style.display = ""; + return shadow(this, "_dialogDimensions", { + dialogWidth: width, + dialogHeight: height + }); + } + #setPosition(x, y) { + this.#dialogX = x; + this.#dialogY = y; + const { + style + } = this.#dialog; + style.left = `${100 * x}%`; + style.top = `${100 * y}%`; + } + #finish() { + if (!this.#editor) { + return; + } + const edited = this.#textInput.value !== this.#commentText; + this.#eventBus.dispatch("reporttelemetry", { + source: this, + details: { + type: "comment", + data: { + edited + } + } + }); + this.#editor?.focusCommentButton(); + this.#editor = null; + this.#textInput.value = this.#previousText = this.#commentText = ""; + this.#overlayManager.closeIfActive(this.#dialog); + this.#textInput.style.height = ""; + this.#uiManager?.addEditListeners(); + this.#uiManager = null; + } + destroy() { + this.#uiManager = null; + this.#editor = null; + this.#finish(); + } +} +class CommentPopup { + #buttonsContainer = null; + #eventBus; + #commentDialog; + #dateFormat; + #editor = null; + #isLTR; + #container = null; + #text = null; + #time = null; + #prevDragX = 0; + #prevDragY = 0; + #posX = 0; + #posY = 0; + #previousFocusedElement = null; + #selected = false; + #visible = false; + constructor(eventBus, dateFormat, ltr, commentDialog) { + this.#eventBus = eventBus; + this.#dateFormat = dateFormat; + this.#isLTR = ltr; + this.#commentDialog = commentDialog; + this.sidebar = null; + } + get _popupWidth() { + const container = this.#createPopup(); + const { + style + } = container; + style.opacity = "0"; + style.display = "block"; + document.body.append(container); + const width = container.getBoundingClientRect().width; + container.remove(); + style.opacity = style.display = ""; + return shadow(this, "_popupWidth", width); + } + #createPopup() { + if (this.#container) { + return this.#container; + } + const container = this.#container = document.createElement("div"); + container.className = "commentPopup"; + container.id = "commentPopup"; + container.tabIndex = -1; + container.role = "dialog"; + container.ariaModal = "false"; + container.addEventListener("contextmenu", noContextMenu); + container.addEventListener("keydown", e => { + if (e.key === "Escape") { + this.toggle(this.#editor, true, false); + this.#previousFocusedElement?.focus(); + stopEvent(e); + } + }); + container.addEventListener("click", () => { + container.focus(); + }); + const top = document.createElement("div"); + top.className = "commentPopupTop"; + const time = this.#time = document.createElement("time"); + time.className = "commentPopupTime"; + const buttons = this.#buttonsContainer = document.createElement("div"); + buttons.className = "commentPopupButtons"; + const edit = document.createElement("button"); + edit.classList.add("commentPopupEdit", "toolbarButton"); + edit.tabIndex = 0; + edit.setAttribute("data-l10n-id", "pdfjs-editor-edit-comment-popup-button"); + edit.ariaHasPopup = "dialog"; + edit.ariaControlsElements = [this.#commentDialog]; + const editLabel = document.createElement("span"); + editLabel.setAttribute("data-l10n-id", "pdfjs-editor-edit-comment-popup-button-label"); + edit.append(editLabel); + edit.addEventListener("click", () => { + const editor = this.#editor; + const height = parseFloat(getComputedStyle(this.#text).height); + this.toggle(editor, true, false); + editor.editComment({ + height + }); + }); + edit.addEventListener("contextmenu", noContextMenu); + const del = document.createElement("button"); + del.classList.add("commentPopupDelete", "toolbarButton"); + del.tabIndex = 0; + del.setAttribute("data-l10n-id", "pdfjs-editor-delete-comment-popup-button"); + const delLabel = document.createElement("span"); + delLabel.setAttribute("data-l10n-id", "pdfjs-editor-delete-comment-popup-button-label"); + del.append(delLabel); + del.addEventListener("click", () => { + this.#eventBus.dispatch("reporttelemetry", { + source: this, + details: { + type: "comment", + data: { + deleted: true + } + } + }); + const editor = this.#editor; + const savedData = editor.comment; + this.destroy(); + if (savedData?.text) { + editor._uiManager.deleteComment(editor, savedData); + } else { + editor.comment = null; + } + editor.focus(); + }); + del.addEventListener("contextmenu", noContextMenu); + buttons.append(edit, del); + top.append(time, buttons); + const separator = document.createElement("hr"); + const text = this.#text = document.createElement("div"); + text.className = "commentPopupText"; + container.append(top, separator, text); + let pointerMoveAC; + const cancelDrag = () => { + container.classList.remove("dragging"); + pointerMoveAC?.abort(); + pointerMoveAC = null; + }; + top.addEventListener("pointerdown", e => { + if (pointerMoveAC) { + cancelDrag(); + return; + } + const { + target, + clientX, + clientY + } = e; + if (buttons.contains(target)) { + return; + } + stopEvent(e); + const { + width: parentWidth, + height: parentHeight + } = this.#editor.parentBoundingClientRect; + this.#prevDragX = clientX; + this.#prevDragY = clientY; + pointerMoveAC = new AbortController(); + const { + signal + } = pointerMoveAC; + container.classList.add("dragging"); + window.addEventListener("pointermove", ev => { + if (!pointerMoveAC) { + return; + } + const { + clientX: x, + clientY: y + } = ev; + this.#setPosition(this.#posX + (x - this.#prevDragX) / parentWidth, this.#posY + (y - this.#prevDragY) / parentHeight, false); + this.#prevDragX = x; + this.#prevDragY = y; + stopEvent(ev); + }, { + signal + }); + window.addEventListener("blur", cancelDrag, { + signal + }); + window.addEventListener("pointerup", ev => { + if (pointerMoveAC) { + cancelDrag(); + stopEvent(ev); + } + }, { + signal + }); + }); + return container; + } + updateColor(editor) { + if (this.#editor !== editor || !this.#visible) { + return; + } + const { + color, + opacity + } = editor.getData(); + this.#container.style.backgroundColor = color && CommentManager._makeCommentColor(color, opacity) || ""; + } + _hide(editor) { + const container = this.#createPopup(); + container.classList.toggle("hidden", true); + container.classList.toggle("selected", false); + (editor || this.#editor)?.setCommentButtonStates({ + selected: false, + hasPopup: false + }); + this.#editor = null; + this.#selected = false; + this.#visible = false; + this.#text.replaceChildren(); + this.sidebar.selectComment(null); + } + toggle(editor, isSelected, visibility = undefined, isEditable = true) { + if (!editor) { + this.destroy(); + return; + } + if (isSelected) { + visibility ??= this.#editor === editor ? !this.#selected || !this.#visible : true; + } else { + if (this.#selected) { + return; + } + visibility ??= !this.#visible; + } + if (!visibility) { + this._hide(editor); + return; + } + this.#visible = true; + if (this.#editor !== editor) { + this.#editor?.setCommentButtonStates({ + selected: false, + hasPopup: false + }); + } + const container = this.#createPopup(); + this.#buttonsContainer.classList.toggle("hidden", !isEditable); + container.classList.toggle("hidden", false); + container.classList.toggle("selected", isSelected); + this.#selected = isSelected; + this.#editor = editor; + editor.setCommentButtonStates({ + selected: isSelected, + hasPopup: true + }); + const { + contentsObj, + richText, + creationDate, + modificationDate, + color, + opacity + } = editor.getData(); + container.style.backgroundColor = color && CommentManager._makeCommentColor(color, opacity) || ""; + this.#text.replaceChildren(); + const html = richText?.str && (!contentsObj?.str || richText.str === contentsObj.str) ? richText.html : contentsObj?.str; + if (html) { + renderRichText({ + html, + dir: contentsObj?.dir || "auto", + className: "richText" + }, this.#text); + } + this.#time.textContent = this.#dateFormat.format(PDFDateString.toDateObject(modificationDate || creationDate)); + this.#setPosition(...editor.commentPopupPosition, editor.hasDefaultPopupPosition()); + editor.elementBeforePopup.after(container); + container.addEventListener("focus", ({ + relatedTarget + }) => { + this.#previousFocusedElement = relatedTarget; + }, { + once: true + }); + if (isSelected) { + setTimeout(() => container.focus(), 0); + } + } + #setPosition(x, y, correctPosition) { + if (!correctPosition) { + this.#editor.commentPopupPosition = [x, y]; + } else { + const parentRect = this.#editor.parentBoundingClientRect; + const widthRatio = this._popupWidth / parentRect.width; + if (this.#isLTR && x + widthRatio > 1 || !this.#isLTR && x - widthRatio >= 0) { + const buttonWidth = this.#editor.commentButtonWidth; + x -= widthRatio - buttonWidth; + } + const margin = 0.01; + if (this.#isLTR) { + x = Math.max(x, -parentRect.x / parentRect.width + margin); + } else { + x = Math.min(x, (window.innerWidth - parentRect.x) / parentRect.width - widthRatio - margin); + } + } + this.#posX = x; + this.#posY = y; + const { + style + } = this.#container; + style.left = `${100 * x}%`; + style.top = `${100 * y}%`; + } + destroy() { + this._hide(); + this.#container?.remove(); + this.#container = this.#text = this.#time = null; + this.#prevDragX = this.#prevDragY = Infinity; + this.#posX = this.#posY = 0; + this.#previousFocusedElement = null; + } +} + +;// ./web/base_download_manager.js + +class BaseDownloadManager { + #openBlobUrls = new WeakMap(); + _triggerDownload(blobUrl, originalUrl, filename, isAttachment = false) { + throw new Error("Not implemented: _triggerDownload"); + } + _getOpenDataUrl(blobUrl, filename, dest = null) { + throw new Error("Not implemented: _getOpenDataUrl"); + } + downloadData(data, filename, contentType) { + const blobUrl = URL.createObjectURL(new Blob([data], { + type: contentType + })); + this._triggerDownload(blobUrl, blobUrl, filename, true); + } + openOrDownloadData(data, filename, dest = null) { + const isPdfData = isPdfFile(filename); + const contentType = isPdfData ? "application/pdf" : ""; + if (isPdfData) { + const blobUrl = this.#openBlobUrls.getOrInsertComputed(data, () => URL.createObjectURL(new Blob([data], { + type: contentType + }))); + try { + const viewerUrl = this._getOpenDataUrl(blobUrl, filename, dest); + window.open(viewerUrl); + return true; + } catch (ex) { + console.error("openOrDownloadData:", ex); + URL.revokeObjectURL(blobUrl); + this.#openBlobUrls.delete(data); + } + } + this.downloadData(data, filename, contentType); + return false; + } + download(data, url, filename) { + const blobUrl = data ? URL.createObjectURL(new Blob([data], { + type: "application/pdf" + })) : null; + this._triggerDownload(blobUrl, url, filename); + } +} + +;// ./web/download_manager.js + + +class DownloadManager extends BaseDownloadManager { + _triggerDownload(blobUrl, originalUrl, filename, isAttachment = false) { + if (!blobUrl && !isAttachment) { + if (!createValidAbsoluteUrl(originalUrl, "http://example.com")) { + throw new Error(`_triggerDownload - not a valid URL: ${originalUrl}`); + } + blobUrl = originalUrl + "#pdfjs.action=download"; + } + const a = document.createElement("a"); + a.href = blobUrl; + a.target = "_parent"; + if ("download" in a) { + a.download = filename; + } + (document.body || document.documentElement).append(a); + a.click(); + a.remove(); + } + _getOpenDataUrl(blobUrl, filename, dest = null) { + let url = "?file=" + encodeURIComponent(blobUrl + "#" + filename); + if (dest) { + url += `#${escape(dest)}`; + } + return url; + } +} + +;// ./web/editor_undo_bar.js + +class EditorUndoBar { + #closeButton = null; + #container; + #eventBus = null; + #focusTimeout = null; + #initController = null; + isOpen = false; + #message; + #showController = null; + #undoButton; + static #l10nMessages = Object.freeze({ + highlight: "pdfjs-editor-undo-bar-message-highlight", + freetext: "pdfjs-editor-undo-bar-message-freetext", + stamp: "pdfjs-editor-undo-bar-message-stamp", + ink: "pdfjs-editor-undo-bar-message-ink", + signature: "pdfjs-editor-undo-bar-message-signature", + comment: "pdfjs-editor-undo-bar-message-comment", + _multiple: "pdfjs-editor-undo-bar-message-multiple" + }); + constructor({ + container, + message, + undoButton, + closeButton + }, eventBus) { + this.#container = container; + this.#message = message; + this.#undoButton = undoButton; + this.#closeButton = closeButton; + this.#eventBus = eventBus; + } + destroy() { + this.#initController?.abort(); + this.#initController = null; + this.hide(); + } + show(undoAction, messageData) { + if (!this.#initController) { + this.#initController = new AbortController(); + const opts = { + signal: this.#initController.signal + }; + const boundHide = this.hide.bind(this); + this.#container.addEventListener("contextmenu", noContextMenu, opts); + this.#closeButton.addEventListener("click", boundHide, opts); + this.#eventBus._on("beforeprint", boundHide, opts); + this.#eventBus._on("download", boundHide, opts); + } + this.hide(); + if (typeof messageData === "string") { + this.#message.setAttribute("data-l10n-id", EditorUndoBar.#l10nMessages[messageData]); + } else { + this.#message.setAttribute("data-l10n-id", EditorUndoBar.#l10nMessages._multiple); + this.#message.setAttribute("data-l10n-args", JSON.stringify({ + count: messageData + })); + } + this.isOpen = true; + this.#container.hidden = false; + this.#showController = new AbortController(); + this.#undoButton.addEventListener("click", () => { + undoAction(); + this.hide(); + }, { + signal: this.#showController.signal + }); + this.#focusTimeout = setTimeout(() => { + this.#container.focus(); + this.#focusTimeout = null; + }, 100); + } + hide() { + if (!this.isOpen) { + return; + } + this.isOpen = false; + this.#container.hidden = true; + this.#showController?.abort(); + this.#showController = null; + if (this.#focusTimeout) { + clearTimeout(this.#focusTimeout); + this.#focusTimeout = null; + } + } +} + +;// ./web/overlay_manager.js +class OverlayManager { + #overlays = new WeakMap(); + #active = null; + get active() { + return this.#active; + } + async register(dialog, canForceClose = false) { + if (typeof dialog !== "object") { + throw new Error("Not enough parameters."); + } else if (this.#overlays.has(dialog)) { + throw new Error("The overlay is already registered."); + } + this.#overlays.set(dialog, { + canForceClose + }); + dialog.addEventListener("cancel", ({ + target + }) => { + if (this.#active === target) { + this.#active = null; + } + }); + } + async open(dialog) { + if (!this.#overlays.has(dialog)) { + throw new Error("The overlay does not exist."); + } else if (this.#active) { + if (this.#active === dialog) { + throw new Error("The overlay is already active."); + } else if (this.#overlays.get(dialog).canForceClose) { + await this.close(); + } else { + throw new Error("Another overlay is currently active."); + } + } + this.#active = dialog; + dialog.showModal(); + } + async close(dialog = this.#active) { + if (!this.#overlays.has(dialog)) { + throw new Error("The overlay does not exist."); + } else if (!this.#active) { + throw new Error("The overlay is currently not active."); + } else if (this.#active !== dialog) { + throw new Error("Another overlay is currently active."); + } + dialog.close(); + this.#active = null; + } + async closeIfActive(dialog) { + if (this.#active === dialog) { + await this.close(dialog); + } + } +} + +;// ./web/password_prompt.js + +class PasswordPrompt { + #activeCapability = null; + #updateCallback = null; + #reason = null; + constructor(options, overlayManager, isViewerEmbedded = false) { + this.dialog = options.dialog; + this.label = options.label; + this.input = options.input; + this.submitButton = options.submitButton; + this.cancelButton = options.cancelButton; + this.overlayManager = overlayManager; + this._isViewerEmbedded = isViewerEmbedded; + this.submitButton.addEventListener("click", this.#verify.bind(this)); + this.cancelButton.addEventListener("click", this.close.bind(this)); + this.input.addEventListener("keydown", e => { + if (e.keyCode === 13) { + this.#verify(); + } + }); + this.overlayManager.register(this.dialog, true); + this.dialog.addEventListener("close", this.#cancel.bind(this)); + } + async open() { + await this.#activeCapability?.promise; + this.#activeCapability = Promise.withResolvers(); + try { + await this.overlayManager.open(this.dialog); + } catch (ex) { + this.#activeCapability.resolve(); + throw ex; + } + const passwordIncorrect = this.#reason === PasswordResponses.INCORRECT_PASSWORD; + if (!this._isViewerEmbedded || passwordIncorrect) { + this.input.focus(); + } + this.label.setAttribute("data-l10n-id", passwordIncorrect ? "pdfjs-password-invalid" : "pdfjs-password-label"); + } + async close() { + this.overlayManager.closeIfActive(this.dialog); + } + #verify() { + const password = this.input.value; + if (password?.length > 0) { + this.#invokeCallback(password); + } + } + #cancel() { + this.#invokeCallback(new Error("PasswordPrompt cancelled.")); + this.#activeCapability.resolve(); + } + #invokeCallback(password) { + if (!this.#updateCallback) { + return; + } + this.close(); + this.input.value = ""; + this.#updateCallback(password); + this.#updateCallback = null; + } + async setUpdateCallback(updateCallback, reason) { + if (this.#activeCapability) { + await this.#activeCapability.promise; + } + this.#updateCallback = updateCallback; + this.#reason = reason; + } +} + +;// ./web/base_tree_viewer.js + + +const TREEITEM_SELECTED_CLASS = "selected"; +class BaseTreeViewer { + constructor(options) { + this.container = options.container; + this.eventBus = options.eventBus; + this._l10n = options.l10n; + this.reset(); + } + reset() { + this._pdfDocument = null; + this._lastToggleIsShow = true; + this._currentTreeItem = null; + this.container.replaceChildren(); + this.container.classList.remove("withNesting"); + } + _dispatchEvent(count) { + throw new Error("Not implemented: _dispatchEvent"); + } + _bindLink(element, params) { + throw new Error("Not implemented: _bindLink"); + } + _normalizeTextContent(str) { + return removeNullCharacters(str, true) || "\u2013"; + } + _addToggleButton(div, hidden = false) { + const toggler = document.createElement("div"); + toggler.className = "treeItemToggler"; + if (hidden) { + toggler.classList.add("treeItemsHidden"); + } + div.prepend(toggler); + } + _toggleTreeItem(root, show = false) { + this._l10n.pause(); + this._lastToggleIsShow = show; + for (const toggler of root.querySelectorAll(".treeItemToggler")) { + toggler.classList.toggle("treeItemsHidden", !show); + } + this._l10n.resume(); + } + _toggleAllTreeItems() { + this._toggleTreeItem(this.container, !this._lastToggleIsShow); + } + _finishRendering(fragment, count, hasAnyNesting = false) { + if (hasAnyNesting) { + this.container.classList.add("withNesting"); + this._lastToggleIsShow = !fragment.querySelector(".treeItemsHidden"); + this.container.addEventListener("click", e => { + const { + target + } = e; + if (!target.classList.contains("treeItemToggler")) { + return; + } + stopEvent(e); + target.classList.toggle("treeItemsHidden"); + if (e.shiftKey) { + const shouldShowAll = !target.classList.contains("treeItemsHidden"); + this._toggleTreeItem(target.parentNode, shouldShowAll); + } + }); + } + this._l10n.pause(); + this.container.append(fragment); + this._l10n.resume(); + this._dispatchEvent(count); + } + render(params) { + throw new Error("Not implemented: render"); + } + _updateCurrentTreeItem(treeItem = null) { + if (this._currentTreeItem) { + this._currentTreeItem.classList.remove(TREEITEM_SELECTED_CLASS); + this._currentTreeItem = null; + } + if (treeItem) { + treeItem.classList.add(TREEITEM_SELECTED_CLASS); + this._currentTreeItem = treeItem; + } + } + _scrollToCurrentTreeItem(treeItem) { + if (!treeItem) { + return; + } + this._l10n.pause(); + let currentNode = treeItem.parentNode; + while (currentNode && currentNode !== this.container) { + if (currentNode.classList.contains("treeItem")) { + const toggler = currentNode.firstElementChild; + toggler?.classList.remove("treeItemsHidden"); + } + currentNode = currentNode.parentNode; + } + this._l10n.resume(); + this._updateCurrentTreeItem(treeItem); + treeItem.scrollIntoView({ + behavior: "instant", + block: "center", + inline: "center", + container: "nearest" + }); + } +} + +;// ./web/pdf_attachment_viewer.js + + +class PDFAttachmentViewer extends BaseTreeViewer { + constructor(options) { + super(options); + this.downloadManager = options.downloadManager; + this.eventBus._on("fileattachmentannotation", this.#appendAttachment.bind(this)); + } + reset(keepRenderedCapability = false) { + super.reset(); + this._attachments = null; + if (!keepRenderedCapability) { + this._renderedCapability = Promise.withResolvers(); + } + this._pendingDispatchEvent = false; + } + async _dispatchEvent(attachmentsCount) { + this._renderedCapability.resolve(); + if (attachmentsCount === 0 && !this._pendingDispatchEvent) { + this._pendingDispatchEvent = true; + await waitOnEventOrTimeout({ + target: this.eventBus, + name: "annotationlayerrendered", + delay: 1000 + }); + if (!this._pendingDispatchEvent) { + return; + } + } + this._pendingDispatchEvent = false; + this.eventBus.dispatch("attachmentsloaded", { + source: this, + attachmentsCount + }); + } + _bindLink(element, { + content, + description, + filename + }) { + if (description) { + element.title = description; + } + element.onclick = () => { + this.downloadManager.openOrDownloadData(content, filename); + return false; + }; + } + render({ + attachments, + keepRenderedCapability = false + }) { + if (this._attachments) { + this.reset(keepRenderedCapability); + } + this._attachments = attachments || null; + if (!attachments) { + this._dispatchEvent(0); + return; + } + const fragment = document.createDocumentFragment(); + const ul = document.createElement("ul"); + fragment.append(ul); + let attachmentsCount = 0; + for (const name in attachments) { + const item = attachments[name]; + const li = document.createElement("li"); + ul.append(li); + const element = document.createElement("a"); + li.append(element); + this._bindLink(element, item); + element.textContent = this._normalizeTextContent(item.filename); + attachmentsCount++; + } + this._finishRendering(fragment, attachmentsCount); + } + #appendAttachment(item) { + const renderedPromise = this._renderedCapability.promise; + renderedPromise.then(() => { + if (renderedPromise !== this._renderedCapability.promise) { + return; + } + const attachments = this._attachments || Object.create(null); + for (const name in attachments) { + if (item.filename === name) { + return; + } + } + attachments[item.filename] = item; + this.render({ + attachments, + keepRenderedCapability: true + }); + }); + } +} + +;// ./web/grab_to_pan.js + +const CSS_CLASS_GRAB = "grab-to-pan-grab"; +class GrabToPan { + #activateAC = null; + #mouseDownAC = null; + #scrollAC = null; + constructor({ + element + }) { + this.element = element; + this.document = element.ownerDocument; + const overlay = this.overlay = document.createElement("div"); + overlay.className = "grab-to-pan-grabbing"; + } + activate() { + if (!this.#activateAC) { + this.#activateAC = new AbortController(); + this.element.addEventListener("mousedown", this.#onMouseDown.bind(this), { + capture: true, + signal: this.#activateAC.signal + }); + this.element.classList.add(CSS_CLASS_GRAB); + } + } + deactivate() { + if (this.#activateAC) { + this.#activateAC.abort(); + this.#activateAC = null; + this.#endPan(); + this.element.classList.remove(CSS_CLASS_GRAB); + } + } + toggle() { + if (this.#activateAC) { + this.deactivate(); + } else { + this.activate(); + } + } + ignoreTarget(node) { + return node.matches("a[href], a[href] *, input, textarea, button, button *, select, option"); + } + #onMouseDown(event) { + if (event.button !== 0 || this.ignoreTarget(event.target)) { + return; + } + if (event.originalTarget) { + try { + event.originalTarget.tagName; + } catch { + return; + } + } + this.scrollLeftStart = this.element.scrollLeft; + this.scrollTopStart = this.element.scrollTop; + this.clientXStart = event.clientX; + this.clientYStart = event.clientY; + this.#mouseDownAC = new AbortController(); + const boundEndPan = this.#endPan.bind(this), + mouseOpts = { + capture: true, + signal: this.#mouseDownAC.signal + }; + this.document.addEventListener("mousemove", this.#onMouseMove.bind(this), mouseOpts); + this.document.addEventListener("mouseup", boundEndPan, mouseOpts); + this.#scrollAC = new AbortController(); + this.element.addEventListener("scroll", boundEndPan, { + capture: true, + signal: this.#scrollAC.signal + }); + stopEvent(event); + const focusedElement = document.activeElement; + if (focusedElement && !focusedElement.contains(event.target)) { + focusedElement.blur(); + } + } + #onMouseMove(event) { + this.#scrollAC?.abort(); + this.#scrollAC = null; + if (!(event.buttons & 1)) { + this.#endPan(); + return; + } + const xDiff = event.clientX - this.clientXStart; + const yDiff = event.clientY - this.clientYStart; + this.element.scrollTo({ + top: this.scrollTopStart - yDiff, + left: this.scrollLeftStart - xDiff, + behavior: "instant" + }); + if (!this.overlay.parentNode) { + document.body.append(this.overlay); + } + } + #endPan() { + this.#mouseDownAC?.abort(); + this.#mouseDownAC = null; + this.#scrollAC?.abort(); + this.#scrollAC = null; + this.overlay.remove(); + } +} + +;// ./web/pdf_cursor_tools.js + + + +class PDFCursorTools { + #active = CursorTool.SELECT; + #prevActive = null; + constructor({ + container, + eventBus, + cursorToolOnLoad = CursorTool.SELECT + }) { + this.container = container; + this.eventBus = eventBus; + this.#addEventListeners(); + Promise.resolve().then(() => { + this.switchTool(cursorToolOnLoad); + }); + } + get activeTool() { + return this.#active; + } + switchTool(tool) { + if (this.#prevActive !== null) { + return; + } + this.#switchTool(tool); + } + #switchTool(tool, disabled = false) { + if (tool === this.#active) { + if (this.#prevActive !== null) { + this.eventBus.dispatch("cursortoolchanged", { + source: this, + tool, + disabled + }); + } + return; + } + const disableActiveTool = () => { + switch (this.#active) { + case CursorTool.SELECT: + break; + case CursorTool.HAND: + this._handTool.deactivate(); + break; + case CursorTool.ZOOM: + } + }; + switch (tool) { + case CursorTool.SELECT: + disableActiveTool(); + break; + case CursorTool.HAND: + disableActiveTool(); + this._handTool.activate(); + break; + case CursorTool.ZOOM: + default: + console.error(`switchTool: "${tool}" is an unsupported value.`); + return; + } + this.#active = tool; + this.eventBus.dispatch("cursortoolchanged", { + source: this, + tool, + disabled + }); + } + #addEventListeners() { + this.eventBus._on("switchcursortool", evt => { + if (!evt.reset) { + this.switchTool(evt.tool); + } else if (this.#prevActive !== null) { + annotationEditorMode = AnnotationEditorType.NONE; + presentationModeState = PresentationModeState.NORMAL; + enableActive(); + } + }); + let annotationEditorMode = AnnotationEditorType.NONE, + presentationModeState = PresentationModeState.NORMAL; + const disableActive = () => { + this.#prevActive ??= this.#active; + this.#switchTool(CursorTool.SELECT, true); + }; + const enableActive = () => { + if (this.#prevActive !== null && annotationEditorMode === AnnotationEditorType.NONE && presentationModeState === PresentationModeState.NORMAL) { + this.#switchTool(this.#prevActive); + this.#prevActive = null; + } + }; + this.eventBus._on("annotationeditormodechanged", ({ + mode + }) => { + annotationEditorMode = mode; + if (mode === AnnotationEditorType.NONE) { + enableActive(); + } else { + disableActive(); + } + }); + this.eventBus._on("presentationmodechanged", ({ + state + }) => { + presentationModeState = state; + if (state === PresentationModeState.NORMAL) { + enableActive(); + } else if (state === PresentationModeState.FULLSCREEN) { + disableActive(); + } + }); + } + get _handTool() { + return shadow(this, "_handTool", new GrabToPan({ + element: this.container + })); + } +} + +;// ./web/pdf_document_properties.js + + +const NON_METRIC_LOCALES = ["en-us", "en-lr", "my"]; +const US_PAGE_NAMES = { + "8.5x11": "pdfjs-document-properties-page-size-name-letter", + "8.5x14": "pdfjs-document-properties-page-size-name-legal" +}; +const METRIC_PAGE_NAMES = { + "297x420": "pdfjs-document-properties-page-size-name-a-three", + "210x297": "pdfjs-document-properties-page-size-name-a-four" +}; +function getPageName(size, isPortrait, pageNames) { + const width = isPortrait ? size.width : size.height; + const height = isPortrait ? size.height : size.width; + return pageNames[`${width}x${height}`]; +} +class PDFDocumentProperties { + #fieldData = null; + constructor({ + dialog, + fields, + closeButton + }, overlayManager, eventBus, l10n, fileNameLookup, titleLookup) { + this.dialog = dialog; + this.fields = fields; + this.overlayManager = overlayManager; + this.l10n = l10n; + this._fileNameLookup = fileNameLookup; + this._titleLookup = titleLookup; + this.#reset(); + closeButton.addEventListener("click", this.close.bind(this)); + this.overlayManager.register(this.dialog); + eventBus._on("pagechanging", evt => { + this._currentPageNumber = evt.pageNumber; + }); + eventBus._on("rotationchanging", evt => { + this._pagesRotation = evt.pagesRotation; + }); + } + async open() { + await Promise.all([this.overlayManager.open(this.dialog), this._dataAvailableCapability.promise]); + const currentPageNumber = this._currentPageNumber; + const pagesRotation = this._pagesRotation; + if (this.#fieldData && currentPageNumber === this.#fieldData._currentPageNumber && pagesRotation === this.#fieldData._pagesRotation) { + this.#updateUI(); + return; + } + const [{ + info, + metadata, + contentLength + }, pdfPage] = await Promise.all([this.pdfDocument.getMetadata(), this.pdfDocument.getPage(currentPageNumber)]); + const [fileName, fileSize, title, creationDate, modificationDate, pageSize, isLinearized] = await Promise.all([this._fileNameLookup(), this.#parseFileSize(contentLength), this._titleLookup(), this.#parseDate(metadata?.get("xmp:createdate"), info.CreationDate), this.#parseDate(metadata?.get("xmp:modifydate"), info.ModDate), this.#parsePageSize(getPageSizeInches(pdfPage), pagesRotation), this.#parseLinearization(info.IsLinearized)]); + this.#fieldData = Object.freeze({ + fileName, + fileSize, + title, + author: metadata?.get("dc:creator")?.join("\n") || info.Author, + subject: metadata?.get("dc:subject")?.join("\n") || info.Subject, + keywords: metadata?.get("pdf:keywords") || info.Keywords, + creationDate, + modificationDate, + creator: metadata?.get("xmp:creatortool") || info.Creator, + producer: metadata?.get("pdf:producer") || info.Producer, + version: info.PDFFormatVersion, + pageCount: this.pdfDocument.numPages, + pageSize, + linearized: isLinearized, + _currentPageNumber: currentPageNumber, + _pagesRotation: pagesRotation + }); + this.#updateUI(); + const { + length + } = await this.pdfDocument.getDownloadInfo(); + if (contentLength === length) { + return; + } + const data = Object.assign(Object.create(null), this.#fieldData); + data.fileSize = await this.#parseFileSize(length); + this.#fieldData = Object.freeze(data); + this.#updateUI(); + } + async close() { + this.overlayManager.close(this.dialog); + } + setDocument(pdfDocument) { + if (this.pdfDocument) { + this.#reset(); + this.#updateUI(); + } + if (!pdfDocument) { + return; + } + this.pdfDocument = pdfDocument; + this._dataAvailableCapability.resolve(); + } + #reset() { + this.pdfDocument = null; + this.#fieldData = null; + this._dataAvailableCapability = Promise.withResolvers(); + this._currentPageNumber = 1; + this._pagesRotation = 0; + } + #updateUI() { + if (this.#fieldData && this.overlayManager.active !== this.dialog) { + return; + } + for (const id in this.fields) { + const content = this.#fieldData?.[id]; + this.fields[id].textContent = content || content === 0 ? content : "-"; + } + } + async #parseFileSize(b = 0) { + const kb = b / 1024, + mb = kb / 1024; + return kb ? this.l10n.get(mb >= 1 ? "pdfjs-document-properties-size-mb" : "pdfjs-document-properties-size-kb", { + mb, + kb, + b + }) : undefined; + } + async #parsePageSize(pageSizeInches, pagesRotation) { + if (!pageSizeInches) { + return undefined; + } + if (pagesRotation % 180 !== 0) { + pageSizeInches = { + width: pageSizeInches.height, + height: pageSizeInches.width + }; + } + const isPortrait = isPortraitOrientation(pageSizeInches), + nonMetric = NON_METRIC_LOCALES.includes(this.l10n.getLanguage()); + let sizeInches = { + width: Math.round(pageSizeInches.width * 100) / 100, + height: Math.round(pageSizeInches.height * 100) / 100 + }; + let sizeMillimeters = { + width: Math.round(pageSizeInches.width * 25.4 * 10) / 10, + height: Math.round(pageSizeInches.height * 25.4 * 10) / 10 + }; + let nameId = getPageName(sizeInches, isPortrait, US_PAGE_NAMES) || getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES); + if (!nameId && !(Number.isInteger(sizeMillimeters.width) && Number.isInteger(sizeMillimeters.height))) { + const exactMillimeters = { + width: pageSizeInches.width * 25.4, + height: pageSizeInches.height * 25.4 + }; + const intMillimeters = { + width: Math.round(sizeMillimeters.width), + height: Math.round(sizeMillimeters.height) + }; + if (Math.abs(exactMillimeters.width - intMillimeters.width) < 0.1 && Math.abs(exactMillimeters.height - intMillimeters.height) < 0.1) { + nameId = getPageName(intMillimeters, isPortrait, METRIC_PAGE_NAMES); + if (nameId) { + sizeInches = { + width: Math.round(intMillimeters.width / 25.4 * 100) / 100, + height: Math.round(intMillimeters.height / 25.4 * 100) / 100 + }; + sizeMillimeters = intMillimeters; + } + } + } + const [{ + width, + height + }, unit, name, orientation] = await Promise.all([nonMetric ? sizeInches : sizeMillimeters, this.l10n.get(nonMetric ? "pdfjs-document-properties-page-size-unit-inches" : "pdfjs-document-properties-page-size-unit-millimeters"), nameId && this.l10n.get(nameId), this.l10n.get(isPortrait ? "pdfjs-document-properties-page-size-orientation-portrait" : "pdfjs-document-properties-page-size-orientation-landscape")]); + return this.l10n.get(name ? "pdfjs-document-properties-page-size-dimension-name-string" : "pdfjs-document-properties-page-size-dimension-string", { + width, + height, + unit, + name, + orientation + }); + } + async #parseDate(metadataDate, infoDate) { + const dateObj = Date.parse(metadataDate) || PDFDateString.toDateObject(infoDate); + return dateObj ? this.l10n.get("pdfjs-document-properties-date-time-string", { + dateObj: dateObj.valueOf() + }) : undefined; + } + #parseLinearization(isLinearized) { + return this.l10n.get(isLinearized ? "pdfjs-document-properties-linearized-yes" : "pdfjs-document-properties-linearized-no"); + } +} + +;// ./web/pdf_find_utils.js + +const CharacterType = { + SPACE: 0, + ALPHA_LETTER: 1, + PUNCT: 2, + HAN_LETTER: 3, + KATAKANA_LETTER: 4, + HIRAGANA_LETTER: 5, + HALFWIDTH_KATAKANA_LETTER: 6, + THAI_LETTER: 7 +}; +function isAlphabeticalScript(charCode) { + return charCode < 0x2e80; +} +function isAscii(charCode) { + return (charCode & 0xff80) === 0; +} +function isAsciiAlpha(charCode) { + return charCode >= 0x61 && charCode <= 0x7a || charCode >= 0x41 && charCode <= 0x5a; +} +function isAsciiDigit(charCode) { + return charCode >= 0x30 && charCode <= 0x39; +} +function isAsciiSpace(charCode) { + return charCode === 0x20 || charCode === 0x09 || charCode === 0x0d || charCode === 0x0a; +} +function isHan(charCode) { + return charCode >= 0x3400 && charCode <= 0x9fff || charCode >= 0xf900 && charCode <= 0xfaff; +} +function isKatakana(charCode) { + return charCode >= 0x30a0 && charCode <= 0x30ff; +} +function isHiragana(charCode) { + return charCode >= 0x3040 && charCode <= 0x309f; +} +function isHalfwidthKatakana(charCode) { + return charCode >= 0xff60 && charCode <= 0xff9f; +} +function isThai(charCode) { + return (charCode & 0xff80) === 0x0e00; +} +function getCharacterType(charCode) { + if (isAlphabeticalScript(charCode)) { + if (isAscii(charCode)) { + if (isAsciiSpace(charCode)) { + return CharacterType.SPACE; + } else if (isAsciiAlpha(charCode) || isAsciiDigit(charCode) || charCode === 0x5f) { + return CharacterType.ALPHA_LETTER; + } + return CharacterType.PUNCT; + } else if (isThai(charCode)) { + return CharacterType.THAI_LETTER; + } else if (charCode === 0xa0) { + return CharacterType.SPACE; + } + return CharacterType.ALPHA_LETTER; + } + if (isHan(charCode)) { + return CharacterType.HAN_LETTER; + } else if (isKatakana(charCode)) { + return CharacterType.KATAKANA_LETTER; + } else if (isHiragana(charCode)) { + return CharacterType.HIRAGANA_LETTER; + } else if (isHalfwidthKatakana(charCode)) { + return CharacterType.HALFWIDTH_KATAKANA_LETTER; + } + return CharacterType.ALPHA_LETTER; +} +let NormalizeWithNFKC; +function getNormalizeWithNFKC() { + if (!NormalizeWithNFKC) { + const ranges = []; + const range = []; + const diacriticsRegex = /^\p{M}$/u; + for (let i = 0; i < 65536; i++) { + if (i >= 0xd800 && i <= 0xdfff) { + continue; + } + const c = String.fromCharCode(i); + if (c.normalize("NFKC") !== c && !diacriticsRegex.test(c)) { + if (range.length !== 2) { + range[0] = range[1] = i; + continue; + } + if (range[1] + 1 !== i) { + if (range[0] === range[1]) { + ranges.push(String.fromCharCode(range[0])); + } else { + ranges.push(`${String.fromCharCode(range[0])}-${String.fromCharCode(range[1])}`); + } + range[0] = range[1] = i; + } else { + range[1] = i; + } + } + } + const rangesStr = ranges.join(""); + if (!NormalizeWithNFKC) { + NormalizeWithNFKC = rangesStr; + } else if (rangesStr !== NormalizeWithNFKC) { + for (let i = 1; i < rangesStr.length; i++) { + if (rangesStr[i] !== NormalizeWithNFKC[i]) { + console.log(`Difference at index ${i}: ` + `U+${rangesStr.charCodeAt(i).toString(16).toUpperCase().padStart(4, "0")}` + `!== U+${NormalizeWithNFKC.charCodeAt(i).toString(16).toUpperCase().padStart(4, "0")}`); + break; + } + } + throw new Error("getNormalizeWithNFKC - update the `NormalizeWithNFKC` string."); + } + } + return NormalizeWithNFKC; +} + +;// ./web/pdf_find_controller.js + + +const FindState = { + FOUND: 0, + NOT_FOUND: 1, + WRAPPED: 2, + PENDING: 3 +}; +const FIND_TIMEOUT = 250; +const MATCH_SCROLL_OFFSET_TOP = -50; +const CHARACTERS_TO_NORMALIZE = { + "\u2010": "-", + "\u2018": "'", + "\u2019": "'", + "\u201A": "'", + "\u201B": "'", + "\u201C": '"', + "\u201D": '"', + "\u201E": '"', + "\u201F": '"', + "\u00BC": "1/4", + "\u00BD": "1/2", + "\u00BE": "3/4" +}; +const DIACRITICS_EXCEPTION = new Set([0x3099, 0x309a, 0x094d, 0x09cd, 0x0a4d, 0x0acd, 0x0b4d, 0x0bcd, 0x0c4d, 0x0ccd, 0x0d3b, 0x0d3c, 0x0d4d, 0x0dca, 0x0e3a, 0x0eba, 0x0f84, 0x1039, 0x103a, 0x1714, 0x1734, 0x17d2, 0x1a60, 0x1b44, 0x1baa, 0x1bab, 0x1bf2, 0x1bf3, 0x2d7f, 0xa806, 0xa82c, 0xa8c4, 0xa953, 0xa9c0, 0xaaf6, 0xabed, 0x0c56, 0x0f71, 0x0f72, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f80, 0x0f74]); +let DIACRITICS_EXCEPTION_STR; +const DIACRITICS_REG_EXP = /\p{M}+/gu; +const SPECIAL_CHARS_REG_EXP = /([+^$|])|(\p{P}+)|(\s+)|(\p{M})|(\p{L})/gu; +const NOT_DIACRITIC_FROM_END_REG_EXP = /([^\p{M}])\p{M}*$/u; +const NOT_DIACRITIC_FROM_START_REG_EXP = /^\p{M}*([^\p{M}])/u; +const SYLLABLES_REG_EXP = /[\uAC00-\uD7AF\uFA6C\uFACF-\uFAD1\uFAD5-\uFAD7]+/g; +const SYLLABLES_LENGTHS = new Map(); +const FIRST_CHAR_SYLLABLES_REG_EXP = "[\\u1100-\\u1112\\ud7a4-\\ud7af\\ud84a\\ud84c\\ud850\\ud854\\ud857\\ud85f]"; +const NFKC_CHARS_TO_NORMALIZE = new Map(); +let noSyllablesRegExp = null; +let withSyllablesRegExp = null; +function normalize(text, options = {}) { + const syllablePositions = []; + let m; + while ((m = SYLLABLES_REG_EXP.exec(text)) !== null) { + let { + index + } = m; + for (const char of m[0]) { + let len = SYLLABLES_LENGTHS.get(char); + if (!len) { + len = char.normalize("NFD").length; + SYLLABLES_LENGTHS.set(char, len); + } + syllablePositions.push([len, index++]); + } + } + const hasSyllables = syllablePositions.length > 0; + const ignoreDashEOL = options.ignoreDashEOL ?? false; + let normalizationRegex; + if (!hasSyllables && noSyllablesRegExp) { + normalizationRegex = noSyllablesRegExp; + } else if (hasSyllables && withSyllablesRegExp) { + normalizationRegex = withSyllablesRegExp; + } else { + const replace = Object.keys(CHARACTERS_TO_NORMALIZE).join(""); + const toNormalizeWithNFKC = getNormalizeWithNFKC(); + const CJK = "(?:\\p{Ideographic}|[\u3040-\u30FF])"; + const HKDiacritics = "(?:\u3099|\u309A)"; + const BrokenWord = `\\p{Ll}-\\n(?=\\p{Ll})|\\p{Lu}-\\n(?=\\p{L})`; + const regexps = [`[${replace}]`, `[${toNormalizeWithNFKC}]`, `${HKDiacritics}\\n`, "\\p{M}+(?:-\\n)?", `${BrokenWord}`, "\\S-\\n", `${CJK}\\n`, "\\n", hasSyllables ? FIRST_CHAR_SYLLABLES_REG_EXP : "\\u0000"]; + normalizationRegex = new RegExp(regexps.map(r => `(${r})`).join("|"), "gum"); + if (hasSyllables) { + withSyllablesRegExp = normalizationRegex; + } else { + noSyllablesRegExp = normalizationRegex; + } + } + const rawDiacriticsPositions = []; + while ((m = DIACRITICS_REG_EXP.exec(text)) !== null) { + rawDiacriticsPositions.push([m[0].length, m.index]); + } + let normalized = text.normalize("NFD"); + const positions = [0, 0]; + let rawDiacriticsIndex = 0; + let syllableIndex = 0; + let shift = 0; + let shiftOrigin = 0; + let eol = 0; + let hasDiacritics = false; + normalized = normalized.replace(normalizationRegex, (match, p1, p2, p3, p4, p5, p6, p7, p8, p9, i) => { + i -= shiftOrigin; + if (p1) { + const replacement = CHARACTERS_TO_NORMALIZE[p1]; + const jj = replacement.length; + for (let j = 1; j < jj; j++) { + positions.push(i - shift + j, shift - j); + } + shift -= jj - 1; + return replacement; + } + if (p2) { + let replacement = NFKC_CHARS_TO_NORMALIZE.get(p2); + if (!replacement) { + replacement = p2.normalize("NFKC"); + NFKC_CHARS_TO_NORMALIZE.set(p2, replacement); + } + const jj = replacement.length; + for (let j = 1; j < jj; j++) { + positions.push(i - shift + j, shift - j); + } + shift -= jj - 1; + return replacement; + } + if (p3) { + hasDiacritics = true; + if (i + eol === rawDiacriticsPositions[rawDiacriticsIndex]?.[1]) { + ++rawDiacriticsIndex; + } else { + positions.push(i - 1 - shift + 1, shift - 1); + shift -= 1; + shiftOrigin += 1; + } + positions.push(i - shift + 1, shift); + shiftOrigin += 1; + eol += 1; + return p3.charAt(0); + } + if (p4) { + const hasTrailingDashEOL = p4.endsWith("\n"); + const len = hasTrailingDashEOL ? p4.length - 2 : p4.length; + hasDiacritics = true; + let jj = len; + if (i + eol === rawDiacriticsPositions[rawDiacriticsIndex]?.[1]) { + jj -= rawDiacriticsPositions[rawDiacriticsIndex][0]; + ++rawDiacriticsIndex; + } + for (let j = 1; j <= jj; j++) { + positions.push(i - 1 - shift + j, shift - j); + } + shift -= jj; + shiftOrigin += jj; + if (hasTrailingDashEOL) { + i += len - 1; + positions.push(i - shift + 1, 1 + shift); + shift += 1; + shiftOrigin += 1; + eol += 1; + return p4.slice(0, len); + } + return p4; + } + if (p5) { + if (ignoreDashEOL) { + shiftOrigin += 1; + eol += 1; + return p5.slice(0, -1); + } + const len = p5.length - 2; + positions.push(i - shift + len, 1 + shift); + shift += 1; + shiftOrigin += 1; + eol += 1; + return p5.slice(0, -2); + } + if (p6) { + shiftOrigin += 1; + eol += 1; + return p6.slice(0, -1); + } + if (p7) { + const len = p7.length - 1; + positions.push(i - shift + len, shift); + shiftOrigin += 1; + eol += 1; + return p7.slice(0, -1); + } + if (p8) { + positions.push(i - shift + 1, shift - 1); + shift -= 1; + shiftOrigin += 1; + eol += 1; + return " "; + } + if (i + eol === syllablePositions[syllableIndex]?.[1]) { + const newCharLen = syllablePositions[syllableIndex][0] - 1; + ++syllableIndex; + for (let j = 1; j <= newCharLen; j++) { + positions.push(i - (shift - j), shift - j); + } + shift -= newCharLen; + shiftOrigin += newCharLen; + } + return p9; + }); + positions.push(normalized.length, shift); + const starts = new Uint32Array(positions.length >> 1); + const shifts = new Int32Array(positions.length >> 1); + for (let i = 0, ii = positions.length; i < ii; i += 2) { + starts[i >> 1] = positions[i]; + shifts[i >> 1] = positions[i + 1]; + } + return [normalized, [starts, shifts], hasDiacritics]; +} +function getOriginalIndex(diffs, pos, len) { + if (!diffs) { + return [pos, len]; + } + const [starts, shifts] = diffs; + const start = pos; + const end = pos + len - 1; + let i = binarySearchFirstItem(starts, x => x >= start); + if (starts[i] > start) { + --i; + } + let j = binarySearchFirstItem(starts, x => x >= end, i); + if (starts[j] > end) { + --j; + } + const oldStart = start + shifts[i]; + const oldEnd = end + shifts[j]; + const oldLen = oldEnd + 1 - oldStart; + return [oldStart, oldLen]; +} +class PDFFindController { + #state = null; + #updateMatchesCountOnProgress = true; + #visitedPagesCount = 0; + #copiedExtractTextPromises = null; + constructor({ + linkService, + eventBus, + updateMatchesCountOnProgress = true + }) { + this._linkService = linkService; + this._eventBus = eventBus; + this.#updateMatchesCountOnProgress = updateMatchesCountOnProgress; + this.onIsPageVisible = null; + this.#reset(); + eventBus._on("find", this.#onFind.bind(this)); + eventBus._on("findbarclose", this.#onFindBarClose.bind(this)); + eventBus._on("pagesedited", this.#onPagesEdited.bind(this)); + } + get highlightMatches() { + return this._highlightMatches; + } + get pageMatches() { + return this._pageMatches; + } + get pageMatchesLength() { + return this._pageMatchesLength; + } + get selected() { + return this._selected; + } + get state() { + return this.#state; + } + setDocument(pdfDocument) { + if (this._pdfDocument) { + this.#reset(); + } + if (!pdfDocument) { + return; + } + this._pdfDocument = pdfDocument; + this._firstPageCapability.resolve(); + } + #onFind(state) { + if (!state) { + return; + } + const pdfDocument = this._pdfDocument; + const { + type + } = state; + if (this.#state === null || this.#shouldDirtyMatch(state)) { + this._dirtyMatch = true; + } + this.#state = state; + if (type !== "highlightallchange") { + this.#updateUIState(FindState.PENDING); + } + this._firstPageCapability.promise.then(() => { + if (!this._pdfDocument || pdfDocument && this._pdfDocument !== pdfDocument) { + return; + } + this.#extractText(); + const findbarClosed = !this._highlightMatches; + const pendingTimeout = !!this._findTimeout; + if (this._findTimeout) { + clearTimeout(this._findTimeout); + this._findTimeout = null; + } + if (!type) { + this._findTimeout = setTimeout(() => { + this.#nextMatch(); + this._findTimeout = null; + }, FIND_TIMEOUT); + } else if (this._dirtyMatch) { + this.#nextMatch(); + } else if (type === "again") { + this.#nextMatch(); + if (findbarClosed && this.#state.highlightAll) { + this.#updateAllPages(); + } + } else if (type === "highlightallchange") { + if (pendingTimeout) { + this.#nextMatch(); + } else { + this._highlightMatches = true; + } + this.#updateAllPages(); + } else { + this.#nextMatch(); + } + }); + } + scrollMatchIntoView({ + element = null, + selectedLeft = 0, + pageIndex = -1, + matchIndex = -1 + }) { + if (!this._scrollMatches || !element) { + return; + } else if (matchIndex === -1 || matchIndex !== this._selected.matchIdx) { + return; + } else if (pageIndex === -1 || pageIndex !== this._selected.pageIdx) { + return; + } + this._scrollMatches = false; + const spot = { + top: MATCH_SCROLL_OFFSET_TOP, + left: selectedLeft + }; + scrollIntoView(element, spot, true); + } + #reset() { + this._highlightMatches = false; + this._scrollMatches = false; + this._pdfDocument = null; + this._pageMatches = []; + this._pageMatchesLength = []; + this.#visitedPagesCount = 0; + this.#state = null; + this._selected = { + pageIdx: -1, + matchIdx: -1 + }; + this._offset = { + pageIdx: null, + matchIdx: null, + wrapped: false + }; + this._extractTextPromises = []; + this._pageContents = []; + this._pageDiffs = []; + this._hasDiacritics = []; + this._matchesCountTotal = 0; + this._pagesToSearch = null; + this._pendingFindMatches = new Set(); + this._resumePageIdx = null; + this._dirtyMatch = false; + clearTimeout(this._findTimeout); + this._findTimeout = null; + this.#copiedExtractTextPromises = null; + this._firstPageCapability = Promise.withResolvers(); + } + get #query() { + const { + query + } = this.#state; + if (typeof query === "string") { + if (query !== this._rawQuery) { + this._rawQuery = query; + [this._normalizedQuery] = normalize(query); + } + return this._normalizedQuery; + } + return (query || []).filter(q => !!q).map(q => normalize(q)[0]); + } + #shouldDirtyMatch(state) { + const newQuery = state.query, + prevQuery = this.#state.query; + const newType = typeof newQuery, + prevType = typeof prevQuery; + if (newType !== prevType) { + return true; + } + if (newType === "string") { + if (newQuery !== prevQuery) { + return true; + } + } else if (JSON.stringify(newQuery) !== JSON.stringify(prevQuery)) { + return true; + } + switch (state.type) { + case "again": + const pageNumber = this._selected.pageIdx + 1; + const linkService = this._linkService; + return pageNumber >= 1 && pageNumber <= linkService.pagesCount && pageNumber !== linkService.page && !(this.onIsPageVisible?.(pageNumber) ?? true); + case "highlightallchange": + return false; + } + return true; + } + #isEntireWord(content, startIdx, length) { + let match = content.slice(0, startIdx).match(NOT_DIACRITIC_FROM_END_REG_EXP); + if (match) { + const first = content.charCodeAt(startIdx); + const limit = match[1].charCodeAt(0); + if (getCharacterType(first) === getCharacterType(limit)) { + return false; + } + } + match = content.slice(startIdx + length).match(NOT_DIACRITIC_FROM_START_REG_EXP); + if (match) { + const last = content.charCodeAt(startIdx + length - 1); + const limit = match[1].charCodeAt(0); + if (getCharacterType(last) === getCharacterType(limit)) { + return false; + } + } + return true; + } + #convertToRegExpString(query, hasDiacritics) { + const { + matchDiacritics + } = this.#state; + let isUnicode = false; + const addExtraWhitespaces = (original, fixed) => { + if (original === query) { + return fixed; + } + if (query.startsWith(original)) { + return `${fixed}[ ]*`; + } + if (query.endsWith(original)) { + return `[ ]*${fixed}`; + } + return `[ ]*${fixed}[ ]*`; + }; + query = query.replaceAll(SPECIAL_CHARS_REG_EXP, (match, p1, p2, p3, p4, p5) => { + if (p1) { + return addExtraWhitespaces(p1, RegExp.escape(p1)); + } + if (p2) { + return addExtraWhitespaces(p2, RegExp.escape(p2)); + } + if (p3) { + return "[ ]+"; + } + if (matchDiacritics) { + return p4 || p5; + } + if (p4) { + return DIACRITICS_EXCEPTION.has(p4.charCodeAt(0)) ? p4 : ""; + } + if (hasDiacritics) { + isUnicode = true; + return `${p5}\\p{M}*`; + } + return p5; + }); + const trailingSpaces = "[ ]*"; + if (query.endsWith(trailingSpaces)) { + query = query.slice(0, query.length - trailingSpaces.length); + } + if (matchDiacritics) { + if (hasDiacritics) { + DIACRITICS_EXCEPTION_STR ||= String.fromCharCode(...DIACRITICS_EXCEPTION); + isUnicode = true; + query = `${query}(?=[${DIACRITICS_EXCEPTION_STR}]|[^\\p{M}]|$)`; + } + } + return [isUnicode, query]; + } + #calculateMatch(pageIndex) { + if (!this.#state) { + return; + } + const query = this.#query; + if (query.length === 0) { + return; + } + const pageContent = this._pageContents[pageIndex]; + const matcherResult = this.match(query, pageContent, pageIndex); + const matches = this._pageMatches[pageIndex] = []; + const matchesLength = this._pageMatchesLength[pageIndex] = []; + const diffs = this._pageDiffs[pageIndex]; + matcherResult?.forEach(({ + index, + length + }) => { + const [matchPos, matchLen] = getOriginalIndex(diffs, index, length); + if (matchLen) { + matches.push(matchPos); + matchesLength.push(matchLen); + } + }); + if (this.#state.highlightAll) { + this.#updatePage(pageIndex); + } + if (this._resumePageIdx === pageIndex) { + this._resumePageIdx = null; + this.#nextPageMatch(); + } + const pageMatchesCount = matches.length; + this._matchesCountTotal += pageMatchesCount; + if (this.#updateMatchesCountOnProgress) { + if (pageMatchesCount > 0) { + this.#updateUIResultsCount(); + } + } else if (++this.#visitedPagesCount === this._linkService.pagesCount) { + this.#updateUIResultsCount(); + } + } + match(query, pageContent, pageIndex) { + const hasDiacritics = this._hasDiacritics[pageIndex]; + let isUnicode = false; + if (typeof query === "string") { + [isUnicode, query] = this.#convertToRegExpString(query, hasDiacritics); + } else { + query = query.sort().reverse().map(q => { + const [isUnicodePart, queryPart] = this.#convertToRegExpString(q, hasDiacritics); + isUnicode ||= isUnicodePart; + return `(${queryPart})`; + }).join("|"); + } + if (!query) { + return undefined; + } + const { + caseSensitive, + entireWord + } = this.#state; + const flags = `g${isUnicode ? "u" : ""}${caseSensitive ? "" : "i"}`; + query = new RegExp(query, flags); + const matches = []; + let match; + while ((match = query.exec(pageContent)) !== null) { + if (entireWord && !this.#isEntireWord(pageContent, match.index, match[0].length)) { + continue; + } + matches.push({ + index: match.index, + length: match[0].length + }); + } + return matches; + } + #extractText() { + if (this._extractTextPromises.length > 0) { + return; + } + let deferred = Promise.resolve(); + const textOptions = { + disableNormalization: true + }; + const pdfDoc = this._pdfDocument; + for (let i = 0, ii = this._linkService.pagesCount; i < ii; i++) { + const { + promise, + resolve + } = Promise.withResolvers(); + this._extractTextPromises[i] = promise; + deferred = deferred.then(async () => { + if (pdfDoc !== this._pdfDocument) { + resolve(); + return; + } + await pdfDoc.getPage(i + 1).then(pdfPage => pdfPage.getTextContent(textOptions)).then(textContent => { + const strBuf = []; + for (const textItem of textContent.items) { + strBuf.push(textItem.str); + if (textItem.hasEOL) { + strBuf.push("\n"); + } + } + [this._pageContents[i], this._pageDiffs[i], this._hasDiacritics[i]] = normalize(strBuf.join("")); + resolve(); + }, reason => { + console.error(`Unable to get text content for page ${i + 1}`, reason); + this._pageContents[i] = ""; + this._pageDiffs[i] = null; + this._hasDiacritics[i] = false; + resolve(); + }); + }); + } + } + #updatePage(index) { + if (this._scrollMatches && this._selected.pageIdx === index) { + this._linkService.page = index + 1; + } + this._eventBus.dispatch("updatetextlayermatches", { + source: this, + pageIndex: index + }); + } + #updateAllPages() { + this._eventBus.dispatch("updatetextlayermatches", { + source: this, + pageIndex: -1 + }); + } + #nextMatch() { + const previous = this.#state.findPrevious; + const currentPageIndex = this._linkService.page - 1; + const numPages = this._linkService.pagesCount; + this._highlightMatches = true; + if (this._dirtyMatch) { + this._dirtyMatch = false; + this._selected.pageIdx = this._selected.matchIdx = -1; + this._offset.pageIdx = currentPageIndex; + this._offset.matchIdx = null; + this._offset.wrapped = false; + this._resumePageIdx = null; + this._pageMatches.length = 0; + this._pageMatchesLength.length = 0; + this.#visitedPagesCount = 0; + this._matchesCountTotal = 0; + this.#updateAllPages(); + for (let i = 0; i < numPages; i++) { + if (this._pendingFindMatches.has(i)) { + continue; + } + this._pendingFindMatches.add(i); + this._extractTextPromises[i].then(() => { + this._pendingFindMatches.delete(i); + this.#calculateMatch(i); + }); + } + } + const query = this.#query; + if (query.length === 0) { + this.#updateUIState(FindState.FOUND); + return; + } + if (this._resumePageIdx) { + return; + } + const offset = this._offset; + this._pagesToSearch = numPages; + if (offset.matchIdx !== null) { + const numPageMatches = this._pageMatches[offset.pageIdx].length; + if (!previous && offset.matchIdx + 1 < numPageMatches || previous && offset.matchIdx > 0) { + offset.matchIdx = previous ? offset.matchIdx - 1 : offset.matchIdx + 1; + this.#updateMatch(true); + return; + } + this.#advanceOffsetPage(previous); + } + this.#nextPageMatch(); + } + #matchesReady(matches) { + const offset = this._offset; + const numMatches = matches.length; + const previous = this.#state.findPrevious; + if (numMatches) { + offset.matchIdx = previous ? numMatches - 1 : 0; + this.#updateMatch(true); + return true; + } + this.#advanceOffsetPage(previous); + if (offset.wrapped) { + offset.matchIdx = null; + if (this._pagesToSearch < 0) { + this.#updateMatch(false); + return true; + } + } + return false; + } + #nextPageMatch() { + if (this._resumePageIdx !== null) { + console.error("There can only be one pending page."); + } + let matches = null; + do { + const pageIdx = this._offset.pageIdx; + matches = this._pageMatches[pageIdx]; + if (!matches) { + this._resumePageIdx = pageIdx; + break; + } + } while (!this.#matchesReady(matches)); + } + #advanceOffsetPage(previous) { + const offset = this._offset; + const numPages = this._linkService.pagesCount; + offset.pageIdx = previous ? offset.pageIdx - 1 : offset.pageIdx + 1; + offset.matchIdx = null; + this._pagesToSearch--; + if (offset.pageIdx >= numPages || offset.pageIdx < 0) { + offset.pageIdx = previous ? numPages - 1 : 0; + offset.wrapped = true; + } + } + #updateMatch(found = false) { + let state = FindState.NOT_FOUND; + const wrapped = this._offset.wrapped; + this._offset.wrapped = false; + if (found) { + const previousPage = this._selected.pageIdx; + this._selected.pageIdx = this._offset.pageIdx; + this._selected.matchIdx = this._offset.matchIdx; + state = wrapped ? FindState.WRAPPED : FindState.FOUND; + if (previousPage !== -1 && previousPage !== this._selected.pageIdx) { + this.#updatePage(previousPage); + } + } + this.#updateUIState(state, this.#state.findPrevious); + if (this._selected.pageIdx !== -1) { + this._scrollMatches = true; + this.#updatePage(this._selected.pageIdx); + } + } + #onPagesEdited({ + pagesMapper, + type, + pageNumbers + }) { + if (this._extractTextPromises.length === 0) { + return; + } + if (type === "copy") { + this.#copiedExtractTextPromises = new Map(); + for (const pageNum of pageNumbers) { + this.#copiedExtractTextPromises.set(pageNum, this._extractTextPromises[pageNum - 1]); + } + return; + } + this.#onFindBarClose(); + this._dirtyMatch = true; + const prevTextPromises = this._extractTextPromises; + const extractTextPromises = this._extractTextPromises.length = []; + for (let i = 1, ii = pagesMapper.length; i <= ii; i++) { + const prevPageNumber = pagesMapper.getPrevPageNumber(i); + if (prevPageNumber < 0) { + extractTextPromises.push(this.#copiedExtractTextPromises?.get(-prevPageNumber) || Promise.resolve()); + continue; + } + extractTextPromises.push(prevTextPromises[prevPageNumber - 1] || Promise.resolve()); + } + } + #onFindBarClose(evt) { + const pdfDocument = this._pdfDocument; + this._firstPageCapability.promise.then(() => { + if (!this._pdfDocument || pdfDocument && this._pdfDocument !== pdfDocument) { + return; + } + if (this._findTimeout) { + clearTimeout(this._findTimeout); + this._findTimeout = null; + } + if (this._resumePageIdx) { + this._resumePageIdx = null; + this._dirtyMatch = true; + } + this.#updateUIState(FindState.FOUND); + this._highlightMatches = false; + this.#updateAllPages(); + }); + } + #requestMatchesCount() { + const { + pageIdx, + matchIdx + } = this._selected; + let current = 0, + total = this._matchesCountTotal; + if (matchIdx !== -1) { + for (let i = 0; i < pageIdx; i++) { + current += this._pageMatches[i]?.length || 0; + } + current += matchIdx + 1; + } + if (current < 1 || current > total) { + current = total = 0; + } + return { + current, + total + }; + } + #updateUIResultsCount() { + this._eventBus.dispatch("updatefindmatchescount", { + source: this, + matchesCount: this.#requestMatchesCount() + }); + } + #updateUIState(state, previous = false) { + if (!this.#updateMatchesCountOnProgress && (this.#visitedPagesCount !== this._linkService.pagesCount || state === FindState.PENDING)) { + return; + } + this._eventBus.dispatch("updatefindcontrolstate", { + source: this, + state, + previous, + entireWord: this.#state?.entireWord ?? null, + matchesCount: this.#requestMatchesCount(), + rawQuery: this.#state?.query ?? null + }); + } +} + +;// ./web/pdf_find_bar.js + + +const MATCHES_COUNT_LIMIT = 1000; +class PDFFindBar { + #mainContainer; + #resizeObserver = new ResizeObserver(this.#resizeObserverCallback.bind(this)); + opened = false; + constructor(options, mainContainer, eventBus) { + this.bar = options.bar; + this.toggleButton = options.toggleButton; + this.findField = options.findField; + this.highlightAll = options.highlightAllCheckbox; + this.caseSensitive = options.caseSensitiveCheckbox; + this.matchDiacritics = options.matchDiacriticsCheckbox; + this.entireWord = options.entireWordCheckbox; + this.findMsg = options.findMsg; + this.findResultsCount = options.findResultsCount; + this.findPreviousButton = options.findPreviousButton; + this.findNextButton = options.findNextButton; + this.eventBus = eventBus; + this.#mainContainer = mainContainer; + const checkedInputs = new Map([[this.highlightAll, "highlightallchange"], [this.caseSensitive, "casesensitivitychange"], [this.entireWord, "entirewordchange"], [this.matchDiacritics, "diacriticmatchingchange"]]); + this.toggleButton.addEventListener("click", () => { + this.toggle(); + }); + this.findField.addEventListener("input", () => { + this.dispatchEvent(""); + }); + this.bar.addEventListener("keydown", ({ + keyCode, + shiftKey, + target + }) => { + switch (keyCode) { + case 13: + if (target === this.findField) { + this.dispatchEvent("again", shiftKey); + } else if (checkedInputs.has(target)) { + target.checked = !target.checked; + this.dispatchEvent(checkedInputs.get(target)); + } + break; + case 27: + this.close(); + break; + } + }); + this.findPreviousButton.addEventListener("click", () => { + this.dispatchEvent("again", true); + }); + this.findNextButton.addEventListener("click", () => { + this.dispatchEvent("again", false); + }); + for (const [elem, evtName] of checkedInputs) { + elem.addEventListener("click", () => { + this.dispatchEvent(evtName); + }); + } + } + reset() { + this.updateUIState(); + } + dispatchEvent(type, findPrev = false) { + this.eventBus.dispatch("find", { + source: this, + type, + query: this.findField.value, + caseSensitive: this.caseSensitive.checked, + entireWord: this.entireWord.checked, + highlightAll: this.highlightAll.checked, + findPrevious: findPrev, + matchDiacritics: this.matchDiacritics.checked + }); + } + updateUIState(state, previous, matchesCount) { + const { + findField, + findMsg + } = this; + let findMsgId = "", + status = ""; + switch (state) { + case FindState.FOUND: + break; + case FindState.PENDING: + status = "pending"; + break; + case FindState.NOT_FOUND: + findMsgId = "pdfjs-find-not-found"; + status = "notFound"; + break; + case FindState.WRAPPED: + findMsgId = previous ? "pdfjs-find-reached-top" : "pdfjs-find-reached-bottom"; + break; + } + findField.setAttribute("data-status", status); + findField.setAttribute("aria-invalid", state === FindState.NOT_FOUND); + findMsg.setAttribute("data-status", status); + if (findMsgId) { + findMsg.setAttribute("data-l10n-id", findMsgId); + } else { + findMsg.removeAttribute("data-l10n-id"); + findMsg.textContent = ""; + } + this.updateResultsCount(matchesCount); + } + updateResultsCount({ + current = 0, + total = 0 + } = {}) { + const { + findResultsCount + } = this; + if (total > 0) { + const limit = MATCHES_COUNT_LIMIT; + findResultsCount.setAttribute("data-l10n-id", total > limit ? "pdfjs-find-match-count-limit" : "pdfjs-find-match-count"); + findResultsCount.setAttribute("data-l10n-args", JSON.stringify({ + limit, + current, + total + })); + } else { + findResultsCount.removeAttribute("data-l10n-id"); + findResultsCount.textContent = ""; + } + } + open() { + if (!this.opened) { + this.#resizeObserver.observe(this.#mainContainer); + this.#resizeObserver.observe(this.bar); + this.opened = true; + toggleExpandedBtn(this.toggleButton, true, this.bar); + } + this.findField.select(); + this.findField.focus(); + } + close() { + if (!this.opened) { + return; + } + this.#resizeObserver.disconnect(); + this.opened = false; + toggleExpandedBtn(this.toggleButton, false, this.bar); + this.eventBus.dispatch("findbarclose", { + source: this + }); + } + toggle() { + if (this.opened) { + this.close(); + } else { + this.open(); + } + } + #resizeObserverCallback() { + const { + bar + } = this; + bar.classList.remove("wrapContainers"); + const findbarHeight = bar.clientHeight; + const inputContainerHeight = bar.firstElementChild.clientHeight; + if (findbarHeight > inputContainerHeight) { + bar.classList.add("wrapContainers"); + } + } +} + +;// ./web/pdf_history.js + + + +const HASH_CHANGE_TIMEOUT = 1000; +const POSITION_UPDATED_THRESHOLD = 50; +const UPDATE_VIEWAREA_TIMEOUT = 1000; +function getCurrentHash() { + return document.location.hash; +} +class PDFHistory { + #eventAbortController = null; + constructor({ + linkService, + eventBus + }) { + this.linkService = linkService; + this.eventBus = eventBus; + this._initialized = false; + this._fingerprint = ""; + this.reset(); + this.eventBus._on("pagesinit", () => { + this._isPagesLoaded = false; + this.eventBus._on("pagesloaded", evt => { + this._isPagesLoaded = !!evt.pagesCount; + }, { + once: true + }); + }); + } + initialize({ + fingerprint, + resetHistory = false, + updateUrl = false + }) { + if (!fingerprint || typeof fingerprint !== "string") { + console.error('PDFHistory.initialize: The "fingerprint" must be a non-empty string.'); + return; + } + if (this._initialized) { + this.reset(); + } + const reInitialized = this._fingerprint !== "" && this._fingerprint !== fingerprint; + this._fingerprint = fingerprint; + this._updateUrl = updateUrl === true; + this._initialized = true; + this.#bindEvents(); + const state = window.history.state; + this._popStateInProgress = false; + this._blockHashChange = 0; + this._currentHash = getCurrentHash(); + this._numPositionUpdates = 0; + this._uid = this._maxUid = 0; + this._destination = null; + this._position = null; + if (!this.#isValidState(state, true) || resetHistory) { + const { + hash, + page, + rotation + } = this.#parseCurrentHash(true); + if (!hash || reInitialized || resetHistory) { + this.#pushOrReplaceState(null, true); + return; + } + this.#pushOrReplaceState({ + hash, + page, + rotation + }, true); + return; + } + const destination = state.destination; + this.#updateInternalState(destination, state.uid, true); + if (destination.rotation !== undefined) { + this._initialRotation = destination.rotation; + } + if (destination.dest) { + this._initialBookmark = JSON.stringify(destination.dest); + this._destination.page = null; + } else if (destination.hash) { + this._initialBookmark = destination.hash; + } else if (destination.page) { + this._initialBookmark = `page=${destination.page}`; + } + } + reset() { + if (this._initialized) { + this.#pageHide(); + this._initialized = false; + this.#unbindEvents(); + } + if (this._updateViewareaTimeout) { + clearTimeout(this._updateViewareaTimeout); + this._updateViewareaTimeout = null; + } + this._initialBookmark = null; + this._initialRotation = null; + } + push({ + namedDest = null, + explicitDest, + pageNumber + }) { + if (!this._initialized) { + return; + } + if (namedDest && typeof namedDest !== "string") { + console.error("PDFHistory.push: " + `"${namedDest}" is not a valid namedDest parameter.`); + return; + } else if (!Array.isArray(explicitDest)) { + console.error("PDFHistory.push: " + `"${explicitDest}" is not a valid explicitDest parameter.`); + return; + } else if (!this.#isValidPage(pageNumber)) { + if (pageNumber !== null || this._destination) { + console.error("PDFHistory.push: " + `"${pageNumber}" is not a valid pageNumber parameter.`); + return; + } + } + const hash = namedDest || JSON.stringify(explicitDest); + if (!hash) { + return; + } + let forceReplace = false; + if (this._destination && (isDestHashesEqual(this._destination.hash, hash) || isDestArraysEqual(this._destination.dest, explicitDest))) { + if (this._destination.page) { + return; + } + forceReplace = true; + } + if (this._popStateInProgress && !forceReplace) { + return; + } + this.#pushOrReplaceState({ + dest: explicitDest, + hash, + page: pageNumber, + rotation: this.linkService.rotation + }, forceReplace); + if (!this._popStateInProgress) { + this._popStateInProgress = true; + Promise.resolve().then(() => { + this._popStateInProgress = false; + }); + } + } + pushPage(pageNumber) { + if (!this._initialized) { + return; + } + if (!this.#isValidPage(pageNumber)) { + console.error(`PDFHistory.pushPage: "${pageNumber}" is not a valid page number.`); + return; + } + if (this._destination?.page === pageNumber) { + return; + } + if (this._popStateInProgress) { + return; + } + this.#pushOrReplaceState({ + dest: null, + hash: `page=${pageNumber}`, + page: pageNumber, + rotation: this.linkService.rotation + }); + if (!this._popStateInProgress) { + this._popStateInProgress = true; + Promise.resolve().then(() => { + this._popStateInProgress = false; + }); + } + } + pushCurrentPosition() { + if (!this._initialized || this._popStateInProgress) { + return; + } + this.#tryPushCurrentPosition(); + } + back() { + if (!this._initialized || this._popStateInProgress) { + return; + } + const state = window.history.state; + if (this.#isValidState(state) && state.uid > 0) { + window.history.back(); + } + } + forward() { + if (!this._initialized || this._popStateInProgress) { + return; + } + const state = window.history.state; + if (this.#isValidState(state) && state.uid < this._maxUid) { + window.history.forward(); + } + } + get popStateInProgress() { + return this._initialized && (this._popStateInProgress || this._blockHashChange > 0); + } + get initialBookmark() { + return this._initialized ? this._initialBookmark : null; + } + get initialRotation() { + return this._initialized ? this._initialRotation : null; + } + #pushOrReplaceState(destination, forceReplace = false) { + const shouldReplace = forceReplace || !this._destination; + const newState = { + fingerprint: this._fingerprint, + uid: shouldReplace ? this._uid : this._uid + 1, + destination + }; + this.#updateInternalState(destination, newState.uid); + let newUrl; + if (this._updateUrl && destination?.hash) { + const { + href, + protocol + } = document.location; + if (protocol !== "file:") { + newUrl = updateUrlHash(href, destination.hash); + } + } + if (shouldReplace) { + window.history.replaceState(newState, "", newUrl); + } else { + window.history.pushState(newState, "", newUrl); + } + } + #tryPushCurrentPosition(temporary = false) { + if (!this._position) { + return; + } + let position = this._position; + if (temporary) { + position = Object.assign(Object.create(null), this._position); + position.temporary = true; + } + if (!this._destination) { + this.#pushOrReplaceState(position); + return; + } + if (this._destination.temporary) { + this.#pushOrReplaceState(position, true); + return; + } + if (this._destination.hash === position.hash) { + return; + } + if (!this._destination.page && (POSITION_UPDATED_THRESHOLD <= 0 || this._numPositionUpdates <= POSITION_UPDATED_THRESHOLD)) { + return; + } + let forceReplace = false; + if (this._destination.page >= position.first && this._destination.page <= position.page) { + if (this._destination.dest !== undefined || !this._destination.first) { + return; + } + forceReplace = true; + } + this.#pushOrReplaceState(position, forceReplace); + } + #isValidPage(val) { + return Number.isInteger(val) && val > 0 && val <= this.linkService.pagesCount; + } + #isValidState(state, checkReload = false) { + if (!state) { + return false; + } + if (state.fingerprint !== this._fingerprint) { + if (checkReload) { + if (typeof state.fingerprint !== "string" || state.fingerprint.length !== this._fingerprint.length) { + return false; + } + const [perfEntry] = performance.getEntriesByType("navigation"); + if (perfEntry?.type !== "reload") { + return false; + } + } else { + return false; + } + } + if (!Number.isInteger(state.uid) || state.uid < 0) { + return false; + } + if (state.destination === null || typeof state.destination !== "object") { + return false; + } + return true; + } + #updateInternalState(destination, uid, removeTemporary = false) { + if (this._updateViewareaTimeout) { + clearTimeout(this._updateViewareaTimeout); + this._updateViewareaTimeout = null; + } + if (removeTemporary && destination?.temporary) { + delete destination.temporary; + } + this._destination = destination; + this._uid = uid; + this._maxUid = Math.max(this._maxUid, uid); + this._numPositionUpdates = 0; + } + #parseCurrentHash(checkNameddest = false) { + const hash = unescape(getCurrentHash()).substring(1); + const params = parseQueryString(hash); + const nameddest = params.get("nameddest") || ""; + let page = params.get("page") | 0; + if (!this.#isValidPage(page) || checkNameddest && nameddest.length > 0) { + page = null; + } + return { + hash, + page, + rotation: this.linkService.rotation + }; + } + #updateViewarea({ + location + }) { + if (this._updateViewareaTimeout) { + clearTimeout(this._updateViewareaTimeout); + this._updateViewareaTimeout = null; + } + this._position = { + hash: location.pdfOpenParams.substring(1), + page: this.linkService.page, + first: location.pageNumber, + rotation: location.rotation + }; + if (this._popStateInProgress) { + return; + } + if (POSITION_UPDATED_THRESHOLD > 0 && this._isPagesLoaded && this._destination && !this._destination.page) { + this._numPositionUpdates++; + } + if (UPDATE_VIEWAREA_TIMEOUT > 0) { + this._updateViewareaTimeout = setTimeout(() => { + if (!this._popStateInProgress) { + this.#tryPushCurrentPosition(true); + } + this._updateViewareaTimeout = null; + }, UPDATE_VIEWAREA_TIMEOUT); + } + } + #popState({ + state + }) { + const newHash = getCurrentHash(), + hashChanged = this._currentHash !== newHash; + this._currentHash = newHash; + if (!state) { + this._uid++; + const { + hash, + page, + rotation + } = this.#parseCurrentHash(); + this.#pushOrReplaceState({ + hash, + page, + rotation + }, true); + return; + } + if (!this.#isValidState(state)) { + return; + } + this._popStateInProgress = true; + if (hashChanged) { + this._blockHashChange++; + waitOnEventOrTimeout({ + target: window, + name: "hashchange", + delay: HASH_CHANGE_TIMEOUT + }).then(() => { + this._blockHashChange--; + }); + } + const destination = state.destination; + this.#updateInternalState(destination, state.uid, true); + if (isValidRotation(destination.rotation)) { + this.linkService.rotation = destination.rotation; + } + if (destination.dest) { + this.linkService.goToDestination(destination.dest); + } else if (destination.hash) { + this.linkService.setHash(destination.hash); + } else if (destination.page) { + this.linkService.page = destination.page; + } + Promise.resolve().then(() => { + this._popStateInProgress = false; + }); + } + #pageHide() { + if (!this._destination || this._destination.temporary) { + this.#tryPushCurrentPosition(); + } + } + #bindEvents() { + if (this.#eventAbortController) { + return; + } + this.#eventAbortController = new AbortController(); + const { + signal + } = this.#eventAbortController; + this.eventBus._on("updateviewarea", this.#updateViewarea.bind(this), { + signal + }); + window.addEventListener("popstate", this.#popState.bind(this), { + signal + }); + window.addEventListener("pagehide", this.#pageHide.bind(this), { + signal + }); + } + #unbindEvents() { + this.#eventAbortController?.abort(); + this.#eventAbortController = null; + } +} +function isDestHashesEqual(destHash, pushHash) { + if (typeof destHash !== "string" || typeof pushHash !== "string") { + return false; + } + if (destHash === pushHash) { + return true; + } + const nameddest = parseQueryString(destHash).get("nameddest"); + if (nameddest === pushHash) { + return true; + } + return false; +} +function isDestArraysEqual(firstDest, secondDest) { + function isEntryEqual(first, second) { + if (typeof first !== typeof second) { + return false; + } + if (Array.isArray(first) || Array.isArray(second)) { + return false; + } + if (first !== null && typeof first === "object" && second !== null) { + if (Object.keys(first).length !== Object.keys(second).length) { + return false; + } + for (const key in first) { + if (!isEntryEqual(first[key], second[key])) { + return false; + } + } + return true; + } + return first === second || Number.isNaN(first) && Number.isNaN(second); + } + if (!(Array.isArray(firstDest) && Array.isArray(secondDest))) { + return false; + } + if (firstDest.length !== secondDest.length) { + return false; + } + for (let i = 0, ii = firstDest.length; i < ii; i++) { + if (!isEntryEqual(firstDest[i], secondDest[i])) { + return false; + } + } + return true; +} + +;// ./web/pdf_layer_viewer.js + +class PDFLayerViewer extends BaseTreeViewer { + constructor(options) { + super(options); + this.eventBus._on("optionalcontentconfigchanged", evt => { + this.#updateLayers(evt.promise); + }); + this.eventBus._on("resetlayers", () => { + this.#updateLayers(); + }); + this.eventBus._on("togglelayerstree", this._toggleAllTreeItems.bind(this)); + } + reset() { + super.reset(); + this._optionalContentConfig = null; + this._optionalContentVisibility?.clear(); + this._optionalContentVisibility = null; + } + _dispatchEvent(layersCount) { + this.eventBus.dispatch("layersloaded", { + source: this, + layersCount + }); + } + _bindLink(element, { + groupId, + input + }) { + const setVisibility = () => { + const visible = input.checked; + this._optionalContentConfig.setVisibility(groupId, visible); + const cached = this._optionalContentVisibility.get(groupId); + if (cached) { + cached.visible = visible; + } + this.eventBus.dispatch("optionalcontentconfig", { + source: this, + promise: Promise.resolve(this._optionalContentConfig) + }); + }; + element.onclick = evt => { + if (evt.target === input) { + setVisibility(); + return true; + } else if (evt.target !== element) { + return true; + } + input.checked = !input.checked; + setVisibility(); + return false; + }; + } + _setNestedName(element, { + name = null + }) { + if (typeof name === "string") { + element.textContent = this._normalizeTextContent(name); + return; + } + element.setAttribute("data-l10n-id", "pdfjs-additional-layers"); + element.style.fontStyle = "italic"; + this._l10n.translateOnce(element); + } + _addToggleButton(div, { + name = null + }) { + super._addToggleButton(div, name === null); + } + _toggleAllTreeItems() { + if (!this._optionalContentConfig) { + return; + } + super._toggleAllTreeItems(); + } + render({ + optionalContentConfig, + pdfDocument + }) { + if (this._optionalContentConfig) { + this.reset(); + } + this._optionalContentConfig = optionalContentConfig || null; + this._pdfDocument = pdfDocument || null; + const groups = optionalContentConfig?.getOrder(); + if (!groups) { + this._dispatchEvent(0); + return; + } + this._optionalContentVisibility = new Map(); + const fragment = document.createDocumentFragment(), + queue = [{ + parent: fragment, + groups + }]; + let layersCount = 0, + hasAnyNesting = false; + while (queue.length > 0) { + const levelData = queue.shift(); + for (const groupId of levelData.groups) { + const div = document.createElement("div"); + div.className = "treeItem"; + const element = document.createElement("a"); + div.append(element); + if (typeof groupId === "object") { + hasAnyNesting = true; + this._addToggleButton(div, groupId); + this._setNestedName(element, groupId); + const itemsDiv = document.createElement("div"); + itemsDiv.className = "treeItems"; + div.append(itemsDiv); + queue.push({ + parent: itemsDiv, + groups: groupId.order + }); + } else { + const group = optionalContentConfig.getGroup(groupId); + const label = document.createElement("label"); + const input = document.createElement("input"); + label.append(input, document.createTextNode(this._normalizeTextContent(group.name))); + this._bindLink(element, { + groupId, + input + }); + input.type = "checkbox"; + input.checked = group.visible; + this._optionalContentVisibility.set(groupId, { + input, + visible: input.checked + }); + element.append(label); + layersCount++; + } + levelData.parent.append(div); + } + } + this._finishRendering(fragment, layersCount, hasAnyNesting); + } + async #updateLayers(promise = null) { + if (!this._optionalContentConfig) { + return; + } + const pdfDocument = this._pdfDocument; + const optionalContentConfig = await (promise || pdfDocument.getOptionalContentConfig({ + intent: "display" + })); + if (pdfDocument !== this._pdfDocument) { + return; + } + if (promise) { + for (const [groupId, cached] of this._optionalContentVisibility) { + const group = optionalContentConfig.getGroup(groupId); + if (group && cached.visible !== group.visible) { + cached.input.checked = cached.visible = !cached.visible; + } + } + return; + } + this.eventBus.dispatch("optionalcontentconfig", { + source: this, + promise: Promise.resolve(optionalContentConfig) + }); + this.render({ + optionalContentConfig, + pdfDocument: this._pdfDocument + }); + } +} + +;// ./web/pdf_outline_viewer.js + + +class PDFOutlineViewer extends BaseTreeViewer { + constructor(options) { + super(options); + this.linkService = options.linkService; + this.downloadManager = options.downloadManager; + this.eventBus._on("toggleoutlinetree", this._toggleAllTreeItems.bind(this)); + this.eventBus._on("currentoutlineitem", this._currentOutlineItem.bind(this)); + this.eventBus._on("pagechanging", evt => { + this._currentPageNumber = evt.pageNumber; + }); + this.eventBus._on("pagesloaded", evt => { + this._isPagesLoaded = !!evt.pagesCount; + this._currentOutlineItemCapability?.resolve(this._isPagesLoaded); + }); + this.eventBus._on("sidebarviewchanged", evt => { + this._sidebarView = evt.view; + }); + } + reset() { + super.reset(); + this._outline = null; + this._pageNumberToDestHashCapability = null; + this._currentPageNumber = 1; + this._isPagesLoaded = null; + this._currentOutlineItemCapability?.resolve(false); + this._currentOutlineItemCapability = null; + } + _dispatchEvent(outlineCount) { + this._currentOutlineItemCapability = Promise.withResolvers(); + if (outlineCount === 0 || this._pdfDocument?.loadingParams.disableAutoFetch) { + this._currentOutlineItemCapability.resolve(false); + } else if (this._isPagesLoaded !== null) { + this._currentOutlineItemCapability.resolve(this._isPagesLoaded); + } + this.eventBus.dispatch("outlineloaded", { + source: this, + outlineCount, + currentOutlineItemPromise: this._currentOutlineItemCapability.promise + }); + } + _bindLink(element, { + url, + newWindow, + action, + attachment, + dest, + setOCGState + }) { + const { + linkService + } = this; + if (url) { + linkService.addLinkAttributes(element, url, newWindow); + return; + } + if (action) { + element.href = linkService.getAnchorUrl(""); + element.onclick = () => { + linkService.executeNamedAction(action); + return false; + }; + return; + } + if (attachment) { + element.href = linkService.getAnchorUrl(""); + element.onclick = () => { + this.downloadManager.openOrDownloadData(attachment.content, attachment.filename); + return false; + }; + return; + } + if (setOCGState) { + element.href = linkService.getAnchorUrl(""); + element.onclick = () => { + linkService.executeSetOCGState(setOCGState); + return false; + }; + return; + } + element.href = linkService.getDestinationHash(dest); + element.onclick = evt => { + this._updateCurrentTreeItem(evt.target.parentNode); + if (dest) { + linkService.goToDestination(dest); + } + return false; + }; + } + _setStyles(element, { + bold, + italic + }) { + if (bold) { + element.style.fontWeight = "bold"; + } + if (italic) { + element.style.fontStyle = "italic"; + } + } + _addToggleButton(div, { + count, + items + }) { + let hidden = false; + if (count < 0) { + let totalCount = items.length; + if (totalCount > 0) { + const queue = [...items]; + while (queue.length > 0) { + const { + count: nestedCount, + items: nestedItems + } = queue.shift(); + if (nestedCount > 0 && nestedItems.length > 0) { + totalCount += nestedItems.length; + queue.push(...nestedItems); + } + } + } + if (Math.abs(count) === totalCount) { + hidden = true; + } + } + super._addToggleButton(div, hidden); + } + _toggleAllTreeItems() { + if (!this._outline) { + return; + } + super._toggleAllTreeItems(); + } + render({ + outline, + pdfDocument + }) { + if (this._outline) { + this.reset(); + } + this._outline = outline || null; + this._pdfDocument = pdfDocument || null; + if (!outline) { + this._dispatchEvent(0); + return; + } + const fragment = document.createDocumentFragment(); + const queue = [{ + parent: fragment, + items: outline + }]; + let outlineCount = 0, + hasAnyNesting = false; + while (queue.length > 0) { + const levelData = queue.shift(); + for (const item of levelData.items) { + const div = document.createElement("div"); + div.className = "treeItem"; + const element = document.createElement("a"); + this._bindLink(element, item); + this._setStyles(element, item); + element.textContent = this._normalizeTextContent(item.title); + div.append(element); + if (item.items.length > 0) { + hasAnyNesting = true; + this._addToggleButton(div, item); + const itemsDiv = document.createElement("div"); + itemsDiv.className = "treeItems"; + div.append(itemsDiv); + queue.push({ + parent: itemsDiv, + items: item.items + }); + } + levelData.parent.append(div); + outlineCount++; + } + } + this._finishRendering(fragment, outlineCount, hasAnyNesting); + } + async _currentOutlineItem() { + if (!this._isPagesLoaded) { + throw new Error("_currentOutlineItem: All pages have not been loaded."); + } + if (!this._outline || !this._pdfDocument) { + return; + } + const pageNumberToDestHash = await this._getPageNumberToDestHash(this._pdfDocument); + if (!pageNumberToDestHash) { + return; + } + this._updateCurrentTreeItem(null); + if (this._sidebarView !== SidebarView.OUTLINE) { + return; + } + for (let i = this._currentPageNumber; i > 0; i--) { + const destHash = pageNumberToDestHash.get(i); + if (!destHash) { + continue; + } + const linkElement = this.container.querySelector(`a[href="${destHash}"]`); + if (!linkElement) { + continue; + } + this._scrollToCurrentTreeItem(linkElement.parentNode); + break; + } + } + async _getPageNumberToDestHash(pdfDocument) { + if (this._pageNumberToDestHashCapability) { + return this._pageNumberToDestHashCapability.promise; + } + this._pageNumberToDestHashCapability = Promise.withResolvers(); + const pageNumberToDestHash = new Map(), + pageNumberNesting = new Map(); + const queue = [{ + nesting: 0, + items: this._outline + }]; + while (queue.length > 0) { + const levelData = queue.shift(), + currentNesting = levelData.nesting; + for (const { + dest, + items + } of levelData.items) { + let explicitDest, pageNumber; + if (typeof dest === "string") { + explicitDest = await pdfDocument.getDestination(dest); + if (pdfDocument !== this._pdfDocument) { + return null; + } + } else { + explicitDest = dest; + } + if (Array.isArray(explicitDest)) { + const [destRef] = explicitDest; + if (destRef && typeof destRef === "object") { + pageNumber = pdfDocument.cachedPageNumber(destRef); + } else if (Number.isInteger(destRef)) { + pageNumber = destRef + 1; + } + if (Number.isInteger(pageNumber) && (!pageNumberToDestHash.has(pageNumber) || currentNesting > pageNumberNesting.get(pageNumber))) { + const destHash = this.linkService.getDestinationHash(dest); + pageNumberToDestHash.set(pageNumber, destHash); + pageNumberNesting.set(pageNumber, currentNesting); + } + } + if (items.length > 0) { + queue.push({ + nesting: currentNesting + 1, + items + }); + } + } + } + this._pageNumberToDestHashCapability.resolve(pageNumberToDestHash.size > 0 ? pageNumberToDestHash : null); + return this._pageNumberToDestHashCapability.promise; + } +} + +;// ./web/pdf_presentation_mode.js + + +const DELAY_BEFORE_HIDING_CONTROLS = 3000; +const ACTIVE_SELECTOR = "pdfPresentationMode"; +const CONTROLS_SELECTOR = "pdfPresentationModeControls"; +const MOUSE_SCROLL_COOLDOWN_TIME = 50; +const PAGE_SWITCH_THRESHOLD = 0.1; +const SWIPE_MIN_DISTANCE_THRESHOLD = 50; +const SWIPE_ANGLE_THRESHOLD = Math.PI / 6; +class PDFPresentationMode { + #state = PresentationModeState.UNKNOWN; + #args = null; + #fullscreenChangeAbortController = null; + #windowAbortController = null; + constructor({ + container, + pdfViewer, + eventBus + }) { + this.container = container; + this.pdfViewer = pdfViewer; + this.eventBus = eventBus; + this.contextMenuOpen = false; + this.mouseScrollTimeStamp = 0; + this.mouseScrollDelta = 0; + this.touchSwipeState = null; + } + async request() { + const { + container, + pdfViewer + } = this; + if (this.active || !pdfViewer.pagesCount || !container.requestFullscreen) { + return false; + } + this.#addFullscreenChangeListeners(); + this.#notifyStateChange(PresentationModeState.CHANGING); + const promise = container.requestFullscreen(); + this.#args = { + pageNumber: pdfViewer.currentPageNumber, + scaleValue: pdfViewer.currentScaleValue, + scrollMode: pdfViewer.scrollMode, + spreadMode: null, + annotationEditorMode: null + }; + if (pdfViewer.spreadMode !== SpreadMode.NONE && !(pdfViewer.pageViewsReady && pdfViewer.hasEqualPageSizes)) { + console.warn("Ignoring Spread modes when entering PresentationMode, " + "since the document may contain varying page sizes."); + this.#args.spreadMode = pdfViewer.spreadMode; + } + if (pdfViewer.annotationEditorMode !== AnnotationEditorType.DISABLE) { + this.#args.annotationEditorMode = pdfViewer.annotationEditorMode; + } + try { + await promise; + pdfViewer.focus(); + return true; + } catch { + this.#removeFullscreenChangeListeners(); + this.#notifyStateChange(PresentationModeState.NORMAL); + } + return false; + } + get active() { + return this.#state === PresentationModeState.CHANGING || this.#state === PresentationModeState.FULLSCREEN; + } + #mouseWheel(evt) { + if (!this.active) { + return; + } + evt.preventDefault(); + const delta = normalizeWheelEventDelta(evt); + const currentTime = Date.now(); + const storedTime = this.mouseScrollTimeStamp; + if (currentTime > storedTime && currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) { + return; + } + if (this.mouseScrollDelta > 0 && delta < 0 || this.mouseScrollDelta < 0 && delta > 0) { + this.#resetMouseScrollState(); + } + this.mouseScrollDelta += delta; + if (Math.abs(this.mouseScrollDelta) >= PAGE_SWITCH_THRESHOLD) { + const totalDelta = this.mouseScrollDelta; + this.#resetMouseScrollState(); + const success = totalDelta > 0 ? this.pdfViewer.previousPage() : this.pdfViewer.nextPage(); + if (success) { + this.mouseScrollTimeStamp = currentTime; + } + } + } + #notifyStateChange(state) { + this.#state = state; + this.eventBus.dispatch("presentationmodechanged", { + source: this, + state + }); + } + #enter() { + this.#notifyStateChange(PresentationModeState.FULLSCREEN); + this.container.classList.add(ACTIVE_SELECTOR); + setTimeout(() => { + this.pdfViewer.scrollMode = ScrollMode.PAGE; + if (this.#args.spreadMode !== null) { + this.pdfViewer.spreadMode = SpreadMode.NONE; + } + this.pdfViewer.currentPageNumber = this.#args.pageNumber; + this.pdfViewer.currentScaleValue = "page-fit"; + if (this.#args.annotationEditorMode !== null) { + this.pdfViewer.annotationEditorMode = { + mode: AnnotationEditorType.NONE + }; + } + }, 0); + this.#addWindowListeners(); + this.#showControls(); + this.contextMenuOpen = false; + document.getSelection().empty(); + } + #exit() { + const pageNumber = this.pdfViewer.currentPageNumber; + this.container.classList.remove(ACTIVE_SELECTOR); + setTimeout(() => { + this.#removeFullscreenChangeListeners(); + this.#notifyStateChange(PresentationModeState.NORMAL); + this.pdfViewer.scrollMode = this.#args.scrollMode; + if (this.#args.spreadMode !== null) { + this.pdfViewer.spreadMode = this.#args.spreadMode; + } + this.pdfViewer.currentScaleValue = this.#args.scaleValue; + this.pdfViewer.currentPageNumber = pageNumber; + if (this.#args.annotationEditorMode !== null) { + this.pdfViewer.annotationEditorMode = { + mode: this.#args.annotationEditorMode + }; + } + this.#args = null; + }, 0); + this.#removeWindowListeners(); + this.#hideControls(); + this.#resetMouseScrollState(); + this.contextMenuOpen = false; + } + #mouseDown(evt) { + if (this.contextMenuOpen) { + this.contextMenuOpen = false; + evt.preventDefault(); + return; + } + if (evt.button !== 0) { + return; + } + if (evt.target.href && evt.target.parentNode?.hasAttribute("data-internal-link")) { + return; + } + evt.preventDefault(); + if (evt.shiftKey) { + this.pdfViewer.previousPage(); + } else { + this.pdfViewer.nextPage(); + } + } + #contextMenu() { + this.contextMenuOpen = true; + } + #showControls() { + if (this.controlsTimeout) { + clearTimeout(this.controlsTimeout); + } else { + this.container.classList.add(CONTROLS_SELECTOR); + } + this.controlsTimeout = setTimeout(() => { + this.container.classList.remove(CONTROLS_SELECTOR); + delete this.controlsTimeout; + }, DELAY_BEFORE_HIDING_CONTROLS); + } + #hideControls() { + if (!this.controlsTimeout) { + return; + } + clearTimeout(this.controlsTimeout); + this.container.classList.remove(CONTROLS_SELECTOR); + delete this.controlsTimeout; + } + #resetMouseScrollState() { + this.mouseScrollTimeStamp = 0; + this.mouseScrollDelta = 0; + } + #touchSwipe(evt) { + if (!this.active) { + return; + } + if (evt.touches.length > 1) { + this.touchSwipeState = null; + return; + } + switch (evt.type) { + case "touchstart": + this.touchSwipeState = { + startX: evt.touches[0].pageX, + startY: evt.touches[0].pageY, + endX: evt.touches[0].pageX, + endY: evt.touches[0].pageY + }; + break; + case "touchmove": + if (this.touchSwipeState === null) { + return; + } + this.touchSwipeState.endX = evt.touches[0].pageX; + this.touchSwipeState.endY = evt.touches[0].pageY; + evt.preventDefault(); + break; + case "touchend": + if (this.touchSwipeState === null) { + return; + } + let delta = 0; + const dx = this.touchSwipeState.endX - this.touchSwipeState.startX; + const dy = this.touchSwipeState.endY - this.touchSwipeState.startY; + const absAngle = Math.abs(Math.atan2(dy, dx)); + if (Math.abs(dx) > SWIPE_MIN_DISTANCE_THRESHOLD && (absAngle <= SWIPE_ANGLE_THRESHOLD || absAngle >= Math.PI - SWIPE_ANGLE_THRESHOLD)) { + delta = dx; + } else if (Math.abs(dy) > SWIPE_MIN_DISTANCE_THRESHOLD && Math.abs(absAngle - Math.PI / 2) <= SWIPE_ANGLE_THRESHOLD) { + delta = dy; + } + if (delta > 0) { + this.pdfViewer.previousPage(); + } else if (delta < 0) { + this.pdfViewer.nextPage(); + } + break; + } + } + #addWindowListeners() { + if (this.#windowAbortController) { + return; + } + this.#windowAbortController = new AbortController(); + const { + signal + } = this.#windowAbortController; + const touchSwipeBind = this.#touchSwipe.bind(this); + window.addEventListener("mousemove", this.#showControls.bind(this), { + signal + }); + window.addEventListener("mousedown", this.#mouseDown.bind(this), { + signal + }); + window.addEventListener("wheel", this.#mouseWheel.bind(this), { + passive: false, + signal + }); + window.addEventListener("keydown", this.#resetMouseScrollState.bind(this), { + signal + }); + window.addEventListener("contextmenu", this.#contextMenu.bind(this), { + signal + }); + window.addEventListener("touchstart", touchSwipeBind, { + signal + }); + window.addEventListener("touchmove", touchSwipeBind, { + signal + }); + window.addEventListener("touchend", touchSwipeBind, { + signal + }); + } + #removeWindowListeners() { + this.#windowAbortController?.abort(); + this.#windowAbortController = null; + } + #addFullscreenChangeListeners() { + if (this.#fullscreenChangeAbortController) { + return; + } + this.#fullscreenChangeAbortController = new AbortController(); + window.addEventListener("fullscreenchange", () => { + if (document.fullscreenElement) { + this.#enter(); + } else { + this.#exit(); + } + }, { + signal: this.#fullscreenChangeAbortController.signal + }); + } + #removeFullscreenChangeListeners() { + this.#fullscreenChangeAbortController?.abort(); + this.#fullscreenChangeAbortController = null; + } +} + +;// ./web/xfa_layer_builder.js + +class XfaLayerBuilder { + constructor({ + pdfPage, + annotationStorage = null, + linkService, + xfaHtml = null + }) { + this.pdfPage = pdfPage; + this.annotationStorage = annotationStorage; + this.linkService = linkService; + this.xfaHtml = xfaHtml; + this.div = null; + this._cancelled = false; + } + async render({ + viewport, + intent = "display" + }) { + if (intent === "print") { + const parameters = { + viewport: viewport.clone({ + dontFlip: true + }), + div: this.div, + xfaHtml: this.xfaHtml, + annotationStorage: this.annotationStorage, + linkService: this.linkService, + intent + }; + this.div = document.createElement("div"); + parameters.div = this.div; + return XfaLayer.render(parameters); + } + const xfaHtml = await this.pdfPage.getXfa(); + if (this._cancelled || !xfaHtml) { + return { + textDivs: [] + }; + } + const parameters = { + viewport: viewport.clone({ + dontFlip: true + }), + div: this.div, + xfaHtml, + annotationStorage: this.annotationStorage, + linkService: this.linkService, + intent + }; + if (this.div) { + return XfaLayer.update(parameters); + } + this.div = document.createElement("div"); + parameters.div = this.div; + return XfaLayer.render(parameters); + } + cancel() { + this._cancelled = true; + } + hide() { + if (!this.div) { + return; + } + this.div.hidden = true; + } +} + +;// ./web/print_utils.js + + + +class BasePrintServiceFactory { + static initGlobals(app) {} + static get supportsPrinting() { + throw new Error("Not implemented: supportsPrinting"); + } + static createPrintService(params) { + throw new Error("Not implemented: createPrintService"); + } +} +function getXfaHtmlForPrinting(printContainer, pdfDocument) { + const xfaHtml = pdfDocument.allXfaHtml; + const linkService = new SimpleLinkService(); + const scale = Math.round(PixelsPerInch.PDF_TO_CSS_UNITS * 100) / 100; + for (const xfaPage of xfaHtml.children) { + const page = document.createElement("div"); + page.className = "xfaPrintedPage"; + printContainer.append(page); + const builder = new XfaLayerBuilder({ + pdfPage: null, + annotationStorage: pdfDocument.annotationStorage, + linkService, + xfaHtml: xfaPage + }); + const viewport = getXfaPageViewport(xfaPage, { + scale + }); + builder.render({ + viewport, + intent: "print" + }); + page.append(builder.div); + } +} + +;// ./web/pdf_print_service.js + + +let activeService = null; +let dialog = null; +let overlayManager = null; +let viewerApp = { + initialized: false +}; +function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size, printResolution, optionalContentConfigPromise, printAnnotationStoragePromise) { + const scratchCanvas = activeService.scratchCanvas; + const PRINT_UNITS = printResolution / PixelsPerInch.PDF; + scratchCanvas.width = Math.floor(size.width * PRINT_UNITS); + scratchCanvas.height = Math.floor(size.height * PRINT_UNITS); + const ctx = scratchCanvas.getContext("2d"); + ctx.save(); + ctx.fillStyle = "rgb(255, 255, 255)"; + ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height); + ctx.restore(); + return Promise.all([pdfDocument.getPage(pageNumber), printAnnotationStoragePromise]).then(function ([pdfPage, printAnnotationStorage]) { + const renderContext = { + canvas: scratchCanvas, + transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], + viewport: pdfPage.getViewport({ + scale: 1, + rotation: size.rotation + }), + intent: "print", + annotationMode: AnnotationMode.ENABLE_STORAGE, + optionalContentConfigPromise, + printAnnotationStorage + }; + const renderTask = pdfPage.render(renderContext); + return renderTask.promise.catch(reason => { + if (!(reason instanceof RenderingCancelledException)) { + console.error(reason); + } + throw reason; + }); + }); +} +class PDFPrintService { + constructor({ + pdfDocument, + pagesOverview, + printContainer, + printResolution, + printAnnotationStoragePromise = null + }) { + this.pdfDocument = pdfDocument; + this.pagesOverview = pagesOverview; + this.printContainer = printContainer; + this._printResolution = printResolution || 150; + this._optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({ + intent: "print" + }); + this._printAnnotationStoragePromise = printAnnotationStoragePromise || Promise.resolve(); + this.currentPage = -1; + this.scratchCanvas = document.createElement("canvas"); + } + layout() { + this.throwIfInactive(); + const body = document.querySelector("body"); + body.setAttribute("data-pdfjsprinting", true); + const { + width, + height + } = this.pagesOverview[0]; + const hasEqualPageSizes = this.pagesOverview.every(size => size.width === width && size.height === height); + if (!hasEqualPageSizes) { + console.warn("Not all pages have the same size. The printed result may be incorrect!"); + } + this.pageStyleSheet = document.createElement("style"); + this.pageStyleSheet.textContent = `@page { size: ${width}pt ${height}pt;}`; + body.append(this.pageStyleSheet); + } + destroy() { + if (activeService !== this) { + return; + } + this.printContainer.textContent = ""; + const body = document.querySelector("body"); + body.removeAttribute("data-pdfjsprinting"); + if (this.pageStyleSheet) { + this.pageStyleSheet.remove(); + this.pageStyleSheet = null; + } + this.scratchCanvas.width = this.scratchCanvas.height = 0; + this.scratchCanvas = null; + activeService = null; + ensureOverlay().then(function () { + overlayManager.closeIfActive(dialog); + }); + } + renderPages() { + if (this.pdfDocument.isPureXfa) { + getXfaHtmlForPrinting(this.printContainer, this.pdfDocument); + return Promise.resolve(); + } + const pageCount = this.pagesOverview.length; + const renderNextPage = (resolve, reject) => { + this.throwIfInactive(); + if (++this.currentPage >= pageCount) { + renderProgress(pageCount, pageCount); + resolve(); + return; + } + const index = this.currentPage; + renderProgress(index, pageCount); + renderPage(this, this.pdfDocument, index + 1, this.pagesOverview[index], this._printResolution, this._optionalContentConfigPromise, this._printAnnotationStoragePromise).then(this.useRenderedPage.bind(this)).then(function () { + renderNextPage(resolve, reject); + }, reject); + }; + return new Promise(renderNextPage); + } + useRenderedPage() { + this.throwIfInactive(); + const img = document.createElement("img"); + this.scratchCanvas.toBlob(blob => { + img.src = URL.createObjectURL(blob); + }); + const wrapper = document.createElement("div"); + wrapper.className = "printedPage"; + wrapper.append(img); + this.printContainer.append(wrapper); + const { + promise, + resolve, + reject + } = Promise.withResolvers(); + img.onload = resolve; + img.onerror = reject; + promise.catch(() => {}).then(() => { + URL.revokeObjectURL(img.src); + }); + return promise; + } + performPrint() { + this.throwIfInactive(); + return new Promise(resolve => { + setTimeout(() => { + if (!this.active) { + resolve(); + return; + } + print.call(window); + setTimeout(resolve, 20); + }, 0); + }); + } + get active() { + return this === activeService; + } + throwIfInactive() { + if (!this.active) { + throw new Error("This print request was cancelled or completed."); + } + } +} +const print = window.print; +window.print = function () { + if (activeService) { + console.warn("Ignored window.print() because of a pending print job."); + return; + } + ensureOverlay().then(function () { + if (activeService) { + overlayManager.open(dialog); + } + }); + try { + dispatchEvent("beforeprint"); + } finally { + if (!activeService) { + console.error("Expected print service to be initialized."); + ensureOverlay().then(function () { + overlayManager.closeIfActive(dialog); + }); + } else { + const activeServiceOnEntry = activeService; + activeService.renderPages().then(() => activeServiceOnEntry.performPrint()).catch(() => {}).then(() => { + if (activeServiceOnEntry.active) { + abort(); + } + }); + } + } +}; +function dispatchEvent(eventType) { + const event = new CustomEvent(eventType, { + bubbles: false, + cancelable: false, + detail: "custom" + }); + window.dispatchEvent(event); +} +function abort() { + if (activeService) { + activeService.destroy(); + dispatchEvent("afterprint"); + } +} +function renderProgress(index, total) { + dialog ||= document.getElementById("printServiceDialog"); + const progress = Math.round(100 * index / total); + const progressBar = dialog.querySelector("progress"); + const progressPerc = dialog.querySelector(".relative-progress"); + progressBar.value = progress; + progressPerc.setAttribute("data-l10n-args", JSON.stringify({ + progress + })); +} +window.addEventListener("keydown", function (event) { + if (event.keyCode === 80 && (event.ctrlKey || event.metaKey) && !event.altKey && (!event.shiftKey || window.chrome || window.opera)) { + window.print(); + event.preventDefault(); + event.stopImmediatePropagation(); + } +}, true); +if ("onbeforeprint" in window) { + const stopPropagationIfNeeded = function (event) { + if (event.detail !== "custom") { + event.stopImmediatePropagation(); + } + }; + window.addEventListener("beforeprint", stopPropagationIfNeeded); + window.addEventListener("afterprint", stopPropagationIfNeeded); +} +let overlayPromise; +function ensureOverlay() { + if (!overlayPromise) { + overlayManager = viewerApp.overlayManager; + if (!overlayManager) { + throw new Error("The overlay manager has not yet been initialized."); + } + dialog ||= document.getElementById("printServiceDialog"); + overlayPromise = overlayManager.register(dialog, true); + document.getElementById("printCancel").onclick = abort; + dialog.addEventListener("close", abort); + } + return overlayPromise; +} +class PDFPrintServiceFactory extends BasePrintServiceFactory { + static initGlobals(app) { + viewerApp = app; + } + static get supportsPrinting() { + return shadow(this, "supportsPrinting", true); + } + static createPrintService(params) { + if (activeService) { + throw new Error("The print service is created and active."); + } + return activeService = new PDFPrintService(params); + } +} + +;// ./web/renderable_view.js +const RenderingStates = { + INITIAL: 0, + RUNNING: 1, + PAUSED: 2, + FINISHED: 3 +}; +class RenderableView { + renderingId = ""; + renderTask = null; + resume = null; + get renderingState() { + throw new Error("Abstract getter `renderingState` accessed"); + } + set renderingState(state) { + throw new Error("Abstract setter `renderingState` accessed"); + } + async draw() { + throw new Error("Not implemented: draw"); + } +} + +;// ./web/pdf_rendering_queue.js + + +const CLEANUP_TIMEOUT = 30000; +class PDFRenderingQueue { + #highestPriorityPage = null; + #idleTimeout = null; + #pdfThumbnailViewer = null; + #pdfViewer = null; + isThumbnailViewEnabled = false; + onIdle = null; + printing = false; + constructor() { + Object.defineProperty(this, "hasViewer", { + value: () => !!this.#pdfViewer + }); + } + setViewer(pdfViewer) { + this.#pdfViewer = pdfViewer; + } + setThumbnailViewer(pdfThumbnailViewer) { + this.#pdfThumbnailViewer = pdfThumbnailViewer; + } + isHighestPriority(view) { + return this.#highestPriorityPage === view.renderingId; + } + renderHighestPriority(currentlyVisiblePages) { + if (this.#idleTimeout) { + clearTimeout(this.#idleTimeout); + this.#idleTimeout = null; + } + if (this.#pdfViewer.forceRendering(currentlyVisiblePages)) { + return; + } + if (this.isThumbnailViewEnabled && this.#pdfThumbnailViewer?.forceRendering()) { + return; + } + if (this.printing) { + return; + } + if (this.onIdle) { + this.#idleTimeout = setTimeout(this.onIdle.bind(this), CLEANUP_TIMEOUT); + } + } + getHighestPriority(visible, views, scrolledDown, preRenderExtra = false, ignoreDetailViews = false) { + const visibleViews = visible.views, + numVisible = visibleViews.length; + if (numVisible === 0) { + return null; + } + for (let i = 0; i < numVisible; i++) { + const view = visibleViews[i].view; + if (!this.isViewFinished(view)) { + return view; + } + } + if (!ignoreDetailViews) { + for (let i = 0; i < numVisible; i++) { + const { + detailView + } = visibleViews[i].view; + if (detailView && !this.isViewFinished(detailView)) { + return detailView; + } + } + } + const firstId = visible.first.id, + lastId = visible.last.id; + if (lastId - firstId + 1 > numVisible) { + const visibleIds = visible.ids; + for (let i = 1, ii = lastId - firstId; i < ii; i++) { + const holeId = scrolledDown ? firstId + i : lastId - i; + if (visibleIds.has(holeId)) { + continue; + } + const holeView = views[holeId - 1]; + if (!this.isViewFinished(holeView)) { + return holeView; + } + } + } + let preRenderIndex = scrolledDown ? lastId : firstId - 2; + let preRenderView = views[preRenderIndex]; + if (preRenderView && !this.isViewFinished(preRenderView)) { + return preRenderView; + } + if (preRenderExtra) { + preRenderIndex += scrolledDown ? 1 : -1; + preRenderView = views[preRenderIndex]; + if (preRenderView && !this.isViewFinished(preRenderView)) { + return preRenderView; + } + } + return null; + } + isViewFinished(view) { + return view.renderingState === RenderingStates.FINISHED; + } + renderView(view) { + switch (view.renderingState) { + case RenderingStates.FINISHED: + return false; + case RenderingStates.PAUSED: + this.#highestPriorityPage = view.renderingId; + view.resume(); + break; + case RenderingStates.RUNNING: + this.#highestPriorityPage = view.renderingId; + break; + case RenderingStates.INITIAL: + this.#highestPriorityPage = view.renderingId; + view.draw().finally(() => { + this.renderHighestPriority(); + }).catch(reason => { + if (reason instanceof RenderingCancelledException) { + return; + } + console.error("renderView:", reason); + }); + break; + } + return true; + } +} + +;// ./web/pdf_scripting_manager.js + + + +class PDFScriptingManager { + #closeCapability = null; + #destroyCapability = null; + #docProperties = null; + #eventAbortController = null; + #eventBus = null; + #externalServices = null; + #pdfDocument = null; + #pdfViewer = null; + #ready = false; + #scripting = null; + #willPrintCapability = null; + constructor({ + eventBus, + externalServices = null, + docProperties = null + }) { + this.#eventBus = eventBus; + this.#externalServices = externalServices; + this.#docProperties = docProperties; + } + setViewer(pdfViewer) { + this.#pdfViewer = pdfViewer; + } + async setDocument(pdfDocument) { + if (this.#pdfDocument) { + await this.#destroyScripting(); + } + this.#pdfDocument = pdfDocument; + if (!pdfDocument) { + return; + } + const [objects, calculationOrder, docActions] = await Promise.all([pdfDocument.getFieldObjects(), pdfDocument.getCalculationOrderIds(), pdfDocument.getJSActions()]); + if (!objects && !docActions) { + await this.#destroyScripting(); + return; + } + if (pdfDocument !== this.#pdfDocument) { + return; + } + try { + this.#scripting = this.#initScripting(); + } catch (error) { + console.error("setDocument:", error); + await this.#destroyScripting(); + return; + } + const eventBus = this.#eventBus; + this.#eventAbortController = new AbortController(); + const { + signal + } = this.#eventAbortController; + eventBus._on("updatefromsandbox", event => { + if (event?.source === window) { + this.#updateFromSandbox(event.detail); + } + }, { + signal + }); + eventBus._on("dispatcheventinsandbox", event => { + this.#scripting?.dispatchEventInSandbox(event.detail); + }, { + signal + }); + eventBus._on("pagechanging", ({ + pageNumber, + previous + }) => { + if (pageNumber === previous) { + return; + } + this.#dispatchPageClose(previous); + this.#dispatchPageOpen(pageNumber); + }, { + signal + }); + eventBus._on("pagerendered", ({ + pageNumber + }) => { + if (!this._pageOpenPending.has(pageNumber)) { + return; + } + if (pageNumber !== this.#pdfViewer.currentPageNumber) { + return; + } + this.#dispatchPageOpen(pageNumber); + }, { + signal + }); + eventBus._on("pagesdestroy", async () => { + await this.#dispatchPageClose(this.#pdfViewer.currentPageNumber); + await this.#scripting?.dispatchEventInSandbox({ + id: "doc", + name: "WillClose" + }); + this.#closeCapability?.resolve(); + }, { + signal + }); + try { + const docProperties = await this.#docProperties(pdfDocument); + if (pdfDocument !== this.#pdfDocument) { + return; + } + await this.#scripting.createSandbox({ + objects, + calculationOrder, + appInfo: { + platform: navigator.platform, + language: navigator.language + }, + docInfo: { + ...docProperties, + actions: docActions + } + }); + eventBus.dispatch("sandboxcreated", { + source: this + }); + } catch (error) { + console.error("setDocument:", error); + await this.#destroyScripting(); + return; + } + await this.#scripting?.dispatchEventInSandbox({ + id: "doc", + name: "Open" + }); + await this.#dispatchPageOpen(this.#pdfViewer.currentPageNumber, true); + Promise.resolve().then(() => { + if (pdfDocument === this.#pdfDocument) { + this.#ready = true; + } + }); + } + async dispatchWillSave() { + return this.#scripting?.dispatchEventInSandbox({ + id: "doc", + name: "WillSave" + }); + } + async dispatchDidSave() { + return this.#scripting?.dispatchEventInSandbox({ + id: "doc", + name: "DidSave" + }); + } + async dispatchWillPrint() { + if (!this.#scripting) { + return; + } + await this.#willPrintCapability?.promise; + this.#willPrintCapability = Promise.withResolvers(); + try { + await this.#scripting.dispatchEventInSandbox({ + id: "doc", + name: "WillPrint" + }); + } catch (ex) { + this.#willPrintCapability.resolve(); + this.#willPrintCapability = null; + throw ex; + } + await this.#willPrintCapability.promise; + } + async dispatchDidPrint() { + return this.#scripting?.dispatchEventInSandbox({ + id: "doc", + name: "DidPrint" + }); + } + get destroyPromise() { + return this.#destroyCapability?.promise || null; + } + get ready() { + return this.#ready; + } + get _pageOpenPending() { + return shadow(this, "_pageOpenPending", new Set()); + } + get _visitedPages() { + return shadow(this, "_visitedPages", new Map()); + } + async #updateFromSandbox(detail) { + const pdfViewer = this.#pdfViewer; + const isInPresentationMode = pdfViewer.isInPresentationMode || pdfViewer.isChangingPresentationMode; + const { + id, + siblings, + command, + value + } = detail; + if (!id) { + switch (command) { + case "clear": + console.clear(); + break; + case "error": + console.error(value); + break; + case "layout": + if (!isInPresentationMode) { + const modes = apiPageLayoutToViewerModes(value); + pdfViewer.spreadMode = modes.spreadMode; + } + break; + case "page-num": + pdfViewer.currentPageNumber = value + 1; + break; + case "print": + await pdfViewer.pagesPromise; + this.#eventBus.dispatch("print", { + source: this + }); + break; + case "println": + console.log(value); + break; + case "zoom": + if (!isInPresentationMode) { + pdfViewer.currentScaleValue = value; + } + break; + case "SaveAs": + this.#eventBus.dispatch("download", { + source: this + }); + break; + case "FirstPage": + pdfViewer.currentPageNumber = 1; + break; + case "LastPage": + pdfViewer.currentPageNumber = pdfViewer.pagesCount; + break; + case "NextPage": + pdfViewer.nextPage(); + break; + case "PrevPage": + pdfViewer.previousPage(); + break; + case "ZoomViewIn": + if (!isInPresentationMode) { + pdfViewer.increaseScale(); + } + break; + case "ZoomViewOut": + if (!isInPresentationMode) { + pdfViewer.decreaseScale(); + } + break; + case "WillPrintFinished": + this.#willPrintCapability?.resolve(); + this.#willPrintCapability = null; + break; + } + return; + } + if (isInPresentationMode && detail.focus) { + return; + } + delete detail.id; + delete detail.siblings; + const ids = siblings ? [id, ...siblings] : [id]; + for (const elementId of ids) { + const element = document.querySelector(`[data-element-id="${elementId}"]`); + if (element) { + element.dispatchEvent(new CustomEvent("updatefromsandbox", { + detail + })); + } else { + this.#pdfDocument?.annotationStorage.setValue(elementId, detail); + } + } + } + async #dispatchPageOpen(pageNumber, initialize = false) { + const pdfDocument = this.#pdfDocument, + visitedPages = this._visitedPages; + if (initialize) { + this.#closeCapability = Promise.withResolvers(); + } + if (!this.#closeCapability) { + return; + } + const pageView = this.#pdfViewer.getPageView(pageNumber - 1); + if (pageView?.renderingState !== RenderingStates.FINISHED) { + this._pageOpenPending.add(pageNumber); + return; + } + this._pageOpenPending.delete(pageNumber); + const actionsPromise = (async () => { + const actions = await (!visitedPages.has(pageNumber) ? pageView.pdfPage?.getJSActions() : null); + if (pdfDocument !== this.#pdfDocument) { + return; + } + await this.#scripting?.dispatchEventInSandbox({ + id: "page", + name: "PageOpen", + pageNumber, + actions + }); + })(); + visitedPages.set(pageNumber, actionsPromise); + } + async #dispatchPageClose(pageNumber) { + const pdfDocument = this.#pdfDocument, + visitedPages = this._visitedPages; + if (!this.#closeCapability) { + return; + } + if (this._pageOpenPending.has(pageNumber)) { + return; + } + const actionsPromise = visitedPages.get(pageNumber); + if (!actionsPromise) { + return; + } + visitedPages.set(pageNumber, null); + await actionsPromise; + if (pdfDocument !== this.#pdfDocument) { + return; + } + await this.#scripting?.dispatchEventInSandbox({ + id: "page", + name: "PageClose", + pageNumber + }); + } + #initScripting() { + this.#destroyCapability = Promise.withResolvers(); + if (this.#scripting) { + throw new Error("#initScripting: Scripting already exists."); + } + return this.#externalServices.createScripting(); + } + async #destroyScripting() { + if (!this.#scripting) { + this.#pdfDocument = null; + this.#destroyCapability?.resolve(); + return; + } + if (this.#closeCapability) { + await Promise.race([this.#closeCapability.promise, new Promise(resolve => { + setTimeout(resolve, 1000); + })]).catch(() => {}); + this.#closeCapability = null; + } + this.#pdfDocument = null; + try { + await this.#scripting.destroySandbox(); + } catch {} + this.#willPrintCapability?.reject(new Error("Scripting destroyed.")); + this.#willPrintCapability = null; + this.#eventAbortController?.abort(); + this.#eventAbortController = null; + this._pageOpenPending.clear(); + this._visitedPages.clear(); + this.#scripting = null; + this.#ready = false; + this.#destroyCapability?.resolve(); + } +} + +;// ./web/pdf_text_extractor.js +class PdfTextExtractor { + #pdfViewer; + #externalServices; + #textPromise; + #pendingRequests = new Set(); + constructor(externalServices) { + this.#externalServices = externalServices; + window.addEventListener("requestTextContent", ({ + detail + }) => { + this.extractTextContent(detail.requestId); + }); + } + setViewer(pdfViewer) { + this.#pdfViewer = pdfViewer; + if (this.#pdfViewer && this.#pendingRequests.size) { + for (const pendingRequest of this.#pendingRequests) { + this.extractTextContent(pendingRequest); + } + this.#pendingRequests.clear(); + } + } + async extractTextContent(requestId) { + if (!this.#pdfViewer) { + this.#pendingRequests.add(requestId); + return; + } + if (!this.#textPromise) { + const textPromise = this.#textPromise = this.#pdfViewer.getAllText(); + textPromise.then(() => { + setTimeout(() => { + if (this.#textPromise === textPromise) { + this.#textPromise = null; + } + }, 5000); + }); + } + this.#externalServices.reportText({ + text: await this.#textPromise, + requestId + }); + } +} + +;// ./web/menu.js + +class Menu { + #triggeringButton; + #menu; + #menuItems; + #openMenuAC = null; + #menuAC = new AbortController(); + #lastIndex = -1; + #onFocusOutBound = this.#onFocusOut.bind(this); + constructor(menuContainer, triggeringButton, menuItems) { + this.#menu = menuContainer; + this.#triggeringButton = triggeringButton; + if (Array.isArray(menuItems)) { + this.#menuItems = menuItems; + } else { + this.#menuItems = []; + for (const button of this.#menu.querySelectorAll("button")) { + this.#menuItems.push(button); + } + } + this.#setUpMenu(); + } + #closeMenu() { + if (!this.#openMenuAC) { + return; + } + const menu = this.#menu; + this.#triggeringButton.ariaExpanded = "false"; + this.#openMenuAC.abort(); + this.#openMenuAC = null; + if (menu.contains(document.activeElement)) { + setTimeout(() => { + if (!menu.contains(document.activeElement)) { + this.#triggeringButton.focus(); + } + }, 0); + } + this.#lastIndex = -1; + } + #openMenu() { + if (this.#openMenuAC) { + return; + } + const menu = this.#menu; + this.#triggeringButton.ariaExpanded = "true"; + this.#openMenuAC = new AbortController(); + const signal = AbortSignal.any([this.#menuAC.signal, this.#openMenuAC.signal]); + window.addEventListener("pointerdown", ({ + target + }) => { + if (!this.#triggeringButton.contains(target) && !menu.contains(target)) { + this.#closeMenu(); + } + }, { + signal + }); + const closeMenu = this.#closeMenu.bind(this); + window.addEventListener("blur", closeMenu, { + signal + }); + menu.addEventListener("focusout", this.#onFocusOutBound, { + signal + }); + } + #onFocusOut({ + relatedTarget + }) { + if (!this.#triggeringButton.contains(relatedTarget) && !this.#menu.contains(relatedTarget)) { + this.#closeMenu(); + } + } + #setUpMenu() { + this.#triggeringButton.addEventListener("click", e => { + if (this.#openMenuAC) { + this.#closeMenu(); + return; + } + this.#openMenu(); + }); + this.#triggeringButton.addEventListener("focusout", this.#onFocusOutBound); + const { + signal + } = this.#menuAC; + this.#menu.addEventListener("keydown", e => { + switch (e.key) { + case "Escape": + this.#closeMenu(); + stopEvent(e); + break; + case "ArrowDown": + this.#goToNextItem(e.target, true); + stopEvent(e); + break; + case "ArrowUp": + this.#goToNextItem(e.target, false); + stopEvent(e); + break; + case "Home": + this.#menuItems.find(item => !item.disabled && !item.classList.contains("hidden"))?.focus(); + stopEvent(e); + break; + case "End": + this.#menuItems.findLast(item => !item.disabled && !item.classList.contains("hidden"))?.focus(); + stopEvent(e); + break; + default: + const { + key + } = e; + if (!/^\p{L}$/u.test(key)) { + break; + } + const char = key.toLocaleLowerCase(); + this.#goToNextItem(e.target, true, item => item.textContent.trim().toLowerCase().startsWith(char)); + stopEvent(e); + break; + } + }, { + signal, + capture: true + }); + this.#menu.addEventListener("contextmenu", noContextMenu, { + signal + }); + this.#menu.addEventListener("click", this.#closeMenu.bind(this), { + signal, + capture: true + }); + this.#triggeringButton.addEventListener("keydown", e => { + switch (e.key) { + case " ": + case "Enter": + case "ArrowDown": + case "Home": + stopEvent(e); + if (!this.#openMenuAC) { + this.#openMenu(); + } + this.#menuItems.find(item => !item.disabled && !item.classList.contains("hidden"))?.focus(); + break; + case "ArrowUp": + case "End": + stopEvent(e); + if (!this.#openMenuAC) { + this.#openMenu(); + } + this.#menuItems.findLast(item => !item.disabled && !item.classList.contains("hidden"))?.focus(); + break; + case "Escape": + this.#closeMenu(); + stopEvent(e); + break; + } + }, { + signal + }); + } + #goToNextItem(element, forward, check = () => true) { + const index = this.#lastIndex === -1 ? this.#menuItems.indexOf(element) : this.#lastIndex; + const len = this.#menuItems.length; + const increment = forward ? 1 : len - 1; + for (let i = (index + increment) % len; i !== index; i = (i + increment) % len) { + const menuItem = this.#menuItems[i]; + if (!menuItem.disabled && !menuItem.classList.contains("hidden") && check(menuItem)) { + menuItem.focus(); + this.#lastIndex = i; + break; + } + } + } + destroy() { + this.#closeMenu(); + this.#menuAC?.abort(); + this.#menuAC = null; + } +} + +;// ./web/pdf_thumbnail_view.js + + + +const DRAW_UPSCALE_FACTOR = 2; +const MAX_NUM_SCALING_STEPS = 3; +const THUMBNAIL_WIDTH = 126; +class TempImageFactory { + static getCanvas(width, height) { + let tempCanvas; + if (FeatureTest.isOffscreenCanvasSupported) { + tempCanvas = new OffscreenCanvas(width, height); + } else { + tempCanvas = document.createElement("canvas"); + tempCanvas.width = width; + tempCanvas.height = height; + } + const ctx = tempCanvas.getContext("2d", { + alpha: false + }); + ctx.save(); + ctx.fillStyle = "rgb(255, 255, 255)"; + ctx.fillRect(0, 0, width, height); + ctx.restore(); + return [tempCanvas, ctx]; + } +} +class PDFThumbnailView extends RenderableView { + #renderingState = RenderingStates.INITIAL; + constructor({ + container, + eventBus, + id, + defaultViewport, + optionalContentConfigPromise, + linkService, + renderingQueue, + maxCanvasPixels, + maxCanvasDim, + pageColors, + enableSplitMerge = false + }) { + super(); + this.id = id; + this.renderingId = `thumbnail${id}`; + this.pageLabel = null; + this.pdfPage = null; + this.rotation = 0; + this.viewport = defaultViewport; + this.pdfPageRotate = defaultViewport.rotation; + this._optionalContentConfigPromise = optionalContentConfigPromise || null; + this.maxCanvasPixels = maxCanvasPixels ?? AppOptions.get("maxCanvasPixels"); + this.maxCanvasDim = maxCanvasDim || AppOptions.get("maxCanvasDim"); + this.pageColors = pageColors || null; + this.eventBus = eventBus; + this.linkService = linkService; + this.renderingQueue = renderingQueue; + this.placeholder = null; + const thumbnailContainer = this.div = document.createElement("div"); + thumbnailContainer.className = "thumbnail"; + thumbnailContainer.setAttribute("page-number", id); + const imageContainer = this.imageContainer = document.createElement("div"); + thumbnailContainer.append(imageContainer); + imageContainer.classList.add("thumbnailImageContainer", "missingThumbnailImage"); + imageContainer.role = "button"; + imageContainer.tabIndex = -1; + imageContainer.draggable = false; + imageContainer.setAttribute("page-number", id); + imageContainer.setAttribute("data-l10n-id", "pdfjs-thumb-page-title1"); + imageContainer.setAttribute("data-l10n-args", this.#getPageL10nArgs(true)); + const image = this.image = document.createElement("img"); + imageContainer.append(image); + if (enableSplitMerge) { + const checkbox = this.checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + checkbox.tabIndex = -1; + checkbox.setAttribute("data-l10n-id", "pdfjs-thumb-page-checkbox1"); + checkbox.setAttribute("data-l10n-args", this.#getPageL10nArgs()); + thumbnailContainer.append(checkbox); + this.pasteButton = null; + } + this.#updateDims(); + container.append(thumbnailContainer); + } + clone(container, id) { + const thumbnailView = new PDFThumbnailView({ + container, + id, + eventBus: this.eventBus, + defaultViewport: this.viewport, + optionalContentConfigPromise: this._optionalContentConfigPromise, + linkService: this.linkService, + renderingQueue: this.renderingQueue, + maxCanvasPixels: this.maxCanvasPixels, + maxCanvasDim: this.maxCanvasDim, + pageColors: this.pageColors, + enableSplitMerge: !!this.checkbox + }); + thumbnailView.setPdfPage(this.pdfPage); + const { + imageContainer + } = this; + if (!imageContainer.classList.contains("missingThumbnailImage")) { + thumbnailView.image.replaceWith(this.image.cloneNode(true)); + thumbnailView.imageContainer.classList.remove("missingThumbnailImage"); + } + return thumbnailView; + } + addPasteButton(pasteCallback) { + if (this.pasteButton) { + return; + } + const pasteButton = this.pasteButton = document.createElement("button"); + pasteButton.classList.add("thumbnailPasteButton", "viewsManagerButton"); + pasteButton.tabIndex = 0; + const span = document.createElement("span"); + span.setAttribute("data-l10n-id", "pdfjs-views-manager-paste-button-label"); + pasteButton.append(span); + pasteButton.addEventListener("click", () => { + pasteCallback(this.id); + }); + this.imageContainer.after(pasteButton); + } + toggleSelected(isSelected) { + if (this.checkbox) { + this.checkbox.checked = isSelected; + } + } + updateId(newId) { + this.id = newId; + this.renderingId = `thumbnail${newId}`; + this.div.setAttribute("page-number", newId); + this.imageContainer.setAttribute("page-number", newId); + this.setPageLabel(this.pageLabel); + } + #updateDims() { + const { + width, + height + } = this.viewport; + const ratio = width / height; + const canvasWidth = this.canvasWidth = THUMBNAIL_WIDTH; + const canvasHeight = this.canvasHeight = canvasWidth / ratio | 0; + this.scale = canvasWidth / width; + this.imageContainer.style.height = `${canvasHeight}px`; + } + get renderingState() { + return this.#renderingState; + } + set renderingState(state) { + this.#renderingState = state; + } + setPdfPage(pdfPage) { + this.pdfPage = pdfPage; + this.pdfPageRotate = pdfPage.rotate; + const totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = pdfPage.getViewport({ + scale: 1, + rotation: totalRotation + }); + this.reset(); + } + reset() { + this.cancelRendering(); + this.renderingState = RenderingStates.INITIAL; + this.#updateDims(); + const { + image, + imageContainer + } = this; + const url = image.src; + if (url) { + URL.revokeObjectURL(url); + image.src = ""; + imageContainer.removeAttribute("data-l10n-id"); + imageContainer.removeAttribute("data-l10n-args"); + imageContainer.classList.add("missingThumbnailImage"); + } + } + destroy() { + this.reset(); + this.toggleCurrent(false); + this.div.remove(); + } + update({ + rotation = null + }) { + if (typeof rotation === "number") { + this.rotation = rotation; + } + const totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = this.viewport.clone({ + scale: 1, + rotation: totalRotation + }); + this.reset(); + } + toggleCurrent(isCurrent) { + const { + imageContainer + } = this; + if (isCurrent) { + imageContainer.ariaCurrent = "page"; + imageContainer.tabIndex = 0; + if (this.checkbox) { + this.checkbox.tabIndex = 0; + } + } else { + imageContainer.ariaCurrent = false; + imageContainer.tabIndex = -1; + if (this.checkbox) { + this.checkbox.tabIndex = -1; + } + } + } + cancelRendering() { + if (this.renderTask) { + this.renderTask.cancel(); + this.renderTask = null; + } + this.resume = null; + } + #getPageDrawContext(upscaleFactor = 1) { + const outputScale = new OutputScale(); + const width = upscaleFactor * this.canvasWidth, + height = upscaleFactor * this.canvasHeight; + outputScale.limitCanvas(width, height, this.maxCanvasPixels, this.maxCanvasDim); + const canvas = document.createElement("canvas"); + canvas.width = width * outputScale.sx | 0; + canvas.height = height * outputScale.sy | 0; + const transform = outputScale.scaled ? [outputScale.sx, 0, 0, outputScale.sy, 0, 0] : null; + return { + canvas, + transform + }; + } + async #convertCanvasToImage(canvas) { + if (this.renderingState !== RenderingStates.FINISHED) { + throw new Error("#convertCanvasToImage: Rendering has not finished."); + } + const reducedCanvas = this.#reduceImage(canvas); + const { + imageContainer, + image + } = this; + const { + promise, + resolve + } = Promise.withResolvers(); + reducedCanvas.toBlob(resolve); + const blob = await promise; + image.src = URL.createObjectURL(blob); + image.setAttribute("data-l10n-id", "pdfjs-thumb-page-canvas"); + image.setAttribute("data-l10n-args", this.#getPageL10nArgs()); + imageContainer.classList.remove("missingThumbnailImage"); + if (!FeatureTest.isOffscreenCanvasSupported) { + reducedCanvas.width = reducedCanvas.height = 0; + } + } + async draw() { + if (this.renderingState !== RenderingStates.INITIAL) { + console.error("Must be in new state before drawing"); + return; + } + const { + pageColors, + pdfPage + } = this; + if (!pdfPage) { + this.renderingState = RenderingStates.FINISHED; + throw new Error("pdfPage is not loaded"); + } + this.renderingState = RenderingStates.RUNNING; + const { + canvas, + transform + } = this.#getPageDrawContext(DRAW_UPSCALE_FACTOR); + const drawViewport = this.viewport.clone({ + scale: DRAW_UPSCALE_FACTOR * this.scale + }); + const renderContinueCallback = cont => { + if (!this.renderingQueue.isHighestPriority(this)) { + this.renderingState = RenderingStates.PAUSED; + this.resume = () => { + this.renderingState = RenderingStates.RUNNING; + cont(); + }; + return; + } + cont(); + }; + const renderContext = { + canvas, + transform, + viewport: drawViewport, + optionalContentConfigPromise: this._optionalContentConfigPromise, + pageColors + }; + const renderTask = this.renderTask = pdfPage.render(renderContext); + renderTask.onContinue = renderContinueCallback; + let error = null; + try { + await renderTask.promise; + } catch (e) { + if (e instanceof RenderingCancelledException) { + return; + } + error = e; + } finally { + if (renderTask === this.renderTask) { + this.renderTask = null; + } + } + this.renderingState = RenderingStates.FINISHED; + await this.#convertCanvasToImage(canvas); + this.eventBus.dispatch("thumbnailrendered", { + source: this, + pageNumber: this.id, + pdfPage + }); + if (error) { + throw error; + } + } + setImage(pageView) { + if (this.renderingState !== RenderingStates.INITIAL) { + return; + } + const { + thumbnailCanvas: canvas, + pdfPage, + scale + } = pageView; + if (!canvas) { + return; + } + if (!this.pdfPage) { + this.setPdfPage(pdfPage); + } + if (scale < this.scale) { + return; + } + this.renderingState = RenderingStates.FINISHED; + this.#convertCanvasToImage(canvas); + } + #getReducedImageDims(canvas) { + const width = canvas.width << MAX_NUM_SCALING_STEPS, + height = canvas.height << MAX_NUM_SCALING_STEPS; + const outputScale = new OutputScale(); + outputScale.sx = outputScale.sy = 1; + outputScale.limitCanvas(width, height, this.maxCanvasPixels, this.maxCanvasDim); + return [width * outputScale.sx | 0, height * outputScale.sy | 0]; + } + #reduceImage(img) { + const { + canvas + } = this.#getPageDrawContext(1); + const ctx = canvas.getContext("2d", { + alpha: false, + willReadFrequently: false + }); + if (img.width <= 2 * canvas.width) { + ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height); + return canvas; + } + let [reducedWidth, reducedHeight] = this.#getReducedImageDims(canvas); + const [reducedImage, reducedImageCtx] = TempImageFactory.getCanvas(reducedWidth, reducedHeight); + while (reducedWidth > img.width || reducedHeight > img.height) { + reducedWidth >>= 1; + reducedHeight >>= 1; + } + reducedImageCtx.drawImage(img, 0, 0, img.width, img.height, 0, 0, reducedWidth, reducedHeight); + while (reducedWidth > 2 * canvas.width) { + reducedImageCtx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, reducedWidth >> 1, reducedHeight >> 1); + reducedWidth >>= 1; + reducedHeight >>= 1; + } + ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, canvas.width, canvas.height); + return canvas; + } + #getPageL10nArgs(hasTotal = false) { + return JSON.stringify({ + page: this.pageLabel ?? this.id, + total: hasTotal ? this.linkService.pagesCount : undefined + }); + } + setPageLabel(label) { + this.pageLabel = typeof label === "string" ? label : null; + this.imageContainer.setAttribute("data-l10n-args", this.#getPageL10nArgs(true)); + this.image.setAttribute("data-l10n-args", this.#getPageL10nArgs()); + this.checkbox?.setAttribute("data-l10n-args", this.#getPageL10nArgs()); + } +} + +;// ./web/pdf_thumbnail_viewer.js + + + + + +const SCROLL_OPTIONS = { + behavior: "instant", + block: "nearest", + inline: "nearest", + container: "nearest" +}; +const DRAG_THRESHOLD_IN_PIXELS = 5; +const PIXELS_TO_SCROLL_WHEN_DRAGGING = 20; +const SPACE_FOR_DRAG_MARKER_WHEN_NO_NEXT_ELEMENT = 15; +class PDFThumbnailViewer { + static #draggingScaleFactor = 0; + #enableSplitMerge = false; + #dragAC = null; + #draggedContainer = null; + #thumbnailsPositions = null; + #lastDraggedOverIndex = NaN; + #selectedPages = null; + #draggedImageX = 0; + #draggedImageY = 0; + #draggedImageWidth = 0; + #draggedImageHeight = 0; + #draggedImageOffsetX = 0; + #draggedImageOffsetY = 0; + #dragMarker = null; + #pageNumberToRemove = NaN; + #currentScrollBottom = 0; + #currentScrollTop = 0; + #pagesMapper = null; + #manageSaveAsButton = null; + #manageDeleteButton = null; + #manageCopyButton = null; + #manageCutButton = null; + #copiedThumbnails = null; + #copiedPageNumbers = null; + #isCut = false; + #isOneColumnView = false; + #scrollableContainerWidth = 0; + #scrollableContainerHeight = 0; + constructor({ + container, + eventBus, + linkService, + renderingQueue, + maxCanvasPixels, + maxCanvasDim, + pageColors, + abortSignal, + enableHWA, + enableSplitMerge, + manageMenu, + addFileButton + }) { + this.scrollableContainer = container.parentElement; + this.container = container; + this.eventBus = eventBus; + this.linkService = linkService; + this.renderingQueue = renderingQueue; + this.maxCanvasPixels = maxCanvasPixels; + this.maxCanvasDim = maxCanvasDim; + this.pageColors = pageColors || null; + this.enableHWA = enableHWA || false; + this.#enableSplitMerge = enableSplitMerge || false; + if (this.#enableSplitMerge && manageMenu) { + const { + button, + menu, + copy, + cut, + delete: del, + saveAs + } = manageMenu; + this.eventBus.on("pagesloaded", () => { + button.disabled = false; + }, { + once: true + }); + this._manageMenu = new Menu(menu, button, [copy, cut, del, saveAs]); + this.#manageSaveAsButton = saveAs; + saveAs.addEventListener("click", () => { + this.eventBus.dispatch("savepageseditedpdf", { + source: this, + data: this.#pagesMapper.getPageMappingForSaving() + }); + }); + this.#manageDeleteButton = del; + del.addEventListener("click", this.#deletePages.bind(this)); + this.#manageCopyButton = copy; + copy.addEventListener("click", this.#copyPages.bind(this)); + this.#manageCutButton = cut; + cut.addEventListener("click", this.#cutPages.bind(this)); + this.#toggleMenuEntries(false); + button.disabled = true; + } else { + manageMenu.button.hidden = true; + } + this.scroll = watchScroll(this.scrollableContainer, this.#scrollUpdated.bind(this), abortSignal); + this.#resetView(); + this.#addEventListeners(); + } + #scrollUpdated() { + this.renderingQueue.renderHighestPriority(); + } + getThumbnail(index) { + return this._thumbnails[index]; + } + #getVisibleThumbs() { + return getVisibleElements({ + scrollEl: this.scrollableContainer, + views: this._thumbnails + }); + } + scrollThumbnailIntoView(pageNumber) { + if (!this.pdfDocument) { + return; + } + const thumbnailView = this._thumbnails[pageNumber - 1]; + if (!thumbnailView) { + console.error('scrollThumbnailIntoView: Invalid "pageNumber" parameter.'); + return; + } + if (pageNumber !== this._currentPageNumber) { + const prevThumbnailView = this._thumbnails[this._currentPageNumber - 1]; + prevThumbnailView?.toggleCurrent(false); + thumbnailView.toggleCurrent(true); + this._currentPageNumber = pageNumber; + } + const { + first, + last, + views + } = this.#getVisibleThumbs(); + if (views.length > 0) { + let shouldScroll = false; + if (pageNumber <= first.id || pageNumber >= last.id) { + shouldScroll = true; + } else { + for (const { + id, + percent + } of views) { + if (id !== pageNumber) { + continue; + } + shouldScroll = percent < 100; + break; + } + } + if (shouldScroll) { + thumbnailView.div.scrollIntoView(SCROLL_OPTIONS); + } + } + this._currentPageNumber = pageNumber; + } + get pagesRotation() { + return this._pagesRotation; + } + set pagesRotation(rotation) { + if (!isValidRotation(rotation)) { + throw new Error("Invalid thumbnails rotation angle."); + } + if (!this.pdfDocument) { + return; + } + if (this._pagesRotation === rotation) { + return; + } + this._pagesRotation = rotation; + const updateArgs = { + rotation + }; + for (const thumbnail of this._thumbnails) { + thumbnail.update(updateArgs); + } + } + cleanup() { + for (const thumbnail of this._thumbnails) { + if (thumbnail.renderingState !== RenderingStates.FINISHED) { + thumbnail.reset(); + } + } + } + #resetView() { + this._thumbnails = []; + this._currentPageNumber = 1; + this._pageLabels = null; + this._pagesRotation = 0; + this.container.textContent = ""; + } + setDocument(pdfDocument) { + if (this.pdfDocument) { + this.#cancelRendering(); + this.#resetView(); + } + this.pdfDocument = pdfDocument; + if (!pdfDocument) { + return; + } + this.#pagesMapper = pdfDocument.pagesMapper; + const firstPagePromise = pdfDocument.getPage(1); + const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({ + intent: "display" + }); + firstPagePromise.then(firstPdfPage => { + const pagesCount = pdfDocument.numPages; + const viewport = firstPdfPage.getViewport({ + scale: 1 + }); + const fragment = document.createDocumentFragment(); + for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) { + const thumbnail = new PDFThumbnailView({ + container: fragment, + eventBus: this.eventBus, + id: pageNum, + defaultViewport: viewport.clone(), + optionalContentConfigPromise, + linkService: this.linkService, + renderingQueue: this.renderingQueue, + maxCanvasPixels: this.maxCanvasPixels, + maxCanvasDim: this.maxCanvasDim, + pageColors: this.pageColors, + enableHWA: this.enableHWA, + enableSplitMerge: this.#enableSplitMerge + }); + this._thumbnails.push(thumbnail); + } + this._thumbnails[0]?.setPdfPage(firstPdfPage); + const thumbnailView = this._thumbnails[this._currentPageNumber - 1]; + thumbnailView.toggleCurrent(true); + this.container.append(fragment); + }).catch(reason => { + console.error("Unable to initialize thumbnail viewer", reason); + }); + } + #cancelRendering() { + for (const thumbnail of this._thumbnails) { + thumbnail.cancelRendering(); + } + } + setPageLabels(labels) { + if (!this.pdfDocument) { + return; + } + if (!labels) { + this._pageLabels = null; + } else if (!(Array.isArray(labels) && this.pdfDocument.numPages === labels.length)) { + this._pageLabels = null; + console.error("PDFThumbnailViewer_setPageLabels: Invalid page labels."); + } else { + this._pageLabels = labels; + } + for (let i = 0, ii = this._thumbnails.length; i < ii; i++) { + this._thumbnails[i].setPageLabel(this._pageLabels?.[i] ?? null); + } + } + async #ensurePdfPageLoaded(thumbView) { + if (thumbView.pdfPage) { + return thumbView.pdfPage; + } + try { + const pdfPage = await this.pdfDocument.getPage(thumbView.id); + if (!thumbView.pdfPage) { + thumbView.setPdfPage(pdfPage); + } + return pdfPage; + } catch (reason) { + console.error("Unable to get page for thumb view", reason); + return null; + } + } + #getScrollAhead(visible) { + if (visible.first?.id === 1) { + return true; + } else if (visible.last?.id === this._thumbnails.length) { + return false; + } + return this.scroll.down; + } + forceRendering() { + const visibleThumbs = this.#getVisibleThumbs(); + const scrollAhead = this.#getScrollAhead(visibleThumbs); + const thumbView = this.renderingQueue.getHighestPriority(visibleThumbs, this._thumbnails, scrollAhead, false, true); + if (thumbView) { + this.#ensurePdfPageLoaded(thumbView).then(() => { + this.renderingQueue.renderView(thumbView); + }); + return true; + } + return false; + } + static #getScaleFactor(image) { + return PDFThumbnailViewer.#draggingScaleFactor ||= parseFloat(getComputedStyle(image).getPropertyValue("--thumbnail-dragging-scale")); + } + #updateThumbnails(currentPageNumber) { + let newCurrentPageNumber = 0; + const pagesMapper = this.#pagesMapper; + this.container.replaceChildren(); + const prevThumbnails = this._thumbnails; + const newThumbnails = this._thumbnails = []; + const fragment = document.createDocumentFragment(); + const isCut = this.#isCut; + const oldThumbnails = new Set(prevThumbnails); + for (let i = 1, ii = pagesMapper.pagesNumber; i <= ii; i++) { + const prevPageNumber = pagesMapper.getPrevPageNumber(i); + if (prevPageNumber < 0) { + let thumbnail = this.#copiedThumbnails.get(-prevPageNumber); + oldThumbnails.delete(thumbnail); + thumbnail.checkbox.checked = false; + if (isCut) { + thumbnail.updateId(i); + fragment.append(thumbnail.div); + } else { + thumbnail = thumbnail.clone(fragment, i); + } + newThumbnails.push(thumbnail); + continue; + } + if (prevPageNumber === currentPageNumber) { + newCurrentPageNumber = i; + } + const newThumbnail = prevThumbnails[prevPageNumber - 1]; + newThumbnails.push(newThumbnail); + newThumbnail.updateId(i); + oldThumbnails.delete(newThumbnail); + newThumbnail.checkbox.checked = false; + fragment.append(newThumbnail.div); + } + this.container.append(fragment); + for (const oldThumbnail of oldThumbnails) { + oldThumbnail.destroy(); + } + return newCurrentPageNumber; + } + #onStartDragging(draggedThumbnail) { + this.#currentScrollTop = this.scrollableContainer.scrollTop; + this.#currentScrollBottom = this.#currentScrollTop + this.scrollableContainer.clientHeight; + this.#dragAC = new AbortController(); + this.container.classList.add("isDragging"); + const startPageNumber = parseInt(draggedThumbnail.getAttribute("page-number"), 10); + this.#lastDraggedOverIndex = startPageNumber - 1; + if (!this.#selectedPages?.has(startPageNumber)) { + this.#pageNumberToRemove = startPageNumber; + this.#selectPage(startPageNumber, true); + } + for (const selected of this.#selectedPages) { + const thumbnail = this._thumbnails[selected - 1]; + const placeholder = thumbnail.placeholder = document.createElement("div"); + placeholder.classList.add("thumbnailImageContainer", "placeholder"); + const { + div, + imageContainer + } = thumbnail; + div.classList.add("isDragging"); + placeholder.style.height = getComputedStyle(imageContainer).height; + imageContainer.after(placeholder); + if (selected !== startPageNumber) { + imageContainer.classList.add("hidden"); + continue; + } + if (this.#selectedPages.size === 1) { + imageContainer.classList.add("draggingThumbnail"); + this.#draggedContainer = imageContainer; + continue; + } + const draggedContainer = this.#draggedContainer = document.createElement("div"); + draggedContainer.classList.add("draggingThumbnail", "thumbnailImageContainer", "multiple"); + draggedContainer.style.height = getComputedStyle(imageContainer).height; + imageContainer.replaceWith(draggedContainer); + imageContainer.classList.remove("thumbnailImageContainer"); + draggedContainer.append(imageContainer); + draggedContainer.setAttribute("data-multiple-count", this.#selectedPages.size); + } + } + #onStopDragging(isDropping = false) { + const draggedContainer = this.#draggedContainer; + this.#draggedContainer = null; + const lastDraggedOverIndex = this.#lastDraggedOverIndex; + this.#lastDraggedOverIndex = NaN; + this.#dragMarker?.remove(); + this.#dragMarker = null; + this.#dragAC.abort(); + this.#dragAC = null; + this.container.classList.remove("isDragging"); + for (const selected of this.#selectedPages) { + const thumbnail = this._thumbnails[selected - 1]; + const { + div, + placeholder, + imageContainer + } = thumbnail; + placeholder.remove(); + imageContainer.classList.remove("draggingThumbnail", "hidden"); + div.classList.remove("isDragging"); + } + if (draggedContainer.classList.contains("multiple")) { + const originalImageContainer = draggedContainer.firstElementChild; + draggedContainer.replaceWith(originalImageContainer); + originalImageContainer.classList.add("thumbnailImageContainer"); + } else { + draggedContainer.style.translate = ""; + } + const selectedPages = this.#selectedPages; + if (!isNaN(lastDraggedOverIndex) && isDropping && !(selectedPages.size === 1 && (selectedPages.has(lastDraggedOverIndex + 1) || selectedPages.has(lastDraggedOverIndex + 2)))) { + this._thumbnails[this._currentPageNumber - 1]?.toggleCurrent(false); + this._currentPageNumber = -1; + const newIndex = lastDraggedOverIndex + 1; + const pagesToMove = Array.from(selectedPages).sort((a, b) => a - b); + const pagesMapper = this.#pagesMapper; + let currentPageNumber = isNaN(this.#pageNumberToRemove) ? pagesToMove[0] : this.#pageNumberToRemove; + pagesMapper.movePages(selectedPages, pagesToMove, newIndex); + currentPageNumber = this.#updateThumbnails(currentPageNumber); + this.#computeThumbnailsPosition(); + selectedPages.clear(); + this.#pageNumberToRemove = NaN; + this.#updateMenuEntries(); + this.eventBus.dispatch("pagesedited", { + source: this, + pagesMapper, + type: "move" + }); + setTimeout(() => { + this.forceRendering(); + this.linkService.goToPage(currentPageNumber); + }, 0); + } + if (!isNaN(this.#pageNumberToRemove)) { + this.#selectPage(this.#pageNumberToRemove, false); + this.#pageNumberToRemove = NaN; + } + } + #clearSelection() { + for (const pageNumber of this.#selectedPages) { + this._thumbnails[pageNumber - 1].toggleSelected(false); + } + this.#selectedPages.clear(); + } + #copyPages(clearSelection = true) { + const pageNumbersToCopy = this.#copiedPageNumbers = Uint32Array.from(this.#selectedPages).sort((a, b) => a - b); + const pagesMapper = this.#pagesMapper; + pagesMapper.copyPages(pageNumbersToCopy); + this.#copiedThumbnails ||= new Map(); + for (const pageNumber of pageNumbersToCopy) { + this.#copiedThumbnails.set(pageNumber, this._thumbnails[pageNumber - 1]); + } + this.eventBus.dispatch("pagesedited", { + source: this, + pagesMapper, + pageNumbers: pageNumbersToCopy, + type: "copy" + }); + if (clearSelection) { + this.#clearSelection(); + } + for (const thumbnail of this._thumbnails) { + thumbnail.addPasteButton(this.#pastePages.bind(this)); + } + this.container.classList.add("pasteMode"); + this.#toggleMenuEntries(false); + } + #cutPages() { + this.#isCut = true; + this.#copyPages(false); + this.#deletePages("cut"); + } + #pastePages(index) { + this.container.classList.remove("pasteMode"); + this.#toggleMenuEntries(true); + const pagesMapper = this.#pagesMapper; + let currentPageNumber = this.#copiedPageNumbers.includes(this._currentPageNumber) ? 0 : this._currentPageNumber; + pagesMapper.pastePages(index); + currentPageNumber = this.#updateThumbnails(currentPageNumber); + this.eventBus.dispatch("pagesedited", { + source: this, + pagesMapper, + hasBeenCut: this.#isCut, + type: "paste" + }); + this.#copiedThumbnails = null; + this.#isCut = false; + this.#updateMenuEntries(); + setTimeout(() => { + this.forceRendering(); + this.linkService.goToPage(currentPageNumber || 1); + }, 0); + } + #deletePages(type = "delete") { + const selectedPages = this.#selectedPages; + if (selectedPages.size === 0) { + return; + } + const pagesMapper = this.#pagesMapper; + let currentPageNumber = selectedPages.has(this._currentPageNumber) ? 0 : this._currentPageNumber; + const pagesToDelete = Uint32Array.from(selectedPages).sort((a, b) => a - b); + pagesMapper.deletePages(pagesToDelete); + currentPageNumber = this.#updateThumbnails(currentPageNumber); + selectedPages.clear(); + this.#updateMenuEntries(); + this.eventBus.dispatch("pagesedited", { + source: this, + pagesMapper, + pageNumbers: pagesToDelete, + type + }); + setTimeout(() => { + this.forceRendering(); + this.linkService.goToPage(currentPageNumber || 1); + }, 0); + } + #updateMenuEntries() { + this.#manageSaveAsButton.disabled = !this.#pagesMapper.hasBeenAltered(); + this.#manageDeleteButton.disabled = this.#manageCopyButton.disabled = this.#manageCutButton.disabled = !this.#selectedPages?.size; + } + #toggleMenuEntries(enable) { + this.#manageSaveAsButton.disabled = this.#manageDeleteButton.disabled = this.#manageCopyButton.disabled = this.#manageCutButton.disabled = !enable; + } + #moveDraggedContainer(dx, dy) { + if (this.#isOneColumnView) { + dx = 0; + } + if (this.#draggedImageX + dx < 0 || this.#draggedImageX + this.#draggedImageWidth + dx > this.#scrollableContainerWidth) { + dx = 0; + } + if (this.#draggedImageY + dy < 0 || this.#draggedImageY + this.#draggedImageHeight + dy > this.#scrollableContainerHeight) { + dy = 0; + } + this.#draggedImageX += dx; + this.#draggedImageY += dy; + this.#draggedImageOffsetX += dx; + this.#draggedImageOffsetY += dy; + this.#draggedContainer.style.translate = `${this.#draggedImageOffsetX}px ${this.#draggedImageOffsetY}px`; + if (this.#draggedImageY + this.#draggedImageHeight > this.#currentScrollBottom) { + this.scrollableContainer.scrollTop = Math.min(this.scrollableContainer.scrollTop + PIXELS_TO_SCROLL_WHEN_DRAGGING, this.#scrollableContainerHeight); + } else if (this.#draggedImageY < this.#currentScrollTop) { + this.scrollableContainer.scrollTop = Math.max(this.scrollableContainer.scrollTop - PIXELS_TO_SCROLL_WHEN_DRAGGING, 0); + } + const positionData = this.#findClosestThumbnail(this.#draggedImageX + this.#draggedImageWidth / 2, this.#draggedImageY + this.#draggedImageHeight / 2); + if (!positionData) { + return; + } + let dragMarker = this.#dragMarker; + if (!dragMarker) { + dragMarker = this.#dragMarker = document.createElement("div"); + dragMarker.className = "dragMarker"; + this.container.firstChild.before(dragMarker); + } + const [index, space] = positionData; + const dragMarkerStyle = dragMarker.style; + const { + bbox, + x: xPos + } = this.#thumbnailsPositions; + let x, y, width, height; + if (index < 0) { + if (xPos.length === 1) { + y = bbox[1] - SPACE_FOR_DRAG_MARKER_WHEN_NO_NEXT_ELEMENT; + x = bbox[4]; + width = bbox[2]; + } else { + y = bbox[1]; + x = bbox[0] - SPACE_FOR_DRAG_MARKER_WHEN_NO_NEXT_ELEMENT; + height = bbox[3]; + } + } else if (xPos.length === 1) { + y = bbox[index * 4 + 1] + bbox[index * 4 + 3] + space; + x = bbox[index * 4]; + width = bbox[index * 4 + 2]; + } else { + y = bbox[index * 4 + 1]; + x = bbox[index * 4] + bbox[index * 4 + 2] + space; + height = bbox[index * 4 + 3]; + } + dragMarkerStyle.translate = `${x}px ${y}px`; + dragMarkerStyle.width = width ? `${width}px` : ""; + dragMarkerStyle.height = height ? `${height}px` : ""; + } + #computeThumbnailsPosition() { + const positionsX = []; + const positionsY = []; + const positionsLastX = []; + const bbox = new Float32Array(this._thumbnails.length * 4); + let prevX = -Infinity; + let prevY = -Infinity; + let reminder = -1; + let firstRightX; + let lastRightX; + let firstBottomY; + for (let i = 0, ii = this._thumbnails.length; i < ii; i++) { + const { + div + } = this._thumbnails[i]; + const { + offsetTop: y, + offsetLeft: x, + offsetWidth: w, + offsetHeight: h + } = div; + if (w === 0) { + return; + } + bbox[i * 4] = x; + bbox[i * 4 + 1] = y; + bbox[i * 4 + 2] = w; + bbox[i * 4 + 3] = h; + if (x > prevX) { + prevX = x + w / 2; + firstRightX ??= prevX + w; + positionsX.push(prevX); + } + if (reminder > 0 && i >= ii - reminder) { + const cx = x + w / 2; + positionsLastX.push(cx); + lastRightX ??= cx + w; + } + if (y > prevY) { + if (reminder === -1 && positionsX.length > 1) { + reminder = ii % positionsX.length; + } + prevY = y + h / 2; + firstBottomY ??= prevY + h; + positionsY.push(prevY); + } + } + const space = positionsX.length > 1 ? (positionsX[1] - firstRightX) / 2 : (positionsY[1] - firstBottomY) / 2; + this.#thumbnailsPositions = { + x: positionsX, + y: positionsY, + lastX: positionsLastX, + space, + lastSpace: (positionsLastX.at(-1) - lastRightX) / 2, + bbox + }; + this.#isOneColumnView = positionsX.length === 1; + ({ + clientWidth: this.#scrollableContainerWidth, + scrollHeight: this.#scrollableContainerHeight + } = this.scrollableContainer); + } + #addEventListeners() { + this.eventBus.on("resize", ({ + source + }) => { + if (source.thumbnailsView === this.container) { + this.#computeThumbnailsPosition(); + } + }); + this.container.addEventListener("keydown", e => { + const { + target + } = e; + const isCheckbox = target instanceof HTMLInputElement && target.type === "checkbox"; + switch (e.key) { + case "ArrowLeft": + this.#goToNextItem(target, false, true, isCheckbox); + stopEvent(e); + break; + case "ArrowRight": + this.#goToNextItem(target, true, true, isCheckbox); + stopEvent(e); + break; + case "ArrowDown": + this.#goToNextItem(target, true, false, isCheckbox); + stopEvent(e); + break; + case "ArrowUp": + this.#goToNextItem(target, false, false, isCheckbox); + stopEvent(e); + break; + case "Home": + this.#focusThumbnailElement(this._thumbnails[0], isCheckbox); + stopEvent(e); + break; + case "End": + this.#focusThumbnailElement(this._thumbnails.at(-1), isCheckbox); + stopEvent(e); + break; + case "Enter": + case " ": + if (!isCheckbox) { + this.#goToPage(e); + } + break; + case "c": + if (this.#enableSplitMerge && (e.ctrlKey || e.metaKey) && this.#selectedPages?.size) { + this.#copyPages(); + stopEvent(e); + } + break; + case "x": + if (this.#enableSplitMerge && (e.ctrlKey || e.metaKey) && this.#selectedPages?.size) { + this.#cutPages(); + stopEvent(e); + } + break; + case "Delete": + case "Backspace": + if (this.#enableSplitMerge && this.#selectedPages?.size) { + this.#deletePages(); + stopEvent(e); + } + break; + } + }); + this.container.addEventListener("click", e => { + const { + target + } = e; + if (target instanceof HTMLInputElement) { + const pageNumber = parseInt(target.parentElement.getAttribute("page-number"), 10); + this.#selectPage(pageNumber, target.checked); + return; + } + this.#goToPage(e); + }); + this.#addDragListeners(); + } + #selectPage(pageNumber, checked) { + const set = this.#selectedPages ??= new Set(); + if (checked) { + set.add(pageNumber); + } else { + set.delete(pageNumber); + } + this.#updateMenuEntries(); + } + #addDragListeners() { + if (!this.#enableSplitMerge) { + return; + } + this.container.addEventListener("pointerdown", e => { + const { + target: draggedImage, + clientX: clickX, + clientY: clickY, + pointerId: dragPointerId + } = e; + if (e.button !== 0 || this.#pagesMapper.copiedPageNumbers?.length > 0 || !isNaN(this.#lastDraggedOverIndex) || !draggedImage.classList.contains("thumbnailImageContainer")) { + return; + } + const thumbnail = draggedImage.parentElement; + const pointerDownAC = new AbortController(); + const { + signal: pointerDownSignal + } = pointerDownAC; + let prevDragX = clickX; + let prevDragY = clickY; + let prevScrollTop = this.scrollableContainer.scrollTop; + const scaleFactor = PDFThumbnailViewer.#getScaleFactor(draggedImage); + this.#draggedImageOffsetY = ((scaleFactor - 1) * e.layerY + draggedImage.offsetTop) / scaleFactor; + if (this.#isOneColumnView) { + this.#draggedImageOffsetX = draggedImage.offsetLeft + (scaleFactor - 1) * 0.5 * draggedImage.offsetWidth / scaleFactor; + } else { + this.#draggedImageOffsetX = ((scaleFactor - 1) * e.layerX + draggedImage.offsetLeft) / scaleFactor; + } + this.#draggedImageX = thumbnail.offsetLeft + this.#draggedImageOffsetX; + this.#draggedImageY = thumbnail.offsetTop + this.#draggedImageOffsetY; + this.#draggedImageWidth = draggedImage.offsetWidth / scaleFactor; + this.#draggedImageHeight = draggedImage.offsetHeight / scaleFactor; + this.container.addEventListener("pointermove", ev => { + const { + clientX: x, + clientY: y, + pointerId + } = ev; + if (isNaN(this.#lastDraggedOverIndex)) { + if (pointerId !== dragPointerId || Math.abs(x - clickX) <= DRAG_THRESHOLD_IN_PIXELS && Math.abs(y - clickY) <= DRAG_THRESHOLD_IN_PIXELS) { + return; + } + this.#onStartDragging(thumbnail); + const stopDragging = (_e, isDropping = false) => { + this.#onStopDragging(isDropping); + pointerDownAC.abort(); + }; + const { + signal + } = this.#dragAC; + window.addEventListener("touchmove", stopEvent, { + passive: false, + signal + }); + window.addEventListener("contextmenu", noContextMenu, { + signal + }); + this.scrollableContainer.addEventListener("scrollend", () => { + const { + scrollableContainer: { + clientHeight, + scrollTop + } + } = this; + this.#currentScrollTop = scrollTop; + this.#currentScrollBottom = scrollTop + clientHeight; + const dy = scrollTop - prevScrollTop; + prevScrollTop = scrollTop; + this.#moveDraggedContainer(0, dy); + }, { + passive: true, + signal + }); + window.addEventListener("pointerup", upEv => { + if (upEv.pointerId !== dragPointerId) { + return; + } + window.addEventListener("click", stopEvent, { + capture: true, + once: true, + signal + }); + stopEvent(upEv); + stopDragging(upEv, true); + }, { + signal + }); + window.addEventListener("blur", stopDragging, { + signal + }); + window.addEventListener("pointercancel", stopDragging, { + signal + }); + window.addEventListener("wheel", stopEvent, { + passive: false, + signal + }); + window.addEventListener("keydown", kEv => { + if (kEv.key === "Escape" && !isNaN(this.#lastDraggedOverIndex)) { + stopDragging(kEv); + } + }, { + signal + }); + } + const dx = x - prevDragX; + const dy = y - prevDragY; + prevDragX = x; + prevDragY = y; + this.#moveDraggedContainer(dx, dy); + }, { + passive: true, + signal: pointerDownSignal + }); + window.addEventListener("pointerup", ({ + pointerId + }) => { + if (pointerId !== dragPointerId) { + return; + } + pointerDownAC.abort(); + }, { + signal: pointerDownSignal + }); + window.addEventListener("dragstart", stopEvent, { + capture: true, + signal: pointerDownSignal + }); + }); + } + #goToPage(e) { + const { + target + } = e; + if (target.classList.contains("thumbnailImageContainer")) { + const pageNumber = parseInt(target.parentElement.getAttribute("page-number"), 10); + this.linkService.goToPage(pageNumber); + stopEvent(e); + } + } + #focusThumbnailElement(thumbnail, focusCheckbox) { + if (focusCheckbox && thumbnail.checkbox) { + thumbnail.checkbox.focus(); + } else { + thumbnail.imageContainer.focus(); + } + } + #goToNextItem(element, forward, horizontal, navigateCheckboxes = false) { + let currentPageNumber = parseInt(element.parentElement.getAttribute("page-number"), 10); + if (isNaN(currentPageNumber)) { + currentPageNumber = this._currentPageNumber; + } + const increment = forward ? 1 : -1; + let nextThumbnail; + if (horizontal) { + const nextPageNumber = MathClamp(currentPageNumber + increment, 1, this._thumbnails.length + 1); + nextThumbnail = this._thumbnails[nextPageNumber - 1]; + } else { + const currentThumbnail = this._thumbnails[currentPageNumber - 1]; + const { + x: currentX, + y: currentY + } = currentThumbnail.div.getBoundingClientRect(); + let firstWithDifferentY; + for (let i = currentPageNumber - 1 + increment; i >= 0 && i < this._thumbnails.length; i += increment) { + const thumbnail = this._thumbnails[i]; + const { + x, + y + } = thumbnail.div.getBoundingClientRect(); + if (!firstWithDifferentY && y !== currentY) { + firstWithDifferentY = thumbnail; + } + if (x === currentX) { + nextThumbnail = thumbnail; + break; + } + } + if (!nextThumbnail) { + nextThumbnail = firstWithDifferentY; + } + } + if (nextThumbnail) { + this.#focusThumbnailElement(nextThumbnail, navigateCheckboxes); + } + } + #findClosestThumbnail(x, y) { + if (!this.#thumbnailsPositions) { + this.#computeThumbnailsPosition(); + } + const { + x: positionsX, + y: positionsY, + lastX: positionsLastX, + space: spaceBetweenThumbnails, + lastSpace: lastSpaceBetweenThumbnails + } = this.#thumbnailsPositions; + const lastDraggedOverIndex = this.#lastDraggedOverIndex; + let xPos = lastDraggedOverIndex % positionsX.length; + let yPos = Math.floor(lastDraggedOverIndex / positionsX.length); + let xArray = yPos === positionsY.length - 1 ? positionsLastX : positionsX; + if (positionsY[yPos] <= y && y < (positionsY[yPos + 1] ?? Infinity) && xArray[xPos] <= x && x < (xArray[xPos + 1] ?? Infinity)) { + return null; + } + let index; + yPos = binarySearchFirstItem(positionsY, cy => y < cy); + if (this.#isOneColumnView) { + index = yPos - 1; + } else { + if (yPos === positionsY.length) { + yPos = positionsY.length - 1; + } else { + const dist1 = Math.abs(positionsY[yPos - 1] - y); + const dist2 = Math.abs(positionsY[yPos] - y); + yPos = dist1 < dist2 ? yPos - 1 : yPos; + } + xArray = yPos === positionsY.length - 1 && positionsLastX.length > 0 ? positionsLastX : positionsX; + xPos = binarySearchFirstItem(xArray, cx => x < cx) - 1; + if (yPos < 0) { + if (xPos <= 0) { + xPos = -1; + } + yPos = 0; + } + index = MathClamp(yPos * positionsX.length + xPos, -1, this._thumbnails.length - 1); + } + if (index === lastDraggedOverIndex) { + return null; + } + this.#lastDraggedOverIndex = index; + const space = yPos === positionsY.length - 1 && positionsLastX.length > 0 && xPos >= 0 ? lastSpaceBetweenThumbnails : spaceBetweenThumbnails; + return [index, space]; + } +} + +;// ./web/annotation_editor_layer_builder.js + + +class AnnotationEditorLayerBuilder { + #annotationLayer = null; + #drawLayer = null; + #onAppend = null; + #structTreeLayer = null; + #textLayer = null; + #uiManager; + #clonedFrom = null; + constructor(options) { + this.pageIndex = options.pageIndex; + this.accessibilityManager = options.accessibilityManager; + this.l10n = options.l10n; + this.l10n ||= new genericl10n_GenericL10n(); + this.annotationEditorLayer = null; + this.div = null; + this._cancelled = false; + this.#uiManager = options.uiManager; + this.#annotationLayer = options.annotationLayer || null; + this.#textLayer = options.textLayer || null; + this.#drawLayer = options.drawLayer || null; + this.#onAppend = options.onAppend || null; + this.#structTreeLayer = options.structTreeLayer || null; + this.#clonedFrom = options.clonedFrom || null; + } + updatePageIndex(newPageIndex) { + this.pageIndex = newPageIndex; + this.annotationEditorLayer?.updatePageIndex(newPageIndex); + } + async render({ + viewport, + intent = "display" + }) { + if (intent !== "display") { + return; + } + if (this._cancelled) { + return; + } + const clonedViewport = viewport.clone({ + dontFlip: true + }); + if (this.div) { + this.annotationEditorLayer.update({ + viewport: clonedViewport + }); + this.show(); + return; + } + const div = this.div = document.createElement("div"); + div.className = "annotationEditorLayer"; + div.hidden = true; + div.dir = this.#uiManager.direction; + this.#onAppend?.(div); + this.annotationEditorLayer = new AnnotationEditorLayer({ + uiManager: this.#uiManager, + div, + structTreeLayer: this.#structTreeLayer, + accessibilityManager: this.accessibilityManager, + pageIndex: this.pageIndex, + l10n: this.l10n, + viewport: clonedViewport, + annotationLayer: this.#annotationLayer, + textLayer: this.#textLayer, + drawLayer: this.#drawLayer + }); + this.annotationEditorLayer.setClonedFrom(this.#clonedFrom?.annotationEditorLayer); + this.#clonedFrom = null; + const parameters = { + viewport: clonedViewport, + div, + annotations: null, + intent + }; + this.annotationEditorLayer.render(parameters); + this.show(); + } + cancel() { + this._cancelled = true; + if (!this.div) { + return; + } + this.annotationEditorLayer.destroy(); + } + hide() { + if (!this.div) { + return; + } + this.annotationEditorLayer.pause(true); + this.div.hidden = true; + } + show() { + if (!this.div || this.annotationEditorLayer.isInvisible) { + return; + } + this.div.hidden = false; + this.annotationEditorLayer.pause(false); + } +} + +;// ./web/annotation_layer_builder.js + + +class AnnotationLayerBuilder { + #annotations = null; + #commentManager = null; + #externalHide = false; + #onAppend = null; + #eventAbortController = null; + #linksInjected = false; + constructor({ + pdfPage, + linkService, + downloadManager, + annotationStorage = null, + imageResourcesPath = "", + renderForms = true, + enableComment = false, + commentManager = null, + enableScripting = false, + hasJSActionsPromise = null, + fieldObjectsPromise = null, + annotationCanvasMap = null, + accessibilityManager = null, + annotationEditorUIManager = null, + onAppend = null + }) { + this.pdfPage = pdfPage; + this.linkService = linkService; + this.downloadManager = downloadManager; + this.imageResourcesPath = imageResourcesPath; + this.renderForms = renderForms; + this.annotationStorage = annotationStorage; + this.enableComment = enableComment; + this.#commentManager = commentManager; + this.enableScripting = enableScripting; + this._hasJSActionsPromise = hasJSActionsPromise || Promise.resolve(false); + this._fieldObjectsPromise = fieldObjectsPromise || Promise.resolve(null); + this._annotationCanvasMap = annotationCanvasMap; + this._accessibilityManager = accessibilityManager; + this._annotationEditorUIManager = annotationEditorUIManager; + this.#onAppend = onAppend; + this.annotationLayer = null; + this.div = null; + this._cancelled = false; + this._eventBus = linkService.eventBus; + } + async render({ + viewport, + intent = "display", + structTreeLayer = null + }) { + if (this.div) { + if (this._cancelled || !this.annotationLayer) { + return; + } + this.annotationLayer.update({ + viewport: viewport.clone({ + dontFlip: true + }) + }); + return; + } + const [annotations, hasJSActions, fieldObjects] = await Promise.all([this.pdfPage.getAnnotations({ + intent + }), this._hasJSActionsPromise, this._fieldObjectsPromise]); + if (this._cancelled) { + return; + } + const div = this.div = document.createElement("div"); + div.className = "annotationLayer"; + this.#onAppend?.(div); + this.#initAnnotationLayer(viewport, structTreeLayer); + if (annotations.length === 0) { + this.#annotations = annotations; + setLayerDimensions(this.div, viewport); + return; + } + await this.annotationLayer.render({ + annotations, + imageResourcesPath: this.imageResourcesPath, + renderForms: this.renderForms, + downloadManager: this.downloadManager, + enableComment: this.enableComment, + enableScripting: this.enableScripting, + hasJSActions, + fieldObjects + }); + this.#annotations = annotations; + if (this.linkService.isInPresentationMode) { + this.#updatePresentationModeState(PresentationModeState.FULLSCREEN); + } + if (!this.#eventAbortController) { + this.#eventAbortController = new AbortController(); + this._eventBus?._on("presentationmodechanged", evt => { + this.#updatePresentationModeState(evt.state); + }, { + signal: this.#eventAbortController.signal + }); + } + } + #initAnnotationLayer(viewport, structTreeLayer) { + this.annotationLayer = new AnnotationLayer({ + div: this.div, + accessibilityManager: this._accessibilityManager, + annotationCanvasMap: this._annotationCanvasMap, + annotationEditorUIManager: this._annotationEditorUIManager, + annotationStorage: this.annotationStorage, + page: this.pdfPage, + viewport: viewport.clone({ + dontFlip: true + }), + structTreeLayer, + commentManager: this.#commentManager, + linkService: this.linkService + }); + } + cancel() { + this._cancelled = true; + this.#eventAbortController?.abort(); + this.#eventAbortController = null; + } + hide(internal = false) { + this.#externalHide = !internal; + if (!this.div) { + return; + } + this.div.hidden = true; + } + hasEditableAnnotations() { + return !!this.annotationLayer?.hasEditableAnnotations(); + } + async injectLinkAnnotations(inferredLinks) { + if (this.#annotations === null) { + throw new Error("`render` method must be called before `injectLinkAnnotations`."); + } + if (this._cancelled || this.#linksInjected) { + return; + } + this.#linksInjected = true; + const newLinks = this.#annotations.length ? this.#checkInferredLinks(inferredLinks) : inferredLinks; + if (!newLinks.length) { + return; + } + await this.annotationLayer.addLinkAnnotations(newLinks); + if (!this.#externalHide) { + this.div.hidden = false; + } + } + #updatePresentationModeState(state) { + if (!this.div) { + return; + } + let disableFormElements = false; + switch (state) { + case PresentationModeState.FULLSCREEN: + disableFormElements = true; + break; + case PresentationModeState.NORMAL: + break; + default: + return; + } + for (const section of this.div.childNodes) { + if (section.hasAttribute("data-internal-link")) { + continue; + } + section.inert = disableFormElements; + } + } + #checkInferredLinks(inferredLinks) { + function annotationRects(annot) { + if (!annot.quadPoints) { + return [annot.rect]; + } + const rects = []; + for (let i = 2, ii = annot.quadPoints.length; i < ii; i += 8) { + const trX = annot.quadPoints[i]; + const trY = annot.quadPoints[i + 1]; + const blX = annot.quadPoints[i + 2]; + const blY = annot.quadPoints[i + 3]; + rects.push([blX, blY, trX, trY]); + } + return rects; + } + function intersectAnnotations(annot1, annot2) { + const intersections = []; + const annot1Rects = annotationRects(annot1); + const annot2Rects = annotationRects(annot2); + for (const rect1 of annot1Rects) { + for (const rect2 of annot2Rects) { + const intersection = Util.intersect(rect1, rect2); + if (intersection) { + intersections.push(intersection); + } + } + } + return intersections; + } + function areaRects(rects) { + let totalArea = 0; + for (const rect of rects) { + totalArea += Math.abs((rect[2] - rect[0]) * (rect[3] - rect[1])); + } + return totalArea; + } + return inferredLinks.filter(link => { + let linkAreaRects; + for (const annotation of this.#annotations) { + if (annotation.annotationType !== AnnotationType.LINK || !annotation.url) { + continue; + } + const intersections = intersectAnnotations(annotation, link); + if (intersections.length === 0) { + continue; + } + linkAreaRects ??= areaRects(annotationRects(link)); + if (areaRects(intersections) / linkAreaRects > 0.5) { + return false; + } + } + return true; + }); + } +} + +;// ./web/autolinker.js + + +function DOMRectToPDF({ + width, + height, + left, + top +}, pdfPageView) { + if (width === 0 || height === 0) { + return null; + } + const pageBox = pdfPageView.textLayer.div.getBoundingClientRect(); + const bottomLeft = pdfPageView.getPagePoint(left - pageBox.left, top - pageBox.top); + const topRight = pdfPageView.getPagePoint(left - pageBox.left + width, top - pageBox.top + height); + return Util.normalizeRect([bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]]); +} +function calculateLinkPosition(range, pdfPageView) { + const rangeRects = range.getClientRects(); + if (rangeRects.length === 1) { + return { + rect: DOMRectToPDF(rangeRects[0], pdfPageView) + }; + } + const rect = [Infinity, Infinity, -Infinity, -Infinity]; + const quadPoints = []; + let i = 0; + for (const domRect of rangeRects) { + const normalized = DOMRectToPDF(domRect, pdfPageView); + if (normalized === null) { + continue; + } + quadPoints[i] = quadPoints[i + 4] = normalized[0]; + quadPoints[i + 1] = quadPoints[i + 3] = normalized[3]; + quadPoints[i + 2] = quadPoints[i + 6] = normalized[2]; + quadPoints[i + 5] = quadPoints[i + 7] = normalized[1]; + Util.rectBoundingBox(...normalized, rect); + i += 8; + } + return { + quadPoints, + rect + }; +} +function textPosition(container, offset) { + let currentContainer = container; + do { + if (currentContainer.nodeType === Node.TEXT_NODE) { + const currentLength = currentContainer.textContent.length; + if (offset <= currentLength) { + return [currentContainer, offset]; + } + offset -= currentLength; + } else if (currentContainer.firstChild) { + currentContainer = currentContainer.firstChild; + continue; + } + while (!currentContainer.nextSibling && currentContainer !== container) { + currentContainer = currentContainer.parentNode; + } + if (currentContainer !== container) { + currentContainer = currentContainer.nextSibling; + } + } while (currentContainer !== container); + throw new Error("Offset is bigger than container's contents length."); +} +function createLinkAnnotation({ + url, + index, + length +}, pdfPageView, id) { + const highlighter = pdfPageView._textHighlighter; + const [{ + begin, + end + }] = highlighter._convertMatches([index], [length]); + const range = new Range(); + range.setStart(...textPosition(highlighter.textDivs[begin.divIdx], begin.offset)); + range.setEnd(...textPosition(highlighter.textDivs[end.divIdx], end.offset)); + return { + id: `inferred_link_${id}`, + unsafeUrl: url, + url, + annotationType: AnnotationType.LINK, + rotation: 0, + ...calculateLinkPosition(range, pdfPageView), + borderStyle: null + }; +} +class Autolinker { + static #index = 0; + static #regex; + static #numericTLDRegex; + static findLinks(text) { + this.#regex ??= /\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|(?=\p{L})[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[[\p{P}--\-]<>]]+(?:\.[\S--[[\p{P}--\-]<>]]+)+)/gmv; + const [normalizedText, diffs] = normalize(text, { + ignoreDashEOL: true + }); + const matches = normalizedText.matchAll(this.#regex); + const links = []; + for (const match of matches) { + const [url, emailDomain] = match; + let raw; + if (url.startsWith("www.") || url.startsWith("http://") || url.startsWith("https://")) { + raw = url; + } else if (emailDomain) { + const hostname = URL.parse(`http://${emailDomain}`)?.hostname; + if (!hostname) { + continue; + } + this.#numericTLDRegex ??= /\.\d+$/; + if (this.#numericTLDRegex.test(hostname)) { + continue; + } + } + raw ??= url.startsWith("mailto:") ? url : `mailto:${url}`; + const absoluteURL = createValidAbsoluteUrl(raw, null, { + addDefaultProtocol: true + }); + if (absoluteURL) { + const [index, length] = getOriginalIndex(diffs, match.index, url.length); + links.push({ + url: absoluteURL.href, + index, + length + }); + } + } + return links; + } + static processLinks(pdfPageView) { + return this.findLinks(pdfPageView._textHighlighter.textContentItemsStr.join("\n")).map(link => createLinkAnnotation(link, pdfPageView, this.#index++)); + } +} + +;// ./web/base_pdf_page_view.js + + +class BasePDFPageView extends RenderableView { + #loadingId = null; + #renderError = null; + #renderingState = RenderingStates.INITIAL; + #showCanvas = null; + #startTime = 0; + #tempCanvas = null; + canvas = null; + div = null; + enableOptimizedPartialRendering = false; + eventBus = null; + id = null; + pageColors = null; + recordedBBoxes = null; + renderingQueue = null; + constructor(options) { + super(); + this.eventBus = options.eventBus; + this.id = options.id; + this.pageColors = options.pageColors || null; + this.renderingQueue = options.renderingQueue; + this.enableOptimizedPartialRendering = options.enableOptimizedPartialRendering ?? false; + this.minDurationToUpdateCanvas = options.minDurationToUpdateCanvas ?? 500; + } + get renderingState() { + return this.#renderingState; + } + set renderingState(state) { + if (state === this.#renderingState) { + return; + } + this.#renderingState = state; + if (this.#loadingId) { + clearTimeout(this.#loadingId); + this.#loadingId = null; + } + switch (state) { + case RenderingStates.PAUSED: + this.div.classList.remove("loading"); + this.#startTime = 0; + this.#showCanvas?.(false); + break; + case RenderingStates.RUNNING: + this.div.classList.add("loadingIcon"); + this.#loadingId = setTimeout(() => { + this.div.classList.add("loading"); + this.#loadingId = null; + }, 0); + this.#startTime = Date.now(); + break; + case RenderingStates.INITIAL: + case RenderingStates.FINISHED: + this.div.classList.remove("loadingIcon", "loading"); + this.#startTime = 0; + break; + } + } + _createCanvas(onShow, hideUntilComplete = false) { + const { + pageColors + } = this; + const hasHCM = !!(pageColors?.background && pageColors?.foreground); + const prevCanvas = this.canvas; + const updateOnFirstShow = !prevCanvas && !hasHCM && !hideUntilComplete; + let canvas = this.canvas = document.createElement("canvas"); + this.#showCanvas = isLastShow => { + if (updateOnFirstShow) { + let tempCanvas = this.#tempCanvas; + if (!isLastShow && this.minDurationToUpdateCanvas > 0) { + if (Date.now() - this.#startTime < this.minDurationToUpdateCanvas) { + return; + } + if (!tempCanvas) { + tempCanvas = this.#tempCanvas = canvas; + canvas = this.canvas = canvas.cloneNode(false); + onShow(canvas); + } + } + if (tempCanvas) { + const ctx = canvas.getContext("2d", { + alpha: false + }); + ctx.drawImage(tempCanvas, 0, 0); + if (isLastShow) { + this.#resetTempCanvas(); + } else { + this.#startTime = Date.now(); + } + return; + } + onShow(canvas); + this.#showCanvas = null; + return; + } + if (!isLastShow) { + return; + } + if (prevCanvas) { + prevCanvas.replaceWith(canvas); + prevCanvas.width = prevCanvas.height = 0; + } else { + onShow(canvas); + } + }; + return { + canvas, + prevCanvas + }; + } + #renderContinueCallback = cont => { + this.#showCanvas?.(false); + if (this.renderingQueue && !this.renderingQueue.isHighestPriority(this)) { + this.renderingState = RenderingStates.PAUSED; + this.resume = () => { + this.renderingState = RenderingStates.RUNNING; + cont(); + }; + return; + } + cont(); + }; + _resetCanvas() { + const { + canvas + } = this; + if (!canvas) { + return; + } + canvas.remove(); + canvas.width = canvas.height = 0; + this.canvas = null; + this.#resetTempCanvas(); + } + #resetTempCanvas() { + if (this.#tempCanvas) { + this.#tempCanvas.width = this.#tempCanvas.height = 0; + this.#tempCanvas = null; + } + } + async _drawCanvas(options, onCancel, onFinish) { + const renderTask = this.renderTask = this.pdfPage.render(options); + renderTask.onContinue = this.#renderContinueCallback; + renderTask.onError = error => { + if (error instanceof RenderingCancelledException) { + onCancel(); + this.#renderError = null; + } + }; + let error = null; + try { + await renderTask.promise; + this.#showCanvas?.(true); + } catch (e) { + if (e instanceof RenderingCancelledException) { + return; + } + error = e; + this.#showCanvas?.(true); + } finally { + this.#renderError = error; + if (renderTask === this.renderTask) { + this.renderTask = null; + if (this.enableOptimizedPartialRendering) { + this.recordedBBoxes ??= renderTask.recordedBBoxes; + } + } + } + this.renderingState = RenderingStates.FINISHED; + onFinish(renderTask); + if (error) { + throw error; + } + } + cancelRendering({ + cancelExtraDelay = 0 + } = {}) { + if (this.renderTask) { + this.renderTask.cancel(cancelExtraDelay); + this.renderTask = null; + } + this.resume = null; + } + dispatchPageRender() { + this.eventBus.dispatch("pagerender", { + source: this, + pageNumber: this.id + }); + } + dispatchPageRendered(cssTransform, isDetailView) { + this.eventBus.dispatch("pagerendered", { + source: this, + pageNumber: this.id, + cssTransform, + isDetailView, + timestamp: performance.now(), + error: this.#renderError + }); + } +} + +;// ./web/draw_layer_builder.js + +class DrawLayerBuilder { + #drawLayer = null; + async render({ + intent = "display" + }) { + if (intent !== "display" || this.#drawLayer || this._cancelled) { + return; + } + this.#drawLayer = new DrawLayer(); + } + cancel() { + this._cancelled = true; + if (!this.#drawLayer) { + return; + } + this.#drawLayer.destroy(); + this.#drawLayer = null; + } + setParent(parent) { + this.#drawLayer?.setParent(parent); + } + getDrawLayer() { + return this.#drawLayer; + } +} + +;// ./web/pdf_page_detail_view.js + + + +class PDFPageDetailView extends BasePDFPageView { + #detailArea = null; + renderingCancelled = false; + constructor({ + pageView + }) { + super(pageView); + this.pageView = pageView; + this.renderingId = "detail" + this.id; + this.div = pageView.div; + } + setPdfPage(pdfPage) { + this.pageView.setPdfPage(pdfPage); + } + get pdfPage() { + return this.pageView.pdfPage; + } + get renderingState() { + return super.renderingState; + } + set renderingState(state) { + this.renderingCancelled = false; + super.renderingState = state; + } + reset({ + keepCanvas = false + } = {}) { + const renderingCancelled = this.renderingCancelled || this.renderingState === RenderingStates.RUNNING || this.renderingState === RenderingStates.PAUSED; + this.cancelRendering(); + this.renderingState = RenderingStates.INITIAL; + this.renderingCancelled = renderingCancelled; + if (!keepCanvas) { + this._resetCanvas(); + } + } + #shouldRenderDifferentArea(visibleArea) { + if (!this.#detailArea) { + return true; + } + const minDetailX = this.#detailArea.minX; + const minDetailY = this.#detailArea.minY; + const maxDetailX = this.#detailArea.width + minDetailX; + const maxDetailY = this.#detailArea.height + minDetailY; + if (visibleArea.minX < minDetailX || visibleArea.minY < minDetailY || visibleArea.maxX > maxDetailX || visibleArea.maxY > maxDetailY) { + return true; + } + const { + width: maxWidth, + height: maxHeight, + scale + } = this.pageView.viewport; + if (this.#detailArea.scale !== scale) { + return true; + } + const paddingLeftSize = visibleArea.minX - minDetailX; + const paddingRightSize = maxDetailX - visibleArea.maxX; + const paddingTopSize = visibleArea.minY - minDetailY; + const paddingBottomSize = maxDetailY - visibleArea.maxY; + const MOVEMENT_THRESHOLD = 0.5; + const ratio = (1 + MOVEMENT_THRESHOLD) / MOVEMENT_THRESHOLD; + if (minDetailX > 0 && paddingRightSize / paddingLeftSize > ratio || maxDetailX < maxWidth && paddingLeftSize / paddingRightSize > ratio || minDetailY > 0 && paddingBottomSize / paddingTopSize > ratio || maxDetailY < maxHeight && paddingTopSize / paddingBottomSize > ratio) { + return true; + } + return false; + } + update({ + visibleArea = null, + underlyingViewUpdated = false + } = {}) { + if (underlyingViewUpdated) { + this.cancelRendering(); + this.renderingState = RenderingStates.INITIAL; + return; + } + if (!this.#shouldRenderDifferentArea(visibleArea)) { + return; + } + const { + viewport, + maxCanvasPixels, + capCanvasAreaFactor + } = this.pageView; + const visibleWidth = visibleArea.maxX - visibleArea.minX; + const visibleHeight = visibleArea.maxY - visibleArea.minY; + const visiblePixels = visibleWidth * visibleHeight * OutputScale.pixelRatio ** 2; + const maxDetailToVisibleLinearRatio = Math.sqrt(OutputScale.capPixels(maxCanvasPixels, capCanvasAreaFactor) / visiblePixels); + const maxOverflowScale = (maxDetailToVisibleLinearRatio - 1) / 2; + let overflowScale = Math.min(1, maxOverflowScale); + if (overflowScale < 0) { + overflowScale = 0; + } + const overflowWidth = visibleWidth * overflowScale; + const overflowHeight = visibleHeight * overflowScale; + const minX = Math.max(0, visibleArea.minX - overflowWidth); + const maxX = Math.min(viewport.width, visibleArea.maxX + overflowWidth); + const minY = Math.max(0, visibleArea.minY - overflowHeight); + const maxY = Math.min(viewport.height, visibleArea.maxY + overflowHeight); + const width = maxX - minX; + const height = maxY - minY; + this.#detailArea = { + minX, + minY, + width, + height, + scale: viewport.scale + }; + this.reset({ + keepCanvas: true + }); + } + _getRenderingContext(canvas, transform) { + const baseContext = this.pageView._getRenderingContext(canvas, transform, false); + const recordedBBoxes = this.pdfPage.recordedBBoxes; + if (!recordedBBoxes || !this.enableOptimizedPartialRendering) { + return baseContext; + } + const { + viewport: { + width: vWidth, + height: vHeight + } + } = this.pageView; + const { + width: aWidth, + height: aHeight, + minX: aMinX, + minY: aMinY + } = this.#detailArea; + const detailMinX = aMinX / vWidth; + const detailMinY = aMinY / vHeight; + const detailMaxX = (aMinX + aWidth) / vWidth; + const detailMaxY = (aMinY + aHeight) / vHeight; + return { + ...baseContext, + operationsFilter(index) { + if (recordedBBoxes.isEmpty(index)) { + return false; + } + return recordedBBoxes.minX(index) <= detailMaxX && recordedBBoxes.maxX(index) >= detailMinX && recordedBBoxes.minY(index) <= detailMaxY && recordedBBoxes.maxY(index) >= detailMinY; + } + }; + } + async draw() { + if (this.pageView.detailView !== this) { + return undefined; + } + const hideUntilComplete = this.pageView.renderingState === RenderingStates.FINISHED || this.renderingState === RenderingStates.FINISHED; + if (this.renderingState !== RenderingStates.INITIAL) { + console.error("Must be in new state before drawing"); + this.reset(); + } + const { + div, + pdfPage, + viewport + } = this.pageView; + if (!pdfPage) { + this.renderingState = RenderingStates.FINISHED; + throw new Error("pdfPage is not loaded"); + } + this.renderingState = RenderingStates.RUNNING; + const canvasWrapper = this.pageView._ensureCanvasWrapper(); + const { + canvas, + prevCanvas + } = this._createCanvas(newCanvas => { + if (canvasWrapper.firstElementChild?.tagName === "CANVAS") { + canvasWrapper.firstElementChild.after(newCanvas); + } else { + canvasWrapper.prepend(newCanvas); + } + }, hideUntilComplete); + canvas.ariaHidden = true; + if (this.enableOptimizedPartialRendering) { + canvas.className = "detailView"; + } + const { + width, + height + } = viewport; + const area = this.#detailArea; + const { + pixelRatio + } = OutputScale; + const transform = [pixelRatio, 0, 0, pixelRatio, -area.minX * pixelRatio, -area.minY * pixelRatio]; + canvas.width = area.width * pixelRatio; + canvas.height = area.height * pixelRatio; + const { + style + } = canvas; + style.width = `${area.width * 100 / width}%`; + style.height = `${area.height * 100 / height}%`; + style.top = `${area.minY * 100 / height}%`; + style.left = `${area.minX * 100 / width}%`; + const renderingPromise = this._drawCanvas(this._getRenderingContext(canvas, transform), () => { + this.canvas?.remove(); + this.canvas = prevCanvas; + }, () => { + this.dispatchPageRendered(false, true); + }); + div.setAttribute("data-loaded", true); + this.dispatchPageRender(); + return renderingPromise; + } +} + +;// ./web/struct_tree_layer_builder.js + + +const PDF_ROLE_TO_HTML_ROLE = { + Document: null, + DocumentFragment: null, + Part: "group", + Sect: "group", + Div: "group", + Aside: "note", + NonStruct: "none", + P: null, + H: "heading", + Title: null, + FENote: "note", + Sub: "group", + Lbl: null, + Span: null, + Em: null, + Strong: null, + Link: "link", + Annot: "note", + Form: "form", + Ruby: null, + RB: null, + RT: null, + RP: null, + Warichu: null, + WT: null, + WP: null, + L: "list", + LI: "listitem", + LBody: null, + Table: "table", + TR: "row", + TH: "columnheader", + TD: "cell", + THead: "rowgroup", + TBody: "rowgroup", + TFoot: null, + Caption: null, + Figure: "figure", + Formula: null, + Artifact: null +}; +const MathMLElements = new Set(["math", "merror", "mfrac", "mi", "mmultiscripts", "mn", "mo", "mover", "mpadded", "mprescripts", "mroot", "mrow", "ms", "mspace", "msqrt", "mstyle", "msub", "msubsup", "msup", "mtable", "mtd", "mtext", "mtr", "munder", "munderover", "semantics"]); +const MathMLNamespace = "http://www.w3.org/1998/Math/MathML"; +class MathMLSanitizer { + static get sanitizer() { + return shadow(this, "sanitizer", FeatureTest.isSanitizerSupported ? new Sanitizer({ + elements: [...MathMLElements].map(name => ({ + name, + namespace: MathMLNamespace + })), + replaceWithChildrenElements: [{ + name: "maction", + namespace: MathMLNamespace + }], + attributes: ["dir", "displaystyle", "mathbackground", "mathcolor", "mathsize", "scriptlevel", "encoding", "display", "linethickness", "intent", "arg", "form", "fence", "separator", "lspace", "rspace", "stretchy", "symmetric", "maxsize", "minsize", "largeop", "movablelimits", "width", "height", "depth", "voffset", "accent", "accentunder", "columnspan", "rowspan"], + comments: false + }) : null); + } +} +const HEADING_PATTERN = /^H(\d+)$/; +class StructTreeLayerBuilder { + #promise; + #treeDom = null; + #treePromise; + #elementAttributes = new Map(); + #rawDims; + #elementsToAddToTextLayer = null; + #elementsToHideInTextLayer = null; + #elementsToStealFromTextLayer = null; + constructor(pdfPage, rawDims) { + this.#promise = pdfPage.getStructTree(); + this.#rawDims = rawDims; + } + async render() { + if (this.#treePromise) { + return this.#treePromise; + } + const { + promise, + resolve, + reject + } = Promise.withResolvers(); + this.#treePromise = promise; + try { + this.#treeDom = this.#walk(await this.#promise); + } catch (ex) { + reject(ex); + } + this.#promise = null; + this.#treeDom?.classList.add("structTree"); + resolve(this.#treeDom); + return promise; + } + async getAriaAttributes(annotationId) { + try { + await this.render(); + return this.#elementAttributes.get(annotationId); + } catch {} + return null; + } + hide() { + if (this.#treeDom && !this.#treeDom.hidden) { + this.#treeDom.hidden = true; + } + } + show() { + if (this.#treeDom?.hidden) { + this.#treeDom.hidden = false; + } + } + #setAttributes(structElement, htmlElement) { + const { + alt, + id, + lang + } = structElement; + if (alt !== undefined) { + let added = false; + const label = removeNullCharacters(alt); + for (const child of structElement.children) { + if (child.type === "annotation") { + this.#elementAttributes.getOrInsertComputed(child.id, makeMap).set("aria-label", label); + added = true; + } + } + if (!added) { + htmlElement.setAttribute("aria-label", label); + } + } + if (id !== undefined) { + htmlElement.setAttribute("aria-owns", id); + } + if (lang !== undefined) { + htmlElement.setAttribute("lang", removeNullCharacters(lang, true)); + } + } + #addImageInTextLayer(node, element) { + const { + alt, + bbox, + children + } = node; + const child = children?.[0]; + if (!this.#rawDims || !alt || !bbox || child?.type !== "content") { + return false; + } + const { + id + } = child; + if (!id) { + return false; + } + element.setAttribute("aria-owns", id); + const img = document.createElement("span"); + (this.#elementsToAddToTextLayer ||= new Map()).set(id, img); + img.setAttribute("role", "img"); + img.setAttribute("aria-label", removeNullCharacters(alt)); + const { + pageHeight, + pageX, + pageY + } = this.#rawDims; + const calc = "calc(var(--total-scale-factor) *"; + const { + style + } = img; + style.width = `${calc}${bbox[2] - bbox[0]}px)`; + style.height = `${calc}${bbox[3] - bbox[1]}px)`; + style.left = `${calc}${bbox[0] - pageX}px)`; + style.top = `${calc}${pageHeight - bbox[3] + pageY}px)`; + return true; + } + updateTextLayer() { + if (this.#elementsToAddToTextLayer) { + for (const [id, img] of this.#elementsToAddToTextLayer) { + document.getElementById(id)?.append(img); + } + this.#elementsToAddToTextLayer.clear(); + this.#elementsToAddToTextLayer = null; + } + if (this.#elementsToHideInTextLayer) { + for (const id of this.#elementsToHideInTextLayer) { + const elem = document.getElementById(id); + if (elem) { + elem.ariaHidden = true; + } + } + this.#elementsToHideInTextLayer.length = 0; + this.#elementsToHideInTextLayer = null; + } + if (this.#elementsToStealFromTextLayer) { + for (let i = 0, ii = this.#elementsToStealFromTextLayer.length; i < ii; i += 2) { + const element = this.#elementsToStealFromTextLayer[i]; + const ids = this.#elementsToStealFromTextLayer[i + 1]; + let textContent = ""; + for (const id of ids) { + const elem = document.getElementById(id); + if (elem) { + textContent += elem.textContent.trim() || ""; + elem.ariaHidden = "true"; + } + } + if (textContent) { + element.textContent = textContent; + } + } + this.#elementsToStealFromTextLayer.length = 0; + this.#elementsToStealFromTextLayer = null; + } + } + #walk(node, parentNodes = []) { + if (!node) { + return null; + } + let element; + if ("role" in node) { + const { + role + } = node; + if (MathMLElements.has(role)) { + element = document.createElementNS(MathMLNamespace, role); + const ids = []; + (this.#elementsToStealFromTextLayer ||= []).push(element, ids); + for (const { + type, + id + } of node.children || []) { + if (type === "content" && id) { + ids.push(id); + } + } + } else { + element = document.createElement("span"); + } + const match = role.match(HEADING_PATTERN); + if (match) { + element.setAttribute("role", "heading"); + element.setAttribute("aria-level", match[1]); + } else if (PDF_ROLE_TO_HTML_ROLE[role]) { + element.setAttribute("role", role === "TH" && parentNodes.at(-1)?.role === "TR" && parentNodes.at(-2)?.role === "TBody" ? "rowheader" : PDF_ROLE_TO_HTML_ROLE[role]); + } + if (role === "Figure" && this.#addImageInTextLayer(node, element)) { + return element; + } + if (role === "Formula") { + if (node.mathML && MathMLSanitizer.sanitizer) { + element.setHTML(node.mathML, { + sanitizer: MathMLSanitizer.sanitizer + }); + for (const { + id + } of node.children || []) { + if (!id) { + continue; + } + (this.#elementsToHideInTextLayer ||= []).push(id); + } + delete node.alt; + } + if (!node.mathML && node.children.length === 1 && node.children[0].role !== "math") { + element = document.createElementNS(MathMLNamespace, "math"); + delete node.alt; + } + } + } + element ||= document.createElement("span"); + this.#setAttributes(node, element); + if (node.children) { + if (node.children.length === 1 && "id" in node.children[0]) { + this.#setAttributes(node.children[0], element); + } else { + parentNodes.push(node); + for (const kid of node.children) { + element.append(this.#walk(kid, parentNodes)); + } + parentNodes.pop(); + } + } + return element; + } +} + +;// ./web/text_accessibility.js + +class TextAccessibilityManager { + #enabled = false; + #textChildren = null; + #textNodes = new Map(); + #waitingElements = new Map(); + setTextMapping(textDivs) { + this.#textChildren = textDivs; + } + static #compareElementPositions(e1, e2) { + const rect1 = e1.getBoundingClientRect(); + const rect2 = e2.getBoundingClientRect(); + if (rect1.width === 0 && rect1.height === 0) { + return +1; + } + if (rect2.width === 0 && rect2.height === 0) { + return -1; + } + const top1 = rect1.y; + const bot1 = rect1.y + rect1.height; + const mid1 = rect1.y + rect1.height / 2; + const top2 = rect2.y; + const bot2 = rect2.y + rect2.height; + const mid2 = rect2.y + rect2.height / 2; + if (mid1 <= top2 && mid2 >= bot1) { + return -1; + } + if (mid2 <= top1 && mid1 >= bot2) { + return +1; + } + const centerX1 = rect1.x + rect1.width / 2; + const centerX2 = rect2.x + rect2.width / 2; + return centerX1 - centerX2; + } + enable() { + if (this.#enabled) { + throw new Error("TextAccessibilityManager is already enabled."); + } + if (!this.#textChildren) { + throw new Error("Text divs and strings have not been set."); + } + this.#enabled = true; + this.#textChildren = this.#textChildren.slice(); + this.#textChildren.sort(TextAccessibilityManager.#compareElementPositions); + if (this.#textNodes.size > 0) { + const textChildren = this.#textChildren; + for (const [id, nodeIndex] of this.#textNodes) { + const element = document.getElementById(id); + if (!element) { + this.#textNodes.delete(id); + continue; + } + this.#addIdToAriaOwns(id, textChildren[nodeIndex]); + } + } + for (const [element, isRemovable] of this.#waitingElements) { + this.addPointerInTextLayer(element, isRemovable); + } + this.#waitingElements.clear(); + } + disable() { + if (!this.#enabled) { + return; + } + this.#waitingElements.clear(); + this.#textChildren = null; + this.#enabled = false; + } + removePointerInTextLayer(element) { + if (!this.#enabled) { + this.#waitingElements.delete(element); + return; + } + const children = this.#textChildren; + if (!children || children.length === 0) { + return; + } + const { + id + } = element; + const nodeIndex = this.#textNodes.get(id); + if (nodeIndex === undefined) { + return; + } + const node = children[nodeIndex]; + this.#textNodes.delete(id); + let owns = node.getAttribute("aria-owns"); + if (owns?.includes(id)) { + owns = owns.split(" ").filter(x => x !== id).join(" "); + if (owns) { + node.setAttribute("aria-owns", owns); + } else { + node.removeAttribute("aria-owns"); + node.setAttribute("role", "presentation"); + } + } + } + #addIdToAriaOwns(id, node) { + const owns = node.getAttribute("aria-owns"); + if (!owns?.includes(id)) { + node.setAttribute("aria-owns", owns ? `${owns} ${id}` : id); + } + node.removeAttribute("role"); + } + addPointerInTextLayer(element, isRemovable) { + const { + id + } = element; + if (!id) { + return null; + } + if (!this.#enabled) { + this.#waitingElements.set(element, isRemovable); + return null; + } + if (isRemovable) { + this.removePointerInTextLayer(element); + } + const children = this.#textChildren; + if (!children || children.length === 0) { + return null; + } + const index = binarySearchFirstItem(children, node => TextAccessibilityManager.#compareElementPositions(element, node) < 0); + const nodeIndex = Math.max(0, index - 1); + const child = children[nodeIndex]; + this.#addIdToAriaOwns(id, child); + this.#textNodes.set(id, nodeIndex); + const parent = child.parentNode; + return parent?.classList.contains("markedContent") ? parent.id : null; + } + moveElementInDOM(container, element, contentElement, isRemovable) { + const id = this.addPointerInTextLayer(contentElement, isRemovable); + if (!container.hasChildNodes()) { + container.append(element); + return id; + } + const children = Array.from(container.childNodes).filter(node => node !== element); + if (children.length === 0) { + return id; + } + const index = binarySearchFirstItem(children, node => TextAccessibilityManager.#compareElementPositions(element, node) < 0); + if (index === 0) { + children[0].before(element); + } else { + children[index - 1].after(element); + } + return id; + } +} + +;// ./web/text_highlighter.js +class TextHighlighter { + #eventAbortController = null; + constructor({ + findController, + eventBus, + pageIndex + }) { + this.findController = findController; + this.matches = []; + this.eventBus = eventBus; + this.pageIdx = pageIndex; + this.textDivs = null; + this.textContentItemsStr = null; + this.enabled = false; + } + setTextMapping(divs, texts) { + this.textDivs = divs; + this.textContentItemsStr = texts; + } + enable() { + if (!this.textDivs || !this.textContentItemsStr) { + throw new Error("Text divs and strings have not been set."); + } + if (this.enabled) { + throw new Error("TextHighlighter is already enabled."); + } + this.enabled = true; + if (!this.#eventAbortController) { + this.#eventAbortController = new AbortController(); + this.eventBus._on("updatetextlayermatches", evt => { + if (evt.pageIndex === this.pageIdx || evt.pageIndex === -1) { + this._updateMatches(); + } + }, { + signal: this.#eventAbortController.signal + }); + } + this._updateMatches(); + } + disable() { + if (!this.enabled) { + return; + } + this.enabled = false; + this.#eventAbortController?.abort(); + this.#eventAbortController = null; + this._updateMatches(true); + } + _convertMatches(matches, matchesLength) { + if (!matches) { + return []; + } + const { + textContentItemsStr + } = this; + let i = 0, + iIndex = 0; + const end = textContentItemsStr.length - 1; + const result = []; + for (let m = 0, mm = matches.length; m < mm; m++) { + let matchIdx = matches[m]; + while (i !== end && matchIdx >= iIndex + textContentItemsStr[i].length) { + iIndex += textContentItemsStr[i].length; + i++; + } + if (i === textContentItemsStr.length) { + console.error("Could not find a matching mapping"); + } + const match = { + begin: { + divIdx: i, + offset: matchIdx - iIndex + } + }; + matchIdx += matchesLength[m]; + while (i !== end && matchIdx > iIndex + textContentItemsStr[i].length) { + iIndex += textContentItemsStr[i].length; + i++; + } + match.end = { + divIdx: i, + offset: matchIdx - iIndex + }; + result.push(match); + } + return result; + } + _renderMatches(matches) { + if (matches.length === 0) { + return; + } + const { + findController, + pageIdx + } = this; + const { + textContentItemsStr, + textDivs + } = this; + const isSelectedPage = pageIdx === findController.selected.pageIdx; + const selectedMatchIdx = findController.selected.matchIdx; + const highlightAll = findController.state.highlightAll; + let prevEnd = null; + const infinity = { + divIdx: -1, + offset: undefined + }; + function beginText(begin, className) { + const divIdx = begin.divIdx; + textDivs[divIdx].textContent = ""; + return appendTextToDiv(divIdx, 0, begin.offset, className); + } + function appendTextToDiv(divIdx, fromOffset, toOffset, className) { + let div = textDivs[divIdx]; + if (div.nodeType === Node.TEXT_NODE) { + const span = document.createElement("span"); + div.before(span); + span.append(div); + textDivs[divIdx] = span; + div = span; + } + const content = textContentItemsStr[divIdx].substring(fromOffset, toOffset); + const node = document.createTextNode(content); + if (className) { + const span = document.createElement("span"); + span.className = `${className} appended`; + span.append(node); + div.append(span); + if (className.includes("selected")) { + const { + left + } = span.getClientRects()[0]; + const parentLeft = div.getBoundingClientRect().left; + return left - parentLeft; + } + return 0; + } + div.append(node); + return 0; + } + let i0 = selectedMatchIdx, + i1 = i0 + 1; + if (highlightAll) { + i0 = 0; + i1 = matches.length; + } else if (!isSelectedPage) { + return; + } + let lastDivIdx = -1; + let lastOffset = -1; + for (let i = i0; i < i1; i++) { + const match = matches[i]; + const begin = match.begin; + if (begin.divIdx === lastDivIdx && begin.offset === lastOffset) { + continue; + } + lastDivIdx = begin.divIdx; + lastOffset = begin.offset; + const end = match.end; + const isSelected = isSelectedPage && i === selectedMatchIdx; + const highlightSuffix = isSelected ? " selected" : ""; + let selectedLeft = 0; + if (!prevEnd || begin.divIdx !== prevEnd.divIdx) { + if (prevEnd !== null) { + appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset); + } + beginText(begin); + } else { + appendTextToDiv(prevEnd.divIdx, prevEnd.offset, begin.offset); + } + if (begin.divIdx === end.divIdx) { + selectedLeft = appendTextToDiv(begin.divIdx, begin.offset, end.offset, "highlight" + highlightSuffix); + } else { + selectedLeft = appendTextToDiv(begin.divIdx, begin.offset, infinity.offset, "highlight begin" + highlightSuffix); + for (let n0 = begin.divIdx + 1, n1 = end.divIdx; n0 < n1; n0++) { + textDivs[n0].className = "highlight middle" + highlightSuffix; + } + beginText(end, "highlight end" + highlightSuffix); + } + prevEnd = end; + if (isSelected) { + findController.scrollMatchIntoView({ + element: textDivs[begin.divIdx], + selectedLeft, + pageIndex: pageIdx, + matchIndex: selectedMatchIdx + }); + } + } + if (prevEnd) { + appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset); + } + } + _updateMatches(reset = false) { + if (!this.enabled && !reset) { + return; + } + const { + findController, + matches, + pageIdx + } = this; + const { + textContentItemsStr, + textDivs + } = this; + let clearedUntilDivIdx = -1; + for (const match of matches) { + const begin = Math.max(clearedUntilDivIdx, match.begin.divIdx); + for (let n = begin, end = match.end.divIdx; n <= end; n++) { + const div = textDivs[n]; + div.textContent = textContentItemsStr[n]; + div.className = ""; + } + clearedUntilDivIdx = match.end.divIdx + 1; + } + if (!findController?.highlightMatches || reset) { + return; + } + const pageMatches = findController.pageMatches[pageIdx] || null; + const pageMatchesLength = findController.pageMatchesLength[pageIdx] || null; + this.matches = this._convertMatches(pageMatches, pageMatchesLength); + this._renderMatches(this.matches); + } +} + +;// ./web/text_layer_builder.js + + +class TextLayerBuilder { + #enablePermissions = false; + #onAppend = null; + #renderingDone = false; + #textLayer = null; + static #textLayers = new Map(); + static #selectionChangeAbortController = null; + constructor({ + pdfPage, + highlighter = null, + accessibilityManager = null, + enablePermissions = false, + onAppend = null + }) { + this.pdfPage = pdfPage; + this.highlighter = highlighter; + this.accessibilityManager = accessibilityManager; + this.#enablePermissions = enablePermissions === true; + this.#onAppend = onAppend; + this.div = document.createElement("div"); + this.div.tabIndex = 0; + this.div.className = "textLayer"; + } + async render({ + viewport, + textContentParams = null + }) { + if (this.#renderingDone && this.#textLayer) { + this.#textLayer.update({ + viewport, + onBefore: this.hide.bind(this) + }); + this.show(); + return; + } + this.cancel(); + this.#textLayer = new TextLayer({ + textContentSource: this.pdfPage.streamTextContent(textContentParams || { + includeMarkedContent: true, + disableNormalization: true + }), + container: this.div, + viewport + }); + const { + textDivs, + textContentItemsStr + } = this.#textLayer; + this.highlighter?.setTextMapping(textDivs, textContentItemsStr); + this.accessibilityManager?.setTextMapping(textDivs); + await this.#textLayer.render(); + this.#renderingDone = true; + const endOfContent = document.createElement("div"); + endOfContent.className = "endOfContent"; + this.div.append(endOfContent); + this.#bindMouse(endOfContent); + this.#onAppend?.(this.div); + this.highlighter?.enable(); + this.accessibilityManager?.enable(); + } + hide() { + if (!this.div.hidden && this.#renderingDone) { + this.highlighter?.disable(); + this.div.hidden = true; + } + } + show() { + if (this.div.hidden && this.#renderingDone) { + this.div.hidden = false; + this.highlighter?.enable(); + } + } + cancel() { + this.#textLayer?.cancel(); + this.#textLayer = null; + this.highlighter?.disable(); + this.accessibilityManager?.disable(); + TextLayerBuilder.#removeGlobalSelectionListener(this.div); + } + #bindMouse(end) { + const { + div + } = this; + div.addEventListener("mousedown", () => { + div.classList.add("selecting"); + }); + div.addEventListener("copy", event => { + if (!this.#enablePermissions) { + const selection = document.getSelection(); + event.clipboardData.setData("text/plain", removeNullCharacters(normalizeUnicode(selection.toString()))); + } + stopEvent(event); + }); + TextLayerBuilder.#textLayers.set(div, end); + TextLayerBuilder.#enableGlobalSelectionListener(); + } + static #removeGlobalSelectionListener(textLayerDiv) { + this.#textLayers.delete(textLayerDiv); + if (this.#textLayers.size === 0) { + this.#selectionChangeAbortController?.abort(); + this.#selectionChangeAbortController = null; + } + } + static #enableGlobalSelectionListener() { + if (this.#selectionChangeAbortController) { + return; + } + this.#selectionChangeAbortController = new AbortController(); + const { + signal + } = this.#selectionChangeAbortController; + const reset = (end, textLayer) => { + textLayer.append(end); + end.style.width = ""; + end.style.height = ""; + textLayer.classList.remove("selecting"); + }; + let isPointerDown = false; + document.addEventListener("pointerdown", () => { + isPointerDown = true; + }, { + signal + }); + document.addEventListener("pointerup", () => { + isPointerDown = false; + this.#textLayers.forEach(reset); + }, { + signal + }); + window.addEventListener("blur", () => { + isPointerDown = false; + this.#textLayers.forEach(reset); + }, { + signal + }); + document.addEventListener("keyup", () => { + if (!isPointerDown) { + this.#textLayers.forEach(reset); + } + }, { + signal + }); + var isFirefox, prevRange; + document.addEventListener("selectionchange", () => { + const selection = document.getSelection(); + if (selection.rangeCount === 0) { + this.#textLayers.forEach(reset); + return; + } + const activeTextLayers = new Set(); + for (let i = 0; i < selection.rangeCount; i++) { + const range = selection.getRangeAt(i); + for (const textLayerDiv of this.#textLayers.keys()) { + if (!activeTextLayers.has(textLayerDiv) && range.intersectsNode(textLayerDiv)) { + activeTextLayers.add(textLayerDiv); + } + } + } + for (const [textLayerDiv, endDiv] of this.#textLayers) { + if (activeTextLayers.has(textLayerDiv)) { + textLayerDiv.classList.add("selecting"); + } else { + reset(endDiv, textLayerDiv); + } + } + isFirefox ??= getComputedStyle(this.#textLayers.values().next().value).getPropertyValue("-moz-user-select") === "none"; + if (isFirefox) { + return; + } + const range = selection.getRangeAt(0); + const modifyStart = prevRange && (range.compareBoundaryPoints(Range.END_TO_END, prevRange) === 0 || range.compareBoundaryPoints(Range.START_TO_END, prevRange) === 0); + let anchor = modifyStart ? range.startContainer : range.endContainer; + if (anchor.nodeType === Node.TEXT_NODE) { + anchor = anchor.parentNode; + } + if (anchor.classList?.contains("highlight")) { + anchor = anchor.parentNode; + } + if (!modifyStart && range.endOffset === 0) { + do { + while (!anchor.previousSibling) { + anchor = anchor.parentNode; + } + anchor = anchor.previousSibling; + } while (!anchor.childNodes.length); + } + const parentTextLayer = anchor.parentElement?.closest(".textLayer"); + const endDiv = this.#textLayers.get(parentTextLayer); + if (endDiv) { + endDiv.style.width = parentTextLayer.style.width; + endDiv.style.height = parentTextLayer.style.height; + endDiv.style.userSelect = "text"; + anchor.parentElement.insertBefore(endDiv, modifyStart ? anchor : anchor.nextSibling); + } + prevRange = range.cloneRange(); + }, { + signal + }); + } +} + +;// ./web/pdf_page_view.js + + + + + + + + + + + + + + + + + +const DEFAULT_LAYER_PROPERTIES = null; +const LAYERS_ORDER = new Map([["canvasWrapper", 0], ["textLayer", 1], ["annotationLayer", 2], ["annotationEditorLayer", 3], ["xfaLayer", 3]]); +class PDFPageView extends BasePDFPageView { + #annotationMode = AnnotationMode.ENABLE_FORMS; + #canvasWrapper = null; + #commentManager = null; + #enableAutoLinking = true; + #hasRestrictedScaling = false; + #isEditing = false; + #layerProperties = null; + #needsRestrictedScaling = false; + #originalViewport = null; + #previousRotation = null; + #scaleRoundX = 1; + #scaleRoundY = 1; + #textLayerMode = TextLayerMode.ENABLE; + #userUnit = 1; + #useThumbnailCanvas = { + directDrawing: true, + initialOptionalContent: true, + regularAnnotations: true + }; + #layers = [null, null, null, null]; + #clonedFrom = null; + constructor(options) { + super(options); + const { + container, + defaultViewport + } = options; + this.renderingId = "page" + this.id; + this.#layerProperties = options.layerProperties || DEFAULT_LAYER_PROPERTIES; + this.pdfPage = null; + this.pageLabel = null; + this.rotation = 0; + this.scale = options.scale || DEFAULT_SCALE; + this.viewport = defaultViewport; + this.pdfPageRotate = defaultViewport.rotation; + this._optionalContentConfigPromise = options.optionalContentConfigPromise || null; + this.#textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE; + this.#annotationMode = options.annotationMode ?? AnnotationMode.ENABLE_FORMS; + this.imageResourcesPath = options.imageResourcesPath || ""; + this.enableDetailCanvas = options.enableDetailCanvas ?? true; + this.maxCanvasPixels = options.maxCanvasPixels ?? AppOptions.get("maxCanvasPixels"); + this.maxCanvasDim = options.maxCanvasDim || AppOptions.get("maxCanvasDim"); + this.capCanvasAreaFactor = options.capCanvasAreaFactor ?? AppOptions.get("capCanvasAreaFactor"); + this.#enableAutoLinking = options.enableAutoLinking !== false; + this.#commentManager = options.commentManager || null; + this.#clonedFrom = options.clonedFrom || null; + this.l10n = options.l10n; + this.l10n ||= new genericl10n_GenericL10n(); + this._isStandalone = !this.renderingQueue?.hasViewer(); + this._container = container; + this._annotationCanvasMap = null; + this.annotationLayer = null; + this.annotationEditorLayer = null; + this.textLayer = null; + this.xfaLayer = null; + this.structTreeLayer = null; + this.drawLayer = null; + this.detailView = null; + const div = document.createElement("div"); + div.className = "page"; + div.setAttribute("data-page-number", this.id); + div.setAttribute("role", "region"); + div.setAttribute("data-l10n-id", "pdfjs-page-landmark"); + div.setAttribute("data-l10n-args", JSON.stringify({ + page: this.id + })); + this.div = div; + this.#setDimensions(); + container?.append(div); + if (this._isStandalone) { + container?.style.setProperty("--scale-factor", this.scale * PixelsPerInch.PDF_TO_CSS_UNITS); + if (this.pageColors?.background) { + container?.style.setProperty("--page-bg-color", this.pageColors.background); + } + const { + optionalContentConfigPromise + } = options; + if (optionalContentConfigPromise) { + optionalContentConfigPromise.then(optionalContentConfig => { + if (optionalContentConfigPromise !== this._optionalContentConfigPromise) { + return; + } + this.#useThumbnailCanvas.initialOptionalContent = optionalContentConfig.hasInitialVisibility; + }); + } + if (!options.l10n) { + this.l10n.translate(this.div); + } + } + } + clone(id) { + const clone = new PDFPageView({ + container: null, + eventBus: this.eventBus, + pagesColors: this.pageColors, + renderingQueue: this.renderingQueue, + enableOptimizedPartialRendering: this.enableOptimizedPartialRendering, + minDurationToUpdateCanvas: this.minDurationToUpdateCanvas, + defaultViewport: this.viewport, + id, + layerProperties: this.#layerProperties, + scale: this.scale, + optionalContentConfigPromise: this._optionalContentConfigPromise, + textLayerMode: this.#textLayerMode, + annotationMode: this.#annotationMode, + imageResourcesPath: this.imageResourcesPath, + enableDetailCanvas: this.enableDetailCanvas, + maxCanvasPixels: this.maxCanvasPixels, + maxCanvasDim: this.maxCanvasDim, + capCanvasAreaFactor: this.capCanvasAreaFactor, + enableAutoLinking: this.#enableAutoLinking, + commentManager: this.#commentManager, + l10n: this.l10n, + clonedFrom: this + }); + clone.setPdfPage(this.pdfPage); + return clone; + } + #addLayer(div, name) { + const pos = LAYERS_ORDER.get(name); + const oldDiv = this.#layers[pos]; + this.#layers[pos] = div; + if (oldDiv) { + oldDiv.replaceWith(div); + return; + } + for (let i = pos - 1; i >= 0; i--) { + const layer = this.#layers[i]; + if (layer) { + layer.after(div); + return; + } + } + this.div.prepend(div); + } + #setDimensions() { + const { + div, + viewport + } = this; + if (viewport.userUnit !== this.#userUnit) { + if (viewport.userUnit !== 1) { + div.style.setProperty("--user-unit", viewport.userUnit); + } else { + div.style.removeProperty("--user-unit"); + } + this.#userUnit = viewport.userUnit; + } + if (this.pdfPage) { + if (this.#previousRotation === viewport.rotation) { + return; + } + this.#previousRotation = viewport.rotation; + } + setLayerDimensions(div, viewport, true, false); + } + updatePageNumber(newPageNumber) { + if (this.id === newPageNumber) { + return; + } + this.id = newPageNumber; + this.renderingId = `page${newPageNumber}`; + if (this.pdfPage) { + this.pdfPage.pageNumber = newPageNumber; + } + this.setPageLabel(this.pageLabel); + const { + div + } = this; + div.setAttribute("data-page-number", newPageNumber); + div.setAttribute("data-l10n-args", JSON.stringify({ + page: newPageNumber + })); + this._textHighlighter.pageIdx = newPageNumber - 1; + this.annotationEditorLayer?.updatePageIndex(newPageNumber - 1); + } + setPdfPage(pdfPage) { + if (this._isStandalone && (this.pageColors?.foreground === "CanvasText" || this.pageColors?.background === "Canvas")) { + this._container?.style.setProperty("--hcm-highlight-filter", pdfPage.filterFactory.addHighlightHCMFilter("highlight", "CanvasText", "Canvas", "HighlightText", "Highlight")); + this._container?.style.setProperty("--hcm-highlight-selected-filter", pdfPage.filterFactory.addHighlightHCMFilter("highlight_selected", "CanvasText", "Canvas", "HighlightText", "Highlight")); + } + this.pdfPage = pdfPage; + this.pdfPageRotate = pdfPage.rotate; + const totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = pdfPage.getViewport({ + scale: this.scale * PixelsPerInch.PDF_TO_CSS_UNITS, + rotation: totalRotation + }); + this.#setDimensions(); + this.reset(); + } + destroy() { + this.reset(); + this.pdfPage?.cleanup(); + } + deleteMe(isCut) { + if (isCut) { + this.div.remove(); + return; + } + this.destroy(); + this.#layerProperties.annotationEditorUIManager?.deletePage(this.id); + } + hasEditableAnnotations() { + return !!this.annotationLayer?.hasEditableAnnotations(); + } + get _textHighlighter() { + return shadow(this, "_textHighlighter", new TextHighlighter({ + pageIndex: this.id - 1, + eventBus: this.eventBus, + findController: this.#layerProperties.findController + })); + } + #dispatchLayerRendered(name, error) { + this.eventBus.dispatch(name, { + source: this, + pageNumber: this.id, + error + }); + } + async #renderAnnotationLayer() { + let error = null; + try { + await this.annotationLayer.render({ + viewport: this.viewport, + intent: "display", + structTreeLayer: this.structTreeLayer + }); + } catch (ex) { + console.error("#renderAnnotationLayer:", ex); + error = ex; + } finally { + this.#dispatchLayerRendered("annotationlayerrendered", error); + } + } + async #renderAnnotationEditorLayer() { + let error = null; + try { + await this.annotationEditorLayer.render({ + viewport: this.viewport, + intent: "display" + }); + } catch (ex) { + console.error("#renderAnnotationEditorLayer:", ex); + error = ex; + } finally { + this.#dispatchLayerRendered("annotationeditorlayerrendered", error); + } + } + async #renderDrawLayer() { + try { + await this.drawLayer.render({ + intent: "display" + }); + } catch (ex) { + console.error("#renderDrawLayer:", ex); + } + } + async #renderXfaLayer() { + let error = null; + try { + const result = await this.xfaLayer.render({ + viewport: this.viewport, + intent: "display" + }); + if (result?.textDivs && this._textHighlighter) { + this.#buildXfaTextContentItems(result.textDivs); + } + } catch (ex) { + console.error("#renderXfaLayer:", ex); + error = ex; + } finally { + if (this.xfaLayer?.div) { + this.l10n.pause(); + this.#addLayer(this.xfaLayer.div, "xfaLayer"); + this.l10n.resume(); + } + this.#dispatchLayerRendered("xfalayerrendered", error); + } + } + async #renderTextLayer() { + if (!this.textLayer) { + return; + } + let error = null; + try { + await this.textLayer.render({ + viewport: this.viewport + }); + } catch (ex) { + if (ex instanceof AbortException) { + return; + } + console.error("#renderTextLayer:", ex); + error = ex; + } + this.#dispatchLayerRendered("textlayerrendered", error); + this.#renderStructTreeLayer(); + } + async #renderStructTreeLayer() { + if (!this.textLayer) { + return; + } + const treeDom = await this.structTreeLayer?.render(); + if (treeDom) { + this.l10n.pause(); + this.structTreeLayer?.updateTextLayer(); + if (this.canvas && treeDom.parentNode !== this.canvas) { + this.canvas.append(treeDom); + } + this.l10n.resume(); + } + this.structTreeLayer?.show(); + } + async #buildXfaTextContentItems(textDivs) { + const text = await this.pdfPage.getTextContent(); + const items = []; + for (const item of text.items) { + items.push(item.str); + } + this._textHighlighter.setTextMapping(textDivs, items); + this._textHighlighter.enable(); + } + async #injectLinkAnnotations(textLayerPromise) { + let error = null; + try { + await textLayerPromise; + if (!this.annotationLayer) { + return; + } + await this.annotationLayer.injectLinkAnnotations(Autolinker.processLinks(this)); + } catch (ex) { + console.error("#injectLinkAnnotations:", ex); + error = ex; + } + } + _resetCanvas() { + super._resetCanvas(); + this.#originalViewport = null; + } + reset({ + keepAnnotationLayer = false, + keepAnnotationEditorLayer = false, + keepXfaLayer = false, + keepTextLayer = false, + keepCanvasWrapper = false, + preserveDetailViewState = false + } = {}) { + const keepPdfBugGroups = this.pdfPage?._pdfBug ?? false; + this.cancelRendering({ + keepAnnotationLayer, + keepAnnotationEditorLayer, + keepXfaLayer, + keepTextLayer + }); + this.renderingState = RenderingStates.INITIAL; + const div = this.div; + const childNodes = div.childNodes, + annotationLayerNode = keepAnnotationLayer && this.annotationLayer?.div || null, + annotationEditorLayerNode = keepAnnotationEditorLayer && this.annotationEditorLayer?.div || null, + xfaLayerNode = keepXfaLayer && this.xfaLayer?.div || null, + textLayerNode = keepTextLayer && this.textLayer?.div || null, + canvasWrapperNode = keepCanvasWrapper && this.#canvasWrapper || null; + for (let i = childNodes.length - 1; i >= 0; i--) { + const node = childNodes[i]; + switch (node) { + case annotationLayerNode: + case annotationEditorLayerNode: + case xfaLayerNode: + case textLayerNode: + case canvasWrapperNode: + continue; + } + if (keepPdfBugGroups && node.classList.contains("pdfBugGroupsLayer")) { + continue; + } + node.remove(); + const layerIndex = this.#layers.indexOf(node); + if (layerIndex >= 0) { + this.#layers[layerIndex] = null; + } + } + div.removeAttribute("data-loaded"); + if (annotationLayerNode) { + this.annotationLayer.hide(); + } + if (annotationEditorLayerNode) { + this.annotationEditorLayer.hide(); + } + if (xfaLayerNode) { + this.xfaLayer.hide(); + } + if (textLayerNode) { + this.textLayer.hide(); + } + this.structTreeLayer?.hide(); + if (!keepCanvasWrapper && this.#canvasWrapper) { + this.#canvasWrapper = null; + this._resetCanvas(); + } + if (!preserveDetailViewState) { + this.detailView?.reset({ + keepCanvas: keepCanvasWrapper + }); + if (!keepCanvasWrapper) { + this.detailView = null; + } + } + } + toggleEditingMode(isEditing) { + this.#isEditing = isEditing; + if (!this.hasEditableAnnotations()) { + return; + } + this.reset({ + keepAnnotationLayer: true, + keepAnnotationEditorLayer: true, + keepXfaLayer: true, + keepTextLayer: true, + keepCanvasWrapper: true + }); + } + updateVisibleArea(visibleArea) { + if (this.enableDetailCanvas) { + if (this.#needsRestrictedScaling && this.maxCanvasPixels > 0 && visibleArea) { + this.detailView ??= new PDFPageDetailView({ + pageView: this, + enableOptimizedPartialRendering: this.enableOptimizedPartialRendering + }); + this.detailView.update({ + visibleArea + }); + } else if (this.detailView) { + this.detailView.reset(); + this.detailView = null; + } + } + } + update({ + scale = 0, + rotation = null, + optionalContentConfigPromise = null, + drawingDelay = -1 + }) { + this.scale = scale || this.scale; + if (typeof rotation === "number") { + this.rotation = rotation; + } + if (optionalContentConfigPromise instanceof Promise) { + this._optionalContentConfigPromise = optionalContentConfigPromise; + optionalContentConfigPromise.then(optionalContentConfig => { + if (optionalContentConfigPromise !== this._optionalContentConfigPromise) { + return; + } + this.#useThumbnailCanvas.initialOptionalContent = optionalContentConfig.hasInitialVisibility; + }); + } + this.#useThumbnailCanvas.directDrawing = true; + const totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = this.viewport.clone({ + scale: this.scale * PixelsPerInch.PDF_TO_CSS_UNITS, + rotation: totalRotation + }); + this.#setDimensions(); + if (this._isStandalone) { + this._container?.style.setProperty("--scale-factor", this.viewport.scale); + } + this.#computeScale(); + if (this.canvas) { + const onlyCssZoom = this.#hasRestrictedScaling && this.#needsRestrictedScaling; + const postponeDrawing = drawingDelay >= 0 && drawingDelay < 1000; + if (postponeDrawing || onlyCssZoom) { + if (postponeDrawing && !onlyCssZoom && this.renderingState !== RenderingStates.FINISHED) { + this.cancelRendering({ + keepAnnotationLayer: true, + keepAnnotationEditorLayer: true, + keepXfaLayer: true, + keepTextLayer: true, + cancelExtraDelay: drawingDelay + }); + this.renderingState = RenderingStates.FINISHED; + this.#useThumbnailCanvas.directDrawing = false; + } + this.cssTransform({ + redrawAnnotationLayer: true, + redrawAnnotationEditorLayer: true, + redrawXfaLayer: true, + redrawTextLayer: !postponeDrawing, + hideTextLayer: postponeDrawing + }); + if (!postponeDrawing) { + this.detailView?.update({ + underlyingViewUpdated: true + }); + this.dispatchPageRendered(true, false); + } + return; + } + } + this.cssTransform({}); + this.reset({ + keepAnnotationLayer: true, + keepAnnotationEditorLayer: true, + keepXfaLayer: true, + keepTextLayer: true, + keepCanvasWrapper: true, + preserveDetailViewState: true + }); + this.detailView?.update({ + underlyingViewUpdated: true + }); + } + #computeScale() { + const { + width, + height + } = this.viewport; + const outputScale = this.outputScale = new OutputScale(); + if (this.maxCanvasPixels === 0) { + const invScale = 1 / this.scale; + outputScale.sx *= invScale; + outputScale.sy *= invScale; + this.#needsRestrictedScaling = true; + } else { + this.#needsRestrictedScaling = outputScale.limitCanvas(width, height, this.maxCanvasPixels, this.maxCanvasDim, this.capCanvasAreaFactor); + if (this.#needsRestrictedScaling && this.enableDetailCanvas) { + const factor = this.enableOptimizedPartialRendering ? 4 : 2; + outputScale.sx /= factor; + outputScale.sy /= factor; + } + } + } + cancelRendering({ + keepAnnotationLayer = false, + keepAnnotationEditorLayer = false, + keepXfaLayer = false, + keepTextLayer = false, + cancelExtraDelay = 0 + } = {}) { + super.cancelRendering({ + cancelExtraDelay + }); + if (this.textLayer && (!keepTextLayer || !this.textLayer.div)) { + this.textLayer.cancel(); + this.textLayer = null; + } + if (this.annotationLayer && (!keepAnnotationLayer || !this.annotationLayer.div)) { + this.annotationLayer.cancel(); + this.annotationLayer = null; + this._annotationCanvasMap = null; + } + if (this.structTreeLayer && !this.textLayer) { + this.structTreeLayer = null; + } + if (this.annotationEditorLayer && (!keepAnnotationEditorLayer || !this.annotationEditorLayer.div)) { + if (this.drawLayer) { + this.drawLayer.cancel(); + this.drawLayer = null; + } + this.annotationEditorLayer.cancel(); + this.annotationEditorLayer = null; + } + if (this.xfaLayer && (!keepXfaLayer || !this.xfaLayer.div)) { + this.xfaLayer.cancel(); + this.xfaLayer = null; + this._textHighlighter?.disable(); + } + } + cssTransform({ + redrawAnnotationLayer = false, + redrawAnnotationEditorLayer = false, + redrawXfaLayer = false, + redrawTextLayer = false, + hideTextLayer = false + }) { + const { + canvas + } = this; + if (!canvas) { + return; + } + const originalViewport = this.#originalViewport; + if (this.viewport !== originalViewport) { + const relativeRotation = (360 + this.viewport.rotation - originalViewport.rotation) % 360; + if (relativeRotation === 90 || relativeRotation === 270) { + const { + width, + height + } = this.viewport; + const scaleX = height / width; + const scaleY = width / height; + canvas.style.transform = `rotate(${relativeRotation}deg) scale(${scaleX},${scaleY})`; + } else { + canvas.style.transform = relativeRotation === 0 ? "" : `rotate(${relativeRotation}deg)`; + } + } + if (redrawAnnotationLayer && this.annotationLayer) { + this.#renderAnnotationLayer(); + } + if (redrawAnnotationEditorLayer && this.annotationEditorLayer) { + if (this.drawLayer) { + this.#renderDrawLayer(); + } + this.#renderAnnotationEditorLayer(); + } + if (redrawXfaLayer && this.xfaLayer) { + this.#renderXfaLayer(); + } + if (this.textLayer) { + if (hideTextLayer) { + this.textLayer.hide(); + this.structTreeLayer?.hide(); + } else if (redrawTextLayer) { + this.#renderTextLayer(); + } + } + } + get width() { + return this.viewport.width; + } + get height() { + return this.viewport.height; + } + getPagePoint(x, y) { + return this.viewport.convertToPdfPoint(x, y); + } + _ensureCanvasWrapper() { + let canvasWrapper = this.#canvasWrapper; + if (!canvasWrapper) { + canvasWrapper = this.#canvasWrapper = document.createElement("div"); + canvasWrapper.classList.add("canvasWrapper"); + this.#addLayer(canvasWrapper, "canvasWrapper"); + } + return canvasWrapper; + } + _getRenderingContext(canvas, transform, recordOperations) { + return { + canvas, + transform, + viewport: this.viewport, + annotationMode: this.#annotationMode, + optionalContentConfigPromise: this._optionalContentConfigPromise, + annotationCanvasMap: this._annotationCanvasMap, + pageColors: this.pageColors, + isEditing: this.#isEditing, + recordOperations + }; + } + async draw() { + if (this.renderingState !== RenderingStates.INITIAL) { + console.error("Must be in new state before drawing"); + this.reset(); + } + const { + div, + l10n, + pdfPage, + viewport + } = this; + if (!pdfPage) { + this.renderingState = RenderingStates.FINISHED; + throw new Error("pdfPage is not loaded"); + } + this.renderingState = RenderingStates.RUNNING; + const canvasWrapper = this._ensureCanvasWrapper(); + if (!this.textLayer && this.#textLayerMode !== TextLayerMode.DISABLE && !pdfPage.isPureXfa) { + this._accessibilityManager ||= new TextAccessibilityManager(); + this.textLayer = new TextLayerBuilder({ + pdfPage, + highlighter: this._textHighlighter, + accessibilityManager: this._accessibilityManager, + enablePermissions: this.#textLayerMode === TextLayerMode.ENABLE_PERMISSIONS, + onAppend: textLayerDiv => { + this.l10n.pause(); + this.#addLayer(textLayerDiv, "textLayer"); + this.l10n.resume(); + } + }); + } + if (!this.annotationLayer && this.#annotationMode !== AnnotationMode.DISABLE) { + const { + annotationStorage, + annotationEditorUIManager, + downloadManager, + enableComment, + enableScripting, + fieldObjectsPromise, + hasJSActionsPromise, + linkService + } = this.#layerProperties; + this._annotationCanvasMap ||= new Map(); + this.annotationLayer = new AnnotationLayerBuilder({ + pdfPage, + annotationStorage, + imageResourcesPath: this.imageResourcesPath, + renderForms: this.#annotationMode === AnnotationMode.ENABLE_FORMS, + linkService, + downloadManager, + enableComment, + enableScripting, + hasJSActionsPromise, + fieldObjectsPromise, + annotationCanvasMap: this._annotationCanvasMap, + accessibilityManager: this._accessibilityManager, + annotationEditorUIManager, + commentManager: this.#commentManager, + onAppend: annotationLayerDiv => { + this.#addLayer(annotationLayerDiv, "annotationLayer"); + } + }); + } + const { + width, + height + } = viewport; + this.#originalViewport = viewport; + const { + canvas, + prevCanvas + } = this._createCanvas(newCanvas => { + canvasWrapper.prepend(newCanvas); + }); + canvas.setAttribute("role", "presentation"); + if (!this.outputScale) { + this.#computeScale(); + } + const { + outputScale + } = this; + this.#hasRestrictedScaling = this.#needsRestrictedScaling; + const sfx = approximateFraction(outputScale.sx); + const sfy = approximateFraction(outputScale.sy); + const canvasWidth = canvas.width = floorToDivide(calcRound(width * outputScale.sx), sfx[0]); + const canvasHeight = canvas.height = floorToDivide(calcRound(height * outputScale.sy), sfy[0]); + const pageWidth = floorToDivide(calcRound(width), sfx[1]); + const pageHeight = floorToDivide(calcRound(height), sfy[1]); + outputScale.sx = canvasWidth / pageWidth; + outputScale.sy = canvasHeight / pageHeight; + if (this.#scaleRoundX !== sfx[1]) { + div.style.setProperty("--scale-round-x", `${sfx[1]}px`); + this.#scaleRoundX = sfx[1]; + } + if (this.#scaleRoundY !== sfy[1]) { + div.style.setProperty("--scale-round-y", `${sfy[1]}px`); + this.#scaleRoundY = sfy[1]; + } + const recordBBoxes = this.enableOptimizedPartialRendering && this.#hasRestrictedScaling && !this.recordedBBoxes; + const transform = outputScale.scaled ? [outputScale.sx, 0, 0, outputScale.sy, 0, 0] : null; + const resultPromise = this._drawCanvas(this._getRenderingContext(canvas, transform, recordBBoxes), () => { + prevCanvas?.remove(); + this._resetCanvas(); + }, renderTask => { + this.#useThumbnailCanvas.regularAnnotations = !renderTask.separateAnnots; + this.dispatchPageRendered(false, false); + }).then(async () => { + if (this.renderingState !== RenderingStates.FINISHED) { + return; + } + this.structTreeLayer ||= new StructTreeLayerBuilder(pdfPage, viewport.rawDims); + const textLayerPromise = this.#renderTextLayer(); + if (this.annotationLayer) { + await this.#renderAnnotationLayer(); + if (this.#enableAutoLinking && this.annotationLayer && this.textLayer) { + await this.#injectLinkAnnotations(textLayerPromise); + } + } + const { + annotationEditorUIManager + } = this.#layerProperties; + if (!annotationEditorUIManager) { + return; + } + this.drawLayer ||= new DrawLayerBuilder(); + await this.#renderDrawLayer(); + this.drawLayer.setParent(canvasWrapper); + if (this.annotationLayer || this.#annotationMode === AnnotationMode.DISABLE) { + this.annotationEditorLayer ||= new AnnotationEditorLayerBuilder({ + uiManager: annotationEditorUIManager, + pageIndex: this.id - 1, + l10n, + structTreeLayer: this.structTreeLayer, + accessibilityManager: this._accessibilityManager, + annotationLayer: this.annotationLayer?.annotationLayer, + textLayer: this.textLayer, + drawLayer: this.drawLayer.getDrawLayer(), + clonedFrom: this.#clonedFrom?.annotationEditorLayer, + onAppend: annotationEditorLayerDiv => { + this.#addLayer(annotationEditorLayerDiv, "annotationEditorLayer"); + } + }); + this.#clonedFrom = null; + this.#renderAnnotationEditorLayer(); + } + }); + if (pdfPage.isPureXfa) { + if (!this.xfaLayer) { + const { + annotationStorage, + linkService + } = this.#layerProperties; + this.xfaLayer = new XfaLayerBuilder({ + pdfPage, + annotationStorage, + linkService + }); + } + this.#renderXfaLayer(); + } + div.setAttribute("data-loaded", true); + this.dispatchPageRender(); + return resultPromise; + } + setPageLabel(label) { + this.pageLabel = typeof label === "string" ? label : null; + this.div.setAttribute("data-l10n-args", JSON.stringify({ + page: this.pageLabel ?? this.id + })); + if (this.pageLabel !== null) { + this.div.setAttribute("data-page-label", this.pageLabel); + } else { + this.div.removeAttribute("data-page-label"); + } + } + get thumbnailCanvas() { + const { + directDrawing, + initialOptionalContent, + regularAnnotations + } = this.#useThumbnailCanvas; + return directDrawing && initialOptionalContent && regularAnnotations ? this.canvas : null; + } +} + +;// ./web/pdf_viewer.js + + + + + + + +const DEFAULT_CACHE_SIZE = 10; +const PagesCountLimit = { + FORCE_SCROLL_MODE_PAGE: 10000, + FORCE_LAZY_PAGE_INIT: 5000, + PAUSE_EAGER_PAGE_INIT: 250 +}; +function isValidAnnotationEditorMode(mode) { + return Object.values(AnnotationEditorType).includes(mode) && mode !== AnnotationEditorType.DISABLE; +} +class PDFPageViewBuffer { + #buf = new Set(); + #size = 0; + constructor(size) { + this.#size = size; + } + push(view) { + const buf = this.#buf; + if (buf.has(view)) { + buf.delete(view); + } + buf.add(view); + if (buf.size > this.#size) { + this.#destroyFirstView(); + } + } + resize(newSize, idsToKeep = null) { + this.#size = newSize; + const buf = this.#buf; + if (idsToKeep) { + const ii = buf.size; + let i = 1; + for (const view of buf) { + if (idsToKeep.has(view.id)) { + buf.delete(view); + buf.add(view); + } + if (++i > ii) { + break; + } + } + } + while (buf.size > this.#size) { + this.#destroyFirstView(); + } + } + has(view) { + return this.#buf.has(view); + } + [Symbol.iterator]() { + return this.#buf.keys(); + } + #destroyFirstView() { + const firstView = this.#buf.keys().next().value; + firstView?.destroy(); + this.#buf.delete(firstView); + } +} +class PDFViewer { + #buffer = null; + #altTextManager = null; + #annotationEditorHighlightColors = null; + #annotationEditorMode = AnnotationEditorType.NONE; + #annotationEditorUIManager = null; + #annotationMode = AnnotationMode.ENABLE_FORMS; + #commentManager = null; + #containerTopLeft = null; + #editorUndoBar = null; + #enableHWA = false; + #enableHighlightFloatingButton = false; + #enablePermissions = false; + #enableUpdatedAddImage = false; + #enableNewAltTextWhenAddingImage = false; + #enableAutoLinking = true; + #eventAbortController = null; + #minDurationToUpdateCanvas = 0; + #mlManager = null; + #printingAllowed = true; + #scrollTimeoutId = null; + #switchAnnotationEditorModeAC = null; + #switchAnnotationEditorModeTimeoutId = null; + #getAllTextInProgress = false; + #hiddenCopyElement = null; + #interruptCopyCondition = false; + #previousContainerHeight = 0; + #resizeObserver = new ResizeObserver(this.#resizeObserverCallback.bind(this)); + #scrollModePageState = null; + #scaleTimeoutId = null; + #signatureManager = null; + #supportsPinchToZoom = true; + #textLayerMode = TextLayerMode.ENABLE; + #viewerAlert = null; + #copiedPageViews = null; + constructor(options) { + const viewerVersion = "5.5.207"; + if (version !== viewerVersion) { + throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`); + } + this.container = options.container; + this.viewer = options.viewer || options.container.firstElementChild; + this.#viewerAlert = options.viewerAlert || null; + if (this.container?.tagName !== "DIV" || this.viewer?.tagName !== "DIV") { + throw new Error("Invalid `container` and/or `viewer` option."); + } + if (this.container.offsetParent && getComputedStyle(this.container).position !== "absolute") { + throw new Error("The `container` must be absolutely positioned."); + } + this.#resizeObserver.observe(this.container); + this.eventBus = options.eventBus; + this.linkService = options.linkService || new SimpleLinkService(); + this.downloadManager = options.downloadManager || null; + this.findController = options.findController || null; + this.#altTextManager = options.altTextManager || null; + this.#commentManager = options.commentManager || null; + this.#signatureManager = options.signatureManager || null; + this.#editorUndoBar = options.editorUndoBar || null; + if (this.findController) { + this.findController.onIsPageVisible = pageNumber => this._getVisiblePages().ids.has(pageNumber); + } + this._scriptingManager = options.scriptingManager || null; + this.#textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE; + this.#annotationMode = options.annotationMode ?? AnnotationMode.ENABLE_FORMS; + this.#annotationEditorMode = options.annotationEditorMode ?? AnnotationEditorType.NONE; + this.#annotationEditorHighlightColors = options.annotationEditorHighlightColors || null; + this.#enableHighlightFloatingButton = options.enableHighlightFloatingButton === true; + this.#enableUpdatedAddImage = options.enableUpdatedAddImage === true; + this.#enableNewAltTextWhenAddingImage = options.enableNewAltTextWhenAddingImage === true; + this.imageResourcesPath = options.imageResourcesPath || ""; + this.enablePrintAutoRotate = options.enablePrintAutoRotate || false; + this.removePageBorders = options.removePageBorders || false; + this.maxCanvasPixels = options.maxCanvasPixels; + this.maxCanvasDim = options.maxCanvasDim; + this.capCanvasAreaFactor = options.capCanvasAreaFactor; + this.enableDetailCanvas = options.enableDetailCanvas ?? true; + this.enableOptimizedPartialRendering = options.enableOptimizedPartialRendering ?? false; + this.l10n = options.l10n; + this.l10n ||= new genericl10n_GenericL10n(); + this.#enablePermissions = options.enablePermissions || false; + this.pageColors = options.pageColors || null; + this.#mlManager = options.mlManager || null; + this.#enableHWA = options.enableHWA || false; + this.#supportsPinchToZoom = options.supportsPinchToZoom !== false; + this.#enableAutoLinking = options.enableAutoLinking !== false; + this.#minDurationToUpdateCanvas = options.minDurationToUpdateCanvas ?? 500; + this.defaultRenderingQueue = !options.renderingQueue; + if (this.defaultRenderingQueue) { + this.renderingQueue = new PDFRenderingQueue(); + this.renderingQueue.setViewer(this); + } else { + this.renderingQueue = options.renderingQueue; + } + const { + abortSignal + } = options; + abortSignal?.addEventListener("abort", () => { + this.#resizeObserver.disconnect(); + this.#resizeObserver = null; + }, { + once: true + }); + this.scroll = watchScroll(this.container, this._scrollUpdate.bind(this), abortSignal); + this.presentationModeState = PresentationModeState.UNKNOWN; + this._resetView(); + if (this.removePageBorders) { + this.viewer.classList.add("removePageBorders"); + } + this.#updateContainerHeightCss(); + this.eventBus._on("thumbnailrendered", ({ + pageNumber, + pdfPage + }) => { + const pageView = this._pages[pageNumber - 1]; + if (!this.#buffer.has(pageView)) { + pdfPage?.cleanup(); + } + }); + if (!options.l10n) { + this.l10n.translate(this.container); + } + } + get printingAllowed() { + return this.#printingAllowed; + } + get pagesCount() { + return this._pages.length; + } + getPageView(index) { + return this._pages[index]; + } + getCachedPageViews() { + return new Set(this.#buffer); + } + get pageViewsReady() { + return this._pages.every(pageView => pageView?.pdfPage); + } + get renderForms() { + return this.#annotationMode === AnnotationMode.ENABLE_FORMS; + } + get enableScripting() { + return !!this._scriptingManager; + } + get currentPageNumber() { + return this._currentPageNumber; + } + set currentPageNumber(val) { + if (!Number.isInteger(val)) { + throw new Error("Invalid page number."); + } + if (!this.pdfDocument) { + return; + } + if (!this._setCurrentPageNumber(val, true)) { + console.error(`currentPageNumber: "${val}" is not a valid page.`); + } + } + _setCurrentPageNumber(val, resetCurrentPageView = false) { + if (this._currentPageNumber === val) { + if (resetCurrentPageView) { + this.#resetCurrentPageView(); + } + return true; + } + if (!(0 < val && val <= this.pagesCount)) { + return false; + } + const previous = this._currentPageNumber; + this._currentPageNumber = val; + this.eventBus.dispatch("pagechanging", { + source: this, + pageNumber: val, + pageLabel: this._pageLabels?.[val - 1] ?? null, + previous + }); + if (resetCurrentPageView) { + this.#resetCurrentPageView(); + } + return true; + } + get currentPageLabel() { + return this._pageLabels?.[this._currentPageNumber - 1] ?? null; + } + set currentPageLabel(val) { + if (!this.pdfDocument) { + return; + } + let page = val | 0; + if (this._pageLabels) { + const i = this._pageLabels.indexOf(val); + if (i >= 0) { + page = i + 1; + } + } + if (!this._setCurrentPageNumber(page, true)) { + console.error(`currentPageLabel: "${val}" is not a valid page.`); + } + } + get currentScale() { + return this._currentScale !== UNKNOWN_SCALE ? this._currentScale : DEFAULT_SCALE; + } + set currentScale(val) { + if (isNaN(val)) { + throw new Error("Invalid numeric scale."); + } + if (!this.pdfDocument) { + return; + } + this.#setScale(val, { + noScroll: false + }); + } + get currentScaleValue() { + return this._currentScaleValue; + } + set currentScaleValue(val) { + if (!this.pdfDocument) { + return; + } + this.#setScale(val, { + noScroll: false + }); + } + get pagesRotation() { + return this._pagesRotation; + } + set pagesRotation(rotation) { + if (!isValidRotation(rotation)) { + throw new Error("Invalid pages rotation angle."); + } + if (!this.pdfDocument) { + return; + } + rotation %= 360; + if (rotation < 0) { + rotation += 360; + } + if (this._pagesRotation === rotation) { + return; + } + this._pagesRotation = rotation; + const pageNumber = this._currentPageNumber; + this.refresh(true, { + rotation + }); + if (this._currentScaleValue) { + this.#setScale(this._currentScaleValue, { + noScroll: true + }); + } + this.eventBus.dispatch("rotationchanging", { + source: this, + pagesRotation: rotation, + pageNumber + }); + if (this.defaultRenderingQueue) { + this.update(); + } + } + get firstPagePromise() { + return this.pdfDocument ? this._firstPageCapability.promise : null; + } + get onePageRendered() { + return this.pdfDocument ? this._onePageRenderedCapability.promise : null; + } + get pagesPromise() { + return this.pdfDocument ? this._pagesCapability.promise : null; + } + get _layerProperties() { + const self = this; + return shadow(this, "_layerProperties", { + get annotationEditorUIManager() { + return self.#annotationEditorUIManager; + }, + get annotationStorage() { + return self.pdfDocument?.annotationStorage; + }, + get downloadManager() { + return self.downloadManager; + }, + get enableComment() { + return !!self.#commentManager; + }, + get enableScripting() { + return !!self._scriptingManager; + }, + get fieldObjectsPromise() { + return self.pdfDocument?.getFieldObjects(); + }, + get findController() { + return self.findController; + }, + get hasJSActionsPromise() { + return self.pdfDocument?.hasJSActions(); + }, + get linkService() { + return self.linkService; + } + }); + } + #initializePermissions(permissions) { + const params = { + annotationEditorMode: this.#annotationEditorMode, + annotationMode: this.#annotationMode, + textLayerMode: this.#textLayerMode + }; + if (!permissions) { + this.#printingAllowed = true; + this.eventBus.dispatch("printingallowed", { + source: this, + isAllowed: this.#printingAllowed + }); + return params; + } + this.#printingAllowed = permissions.includes(PermissionFlag.PRINT_HIGH_QUALITY) || permissions.includes(PermissionFlag.PRINT); + this.eventBus.dispatch("printingallowed", { + source: this, + isAllowed: this.#printingAllowed + }); + if (!permissions.includes(PermissionFlag.COPY) && this.#textLayerMode === TextLayerMode.ENABLE) { + params.textLayerMode = TextLayerMode.ENABLE_PERMISSIONS; + } + if (!permissions.includes(PermissionFlag.MODIFY_CONTENTS)) { + params.annotationEditorMode = AnnotationEditorType.DISABLE; + } + if (!permissions.includes(PermissionFlag.MODIFY_ANNOTATIONS) && !permissions.includes(PermissionFlag.FILL_INTERACTIVE_FORMS) && this.#annotationMode === AnnotationMode.ENABLE_FORMS) { + params.annotationMode = AnnotationMode.ENABLE; + } + return params; + } + async #onePageRenderedOrForceFetch(signal) { + if (document.visibilityState === "hidden" || !this.container.offsetParent || this._getVisiblePages().views.length === 0) { + return; + } + const hiddenCapability = Promise.withResolvers(), + ac = new AbortController(); + document.addEventListener("visibilitychange", () => { + if (document.visibilityState === "hidden") { + hiddenCapability.resolve(); + } + }, { + signal: AbortSignal.any([signal, ac.signal]) + }); + await Promise.race([this._onePageRenderedCapability.promise, hiddenCapability.promise]); + ac.abort(); + } + async getAllText() { + const texts = []; + const buffer = []; + for (let pageNum = 1, pagesCount = this.pdfDocument.numPages; pageNum <= pagesCount; ++pageNum) { + if (this.#interruptCopyCondition) { + return null; + } + buffer.length = 0; + const page = await this.pdfDocument.getPage(pageNum); + const { + items + } = await page.getTextContent(); + for (const item of items) { + if (item.str) { + buffer.push(item.str); + } + if (item.hasEOL) { + buffer.push("\n"); + } + } + texts.push(removeNullCharacters(buffer.join(""))); + } + return texts.join("\n"); + } + #copyCallback(textLayerMode, event) { + const selection = document.getSelection(); + const { + focusNode, + anchorNode + } = selection; + if (anchorNode && focusNode && selection.containsNode(this.#hiddenCopyElement)) { + if (this.#getAllTextInProgress || textLayerMode === TextLayerMode.ENABLE_PERMISSIONS) { + stopEvent(event); + return; + } + this.#getAllTextInProgress = true; + const { + classList + } = this.viewer; + classList.add("copyAll"); + const ac = new AbortController(); + window.addEventListener("keydown", ev => this.#interruptCopyCondition = ev.key === "Escape", { + signal: ac.signal + }); + this.getAllText().then(async text => { + if (text !== null) { + await navigator.clipboard.writeText(text); + } + }).catch(reason => { + console.warn(`Something goes wrong when extracting the text: ${reason.message}`); + }).finally(() => { + this.#getAllTextInProgress = false; + this.#interruptCopyCondition = false; + ac.abort(); + classList.remove("copyAll"); + }); + stopEvent(event); + } + } + setDocument(pdfDocument) { + if (this.pdfDocument) { + this.eventBus.dispatch("pagesdestroy", { + source: this + }); + this._cancelRendering(); + this._resetView(); + this.findController?.setDocument(null); + this._scriptingManager?.setDocument(null); + this.#annotationEditorUIManager?.destroy(); + this.#annotationEditorUIManager = null; + this.#annotationEditorMode = AnnotationEditorType.NONE; + this.#printingAllowed = true; + } + this.pdfDocument = pdfDocument; + if (!pdfDocument) { + return; + } + const pagesCount = pdfDocument.numPages; + const firstPagePromise = pdfDocument.getPage(1); + const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({ + intent: "display" + }); + const permissionsPromise = this.#enablePermissions ? pdfDocument.getPermissions() : Promise.resolve(); + const { + eventBus, + pageColors, + viewer + } = this; + this.#eventAbortController = new AbortController(); + const { + signal + } = this.#eventAbortController; + if (pagesCount > PagesCountLimit.FORCE_SCROLL_MODE_PAGE) { + console.warn("Forcing PAGE-scrolling for performance reasons, given the length of the document."); + const mode = this._scrollMode = ScrollMode.PAGE; + eventBus.dispatch("scrollmodechanged", { + source: this, + mode + }); + } + this._pagesCapability.promise.then(() => { + eventBus.dispatch("pagesloaded", { + source: this, + pagesCount + }); + }, () => {}); + const onBeforeDraw = evt => { + const pageView = this._pages[evt.pageNumber - 1]; + if (!pageView) { + return; + } + this.#buffer.push(pageView); + }; + eventBus._on("pagerender", onBeforeDraw, { + signal + }); + const onAfterDraw = evt => { + if (evt.cssTransform || evt.isDetailView) { + return; + } + this._onePageRenderedCapability.resolve({ + timestamp: evt.timestamp + }); + eventBus._off("pagerendered", onAfterDraw); + }; + eventBus._on("pagerendered", onAfterDraw, { + signal + }); + Promise.all([firstPagePromise, permissionsPromise]).then(([firstPdfPage, permissions]) => { + if (pdfDocument !== this.pdfDocument) { + return; + } + this._firstPageCapability.resolve(firstPdfPage); + this._optionalContentConfigPromise = optionalContentConfigPromise; + const { + annotationEditorMode, + annotationMode, + textLayerMode + } = this.#initializePermissions(permissions); + if (textLayerMode !== TextLayerMode.DISABLE) { + const element = this.#hiddenCopyElement = document.createElement("div"); + element.id = "hiddenCopyElement"; + viewer.before(element); + } + if (annotationEditorMode !== AnnotationEditorType.DISABLE) { + const mode = annotationEditorMode; + if (pdfDocument.isPureXfa) { + console.warn("Warning: XFA-editing is not implemented."); + } else if (isValidAnnotationEditorMode(mode)) { + this.#annotationEditorUIManager = new AnnotationEditorUIManager(this.container, viewer, this.#viewerAlert, this.#altTextManager, this.#commentManager, this.#signatureManager, eventBus, pdfDocument, pageColors, this.#annotationEditorHighlightColors, this.#enableHighlightFloatingButton, this.#enableUpdatedAddImage, this.#enableNewAltTextWhenAddingImage, this.#mlManager, this.#editorUndoBar, this.#supportsPinchToZoom); + eventBus.dispatch("annotationeditoruimanager", { + source: this, + uiManager: this.#annotationEditorUIManager + }); + if (mode !== AnnotationEditorType.NONE) { + this.#preloadEditingData(mode); + this.#annotationEditorUIManager.updateMode(mode); + } + } else { + console.error(`Invalid AnnotationEditor mode: ${mode}`); + } + } + const viewerElement = this._scrollMode === ScrollMode.PAGE ? null : viewer; + const scale = this.currentScale; + const viewport = firstPdfPage.getViewport({ + scale: scale * PixelsPerInch.PDF_TO_CSS_UNITS + }); + viewer.style.setProperty("--scale-factor", viewport.scale); + if (pageColors?.background) { + viewer.style.setProperty("--page-bg-color", pageColors.background); + } + if (pageColors?.foreground === "CanvasText" || pageColors?.background === "Canvas") { + viewer.style.setProperty("--hcm-highlight-filter", pdfDocument.filterFactory.addHighlightHCMFilter("highlight", "CanvasText", "Canvas", "HighlightText", "Highlight")); + viewer.style.setProperty("--hcm-highlight-selected-filter", pdfDocument.filterFactory.addHighlightHCMFilter("highlight_selected", "CanvasText", "Canvas", "HighlightText", "ButtonText")); + } + for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) { + const pageView = new PDFPageView({ + container: viewerElement, + eventBus, + id: pageNum, + scale, + defaultViewport: viewport.clone(), + optionalContentConfigPromise, + renderingQueue: this.renderingQueue, + textLayerMode, + annotationMode, + imageResourcesPath: this.imageResourcesPath, + maxCanvasPixels: this.maxCanvasPixels, + maxCanvasDim: this.maxCanvasDim, + capCanvasAreaFactor: this.capCanvasAreaFactor, + enableDetailCanvas: this.enableDetailCanvas, + enableOptimizedPartialRendering: this.enableOptimizedPartialRendering, + pageColors, + l10n: this.l10n, + layerProperties: this._layerProperties, + enableHWA: this.#enableHWA, + enableAutoLinking: this.#enableAutoLinking, + minDurationToUpdateCanvas: this.#minDurationToUpdateCanvas, + commentManager: this.#commentManager + }); + this._pages.push(pageView); + } + this._pages[0]?.setPdfPage(firstPdfPage); + if (this._scrollMode === ScrollMode.PAGE) { + this.#ensurePageViewVisible(); + } else if (this._spreadMode !== SpreadMode.NONE) { + this._updateSpreadMode(); + } + eventBus._on("annotationeditorlayerrendered", evt => { + if (this.#annotationEditorUIManager) { + eventBus.dispatch("annotationeditormodechanged", { + source: this, + mode: this.#annotationEditorMode + }); + } + }, { + once: true, + signal + }); + this.#onePageRenderedOrForceFetch(signal).then(async () => { + if (pdfDocument !== this.pdfDocument) { + return; + } + this.findController?.setDocument(pdfDocument); + this._scriptingManager?.setDocument(pdfDocument); + if (this.#hiddenCopyElement) { + document.addEventListener("copy", this.#copyCallback.bind(this, textLayerMode), { + signal + }); + } + if (pdfDocument.loadingParams.disableAutoFetch || pagesCount > PagesCountLimit.FORCE_LAZY_PAGE_INIT) { + this._pagesCapability.resolve(); + return; + } + let getPagesLeft = pagesCount - 1; + if (getPagesLeft <= 0) { + this._pagesCapability.resolve(); + return; + } + for (let pageNum = 2; pageNum <= pagesCount; ++pageNum) { + const promise = pdfDocument.getPage(pageNum).then(pdfPage => { + const pageView = this._pages[pageNum - 1]; + if (!pageView.pdfPage) { + pageView.setPdfPage(pdfPage); + } + if (--getPagesLeft === 0) { + this._pagesCapability.resolve(); + } + }, reason => { + console.error(`Unable to get page ${pageNum} to initialize viewer`, reason); + if (--getPagesLeft === 0) { + this._pagesCapability.resolve(); + } + }); + if (pageNum % PagesCountLimit.PAUSE_EAGER_PAGE_INIT === 0) { + await promise; + } + } + }); + eventBus.dispatch("pagesinit", { + source: this + }); + pdfDocument.getMetadata().then(({ + info + }) => { + if (pdfDocument !== this.pdfDocument) { + return; + } + if (info.Language) { + viewer.lang = info.Language; + } + }); + if (this.defaultRenderingQueue) { + this.update(); + } + }).catch(reason => { + console.error("Unable to initialize viewer", reason); + this._pagesCapability.reject(reason); + }); + } + onPagesEdited({ + pagesMapper, + type, + hasBeenCut, + pageNumbers + }) { + if (type === "copy") { + this.#copiedPageViews = new Map(); + for (const pageNum of pageNumbers) { + this.#copiedPageViews.set(pageNum, this._pages[pageNum - 1]); + } + return; + } + const isCut = type === "cut"; + if (isCut || type === "delete") { + for (const pageNum of pageNumbers) { + this._pages[pageNum - 1].deleteMe(isCut); + } + } + this._currentPageNumber = 0; + const prevPages = this._pages; + const newPages = this._pages = []; + for (let i = 1, ii = pagesMapper.pagesNumber; i <= ii; i++) { + const prevPageNumber = pagesMapper.getPrevPageNumber(i); + if (prevPageNumber < 0) { + let page = this.#copiedPageViews.get(-prevPageNumber); + if (hasBeenCut) { + page.updatePageNumber(i); + } else { + page = page.clone(i); + } + newPages.push(page); + continue; + } + const page = prevPages[prevPageNumber - 1]; + newPages.push(page); + page.updatePageNumber(i); + } + if (!isCut) { + this.#copiedPageViews = null; + } + const viewerElement = this._scrollMode === ScrollMode.PAGE ? null : this.viewer; + if (viewerElement) { + viewerElement.replaceChildren(); + const fragment = document.createDocumentFragment(); + for (let i = 0, ii = pagesMapper.pagesNumber; i < ii; i++) { + const { + div + } = newPages[i]; + div.setAttribute("data-page-number", i + 1); + fragment.append(div); + } + viewerElement.append(fragment); + } + setTimeout(() => { + this.forceRendering(); + }); + } + setPageLabels(labels) { + if (!this.pdfDocument) { + return; + } + if (!labels) { + this._pageLabels = null; + } else if (!(Array.isArray(labels) && this.pdfDocument.numPages === labels.length)) { + this._pageLabels = null; + console.error(`setPageLabels: Invalid page labels.`); + } else { + this._pageLabels = labels; + } + for (let i = 0, ii = this._pages.length; i < ii; i++) { + this._pages[i].setPageLabel(this._pageLabels?.[i] ?? null); + } + } + _resetView() { + this._pages = []; + this._currentPageNumber = 1; + this._currentScale = UNKNOWN_SCALE; + this._currentScaleValue = null; + this._pageLabels = null; + this.#buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE); + this._location = null; + this._pagesRotation = 0; + this._optionalContentConfigPromise = null; + this._firstPageCapability = Promise.withResolvers(); + this._onePageRenderedCapability = Promise.withResolvers(); + this._pagesCapability = Promise.withResolvers(); + this._scrollMode = ScrollMode.VERTICAL; + this._previousScrollMode = ScrollMode.UNKNOWN; + this._spreadMode = SpreadMode.NONE; + this.#scrollModePageState = { + previousPageNumber: 1, + scrollDown: true, + pages: [] + }; + this.#eventAbortController?.abort(); + this.#eventAbortController = null; + this.viewer.textContent = ""; + this._updateScrollMode(); + this.viewer.removeAttribute("lang"); + this.#hiddenCopyElement?.remove(); + this.#hiddenCopyElement = null; + this.#cleanupTimeouts(); + this.#cleanupSwitchAnnotationEditorMode(); + } + #ensurePageViewVisible() { + if (this._scrollMode !== ScrollMode.PAGE) { + throw new Error("#ensurePageViewVisible: Invalid scrollMode value."); + } + const pageNumber = this._currentPageNumber, + state = this.#scrollModePageState, + viewer = this.viewer; + viewer.textContent = ""; + state.pages.length = 0; + if (this._spreadMode === SpreadMode.NONE && !this.isInPresentationMode) { + const pageView = this._pages[pageNumber - 1]; + viewer.append(pageView.div); + state.pages.push(pageView); + } else { + const pageIndexSet = new Set(), + parity = this._spreadMode - 1; + if (parity === -1) { + pageIndexSet.add(pageNumber - 1); + } else if (pageNumber % 2 !== parity) { + pageIndexSet.add(pageNumber - 1); + pageIndexSet.add(pageNumber); + } else { + pageIndexSet.add(pageNumber - 2); + pageIndexSet.add(pageNumber - 1); + } + const spread = document.createElement("div"); + spread.className = "spread"; + if (this.isInPresentationMode) { + const dummyPage = document.createElement("div"); + dummyPage.className = "dummyPage"; + spread.append(dummyPage); + } + for (const i of pageIndexSet) { + const pageView = this._pages[i]; + if (!pageView) { + continue; + } + spread.append(pageView.div); + state.pages.push(pageView); + } + viewer.append(spread); + } + state.scrollDown = pageNumber >= state.previousPageNumber; + state.previousPageNumber = pageNumber; + } + _scrollUpdate() { + if (this.pagesCount === 0) { + return; + } + if (this.#scrollTimeoutId) { + clearTimeout(this.#scrollTimeoutId); + } + this.#scrollTimeoutId = setTimeout(() => { + this.#scrollTimeoutId = null; + this.update(); + }, 100); + this.update(); + } + #scrollIntoView(pageView, pageSpot = null) { + const { + div, + id + } = pageView; + if (this._currentPageNumber !== id) { + this._setCurrentPageNumber(id); + } + if (this._scrollMode === ScrollMode.PAGE) { + this.#ensurePageViewVisible(); + this.update(); + } + if (!pageSpot && !this.isInPresentationMode) { + const left = div.offsetLeft + div.clientLeft, + right = left + div.clientWidth; + const { + scrollLeft, + clientWidth + } = this.container; + if (this._scrollMode === ScrollMode.HORIZONTAL || left < scrollLeft || right > scrollLeft + clientWidth) { + pageSpot = { + left: 0, + top: 0 + }; + } + } + scrollIntoView(div, pageSpot); + if (!this._currentScaleValue && this._location) { + this._location = null; + } + } + #isSameScale(newScale) { + return newScale === this._currentScale || Math.abs(newScale - this._currentScale) < 1e-15; + } + #setScaleUpdatePages(newScale, newValue, { + noScroll = false, + preset = false, + drawingDelay = -1, + origin = null + }) { + this._currentScaleValue = newValue.toString(); + if (this.#isSameScale(newScale)) { + if (preset) { + this.eventBus.dispatch("scalechanging", { + source: this, + scale: newScale, + presetValue: newValue + }); + } + return; + } + this.viewer.style.setProperty("--scale-factor", newScale * PixelsPerInch.PDF_TO_CSS_UNITS); + const postponeDrawing = drawingDelay >= 0 && drawingDelay < 1000; + this.refresh(true, { + scale: newScale, + drawingDelay: postponeDrawing ? drawingDelay : -1 + }); + if (postponeDrawing) { + this.#scaleTimeoutId = setTimeout(() => { + this.#scaleTimeoutId = null; + this.refresh(); + }, drawingDelay); + } + const previousScale = this._currentScale; + this._currentScale = newScale; + if (!noScroll) { + let page = this._currentPageNumber, + dest; + if (this._location && !(this.isInPresentationMode || this.isChangingPresentationMode)) { + page = this._location.pageNumber; + dest = [null, { + name: "XYZ" + }, this._location.left, this._location.top, null]; + } + this.scrollPageIntoView({ + pageNumber: page, + destArray: dest, + allowNegativeOffset: true + }); + if (Array.isArray(origin)) { + const scaleDiff = newScale / previousScale - 1; + const [top, left] = this.containerTopLeft; + this.container.scrollLeft += (origin[0] - left) * scaleDiff; + this.container.scrollTop += (origin[1] - top) * scaleDiff; + } + } + this.eventBus.dispatch("scalechanging", { + source: this, + scale: newScale, + presetValue: preset ? newValue : undefined + }); + if (this.defaultRenderingQueue) { + this.update(); + } + } + get #pageWidthScaleFactor() { + if (this._spreadMode !== SpreadMode.NONE && this._scrollMode !== ScrollMode.HORIZONTAL) { + return 2; + } + return 1; + } + #setScale(value, options) { + let scale = parseFloat(value); + if (scale > 0) { + options.preset = false; + this.#setScaleUpdatePages(scale, value, options); + } else { + const currentPage = this._pages[this._currentPageNumber - 1]; + if (!currentPage) { + return; + } + let hPadding = SCROLLBAR_PADDING, + vPadding = VERTICAL_PADDING; + if (this.isInPresentationMode) { + hPadding = vPadding = 4; + if (this._spreadMode !== SpreadMode.NONE) { + hPadding *= 2; + } + } else if (this.removePageBorders) { + hPadding = vPadding = 0; + } else if (this._scrollMode === ScrollMode.HORIZONTAL) { + [hPadding, vPadding] = [vPadding, hPadding]; + } + const pageWidthScale = (this.container.clientWidth - hPadding) / currentPage.width * currentPage.scale / this.#pageWidthScaleFactor; + const pageHeightScale = (this.container.clientHeight - vPadding) / currentPage.height * currentPage.scale; + switch (value) { + case "page-actual": + scale = 1; + break; + case "page-width": + scale = pageWidthScale; + break; + case "page-height": + scale = pageHeightScale; + break; + case "page-fit": + scale = Math.min(pageWidthScale, pageHeightScale); + break; + case "auto": + const horizontalScale = isPortraitOrientation(currentPage) ? pageWidthScale : Math.min(pageHeightScale, pageWidthScale); + scale = Math.min(MAX_AUTO_SCALE, horizontalScale); + break; + default: + console.error(`#setScale: "${value}" is an unknown zoom value.`); + return; + } + options.preset = true; + this.#setScaleUpdatePages(scale, value, options); + } + } + #resetCurrentPageView() { + const pageView = this._pages[this._currentPageNumber - 1]; + if (this.isInPresentationMode) { + this.#setScale(this._currentScaleValue, { + noScroll: true + }); + } + this.#scrollIntoView(pageView); + } + pageLabelToPageNumber(label) { + if (!this._pageLabels) { + return null; + } + const i = this._pageLabels.indexOf(label); + if (i < 0) { + return null; + } + return i + 1; + } + scrollPageIntoView({ + pageNumber, + destArray = null, + allowNegativeOffset = false, + ignoreDestinationZoom = false, + center = null + }) { + if (!this.pdfDocument) { + return; + } + const pageView = Number.isInteger(pageNumber) && this._pages[pageNumber - 1]; + if (!pageView) { + console.error(`scrollPageIntoView: "${pageNumber}" is not a valid pageNumber parameter.`); + return; + } + if (this.isInPresentationMode || !destArray) { + this._setCurrentPageNumber(pageNumber, true); + return; + } + let x = 0, + y = 0; + let width = 0, + height = 0, + widthScale, + heightScale; + const changeOrientation = pageView.rotation % 180 !== 0; + const pageWidth = (changeOrientation ? pageView.height : pageView.width) / pageView.scale / PixelsPerInch.PDF_TO_CSS_UNITS; + const pageHeight = (changeOrientation ? pageView.width : pageView.height) / pageView.scale / PixelsPerInch.PDF_TO_CSS_UNITS; + let scale = 0; + switch (destArray[1].name) { + case "XYZ": + x = destArray[2]; + y = destArray[3]; + scale = destArray[4]; + x = x !== null ? x : 0; + y = y !== null ? y : pageHeight; + break; + case "Fit": + case "FitB": + scale = "page-fit"; + break; + case "FitH": + case "FitBH": + y = destArray[2]; + scale = "page-width"; + if (y === null && this._location) { + x = this._location.left; + y = this._location.top; + } else if (typeof y !== "number" || y < 0) { + y = pageHeight; + } + break; + case "FitV": + case "FitBV": + x = destArray[2]; + width = pageWidth; + height = pageHeight; + scale = "page-height"; + break; + case "FitR": + x = destArray[2]; + y = destArray[3]; + width = destArray[4] - x; + height = destArray[5] - y; + let hPadding = SCROLLBAR_PADDING, + vPadding = VERTICAL_PADDING; + if (this.removePageBorders) { + hPadding = vPadding = 0; + } + widthScale = (this.container.clientWidth - hPadding) / width / PixelsPerInch.PDF_TO_CSS_UNITS; + heightScale = (this.container.clientHeight - vPadding) / height / PixelsPerInch.PDF_TO_CSS_UNITS; + scale = Math.min(Math.abs(widthScale), Math.abs(heightScale)); + break; + default: + console.error(`scrollPageIntoView: "${destArray[1].name}" is not a valid destination type.`); + return; + } + if (!ignoreDestinationZoom) { + if (scale && scale !== this._currentScale) { + this.currentScaleValue = scale; + } else if (this._currentScale === UNKNOWN_SCALE) { + this.currentScaleValue = DEFAULT_SCALE_VALUE; + } + } + if (scale === "page-fit" && !destArray[4]) { + this.#scrollIntoView(pageView); + return; + } + const boundingRect = [pageView.viewport.convertToViewportPoint(x, y), pageView.viewport.convertToViewportPoint(x + width, y + height)]; + let left = Math.min(boundingRect[0][0], boundingRect[1][0]); + let top = Math.min(boundingRect[0][1], boundingRect[1][1]); + if (center) { + if (center === "both" || center === "vertical") { + top -= (this.container.clientHeight - Math.abs(boundingRect[1][1] - boundingRect[0][1])) / 2; + } + if (center === "both" || center === "horizontal") { + left -= (this.container.clientWidth - Math.abs(boundingRect[1][0] - boundingRect[0][0])) / 2; + } + } else if (!allowNegativeOffset) { + left = Math.max(left, 0); + top = Math.max(top, 0); + } + this.#scrollIntoView(pageView, { + left, + top + }); + } + _updateLocation(firstPage) { + const currentScale = this._currentScale; + const currentScaleValue = this._currentScaleValue; + const normalizedScaleValue = parseFloat(currentScaleValue) === currentScale ? Math.round(currentScale * 10000) / 100 : currentScaleValue; + const pageNumber = firstPage.id; + const currentPageView = this._pages[pageNumber - 1]; + const container = this.container; + const topLeft = currentPageView.getPagePoint(container.scrollLeft - firstPage.x, container.scrollTop - firstPage.y); + const intLeft = Math.round(topLeft[0]); + const intTop = Math.round(topLeft[1]); + let pdfOpenParams = `#page=${pageNumber}`; + if (!this.isInPresentationMode) { + pdfOpenParams += `&zoom=${normalizedScaleValue},${intLeft},${intTop}`; + } + this._location = { + pageNumber, + scale: normalizedScaleValue, + top: intTop, + left: intLeft, + rotation: this._pagesRotation, + pdfOpenParams + }; + } + update() { + const visible = this._getVisiblePages(); + const visiblePages = visible.views, + numVisiblePages = visiblePages.length; + if (numVisiblePages === 0) { + return; + } + const newCacheSize = Math.max(DEFAULT_CACHE_SIZE, 2 * numVisiblePages + 1); + this.#buffer.resize(newCacheSize, visible.ids); + for (const { + view, + visibleArea + } of visiblePages) { + view.updateVisibleArea(visibleArea); + } + for (const view of this.#buffer) { + if (!visible.ids.has(view.id)) { + view.updateVisibleArea(null); + } + } + this.renderingQueue.renderHighestPriority(visible); + const isSimpleLayout = this._spreadMode === SpreadMode.NONE && (this._scrollMode === ScrollMode.PAGE || this._scrollMode === ScrollMode.VERTICAL); + const currentPageNumber = this._currentPageNumber; + let stillFullyVisible = false; + for (const page of visiblePages) { + if (page.percent < 100) { + break; + } + if (page.id === currentPageNumber && isSimpleLayout) { + stillFullyVisible = true; + break; + } + } + this._setCurrentPageNumber(stillFullyVisible ? this._currentPageNumber : visiblePages[0].id); + this._updateLocation(visible.first); + this.eventBus.dispatch("updateviewarea", { + source: this, + location: this._location + }); + } + #switchToEditAnnotationMode() { + const visible = this._getVisiblePages(); + const pagesToRefresh = []; + const { + ids, + views + } = visible; + for (const page of views) { + const { + view + } = page; + if (!view.hasEditableAnnotations()) { + ids.delete(view.id); + continue; + } + pagesToRefresh.push(page); + } + if (pagesToRefresh.length === 0) { + return null; + } + this.renderingQueue.renderHighestPriority({ + first: pagesToRefresh[0], + last: pagesToRefresh.at(-1), + views: pagesToRefresh, + ids + }); + return ids; + } + containsElement(element) { + return this.container.contains(element); + } + focus() { + this.container.focus(); + } + get _isContainerRtl() { + return getComputedStyle(this.container).direction === "rtl"; + } + get isInPresentationMode() { + return this.presentationModeState === PresentationModeState.FULLSCREEN; + } + get isChangingPresentationMode() { + return this.presentationModeState === PresentationModeState.CHANGING; + } + get isHorizontalScrollbarEnabled() { + return this.isInPresentationMode ? false : this.container.scrollWidth > this.container.clientWidth; + } + get isVerticalScrollbarEnabled() { + return this.isInPresentationMode ? false : this.container.scrollHeight > this.container.clientHeight; + } + _getVisiblePages() { + const views = this._scrollMode === ScrollMode.PAGE ? this.#scrollModePageState.pages : this._pages, + horizontal = this._scrollMode === ScrollMode.HORIZONTAL, + rtl = horizontal && this._isContainerRtl; + return getVisibleElements({ + scrollEl: this.container, + views, + sortByVisibility: true, + horizontal, + rtl + }); + } + cleanup() { + for (const pageView of this._pages) { + if (pageView.renderingState !== RenderingStates.FINISHED) { + pageView.reset(); + } + } + } + _cancelRendering() { + for (const pageView of this._pages) { + pageView.cancelRendering(); + } + } + async #ensurePdfPageLoaded(pageView) { + if (pageView.pdfPage) { + return pageView.pdfPage; + } + try { + const pdfPage = await this.pdfDocument.getPage(pageView.id); + if (!pageView.pdfPage) { + pageView.setPdfPage(pdfPage); + } + return pdfPage; + } catch (reason) { + console.error("Unable to get page for page view", reason); + return null; + } + } + #getScrollAhead(visible) { + if (visible.first?.id === 1) { + return true; + } else if (visible.last?.id === this.pagesCount) { + return false; + } + switch (this._scrollMode) { + case ScrollMode.PAGE: + return this.#scrollModePageState.scrollDown; + case ScrollMode.HORIZONTAL: + return this.scroll.right; + } + return this.scroll.down; + } + forceRendering(currentlyVisiblePages) { + const visiblePages = currentlyVisiblePages || this._getVisiblePages(); + const scrollAhead = this.#getScrollAhead(visiblePages); + const preRenderExtra = this._spreadMode !== SpreadMode.NONE && this._scrollMode !== ScrollMode.HORIZONTAL; + const ignoreDetailViews = this.#scaleTimeoutId !== null || this.#scrollTimeoutId !== null && visiblePages.views.some(page => page.detailView?.renderingCancelled); + const pageView = this.renderingQueue.getHighestPriority(visiblePages, this._pages, scrollAhead, preRenderExtra, ignoreDetailViews); + if (pageView) { + this.#ensurePdfPageLoaded(pageView).then(() => { + this.renderingQueue.renderView(pageView); + }); + return true; + } + return false; + } + get hasEqualPageSizes() { + const firstPageView = this._pages[0]; + for (let i = 1, ii = this._pages.length; i < ii; ++i) { + const pageView = this._pages[i]; + if (pageView.width !== firstPageView.width || pageView.height !== firstPageView.height) { + return false; + } + } + return true; + } + getPagesOverview() { + let initialOrientation; + return this._pages.map(pageView => { + const viewport = pageView.pdfPage.getViewport({ + scale: 1 + }); + const orientation = isPortraitOrientation(viewport); + if (initialOrientation === undefined) { + initialOrientation = orientation; + } else if (this.enablePrintAutoRotate && orientation !== initialOrientation) { + return { + width: viewport.height, + height: viewport.width, + rotation: (viewport.rotation - 90) % 360 + }; + } + return { + width: viewport.width, + height: viewport.height, + rotation: viewport.rotation + }; + }); + } + get optionalContentConfigPromise() { + if (!this.pdfDocument) { + return Promise.resolve(null); + } + if (!this._optionalContentConfigPromise) { + console.error("optionalContentConfigPromise: Not initialized yet."); + return this.pdfDocument.getOptionalContentConfig({ + intent: "display" + }); + } + return this._optionalContentConfigPromise; + } + set optionalContentConfigPromise(promise) { + if (!(promise instanceof Promise)) { + throw new Error(`Invalid optionalContentConfigPromise: ${promise}`); + } + if (!this.pdfDocument) { + return; + } + if (!this._optionalContentConfigPromise) { + return; + } + this._optionalContentConfigPromise = promise; + this.refresh(false, { + optionalContentConfigPromise: promise + }); + this.eventBus.dispatch("optionalcontentconfigchanged", { + source: this, + promise + }); + } + get scrollMode() { + return this._scrollMode; + } + set scrollMode(mode) { + if (this._scrollMode === mode) { + return; + } + if (!isValidScrollMode(mode)) { + throw new Error(`Invalid scroll mode: ${mode}`); + } + if (this.pagesCount > PagesCountLimit.FORCE_SCROLL_MODE_PAGE) { + return; + } + this._previousScrollMode = this._scrollMode; + this._scrollMode = mode; + this.eventBus.dispatch("scrollmodechanged", { + source: this, + mode + }); + this._updateScrollMode(this._currentPageNumber); + } + _updateScrollMode(pageNumber = null) { + const scrollMode = this._scrollMode, + viewer = this.viewer; + viewer.classList.toggle("scrollHorizontal", scrollMode === ScrollMode.HORIZONTAL); + viewer.classList.toggle("scrollWrapped", scrollMode === ScrollMode.WRAPPED); + if (!this.pdfDocument || !pageNumber) { + return; + } + if (scrollMode === ScrollMode.PAGE) { + this.#ensurePageViewVisible(); + } else if (this._previousScrollMode === ScrollMode.PAGE) { + this._updateSpreadMode(); + } + if (this._currentScaleValue && isNaN(this._currentScaleValue)) { + this.#setScale(this._currentScaleValue, { + noScroll: true + }); + } + this._setCurrentPageNumber(pageNumber, true); + this.update(); + } + get spreadMode() { + return this._spreadMode; + } + set spreadMode(mode) { + if (this._spreadMode === mode) { + return; + } + if (!isValidSpreadMode(mode)) { + throw new Error(`Invalid spread mode: ${mode}`); + } + this._spreadMode = mode; + this.eventBus.dispatch("spreadmodechanged", { + source: this, + mode + }); + this._updateSpreadMode(this._currentPageNumber); + } + _updateSpreadMode(pageNumber = null) { + if (!this.pdfDocument) { + return; + } + const viewer = this.viewer, + pages = this._pages; + if (this._scrollMode === ScrollMode.PAGE) { + this.#ensurePageViewVisible(); + } else { + viewer.textContent = ""; + if (this._spreadMode === SpreadMode.NONE) { + for (const pageView of this._pages) { + viewer.append(pageView.div); + } + } else { + const parity = this._spreadMode - 1; + let spread = null; + for (let i = 0, ii = pages.length; i < ii; ++i) { + if (spread === null) { + spread = document.createElement("div"); + spread.className = "spread"; + viewer.append(spread); + } else if (i % 2 === parity) { + spread = spread.cloneNode(false); + viewer.append(spread); + } + spread.append(pages[i].div); + } + } + } + if (!pageNumber) { + return; + } + if (this._currentScaleValue && isNaN(this._currentScaleValue)) { + this.#setScale(this._currentScaleValue, { + noScroll: true + }); + } + this._setCurrentPageNumber(pageNumber, true); + this.update(); + } + #getPageAdvance(currentPageNumber, previous = false) { + switch (this._scrollMode) { + case ScrollMode.WRAPPED: + { + const { + views + } = this._getVisiblePages(), + pageLayout = new Map(); + for (const { + id, + y, + percent, + widthPercent + } of views) { + if (percent === 0 || widthPercent < 100) { + continue; + } + pageLayout.getOrInsertComputed(y, makeArr).push(id); + } + for (const yArray of pageLayout.values()) { + const currentIndex = yArray.indexOf(currentPageNumber); + if (currentIndex === -1) { + continue; + } + const numPages = yArray.length; + if (numPages === 1) { + break; + } + if (previous) { + for (let i = currentIndex - 1, ii = 0; i >= ii; i--) { + const currentId = yArray[i], + expectedId = yArray[i + 1] - 1; + if (currentId < expectedId) { + return currentPageNumber - expectedId; + } + } + } else { + for (let i = currentIndex + 1, ii = numPages; i < ii; i++) { + const currentId = yArray[i], + expectedId = yArray[i - 1] + 1; + if (currentId > expectedId) { + return expectedId - currentPageNumber; + } + } + } + if (previous) { + const firstId = yArray[0]; + if (firstId < currentPageNumber) { + return currentPageNumber - firstId + 1; + } + } else { + const lastId = yArray[numPages - 1]; + if (lastId > currentPageNumber) { + return lastId - currentPageNumber + 1; + } + } + break; + } + break; + } + case ScrollMode.HORIZONTAL: + { + break; + } + case ScrollMode.PAGE: + case ScrollMode.VERTICAL: + { + if (this._spreadMode === SpreadMode.NONE) { + break; + } + const parity = this._spreadMode - 1; + if (previous && currentPageNumber % 2 !== parity) { + break; + } else if (!previous && currentPageNumber % 2 === parity) { + break; + } + const { + views + } = this._getVisiblePages(), + expectedId = previous ? currentPageNumber - 1 : currentPageNumber + 1; + for (const { + id, + percent, + widthPercent + } of views) { + if (id !== expectedId) { + continue; + } + if (percent > 0 && widthPercent === 100) { + return 2; + } + break; + } + break; + } + } + return 1; + } + nextPage() { + const currentPageNumber = this._currentPageNumber, + pagesCount = this.pagesCount; + if (currentPageNumber >= pagesCount) { + return false; + } + const advance = this.#getPageAdvance(currentPageNumber, false) || 1; + this.currentPageNumber = Math.min(currentPageNumber + advance, pagesCount); + return true; + } + previousPage() { + const currentPageNumber = this._currentPageNumber; + if (currentPageNumber <= 1) { + return false; + } + const advance = this.#getPageAdvance(currentPageNumber, true) || 1; + this.currentPageNumber = Math.max(currentPageNumber - advance, 1); + return true; + } + updateScale({ + drawingDelay, + scaleFactor = null, + steps = null, + origin + }) { + if (steps === null && scaleFactor === null) { + throw new Error("Invalid updateScale options: either `steps` or `scaleFactor` must be provided."); + } + if (!this.pdfDocument) { + return; + } + let newScale = this._currentScale; + if (scaleFactor > 0 && scaleFactor !== 1) { + newScale = Math.round(newScale * scaleFactor * 100) / 100; + } else if (steps) { + const delta = steps > 0 ? DEFAULT_SCALE_DELTA : 1 / DEFAULT_SCALE_DELTA; + const round = steps > 0 ? Math.ceil : Math.floor; + steps = Math.abs(steps); + do { + newScale = round((newScale * delta).toFixed(2) * 10) / 10; + } while (--steps > 0); + } + newScale = MathClamp(newScale, MIN_SCALE, MAX_SCALE); + this.#setScale(newScale, { + noScroll: false, + drawingDelay, + origin + }); + } + increaseScale(options = {}) { + this.updateScale({ + ...options, + steps: options.steps ?? 1 + }); + } + decreaseScale(options = {}) { + this.updateScale({ + ...options, + steps: -(options.steps ?? 1) + }); + } + #updateContainerHeightCss(height = this.container.clientHeight) { + if (height !== this.#previousContainerHeight) { + this.#previousContainerHeight = height; + docStyle.setProperty("--viewer-container-height", `${height}px`); + } + } + #resizeObserverCallback(entries) { + for (const entry of entries) { + if (entry.target === this.container) { + this.#updateContainerHeightCss(Math.floor(entry.borderBoxSize[0].blockSize)); + this.#containerTopLeft = null; + break; + } + } + } + get containerTopLeft() { + return this.#containerTopLeft ||= [this.container.offsetTop, this.container.offsetLeft]; + } + #cleanupTimeouts() { + if (this.#scaleTimeoutId !== null) { + clearTimeout(this.#scaleTimeoutId); + this.#scaleTimeoutId = null; + } + if (this.#scrollTimeoutId !== null) { + clearTimeout(this.#scrollTimeoutId); + this.#scrollTimeoutId = null; + } + } + #cleanupSwitchAnnotationEditorMode() { + this.#switchAnnotationEditorModeAC?.abort(); + this.#switchAnnotationEditorModeAC = null; + if (this.#switchAnnotationEditorModeTimeoutId !== null) { + clearTimeout(this.#switchAnnotationEditorModeTimeoutId); + this.#switchAnnotationEditorModeTimeoutId = null; + } + } + #preloadEditingData(mode) { + switch (mode) { + case AnnotationEditorType.STAMP: + this.#mlManager?.loadModel("altText"); + break; + case AnnotationEditorType.SIGNATURE: + this.#signatureManager?.loadSignatures(); + break; + } + } + get annotationEditorMode() { + return this.#annotationEditorUIManager ? this.#annotationEditorMode : AnnotationEditorType.DISABLE; + } + set annotationEditorMode({ + mode, + editId = null, + isFromKeyboard = false, + mustEnterInEditMode = false, + editComment = false + }) { + if (!this.#annotationEditorUIManager) { + throw new Error(`The AnnotationEditor is not enabled.`); + } + if (this.#annotationEditorMode === mode) { + return; + } + if (!isValidAnnotationEditorMode(mode)) { + throw new Error(`Invalid AnnotationEditor mode: ${mode}`); + } + if (!this.pdfDocument) { + return; + } + this.#preloadEditingData(mode); + const { + eventBus, + pdfDocument + } = this; + const updater = async () => { + this.#cleanupSwitchAnnotationEditorMode(); + this.#annotationEditorMode = mode; + await this.#annotationEditorUIManager.updateMode(mode, editId, true, isFromKeyboard, mustEnterInEditMode, editComment); + if (mode !== this.#annotationEditorMode || pdfDocument !== this.pdfDocument) { + return; + } + eventBus.dispatch("annotationeditormodechanged", { + source: this, + mode + }); + }; + if (mode === AnnotationEditorType.NONE || this.#annotationEditorMode === AnnotationEditorType.NONE) { + const isEditing = mode !== AnnotationEditorType.NONE; + if (!isEditing) { + this.pdfDocument.annotationStorage.resetModifiedIds(); + } + this.cleanup(); + for (const pageView of this._pages) { + pageView.toggleEditingMode(isEditing); + } + const idsToRefresh = this.#switchToEditAnnotationMode(); + if (isEditing && idsToRefresh) { + this.#cleanupSwitchAnnotationEditorMode(); + this.#switchAnnotationEditorModeAC = new AbortController(); + const signal = AbortSignal.any([this.#eventAbortController.signal, this.#switchAnnotationEditorModeAC.signal]); + eventBus._on("pagerendered", ({ + pageNumber + }) => { + idsToRefresh.delete(pageNumber); + if (idsToRefresh.size === 0) { + this.#switchAnnotationEditorModeTimeoutId = setTimeout(updater, 0); + } + }, { + signal + }); + return; + } + } + updater(); + } + refresh(noUpdate = false, updateArgs = Object.create(null)) { + if (!this.pdfDocument) { + return; + } + for (const pageView of this._pages) { + pageView.update(updateArgs); + } + this.#cleanupTimeouts(); + if (!noUpdate) { + this.update(); + } + } +} + +;// ./web/secondary_toolbar.js + + +class SecondaryToolbar { + #opts; + constructor(options, eventBus) { + this.#opts = options; + const buttons = [{ + element: options.presentationModeButton, + eventName: "presentationmode", + close: true + }, { + element: options.printButton, + eventName: "print", + close: true + }, { + element: options.downloadButton, + eventName: "download", + close: true + }, { + element: options.viewBookmarkButton, + eventName: null, + close: true + }, { + element: options.firstPageButton, + eventName: "firstpage", + close: true + }, { + element: options.lastPageButton, + eventName: "lastpage", + close: true + }, { + element: options.pageRotateCwButton, + eventName: "rotatecw", + close: false + }, { + element: options.pageRotateCcwButton, + eventName: "rotateccw", + close: false + }, { + element: options.cursorSelectToolButton, + eventName: "switchcursortool", + eventDetails: { + tool: CursorTool.SELECT + }, + close: true + }, { + element: options.cursorHandToolButton, + eventName: "switchcursortool", + eventDetails: { + tool: CursorTool.HAND + }, + close: true + }, { + element: options.scrollPageButton, + eventName: "switchscrollmode", + eventDetails: { + mode: ScrollMode.PAGE + }, + close: true + }, { + element: options.scrollVerticalButton, + eventName: "switchscrollmode", + eventDetails: { + mode: ScrollMode.VERTICAL + }, + close: true + }, { + element: options.scrollHorizontalButton, + eventName: "switchscrollmode", + eventDetails: { + mode: ScrollMode.HORIZONTAL + }, + close: true + }, { + element: options.scrollWrappedButton, + eventName: "switchscrollmode", + eventDetails: { + mode: ScrollMode.WRAPPED + }, + close: true + }, { + element: options.spreadNoneButton, + eventName: "switchspreadmode", + eventDetails: { + mode: SpreadMode.NONE + }, + close: true + }, { + element: options.spreadOddButton, + eventName: "switchspreadmode", + eventDetails: { + mode: SpreadMode.ODD + }, + close: true + }, { + element: options.spreadEvenButton, + eventName: "switchspreadmode", + eventDetails: { + mode: SpreadMode.EVEN + }, + close: true + }, { + element: options.imageAltTextSettingsButton, + eventName: "imagealttextsettings", + close: true + }, { + element: options.documentPropertiesButton, + eventName: "documentproperties", + close: true + }]; + buttons.push({ + element: options.openFileButton, + eventName: "openfile", + close: true + }); + this.eventBus = eventBus; + this.opened = false; + this.#bindListeners(buttons); + this.reset(); + } + get isOpen() { + return this.opened; + } + setPageNumber(pageNumber) { + this.pageNumber = pageNumber; + this.#updateUIState(); + } + setPagesCount(pagesCount) { + this.pagesCount = pagesCount; + this.#updateUIState(); + } + reset() { + this.pageNumber = 0; + this.pagesCount = 0; + this.#updateUIState(); + this.eventBus.dispatch("switchcursortool", { + source: this, + reset: true + }); + this.#scrollModeChanged({ + mode: ScrollMode.VERTICAL + }); + this.#spreadModeChanged({ + mode: SpreadMode.NONE + }); + } + #updateUIState() { + const { + firstPageButton, + lastPageButton, + pageRotateCwButton, + pageRotateCcwButton + } = this.#opts; + firstPageButton.disabled = this.pageNumber <= 1; + lastPageButton.disabled = this.pageNumber >= this.pagesCount; + pageRotateCwButton.disabled = this.pagesCount === 0; + pageRotateCcwButton.disabled = this.pagesCount === 0; + } + #bindListeners(buttons) { + const { + eventBus + } = this; + const { + toggleButton + } = this.#opts; + toggleButton.addEventListener("click", this.toggle.bind(this)); + for (const { + element, + eventName, + close, + eventDetails + } of buttons) { + element.addEventListener("click", evt => { + if (eventName !== null) { + eventBus.dispatch(eventName, { + source: this, + ...eventDetails + }); + } + if (close) { + this.close(); + } + eventBus.dispatch("reporttelemetry", { + source: this, + details: { + type: "buttons", + data: { + id: element.id + } + } + }); + }); + } + eventBus._on("cursortoolchanged", this.#cursorToolChanged.bind(this)); + eventBus._on("scrollmodechanged", this.#scrollModeChanged.bind(this)); + eventBus._on("spreadmodechanged", this.#spreadModeChanged.bind(this)); + } + #cursorToolChanged({ + tool, + disabled + }) { + const { + cursorSelectToolButton, + cursorHandToolButton + } = this.#opts; + toggleCheckedBtn(cursorSelectToolButton, tool === CursorTool.SELECT); + toggleCheckedBtn(cursorHandToolButton, tool === CursorTool.HAND); + cursorSelectToolButton.disabled = disabled; + cursorHandToolButton.disabled = disabled; + } + #scrollModeChanged({ + mode + }) { + const { + scrollPageButton, + scrollVerticalButton, + scrollHorizontalButton, + scrollWrappedButton, + spreadNoneButton, + spreadOddButton, + spreadEvenButton + } = this.#opts; + toggleCheckedBtn(scrollPageButton, mode === ScrollMode.PAGE); + toggleCheckedBtn(scrollVerticalButton, mode === ScrollMode.VERTICAL); + toggleCheckedBtn(scrollHorizontalButton, mode === ScrollMode.HORIZONTAL); + toggleCheckedBtn(scrollWrappedButton, mode === ScrollMode.WRAPPED); + const forceScrollModePage = this.pagesCount > PagesCountLimit.FORCE_SCROLL_MODE_PAGE; + scrollPageButton.disabled = forceScrollModePage; + scrollVerticalButton.disabled = forceScrollModePage; + scrollHorizontalButton.disabled = forceScrollModePage; + scrollWrappedButton.disabled = forceScrollModePage; + const isHorizontal = mode === ScrollMode.HORIZONTAL; + spreadNoneButton.disabled = isHorizontal; + spreadOddButton.disabled = isHorizontal; + spreadEvenButton.disabled = isHorizontal; + } + #spreadModeChanged({ + mode + }) { + const { + spreadNoneButton, + spreadOddButton, + spreadEvenButton + } = this.#opts; + toggleCheckedBtn(spreadNoneButton, mode === SpreadMode.NONE); + toggleCheckedBtn(spreadOddButton, mode === SpreadMode.ODD); + toggleCheckedBtn(spreadEvenButton, mode === SpreadMode.EVEN); + } + open() { + if (this.opened) { + return; + } + this.opened = true; + const { + toggleButton, + toolbar + } = this.#opts; + toggleExpandedBtn(toggleButton, true, toolbar); + } + close() { + if (!this.opened) { + return; + } + this.opened = false; + const { + toggleButton, + toolbar + } = this.#opts; + toggleExpandedBtn(toggleButton, false, toolbar); + } + toggle() { + if (this.opened) { + this.close(); + } else { + this.open(); + } + } +} + +;// ./web/signature_manager.js + +const DEFAULT_HEIGHT_IN_PAGE = 40; +class SignatureManager { + #addButton; + #tabsToAltText = null; + #clearButton; + #clearDescription; + #currentEditor; + #description; + #dialog; + #drawCurves = null; + #drawPlaceholder; + #drawPath = null; + #drawPathString = ""; + #drawPoints = null; + #drawSVG; + #drawThickness; + #errorBar; + #errorDescription; + #errorTitle; + #extractedSignatureData = null; + #imagePath = null; + #imagePicker; + #imagePickerLink; + #imagePlaceholder; + #imageSVG; + #saveCheckbox; + #saveContainer; + #tabButtons; + #addSignatureToolbarButton; + #loadSignaturesPromise = null; + #typeInput; + #currentTab = null; + #currentTabAC = null; + #hasDescriptionChanged = false; + #eventBus; + #isStorageFull = false; + #l10n; + #overlayManager; + #editDescriptionDialog; + #signatureStorage; + #uiManager = null; + static #l10nDescription = null; + constructor({ + dialog, + panels, + typeButton, + typeInput, + drawButton, + drawPlaceholder, + drawSVG, + drawThickness, + imageButton, + imageSVG, + imagePlaceholder, + imagePicker, + imagePickerLink, + description, + clearButton, + cancelButton, + addButton, + errorCloseButton, + errorBar, + errorTitle, + errorDescription, + saveCheckbox, + saveContainer + }, editSignatureElements, addSignatureToolbarButton, overlayManager, l10n, signatureStorage, eventBus) { + this.#addButton = addButton; + this.#clearButton = clearButton; + this.#clearDescription = description.lastElementChild; + this.#description = description.firstElementChild; + this.#dialog = dialog; + this.#drawSVG = drawSVG; + this.#drawPlaceholder = drawPlaceholder; + this.#drawThickness = drawThickness; + this.#errorBar = errorBar; + this.#errorTitle = errorTitle; + this.#errorDescription = errorDescription; + this.#imageSVG = imageSVG; + this.#imagePlaceholder = imagePlaceholder; + this.#imagePicker = imagePicker; + this.#imagePickerLink = imagePickerLink; + this.#overlayManager = overlayManager; + this.#saveCheckbox = saveCheckbox; + this.#saveContainer = saveContainer; + this.#addSignatureToolbarButton = addSignatureToolbarButton; + this.#typeInput = typeInput; + this.#l10n = l10n; + this.#signatureStorage = signatureStorage; + this.#eventBus = eventBus; + this.#editDescriptionDialog = new EditDescriptionDialog(editSignatureElements, overlayManager); + SignatureManager.#l10nDescription ||= Object.freeze({ + signature: "pdfjs-editor-add-signature-description-default-when-drawing", + errorUploadTitle: "pdfjs-editor-add-signature-image-upload-error-title", + errorUploadDescription: "pdfjs-editor-add-signature-image-upload-error-description", + errorNoDataTitle: "pdfjs-editor-add-signature-image-no-data-error-title", + errorNoDataDescription: "pdfjs-editor-add-signature-image-no-data-error-description" + }); + dialog.addEventListener("close", this.#close.bind(this)); + dialog.addEventListener("contextmenu", e => { + const { + target + } = e; + if (target !== this.#typeInput && target !== this.#description) { + e.preventDefault(); + } + }); + dialog.addEventListener("drop", e => { + stopEvent(e); + }); + cancelButton.addEventListener("click", this.#cancel.bind(this)); + addButton.addEventListener("click", this.#add.bind(this)); + clearButton.addEventListener("click", () => { + this.#reportTelemetry({ + type: "signature", + action: "pdfjs.signature.clear", + data: { + type: this.#currentTab + } + }); + this.#initTab(null); + }, { + passive: true + }); + this.#description.addEventListener("input", () => { + this.#clearDescription.disabled = this.#description.value === ""; + }, { + passive: true + }); + this.#clearDescription.addEventListener("click", () => { + this.#description.value = ""; + this.#clearDescription.disabled = true; + }, { + passive: true + }); + errorCloseButton.addEventListener("click", () => { + errorBar.hidden = true; + }, { + passive: true + }); + this.#initTabButtons(typeButton, drawButton, imageButton, panels); + imagePicker.accept = SupportedImageMimeTypes.join(","); + eventBus._on("storedsignatureschanged", this.#signaturesChanged.bind(this)); + overlayManager.register(dialog); + } + #initTabButtons(typeButton, drawButton, imageButton, panels) { + const buttons = this.#tabButtons = new Map([["type", typeButton], ["draw", drawButton], ["image", imageButton]]); + const tabCallback = e => { + for (const [name, button] of buttons) { + if (button === e.target) { + button.setAttribute("aria-selected", true); + button.setAttribute("tabindex", 0); + panels.setAttribute("data-selected", name); + this.#initTab(name); + } else { + button.setAttribute("aria-selected", false); + button.setAttribute("tabindex", -1); + } + } + }; + const buttonsArray = Array.from(buttons.values()); + for (let i = 0, ii = buttonsArray.length; i < ii; i++) { + const button = buttonsArray[i]; + button.addEventListener("click", tabCallback, { + passive: true + }); + button.addEventListener("keydown", ({ + key + }) => { + if (key !== "ArrowLeft" && key !== "ArrowRight") { + return; + } + buttonsArray[i + (key === "ArrowLeft" ? -1 : 1)]?.focus(); + }, { + passive: true + }); + } + } + #resetCommon() { + this.#hasDescriptionChanged = false; + this.#description.value = ""; + if (this.#currentTab) { + this.#tabsToAltText.get(this.#currentTab).value = ""; + } + } + #resetTab(name) { + switch (name) { + case "type": + this.#typeInput.value = ""; + break; + case "draw": + this.#drawCurves = null; + this.#drawPoints = null; + this.#drawPathString = ""; + this.#drawPath?.remove(); + this.#drawPath = null; + this.#drawPlaceholder.hidden = false; + this.#drawThickness.value = 1; + break; + case "image": + this.#imagePlaceholder.hidden = false; + this.#imagePath?.remove(); + this.#imagePath = null; + break; + } + } + #initTab(name) { + if (name && this.#currentTab === name) { + return; + } + if (this.#currentTab) { + this.#tabsToAltText.get(this.#currentTab).value = this.#description.value; + } + if (name) { + this.#currentTab = name; + } + this.#errorBar.hidden = true; + const reset = !name; + if (reset) { + this.#resetCommon(); + } else { + this.#description.value = this.#tabsToAltText.get(this.#currentTab).value; + } + this.#clearDescription.disabled = this.#description.value === ""; + this.#currentTabAC?.abort(); + this.#currentTabAC = new AbortController(); + switch (this.#currentTab) { + case "type": + this.#initTypeTab(reset); + break; + case "draw": + this.#initDrawTab(reset); + break; + case "image": + this.#initImageTab(reset); + break; + } + } + #disableButtons(value) { + if (!value || !this.#isStorageFull) { + this.#saveCheckbox.disabled = !value; + } + this.#clearButton.disabled = this.#addButton.disabled = this.#description.disabled = !value; + } + #initTypeTab(reset) { + if (reset) { + this.#resetTab("type"); + } + this.#disableButtons(this.#typeInput.value); + const { + signal + } = this.#currentTabAC; + const options = { + passive: true, + signal + }; + this.#typeInput.addEventListener("input", () => { + const { + value + } = this.#typeInput; + if (!this.#hasDescriptionChanged) { + this.#tabsToAltText.get("type").default = this.#description.value = value; + this.#clearDescription.disabled = value === ""; + } + this.#disableButtons(value); + }, options); + this.#description.addEventListener("input", () => { + this.#hasDescriptionChanged = this.#typeInput.value !== this.#description.value; + }, options); + } + #initDrawTab(reset) { + if (reset) { + this.#resetTab("draw"); + } + this.#disableButtons(this.#drawPath); + const { + signal + } = this.#currentTabAC; + const options = { + signal + }; + let currentPointerId = NaN; + const drawCallback = e => { + const { + pointerId + } = e; + if (!isNaN(currentPointerId) && currentPointerId !== pointerId) { + return; + } + currentPointerId = pointerId; + e.preventDefault(); + this.#drawSVG.setPointerCapture(pointerId); + const { + width: drawWidth, + height: drawHeight + } = this.#drawSVG.getBoundingClientRect(); + let { + offsetX, + offsetY + } = e; + offsetX = Math.round(offsetX); + offsetY = Math.round(offsetY); + if (e.target === this.#drawPlaceholder) { + this.#drawPlaceholder.hidden = true; + } + if (!this.#drawCurves) { + this.#drawCurves = { + width: drawWidth, + height: drawHeight, + thickness: parseInt(this.#drawThickness.value), + curves: [] + }; + this.#disableButtons(true); + const svgFactory = new DOMSVGFactory(); + const path = this.#drawPath = svgFactory.createElement("path"); + path.setAttribute("stroke-width", this.#drawThickness.value); + this.#drawSVG.append(path); + this.#drawSVG.addEventListener("pointerdown", drawCallback, options); + this.#drawPlaceholder.removeEventListener("pointerdown", drawCallback); + if (this.#description.value === "") { + this.#l10n.get(SignatureManager.#l10nDescription.signature).then(description => { + this.#tabsToAltText.get("draw").default = description; + this.#description.value ||= description; + this.#clearDescription.disabled = this.#description.value === ""; + }); + } + } + this.#drawPoints = [offsetX, offsetY]; + this.#drawCurves.curves.push({ + points: this.#drawPoints + }); + this.#drawPathString += `M ${offsetX} ${offsetY}`; + this.#drawPath.setAttribute("d", this.#drawPathString); + const finishDrawAC = new AbortController(); + const listenerDrawOptions = { + signal: AbortSignal.any([signal, finishDrawAC.signal]) + }; + this.#drawSVG.addEventListener("contextmenu", noContextMenu, listenerDrawOptions); + this.#drawSVG.addEventListener("pointermove", evt => { + evt.preventDefault(); + let { + offsetX: x, + offsetY: y + } = evt; + x = Math.round(x); + y = Math.round(y); + const drawPoints = this.#drawPoints; + if (x < 0 || y < 0 || x > drawWidth || y > drawHeight || x === drawPoints.at(-2) && y === drawPoints.at(-1)) { + return; + } + if (drawPoints.length >= 4) { + const [x1, y1, x2, y2] = drawPoints.slice(-4); + this.#drawPathString += `C${(x1 + 5 * x2) / 6} ${(y1 + 5 * y2) / 6} ${(5 * x2 + x) / 6} ${(5 * y2 + y) / 6} ${(x2 + x) / 2} ${(y2 + y) / 2}`; + } else { + this.#drawPathString += `L${x} ${y}`; + } + drawPoints.push(x, y); + this.#drawPath.setAttribute("d", this.#drawPathString); + }, listenerDrawOptions); + this.#drawSVG.addEventListener("pointerup", evt => { + const { + pointerId: pId + } = evt; + if (!isNaN(currentPointerId) && currentPointerId !== pId) { + return; + } + currentPointerId = NaN; + evt.preventDefault(); + this.#drawSVG.releasePointerCapture(pId); + finishDrawAC.abort(); + if (this.#drawPoints.length === 2) { + this.#drawPathString += `L${this.#drawPoints[0]} ${this.#drawPoints[1]}`; + this.#drawPath.setAttribute("d", this.#drawPathString); + } + }, listenerDrawOptions); + }; + if (this.#drawCurves) { + this.#drawSVG.addEventListener("pointerdown", drawCallback, options); + } else { + this.#drawPlaceholder.addEventListener("pointerdown", drawCallback, options); + } + this.#drawThickness.addEventListener("input", () => { + const { + value: thickness + } = this.#drawThickness; + this.#drawThickness.setAttribute("data-l10n-args", JSON.stringify({ + thickness + })); + if (!this.#drawCurves) { + return; + } + this.#drawPath.setAttribute("stroke-width", thickness); + this.#drawCurves.thickness = thickness; + }, options); + } + #showError(type) { + this.#errorTitle.setAttribute("data-l10n-id", SignatureManager.#l10nDescription[`error${type}Title`]); + this.#errorDescription.setAttribute("data-l10n-id", SignatureManager.#l10nDescription[`error${type}Description`]); + this.#errorBar.hidden = false; + } + #initImageTab(reset) { + if (reset) { + this.#resetTab("image"); + } + this.#disableButtons(this.#imagePath); + const { + signal + } = this.#currentTabAC; + const options = { + signal + }; + const passiveOptions = { + passive: true, + signal + }; + this.#imagePickerLink.addEventListener("keydown", e => { + const { + key + } = e; + if (key === "Enter" || key === " ") { + stopEvent(e); + this.#imagePicker.click(); + } + }, options); + this.#imagePicker.addEventListener("click", () => { + this.#dialog.classList.toggle("waiting", true); + }, passiveOptions); + this.#imagePicker.addEventListener("change", async () => { + const file = this.#imagePicker.files?.[0]; + if (!file || !SupportedImageMimeTypes.includes(file.type)) { + this.#showError("Upload"); + this.#dialog.classList.toggle("waiting", false); + return; + } + await this.#extractSignature(file); + }, passiveOptions); + this.#imagePicker.addEventListener("cancel", () => { + this.#dialog.classList.toggle("waiting", false); + }, passiveOptions); + this.#imagePlaceholder.addEventListener("dragover", e => { + const { + dataTransfer + } = e; + for (const { + type + } of dataTransfer.items) { + if (!SupportedImageMimeTypes.includes(type)) { + continue; + } + dataTransfer.dropEffect = dataTransfer.effectAllowed === "copy" ? "copy" : "move"; + stopEvent(e); + return; + } + dataTransfer.dropEffect = "none"; + }, options); + this.#imagePlaceholder.addEventListener("drop", e => { + const { + dataTransfer: { + files + } + } = e; + if (!files?.length) { + return; + } + for (const file of files) { + if (SupportedImageMimeTypes.includes(file.type)) { + this.#extractSignature(file); + break; + } + } + stopEvent(e); + this.#dialog.classList.toggle("waiting", true); + }, options); + } + async #extractSignature(file) { + let data; + try { + data = await this.#uiManager.imageManager.getFromFile(file); + } catch (e) { + console.error("SignatureManager.#extractSignature.", e); + } + if (!data) { + this.#showError("Upload"); + this.#dialog.classList.toggle("waiting", false); + return; + } + const lineData = this.#extractedSignatureData = this.#currentEditor.getFromImage(data.bitmap); + if (!lineData) { + this.#showError("NoData"); + this.#dialog.classList.toggle("waiting", false); + return; + } + const { + outline + } = lineData; + this.#imagePlaceholder.hidden = true; + this.#disableButtons(true); + const svgFactory = new DOMSVGFactory(); + const path = this.#imagePath = svgFactory.createElement("path"); + this.#imageSVG.setAttribute("viewBox", outline.viewBox); + this.#imageSVG.setAttribute("preserveAspectRatio", "xMidYMid meet"); + this.#imageSVG.append(path); + path.setAttribute("d", outline.toSVGPath()); + this.#tabsToAltText.get("image").default = file.name; + if (this.#description.value === "") { + this.#description.value = file.name || ""; + this.#clearDescription.disabled = this.#description.value === ""; + } + this.#dialog.classList.toggle("waiting", false); + } + #getOutlineForType() { + return this.#currentEditor.getFromText(this.#typeInput.value, window.getComputedStyle(this.#typeInput)); + } + #getOutlineForDraw() { + const { + width, + height + } = this.#drawSVG.getBoundingClientRect(); + return this.#currentEditor.getDrawnSignature(this.#drawCurves, width, height); + } + #reportTelemetry(data) { + this.#eventBus.dispatch("reporttelemetry", { + source: this, + details: { + type: "editing", + data + } + }); + } + #addToolbarButton(signatureData, uuid, description) { + const { + curves, + areContours, + thickness, + width, + height + } = signatureData; + const maxDim = Math.max(width, height); + const outlineData = SignatureExtractor.processDrawnLines({ + lines: { + curves, + thickness, + width, + height + }, + pageWidth: maxDim, + pageHeight: maxDim, + rotation: 0, + innerMargin: 0, + mustSmooth: false, + areContours + }); + if (!outlineData) { + return; + } + const { + outline + } = outlineData; + const svgFactory = new DOMSVGFactory(); + const div = document.createElement("div"); + const button = document.createElement("button"); + button.addEventListener("click", () => { + this.#eventBus.dispatch("switchannotationeditorparams", { + source: this, + type: AnnotationEditorParamsType.CREATE, + value: { + signatureData: { + lines: { + curves, + thickness, + width, + height + }, + mustSmooth: false, + areContours, + description, + uuid, + heightInPage: DEFAULT_HEIGHT_IN_PAGE + } + } + }); + }); + div.append(button); + div.classList.add("toolbarAddSignatureButtonContainer"); + const svg = svgFactory.create(1, 1, true); + button.append(svg); + const span = document.createElement("span"); + span.ariaHidden = true; + button.append(span); + button.classList.add("toolbarAddSignatureButton"); + button.type = "button"; + span.textContent = description; + button.setAttribute("data-l10n-id", "pdfjs-editor-add-saved-signature-button"); + button.setAttribute("data-l10n-args", JSON.stringify({ + description + })); + button.tabIndex = 0; + const path = svgFactory.createElement("path"); + svg.append(path); + svg.setAttribute("viewBox", outline.viewBox); + svg.setAttribute("preserveAspectRatio", "xMidYMid meet"); + if (areContours) { + path.classList.add("contours"); + } + path.setAttribute("d", outline.toSVGPath()); + const deleteButton = document.createElement("button"); + div.append(deleteButton); + deleteButton.classList.add("toolbarButton", "deleteButton"); + deleteButton.setAttribute("data-l10n-id", "pdfjs-editor-delete-signature-button1"); + deleteButton.type = "button"; + deleteButton.tabIndex = 0; + deleteButton.addEventListener("click", async () => { + if (await this.#signatureStorage.delete(uuid)) { + div.remove(); + this.#reportTelemetry({ + type: "signature", + action: "pdfjs.signature.delete_saved", + data: { + savedCount: await this.#signatureStorage.size() + } + }); + } + }); + const deleteSpan = document.createElement("span"); + deleteButton.append(deleteSpan); + deleteSpan.setAttribute("data-l10n-id", "pdfjs-editor-delete-signature-button-label1"); + this.#addSignatureToolbarButton.before(div); + } + async #signaturesChanged() { + const parent = this.#addSignatureToolbarButton.parentElement; + while (parent.firstElementChild !== this.#addSignatureToolbarButton) { + parent.firstElementChild.remove(); + } + this.#loadSignaturesPromise = null; + await this.loadSignatures(true); + } + getSignature(params) { + return this.open(params); + } + async loadSignatures(reload = false) { + if (!this.#addSignatureToolbarButton || !reload && this.#addSignatureToolbarButton.previousElementSibling || !this.#signatureStorage) { + return; + } + if (!this.#loadSignaturesPromise) { + this.#loadSignaturesPromise = this.#signatureStorage.getAll().then(async signatures => [signatures, await Promise.all(Array.from(signatures.values(), ({ + signatureData + }) => SignatureExtractor.decompressSignature(signatureData)))]); + if (!reload) { + return; + } + } + const [signatures, signaturesData] = await this.#loadSignaturesPromise; + this.#loadSignaturesPromise = null; + let i = 0; + for (const [uuid, { + description + }] of signatures) { + const data = signaturesData[i++]; + if (!data) { + continue; + } + data.curves = data.outlines.map(points => ({ + points + })); + delete data.outlines; + this.#addToolbarButton(data, uuid, description); + } + } + async renderEditButton(editor) { + const button = document.createElement("button"); + button.classList.add("altText", "editDescription"); + button.tabIndex = 0; + if (editor.description) { + button.title = editor.description; + } + const span = document.createElement("span"); + button.append(span); + span.setAttribute("data-l10n-id", "pdfjs-editor-add-signature-edit-button-label"); + button.addEventListener("click", () => { + this.#editDescriptionDialog.open(editor); + }, { + passive: true + }); + return button; + } + async open({ + uiManager, + editor + }) { + this.#tabsToAltText ||= new Map(this.#tabButtons.keys().map(name => [name, { + value: "", + default: "" + }])); + this.#uiManager = uiManager; + this.#currentEditor = editor; + this.#uiManager.removeEditListeners(); + const isStorageFull = this.#isStorageFull = await this.#signatureStorage.isFull(); + this.#saveContainer.classList.toggle("fullStorage", isStorageFull); + this.#saveCheckbox.checked = !isStorageFull; + await this.#overlayManager.open(this.#dialog); + const tabType = this.#tabButtons.get("type"); + tabType.focus(); + tabType.click(); + } + #cancel() { + this.#finish(); + } + #finish() { + this.#overlayManager.closeIfActive(this.#dialog); + } + #close() { + if (this.#currentEditor._drawId === null) { + this.#currentEditor.remove(); + } + this.#uiManager?.addEditListeners(); + this.#currentTabAC?.abort(); + this.#currentTabAC = null; + this.#uiManager = null; + this.#currentEditor = null; + this.#resetCommon(); + for (const [name] of this.#tabButtons) { + this.#resetTab(name); + } + this.#disableButtons(false); + this.#currentTab = null; + this.#tabsToAltText = null; + } + async #add() { + let data; + const type = this.#currentTab; + switch (type) { + case "type": + data = this.#getOutlineForType(); + break; + case "draw": + data = this.#getOutlineForDraw(); + break; + case "image": + data = this.#extractedSignatureData; + break; + } + let uuid = null; + const description = this.#description.value; + if (this.#saveCheckbox.checked) { + const { + newCurves, + areContours, + thickness, + width, + height + } = data; + const signatureData = await SignatureExtractor.compressSignature({ + outlines: newCurves, + areContours, + thickness, + width, + height + }); + uuid = await this.#signatureStorage.create({ + description, + signatureData + }); + if (uuid) { + this.#addToolbarButton({ + curves: newCurves.map(points => ({ + points + })), + areContours, + thickness, + width, + height + }, uuid, description); + } else { + console.warn("SignatureManager.add: cannot save the signature."); + } + } + const altText = this.#tabsToAltText.get(type); + this.#reportTelemetry({ + type: "signature", + action: "pdfjs.signature.created", + data: { + type, + saved: !!uuid, + savedCount: await this.#signatureStorage.size(), + descriptionChanged: description !== altText.default + } + }); + this.#currentEditor.addSignature(data, DEFAULT_HEIGHT_IN_PAGE, this.#description.value, uuid); + this.#finish(); + } + destroy() { + this.#uiManager = null; + this.#finish(); + } +} +class EditDescriptionDialog { + #currentEditor; + #previousDescription; + #description; + #dialog; + #overlayManager; + #signatureSVG; + #uiManager; + constructor({ + dialog, + description, + cancelButton, + updateButton, + editSignatureView + }, overlayManager) { + const descriptionInput = this.#description = description.firstElementChild; + this.#signatureSVG = editSignatureView; + this.#dialog = dialog; + this.#overlayManager = overlayManager; + dialog.addEventListener("close", this.#close.bind(this)); + dialog.addEventListener("contextmenu", e => { + if (e.target !== this.#description) { + e.preventDefault(); + } + }); + cancelButton.addEventListener("click", this.#cancel.bind(this)); + updateButton.addEventListener("click", this.#update.bind(this)); + const clearDescription = description.lastElementChild; + clearDescription.addEventListener("click", () => { + descriptionInput.value = ""; + clearDescription.disabled = true; + updateButton.disabled = this.#previousDescription === ""; + }); + descriptionInput.addEventListener("input", () => { + const { + value + } = descriptionInput; + clearDescription.disabled = value === ""; + updateButton.disabled = value === this.#previousDescription; + editSignatureView.setAttribute("aria-label", value); + }, { + passive: true + }); + overlayManager.register(dialog); + } + async open(editor) { + this.#uiManager = editor._uiManager; + this.#currentEditor = editor; + this.#previousDescription = this.#description.value = editor.description; + this.#description.dispatchEvent(new Event("input")); + this.#uiManager.removeEditListeners(); + const { + areContours, + outline + } = editor.getSignaturePreview(); + const svgFactory = new DOMSVGFactory(); + const path = svgFactory.createElement("path"); + this.#signatureSVG.append(path); + this.#signatureSVG.setAttribute("viewBox", outline.viewBox); + path.setAttribute("d", outline.toSVGPath()); + if (areContours) { + path.classList.add("contours"); + } + await this.#overlayManager.open(this.#dialog); + } + async #update() { + this.#currentEditor._reportTelemetry({ + action: "pdfjs.signature.edit_description", + data: { + hasBeenChanged: true + } + }); + this.#currentEditor.description = this.#description.value; + this.#finish(); + } + #cancel() { + this.#currentEditor._reportTelemetry({ + action: "pdfjs.signature.edit_description", + data: { + hasBeenChanged: false + } + }); + this.#finish(); + } + #finish() { + this.#overlayManager.closeIfActive(this.#dialog); + } + #close() { + this.#uiManager?.addEditListeners(); + this.#uiManager = null; + this.#currentEditor = null; + this.#signatureSVG.firstElementChild.remove(); + } +} + +;// ./web/toolbar.js + + +class Toolbar { + #colorPicker = null; + #opts; + constructor(options, eventBus, toolbarDensity = 0) { + this.#opts = options; + this.eventBus = eventBus; + const buttons = [{ + element: options.previous, + eventName: "previouspage" + }, { + element: options.next, + eventName: "nextpage" + }, { + element: options.zoomIn, + eventName: "zoomin" + }, { + element: options.zoomOut, + eventName: "zoomout" + }, { + element: options.print, + eventName: "print" + }, { + element: options.download, + eventName: "download" + }, { + element: options.editorCommentButton, + eventName: "switchannotationeditormode", + eventDetails: { + get mode() { + const { + classList + } = options.editorCommentButton; + return classList.contains("toggled") ? AnnotationEditorType.NONE : AnnotationEditorType.POPUP; + } + } + }, { + element: options.editorFreeTextButton, + eventName: "switchannotationeditormode", + eventDetails: { + get mode() { + const { + classList + } = options.editorFreeTextButton; + return classList.contains("toggled") ? AnnotationEditorType.NONE : AnnotationEditorType.FREETEXT; + } + } + }, { + element: options.editorHighlightButton, + eventName: "switchannotationeditormode", + eventDetails: { + get mode() { + const { + classList + } = options.editorHighlightButton; + return classList.contains("toggled") ? AnnotationEditorType.NONE : AnnotationEditorType.HIGHLIGHT; + } + } + }, { + element: options.editorInkButton, + eventName: "switchannotationeditormode", + eventDetails: { + get mode() { + const { + classList + } = options.editorInkButton; + return classList.contains("toggled") ? AnnotationEditorType.NONE : AnnotationEditorType.INK; + } + } + }, { + element: options.editorStampButton, + eventName: "switchannotationeditormode", + eventDetails: { + get mode() { + const { + classList + } = options.editorStampButton; + return classList.contains("toggled") ? AnnotationEditorType.NONE : AnnotationEditorType.STAMP; + } + }, + telemetry: { + type: "editing", + data: { + action: "pdfjs.image.icon_click" + } + } + }, { + element: options.editorSignatureButton, + eventName: "switchannotationeditormode", + eventDetails: { + get mode() { + const { + classList + } = options.editorSignatureButton; + return classList.contains("toggled") ? AnnotationEditorType.NONE : AnnotationEditorType.SIGNATURE; + } + } + }]; + this.#bindListeners(buttons); + this.#updateToolbarDensity({ + value: toolbarDensity + }); + this.reset(); + } + #updateToolbarDensity({ + value + }) { + let name = "normal"; + switch (value) { + case 1: + name = "compact"; + break; + case 2: + name = "touch"; + break; + } + document.documentElement.setAttribute("data-toolbar-density", name); + } + setPageNumber(pageNumber, pageLabel) { + this.pageNumber = pageNumber; + this.pageLabel = pageLabel; + this.#updateUIState(false); + } + setPagesCount(pagesCount, hasPageLabels) { + this.pagesCount = pagesCount; + this.hasPageLabels = hasPageLabels; + this.#updateUIState(true); + } + setPageScale(pageScaleValue, pageScale) { + this.pageScaleValue = (pageScaleValue || pageScale).toString(); + this.pageScale = pageScale; + this.#updateUIState(false); + } + reset() { + this.#colorPicker = null; + this.pageNumber = 0; + this.pageLabel = null; + this.hasPageLabels = false; + this.pagesCount = 0; + this.pageScaleValue = DEFAULT_SCALE_VALUE; + this.pageScale = DEFAULT_SCALE; + this.#updateUIState(true); + this.updateLoadingIndicatorState(); + this.#editorModeChanged({ + mode: AnnotationEditorType.DISABLE + }); + } + #bindListeners(buttons) { + const { + eventBus + } = this; + const { + editorHighlightColorPicker, + editorHighlightButton, + pageNumber, + scaleSelect + } = this.#opts; + const self = this; + for (const { + element, + eventName, + eventDetails, + telemetry + } of buttons) { + element.addEventListener("click", evt => { + if (eventName !== null) { + eventBus.dispatch(eventName, { + source: this, + ...eventDetails, + isFromKeyboard: evt.detail === 0 + }); + } + if (telemetry) { + eventBus.dispatch("reporttelemetry", { + source: this, + details: telemetry + }); + } + }); + } + pageNumber.addEventListener("click", function () { + this.select(); + }); + pageNumber.addEventListener("change", function () { + eventBus.dispatch("pagenumberchanged", { + source: self, + value: this.value + }); + }); + eventBus._on("pagesedited", ({ + pagesMapper + }) => { + const pagesCount = pagesMapper.pagesNumber; + if (pagesCount !== this.pagesCount) { + this.setPagesCount(pagesCount, this.hasPageLabels); + } + }); + scaleSelect.addEventListener("change", function () { + if (this.value === "custom") { + return; + } + eventBus.dispatch("scalechanged", { + source: self, + value: this.value + }); + }); + scaleSelect.addEventListener("click", function ({ + target + }) { + if (this.value === self.pageScaleValue && target.tagName.toUpperCase() === "OPTION") { + this.blur(); + } + }); + scaleSelect.oncontextmenu = noContextMenu; + eventBus._on("annotationeditormodechanged", this.#editorModeChanged.bind(this)); + eventBus._on("showannotationeditorui", ({ + mode + }) => { + switch (mode) { + case AnnotationEditorType.HIGHLIGHT: + editorHighlightButton.click(); + break; + } + }); + eventBus._on("toolbardensity", this.#updateToolbarDensity.bind(this)); + if (editorHighlightColorPicker) { + eventBus._on("annotationeditoruimanager", ({ + uiManager + }) => { + const cp = this.#colorPicker = new ColorPicker({ + uiManager + }); + uiManager.setMainHighlightColorPicker(cp); + editorHighlightColorPicker.append(cp.renderMainDropdown()); + }); + eventBus._on("mainhighlightcolorpickerupdatecolor", ({ + value + }) => { + this.#colorPicker?.updateColor(value); + }); + } + } + #editorModeChanged({ + mode + }) { + const { + editorCommentButton, + editorCommentParamsToolbar, + editorFreeTextButton, + editorFreeTextParamsToolbar, + editorHighlightButton, + editorHighlightParamsToolbar, + editorInkButton, + editorInkParamsToolbar, + editorStampButton, + editorStampParamsToolbar, + editorSignatureButton, + editorSignatureParamsToolbar + } = this.#opts; + toggleExpandedBtn(editorCommentButton, mode === AnnotationEditorType.POPUP, editorCommentParamsToolbar); + toggleExpandedBtn(editorFreeTextButton, mode === AnnotationEditorType.FREETEXT, editorFreeTextParamsToolbar); + toggleExpandedBtn(editorHighlightButton, mode === AnnotationEditorType.HIGHLIGHT, editorHighlightParamsToolbar); + toggleExpandedBtn(editorInkButton, mode === AnnotationEditorType.INK, editorInkParamsToolbar); + toggleExpandedBtn(editorStampButton, mode === AnnotationEditorType.STAMP, editorStampParamsToolbar); + toggleExpandedBtn(editorSignatureButton, mode === AnnotationEditorType.SIGNATURE, editorSignatureParamsToolbar); + editorCommentButton.disabled = editorFreeTextButton.disabled = editorHighlightButton.disabled = editorInkButton.disabled = editorStampButton.disabled = editorSignatureButton.disabled = mode === AnnotationEditorType.DISABLE; + } + #updateUIState(resetNumPages = false) { + const { + pageNumber, + pagesCount, + pageScaleValue, + pageScale + } = this; + const opts = this.#opts; + if (resetNumPages) { + if (this.hasPageLabels) { + opts.pageNumber.type = "text"; + opts.numPages.setAttribute("data-l10n-id", "pdfjs-page-of-pages"); + } else { + opts.pageNumber.type = "number"; + opts.numPages.setAttribute("data-l10n-id", "pdfjs-of-pages"); + opts.numPages.setAttribute("data-l10n-args", JSON.stringify({ + pagesCount + })); + } + opts.pageNumber.max = pagesCount; + } + if (this.hasPageLabels) { + opts.pageNumber.value = this.pageLabel; + opts.numPages.setAttribute("data-l10n-args", JSON.stringify({ + pageNumber, + pagesCount + })); + } else { + opts.pageNumber.value = pageNumber; + } + opts.previous.disabled = pageNumber <= 1; + opts.next.disabled = pageNumber >= pagesCount; + opts.zoomOut.disabled = pageScale <= MIN_SCALE; + opts.zoomIn.disabled = pageScale >= MAX_SCALE; + let predefinedValueFound = false; + for (const option of opts.scaleSelect.options) { + if (option.value !== pageScaleValue) { + option.selected = false; + continue; + } + option.selected = true; + predefinedValueFound = true; + } + if (!predefinedValueFound) { + opts.customScaleOption.selected = true; + opts.customScaleOption.setAttribute("data-l10n-args", JSON.stringify({ + scale: Math.round(pageScale * 10000) / 100 + })); + } + } + updateLoadingIndicatorState(loading = false) { + const { + pageNumber + } = this.#opts; + pageNumber.classList.toggle("loading", loading); + } +} + +;// ./web/view_history.js +const DEFAULT_VIEW_HISTORY_CACHE_SIZE = 20; +class ViewHistory { + constructor(fingerprint, cacheSize = DEFAULT_VIEW_HISTORY_CACHE_SIZE) { + this.fingerprint = fingerprint; + this.cacheSize = cacheSize; + this._initializedPromise = this._readFromStorage().then(databaseStr => { + const database = JSON.parse(databaseStr || "{}"); + let index = -1; + if (!Array.isArray(database.files)) { + database.files = []; + } else { + while (database.files.length >= this.cacheSize) { + database.files.shift(); + } + for (let i = 0, ii = database.files.length; i < ii; i++) { + const branch = database.files[i]; + if (branch.fingerprint === this.fingerprint) { + index = i; + break; + } + } + } + if (index === -1) { + index = database.files.push({ + fingerprint: this.fingerprint + }) - 1; + } + this.file = database.files[index]; + this.database = database; + }); + } + async _writeToStorage() { + const databaseStr = JSON.stringify(this.database); + localStorage.setItem("pdfjs.history", databaseStr); + } + async _readFromStorage() { + return localStorage.getItem("pdfjs.history"); + } + async set(name, val) { + await this._initializedPromise; + this.file[name] = val; + return this._writeToStorage(); + } + async setMultiple(properties) { + await this._initializedPromise; + for (const name in properties) { + this.file[name] = properties[name]; + } + return this._writeToStorage(); + } + async get(name, defaultValue) { + await this._initializedPromise; + const val = this.file[name]; + return val !== undefined ? val : defaultValue; + } + async getMultiple(properties) { + await this._initializedPromise; + const values = Object.create(null); + for (const name in properties) { + const val = this.file[name]; + values[name] = val !== undefined ? val : properties[name]; + } + return values; + } +} + +;// ./web/views_manager.js + + + +const SIDEBAR_WIDTH_VAR = "--viewsManager-width"; +const SIDEBAR_RESIZING_CLASS = "viewsManagerResizing"; +const UI_NOTIFICATION_CLASS = "pdfSidebarNotification"; +class ViewsManager extends Sidebar { + static #l10nDescription = null; + #hasAnimations = !window.matchMedia("(prefers-reduced-motion: reduce)").matches; + constructor({ + elements: { + outerContainer, + sidebarContainer, + toggleButton, + resizer, + thumbnailButton, + outlineButton, + attachmentsButton, + layersButton, + thumbnailsView, + outlinesView, + attachmentsView, + layersView, + viewsManagerAddFileButton, + viewsManagerCurrentOutlineButton, + viewsManagerSelectorButton, + viewsManagerSelectorOptions, + viewsManagerHeaderLabel, + viewsManagerStatus + }, + eventBus, + l10n + }) { + super({ + sidebar: sidebarContainer, + resizer, + toggleButton + }, l10n.getDirection() === "ltr", false); + this.isOpen = false; + this.active = SidebarView.THUMBS; + this.isInitialViewSet = false; + this.isInitialEventDispatched = false; + this.onToggled = null; + this.onUpdateThumbnails = null; + this.outerContainer = outerContainer; + this.sidebarContainer = sidebarContainer; + this.toggleButton = toggleButton; + this.resizer = resizer; + this.thumbnailButton = thumbnailButton; + this.outlineButton = outlineButton; + this.attachmentsButton = attachmentsButton; + this.layersButton = layersButton; + this.thumbnailsView = thumbnailsView; + this.outlinesView = outlinesView; + this.attachmentsView = attachmentsView; + this.layersView = layersView; + this.viewsManagerAddFileButton = viewsManagerAddFileButton; + this.viewsManagerCurrentOutlineButton = viewsManagerCurrentOutlineButton; + this.viewsManagerHeaderLabel = viewsManagerHeaderLabel; + this.viewsManagerStatus = viewsManagerStatus; + this.eventBus = eventBus; + this.menu = new Menu(viewsManagerSelectorOptions, viewsManagerSelectorButton, [thumbnailButton, outlineButton, attachmentsButton, layersButton]); + ViewsManager.#l10nDescription ||= Object.freeze({ + pagesTitle: "pdfjs-views-manager-pages-title", + outlinesTitle: "pdfjs-views-manager-outlines-title", + attachmentsTitle: "pdfjs-views-manager-attachments-title", + layersTitle: "pdfjs-views-manager-layers-title", + notificationButton: "pdfjs-toggle-views-manager-notification-button", + toggleButton: "pdfjs-toggle-views-manager-button" + }); + this.#addEventListeners(); + } + reset() { + this.isInitialViewSet = false; + this.isInitialEventDispatched = false; + this.#hideUINotification(true); + this.switchView(SidebarView.THUMBS); + this.outlineButton.disabled = this.attachmentsButton.disabled = this.layersButton.disabled = false; + this.viewsManagerCurrentOutlineButton.disabled = true; + } + get visibleView() { + return this.isOpen ? this.active : SidebarView.NONE; + } + setInitialView(view = SidebarView.NONE) { + if (this.isInitialViewSet) { + return; + } + this.isInitialViewSet = true; + if (view === SidebarView.NONE || view === SidebarView.UNKNOWN) { + this.#dispatchEvent(); + return; + } + this.switchView(view, true); + if (!this.isInitialEventDispatched) { + this.#dispatchEvent(); + } + } + switchView(view, forceOpen = false) { + const isViewChanged = view !== this.active; + let forceRendering = false; + let titleL10nId = null; + switch (view) { + case SidebarView.NONE: + if (this.isOpen) { + this.close(); + } + return; + case SidebarView.THUMBS: + titleL10nId = "pagesTitle"; + if (this.isOpen && isViewChanged) { + forceRendering = true; + } + break; + case SidebarView.OUTLINE: + titleL10nId = "outlinesTitle"; + if (this.outlineButton.disabled) { + return; + } + break; + case SidebarView.ATTACHMENTS: + titleL10nId = "attachmentsTitle"; + if (this.attachmentsButton.disabled) { + return; + } + break; + case SidebarView.LAYERS: + titleL10nId = "layersTitle"; + if (this.layersButton.disabled) { + return; + } + break; + default: + console.error(`PDFSidebar.switchView: "${view}" is not a valid view.`); + return; + } + this.viewsManagerStatus.hidden = view !== SidebarView.THUMBS; + this.viewsManagerAddFileButton.hidden = view !== SidebarView.THUMBS; + this.viewsManagerCurrentOutlineButton.hidden = view !== SidebarView.OUTLINE; + this.viewsManagerHeaderLabel.setAttribute("data-l10n-id", ViewsManager.#l10nDescription[titleL10nId] || ""); + this.active = view; + toggleSelectedBtn(this.thumbnailButton, view === SidebarView.THUMBS, this.thumbnailsView); + toggleSelectedBtn(this.outlineButton, view === SidebarView.OUTLINE, this.outlinesView); + toggleSelectedBtn(this.attachmentsButton, view === SidebarView.ATTACHMENTS, this.attachmentsView); + toggleSelectedBtn(this.layersButton, view === SidebarView.LAYERS, this.layersView); + if (forceOpen && !this.isOpen) { + this.open(); + return; + } + if (forceRendering) { + this.onUpdateThumbnails(); + this.onToggled(); + } + if (isViewChanged) { + this.#dispatchEvent(); + } + } + open() { + if (this.isOpen) { + return; + } + this.isOpen = true; + this.onResizing(this.width); + this._sidebar.hidden = false; + toggleExpandedBtn(this.toggleButton, true); + this.switchView(this.active); + if (this.#hasAnimations) { + queueMicrotask(() => { + this.outerContainer.classList.add("viewsManagerMoving", "viewsManagerOpen"); + }); + } else { + this.outerContainer.classList.add("viewsManagerOpen"); + this.eventBus.dispatch("resize", { + source: this + }); + } + if (this.active === SidebarView.THUMBS) { + this.onUpdateThumbnails(); + } + this.onToggled(); + this.#dispatchEvent(); + this.#hideUINotification(); + } + close(evt = null) { + if (!this.isOpen) { + return; + } + this.isOpen = false; + this._sidebar.hidden = true; + toggleExpandedBtn(this.toggleButton, false); + this.outerContainer.classList.add("viewsManagerMoving"); + this.outerContainer.classList.remove("viewsManagerOpen"); + this.onToggled(); + this.#dispatchEvent(); + if (evt?.detail > 0) { + this.toggleButton.blur(); + } + } + toggle(evt = null) { + super.toggle(); + if (this.isOpen) { + this.close(evt); + } else { + this.open(); + } + } + #dispatchEvent() { + if (this.isInitialViewSet) { + this.isInitialEventDispatched ||= true; + } + this.eventBus.dispatch("sidebarviewchanged", { + source: this, + view: this.visibleView + }); + } + #showUINotification() { + this.toggleButton.setAttribute("data-l10n-id", ViewsManager.#l10nDescription.notificationButton); + if (!this.isOpen) { + this.toggleButton.classList.add(UI_NOTIFICATION_CLASS); + } + } + #hideUINotification(reset = false) { + if (this.isOpen || reset) { + this.toggleButton.classList.remove(UI_NOTIFICATION_CLASS); + } + if (reset) { + this.toggleButton.setAttribute("data-l10n-id", ViewsManager.#l10nDescription.toggleButton); + } + } + #addEventListeners() { + const { + eventBus, + outerContainer + } = this; + if (this.#hasAnimations) { + this.sidebarContainer.addEventListener("transitionend", evt => { + if (evt.target === this.sidebarContainer) { + outerContainer.classList.remove("viewsManagerMoving"); + eventBus.dispatch("resize", { + source: this + }); + } + }); + } + this.thumbnailButton.addEventListener("click", () => { + this.switchView(SidebarView.THUMBS); + }); + this.outlineButton.addEventListener("click", () => { + this.switchView(SidebarView.OUTLINE); + }); + this.outlineButton.addEventListener("dblclick", () => { + eventBus.dispatch("toggleoutlinetree", { + source: this + }); + }); + this.attachmentsButton.addEventListener("click", () => { + this.switchView(SidebarView.ATTACHMENTS); + }); + this.layersButton.addEventListener("click", () => { + this.switchView(SidebarView.LAYERS); + }); + this.layersButton.addEventListener("dblclick", () => { + eventBus.dispatch("resetlayers", { + source: this + }); + }); + this.viewsManagerCurrentOutlineButton.addEventListener("click", () => { + eventBus.dispatch("currentoutlineitem", { + source: this + }); + }); + const onTreeLoaded = (count, button, view) => { + button.disabled = !count; + if (count) { + this.#showUINotification(); + } else if (this.active === view) { + this.switchView(SidebarView.THUMBS); + } + }; + eventBus._on("outlineloaded", evt => { + onTreeLoaded(evt.outlineCount, this.outlineButton, SidebarView.OUTLINE); + evt.currentOutlineItemPromise.then(enabled => { + if (!this.isInitialViewSet) { + return; + } + this.viewsManagerCurrentOutlineButton.disabled = !enabled; + }); + }); + eventBus._on("attachmentsloaded", evt => { + onTreeLoaded(evt.attachmentsCount, this.attachmentsButton, SidebarView.ATTACHMENTS); + }); + eventBus._on("layersloaded", evt => { + onTreeLoaded(evt.layersCount, this.layersButton, SidebarView.LAYERS); + }); + eventBus._on("presentationmodechanged", evt => { + if (evt.state === PresentationModeState.NORMAL && this.visibleView === SidebarView.THUMBS) { + this.onUpdateThumbnails(); + } + }); + } + onStartResizing() { + this.outerContainer.classList.add(SIDEBAR_RESIZING_CLASS); + } + onStopResizing() { + this.eventBus.dispatch("resize", { + source: this + }); + this.outerContainer.classList.remove(SIDEBAR_RESIZING_CLASS); + } + onResizing(newWidth) { + docStyle.setProperty(SIDEBAR_WIDTH_VAR, `${newWidth}px`); + } +} + +;// ./web/app.js + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +const FORCE_PAGES_LOADED_TIMEOUT = 10000; +const ViewOnLoad = { + UNKNOWN: -1, + PREVIOUS: 0, + INITIAL: 1 +}; +const PDFViewerApplication = { + initialBookmark: document.location.hash.substring(1), + _initializedCapability: { + ...Promise.withResolvers(), + settled: false + }, + appConfig: null, + pdfDocument: null, + pdfLoadingTask: null, + printService: null, + pdfViewer: null, + pdfThumbnailViewer: null, + pdfRenderingQueue: null, + pdfPresentationMode: null, + pdfDocumentProperties: null, + pdfLinkService: null, + pdfTextExtractor: null, + pdfHistory: null, + viewsManager: null, + pdfOutlineViewer: null, + pdfAttachmentViewer: null, + pdfLayerViewer: null, + pdfCursorTools: null, + pdfScriptingManager: null, + store: null, + downloadManager: null, + overlayManager: null, + preferences: new Preferences(), + toolbar: null, + secondaryToolbar: null, + eventBus: null, + l10n: null, + annotationEditorParams: null, + imageAltTextSettings: null, + isInitialViewSet: false, + isViewerEmbedded: window.parent !== window, + url: "", + baseUrl: "", + mlManager: null, + _downloadUrl: "", + _eventBusAbortController: null, + _windowAbortController: null, + _globalAbortController: new AbortController(), + documentInfo: null, + metadata: null, + _contentDispositionFilename: null, + _contentLength: null, + _saveInProgress: false, + _wheelUnusedTicks: 0, + _wheelUnusedFactor: 1, + _touchManager: null, + _touchUnusedTicks: 0, + _touchUnusedFactor: 1, + _PDFBug: null, + _hasAnnotationEditors: false, + _title: document.title, + _printAnnotationStoragePromise: null, + _isCtrlKeyDown: false, + _caretBrowsing: null, + _isScrolling: false, + editorUndoBar: null, + _printPermissionPromise: null, + async initialize(appConfig) { + this.appConfig = appConfig; + try { + await this.preferences.initializedPromise; + } catch (ex) { + console.error("initialize:", ex); + } + if (AppOptions.get("pdfBugEnabled")) { + await this._parseHashParams(); + } + let mode; + switch (AppOptions.get("viewerCssTheme")) { + case 1: + mode = "light"; + break; + case 2: + mode = "dark"; + break; + } + if (mode) { + docStyle.setProperty("color-scheme", mode); + } + this.l10n = await this.externalServices.createL10n(); + document.getElementsByTagName("html")[0].dir = this.l10n.getDirection(); + this.l10n.translate(appConfig.appContainer || document.documentElement); + if (this.isViewerEmbedded && AppOptions.get("externalLinkTarget") === LinkTarget.NONE) { + AppOptions.set("externalLinkTarget", LinkTarget.TOP); + } + await this._initializeViewerComponents(); + this.pdfTextExtractor = new PdfTextExtractor(this.externalServices); + this.bindEvents(); + this.bindWindowEvents(); + this._initializedCapability.settled = true; + this._initializedCapability.resolve(); + }, + async _parseHashParams() { + const hash = document.location.hash.substring(1); + if (!hash) { + return; + } + const { + mainContainer, + viewerContainer + } = this.appConfig, + params = parseQueryString(hash); + const loadPDFBug = async () => { + if (this._PDFBug) { + return; + } + const { + PDFBug + } = await import( + /*webpackIgnore: true*/ + /*@vite-ignore*/ + AppOptions.get("debuggerSrc")); + this._PDFBug = PDFBug; + }; + if (params.get("disableworker") === "true") { + try { + GlobalWorkerOptions.workerSrc ||= AppOptions.get("workerSrc"); + await import( + /*webpackIgnore: true*/ + /*@vite-ignore*/ + PDFWorker.workerSrc); + AppOptions.set("workerPort", null); + } catch (ex) { + console.error("_parseHashParams:", ex); + } + } + if (params.has("textlayer")) { + switch (params.get("textlayer")) { + case "off": + AppOptions.set("textLayerMode", TextLayerMode.DISABLE); + break; + case "visible": + case "shadow": + case "hover": + viewerContainer.classList.add(`textLayer-${params.get("textlayer")}`); + try { + await loadPDFBug(); + this._PDFBug.loadCSS(); + } catch (ex) { + console.error("_parseHashParams:", ex); + } + break; + } + } + if (params.has("pdfbug")) { + const enabled = params.get("pdfbug").split(","); + try { + await loadPDFBug(); + this._PDFBug.init(mainContainer, enabled); + } catch (ex) { + console.error("_parseHashParams:", ex); + } + const debugOpts = { + pdfBug: true, + fontExtraProperties: true + }; + if (globalThis.StepperManager?.enabled) { + debugOpts.minDurationToUpdateCanvas = 0; + } + AppOptions.setAll(debugOpts); + } + if (params.has("locale")) { + AppOptions.set("localeProperties", { + lang: params.get("locale") + }); + } + const opts = { + disableAutoFetch: x => x === "true", + disableFontFace: x => x === "true", + disableHistory: x => x === "true", + disableRange: x => x === "true", + disableStream: x => x === "true", + verbosity: x => x | 0 + }; + for (const name in opts) { + const check = opts[name], + key = name.toLowerCase(); + if (params.has(key)) { + AppOptions.set(name, check(params.get(key))); + } + } + }, + async _initializeViewerComponents() { + const { + appConfig, + externalServices, + l10n, + mlManager + } = this; + const abortSignal = this._globalAbortController.signal; + const eventBus = new EventBus(); + this.eventBus = AppOptions.eventBus = eventBus; + mlManager?.setEventBus(eventBus, abortSignal); + const overlayManager = this.overlayManager = new OverlayManager(); + const renderingQueue = this.pdfRenderingQueue = new PDFRenderingQueue(); + renderingQueue.onIdle = this._cleanup.bind(this); + const linkService = this.pdfLinkService = new PDFLinkService({ + eventBus, + externalLinkTarget: AppOptions.get("externalLinkTarget"), + externalLinkRel: AppOptions.get("externalLinkRel"), + ignoreDestinationZoom: AppOptions.get("ignoreDestinationZoom") + }); + const downloadManager = this.downloadManager = new DownloadManager(); + const findController = this.findController = new PDFFindController({ + linkService, + eventBus, + updateMatchesCountOnProgress: true + }); + const pdfScriptingManager = this.pdfScriptingManager = new PDFScriptingManager({ + eventBus, + externalServices, + docProperties: this._scriptingDocProperties.bind(this) + }); + const container = appConfig.mainContainer, + viewer = appConfig.viewerContainer; + const annotationEditorMode = AppOptions.get("annotationEditorMode"); + const hasForcedColors = AppOptions.get("forcePageColors") || window.matchMedia("(forced-colors: active)").matches; + const pageColors = hasForcedColors ? { + background: AppOptions.get("pageColorsBackground"), + foreground: AppOptions.get("pageColorsForeground") + } : null; + let altTextManager; + if (AppOptions.get("enableUpdatedAddImage")) { + altTextManager = appConfig.newAltTextDialog ? new NewAltTextManager(appConfig.newAltTextDialog, overlayManager, eventBus) : null; + } else { + altTextManager = appConfig.altTextDialog ? new AltTextManager(appConfig.altTextDialog, container, overlayManager, eventBus) : null; + } + if (appConfig.editorUndoBar) { + this.editorUndoBar = new EditorUndoBar(appConfig.editorUndoBar, eventBus); + } + const signatureManager = AppOptions.get("enableSignatureEditor") && appConfig.addSignatureDialog ? new SignatureManager(appConfig.addSignatureDialog, appConfig.editSignatureDialog, appConfig.annotationEditorParams?.editorSignatureAddSignature || null, overlayManager, l10n, externalServices.createSignatureStorage(eventBus, abortSignal), eventBus) : null; + const ltr = appConfig.viewerContainer ? getComputedStyle(appConfig.viewerContainer).direction === "ltr" : true; + const commentManager = AppOptions.get("enableComment") && appConfig.editCommentDialog ? new CommentManager(appConfig.editCommentDialog, { + learnMoreUrl: AppOptions.get("commentLearnMoreUrl"), + sidebar: appConfig.annotationEditorParams?.editorCommentsSidebar || null, + sidebarResizer: appConfig.annotationEditorParams?.editorCommentsSidebarResizer || null, + commentsList: appConfig.annotationEditorParams?.editorCommentsSidebarList || null, + commentCount: appConfig.annotationEditorParams?.editorCommentsSidebarCount || null, + sidebarTitle: appConfig.annotationEditorParams?.editorCommentsSidebarTitle || null, + closeButton: appConfig.annotationEditorParams?.editorCommentsSidebarCloseButton || null, + commentToolbarButton: appConfig.toolbar?.editorCommentButton || null + }, eventBus, linkService, overlayManager, ltr, hasForcedColors) : null; + const enableHWA = AppOptions.get("enableHWA"), + maxCanvasPixels = AppOptions.get("maxCanvasPixels"), + maxCanvasDim = AppOptions.get("maxCanvasDim"), + capCanvasAreaFactor = AppOptions.get("capCanvasAreaFactor"); + const pdfViewer = this.pdfViewer = new PDFViewer({ + container, + viewer, + viewerAlert: appConfig.viewerAlert, + eventBus, + renderingQueue, + linkService, + downloadManager, + altTextManager, + commentManager, + signatureManager, + editorUndoBar: this.editorUndoBar, + findController, + scriptingManager: AppOptions.get("enableScripting") && pdfScriptingManager, + l10n, + textLayerMode: AppOptions.get("textLayerMode"), + annotationMode: AppOptions.get("annotationMode"), + annotationEditorMode, + annotationEditorHighlightColors: AppOptions.get("highlightEditorColors"), + enableHighlightFloatingButton: AppOptions.get("enableHighlightFloatingButton"), + enableUpdatedAddImage: AppOptions.get("enableUpdatedAddImage"), + enableNewAltTextWhenAddingImage: AppOptions.get("enableNewAltTextWhenAddingImage"), + imageResourcesPath: AppOptions.get("imageResourcesPath"), + enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"), + maxCanvasPixels, + maxCanvasDim, + capCanvasAreaFactor, + enableDetailCanvas: AppOptions.get("enableDetailCanvas"), + enablePermissions: AppOptions.get("enablePermissions"), + enableOptimizedPartialRendering: AppOptions.get("enableOptimizedPartialRendering"), + pageColors, + mlManager, + abortSignal, + enableHWA, + supportsPinchToZoom: this.supportsPinchToZoom, + enableAutoLinking: AppOptions.get("enableAutoLinking"), + minDurationToUpdateCanvas: AppOptions.get("minDurationToUpdateCanvas") + }); + renderingQueue.setViewer(pdfViewer); + linkService.setViewer(pdfViewer); + pdfScriptingManager.setViewer(pdfViewer); + if (appConfig.viewsManager?.thumbnailsView) { + this.pdfThumbnailViewer = new PDFThumbnailViewer({ + container: appConfig.viewsManager.thumbnailsView, + eventBus, + renderingQueue, + linkService, + maxCanvasPixels, + maxCanvasDim, + pageColors, + abortSignal, + enableHWA, + enableSplitMerge: AppOptions.get("enableSplitMerge"), + manageMenu: appConfig.viewsManager.manageMenu, + addFileButton: appConfig.viewsManager.viewsManagerAddFileButton + }); + renderingQueue.setThumbnailViewer(this.pdfThumbnailViewer); + } + if (!this.isViewerEmbedded && !AppOptions.get("disableHistory")) { + this.pdfHistory = new PDFHistory({ + linkService, + eventBus + }); + linkService.setHistory(this.pdfHistory); + } + if (!this.supportsIntegratedFind && appConfig.findBar) { + this.findBar = new PDFFindBar(appConfig.findBar, appConfig.principalContainer, eventBus); + } + if (appConfig.annotationEditorParams) { + if (annotationEditorMode !== AnnotationEditorType.DISABLE) { + const editorSignatureButton = appConfig.toolbar?.editorSignatureButton; + if (editorSignatureButton && AppOptions.get("enableSignatureEditor")) { + editorSignatureButton.parentElement.hidden = false; + } + const editorCommentButton = appConfig.toolbar?.editorCommentButton; + if (editorCommentButton && AppOptions.get("enableComment")) { + editorCommentButton.parentElement.hidden = false; + } + this.annotationEditorParams = new AnnotationEditorParams(appConfig.annotationEditorParams, eventBus); + } else { + for (const id of ["editorModeButtons", "editorModeSeparator"]) { + document.getElementById(id)?.classList.add("hidden"); + } + } + } + if (mlManager && appConfig.secondaryToolbar?.imageAltTextSettingsButton) { + this.imageAltTextSettings = new ImageAltTextSettings(appConfig.altTextSettingsDialog, overlayManager, eventBus, mlManager); + } + if (appConfig.documentProperties) { + this.pdfDocumentProperties = new PDFDocumentProperties(appConfig.documentProperties, overlayManager, eventBus, l10n, () => this._docFilename, () => this._docTitle); + } + if (appConfig.secondaryToolbar?.cursorHandToolButton) { + this.pdfCursorTools = new PDFCursorTools({ + container, + eventBus, + cursorToolOnLoad: AppOptions.get("cursorToolOnLoad") + }); + } + if (appConfig.toolbar) { + this.toolbar = new Toolbar(appConfig.toolbar, eventBus, AppOptions.get("toolbarDensity")); + } + if (appConfig.secondaryToolbar) { + if (AppOptions.get("enableAltText")) { + appConfig.secondaryToolbar.imageAltTextSettingsButton?.classList.remove("hidden"); + appConfig.secondaryToolbar.imageAltTextSettingsSeparator?.classList.remove("hidden"); + } + this.secondaryToolbar = new SecondaryToolbar(appConfig.secondaryToolbar, eventBus); + } + if (this.supportsFullscreen && appConfig.secondaryToolbar?.presentationModeButton) { + this.pdfPresentationMode = new PDFPresentationMode({ + container, + pdfViewer, + eventBus + }); + } + if (appConfig.passwordOverlay) { + this.passwordPrompt = new PasswordPrompt(appConfig.passwordOverlay, overlayManager, this.isViewerEmbedded); + } + if (appConfig.viewsManager?.outlinesView) { + this.pdfOutlineViewer = new PDFOutlineViewer({ + container: appConfig.viewsManager.outlinesView, + eventBus, + l10n, + linkService, + downloadManager + }); + } + if (appConfig.viewsManager?.attachmentsView) { + this.pdfAttachmentViewer = new PDFAttachmentViewer({ + container: appConfig.viewsManager.attachmentsView, + eventBus, + l10n, + downloadManager + }); + } + if (appConfig.viewsManager?.layersView) { + this.pdfLayerViewer = new PDFLayerViewer({ + container: appConfig.viewsManager.layersView, + eventBus, + l10n + }); + } + if (appConfig.viewsManager) { + this.viewsManager = new ViewsManager({ + elements: appConfig.viewsManager, + eventBus, + l10n + }); + this.viewsManager.onToggled = this.forceRendering.bind(this); + this.viewsManager.onUpdateThumbnails = () => { + for (const pageView of pdfViewer.getCachedPageViews()) { + if (pageView.renderingState === RenderingStates.FINISHED) { + this.pdfThumbnailViewer.getThumbnail(pageView.id - 1)?.setImage(pageView); + } + } + this.pdfThumbnailViewer.scrollThumbnailIntoView(pdfViewer.currentPageNumber); + }; + } + }, + async run(config) { + await this.initialize(config); + const { + appConfig, + eventBus + } = this; + let file; + const queryString = document.location.search.substring(1); + const params = parseQueryString(queryString); + file = params.get("file") ?? AppOptions.get("defaultUrl"); + try { + file = new URL(file).href; + } catch { + file = encodeURIComponent(file).replaceAll("%2F", "/"); + } + validateFileURL(file); + const fileInput = this._openFileInput = document.createElement("input"); + fileInput.id = "fileInput"; + fileInput.hidden = true; + fileInput.type = "file"; + fileInput.value = null; + document.body.append(fileInput); + fileInput.addEventListener("change", function (evt) { + const { + files + } = evt.target; + if (!files || files.length === 0) { + return; + } + eventBus.dispatch("fileinputchange", { + source: this, + fileInput: evt.target + }); + }); + appConfig.mainContainer.addEventListener("dragover", function (evt) { + for (const item of evt.dataTransfer.items) { + if (item.type === "application/pdf") { + evt.dataTransfer.dropEffect = evt.dataTransfer.effectAllowed === "copy" ? "copy" : "move"; + stopEvent(evt); + return; + } + } + }); + appConfig.mainContainer.addEventListener("drop", function (evt) { + if (evt.dataTransfer.files?.[0].type !== "application/pdf") { + return; + } + stopEvent(evt); + eventBus.dispatch("fileinputchange", { + source: this, + fileInput: evt.dataTransfer + }); + }); + if (!AppOptions.get("supportsDocumentFonts")) { + AppOptions.set("disableFontFace", true); + this.l10n.get("pdfjs-web-fonts-disabled").then(msg => { + console.warn(msg); + }); + } + const togglePrintingButtons = visible => { + appConfig.toolbar?.print?.classList.toggle("hidden", !visible); + appConfig.secondaryToolbar?.printButton.classList.toggle("hidden", !visible); + }; + if (!this.supportsPrinting) { + togglePrintingButtons(false); + } else { + eventBus.on("printingallowed", ({ + isAllowed + }) => togglePrintingButtons(isAllowed)); + } + if (!this.supportsFullscreen) { + appConfig.secondaryToolbar?.presentationModeButton.classList.add("hidden"); + } + if (this.supportsIntegratedFind) { + appConfig.findBar?.toggleButton?.classList.add("hidden"); + } + if (file) { + this.open({ + url: file + }); + } else { + this._hideViewBookmark(); + } + }, + get externalServices() { + return shadow(this, "externalServices", new ExternalServices()); + }, + get initialized() { + return this._initializedCapability.settled; + }, + get initializedPromise() { + return this._initializedCapability.promise; + }, + updateZoom(steps, scaleFactor, origin) { + if (this.pdfViewer.isInPresentationMode) { + return; + } + this.pdfViewer.updateScale({ + drawingDelay: AppOptions.get("defaultZoomDelay"), + steps, + scaleFactor, + origin + }); + }, + zoomIn() { + this.updateZoom(1); + }, + zoomOut() { + this.updateZoom(-1); + }, + zoomReset() { + if (this.pdfViewer.isInPresentationMode) { + return; + } + this.pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE; + }, + touchPinchCallback(origin, prevDistance, distance) { + if (this.supportsPinchToZoom) { + const newScaleFactor = this._accumulateFactor(this.pdfViewer.currentScale, distance / prevDistance, "_touchUnusedFactor"); + this.updateZoom(null, newScaleFactor, origin); + } else { + const PIXELS_PER_LINE_SCALE = 30; + const ticks = this._accumulateTicks((distance - prevDistance) / PIXELS_PER_LINE_SCALE, "_touchUnusedTicks"); + this.updateZoom(ticks, null, origin); + } + }, + touchPinchEndCallback() { + this._touchUnusedTicks = 0; + this._touchUnusedFactor = 1; + }, + get pagesCount() { + return this.pdfDocument ? this.pdfDocument.numPages : 0; + }, + get page() { + return this.pdfViewer.currentPageNumber; + }, + set page(val) { + this.pdfViewer.currentPageNumber = val; + }, + get supportsPrinting() { + return shadow(this, "supportsPrinting", AppOptions.get("supportsPrinting") && PDFPrintServiceFactory.supportsPrinting); + }, + get supportsFullscreen() { + return shadow(this, "supportsFullscreen", document.fullscreenEnabled); + }, + get supportsPinchToZoom() { + return shadow(this, "supportsPinchToZoom", AppOptions.get("supportsPinchToZoom")); + }, + get supportsIntegratedFind() { + return shadow(this, "supportsIntegratedFind", AppOptions.get("supportsIntegratedFind")); + }, + get loadingBar() { + const barElement = document.getElementById("loadingBar"); + const bar = barElement ? new ProgressBar(barElement) : null; + return shadow(this, "loadingBar", bar); + }, + get supportsMouseWheelZoomCtrlKey() { + return shadow(this, "supportsMouseWheelZoomCtrlKey", AppOptions.get("supportsMouseWheelZoomCtrlKey")); + }, + get supportsMouseWheelZoomMetaKey() { + return shadow(this, "supportsMouseWheelZoomMetaKey", AppOptions.get("supportsMouseWheelZoomMetaKey")); + }, + get supportsCaretBrowsingMode() { + return AppOptions.get("supportsCaretBrowsingMode"); + }, + moveCaret(isUp, select) { + this._caretBrowsing ||= new CaretBrowsingMode(this._globalAbortController.signal, this.appConfig.mainContainer, this.appConfig.viewerContainer, this.appConfig.toolbar?.container); + this._caretBrowsing.moveCaret(isUp, select); + }, + setTitleUsingUrl(url = "", downloadUrl = null) { + this.url = url; + this.baseUrl = updateUrlHash(url, "", true); + if (downloadUrl) { + this._downloadUrl = downloadUrl === url ? this.baseUrl : updateUrlHash(downloadUrl, "", true); + } + if (isDataScheme(url)) { + this._hideViewBookmark(); + } + let title = getPdfFilenameFromUrl(url, ""); + if (!title) { + try { + title = decodeURIComponent(getFilenameFromUrl(url)); + } catch {} + } + this.setTitle(title || url); + }, + setTitle(title = this._title) { + this._title = title; + if (this.isViewerEmbedded) { + return; + } + const editorIndicator = this._hasAnnotationEditors && !this.pdfRenderingQueue.printing; + document.title = `${editorIndicator ? "* " : ""}${title}`; + }, + get _docFilename() { + return this._contentDispositionFilename || getPdfFilenameFromUrl(this.url); + }, + get _docTitle() { + const { + documentInfo, + metadata + } = this; + const title = metadata?.get("dc:title"); + if (title) { + if (title !== "Untitled" && !/[\uFFF0-\uFFFF]/g.test(title)) { + return title; + } + } + return documentInfo.Title; + }, + _hideViewBookmark() { + const { + secondaryToolbar + } = this.appConfig; + secondaryToolbar?.viewBookmarkButton.classList.add("hidden"); + if (secondaryToolbar?.presentationModeButton.classList.contains("hidden")) { + document.getElementById("viewBookmarkSeparator")?.classList.add("hidden"); + } + }, + async close() { + this._unblockDocumentLoadEvent(); + this._hideViewBookmark(); + if (!this.pdfLoadingTask) { + return; + } + if (this.pdfDocument?.annotationStorage.size > 0 && this._annotationStorageModified) { + try { + await this.save(); + } catch {} + } + const promises = []; + promises.push(this.pdfLoadingTask.destroy()); + this.pdfLoadingTask = null; + if (this.pdfDocument) { + this.pdfDocument = null; + this.pdfThumbnailViewer?.setDocument(null); + this.pdfViewer.setDocument(null); + this.pdfLinkService.setDocument(null); + this.pdfDocumentProperties?.setDocument(null); + this.pdfTextExtractor?.setViewer(null); + } + this.pdfLinkService.externalLinkEnabled = true; + this.store = null; + this.isInitialViewSet = false; + this.url = ""; + this.baseUrl = ""; + this._downloadUrl = ""; + this.documentInfo = null; + this.metadata = null; + this._contentDispositionFilename = null; + this._contentLength = null; + this._saveInProgress = false; + this._hasAnnotationEditors = false; + promises.push(this.pdfScriptingManager.destroyPromise, this.passwordPrompt.close()); + this.setTitle(); + this.viewsManager?.reset(); + this.pdfOutlineViewer?.reset(); + this.pdfAttachmentViewer?.reset(); + this.pdfLayerViewer?.reset(); + this.pdfHistory?.reset(); + this.findBar?.reset(); + this.toolbar?.reset(); + this.secondaryToolbar?.reset(); + this._PDFBug?.cleanup(); + await Promise.all(promises); + }, + async open(args) { + if (this.pdfLoadingTask) { + await this.close(); + } + const workerParams = AppOptions.getAll(OptionKind.WORKER); + Object.assign(GlobalWorkerOptions, workerParams); + if (args.url) { + this.setTitleUsingUrl(args.originalUrl || args.url, args.url); + } + const apiParams = AppOptions.getAll(OptionKind.API); + const loadingTask = getDocument({ + ...apiParams, + ...args + }); + this.pdfLoadingTask = loadingTask; + loadingTask.onPassword = (updateCallback, reason) => { + if (this.isViewerEmbedded) { + this._unblockDocumentLoadEvent(); + } + this.pdfLinkService.externalLinkEnabled = false; + this.passwordPrompt.setUpdateCallback(updateCallback, reason); + this.passwordPrompt.open(); + }; + loadingTask.onProgress = evt => this.progress(evt.percent); + return loadingTask.promise.then(pdfDocument => { + this.load(pdfDocument); + }, reason => { + if (loadingTask !== this.pdfLoadingTask) { + return undefined; + } + let key = "pdfjs-loading-error"; + if (reason instanceof InvalidPDFException) { + key = "pdfjs-invalid-file-error"; + } else if (reason instanceof ResponseException) { + key = reason.missing ? "pdfjs-missing-file-error" : "pdfjs-unexpected-response-error"; + } + return this._documentError(key, { + message: reason.message + }).then(() => { + throw reason; + }); + }); + }, + async download() { + let data; + try { + data = await (this.pdfDocument ? this.pdfDocument.getData() : this.pdfLoadingTask.getData()); + } catch {} + this.downloadManager.download(data, this._downloadUrl, this._docFilename); + }, + async save() { + if (this._saveInProgress) { + return; + } + this._saveInProgress = true; + await this.pdfScriptingManager.dispatchWillSave(); + try { + const data = await this.pdfDocument.saveDocument(); + this.downloadManager.download(data, this._downloadUrl, this._docFilename); + } catch (reason) { + console.error(`Error when saving the document:`, reason); + await this.download(); + } finally { + await this.pdfScriptingManager.dispatchDidSave(); + this._saveInProgress = false; + } + const editorStats = this.pdfDocument?.annotationStorage.editorStats; + if (editorStats) { + this.externalServices.reportTelemetry({ + type: "editing", + data: { + type: "save", + stats: editorStats + } + }); + } + }, + async downloadOrSave() { + const { + classList + } = this.appConfig.appContainer; + classList.add("wait"); + await (this.pdfDocument?.annotationStorage.size > 0 ? this.save() : this.download()); + classList.remove("wait"); + }, + async _documentError(key, moreInfo = null) { + this._unblockDocumentLoadEvent(); + const message = await this._otherError(key || "pdfjs-loading-error", moreInfo); + this.eventBus.dispatch("documenterror", { + source: this, + message, + reason: moreInfo?.message ?? null + }); + }, + async _otherError(key, moreInfo = null) { + const message = await this.l10n.get(key); + const moreInfoText = [`PDF.js v${version || "?"} (build: ${build || "?"})`]; + if (moreInfo) { + moreInfoText.push(`Message: ${moreInfo.message}`); + if (moreInfo.stack) { + moreInfoText.push(`Stack: ${moreInfo.stack}`); + } else { + if (moreInfo.filename) { + moreInfoText.push(`File: ${moreInfo.filename}`); + } + if (moreInfo.lineNumber) { + moreInfoText.push(`Line: ${moreInfo.lineNumber}`); + } + } + } + console.error(`${message}\n\n${moreInfoText.join("\n")}`); + return message; + }, + progress(percent) { + if (!this.loadingBar || percent <= this.loadingBar.percent) { + return; + } + this.loadingBar.percent = percent; + if (this.pdfDocument?.loadingParams.disableAutoFetch ?? AppOptions.get("disableAutoFetch")) { + this.loadingBar.setDisableAutoFetch(); + } + }, + load(pdfDocument) { + this.pdfDocument = pdfDocument; + this._printPermissionPromise = new Promise(resolve => { + this.eventBus.on("printingallowed", ({ + isAllowed + }) => { + resolve(isAllowed); + }, { + once: true + }); + }); + pdfDocument.getDownloadInfo().then(({ + length + }) => { + this._contentLength = length; + this.loadingBar?.hide(); + firstPagePromise.then(() => { + this.eventBus.dispatch("documentloaded", { + source: this + }); + }); + }); + const pageLayoutPromise = pdfDocument.getPageLayout().catch(() => {}); + const pageModePromise = pdfDocument.getPageMode().catch(() => {}); + const openActionPromise = pdfDocument.getOpenAction().catch(() => {}); + this.toolbar?.setPagesCount(pdfDocument.numPages, false); + this.secondaryToolbar?.setPagesCount(pdfDocument.numPages); + this.pdfLinkService.setDocument(pdfDocument); + this.pdfDocumentProperties?.setDocument(pdfDocument); + const pdfViewer = this.pdfViewer; + pdfViewer.setDocument(pdfDocument); + this.pdfTextExtractor.setViewer(pdfViewer); + const { + firstPagePromise, + onePageRendered, + pagesPromise + } = pdfViewer; + this.pdfThumbnailViewer?.setDocument(pdfDocument); + const storedPromise = (this.store = new ViewHistory(pdfDocument.fingerprints[0])).getMultiple({ + page: null, + zoom: DEFAULT_SCALE_VALUE, + scrollLeft: "0", + scrollTop: "0", + rotation: null, + sidebarView: SidebarView.UNKNOWN, + scrollMode: ScrollMode.UNKNOWN, + spreadMode: SpreadMode.UNKNOWN + }).catch(() => {}); + firstPagePromise.then(pdfPage => { + this.loadingBar?.setWidth(this.appConfig.viewerContainer); + this._initializeAnnotationStorageCallbacks(pdfDocument); + Promise.all([animationStarted, storedPromise, pageLayoutPromise, pageModePromise, openActionPromise]).then(async ([timeStamp, stored, pageLayout, pageMode, openAction]) => { + const viewOnLoad = AppOptions.get("viewOnLoad"); + this._initializePdfHistory({ + fingerprint: pdfDocument.fingerprints[0], + viewOnLoad, + initialDest: openAction?.dest + }); + const initialBookmark = this.initialBookmark; + const zoom = AppOptions.get("defaultZoomValue"); + let hash = zoom ? `zoom=${zoom}` : null; + let rotation = null; + let sidebarView = AppOptions.get("sidebarViewOnLoad"); + let scrollMode = AppOptions.get("scrollModeOnLoad"); + let spreadMode = AppOptions.get("spreadModeOnLoad"); + if (stored?.page && viewOnLoad !== ViewOnLoad.INITIAL) { + hash = `page=${stored.page}&zoom=${zoom || stored.zoom},` + `${stored.scrollLeft},${stored.scrollTop}`; + rotation = parseInt(stored.rotation, 10); + if (sidebarView === SidebarView.UNKNOWN) { + sidebarView = stored.sidebarView | 0; + } + if (scrollMode === ScrollMode.UNKNOWN) { + scrollMode = stored.scrollMode | 0; + } + if (spreadMode === SpreadMode.UNKNOWN) { + spreadMode = stored.spreadMode | 0; + } + } + if (pageMode && sidebarView === SidebarView.UNKNOWN) { + sidebarView = apiPageModeToSidebarView(pageMode); + } + if (pageLayout && scrollMode === ScrollMode.UNKNOWN && spreadMode === SpreadMode.UNKNOWN) { + const modes = apiPageLayoutToViewerModes(pageLayout); + spreadMode = modes.spreadMode; + } + this.setInitialView(hash, { + rotation, + sidebarView, + scrollMode, + spreadMode + }); + this.eventBus.dispatch("documentinit", { + source: this + }); + await Promise.race([pagesPromise, new Promise(resolve => { + setTimeout(resolve, FORCE_PAGES_LOADED_TIMEOUT); + })]); + if (!initialBookmark && !hash) { + return; + } + if (pdfViewer.hasEqualPageSizes) { + return; + } + this.initialBookmark = initialBookmark; + pdfViewer.currentScaleValue = pdfViewer.currentScaleValue; + this.setInitialView(hash); + }).catch(() => { + this.setInitialView(); + }).then(function () { + pdfViewer.update(); + }); + }); + pagesPromise.then(() => { + this._unblockDocumentLoadEvent(); + this._initializeAutoPrint(pdfDocument, openActionPromise); + }, reason => { + this._documentError("pdfjs-loading-error", { + message: reason.message + }); + }); + onePageRendered.then(data => { + this.externalServices.reportTelemetry({ + type: "pageInfo", + timestamp: data.timestamp + }); + if (this.pdfOutlineViewer) { + pdfDocument.getOutline().then(outline => { + if (pdfDocument !== this.pdfDocument) { + return; + } + this.pdfOutlineViewer.render({ + outline, + pdfDocument + }); + }); + } + if (this.pdfAttachmentViewer) { + pdfDocument.getAttachments().then(attachments => { + if (pdfDocument !== this.pdfDocument) { + return; + } + this.pdfAttachmentViewer.render({ + attachments + }); + }); + } + if (this.pdfLayerViewer) { + pdfViewer.optionalContentConfigPromise.then(optionalContentConfig => { + if (pdfDocument !== this.pdfDocument) { + return; + } + this.pdfLayerViewer.render({ + optionalContentConfig, + pdfDocument + }); + }); + } + }); + this._initializePageLabels(pdfDocument); + this._initializeMetadata(pdfDocument); + }, + async _scriptingDocProperties(pdfDocument) { + if (!this.documentInfo) { + await new Promise(resolve => { + this.eventBus._on("metadataloaded", resolve, { + once: true + }); + }); + if (pdfDocument !== this.pdfDocument) { + return null; + } + } + if (!this._contentLength) { + await new Promise(resolve => { + this.eventBus._on("documentloaded", resolve, { + once: true + }); + }); + if (pdfDocument !== this.pdfDocument) { + return null; + } + } + return { + ...this.documentInfo, + baseURL: this.baseUrl, + filesize: this._contentLength, + filename: this._docFilename, + metadata: this.metadata?.getRaw(), + authors: this.metadata?.get("dc:creator"), + numPages: this.pagesCount, + URL: this.url + }; + }, + async _initializeAutoPrint(pdfDocument, openActionPromise) { + const [openAction, jsActions] = await Promise.all([openActionPromise, this.pdfViewer.enableScripting ? null : pdfDocument.getJSActions()]); + if (pdfDocument !== this.pdfDocument) { + return; + } + let triggerAutoPrint = openAction?.action === "Print"; + if (jsActions) { + console.warn("Warning: JavaScript support is not enabled"); + for (const name in jsActions) { + if (triggerAutoPrint) { + break; + } + switch (name) { + case "WillClose": + case "WillSave": + case "DidSave": + case "WillPrint": + case "DidPrint": + continue; + } + triggerAutoPrint = jsActions[name].some(js => AutoPrintRegExp.test(js)); + } + } + if (triggerAutoPrint) { + this.triggerPrinting(); + } + }, + async _initializeMetadata(pdfDocument) { + const { + info, + metadata, + contentDispositionFilename, + contentLength, + hasStructTree + } = await pdfDocument.getMetadata(); + if (pdfDocument !== this.pdfDocument) { + return; + } + this.externalServices.reportTelemetry({ + type: "taggedPDF", + data: hasStructTree + }); + this.documentInfo = info; + this.metadata = metadata; + this._contentDispositionFilename ??= contentDispositionFilename; + this._contentLength ??= contentLength; + console.log(`PDF ${pdfDocument.fingerprints[0]} [${info.PDFFormatVersion} ` + `${(metadata?.get("pdf:producer") || info.Producer || "-").trim()} / ` + `${(metadata?.get("xmp:creatortool") || info.Creator || "-").trim()}` + `] (PDF.js: ${version || "?"} [${build || "?"}])`); + const pdfTitle = this._docTitle; + if (pdfTitle) { + this.setTitle(`${pdfTitle} - ${this._contentDispositionFilename || this._title}`); + } else if (this._contentDispositionFilename) { + this.setTitle(this._contentDispositionFilename); + } + if (info.IsXFAPresent && !info.IsAcroFormPresent && !pdfDocument.isPureXfa) { + if (pdfDocument.loadingParams.enableXfa) { + console.warn("Warning: XFA Foreground documents are not supported"); + } else { + console.warn("Warning: XFA support is not enabled"); + } + } else if ((info.IsAcroFormPresent || info.IsXFAPresent) && !this.pdfViewer.renderForms) { + console.warn("Warning: Interactive form support is not enabled"); + } + if (info.IsSignaturesPresent) { + console.warn("Warning: Digital signatures validation is not supported"); + } + this.eventBus.dispatch("metadataloaded", { + source: this + }); + }, + async _initializePageLabels(pdfDocument) { + const labels = await pdfDocument.getPageLabels(); + if (pdfDocument !== this.pdfDocument) { + return; + } + if (!labels || AppOptions.get("disablePageLabels")) { + return; + } + const numLabels = labels.length; + let standardLabels = 0, + emptyLabels = 0; + for (let i = 0; i < numLabels; i++) { + const label = labels[i]; + if (label === (i + 1).toString()) { + standardLabels++; + } else if (label === "") { + emptyLabels++; + } else { + break; + } + } + if (standardLabels >= numLabels || emptyLabels >= numLabels) { + return; + } + const { + pdfViewer, + pdfThumbnailViewer, + toolbar + } = this; + pdfViewer.setPageLabels(labels); + pdfThumbnailViewer?.setPageLabels(labels); + toolbar?.setPagesCount(numLabels, true); + toolbar?.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel); + }, + _initializePdfHistory({ + fingerprint, + viewOnLoad, + initialDest = null + }) { + if (!this.pdfHistory) { + return; + } + this.pdfHistory.initialize({ + fingerprint, + resetHistory: viewOnLoad === ViewOnLoad.INITIAL, + updateUrl: AppOptions.get("historyUpdateUrl") + }); + if (this.pdfHistory.initialBookmark) { + this.initialBookmark = this.pdfHistory.initialBookmark; + this.initialRotation = this.pdfHistory.initialRotation; + } + if (initialDest && !this.initialBookmark && viewOnLoad === ViewOnLoad.UNKNOWN) { + this.initialBookmark = JSON.stringify(initialDest); + this.pdfHistory.push({ + explicitDest: initialDest, + pageNumber: null + }); + } + }, + _initializeAnnotationStorageCallbacks(pdfDocument) { + if (pdfDocument !== this.pdfDocument) { + return; + } + const { + annotationStorage + } = pdfDocument; + annotationStorage.onSetModified = () => { + window.addEventListener("beforeunload", beforeUnload); + this._annotationStorageModified = true; + }; + annotationStorage.onResetModified = () => { + window.removeEventListener("beforeunload", beforeUnload); + delete this._annotationStorageModified; + }; + annotationStorage.onAnnotationEditor = typeStr => { + this._hasAnnotationEditors = !!typeStr; + this.setTitle(); + }; + }, + setInitialView(storedHash, { + rotation, + sidebarView, + scrollMode, + spreadMode + } = {}) { + const setRotation = angle => { + if (isValidRotation(angle)) { + this.pdfViewer.pagesRotation = angle; + } + }; + const setViewerModes = (scroll, spread) => { + if (isValidScrollMode(scroll)) { + this.pdfViewer.scrollMode = scroll; + } + if (isValidSpreadMode(spread)) { + this.pdfViewer.spreadMode = spread; + } + }; + this.isInitialViewSet = true; + this.viewsManager?.setInitialView(sidebarView); + setViewerModes(scrollMode, spreadMode); + if (this.initialBookmark) { + setRotation(this.initialRotation); + delete this.initialRotation; + this.pdfLinkService.setHash(this.initialBookmark); + this.initialBookmark = null; + } else if (storedHash) { + setRotation(rotation); + this.pdfLinkService.setHash(storedHash); + } + this.toolbar?.setPageNumber(this.pdfViewer.currentPageNumber, this.pdfViewer.currentPageLabel); + this.secondaryToolbar?.setPageNumber(this.pdfViewer.currentPageNumber); + if (!this.pdfViewer.currentScaleValue) { + this.pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE; + } + }, + _cleanup() { + if (!this.pdfDocument) { + return; + } + this.pdfViewer.cleanup(); + this.pdfThumbnailViewer?.cleanup(); + this.pdfDocument.cleanup(AppOptions.get("fontExtraProperties")); + }, + forceRendering() { + this.pdfRenderingQueue.printing = !!this.printService; + this.pdfRenderingQueue.isThumbnailViewEnabled = this.viewsManager?.visibleView === SidebarView.THUMBS; + this.pdfRenderingQueue.renderHighestPriority(); + }, + beforePrint() { + this._printAnnotationStoragePromise = this.pdfScriptingManager.dispatchWillPrint().catch(() => {}).then(() => this.pdfDocument?.annotationStorage.print); + if (this.printService) { + return; + } + if (!this.supportsPrinting || !this.pdfViewer.printingAllowed) { + this._otherError("pdfjs-printing-not-supported"); + return; + } + if (!this.pdfViewer.pageViewsReady) { + this.l10n.get("pdfjs-printing-not-ready").then(msg => { + window.alert(msg); + }); + return; + } + this.printService = PDFPrintServiceFactory.createPrintService({ + pdfDocument: this.pdfDocument, + pagesOverview: this.pdfViewer.getPagesOverview(), + printContainer: this.appConfig.printContainer, + printResolution: AppOptions.get("printResolution"), + printAnnotationStoragePromise: this._printAnnotationStoragePromise + }); + this.forceRendering(); + this.setTitle(); + this.printService.layout(); + if (this._hasAnnotationEditors) { + this.externalServices.reportTelemetry({ + type: "editing", + data: { + type: "print", + stats: this.pdfDocument?.annotationStorage.editorStats + } + }); + } + }, + afterPrint() { + if (this._printAnnotationStoragePromise) { + this._printAnnotationStoragePromise.then(() => { + this.pdfScriptingManager.dispatchDidPrint(); + }); + this._printAnnotationStoragePromise = null; + } + if (this.printService) { + this.printService.destroy(); + this.printService = null; + this.pdfDocument?.annotationStorage.resetModified(); + } + this.forceRendering(); + this.setTitle(); + }, + rotatePages(delta) { + this.pdfViewer.pagesRotation += delta; + }, + requestPresentationMode() { + this.pdfPresentationMode?.request(); + }, + async triggerPrinting() { + if (this.supportsPrinting && (await this._printPermissionPromise)) { + window.print(); + } + }, + bindEvents() { + if (this._eventBusAbortController) { + return; + } + const ac = this._eventBusAbortController = new AbortController(); + const opts = { + signal: ac.signal + }; + const { + eventBus, + externalServices, + pdfDocumentProperties, + pdfViewer, + preferences + } = this; + eventBus._on("resize", onResize.bind(this), opts); + eventBus._on("hashchange", onHashchange.bind(this), opts); + eventBus._on("beforeprint", this.beforePrint.bind(this), opts); + eventBus._on("afterprint", this.afterPrint.bind(this), opts); + eventBus._on("pagerender", onPageRender.bind(this), opts); + eventBus._on("pagerendered", onPageRendered.bind(this), opts); + eventBus._on("updateviewarea", onUpdateViewarea.bind(this), opts); + eventBus._on("pagechanging", onPageChanging.bind(this), opts); + eventBus._on("scalechanging", onScaleChanging.bind(this), opts); + eventBus._on("rotationchanging", onRotationChanging.bind(this), opts); + eventBus._on("sidebarviewchanged", onSidebarViewChanged.bind(this), opts); + eventBus._on("pagemode", onPageMode.bind(this), opts); + eventBus._on("namedaction", onNamedAction.bind(this), opts); + eventBus._on("presentationmodechanged", evt => pdfViewer.presentationModeState = evt.state, opts); + eventBus._on("presentationmode", this.requestPresentationMode.bind(this), opts); + eventBus._on("switchannotationeditormode", evt => pdfViewer.annotationEditorMode = evt, opts); + eventBus._on("print", this.triggerPrinting.bind(this), opts); + eventBus._on("download", this.downloadOrSave.bind(this), opts); + eventBus._on("firstpage", () => this.page = 1, opts); + eventBus._on("lastpage", () => this.page = this.pagesCount, opts); + eventBus._on("nextpage", () => pdfViewer.nextPage(), opts); + eventBus._on("previouspage", () => pdfViewer.previousPage(), opts); + eventBus._on("zoomin", this.zoomIn.bind(this), opts); + eventBus._on("zoomout", this.zoomOut.bind(this), opts); + eventBus._on("zoomreset", this.zoomReset.bind(this), opts); + eventBus._on("pagenumberchanged", onPageNumberChanged.bind(this), opts); + eventBus._on("scalechanged", evt => pdfViewer.currentScaleValue = evt.value, opts); + eventBus._on("rotatecw", this.rotatePages.bind(this, 90), opts); + eventBus._on("rotateccw", this.rotatePages.bind(this, -90), opts); + eventBus._on("optionalcontentconfig", evt => pdfViewer.optionalContentConfigPromise = evt.promise, opts); + eventBus._on("switchscrollmode", evt => pdfViewer.scrollMode = evt.mode, opts); + eventBus._on("scrollmodechanged", onViewerModesChanged.bind(this, "scrollMode"), opts); + eventBus._on("switchspreadmode", evt => pdfViewer.spreadMode = evt.mode, opts); + eventBus._on("spreadmodechanged", onViewerModesChanged.bind(this, "spreadMode"), opts); + eventBus._on("imagealttextsettings", onImageAltTextSettings.bind(this), opts); + eventBus._on("documentproperties", () => pdfDocumentProperties?.open(), opts); + eventBus._on("findfromurlhash", onFindFromUrlHash.bind(this), opts); + eventBus._on("updatefindmatchescount", onUpdateFindMatchesCount.bind(this), opts); + eventBus._on("updatefindcontrolstate", onUpdateFindControlState.bind(this), opts); + eventBus._on("fileinputchange", onFileInputChange.bind(this), opts); + eventBus._on("openfile", onOpenFile.bind(this), opts); + eventBus._on("pagesedited", this.onPagesEdited.bind(this), opts); + eventBus._on("savepageseditedpdf", this.onSavePagesEditedPDF.bind(this), opts); + }, + bindWindowEvents() { + if (this._windowAbortController) { + return; + } + this._windowAbortController = new AbortController(); + const { + eventBus, + appConfig: { + mainContainer + }, + pdfViewer, + _windowAbortController: { + signal + } + } = this; + this._touchManager = new TouchManager({ + container: window, + isPinchingDisabled: () => pdfViewer.isInPresentationMode, + isPinchingStopped: () => this.overlayManager?.active, + onPinching: this.touchPinchCallback.bind(this), + onPinchEnd: this.touchPinchEndCallback.bind(this), + signal + }); + function addWindowResolutionChange(evt = null) { + if (evt) { + pdfViewer.refresh(); + } + const mediaQueryList = window.matchMedia(`(resolution: ${OutputScale.pixelRatio}dppx)`); + mediaQueryList.addEventListener("change", addWindowResolutionChange, { + once: true, + signal + }); + } + addWindowResolutionChange(); + window.addEventListener("wheel", onWheel.bind(this), { + passive: false, + signal + }); + window.addEventListener("click", onClick.bind(this), { + signal + }); + window.addEventListener("keydown", onKeyDown.bind(this), { + signal + }); + window.addEventListener("keyup", onKeyUp.bind(this), { + signal + }); + window.addEventListener("resize", () => eventBus.dispatch("resize", { + source: window + }), { + signal + }); + window.addEventListener("hashchange", () => { + eventBus.dispatch("hashchange", { + source: window, + hash: document.location.hash.substring(1) + }); + }, { + signal + }); + window.addEventListener("beforeprint", () => eventBus.dispatch("beforeprint", { + source: window + }), { + signal + }); + window.addEventListener("afterprint", () => eventBus.dispatch("afterprint", { + source: window + }), { + signal + }); + window.addEventListener("updatefromsandbox", evt => { + eventBus.dispatch("updatefromsandbox", { + source: window, + detail: evt.detail + }); + }, { + signal + }); + if (!("onscrollend" in document.documentElement)) { + return; + } + ({ + scrollTop: this._lastScrollTop, + scrollLeft: this._lastScrollLeft + } = mainContainer); + let scrollendTimeoutID, scrollAbortController; + const scrollend = () => { + ({ + scrollTop: this._lastScrollTop, + scrollLeft: this._lastScrollLeft + } = mainContainer); + clearTimeout(scrollendTimeoutID); + if (this._isScrolling) { + scrollAbortController.abort(); + scrollAbortController = null; + this._isScrolling = false; + } + }; + const scroll = () => { + if (this._isCtrlKeyDown) { + return; + } + if (this._lastScrollTop === mainContainer.scrollTop && this._lastScrollLeft === mainContainer.scrollLeft) { + return; + } + if (!this._isScrolling) { + scrollAbortController = new AbortController(); + const abortSignal = AbortSignal.any([scrollAbortController.signal, signal]); + mainContainer.addEventListener("scrollend", scrollend, { + signal: abortSignal + }); + mainContainer.addEventListener("blur", scrollend, { + signal: abortSignal + }); + this._isScrolling = true; + } + clearTimeout(scrollendTimeoutID); + scrollendTimeoutID = setTimeout(scrollend, 100); + }; + mainContainer.addEventListener("scroll", scroll, { + passive: true, + signal + }); + }, + unbindEvents() { + this._eventBusAbortController?.abort(); + this._eventBusAbortController = null; + }, + unbindWindowEvents() { + this._windowAbortController?.abort(); + this._windowAbortController = null; + this._touchManager = null; + }, + async testingClose() { + this.unbindEvents(); + this.unbindWindowEvents(); + this._globalAbortController?.abort(); + this._globalAbortController = null; + this.findBar?.close(); + await Promise.all([this.l10n?.destroy(), this.close()]); + }, + onPagesEdited(data) { + this.pdfViewer.onPagesEdited(data); + }, + async onSavePagesEditedPDF({ + data: extractParams + }) { + if (!this.pdfDocument) { + return; + } + const modifiedPdfBytes = await this.pdfDocument.extractPages(extractParams); + if (!modifiedPdfBytes) { + console.error("Something wrong happened when saving the edited PDF.\nPlease file a bug."); + return; + } + this.downloadManager.download(modifiedPdfBytes, this._downloadUrl, this._docFilename); + }, + _accumulateTicks(ticks, prop) { + if (this[prop] > 0 && ticks < 0 || this[prop] < 0 && ticks > 0) { + this[prop] = 0; + } + this[prop] += ticks; + const wholeTicks = Math.trunc(this[prop]); + this[prop] -= wholeTicks; + return wholeTicks; + }, + _accumulateFactor(previousScale, factor, prop) { + if (factor === 1) { + return 1; + } + if (this[prop] > 1 && factor < 1 || this[prop] < 1 && factor > 1) { + this[prop] = 1; + } + const newFactor = Math.floor(previousScale * factor * this[prop] * 100) / (100 * previousScale); + this[prop] = factor / newFactor; + return newFactor; + }, + _unblockDocumentLoadEvent() { + document.blockUnblockOnload?.(false); + this._unblockDocumentLoadEvent = () => {}; + }, + get scriptingReady() { + return this.pdfScriptingManager.ready; + } +}; +initCom(PDFViewerApplication); +PDFPrintServiceFactory.initGlobals(PDFViewerApplication); +{ + const HOSTED_VIEWER_ORIGINS = new Set(["null", "http://mozilla.github.io", "https://mozilla.github.io"]); + var validateFileURL = function (file) { + if (!file) { + return; + } + const viewerOrigin = URL.parse(window.location)?.origin || "null"; + if (HOSTED_VIEWER_ORIGINS.has(viewerOrigin)) { + return; + } + const fileOrigin = URL.parse(file, window.location)?.origin; + if (fileOrigin === viewerOrigin) { + return; + } + const ex = new Error("file origin does not match viewer's"); + PDFViewerApplication._documentError("pdfjs-loading-error", { + message: ex.message + }); + throw ex; + }; + var onFileInputChange = function (evt) { + if (this.pdfViewer?.isInPresentationMode) { + return; + } + const file = evt.fileInput.files[0]; + this.open({ + url: URL.createObjectURL(file), + originalUrl: encodeURIComponent(file.name) + }); + }; + var onOpenFile = function (evt) { + this._openFileInput?.click(); + }; +} +function onPageRender({ + pageNumber +}) { + if (pageNumber === this.page) { + this.toolbar?.updateLoadingIndicatorState(true); + } +} +function onPageRendered({ + pageNumber, + isDetailView, + error +}) { + if (pageNumber === this.page) { + this.toolbar?.updateLoadingIndicatorState(false); + } + if (!isDetailView && this.viewsManager?.visibleView === SidebarView.THUMBS) { + const pageView = this.pdfViewer.getPageView(pageNumber - 1); + const thumbnailView = this.pdfThumbnailViewer?.getThumbnail(pageNumber - 1); + if (pageView) { + thumbnailView?.setImage(pageView); + } + } + if (error) { + this._otherError("pdfjs-rendering-error", error); + } +} +function onPageMode({ + mode +}) { + let view; + switch (mode) { + case "thumbs": + view = SidebarView.THUMBS; + break; + case "bookmarks": + case "outline": + view = SidebarView.OUTLINE; + break; + case "attachments": + view = SidebarView.ATTACHMENTS; + break; + case "layers": + view = SidebarView.LAYERS; + break; + case "none": + view = SidebarView.NONE; + break; + default: + console.error('Invalid "pagemode" hash parameter: ' + mode); + return; + } + this.viewsManager?.switchView(view, true); +} +function onNamedAction(evt) { + switch (evt.action) { + case "GoToPage": + this.appConfig.toolbar?.pageNumber.select(); + break; + case "Find": + if (!this.supportsIntegratedFind) { + this.findBar?.toggle(); + } + break; + case "Print": + this.triggerPrinting(); + break; + case "SaveAs": + this.downloadOrSave(); + break; + } +} +function onSidebarViewChanged({ + view +}) { + this.pdfRenderingQueue.isThumbnailViewEnabled = view === SidebarView.THUMBS; + if (this.isInitialViewSet) { + this.store?.set("sidebarView", view).catch(() => {}); + } +} +function onUpdateViewarea({ + location +}) { + if (this.isInitialViewSet) { + this.store?.setMultiple({ + page: location.pageNumber, + zoom: location.scale, + scrollLeft: location.left, + scrollTop: location.top, + rotation: location.rotation + }).catch(() => {}); + } + if (this.appConfig.secondaryToolbar) { + this.appConfig.secondaryToolbar.viewBookmarkButton.href = this.pdfLinkService.getAnchorUrl(location.pdfOpenParams); + } +} +function onViewerModesChanged(name, evt) { + if (this.isInitialViewSet && !this.pdfViewer.isInPresentationMode) { + this.store?.set(name, evt.mode).catch(() => {}); + } +} +function onResize() { + const { + pdfDocument, + pdfViewer, + pdfRenderingQueue + } = this; + if (pdfRenderingQueue.printing && window.matchMedia("print").matches) { + return; + } + if (!pdfDocument) { + return; + } + const currentScaleValue = pdfViewer.currentScaleValue; + if (currentScaleValue === "auto" || currentScaleValue === "page-fit" || currentScaleValue === "page-width") { + pdfViewer.currentScaleValue = currentScaleValue; + } + pdfViewer.update(); +} +function onHashchange(evt) { + const hash = evt.hash; + if (!hash) { + return; + } + if (!this.isInitialViewSet) { + this.initialBookmark = hash; + } else if (!this.pdfHistory?.popStateInProgress) { + this.pdfLinkService.setHash(hash); + } +} +function onPageNumberChanged(evt) { + const { + pdfViewer + } = this; + if (evt.value !== "") { + this.pdfLinkService.goToPage(evt.value); + } + if (evt.value !== pdfViewer.currentPageNumber.toString() && evt.value !== pdfViewer.currentPageLabel) { + this.toolbar?.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel); + } +} +function onImageAltTextSettings() { + this.imageAltTextSettings?.open({ + enableGuessAltText: AppOptions.get("enableGuessAltText"), + enableNewAltTextWhenAddingImage: AppOptions.get("enableNewAltTextWhenAddingImage") + }); +} +function onFindFromUrlHash(evt) { + this.eventBus.dispatch("find", { + source: evt.source, + type: "", + query: evt.query, + caseSensitive: false, + entireWord: false, + highlightAll: true, + findPrevious: false, + matchDiacritics: true + }); +} +function onUpdateFindMatchesCount({ + matchesCount +}) { + if (this.supportsIntegratedFind) { + this.externalServices.updateFindMatchesCount(matchesCount); + } else { + this.findBar?.updateResultsCount(matchesCount); + } +} +function onUpdateFindControlState({ + state, + previous, + entireWord, + matchesCount, + rawQuery +}) { + if (this.supportsIntegratedFind) { + this.externalServices.updateFindControlState({ + result: state, + findPrevious: previous, + entireWord, + matchesCount, + rawQuery + }); + } else { + this.findBar?.updateUIState(state, previous, matchesCount); + } +} +function onScaleChanging(evt) { + this.toolbar?.setPageScale(evt.presetValue, evt.scale); + this.pdfViewer.update(); +} +function onRotationChanging(evt) { + if (this.pdfThumbnailViewer) { + this.pdfThumbnailViewer.pagesRotation = evt.pagesRotation; + } + this.forceRendering(); + this.pdfViewer.currentPageNumber = evt.pageNumber; +} +function onPageChanging({ + pageNumber, + pageLabel +}) { + this.toolbar?.setPageNumber(pageNumber, pageLabel); + this.secondaryToolbar?.setPageNumber(pageNumber); + if (this.viewsManager?.visibleView === SidebarView.THUMBS) { + this.pdfThumbnailViewer?.scrollThumbnailIntoView(pageNumber); + } + const currentPage = this.pdfViewer.getPageView(pageNumber - 1); + this.toolbar?.updateLoadingIndicatorState(currentPage?.renderingState === RenderingStates.RUNNING); +} +function onWheel(evt) { + const { + pdfViewer, + supportsMouseWheelZoomCtrlKey, + supportsMouseWheelZoomMetaKey, + supportsPinchToZoom + } = this; + if (pdfViewer.isInPresentationMode) { + return; + } + const deltaMode = evt.deltaMode; + let scaleFactor = Math.exp(-evt.deltaY / 100); + const isBuiltInMac = false; + const isPinchToZoom = evt.ctrlKey && !this._isCtrlKeyDown && deltaMode === WheelEvent.DOM_DELTA_PIXEL && evt.deltaX === 0 && (Math.abs(scaleFactor - 1) < 0.05 || isBuiltInMac) && evt.deltaZ === 0; + const origin = [evt.clientX, evt.clientY]; + if (isPinchToZoom || evt.ctrlKey && supportsMouseWheelZoomCtrlKey || evt.metaKey && supportsMouseWheelZoomMetaKey) { + evt.preventDefault(); + if (this._isScrolling || document.visibilityState === "hidden" || this.overlayManager.active) { + return; + } + if (isPinchToZoom && supportsPinchToZoom) { + scaleFactor = this._accumulateFactor(pdfViewer.currentScale, scaleFactor, "_wheelUnusedFactor"); + this.updateZoom(null, scaleFactor, origin); + } else { + const delta = normalizeWheelEventDirection(evt); + let ticks = 0; + if (deltaMode === WheelEvent.DOM_DELTA_LINE || deltaMode === WheelEvent.DOM_DELTA_PAGE) { + ticks = Math.abs(delta) >= 1 ? Math.sign(delta) : this._accumulateTicks(delta, "_wheelUnusedTicks"); + } else { + const PIXELS_PER_LINE_SCALE = 30; + ticks = this._accumulateTicks(delta / PIXELS_PER_LINE_SCALE, "_wheelUnusedTicks"); + } + this.updateZoom(ticks, null, origin); + } + } +} +function closeSecondaryToolbar({ + target +}) { + if (!this.secondaryToolbar?.isOpen) { + return; + } + const { + toolbar, + secondaryToolbar + } = this.appConfig; + if (this.pdfViewer.containsElement(target) || toolbar?.container.contains(target) && !secondaryToolbar?.toolbar.contains(target) && !secondaryToolbar?.toggleButton.contains(target)) { + this.secondaryToolbar.close(); + } +} +function closeEditorUndoBar(evt) { + if (!this.editorUndoBar?.isOpen) { + return; + } + if (this.appConfig.secondaryToolbar?.toolbar.contains(evt.target)) { + this.editorUndoBar.hide(); + } +} +function onClick(evt) { + closeSecondaryToolbar.call(this, evt); + closeEditorUndoBar.call(this, evt); +} +function onKeyUp(evt) { + if (evt.key === "Control") { + this._isCtrlKeyDown = false; + } +} +function onKeyDown(evt) { + this._isCtrlKeyDown = evt.key === "Control"; + if (this.editorUndoBar?.isOpen && evt.keyCode !== 9 && evt.keyCode !== 16 && !((evt.keyCode === 13 || evt.keyCode === 32) && getActiveOrFocusedElement() === this.appConfig.editorUndoBar.undoButton)) { + this.editorUndoBar.hide(); + } + if (this.overlayManager.active) { + return; + } + const { + eventBus, + pdfViewer + } = this; + const isViewerInPresentationMode = pdfViewer.isInPresentationMode; + let handled = false, + ensureViewerFocused = false; + const cmd = (evt.ctrlKey ? 1 : 0) | (evt.altKey ? 2 : 0) | (evt.shiftKey ? 4 : 0) | (evt.metaKey ? 8 : 0); + if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) { + switch (evt.keyCode) { + case 70: + if (!this.supportsIntegratedFind && !evt.shiftKey) { + this.findBar?.open(); + handled = true; + } + break; + case 71: + if (!this.supportsIntegratedFind) { + const { + state + } = this.findController; + if (state) { + const newState = { + source: window, + type: "again", + findPrevious: cmd === 5 || cmd === 12 + }; + eventBus.dispatch("find", { + ...state, + ...newState + }); + } + handled = true; + } + break; + case 61: + case 107: + case 187: + case 171: + this.zoomIn(); + handled = true; + break; + case 173: + case 109: + case 189: + this.zoomOut(); + handled = true; + break; + case 48: + case 96: + if (!isViewerInPresentationMode) { + setTimeout(() => { + this.zoomReset(); + }); + handled = false; + } + break; + case 38: + if (isViewerInPresentationMode || this.page > 1) { + this.page = 1; + handled = true; + ensureViewerFocused = true; + } + break; + case 40: + if (isViewerInPresentationMode || this.page < this.pagesCount) { + this.page = this.pagesCount; + handled = true; + ensureViewerFocused = true; + } + break; + } + } + if (cmd === 1 || cmd === 8) { + switch (evt.keyCode) { + case 83: + eventBus.dispatch("download", { + source: window + }); + handled = true; + break; + case 79: + { + eventBus.dispatch("openfile", { + source: window + }); + handled = true; + } + break; + } + } + if (cmd === 3 || cmd === 10) { + switch (evt.keyCode) { + case 80: + this.requestPresentationMode(); + handled = true; + this.externalServices.reportTelemetry({ + type: "buttons", + data: { + id: "presentationModeKeyboard" + } + }); + break; + case 71: + if (this.appConfig.toolbar) { + this.appConfig.toolbar.pageNumber.select(); + handled = true; + } + break; + } + } + if (handled) { + if (ensureViewerFocused && !isViewerInPresentationMode) { + pdfViewer.focus(); + } + evt.preventDefault(); + return; + } + const curElement = getActiveOrFocusedElement(); + const curElementTagName = curElement?.tagName.toUpperCase(); + if (curElementTagName === "INPUT" || curElementTagName === "TEXTAREA" || curElementTagName === "SELECT" || curElementTagName === "BUTTON" && evt.keyCode === 32 || curElement?.isContentEditable) { + if (evt.keyCode !== 27) { + return; + } + } + if (cmd === 0) { + let turnPage = 0, + turnOnlyIfPageFit = false; + switch (evt.keyCode) { + case 38: + if (this.supportsCaretBrowsingMode) { + this.moveCaret(true, false); + handled = true; + break; + } + case 33: + if (pdfViewer.isVerticalScrollbarEnabled) { + turnOnlyIfPageFit = true; + } + turnPage = -1; + break; + case 8: + if (!isViewerInPresentationMode) { + turnOnlyIfPageFit = true; + } + turnPage = -1; + break; + case 37: + if (this.supportsCaretBrowsingMode) { + return; + } + if (pdfViewer.isHorizontalScrollbarEnabled) { + turnOnlyIfPageFit = true; + } + case 75: + case 80: + turnPage = -1; + break; + case 27: + if (this.secondaryToolbar?.isOpen) { + this.secondaryToolbar.close(); + handled = true; + } + if (!this.supportsIntegratedFind && this.findBar?.opened) { + this.findBar.close(); + handled = true; + } + break; + case 40: + if (this.supportsCaretBrowsingMode) { + this.moveCaret(false, false); + handled = true; + break; + } + case 34: + if (pdfViewer.isVerticalScrollbarEnabled) { + turnOnlyIfPageFit = true; + } + turnPage = 1; + break; + case 32: + if (!isViewerInPresentationMode) { + turnOnlyIfPageFit = true; + } + turnPage = 1; + break; + case 39: + if (this.supportsCaretBrowsingMode) { + return; + } + if (pdfViewer.isHorizontalScrollbarEnabled) { + turnOnlyIfPageFit = true; + } + case 74: + case 78: + turnPage = 1; + break; + case 36: + if (isViewerInPresentationMode || this.page > 1) { + this.page = 1; + handled = true; + ensureViewerFocused = true; + } + break; + case 35: + if (isViewerInPresentationMode || this.page < this.pagesCount) { + this.page = this.pagesCount; + handled = true; + ensureViewerFocused = true; + } + break; + case 83: + this.pdfCursorTools?.switchTool(CursorTool.SELECT); + break; + case 72: + this.pdfCursorTools?.switchTool(CursorTool.HAND); + break; + case 82: + this.rotatePages(90); + break; + case 115: + this.viewsManager?.toggle(); + break; + } + if (turnPage !== 0 && (!turnOnlyIfPageFit || pdfViewer.currentScaleValue === "page-fit")) { + if (turnPage > 0) { + pdfViewer.nextPage(); + } else { + pdfViewer.previousPage(); + } + handled = true; + } + } + if (cmd === 4) { + switch (evt.keyCode) { + case 32: + if (!isViewerInPresentationMode && pdfViewer.currentScaleValue !== "page-fit") { + break; + } + pdfViewer.previousPage(); + handled = true; + break; + case 38: + this.moveCaret(true, true); + handled = true; + break; + case 40: + this.moveCaret(false, true); + handled = true; + break; + case 82: + this.rotatePages(-90); + break; + } + } + if (!handled && !isViewerInPresentationMode) { + if (evt.keyCode >= 33 && evt.keyCode <= 40 || evt.keyCode === 32 && curElementTagName !== "BUTTON") { + ensureViewerFocused = true; + } + } + if (ensureViewerFocused && !pdfViewer.containsElement(curElement)) { + pdfViewer.focus(); + } + if (handled) { + evt.preventDefault(); + } +} +function beforeUnload(evt) { + evt.preventDefault(); + evt.returnValue = ""; + return false; +} + +;// ./web/viewer.js + + + + + +const AppConstants = { + LinkTarget: LinkTarget, + RenderingStates: RenderingStates, + ScrollMode: ScrollMode, + SpreadMode: SpreadMode +}; +window.PDFViewerApplication = PDFViewerApplication; +window.PDFViewerApplicationConstants = AppConstants; +window.PDFViewerApplicationOptions = AppOptions; +function getViewerConfiguration() { + return { + appContainer: document.body, + principalContainer: document.getElementById("mainContainer"), + mainContainer: document.getElementById("viewerContainer"), + viewerContainer: document.getElementById("viewer"), + viewerAlert: document.getElementById("viewer-alert"), + toolbar: { + container: document.getElementById("toolbarContainer"), + numPages: document.getElementById("numPages"), + pageNumber: document.getElementById("pageNumber"), + scaleSelect: document.getElementById("scaleSelect"), + customScaleOption: document.getElementById("customScaleOption"), + previous: document.getElementById("previous"), + next: document.getElementById("next"), + zoomIn: document.getElementById("zoomInButton"), + zoomOut: document.getElementById("zoomOutButton"), + print: document.getElementById("printButton"), + editorCommentButton: document.getElementById("editorCommentButton"), + editorCommentParamsToolbar: document.getElementById("editorCommentParamsToolbar"), + editorFreeTextButton: document.getElementById("editorFreeTextButton"), + editorFreeTextParamsToolbar: document.getElementById("editorFreeTextParamsToolbar"), + editorHighlightButton: document.getElementById("editorHighlightButton"), + editorHighlightParamsToolbar: document.getElementById("editorHighlightParamsToolbar"), + editorHighlightColorPicker: document.getElementById("editorHighlightColorPicker"), + editorInkButton: document.getElementById("editorInkButton"), + editorInkParamsToolbar: document.getElementById("editorInkParamsToolbar"), + editorStampButton: document.getElementById("editorStampButton"), + editorStampParamsToolbar: document.getElementById("editorStampParamsToolbar"), + editorSignatureButton: document.getElementById("editorSignatureButton"), + editorSignatureParamsToolbar: document.getElementById("editorSignatureParamsToolbar"), + download: document.getElementById("downloadButton") + }, + secondaryToolbar: { + toolbar: document.getElementById("secondaryToolbar"), + toggleButton: document.getElementById("secondaryToolbarToggleButton"), + presentationModeButton: document.getElementById("presentationMode"), + openFileButton: document.getElementById("secondaryOpenFile"), + printButton: document.getElementById("secondaryPrint"), + downloadButton: document.getElementById("secondaryDownload"), + viewBookmarkButton: document.getElementById("viewBookmark"), + firstPageButton: document.getElementById("firstPage"), + lastPageButton: document.getElementById("lastPage"), + pageRotateCwButton: document.getElementById("pageRotateCw"), + pageRotateCcwButton: document.getElementById("pageRotateCcw"), + cursorSelectToolButton: document.getElementById("cursorSelectTool"), + cursorHandToolButton: document.getElementById("cursorHandTool"), + scrollPageButton: document.getElementById("scrollPage"), + scrollVerticalButton: document.getElementById("scrollVertical"), + scrollHorizontalButton: document.getElementById("scrollHorizontal"), + scrollWrappedButton: document.getElementById("scrollWrapped"), + spreadNoneButton: document.getElementById("spreadNone"), + spreadOddButton: document.getElementById("spreadOdd"), + spreadEvenButton: document.getElementById("spreadEven"), + imageAltTextSettingsButton: document.getElementById("imageAltTextSettings"), + imageAltTextSettingsSeparator: document.getElementById("imageAltTextSettingsSeparator"), + documentPropertiesButton: document.getElementById("documentProperties") + }, + viewsManager: { + outerContainer: document.getElementById("outerContainer"), + toggleButton: document.getElementById("viewsManagerToggleButton"), + sidebarContainer: document.getElementById("viewsManager"), + resizer: document.getElementById("viewsManagerResizer"), + thumbnailButton: document.getElementById("thumbnailsViewMenu"), + outlineButton: document.getElementById("outlinesViewMenu"), + attachmentsButton: document.getElementById("attachmentsViewMenu"), + layersButton: document.getElementById("layersViewMenu"), + viewsManagerSelectorButton: document.getElementById("viewsManagerSelectorButton"), + viewsManagerSelectorOptions: document.getElementById("viewsManagerSelectorOptions"), + thumbnailsView: document.getElementById("thumbnailsView"), + outlinesView: document.getElementById("outlinesView"), + attachmentsView: document.getElementById("attachmentsView"), + layersView: document.getElementById("layersView"), + viewsManagerAddFileButton: document.getElementById("viewsManagerAddFileButton"), + viewsManagerCurrentOutlineButton: document.getElementById("viewsManagerCurrentOutlineButton"), + viewsManagerHeaderLabel: document.getElementById("viewsManagerHeaderLabel"), + viewsManagerStatus: document.getElementById("viewsManagerStatus"), + manageMenu: { + button: document.getElementById("viewsManagerStatusActionButton"), + menu: document.getElementById("viewsManagerStatusActionOptions"), + copy: document.getElementById("viewsManagerStatusActionCopy"), + cut: document.getElementById("viewsManagerStatusActionCut"), + delete: document.getElementById("viewsManagerStatusActionDelete"), + saveAs: document.getElementById("viewsManagerStatusActionSaveAs") + } + }, + findBar: { + bar: document.getElementById("findbar"), + toggleButton: document.getElementById("viewFindButton"), + findField: document.getElementById("findInput"), + highlightAllCheckbox: document.getElementById("findHighlightAll"), + caseSensitiveCheckbox: document.getElementById("findMatchCase"), + matchDiacriticsCheckbox: document.getElementById("findMatchDiacritics"), + entireWordCheckbox: document.getElementById("findEntireWord"), + findMsg: document.getElementById("findMsg"), + findResultsCount: document.getElementById("findResultsCount"), + findPreviousButton: document.getElementById("findPreviousButton"), + findNextButton: document.getElementById("findNextButton") + }, + passwordOverlay: { + dialog: document.getElementById("passwordDialog"), + label: document.getElementById("passwordText"), + input: document.getElementById("password"), + submitButton: document.getElementById("passwordSubmit"), + cancelButton: document.getElementById("passwordCancel") + }, + documentProperties: { + dialog: document.getElementById("documentPropertiesDialog"), + closeButton: document.getElementById("documentPropertiesClose"), + fields: { + fileName: document.getElementById("fileNameField"), + fileSize: document.getElementById("fileSizeField"), + title: document.getElementById("titleField"), + author: document.getElementById("authorField"), + subject: document.getElementById("subjectField"), + keywords: document.getElementById("keywordsField"), + creationDate: document.getElementById("creationDateField"), + modificationDate: document.getElementById("modificationDateField"), + creator: document.getElementById("creatorField"), + producer: document.getElementById("producerField"), + version: document.getElementById("versionField"), + pageCount: document.getElementById("pageCountField"), + pageSize: document.getElementById("pageSizeField"), + linearized: document.getElementById("linearizedField") + } + }, + altTextDialog: { + dialog: document.getElementById("altTextDialog"), + optionDescription: document.getElementById("descriptionButton"), + optionDecorative: document.getElementById("decorativeButton"), + textarea: document.getElementById("descriptionTextarea"), + cancelButton: document.getElementById("altTextCancel"), + saveButton: document.getElementById("altTextSave") + }, + newAltTextDialog: { + dialog: document.getElementById("newAltTextDialog"), + title: document.getElementById("newAltTextTitle"), + descriptionContainer: document.getElementById("newAltTextDescriptionContainer"), + textarea: document.getElementById("newAltTextDescriptionTextarea"), + disclaimer: document.getElementById("newAltTextDisclaimer"), + learnMore: document.getElementById("newAltTextLearnMore"), + imagePreview: document.getElementById("newAltTextImagePreview"), + createAutomatically: document.getElementById("newAltTextCreateAutomatically"), + createAutomaticallyButton: document.getElementById("newAltTextCreateAutomaticallyButton"), + downloadModel: document.getElementById("newAltTextDownloadModel"), + downloadModelDescription: document.getElementById("newAltTextDownloadModelDescription"), + error: document.getElementById("newAltTextError"), + errorCloseButton: document.getElementById("newAltTextCloseButton"), + cancelButton: document.getElementById("newAltTextCancel"), + notNowButton: document.getElementById("newAltTextNotNow"), + saveButton: document.getElementById("newAltTextSave") + }, + altTextSettingsDialog: { + dialog: document.getElementById("altTextSettingsDialog"), + createModelButton: document.getElementById("createModelButton"), + learnMore: document.getElementById("altTextSettingsLearnMore"), + showAltTextDialogButton: document.getElementById("showAltTextDialogButton"), + altTextSettingsCloseButton: document.getElementById("altTextSettingsCloseButton"), + closeButton: document.getElementById("altTextSettingsCloseButton") + }, + addSignatureDialog: { + dialog: document.getElementById("addSignatureDialog"), + panels: document.getElementById("addSignatureActionContainer"), + typeButton: document.getElementById("addSignatureTypeButton"), + typeInput: document.getElementById("addSignatureTypeInput"), + drawButton: document.getElementById("addSignatureDrawButton"), + drawSVG: document.getElementById("addSignatureDraw"), + drawPlaceholder: document.getElementById("addSignatureDrawPlaceholder"), + drawThickness: document.getElementById("addSignatureDrawThickness"), + imageButton: document.getElementById("addSignatureImageButton"), + imageSVG: document.getElementById("addSignatureImage"), + imagePlaceholder: document.getElementById("addSignatureImagePlaceholder"), + imagePicker: document.getElementById("addSignatureFilePicker"), + imagePickerLink: document.getElementById("addSignatureImageBrowse"), + description: document.getElementById("addSignatureDescription"), + clearButton: document.getElementById("clearSignatureButton"), + saveContainer: document.getElementById("addSignatureSaveContainer"), + saveCheckbox: document.getElementById("addSignatureSaveCheckbox"), + errorBar: document.getElementById("addSignatureError"), + errorTitle: document.getElementById("addSignatureErrorTitle"), + errorDescription: document.getElementById("addSignatureErrorDescription"), + errorCloseButton: document.getElementById("addSignatureErrorCloseButton"), + cancelButton: document.getElementById("addSignatureCancelButton"), + addButton: document.getElementById("addSignatureAddButton") + }, + editSignatureDialog: { + dialog: document.getElementById("editSignatureDescriptionDialog"), + description: document.getElementById("editSignatureDescription"), + editSignatureView: document.getElementById("editSignatureView"), + cancelButton: document.getElementById("editSignatureCancelButton"), + updateButton: document.getElementById("editSignatureUpdateButton") + }, + annotationEditorParams: { + editorCommentsSidebar: document.getElementById("editorCommentsSidebar"), + editorCommentsSidebarCount: document.getElementById("editorCommentsSidebarCount"), + editorCommentsSidebarTitle: document.getElementById("editorCommentsSidebarTitle"), + editorCommentsSidebarCloseButton: document.getElementById("editorCommentsSidebarCloseButton"), + editorCommentsSidebarList: document.getElementById("editorCommentsSidebarList"), + editorCommentsSidebarResizer: document.getElementById("editorCommentsSidebarResizer"), + editorFreeTextFontSize: document.getElementById("editorFreeTextFontSize"), + editorFreeTextColor: document.getElementById("editorFreeTextColor"), + editorInkColor: document.getElementById("editorInkColor"), + editorInkThickness: document.getElementById("editorInkThickness"), + editorInkOpacity: document.getElementById("editorInkOpacity"), + editorStampAddImage: document.getElementById("editorStampAddImage"), + editorSignatureAddSignature: document.getElementById("editorSignatureAddSignature"), + editorFreeHighlightThickness: document.getElementById("editorFreeHighlightThickness"), + editorHighlightShowAll: document.getElementById("editorHighlightShowAll") + }, + printContainer: document.getElementById("printContainer"), + editorUndoBar: { + container: document.getElementById("editorUndoBar"), + message: document.getElementById("editorUndoBarMessage"), + undoButton: document.getElementById("editorUndoBarUndoButton"), + closeButton: document.getElementById("editorUndoBarCloseButton") + }, + editCommentDialog: { + dialog: document.getElementById("commentManagerDialog"), + toolbar: document.getElementById("commentManagerToolbar"), + title: document.getElementById("commentManagerTitle"), + textInput: document.getElementById("commentManagerTextInput"), + cancelButton: document.getElementById("commentManagerCancelButton"), + saveButton: document.getElementById("commentManagerSaveButton") + } + }; +} +function webViewerLoad() { + const config = getViewerConfiguration(); + const event = new CustomEvent("webviewerloaded", { + bubbles: true, + cancelable: true, + detail: { + source: window + } + }); + try { + parent.document.dispatchEvent(event); + } catch (ex) { + console.error("webviewerloaded:", ex); + document.dispatchEvent(event); + } + PDFViewerApplication.run(config); +} +document.blockUnblockOnload?.(true); +if (document.readyState === "interactive" || document.readyState === "complete") { + webViewerLoad(); +} else { + document.addEventListener("DOMContentLoaded", webViewerLoad, true); +} + +export { PDFViewerApplication, AppConstants as PDFViewerApplicationConstants, AppOptions as PDFViewerApplicationOptions }; + +//# sourceMappingURL=viewer.mjs.map \ No newline at end of file diff --git a/packages/pdfjs-viewer/viewer/viewer.mjs.map b/packages/pdfjs-viewer/viewer/viewer.mjs.map new file mode 100644 index 0000000000..5942a6411c --- /dev/null +++ b/packages/pdfjs-viewer/viewer/viewer.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"viewer.mjs","mappings":"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","sources":["webpack://pdf.js/webpack/bootstrap","webpack://pdf.js/webpack/runtime/define property getters","webpack://pdf.js/webpack/runtime/hasOwnProperty shorthand","webpack://pdf.js/./web/pdfjs.js","webpack://pdf.js/./web/ui_utils.js","webpack://pdf.js/./web/app_options.js","webpack://pdf.js/./web/pdf_link_service.js","webpack://pdf.js/./web/event_utils.js","webpack://pdf.js/./web/external_services.js","webpack://pdf.js/./web/preferences.js","webpack://pdf.js/./node_modules/@fluent/bundle/esm/types.js","webpack://pdf.js/./node_modules/@fluent/bundle/esm/resolver.js","webpack://pdf.js/./node_modules/@fluent/bundle/esm/scope.js","webpack://pdf.js/./node_modules/@fluent/bundle/esm/builtins.js","webpack://pdf.js/./node_modules/@fluent/bundle/esm/memoizer.js","webpack://pdf.js/./node_modules/@fluent/bundle/esm/bundle.js","webpack://pdf.js/./node_modules/@fluent/bundle/esm/resource.js","webpack://pdf.js/./node_modules/@fluent/bundle/esm/index.js","webpack://pdf.js/./node_modules/@fluent/dom/esm/overlay.js","webpack://pdf.js/./node_modules/cached-iterable/src/cached_iterable.mjs","webpack://pdf.js/./node_modules/cached-iterable/src/cached_sync_iterable.mjs","webpack://pdf.js/./node_modules/cached-iterable/src/cached_async_iterable.mjs","webpack://pdf.js/./node_modules/cached-iterable/src/index.mjs","webpack://pdf.js/./node_modules/@fluent/dom/esm/localization.js","webpack://pdf.js/./node_modules/@fluent/dom/esm/dom_localization.js","webpack://pdf.js/./node_modules/@fluent/dom/esm/index.js","webpack://pdf.js/./web/l10n.js","webpack://pdf.js/./web/genericl10n.js","webpack://pdf.js/./web/generic_scripting.js","webpack://pdf.js/./web/generic_signature_storage.js","webpack://pdf.js/./web/genericcom.js","webpack://pdf.js/./web/new_alt_text_manager.js","webpack://pdf.js/./web/alt_text_manager.js","webpack://pdf.js/./web/annotation_editor_params.js","webpack://pdf.js/./web/caret_browsing.js","webpack://pdf.js/./web/sidebar.js","webpack://pdf.js/./web/comment_manager.js","webpack://pdf.js/./web/base_download_manager.js","webpack://pdf.js/./web/download_manager.js","webpack://pdf.js/./web/editor_undo_bar.js","webpack://pdf.js/./web/overlay_manager.js","webpack://pdf.js/./web/password_prompt.js","webpack://pdf.js/./web/base_tree_viewer.js","webpack://pdf.js/./web/pdf_attachment_viewer.js","webpack://pdf.js/./web/grab_to_pan.js","webpack://pdf.js/./web/pdf_cursor_tools.js","webpack://pdf.js/./web/pdf_document_properties.js","webpack://pdf.js/./web/pdf_find_utils.js","webpack://pdf.js/./web/pdf_find_controller.js","webpack://pdf.js/./web/pdf_find_bar.js","webpack://pdf.js/./web/pdf_history.js","webpack://pdf.js/./web/pdf_layer_viewer.js","webpack://pdf.js/./web/pdf_outline_viewer.js","webpack://pdf.js/./web/pdf_presentation_mode.js","webpack://pdf.js/./web/xfa_layer_builder.js","webpack://pdf.js/./web/print_utils.js","webpack://pdf.js/./web/pdf_print_service.js","webpack://pdf.js/./web/renderable_view.js","webpack://pdf.js/./web/pdf_rendering_queue.js","webpack://pdf.js/./web/pdf_scripting_manager.js","webpack://pdf.js/./web/pdf_text_extractor.js","webpack://pdf.js/./web/menu.js","webpack://pdf.js/./web/pdf_thumbnail_view.js","webpack://pdf.js/./web/pdf_thumbnail_viewer.js","webpack://pdf.js/./web/annotation_editor_layer_builder.js","webpack://pdf.js/./web/annotation_layer_builder.js","webpack://pdf.js/./web/autolinker.js","webpack://pdf.js/./web/base_pdf_page_view.js","webpack://pdf.js/./web/draw_layer_builder.js","webpack://pdf.js/./web/pdf_page_detail_view.js","webpack://pdf.js/./web/struct_tree_layer_builder.js","webpack://pdf.js/./web/text_accessibility.js","webpack://pdf.js/./web/text_highlighter.js","webpack://pdf.js/./web/text_layer_builder.js","webpack://pdf.js/./web/pdf_page_view.js","webpack://pdf.js/./web/pdf_viewer.js","webpack://pdf.js/./web/secondary_toolbar.js","webpack://pdf.js/./web/signature_manager.js","webpack://pdf.js/./web/toolbar.js","webpack://pdf.js/./web/view_history.js","webpack://pdf.js/./web/views_manager.js","webpack://pdf.js/./web/app.js","webpack://pdf.js/./web/viewer.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","/* Copyright 2016 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst {\n AbortException,\n AnnotationEditorLayer,\n AnnotationEditorParamsType,\n AnnotationEditorType,\n AnnotationEditorUIManager,\n AnnotationLayer,\n AnnotationMode,\n AnnotationType,\n applyOpacity,\n build,\n ColorPicker,\n createValidAbsoluteUrl,\n CSSConstants,\n DOMSVGFactory,\n DrawLayer,\n FeatureTest,\n fetchData,\n findContrastColor,\n getDocument,\n getFilenameFromUrl,\n getPdfFilenameFromUrl,\n getRGB,\n getUuid,\n getXfaPageViewport,\n GlobalWorkerOptions,\n ImageKind,\n InvalidPDFException,\n isDataScheme,\n isPdfFile,\n isValidExplicitDest,\n makeArr,\n makeMap,\n makeObj,\n MathClamp,\n noContextMenu,\n normalizeUnicode,\n OPS,\n OutputScale,\n PasswordResponses,\n PDFDataRangeTransport,\n PDFDateString,\n PDFWorker,\n PermissionFlag,\n PixelsPerInch,\n RenderingCancelledException,\n renderRichText,\n ResponseException,\n setLayerDimensions,\n shadow,\n SignatureExtractor,\n stopEvent,\n SupportedImageMimeTypes,\n TextLayer,\n TouchManager,\n updateUrlHash,\n Util,\n VerbosityLevel,\n version,\n XfaLayer,\n} = globalThis.pdfjsLib;\n\nexport {\n AbortException,\n AnnotationEditorLayer,\n AnnotationEditorParamsType,\n AnnotationEditorType,\n AnnotationEditorUIManager,\n AnnotationLayer,\n AnnotationMode,\n AnnotationType,\n applyOpacity,\n build,\n ColorPicker,\n createValidAbsoluteUrl,\n CSSConstants,\n DOMSVGFactory,\n DrawLayer,\n FeatureTest,\n fetchData,\n findContrastColor,\n getDocument,\n getFilenameFromUrl,\n getPdfFilenameFromUrl,\n getRGB,\n getUuid,\n getXfaPageViewport,\n GlobalWorkerOptions,\n ImageKind,\n InvalidPDFException,\n isDataScheme,\n isPdfFile,\n isValidExplicitDest,\n makeArr,\n makeMap,\n makeObj,\n MathClamp,\n noContextMenu,\n normalizeUnicode,\n OPS,\n OutputScale,\n PasswordResponses,\n PDFDataRangeTransport,\n PDFDateString,\n PDFWorker,\n PermissionFlag,\n PixelsPerInch,\n RenderingCancelledException,\n renderRichText,\n ResponseException,\n setLayerDimensions,\n shadow,\n SignatureExtractor,\n stopEvent,\n SupportedImageMimeTypes,\n TextLayer,\n TouchManager,\n updateUrlHash,\n Util,\n VerbosityLevel,\n version,\n XfaLayer,\n};\n","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MathClamp } from \"pdfjs-lib\";\n\nconst DEFAULT_SCALE_VALUE = \"auto\";\nconst DEFAULT_SCALE = 1.0;\nconst DEFAULT_SCALE_DELTA = 1.1;\nconst MIN_SCALE = 0.1;\nconst MAX_SCALE = 10.0;\nconst UNKNOWN_SCALE = 0;\nconst MAX_AUTO_SCALE = 1.25;\nconst SCROLLBAR_PADDING = 40;\nconst VERTICAL_PADDING = 5;\n\nconst PresentationModeState = {\n UNKNOWN: 0,\n NORMAL: 1,\n CHANGING: 2,\n FULLSCREEN: 3,\n};\n\nconst SidebarView = {\n UNKNOWN: -1,\n NONE: 0,\n THUMBS: 1, // Default value.\n OUTLINE: 2,\n ATTACHMENTS: 3,\n LAYERS: 4,\n};\n\nconst TextLayerMode = {\n DISABLE: 0,\n ENABLE: 1,\n ENABLE_PERMISSIONS: 2,\n};\n\nconst ScrollMode = {\n UNKNOWN: -1,\n VERTICAL: 0, // Default value.\n HORIZONTAL: 1,\n WRAPPED: 2,\n PAGE: 3,\n};\n\nconst SpreadMode = {\n UNKNOWN: -1,\n NONE: 0, // Default value.\n ODD: 1,\n EVEN: 2,\n};\n\nconst CursorTool = {\n SELECT: 0, // The default value.\n HAND: 1,\n ZOOM: 2,\n};\n\n// Used by `PDFViewerApplication`, and by the API unit-tests.\nconst AutoPrintRegExp = /\\bprint\\s*\\(/;\n\n/**\n * Scrolls specified element into view of its parent.\n * @param {HTMLElement} element - The element to be visible.\n * @param {Object} [spot] - An object with optional top and left properties,\n * specifying the offset from the top left edge.\n * @param {number} [spot.left]\n * @param {number} [spot.top]\n * @param {boolean} [scrollMatches] - When scrolling search results into view,\n * ignore elements that either: Contains marked content identifiers,\n * or have the CSS-rule `overflow: hidden;` set. The default value is `false`.\n */\nfunction scrollIntoView(element, spot, scrollMatches = false) {\n // Assuming offsetParent is available (it's not available when viewer is in\n // hidden iframe or object). We have to scroll: if the offsetParent is not set\n // producing the error. See also animationStarted.\n let parent = element.offsetParent;\n if (!parent) {\n console.error(\"offsetParent is not set -- cannot scroll\");\n return;\n }\n let offsetY = element.offsetTop + element.clientTop;\n let offsetX = element.offsetLeft + element.clientLeft;\n while (\n (parent.clientHeight === parent.scrollHeight &&\n parent.clientWidth === parent.scrollWidth) ||\n (scrollMatches &&\n (parent.classList.contains(\"markedContent\") ||\n getComputedStyle(parent).overflow === \"hidden\"))\n ) {\n offsetY += parent.offsetTop;\n offsetX += parent.offsetLeft;\n\n parent = parent.offsetParent;\n if (!parent) {\n return; // no need to scroll\n }\n }\n if (spot) {\n if (spot.top !== undefined) {\n offsetY += spot.top;\n }\n if (spot.left !== undefined) {\n if (scrollMatches) {\n const elementWidth = element.getBoundingClientRect().width;\n const padding = MathClamp(\n (parent.clientWidth - elementWidth) / 2,\n 20,\n 400\n );\n offsetX += spot.left - padding;\n } else {\n offsetX += spot.left;\n }\n parent.scrollLeft = offsetX;\n }\n }\n parent.scrollTop = offsetY;\n}\n\n/**\n * Helper function to start monitoring the scroll event and converting them into\n * PDF.js friendly one: with scroll debounce and scroll direction.\n */\nfunction watchScroll(viewAreaElement, callback, abortSignal = undefined) {\n const debounceScroll = function (evt) {\n if (rAF) {\n return;\n }\n // schedule an invocation of scroll for next animation frame.\n rAF = window.requestAnimationFrame(function viewAreaElementScrolled() {\n rAF = null;\n\n const currentX = viewAreaElement.scrollLeft;\n const lastX = state.lastX;\n if (currentX !== lastX) {\n state.right = currentX > lastX;\n }\n state.lastX = currentX;\n const currentY = viewAreaElement.scrollTop;\n const lastY = state.lastY;\n if (currentY !== lastY) {\n state.down = currentY > lastY;\n }\n state.lastY = currentY;\n callback(state);\n });\n };\n\n const state = {\n right: true,\n down: true,\n lastX: viewAreaElement.scrollLeft,\n lastY: viewAreaElement.scrollTop,\n _eventHandler: debounceScroll,\n };\n\n let rAF = null;\n viewAreaElement.addEventListener(\"scroll\", debounceScroll, {\n useCapture: true,\n signal: abortSignal,\n });\n abortSignal?.addEventListener(\n \"abort\",\n () => window.cancelAnimationFrame(rAF),\n { once: true }\n );\n return state;\n}\n\n/**\n * Helper function to parse query string (e.g. ?param1=value¶m2=...).\n * @param {string} query\n * @returns {Map}\n */\nfunction parseQueryString(query) {\n const params = new Map();\n for (const [key, value] of new URLSearchParams(query)) {\n params.set(key.toLowerCase(), value);\n }\n return params;\n}\n\nconst InvisibleCharsRegExp = /[\\x00-\\x1F]/g;\n\n/**\n * @param {string} str\n * @param {boolean} [replaceInvisible]\n */\nfunction removeNullCharacters(str, replaceInvisible = false) {\n if (!InvisibleCharsRegExp.test(str)) {\n return str;\n }\n if (replaceInvisible) {\n return str.replaceAll(InvisibleCharsRegExp, m => (m === \"\\x00\" ? \"\" : \" \"));\n }\n return str.replaceAll(\"\\x00\", \"\");\n}\n\n/**\n * Use binary search to find the index of the first item in a given array which\n * passes a given condition. The items are expected to be sorted in the sense\n * that if the condition is true for one item in the array, then it is also true\n * for all following items.\n *\n * @returns {number} Index of the first array element to pass the test,\n * or |items.length| if no such element exists.\n */\nfunction binarySearchFirstItem(items, condition, start = 0) {\n let minIndex = start;\n let maxIndex = items.length - 1;\n\n if (maxIndex < 0 || !condition(items[maxIndex])) {\n return items.length;\n }\n if (condition(items[minIndex])) {\n return minIndex;\n }\n\n while (minIndex < maxIndex) {\n const currentIndex = (minIndex + maxIndex) >> 1;\n const currentItem = items[currentIndex];\n if (condition(currentItem)) {\n maxIndex = currentIndex;\n } else {\n minIndex = currentIndex + 1;\n }\n }\n return minIndex; /* === maxIndex */\n}\n\n/**\n * Approximates float number as a fraction using Farey sequence (max order\n * of 8).\n * @param {number} x - Positive float number.\n * @returns {Array} Estimated fraction: the first array item is a numerator,\n * the second one is a denominator.\n * They are both natural numbers.\n */\nfunction approximateFraction(x) {\n // Fast paths for int numbers or their inversions.\n if (Math.floor(x) === x) {\n return [x, 1];\n }\n const xinv = 1 / x;\n const limit = 8;\n if (xinv > limit) {\n return [1, limit];\n } else if (Math.floor(xinv) === xinv) {\n return [1, xinv];\n }\n\n const x_ = x > 1 ? xinv : x;\n // a/b and c/d are neighbours in Farey sequence.\n let a = 0,\n b = 1,\n c = 1,\n d = 1;\n // Limiting search to order 8.\n while (true) {\n // Generating next term in sequence (order of q).\n const p = a + c,\n q = b + d;\n if (q > limit) {\n break;\n }\n if (x_ <= p / q) {\n c = p;\n d = q;\n } else {\n a = p;\n b = q;\n }\n }\n let result;\n // Select closest of the neighbours to x.\n if (x_ - a / b < c / d - x_) {\n result = x_ === x ? [a, b] : [b, a];\n } else {\n result = x_ === x ? [c, d] : [d, c];\n }\n return result;\n}\n\n/**\n * @param {number} x - A positive number to round to a multiple of `div`.\n * @param {number} div - A natural number.\n */\nfunction floorToDivide(x, div) {\n return x - (x % div);\n}\n\n/**\n * @typedef {Object} GetPageSizeInchesParameters\n * @property {number[]} view\n * @property {number} userUnit\n * @property {number} rotate\n */\n\n/**\n * @typedef {Object} PageSize\n * @property {number} width - In inches.\n * @property {number} height - In inches.\n */\n\n/**\n * Gets the size of the specified page, converted from PDF units to inches.\n * @param {GetPageSizeInchesParameters} params\n * @returns {PageSize}\n */\nfunction getPageSizeInches({ view, userUnit, rotate }) {\n const [x1, y1, x2, y2] = view;\n // We need to take the page rotation into account as well.\n const changeOrientation = rotate % 180 !== 0;\n\n const width = ((x2 - x1) / 72) * userUnit;\n const height = ((y2 - y1) / 72) * userUnit;\n\n return {\n width: changeOrientation ? height : width,\n height: changeOrientation ? width : height,\n };\n}\n\n/**\n * Helper function for getVisibleElements.\n *\n * @param {number} index - initial guess at the first visible element\n * @param {Array} views - array of pages, into which `index` is an index\n * @param {number} top - the top of the scroll pane\n * @returns {number} less than or equal to `index` that is definitely at or\n * before the first visible element in `views`, but not by too much. (Usually,\n * this will be the first element in the first partially visible row in\n * `views`, although sometimes it goes back one row further.)\n */\nfunction backtrackBeforeAllVisibleElements(index, views, top) {\n // binarySearchFirstItem's assumption is that the input is ordered, with only\n // one index where the conditions flips from false to true: [false ...,\n // true...]. With vertical scrolling and spreads, it is possible to have\n // [false ..., true, false, true ...]. With wrapped scrolling we can have a\n // similar sequence, with many more mixed true and false in the middle.\n //\n // So there is no guarantee that the binary search yields the index of the\n // first visible element. It could have been any of the other visible elements\n // that were preceded by a hidden element.\n\n // Of course, if either this element or the previous (hidden) element is also\n // the first element, there's nothing to worry about.\n if (index < 2) {\n return index;\n }\n\n // That aside, the possible cases are represented below.\n //\n // **** = fully hidden\n // A*B* = mix of partially visible and/or hidden pages\n // CDEF = fully visible\n //\n // (1) Binary search could have returned A, in which case we can stop.\n // (2) Binary search could also have returned B, in which case we need to\n // check the whole row.\n // (3) Binary search could also have returned C, in which case we need to\n // check the whole previous row.\n //\n // There's one other possibility:\n //\n // **** = fully hidden\n // ABCD = mix of fully and/or partially visible pages\n //\n // (4) Binary search could only have returned A.\n\n // Initially assume that we need to find the beginning of the current row\n // (case 1, 2, or 4), which means finding a page that is above the current\n // page's top. If the found page is partially visible, we're definitely not in\n // case 3, and this assumption is correct.\n let elt = views[index].div;\n let pageTop = elt.offsetTop + elt.clientTop;\n\n if (pageTop >= top) {\n // The found page is fully visible, so we're actually either in case 3 or 4,\n // and unfortunately we can't tell the difference between them without\n // scanning the entire previous row, so we just conservatively assume that\n // we do need to backtrack to that row. In both cases, the previous page is\n // in the previous row, so use its top instead.\n elt = views[index - 1].div;\n pageTop = elt.offsetTop + elt.clientTop;\n }\n\n // Now we backtrack to the first page that still has its bottom below\n // `pageTop`, which is the top of a page in the first visible row (unless\n // we're in case 4, in which case it's the row before that).\n // `index` is found by binary search, so the page at `index - 1` is\n // invisible and we can start looking for potentially visible pages from\n // `index - 2`. (However, if this loop terminates on its first iteration,\n // which is the case when pages are stacked vertically, `index` should remain\n // unchanged, so we use a distinct loop variable.)\n for (let i = index - 2; i >= 0; --i) {\n elt = views[i].div;\n if (elt.offsetTop + elt.clientTop + elt.clientHeight <= pageTop) {\n // We have reached the previous row, so stop now.\n // This loop is expected to terminate relatively quickly because the\n // number of pages per row is expected to be small.\n break;\n }\n index = i;\n }\n return index;\n}\n\n/**\n * @typedef {Object} GetVisibleElementsParameters\n * @property {HTMLElement} scrollEl - A container that can possibly scroll.\n * @property {Array} views - Objects with a `div` property that contains an\n * HTMLElement, which should all be descendants of `scrollEl` satisfying the\n * relevant layout assumptions.\n * @property {boolean} sortByVisibility - If `true`, the returned elements are\n * sorted in descending order of the percent of their padding box that is\n * visible. The default value is `false`.\n * @property {boolean} horizontal - If `true`, the elements are assumed to be\n * laid out horizontally instead of vertically. The default value is `false`.\n * @property {boolean} rtl - If `true`, the `scrollEl` container is assumed to\n * be in right-to-left mode. The default value is `false`.\n */\n\n/**\n * Generic helper to find out what elements are visible within a scroll pane.\n *\n * Well, pretty generic. There are some assumptions placed on the elements\n * referenced by `views`:\n * - If `horizontal`, no left of any earlier element is to the right of the\n * left of any later element.\n * - Otherwise, `views` can be split into contiguous rows where, within a row,\n * no top of any element is below the bottom of any other element, and\n * between rows, no bottom of any element in an earlier row is below the\n * top of any element in a later row.\n *\n * (Here, top, left, etc. all refer to the padding edge of the element in\n * question. For pages, that ends up being equivalent to the bounding box of the\n * rendering canvas. Earlier and later refer to index in `views`, not page\n * layout.)\n *\n * @param {GetVisibleElementsParameters} params\n * @returns {Object} `{ first, last, views: [{ id, x, y, view, percent }] }`\n */\nfunction getVisibleElements({\n scrollEl,\n views,\n sortByVisibility = false,\n horizontal = false,\n rtl = false,\n}) {\n const top = scrollEl.scrollTop,\n bottom = top + scrollEl.clientHeight;\n const left = scrollEl.scrollLeft,\n right = left + scrollEl.clientWidth;\n\n // Throughout this \"generic\" function, comments will assume we're working with\n // PDF document pages, which is the most important and complex case. In this\n // case, the visible elements we're actually interested is the page canvas,\n // which is contained in a wrapper which adds no padding/border/margin, which\n // is itself contained in `view.div` which adds no padding (but does add a\n // border). So, as specified in this function's doc comment, this function\n // does all of its work on the padding edge of the provided views, starting at\n // offsetLeft/Top (which includes margin) and adding clientLeft/Top (which is\n // the border). Adding clientWidth/Height gets us the bottom-right corner of\n // the padding edge.\n function isElementBottomAfterViewTop(view) {\n const element = view.div;\n const elementBottom =\n element.offsetTop + element.clientTop + element.clientHeight;\n return elementBottom > top;\n }\n function isElementNextAfterViewHorizontally(view) {\n const element = view.div;\n const elementLeft = element.offsetLeft + element.clientLeft;\n const elementRight = elementLeft + element.clientWidth;\n return rtl ? elementLeft < right : elementRight > left;\n }\n\n const visible = [],\n ids = new Set(),\n numViews = views.length;\n let firstVisibleElementInd = binarySearchFirstItem(\n views,\n horizontal\n ? isElementNextAfterViewHorizontally\n : isElementBottomAfterViewTop\n );\n\n // Please note the return value of the `binarySearchFirstItem` function when\n // no valid element is found (hence the `firstVisibleElementInd` check below).\n if (\n firstVisibleElementInd > 0 &&\n firstVisibleElementInd < numViews &&\n !horizontal\n ) {\n // In wrapped scrolling (or vertical scrolling with spreads), with some page\n // sizes, isElementBottomAfterViewTop doesn't satisfy the binary search\n // condition: there can be pages with bottoms above the view top between\n // pages with bottoms below. This function detects and corrects that error;\n // see it for more comments.\n firstVisibleElementInd = backtrackBeforeAllVisibleElements(\n firstVisibleElementInd,\n views,\n top\n );\n }\n\n // lastEdge acts as a cutoff for us to stop looping, because we know all\n // subsequent pages will be hidden.\n //\n // When using wrapped scrolling or vertical scrolling with spreads, we can't\n // simply stop the first time we reach a page below the bottom of the view;\n // the tops of subsequent pages on the same row could still be visible. In\n // horizontal scrolling, we don't have that issue, so we can stop as soon as\n // we pass `right`, without needing the code below that handles the -1 case.\n let lastEdge = horizontal ? right : -1;\n\n for (let i = firstVisibleElementInd; i < numViews; i++) {\n const view = views[i],\n element = view.div;\n const currentWidth = element.offsetLeft + element.clientLeft;\n const currentHeight = element.offsetTop + element.clientTop;\n const viewWidth = element.clientWidth,\n viewHeight = element.clientHeight;\n const viewRight = currentWidth + viewWidth;\n const viewBottom = currentHeight + viewHeight;\n\n if (lastEdge === -1) {\n // As commented above, this is only needed in non-horizontal cases.\n // Setting lastEdge to the bottom of the first page that is partially\n // visible ensures that the next page fully below lastEdge is on the\n // next row, which has to be fully hidden along with all subsequent rows.\n if (viewBottom >= bottom) {\n lastEdge = viewBottom;\n }\n } else if ((horizontal ? currentWidth : currentHeight) > lastEdge) {\n break;\n }\n\n if (\n viewBottom <= top ||\n currentHeight >= bottom ||\n viewRight <= left ||\n currentWidth >= right\n ) {\n continue;\n }\n\n const minY = Math.max(0, top - currentHeight);\n const minX = Math.max(0, left - currentWidth);\n\n const hiddenHeight = minY + Math.max(0, viewBottom - bottom);\n const hiddenWidth = minX + Math.max(0, viewRight - right);\n\n const fractionHeight = (viewHeight - hiddenHeight) / viewHeight,\n fractionWidth = (viewWidth - hiddenWidth) / viewWidth;\n const percent = (fractionHeight * fractionWidth * 100) | 0;\n\n visible.push({\n id: view.id,\n x: currentWidth,\n y: currentHeight,\n visibleArea:\n // We only specify which part of the page is visible when it's not\n // the full page, as there is no point in handling a partial page\n // rendering otherwise.\n percent === 100\n ? null\n : {\n minX,\n minY,\n maxX: Math.min(viewRight, right) - currentWidth,\n maxY: Math.min(viewBottom, bottom) - currentHeight,\n },\n view,\n percent,\n widthPercent: (fractionWidth * 100) | 0,\n });\n ids.add(view.id);\n }\n\n const first = visible[0],\n last = visible.at(-1);\n\n if (sortByVisibility) {\n visible.sort(function (a, b) {\n const pc = a.percent - b.percent;\n if (Math.abs(pc) > 0.001) {\n return -pc;\n }\n return a.id - b.id; // ensure stability\n });\n }\n return { first, last, views: visible, ids };\n}\n\nfunction normalizeWheelEventDirection(evt) {\n let delta = Math.hypot(evt.deltaX, evt.deltaY);\n const angle = Math.atan2(evt.deltaY, evt.deltaX);\n if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) {\n // All that is left-up oriented has to change the sign.\n delta = -delta;\n }\n return delta;\n}\n\nfunction normalizeWheelEventDelta(evt) {\n const deltaMode = evt.deltaMode; // Avoid being affected by bug 1392460.\n let delta = normalizeWheelEventDirection(evt);\n\n const MOUSE_PIXELS_PER_LINE = 30;\n const MOUSE_LINES_PER_PAGE = 30;\n\n // Converts delta to per-page units\n if (deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n delta /= MOUSE_PIXELS_PER_LINE * MOUSE_LINES_PER_PAGE;\n } else if (deltaMode === WheelEvent.DOM_DELTA_LINE) {\n delta /= MOUSE_LINES_PER_PAGE;\n }\n return delta;\n}\n\nfunction isValidRotation(angle) {\n return Number.isInteger(angle) && angle % 90 === 0;\n}\n\nfunction isValidScrollMode(mode) {\n return (\n Number.isInteger(mode) &&\n Object.values(ScrollMode).includes(mode) &&\n mode !== ScrollMode.UNKNOWN\n );\n}\n\nfunction isValidSpreadMode(mode) {\n return (\n Number.isInteger(mode) &&\n Object.values(SpreadMode).includes(mode) &&\n mode !== SpreadMode.UNKNOWN\n );\n}\n\nfunction isPortraitOrientation(size) {\n return size.width <= size.height;\n}\n\n/**\n * Promise that is resolved when DOM window becomes visible.\n */\nconst animationStarted = new Promise(function (resolve) {\n if (\n typeof PDFJSDev !== \"undefined\" &&\n PDFJSDev.test(\"LIB\") &&\n typeof window === \"undefined\"\n ) {\n // Prevent \"ReferenceError: window is not defined\" errors when running the\n // unit-tests in Node.js environments.\n setTimeout(resolve, 20);\n return;\n }\n window.requestAnimationFrame(resolve);\n});\n\nconst docStyle =\n typeof PDFJSDev !== \"undefined\" &&\n PDFJSDev.test(\"LIB\") &&\n typeof document === \"undefined\"\n ? null\n : document.documentElement.style;\n\nclass ProgressBar {\n #classList = null;\n\n #disableAutoFetchTimeout = null;\n\n #percent = 0;\n\n #style = null;\n\n #visible = true;\n\n constructor(bar) {\n this.#classList = bar.classList;\n this.#style = bar.style;\n }\n\n get percent() {\n return this.#percent;\n }\n\n set percent(val) {\n this.#percent = val;\n\n if (isNaN(val)) {\n this.#classList.add(\"indeterminate\");\n return;\n }\n this.#classList.remove(\"indeterminate\");\n\n this.#style.setProperty(\"--progressBar-percent\", `${this.#percent}%`);\n }\n\n setWidth(viewer) {\n if (!viewer) {\n return;\n }\n const container = viewer.parentNode;\n const scrollbarWidth = container.offsetWidth - viewer.offsetWidth;\n if (scrollbarWidth > 0) {\n this.#style.setProperty(\n \"--progressBar-end-offset\",\n `${scrollbarWidth}px`\n );\n }\n }\n\n setDisableAutoFetch(delay = /* ms = */ 5000) {\n if (this.#percent === 100 || isNaN(this.#percent)) {\n return;\n }\n if (this.#disableAutoFetchTimeout) {\n clearTimeout(this.#disableAutoFetchTimeout);\n }\n this.show();\n\n this.#disableAutoFetchTimeout = setTimeout(() => {\n this.#disableAutoFetchTimeout = null;\n this.hide();\n }, delay);\n }\n\n hide() {\n if (!this.#visible) {\n return;\n }\n this.#visible = false;\n this.#classList.add(\"hidden\");\n }\n\n show() {\n if (this.#visible) {\n return;\n }\n this.#visible = true;\n this.#classList.remove(\"hidden\");\n }\n}\n\n/**\n * Get the active or focused element in current DOM.\n *\n * Recursively search for the truly active or focused element in case there are\n * shadow DOMs.\n *\n * @returns {Element} the truly active or focused element.\n */\nfunction getActiveOrFocusedElement() {\n let curRoot = document;\n let curActiveOrFocused =\n curRoot.activeElement || curRoot.querySelector(\":focus\");\n\n while (curActiveOrFocused?.shadowRoot) {\n curRoot = curActiveOrFocused.shadowRoot;\n curActiveOrFocused =\n curRoot.activeElement || curRoot.querySelector(\":focus\");\n }\n\n return curActiveOrFocused;\n}\n\n/**\n * Converts API PageLayout values to the format used by `BaseViewer`.\n * @param {string} layout - The API PageLayout value.\n * @returns {Object}\n */\nfunction apiPageLayoutToViewerModes(layout) {\n let scrollMode = ScrollMode.VERTICAL,\n spreadMode = SpreadMode.NONE;\n\n switch (layout) {\n case \"SinglePage\":\n scrollMode = ScrollMode.PAGE;\n break;\n case \"OneColumn\":\n break;\n case \"TwoPageLeft\":\n scrollMode = ScrollMode.PAGE;\n /* falls through */\n case \"TwoColumnLeft\":\n spreadMode = SpreadMode.ODD;\n break;\n case \"TwoPageRight\":\n scrollMode = ScrollMode.PAGE;\n /* falls through */\n case \"TwoColumnRight\":\n spreadMode = SpreadMode.EVEN;\n break;\n }\n return { scrollMode, spreadMode };\n}\n\n/**\n * Converts API PageMode values to the format used by `PDFSidebar`.\n * NOTE: There's also a \"FullScreen\" parameter which is not possible to support,\n * since the Fullscreen API used in browsers requires that entering\n * fullscreen mode only occurs as a result of a user-initiated event.\n * @param {string} mode - The API PageMode value.\n * @returns {number} A value from {SidebarView}.\n */\nfunction apiPageModeToSidebarView(mode) {\n switch (mode) {\n case \"UseNone\":\n return SidebarView.NONE;\n case \"UseThumbs\":\n return SidebarView.THUMBS;\n case \"UseOutlines\":\n return SidebarView.OUTLINE;\n case \"UseAttachments\":\n return SidebarView.ATTACHMENTS;\n case \"UseOC\":\n return SidebarView.LAYERS;\n }\n return SidebarView.NONE; // Default value.\n}\n\nfunction toggleCheckedBtn(button, toggle, view = null) {\n button.classList.toggle(\"toggled\", toggle);\n button.setAttribute(\"aria-checked\", toggle);\n\n view?.classList.toggle(\"hidden\", !toggle);\n}\n\nfunction toggleSelectedBtn(button, toggle, view = null) {\n button.classList.toggle(\"selected\", toggle);\n button.setAttribute(\"aria-selected\", toggle);\n\n view?.classList.toggle(\"hidden\", !toggle);\n}\n\nfunction toggleExpandedBtn(button, toggle, view = null) {\n button.classList.toggle(\"toggled\", toggle);\n button.setAttribute(\"aria-expanded\", toggle);\n\n view?.classList.toggle(\"hidden\", !toggle);\n}\n\n// In Firefox, the css calc function uses f32 precision but the Chrome or Safari\n// are using f64 one. So in order to have the same rendering in all browsers, we\n// need to use the right precision in order to have correct dimensions.\nconst calcRound =\n typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"MOZCENTRAL\")\n ? Math.fround\n : (function () {\n if (\n typeof PDFJSDev !== \"undefined\" &&\n PDFJSDev.test(\"LIB\") &&\n typeof document === \"undefined\"\n ) {\n return x => x;\n }\n const e = document.createElement(\"div\");\n e.style.width = \"round(down, calc(1.6666666666666665 * 792px), 1px)\";\n return e.style.width === \"calc(1320px)\" ? Math.fround : x => x;\n })();\n\nexport {\n animationStarted,\n apiPageLayoutToViewerModes,\n apiPageModeToSidebarView,\n approximateFraction,\n AutoPrintRegExp,\n backtrackBeforeAllVisibleElements, // only exported for testing\n binarySearchFirstItem,\n calcRound,\n CursorTool,\n DEFAULT_SCALE,\n DEFAULT_SCALE_DELTA,\n DEFAULT_SCALE_VALUE,\n docStyle,\n floorToDivide,\n getActiveOrFocusedElement,\n getPageSizeInches,\n getVisibleElements,\n isPortraitOrientation,\n isValidRotation,\n isValidScrollMode,\n isValidSpreadMode,\n MAX_AUTO_SCALE,\n MAX_SCALE,\n MIN_SCALE,\n normalizeWheelEventDelta,\n normalizeWheelEventDirection,\n parseQueryString,\n PresentationModeState,\n ProgressBar,\n removeNullCharacters,\n SCROLLBAR_PADDING,\n scrollIntoView,\n ScrollMode,\n SidebarView,\n SpreadMode,\n TextLayerMode,\n toggleCheckedBtn,\n toggleExpandedBtn,\n toggleSelectedBtn,\n UNKNOWN_SCALE,\n VERTICAL_PADDING,\n watchScroll,\n};\n","/* Copyright 2018 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nif (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"GENERIC\")) {\n // eslint-disable-next-line no-var\n var compatParams = new Map();\n if (\n typeof PDFJSDev !== \"undefined\" &&\n PDFJSDev.test(\"LIB\") &&\n !globalThis.navigator?.language\n ) {\n globalThis.navigator = {\n language: \"en-US\",\n maxTouchPoints: 1,\n platform: \"\",\n userAgent: \"\",\n };\n }\n const { maxTouchPoints, platform, userAgent } = navigator;\n\n const isAndroid = /Android/.test(userAgent);\n const isIOS =\n /\\b(iPad|iPhone|iPod)(?=;)/.test(userAgent) ||\n (platform === \"MacIntel\" && maxTouchPoints > 1);\n\n // Limit canvas size to 5 mega-pixels on mobile.\n // Support: Android, iOS\n if (isIOS || isAndroid) {\n compatParams.set(\"maxCanvasPixels\", 5242880);\n }\n\n // Don't use system fonts on Android (issue 18210).\n // Support: Android\n if (isAndroid) {\n compatParams.set(\"useSystemFonts\", false);\n }\n}\n\nconst OptionKind = {\n BROWSER: 0x01,\n VIEWER: 0x02,\n API: 0x04,\n WORKER: 0x08,\n EVENT_DISPATCH: 0x10,\n PREFERENCE: 0x80,\n};\n\n// Should only be used with options that allow multiple types.\nconst Type = {\n BOOLEAN: 0x01,\n NUMBER: 0x02,\n OBJECT: 0x04,\n STRING: 0x08,\n UNDEFINED: 0x10,\n};\n\n/**\n * NOTE: These options are used to generate the `default_preferences.json` file,\n * see `OptionKind.PREFERENCE`, hence the values below must use only\n * primitive types and cannot rely on any imported types.\n */\nconst defaultOptions = {\n allowedGlobalEvents: {\n /** @type {Object} */\n value: null,\n kind: OptionKind.BROWSER,\n },\n canvasMaxAreaInBytes: {\n /** @type {number} */\n value: -1,\n kind: OptionKind.BROWSER + OptionKind.API,\n },\n isInAutomation: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.BROWSER,\n },\n localeProperties: {\n /** @type {Object} */\n value:\n typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"GENERIC\")\n ? { lang: navigator.language || \"en-US\" }\n : null,\n kind: OptionKind.BROWSER,\n },\n maxCanvasDim: {\n /** @type {number} */\n value: 32767,\n kind: OptionKind.BROWSER + OptionKind.VIEWER,\n },\n nimbusDataStr: {\n /** @type {string} */\n value: \"\",\n kind: OptionKind.BROWSER,\n },\n supportsCaretBrowsingMode: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.BROWSER,\n },\n supportsDocumentFonts: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.BROWSER,\n },\n supportsIntegratedFind: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.BROWSER,\n },\n supportsMouseWheelZoomCtrlKey: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.BROWSER,\n },\n supportsMouseWheelZoomMetaKey: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.BROWSER,\n },\n supportsPinchToZoom: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.BROWSER,\n },\n supportsPrinting: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.BROWSER,\n },\n toolbarDensity: {\n /** @type {number} */\n value: 0, // 0 = \"normal\", 1 = \"compact\", 2 = \"touch\"\n kind: OptionKind.BROWSER + OptionKind.EVENT_DISPATCH,\n },\n\n altTextLearnMoreUrl: {\n /** @type {string} */\n value:\n typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"MOZCENTRAL\")\n ? \"https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/pdf-alt-text\"\n : \"\",\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n annotationEditorMode: {\n /** @type {number} */\n value: 0,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n annotationMode: {\n /** @type {number} */\n value: 2,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n capCanvasAreaFactor: {\n /** @type {number} */\n value: 200,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n commentLearnMoreUrl: {\n /** @type {string} */\n value:\n typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"MOZCENTRAL\")\n ? \"https://support.mozilla.org/%LOCALE%/kb/view-pdf-files-firefox-or-choose-another-viewer#w_add-a-comment-to-a-pdf\"\n : \"\",\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n cursorToolOnLoad: {\n /** @type {number} */\n value: 0,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n debuggerSrc: {\n /** @type {string} */\n value: \"./debugger.mjs\",\n kind: OptionKind.VIEWER,\n },\n defaultZoomDelay: {\n /** @type {number} */\n value: 400,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n defaultZoomValue: {\n /** @type {string} */\n value: \"\",\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n disableHistory: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.VIEWER,\n },\n disablePageLabels: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableAltText: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableAltTextModelDownload: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE + OptionKind.EVENT_DISPATCH,\n },\n enableAutoLinking: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableComment: {\n /** @type {boolean} */\n value: typeof PDFJSDev === \"undefined\",\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableDetailCanvas: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.VIEWER,\n },\n enableGuessAltText: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE + OptionKind.EVENT_DISPATCH,\n },\n enableHighlightFloatingButton: {\n // We'll probably want to make some experiments before enabling this\n // in Firefox release, but it has to be temporary.\n // TODO: remove it when unnecessary.\n /** @type {boolean} */\n value: typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\"),\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableNewAltTextWhenAddingImage: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableOptimizedPartialRendering: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enablePermissions: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enablePrintAutoRotate: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableScripting: {\n /** @type {boolean} */\n value: typeof PDFJSDev === \"undefined\" || !PDFJSDev.test(\"CHROME\"),\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableSignatureEditor: {\n /** @type {boolean} */\n value: typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\"),\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableSplitMerge: {\n /** @type {boolean} */\n value: typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\"),\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableUpdatedAddImage: {\n // We'll probably want to make some experiments before enabling this\n // in Firefox release, but it has to be temporary.\n // TODO: remove it when unnecessary.\n /** @type {boolean} */\n value: false,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n externalLinkRel: {\n /** @type {string} */\n value: \"noopener noreferrer nofollow\",\n kind: OptionKind.VIEWER,\n },\n externalLinkTarget: {\n /** @type {number} */\n value: 0,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n highlightEditorColors: {\n /** @type {string} */\n value:\n \"yellow=#FFFF98,green=#53FFBC,blue=#80EBFF,pink=#FFCBE6,red=#FF4F5F,\" +\n \"yellow_HCM=#FFFFCC,green_HCM=#53FFBC,blue_HCM=#80EBFF,pink_HCM=#F6B8FF,red_HCM=#C50043\",\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n historyUpdateUrl: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n ignoreDestinationZoom: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n imageResourcesPath: {\n /** @type {string} */\n value:\n typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"MOZCENTRAL\")\n ? \"resource://pdf.js/web/images/\"\n : \"./images/\",\n kind: OptionKind.VIEWER,\n },\n maxCanvasPixels: {\n /** @type {number} */\n value: 2 ** 25,\n kind: OptionKind.VIEWER,\n },\n minDurationToUpdateCanvas: {\n /** @type {number} */\n value: 500, // ms\n kind: OptionKind.VIEWER,\n },\n forcePageColors: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n pageColorsBackground: {\n /** @type {string} */\n value: \"Canvas\",\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n pageColorsForeground: {\n /** @type {string} */\n value: \"CanvasText\",\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n pdfBugEnabled: {\n /** @type {boolean} */\n value: typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\"),\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n printResolution: {\n /** @type {number} */\n value: 150,\n kind: OptionKind.VIEWER,\n },\n sidebarViewOnLoad: {\n /** @type {number} */\n value: -1,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n scrollModeOnLoad: {\n /** @type {number} */\n value: -1,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n spreadModeOnLoad: {\n /** @type {number} */\n value: -1,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n textLayerMode: {\n /** @type {number} */\n value: 1,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n viewerCssTheme: {\n /** @type {number} */\n value: typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"CHROME\") ? 2 : 0,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n viewOnLoad: {\n /** @type {boolean} */\n value: 0,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n\n cMapPacked: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.API,\n },\n cMapUrl: {\n /** @type {string} */\n value:\n // eslint-disable-next-line no-nested-ternary\n typeof PDFJSDev === \"undefined\"\n ? \"../external/bcmaps/\"\n : PDFJSDev.test(\"MOZCENTRAL\")\n ? \"resource://pdf.js/web/cmaps/\"\n : \"../web/cmaps/\",\n kind: OptionKind.API,\n },\n disableAutoFetch: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.API + OptionKind.PREFERENCE,\n },\n disableFontFace: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.API + OptionKind.PREFERENCE,\n },\n disableRange: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.API + OptionKind.PREFERENCE,\n },\n disableStream: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.API + OptionKind.PREFERENCE,\n },\n docBaseUrl: {\n /** @type {string} */\n value:\n typeof PDFJSDev === \"undefined\"\n ? // NOTE: We cannot use the `updateUrlHash` function here, because of\n // the default preferences generation (see `gulpfile.mjs`).\n // However, the following line is *only* used in development mode.\n document.URL.split(\"#\", 1)[0]\n : \"\",\n kind: OptionKind.API,\n },\n enableHWA: {\n /** @type {boolean} */\n value: typeof PDFJSDev !== \"undefined\" && !PDFJSDev.test(\"MOZCENTRAL\"),\n kind: OptionKind.API + OptionKind.VIEWER + OptionKind.PREFERENCE,\n },\n enableXfa: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.API + OptionKind.PREFERENCE,\n },\n fontExtraProperties: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.API,\n },\n iccUrl: {\n /** @type {string} */\n value:\n // eslint-disable-next-line no-nested-ternary\n typeof PDFJSDev === \"undefined\"\n ? \"../external/iccs/\"\n : PDFJSDev.test(\"MOZCENTRAL\")\n ? \"resource://pdf.js/web/iccs/\"\n : \"../web/iccs/\",\n kind: OptionKind.API,\n },\n isEvalSupported: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.API,\n },\n isOffscreenCanvasSupported: {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.API,\n },\n maxImageSize: {\n /** @type {number} */\n value: -1,\n kind: OptionKind.API,\n },\n pdfBug: {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.API,\n },\n standardFontDataUrl: {\n /** @type {string} */\n value:\n // eslint-disable-next-line no-nested-ternary\n typeof PDFJSDev === \"undefined\"\n ? \"../external/standard_fonts/\"\n : PDFJSDev.test(\"MOZCENTRAL\")\n ? \"resource://pdf.js/web/standard_fonts/\"\n : \"../web/standard_fonts/\",\n kind: OptionKind.API,\n },\n useSystemFonts: {\n // On Android, there is almost no chance to have the font we want so we\n // don't use the system fonts in this case (bug 1882613).\n /** @type {boolean|undefined} */\n value: (\n typeof PDFJSDev === \"undefined\"\n ? window.isGECKOVIEW\n : PDFJSDev.test(\"GECKOVIEW\")\n )\n ? false\n : undefined,\n kind: OptionKind.API,\n type: Type.BOOLEAN + Type.UNDEFINED,\n },\n verbosity: {\n /** @type {number} */\n value: 1,\n kind: OptionKind.API,\n },\n wasmUrl: {\n /** @type {string} */\n value:\n typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"MOZCENTRAL\")\n ? \"resource://pdf.js/web/wasm/\"\n : \"../web/wasm/\",\n kind: OptionKind.API,\n },\n\n workerPort: {\n /** @type {Object} */\n value:\n typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"MOZCENTRAL\")\n ? globalThis.pdfjsPreloadedWorker || null\n : null,\n kind: OptionKind.WORKER,\n },\n workerSrc: {\n /** @type {string} */\n value:\n // eslint-disable-next-line no-nested-ternary\n typeof PDFJSDev === \"undefined\"\n ? \"../src/pdf.worker.js\"\n : PDFJSDev.test(\"MOZCENTRAL\")\n ? \"resource://pdf.js/build/pdf.worker.mjs\"\n : \"../build/pdf.worker.mjs\",\n kind: OptionKind.WORKER,\n },\n};\nif (typeof PDFJSDev === \"undefined\" || !PDFJSDev.test(\"MOZCENTRAL\")) {\n defaultOptions.defaultUrl = {\n /** @type {string} */\n value:\n typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"CHROME\")\n ? \"\"\n : \"compressed.tracemonkey-pldi-09.pdf\",\n kind: OptionKind.VIEWER,\n };\n defaultOptions.sandboxBundleSrc = {\n /** @type {string} */\n value:\n typeof PDFJSDev === \"undefined\"\n ? \"../build/dev-sandbox/pdf.sandbox.mjs\"\n : \"../build/pdf.sandbox.mjs\",\n kind: OptionKind.VIEWER,\n };\n defaultOptions.enableFakeMLManager = {\n /** @type {boolean} */\n value: true,\n kind: OptionKind.VIEWER,\n };\n}\nif (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"GENERIC\")) {\n defaultOptions.disablePreferences = {\n /** @type {boolean} */\n value: typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"TESTING\"),\n kind: OptionKind.VIEWER,\n };\n} else if (PDFJSDev.test(\"CHROME\")) {\n defaultOptions.disableTelemetry = {\n /** @type {boolean} */\n value: false,\n kind: OptionKind.VIEWER + OptionKind.PREFERENCE,\n };\n}\n\nif (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\")) {\n // Ensure that the `defaultOptions` are correctly specified.\n for (const name in defaultOptions) {\n const { value, kind, type } = defaultOptions[name];\n\n if (kind & OptionKind.PREFERENCE) {\n if (kind === OptionKind.PREFERENCE) {\n throw new Error(`Cannot use only \"PREFERENCE\" kind: ${name}`);\n }\n if (kind & OptionKind.BROWSER) {\n throw new Error(`Cannot mix \"PREFERENCE\" and \"BROWSER\" kind: ${name}`);\n }\n if (type !== undefined) {\n throw new Error(\n `Cannot have \\`type\\`-field for \"PREFERENCE\" kind: ${name}`\n );\n }\n if (typeof compatParams === \"object\" && compatParams.has(name)) {\n throw new Error(\n `Should not have compatibility-value for \"PREFERENCE\" kind: ${name}`\n );\n }\n // Only \"simple\" preference-values are allowed.\n if (\n typeof value !== \"boolean\" &&\n typeof value !== \"string\" &&\n !Number.isInteger(value)\n ) {\n throw new Error(`Invalid value for \"PREFERENCE\" kind: ${name}`);\n }\n } else if (kind & OptionKind.BROWSER) {\n if (type !== undefined) {\n throw new Error(\n `Cannot have \\`type\\`-field for \"BROWSER\" kind: ${name}`\n );\n }\n if (typeof compatParams === \"object\" && compatParams.has(name)) {\n throw new Error(\n `Should not have compatibility-value for \"BROWSER\" kind: ${name}`\n );\n }\n if (value === undefined) {\n throw new Error(`Invalid value for \"BROWSER\" kind: ${name}`);\n }\n }\n }\n}\n\nclass AppOptions {\n static eventBus;\n\n static #opts = new Map();\n\n static {\n // Initialize all the user-options.\n for (const name in defaultOptions) {\n this.#opts.set(name, defaultOptions[name].value);\n }\n\n if (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"GENERIC\")) {\n // Apply any compatibility-values to the user-options.\n for (const [name, value] of compatParams) {\n this.#opts.set(name, value);\n }\n this._hasInvokedSet = false;\n\n this._checkDisablePreferences = () => {\n if (this.get(\"disablePreferences\")) {\n // Give custom implementations of the default viewer a simpler way to\n // opt-out of having the `Preferences` override existing `AppOptions`.\n return true;\n }\n if (this._hasInvokedSet) {\n console.warn(\n \"The Preferences may override manually set AppOptions; \" +\n 'please use the \"disablePreferences\"-option to prevent that.'\n );\n }\n return false;\n };\n }\n }\n\n constructor() {\n if (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\")) {\n throw new Error(\"Cannot initialize AppOptions.\");\n }\n }\n\n static get(name) {\n return this.#opts.get(name);\n }\n\n static getAll(kind = null, defaultOnly = false) {\n const options = Object.create(null);\n for (const name in defaultOptions) {\n const defaultOpt = defaultOptions[name];\n\n if (kind && !(kind & defaultOpt.kind)) {\n continue;\n }\n options[name] = !defaultOnly ? this.#opts.get(name) : defaultOpt.value;\n }\n return options;\n }\n\n static set(name, value) {\n this.setAll({ [name]: value });\n }\n\n static setAll(options, prefs = false) {\n if (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"GENERIC\")) {\n this._hasInvokedSet ||= true;\n }\n let events;\n\n for (const name in options) {\n const defaultOpt = defaultOptions[name],\n userOpt = options[name];\n\n if (\n !defaultOpt ||\n !(\n typeof userOpt === typeof defaultOpt.value ||\n Type[(typeof userOpt).toUpperCase()] & defaultOpt.type\n )\n ) {\n continue;\n }\n const { kind } = defaultOpt;\n\n if (\n prefs &&\n !(kind & OptionKind.BROWSER || kind & OptionKind.PREFERENCE)\n ) {\n continue;\n }\n if (this.eventBus && kind & OptionKind.EVENT_DISPATCH) {\n (events ||= new Map()).set(name, userOpt);\n }\n this.#opts.set(name, userOpt);\n }\n\n if (events) {\n for (const [name, value] of events) {\n this.eventBus.dispatch(name.toLowerCase(), { source: this, value });\n }\n }\n }\n}\n\nexport { AppOptions, OptionKind };\n","/* Copyright 2015 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** @typedef {import(\"./event_utils\").EventBus} EventBus */\n\nimport { isValidExplicitDest } from \"pdfjs-lib\";\nimport { parseQueryString } from \"./ui_utils.js\";\n\nconst DEFAULT_LINK_REL = \"noopener noreferrer nofollow\";\n\nconst LinkTarget = {\n NONE: 0, // Default value.\n SELF: 1,\n BLANK: 2,\n PARENT: 3,\n TOP: 4,\n};\n\n/**\n * @typedef {Object} PDFLinkServiceOptions\n * @property {EventBus} eventBus - The application event bus.\n * @property {number} [externalLinkTarget] - Specifies the `target` attribute\n * for external links. Must use one of the values from {LinkTarget}.\n * Defaults to using no target.\n * @property {string} [externalLinkRel] - Specifies the `rel` attribute for\n * external links. Defaults to stripping the referrer.\n * @property {boolean} [ignoreDestinationZoom] - Ignores the zoom argument,\n * thus preserving the current zoom level in the viewer, when navigating\n * to internal destinations. The default value is `false`.\n */\n\n/**\n * Performs navigation functions inside PDF, such as opening specified page,\n * or destination.\n */\nclass PDFLinkService {\n externalLinkEnabled = true;\n\n /**\n * @param {PDFLinkServiceOptions} options\n */\n constructor({\n eventBus,\n externalLinkTarget = null,\n externalLinkRel = null,\n ignoreDestinationZoom = false,\n } = {}) {\n this.eventBus = eventBus;\n this.externalLinkTarget = externalLinkTarget;\n this.externalLinkRel = externalLinkRel;\n this._ignoreDestinationZoom = ignoreDestinationZoom;\n\n this.baseUrl = null;\n this.pdfDocument = null;\n this.pdfViewer = null;\n this.pdfHistory = null;\n }\n\n setDocument(pdfDocument, baseUrl = null) {\n this.baseUrl = baseUrl;\n this.pdfDocument = pdfDocument;\n }\n\n setViewer(pdfViewer) {\n this.pdfViewer = pdfViewer;\n }\n\n setHistory(pdfHistory) {\n this.pdfHistory = pdfHistory;\n }\n\n /**\n * @type {number}\n */\n get pagesCount() {\n return this.pdfDocument?.pagesMapper.pagesNumber || 0;\n }\n\n /**\n * @type {number}\n */\n get page() {\n return this.pdfDocument ? this.pdfViewer.currentPageNumber : 1;\n }\n\n /**\n * @param {number} value\n */\n set page(value) {\n if (this.pdfDocument) {\n this.pdfViewer.currentPageNumber = value;\n }\n }\n\n /**\n * @type {number}\n */\n get rotation() {\n return this.pdfDocument ? this.pdfViewer.pagesRotation : 0;\n }\n\n /**\n * @param {number} value\n */\n set rotation(value) {\n if (this.pdfDocument) {\n this.pdfViewer.pagesRotation = value;\n }\n }\n\n /**\n * @type {boolean}\n */\n get isInPresentationMode() {\n return this.pdfDocument ? this.pdfViewer.isInPresentationMode : false;\n }\n\n /**\n * This method will, when available, also update the browser history.\n *\n * @param {string|Array} dest - The named, or explicit, PDF destination.\n */\n async goToDestination(dest) {\n if (!this.pdfDocument) {\n return;\n }\n let namedDest, explicitDest, pageNumber;\n if (typeof dest === \"string\") {\n namedDest = dest;\n explicitDest = await this.pdfDocument.getDestination(dest);\n } else {\n namedDest = null;\n explicitDest = await dest;\n }\n if (!Array.isArray(explicitDest)) {\n console.error(\n `goToDestination: \"${explicitDest}\" is not a valid destination array, for dest=\"${dest}\".`\n );\n return;\n }\n // Dest array looks like that: \n const [destRef] = explicitDest;\n\n if (destRef && typeof destRef === \"object\") {\n pageNumber = this.pdfDocument.cachedPageNumber(destRef);\n\n if (!pageNumber) {\n // Fetch the page reference if it's not yet available. This could\n // only occur during loading, before all pages have been resolved.\n try {\n pageNumber = (await this.pdfDocument.getPageIndex(destRef)) + 1;\n } catch {\n console.error(\n `goToDestination: \"${destRef}\" is not a valid page reference, for dest=\"${dest}\".`\n );\n return;\n }\n }\n } else if (Number.isInteger(destRef)) {\n pageNumber = destRef + 1;\n }\n if (!pageNumber || pageNumber < 1 || pageNumber > this.pagesCount) {\n console.error(\n `goToDestination: \"${pageNumber}\" is not a valid page number, for dest=\"${dest}\".`\n );\n return;\n }\n\n if (this.pdfHistory) {\n // Update the browser history before scrolling the new destination into\n // view, to be able to accurately capture the current document position.\n this.pdfHistory.pushCurrentPosition();\n this.pdfHistory.push({ namedDest, explicitDest, pageNumber });\n }\n\n this.pdfViewer.scrollPageIntoView({\n pageNumber,\n destArray: explicitDest,\n ignoreDestinationZoom: this._ignoreDestinationZoom,\n });\n\n const ac = new AbortController();\n this.eventBus._on(\n \"textlayerrendered\",\n evt => {\n if (evt.pageNumber === pageNumber) {\n evt.source.textLayer.div.focus();\n ac.abort();\n }\n },\n { signal: ac.signal }\n );\n }\n\n /**\n * This method will, when available, also update the browser history.\n *\n * @param {number|string} val - The page number, or page label.\n */\n goToPage(val) {\n if (!this.pdfDocument) {\n return;\n }\n const pageNumber =\n (typeof val === \"string\" && this.pdfViewer.pageLabelToPageNumber(val)) ||\n val | 0;\n if (\n !(\n Number.isInteger(pageNumber) &&\n pageNumber > 0 &&\n pageNumber <= this.pagesCount\n )\n ) {\n console.error(`PDFLinkService.goToPage: \"${val}\" is not a valid page.`);\n return;\n }\n\n if (this.pdfHistory) {\n // Update the browser history before scrolling the new page into view,\n // to be able to accurately capture the current document position.\n this.pdfHistory.pushCurrentPosition();\n this.pdfHistory.pushPage(pageNumber);\n }\n\n this.pdfViewer.scrollPageIntoView({ pageNumber });\n }\n\n /**\n * Scrolls to a specific location in the PDF document.\n * @param {number} pageNumber - The page number to scroll to.\n * @param {number} x - The x-coordinate to scroll to in page coordinates.\n * @param {number} y - The y-coordinate to scroll to in page coordinates.\n * @param {Object} [options]\n */\n goToXY(pageNumber, x, y, options = {}) {\n this.pdfViewer.scrollPageIntoView({\n pageNumber,\n destArray: [null, { name: \"XYZ\" }, x, y],\n ignoreDestinationZoom: true,\n ...options,\n });\n }\n\n /**\n * Adds various attributes (href, title, target, rel) to hyperlinks.\n * @param {HTMLAnchorElement} link\n * @param {string} url\n * @param {boolean} [newWindow]\n */\n addLinkAttributes(link, url, newWindow = false) {\n if (!url || typeof url !== \"string\") {\n throw new Error('A valid \"url\" parameter must provided.');\n }\n const target = newWindow ? LinkTarget.BLANK : this.externalLinkTarget,\n rel = this.externalLinkRel;\n\n if (this.externalLinkEnabled) {\n link.href = link.title = url;\n } else {\n link.href = \"\";\n link.title = `Disabled: ${url}`;\n link.onclick = () => false;\n }\n\n let targetStr = \"\"; // LinkTarget.NONE\n switch (target) {\n case LinkTarget.NONE:\n break;\n case LinkTarget.SELF:\n targetStr = \"_self\";\n break;\n case LinkTarget.BLANK:\n targetStr = \"_blank\";\n break;\n case LinkTarget.PARENT:\n targetStr = \"_parent\";\n break;\n case LinkTarget.TOP:\n targetStr = \"_top\";\n break;\n }\n link.target = targetStr;\n\n link.rel = typeof rel === \"string\" ? rel : DEFAULT_LINK_REL;\n }\n\n /**\n * @param {string|Array} dest - The PDF destination object.\n * @returns {string} The hyperlink to the PDF object.\n */\n getDestinationHash(dest) {\n if (typeof dest === \"string\") {\n if (dest.length > 0) {\n return this.getAnchorUrl(\"#\" + escape(dest));\n }\n } else if (Array.isArray(dest)) {\n const str = JSON.stringify(dest);\n if (str.length > 0) {\n return this.getAnchorUrl(\"#\" + escape(str));\n }\n }\n return this.getAnchorUrl(\"\");\n }\n\n /**\n * Prefix the full url on anchor links to make sure that links are resolved\n * relative to the current URL instead of the one defined in .\n * @param {string} anchor - The anchor hash, including the #.\n * @returns {string} The hyperlink to the PDF object.\n */\n getAnchorUrl(anchor) {\n return this.baseUrl ? this.baseUrl + anchor : anchor;\n }\n\n /**\n * @param {string} hash\n */\n setHash(hash) {\n if (!this.pdfDocument) {\n return;\n }\n let pageNumber, dest;\n if (hash.includes(\"=\")) {\n const params = parseQueryString(hash);\n if (params.has(\"search\")) {\n const query = params.get(\"search\").replaceAll('\"', \"\"),\n phrase = params.get(\"phrase\") === \"true\";\n\n this.eventBus.dispatch(\"findfromurlhash\", {\n source: this,\n query: phrase ? query : query.match(/\\S+/g),\n });\n }\n // borrowing syntax from \"Parameters for Opening PDF Files\"\n if (params.has(\"page\")) {\n pageNumber = params.get(\"page\") | 0 || 1;\n }\n if (params.has(\"zoom\")) {\n // Build the destination array.\n const zoomArgs = params.get(\"zoom\").split(\",\"); // scale,left,top\n const zoomArg = zoomArgs[0];\n const zoomArgNumber = parseFloat(zoomArg);\n\n if (!zoomArg.includes(\"Fit\")) {\n // If the zoomArg is a number, it has to get divided by 100. If it's\n // a string, it should stay as it is.\n dest = [\n null,\n { name: \"XYZ\" },\n zoomArgs.length > 1 ? zoomArgs[1] | 0 : null,\n zoomArgs.length > 2 ? zoomArgs[2] | 0 : null,\n zoomArgNumber ? zoomArgNumber / 100 : zoomArg,\n ];\n } else if (zoomArg === \"Fit\" || zoomArg === \"FitB\") {\n dest = [null, { name: zoomArg }];\n } else if (\n zoomArg === \"FitH\" ||\n zoomArg === \"FitBH\" ||\n zoomArg === \"FitV\" ||\n zoomArg === \"FitBV\"\n ) {\n dest = [\n null,\n { name: zoomArg },\n zoomArgs.length > 1 ? zoomArgs[1] | 0 : null,\n ];\n } else if (zoomArg === \"FitR\") {\n if (zoomArgs.length !== 5) {\n console.error(\n 'PDFLinkService.setHash: Not enough parameters for \"FitR\".'\n );\n } else {\n dest = [\n null,\n { name: zoomArg },\n zoomArgs[1] | 0,\n zoomArgs[2] | 0,\n zoomArgs[3] | 0,\n zoomArgs[4] | 0,\n ];\n }\n } else {\n console.error(\n `PDFLinkService.setHash: \"${zoomArg}\" is not a valid zoom value.`\n );\n }\n }\n if (dest) {\n this.pdfViewer.scrollPageIntoView({\n pageNumber: pageNumber || this.page,\n destArray: dest,\n allowNegativeOffset: true,\n });\n } else if (pageNumber) {\n this.page = pageNumber; // simple page\n }\n if (params.has(\"pagemode\")) {\n this.eventBus.dispatch(\"pagemode\", {\n source: this,\n mode: params.get(\"pagemode\"),\n });\n }\n // Ensure that this parameter is *always* handled last, in order to\n // guarantee that it won't be overridden (e.g. by the \"page\" parameter).\n if (params.has(\"nameddest\")) {\n this.goToDestination(params.get(\"nameddest\"));\n }\n\n if (typeof PDFJSDev === \"undefined\" || !PDFJSDev.test(\"MOZCENTRAL\")) {\n return;\n }\n // Support opening of PDF attachments in the Firefox PDF Viewer,\n // which uses a couple of non-standard hash parameters; refer to\n // `DownloadManager._getOpenDataUrl` in the firefoxcom.js file.\n if (!params.has(\"filename\") || !params.has(\"filedest\")) {\n return;\n }\n hash = params.get(\"filedest\");\n }\n\n // Named (or explicit) destination.\n dest = unescape(hash);\n try {\n dest = JSON.parse(dest);\n\n if (!Array.isArray(dest)) {\n // Avoid incorrectly rejecting a valid named destination, such as\n // e.g. \"4.3\" or \"true\", because `JSON.parse` converted its type.\n dest = dest.toString();\n }\n } catch {}\n\n if (typeof dest === \"string\" || isValidExplicitDest(dest)) {\n this.goToDestination(dest);\n return;\n }\n console.error(\n `PDFLinkService.setHash: \"${unescape(hash)}\" is not a valid destination.`\n );\n }\n\n /**\n * @param {string} action\n */\n executeNamedAction(action) {\n if (!this.pdfDocument) {\n return;\n }\n // See PDF reference, table 8.45 - Named action\n switch (action) {\n case \"GoBack\":\n this.pdfHistory?.back();\n break;\n\n case \"GoForward\":\n this.pdfHistory?.forward();\n break;\n\n case \"NextPage\":\n this.pdfViewer.nextPage();\n break;\n\n case \"PrevPage\":\n this.pdfViewer.previousPage();\n break;\n\n case \"LastPage\":\n this.page = this.pagesCount;\n break;\n\n case \"FirstPage\":\n this.page = 1;\n break;\n\n default:\n break; // No action according to spec\n }\n\n this.eventBus.dispatch(\"namedaction\", {\n source: this,\n action,\n });\n }\n\n /**\n * @param {Object} action\n */\n async executeSetOCGState(action) {\n if (!this.pdfDocument) {\n return;\n }\n const pdfDocument = this.pdfDocument,\n optionalContentConfig = await this.pdfViewer.optionalContentConfigPromise;\n\n if (pdfDocument !== this.pdfDocument) {\n return; // The document was closed while the optional content resolved.\n }\n optionalContentConfig.setOCGState(action);\n\n this.pdfViewer.optionalContentConfigPromise = Promise.resolve(\n optionalContentConfig\n );\n }\n}\n\nclass SimpleLinkService extends PDFLinkService {\n setDocument(pdfDocument, baseUrl = null) {}\n}\n\nexport { LinkTarget, PDFLinkService, SimpleLinkService };\n","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst WaitOnType = {\n EVENT: \"event\",\n TIMEOUT: \"timeout\",\n};\n\n/**\n * @typedef {Object} WaitOnEventOrTimeoutParameters\n * @property {Object} target - The event target, can for example be:\n * `window`, `document`, a DOM element, or an {EventBus} instance.\n * @property {string} name - The name of the event.\n * @property {number} delay - The delay, in milliseconds, after which the\n * timeout occurs (if the event wasn't already dispatched).\n */\n\n/**\n * Allows waiting for an event or a timeout, whichever occurs first.\n * Can be used to ensure that an action always occurs, even when an event\n * arrives late or not at all.\n *\n * @param {WaitOnEventOrTimeoutParameters}\n * @returns {Promise} A promise that is resolved with a {WaitOnType} value.\n */\nasync function waitOnEventOrTimeout({ target, name, delay = 0 }) {\n if (\n typeof target !== \"object\" ||\n !(name && typeof name === \"string\") ||\n !(Number.isInteger(delay) && delay >= 0)\n ) {\n throw new Error(\"waitOnEventOrTimeout - invalid parameters.\");\n }\n const { promise, resolve } = Promise.withResolvers();\n const ac = new AbortController();\n\n function handler(type) {\n ac.abort(); // Remove event listener.\n clearTimeout(timeout);\n\n resolve(type);\n }\n\n const evtMethod = target instanceof EventBus ? \"_on\" : \"addEventListener\";\n target[evtMethod](name, handler.bind(null, WaitOnType.EVENT), {\n signal: ac.signal,\n });\n\n const timeout = setTimeout(handler.bind(null, WaitOnType.TIMEOUT), delay);\n\n return promise;\n}\n\n/**\n * Simple event bus for an application. Listeners are attached using the `on`\n * and `off` methods. To raise an event, the `dispatch` method shall be used.\n */\nclass EventBus {\n #listeners = Object.create(null);\n\n /**\n * @param {string} eventName\n * @param {function} listener\n * @param {Object} [options]\n */\n on(eventName, listener, options = null) {\n this._on(eventName, listener, {\n external: true,\n once: options?.once,\n signal: options?.signal,\n });\n }\n\n /**\n * @param {string} eventName\n * @param {function} listener\n * @param {Object} [options]\n */\n off(eventName, listener, options = null) {\n this._off(eventName, listener);\n }\n\n /**\n * @param {string} eventName\n * @param {Object} data\n */\n dispatch(eventName, data) {\n const eventListeners = this.#listeners[eventName];\n if (!eventListeners || eventListeners.length === 0) {\n return;\n }\n let externalListeners;\n // Making copy of the listeners array in case if it will be modified\n // during dispatch.\n for (const { listener, external, once } of eventListeners.slice(0)) {\n if (once) {\n this._off(eventName, listener);\n }\n if (external) {\n (externalListeners ||= []).push(listener);\n continue;\n }\n listener(data);\n }\n // Dispatch any \"external\" listeners *after* the internal ones, to give the\n // viewer components time to handle events and update their state first.\n if (externalListeners) {\n for (const listener of externalListeners) {\n listener(data);\n }\n externalListeners = null;\n }\n }\n\n /**\n * @ignore\n */\n _on(eventName, listener, options = null) {\n let rmAbort = null;\n if (options?.signal instanceof AbortSignal) {\n const { signal } = options;\n if (signal.aborted) {\n console.error(\"Cannot use an `aborted` signal.\");\n return;\n }\n const onAbort = () => this._off(eventName, listener);\n rmAbort = () => signal.removeEventListener(\"abort\", onAbort);\n\n signal.addEventListener(\"abort\", onAbort);\n }\n\n const eventListeners = (this.#listeners[eventName] ||= []);\n eventListeners.push({\n listener,\n external: options?.external === true,\n once: options?.once === true,\n rmAbort,\n });\n }\n\n /**\n * @ignore\n */\n _off(eventName, listener, options = null) {\n const eventListeners = this.#listeners[eventName];\n if (!eventListeners) {\n return;\n }\n for (let i = 0, ii = eventListeners.length; i < ii; i++) {\n const evt = eventListeners[i];\n if (evt.listener === listener) {\n evt.rmAbort?.(); // Ensure that the `AbortSignal` listener is removed.\n eventListeners.splice(i, 1);\n return;\n }\n }\n }\n}\n\n/**\n * NOTE: Only used in the Firefox built-in pdf viewer.\n */\nclass FirefoxEventBus extends EventBus {\n #externalServices;\n\n #globalEventNames;\n\n #isInAutomation;\n\n constructor(globalEventNames, externalServices, isInAutomation) {\n super();\n this.#globalEventNames = globalEventNames;\n this.#externalServices = externalServices;\n this.#isInAutomation = isInAutomation;\n }\n\n dispatch(eventName, data) {\n if (typeof PDFJSDev !== \"undefined\" && !PDFJSDev.test(\"MOZCENTRAL\")) {\n throw new Error(\"Not implemented: FirefoxEventBus.dispatch\");\n }\n super.dispatch(eventName, data);\n\n if (this.#isInAutomation) {\n const detail = Object.create(null);\n if (data) {\n for (const key in data) {\n const value = data[key];\n if (key === \"source\") {\n if (value === window || value === document) {\n return; // No need to re-dispatch (already) global events.\n }\n continue; // Ignore the `source` property.\n }\n detail[key] = value;\n }\n }\n const event = new CustomEvent(eventName, {\n bubbles: true,\n cancelable: true,\n detail,\n });\n document.dispatchEvent(event);\n }\n\n if (this.#globalEventNames?.has(eventName)) {\n this.#externalServices.dispatchGlobalEvent({\n eventName,\n detail: data,\n });\n }\n }\n}\n\nexport { EventBus, FirefoxEventBus, waitOnEventOrTimeout, WaitOnType };\n","/* Copyright 2024 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass BaseExternalServices {\n constructor() {\n if (\n (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\")) &&\n this.constructor === BaseExternalServices\n ) {\n throw new Error(\"Cannot initialize BaseExternalServices.\");\n }\n }\n\n updateFindControlState(data) {}\n\n updateFindMatchesCount(data) {}\n\n initPassiveLoading() {}\n\n reportTelemetry(data) {}\n\n reportText(data) {}\n\n /**\n * @returns {Promise}\n */\n async createL10n() {\n throw new Error(\"Not implemented: createL10n\");\n }\n\n createScripting() {\n throw new Error(\"Not implemented: createScripting\");\n }\n\n createSignatureStorage() {\n throw new Error(\"Not implemented: createSignatureStorage\");\n }\n\n updateEditorStates(data) {\n throw new Error(\"Not implemented: updateEditorStates\");\n }\n\n dispatchGlobalEvent(_event) {}\n}\n\nexport { BaseExternalServices };\n","/* Copyright 2013 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppOptions, OptionKind } from \"./app_options.js\";\n\n/**\n * BasePreferences - Abstract base class for storing persistent settings.\n * Used for settings that should be applied to all opened documents,\n * or every time the viewer is loaded.\n */\nclass BasePreferences {\n #defaults = Object.freeze(\n AppOptions.getAll(OptionKind.PREFERENCE, /* defaultOnly = */ true)\n );\n\n #initializedPromise = null;\n\n constructor() {\n if (\n (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\")) &&\n this.constructor === BasePreferences\n ) {\n throw new Error(\"Cannot initialize BasePreferences.\");\n }\n\n this.#initializedPromise = this._readFromStorage(this.#defaults).then(\n ({ browserPrefs, prefs }) => {\n if (\n (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"GENERIC\")) &&\n AppOptions._checkDisablePreferences()\n ) {\n return;\n }\n AppOptions.setAll({ ...browserPrefs, ...prefs }, /* prefs = */ true);\n }\n );\n\n if (typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"MOZCENTRAL\")) {\n window.addEventListener(\n \"updatedPreference\",\n async ({ detail: { name, value } }) => {\n await this.#initializedPromise;\n AppOptions.setAll({ [name]: value }, /* prefs = */ true);\n }\n );\n }\n }\n\n /**\n * Stub function for writing preferences to storage.\n * @param {Object} prefObj The preferences that should be written to storage.\n * @returns {Promise} A promise that is resolved when the preference values\n * have been written.\n */\n async _writeToStorage(prefObj) {\n throw new Error(\"Not implemented: _writeToStorage\");\n }\n\n /**\n * Stub function for reading preferences from storage.\n * @param {Object} prefObj The preferences that should be read from storage.\n * @returns {Promise} A promise that is resolved with an {Object} containing\n * the preferences that have been read.\n */\n async _readFromStorage(prefObj) {\n throw new Error(\"Not implemented: _readFromStorage\");\n }\n\n /**\n * Reset the preferences to their default values and update storage.\n * @returns {Promise} A promise that is resolved when the preference values\n * have been reset.\n */\n async reset() {\n if (typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"MOZCENTRAL\")) {\n throw new Error(\"Please use `about:config` to change preferences.\");\n }\n await this.#initializedPromise;\n AppOptions.setAll(this.#defaults, /* prefs = */ true);\n\n await this._writeToStorage(this.#defaults);\n }\n\n /**\n * Set the value of a preference.\n * @param {string} name The name of the preference that should be changed.\n * @param {boolean|number|string} value The new value of the preference.\n * @returns {Promise} A promise that is resolved when the value has been set,\n * provided that the preference exists and the types match.\n */\n async set(name, value) {\n await this.#initializedPromise;\n AppOptions.setAll({ [name]: value }, /* prefs = */ true);\n\n await this._writeToStorage(\n typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"MOZCENTRAL\")\n ? { [name]: AppOptions.get(name) }\n : AppOptions.getAll(OptionKind.PREFERENCE)\n );\n }\n\n /**\n * Get the value of a preference.\n * @param {string} name The name of the preference whose value is requested.\n * @returns {Promise} A promise resolved with a {boolean|number|string}\n * containing the value of the preference.\n */\n async get(name) {\n if (typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"MOZCENTRAL\")) {\n throw new Error(\"Not implemented: get\");\n }\n await this.#initializedPromise;\n return AppOptions.get(name);\n }\n\n get defaults() {\n return this.#defaults;\n }\n\n get initializedPromise() {\n return this.#initializedPromise;\n }\n}\n\nexport { BasePreferences };\n","/**\n * The `FluentType` class is the base of Fluent's type system.\n *\n * Fluent types wrap JavaScript values and store additional configuration for\n * them, which can then be used in the `toString` method together with a proper\n * `Intl` formatter.\n */\nexport class FluentType {\n /**\n * Create a `FluentType` instance.\n *\n * @param value The JavaScript value to wrap.\n */\n constructor(value) {\n this.value = value;\n }\n /**\n * Unwrap the raw value stored by this `FluentType`.\n */\n valueOf() {\n return this.value;\n }\n}\n/**\n * A {@link FluentType} representing no correct value.\n */\nexport class FluentNone extends FluentType {\n /**\n * Create an instance of `FluentNone` with an optional fallback value.\n * @param value The fallback value of this `FluentNone`.\n */\n constructor(value = \"???\") {\n super(value);\n }\n /**\n * Format this `FluentNone` to the fallback string.\n */\n toString(scope) {\n return `{${this.value}}`;\n }\n}\n/**\n * A {@link FluentType} representing a number.\n *\n * A `FluentNumber` instance stores the number value of the number it\n * represents. It may also store an option bag of options which will be passed\n * to `Intl.NumerFormat` when the `FluentNumber` is formatted to a string.\n */\nexport class FluentNumber extends FluentType {\n /**\n * Create an instance of `FluentNumber` with options to the\n * `Intl.NumberFormat` constructor.\n *\n * @param value The number value of this `FluentNumber`.\n * @param opts Options which will be passed to `Intl.NumberFormat`.\n */\n constructor(value, opts = {}) {\n super(value);\n this.opts = opts;\n }\n /**\n * Format this `FluentNumber` to a string.\n */\n toString(scope) {\n if (scope) {\n try {\n const nf = scope.memoizeIntlObject(Intl.NumberFormat, this.opts);\n return nf.format(this.value);\n }\n catch (err) {\n scope.reportError(err);\n }\n }\n return this.value.toString(10);\n }\n}\n/**\n * A {@link FluentType} representing a date and time.\n *\n * A `FluentDateTime` instance stores a Date object, Temporal object, or a number\n * as a numerical timestamp in milliseconds. It may also store an\n * option bag of options which will be passed to `Intl.DateTimeFormat` when the\n * `FluentDateTime` is formatted to a string.\n */\nexport class FluentDateTime extends FluentType {\n static supportsValue(value) {\n if (typeof value === \"number\")\n return true;\n if (value instanceof Date)\n return true;\n if (value instanceof FluentType)\n return FluentDateTime.supportsValue(value.valueOf());\n // Temporary workaround to support environments without Temporal\n if (\"Temporal\" in globalThis) {\n // for TypeScript, which doesn't know about Temporal yet\n const _Temporal = globalThis.Temporal;\n if (value instanceof _Temporal.Instant ||\n value instanceof _Temporal.PlainDateTime ||\n value instanceof _Temporal.PlainDate ||\n value instanceof _Temporal.PlainMonthDay ||\n value instanceof _Temporal.PlainTime ||\n value instanceof _Temporal.PlainYearMonth) {\n return true;\n }\n }\n return false;\n }\n /**\n * Create an instance of `FluentDateTime` with options to the\n * `Intl.DateTimeFormat` constructor.\n *\n * @param value The number value of this `FluentDateTime`, in milliseconds.\n * @param opts Options which will be passed to `Intl.DateTimeFormat`.\n */\n constructor(value, opts = {}) {\n // unwrap any FluentType value, but only retain the opts from FluentDateTime\n if (value instanceof FluentDateTime) {\n opts = { ...value.opts, ...opts };\n value = value.value;\n }\n else if (value instanceof FluentType) {\n value = value.valueOf();\n }\n // Intl.DateTimeFormat defaults to gregorian calendar, but Temporal defaults to iso8601\n if (typeof value === \"object\" &&\n \"calendarId\" in value &&\n opts.calendar === undefined) {\n opts = { ...opts, calendar: value.calendarId };\n }\n super(value);\n this.opts = opts;\n }\n [Symbol.toPrimitive](hint) {\n return hint === \"string\" ? this.toString() : this.toNumber();\n }\n /**\n * Convert this `FluentDateTime` to a number.\n * Note that this isn't always possible due to the nature of Temporal objects.\n * In such cases, a TypeError will be thrown.\n */\n toNumber() {\n const value = this.value;\n if (typeof value === \"number\")\n return value;\n if (value instanceof Date)\n return value.getTime();\n if (\"epochMilliseconds\" in value) {\n return value.epochMilliseconds;\n }\n if (\"toZonedDateTime\" in value) {\n return value.toZonedDateTime(\"UTC\").epochMilliseconds;\n }\n throw new TypeError(\"Unwrapping a non-number value as a number\");\n }\n /**\n * Format this `FluentDateTime` to a string.\n */\n toString(scope) {\n if (scope) {\n try {\n const dtf = scope.memoizeIntlObject(Intl.DateTimeFormat, this.opts);\n return dtf.format(this.value);\n }\n catch (err) {\n scope.reportError(err);\n }\n }\n if (typeof this.value === \"number\" || this.value instanceof Date) {\n return new Date(this.value).toISOString();\n }\n return this.value.toString();\n }\n}\n","/**\n * The role of the Fluent resolver is to format a `Pattern` to an instance of\n * `FluentValue`. For performance reasons, primitive strings are considered\n * such instances, too.\n *\n * Translations can contain references to other messages or variables,\n * conditional logic in form of select expressions, traits which describe their\n * grammatical features, and can use Fluent builtins which make use of the\n * `Intl` formatters to format numbers and dates into the bundle's languages.\n * See the documentation of the Fluent syntax for more information.\n *\n * In case of errors the resolver will try to salvage as much of the\n * translation as possible. In rare situations where the resolver didn't know\n * how to recover from an error it will return an instance of `FluentNone`.\n *\n * All expressions resolve to an instance of `FluentValue`. The caller should\n * use the `toString` method to convert the instance to a native value.\n *\n * Functions in this file pass around an instance of the `Scope` class, which\n * stores the data required for successful resolution and error recovery.\n */\nimport { FluentType, FluentNone, FluentNumber, FluentDateTime, } from \"./types.js\";\n/**\n * The maximum number of placeables which can be expanded in a single call to\n * `formatPattern`. The limit protects against the Billion Laughs and Quadratic\n * Blowup attacks. See https://msdn.microsoft.com/en-us/magazine/ee335713.aspx.\n */\nconst MAX_PLACEABLES = 100;\n/** Unicode bidi isolation characters. */\nconst FSI = \"\\u2068\";\nconst PDI = \"\\u2069\";\n/** Helper: match a variant key to the given selector. */\nfunction match(scope, selector, key) {\n if (key === selector) {\n // Both are strings.\n return true;\n }\n // XXX Consider comparing options too, e.g. minimumFractionDigits.\n if (key instanceof FluentNumber &&\n selector instanceof FluentNumber &&\n key.value === selector.value) {\n return true;\n }\n if (selector instanceof FluentNumber && typeof key === \"string\") {\n let category = scope\n .memoizeIntlObject(Intl.PluralRules, selector.opts)\n .select(selector.value);\n if (key === category) {\n return true;\n }\n }\n return false;\n}\n/** Helper: resolve the default variant from a list of variants. */\nfunction getDefault(scope, variants, star) {\n if (variants[star]) {\n return resolvePattern(scope, variants[star].value);\n }\n scope.reportError(new RangeError(\"No default\"));\n return new FluentNone();\n}\n/** Helper: resolve arguments to a call expression. */\nfunction getArguments(scope, args) {\n const positional = [];\n const named = Object.create(null);\n for (const arg of args) {\n if (arg.type === \"narg\") {\n named[arg.name] = resolveExpression(scope, arg.value);\n }\n else {\n positional.push(resolveExpression(scope, arg));\n }\n }\n return { positional, named };\n}\n/** Resolve an expression to a Fluent type. */\nfunction resolveExpression(scope, expr) {\n switch (expr.type) {\n case \"str\":\n return expr.value;\n case \"num\":\n return new FluentNumber(expr.value, {\n minimumFractionDigits: expr.precision,\n });\n case \"var\":\n return resolveVariableReference(scope, expr);\n case \"mesg\":\n return resolveMessageReference(scope, expr);\n case \"term\":\n return resolveTermReference(scope, expr);\n case \"func\":\n return resolveFunctionReference(scope, expr);\n case \"select\":\n return resolveSelectExpression(scope, expr);\n default:\n return new FluentNone();\n }\n}\n/** Resolve a reference to a variable. */\nfunction resolveVariableReference(scope, { name }) {\n let arg;\n if (scope.params) {\n // We're inside a TermReference. It's OK to reference undefined parameters.\n if (Object.prototype.hasOwnProperty.call(scope.params, name)) {\n arg = scope.params[name];\n }\n else {\n return new FluentNone(`$${name}`);\n }\n }\n else if (scope.args &&\n Object.prototype.hasOwnProperty.call(scope.args, name)) {\n // We're in the top-level Pattern or inside a MessageReference. Missing\n // variables references produce ReferenceErrors.\n arg = scope.args[name];\n }\n else {\n scope.reportError(new ReferenceError(`Unknown variable: $${name}`));\n return new FluentNone(`$${name}`);\n }\n // Return early if the argument already is an instance of FluentType.\n if (arg instanceof FluentType) {\n return arg;\n }\n // Convert the argument to a Fluent type.\n switch (typeof arg) {\n case \"string\":\n return arg;\n case \"number\":\n return new FluentNumber(arg);\n case \"object\":\n if (FluentDateTime.supportsValue(arg)) {\n return new FluentDateTime(arg);\n }\n // eslint-disable-next-line no-fallthrough\n default:\n scope.reportError(new TypeError(`Variable type not supported: $${name}, ${typeof arg}`));\n return new FluentNone(`$${name}`);\n }\n}\n/** Resolve a reference to another message. */\nfunction resolveMessageReference(scope, { name, attr }) {\n const message = scope.bundle._messages.get(name);\n if (!message) {\n scope.reportError(new ReferenceError(`Unknown message: ${name}`));\n return new FluentNone(name);\n }\n if (attr) {\n const attribute = message.attributes[attr];\n if (attribute) {\n return resolvePattern(scope, attribute);\n }\n scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`));\n return new FluentNone(`${name}.${attr}`);\n }\n if (message.value) {\n return resolvePattern(scope, message.value);\n }\n scope.reportError(new ReferenceError(`No value: ${name}`));\n return new FluentNone(name);\n}\n/** Resolve a call to a Term with key-value arguments. */\nfunction resolveTermReference(scope, { name, attr, args }) {\n const id = `-${name}`;\n const term = scope.bundle._terms.get(id);\n if (!term) {\n scope.reportError(new ReferenceError(`Unknown term: ${id}`));\n return new FluentNone(id);\n }\n if (attr) {\n const attribute = term.attributes[attr];\n if (attribute) {\n // Every TermReference has its own variables.\n scope.params = getArguments(scope, args).named;\n const resolved = resolvePattern(scope, attribute);\n scope.params = null;\n return resolved;\n }\n scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`));\n return new FluentNone(`${id}.${attr}`);\n }\n scope.params = getArguments(scope, args).named;\n const resolved = resolvePattern(scope, term.value);\n scope.params = null;\n return resolved;\n}\n/** Resolve a call to a Function with positional and key-value arguments. */\nfunction resolveFunctionReference(scope, { name, args }) {\n // Some functions are built-in. Others may be provided by the runtime via\n // the `FluentBundle` constructor.\n let func = scope.bundle._functions[name];\n if (!func) {\n scope.reportError(new ReferenceError(`Unknown function: ${name}()`));\n return new FluentNone(`${name}()`);\n }\n if (typeof func !== \"function\") {\n scope.reportError(new TypeError(`Function ${name}() is not callable`));\n return new FluentNone(`${name}()`);\n }\n try {\n let resolved = getArguments(scope, args);\n return func(resolved.positional, resolved.named);\n }\n catch (err) {\n scope.reportError(err);\n return new FluentNone(`${name}()`);\n }\n}\n/** Resolve a select expression to the member object. */\nfunction resolveSelectExpression(scope, { selector, variants, star }) {\n let sel = resolveExpression(scope, selector);\n if (sel instanceof FluentNone) {\n return getDefault(scope, variants, star);\n }\n // Match the selector against keys of each variant, in order.\n for (const variant of variants) {\n const key = resolveExpression(scope, variant.key);\n if (match(scope, sel, key)) {\n return resolvePattern(scope, variant.value);\n }\n }\n return getDefault(scope, variants, star);\n}\n/** Resolve a pattern (a complex string with placeables). */\nexport function resolveComplexPattern(scope, ptn) {\n if (scope.dirty.has(ptn)) {\n scope.reportError(new RangeError(\"Cyclic reference\"));\n return new FluentNone();\n }\n // Tag the pattern as dirty for the purpose of the current resolution.\n scope.dirty.add(ptn);\n const result = [];\n // Wrap interpolations with Directional Isolate Formatting characters\n // only when the pattern has more than one element.\n const useIsolating = scope.bundle._useIsolating && ptn.length > 1;\n for (const elem of ptn) {\n if (typeof elem === \"string\") {\n result.push(scope.bundle._transform(elem));\n continue;\n }\n scope.placeables++;\n if (scope.placeables > MAX_PLACEABLES) {\n scope.dirty.delete(ptn);\n // This is a fatal error which causes the resolver to instantly bail out\n // on this pattern. The length check protects against excessive memory\n // usage, and throwing protects against eating up the CPU when long\n // placeables are deeply nested.\n throw new RangeError(`Too many placeables expanded: ${scope.placeables}, ` +\n `max allowed is ${MAX_PLACEABLES}`);\n }\n if (useIsolating) {\n result.push(FSI);\n }\n result.push(resolveExpression(scope, elem).toString(scope));\n if (useIsolating) {\n result.push(PDI);\n }\n }\n scope.dirty.delete(ptn);\n return result.join(\"\");\n}\n/**\n * Resolve a simple or a complex Pattern to a FluentString\n * (which is really the string primitive).\n */\nfunction resolvePattern(scope, value) {\n // Resolve a simple pattern.\n if (typeof value === \"string\") {\n return scope.bundle._transform(value);\n }\n return resolveComplexPattern(scope, value);\n}\n","export class Scope {\n constructor(bundle, errors, args) {\n /**\n * The Set of patterns already encountered during this resolution.\n * Used to detect and prevent cyclic resolutions.\n * @ignore\n */\n this.dirty = new WeakSet();\n /** A dict of parameters passed to a TermReference. */\n this.params = null;\n /**\n * The running count of placeables resolved so far.\n * Used to detect the Billion Laughs and Quadratic Blowup attacks.\n * @ignore\n */\n this.placeables = 0;\n this.bundle = bundle;\n this.errors = errors;\n this.args = args;\n }\n reportError(error) {\n if (!this.errors || !(error instanceof Error)) {\n throw error;\n }\n this.errors.push(error);\n }\n memoizeIntlObject(ctor, opts) {\n let cache = this.bundle._intls.get(ctor);\n if (!cache) {\n cache = {};\n this.bundle._intls.set(ctor, cache);\n }\n let id = JSON.stringify(opts);\n if (!cache[id]) {\n // @ts-expect-error This is fine.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n cache[id] = new ctor(this.bundle.locales, opts);\n }\n return cache[id];\n }\n}\n","/**\n * @overview\n *\n * The FTL resolver ships with a number of functions built-in.\n *\n * Each function take two arguments:\n * - args - an array of positional args\n * - opts - an object of key-value args\n *\n * Arguments to functions are guaranteed to already be instances of\n * `FluentValue`. Functions must return `FluentValues` as well.\n */\nimport { FluentNone, FluentNumber, FluentDateTime, } from \"./types.js\";\nfunction values(opts, allowed) {\n const unwrapped = Object.create(null);\n for (const [name, opt] of Object.entries(opts)) {\n if (allowed.includes(name)) {\n unwrapped[name] = opt.valueOf();\n }\n }\n return unwrapped;\n}\nconst NUMBER_ALLOWED = [\n \"unitDisplay\",\n \"currencyDisplay\",\n \"useGrouping\",\n \"minimumIntegerDigits\",\n \"minimumFractionDigits\",\n \"maximumFractionDigits\",\n \"minimumSignificantDigits\",\n \"maximumSignificantDigits\",\n];\n/**\n * The implementation of the `NUMBER()` builtin available to translations.\n *\n * Translations may call the `NUMBER()` builtin in order to specify formatting\n * options of a number. For example:\n *\n * pi = The value of Ļ€ is {NUMBER($pi, maximumFractionDigits: 2)}.\n *\n * The implementation expects an array of {@link FluentValue | FluentValues} representing the\n * positional arguments, and an object of named {@link FluentValue | FluentValues} representing the\n * named parameters.\n *\n * The following options are recognized:\n *\n * unitDisplay\n * currencyDisplay\n * useGrouping\n * minimumIntegerDigits\n * minimumFractionDigits\n * maximumFractionDigits\n * minimumSignificantDigits\n * maximumSignificantDigits\n *\n * Other options are ignored.\n *\n * @param args The positional arguments passed to this `NUMBER()`.\n * @param opts The named argments passed to this `NUMBER()`.\n */\nexport function NUMBER(args, opts) {\n let arg = args[0];\n if (arg instanceof FluentNone) {\n return new FluentNone(`NUMBER(${arg.valueOf()})`);\n }\n if (arg instanceof FluentNumber) {\n return new FluentNumber(arg.valueOf(), {\n ...arg.opts,\n ...values(opts, NUMBER_ALLOWED),\n });\n }\n if (arg instanceof FluentDateTime) {\n return new FluentNumber(arg.toNumber(), {\n ...values(opts, NUMBER_ALLOWED),\n });\n }\n throw new TypeError(\"Invalid argument to NUMBER\");\n}\nconst DATETIME_ALLOWED = [\n \"dateStyle\",\n \"timeStyle\",\n \"fractionalSecondDigits\",\n \"dayPeriod\",\n \"hour12\",\n \"weekday\",\n \"era\",\n \"year\",\n \"month\",\n \"day\",\n \"hour\",\n \"minute\",\n \"second\",\n \"timeZoneName\",\n];\n/**\n * The implementation of the `DATETIME()` builtin available to translations.\n *\n * Translations may call the `DATETIME()` builtin in order to specify\n * formatting options of a number. For example:\n *\n * now = It's {DATETIME($today, month: \"long\")}.\n *\n * The implementation expects an array of {@link FluentValue | FluentValues} representing the\n * positional arguments, and an object of named {@link FluentValue | FluentValues} representing the\n * named parameters.\n *\n * The following options are recognized:\n *\n * dateStyle\n * timeStyle\n * fractionalSecondDigits\n * dayPeriod\n * hour12\n * weekday\n * era\n * year\n * month\n * day\n * hour\n * minute\n * second\n * timeZoneName\n *\n * Other options are ignored.\n *\n * @param args The positional arguments passed to this `DATETIME()`.\n * @param opts The named argments passed to this `DATETIME()`.\n */\nexport function DATETIME(args, opts) {\n let arg = args[0];\n if (arg instanceof FluentNone) {\n return new FluentNone(`DATETIME(${arg.valueOf()})`);\n }\n if (arg instanceof FluentDateTime || arg instanceof FluentNumber) {\n return new FluentDateTime(arg, values(opts, DATETIME_ALLOWED));\n }\n throw new TypeError(\"Invalid argument to DATETIME\");\n}\n","const cache = new Map();\nexport function getMemoizerForLocale(locales) {\n const stringLocale = Array.isArray(locales) ? locales.join(\" \") : locales;\n let memoizer = cache.get(stringLocale);\n if (memoizer === undefined) {\n memoizer = new Map();\n cache.set(stringLocale, memoizer);\n }\n return memoizer;\n}\n","import { resolveComplexPattern } from \"./resolver.js\";\nimport { Scope } from \"./scope.js\";\nimport { FluentNone } from \"./types.js\";\nimport { NUMBER, DATETIME } from \"./builtins.js\";\nimport { getMemoizerForLocale } from \"./memoizer.js\";\n/**\n * Message bundles are single-language stores of translation resources. They are\n * responsible for formatting message values and attributes to strings.\n */\nexport class FluentBundle {\n /**\n * Create an instance of `FluentBundle`.\n *\n * @example\n * ```js\n * let bundle = new FluentBundle([\"en-US\", \"en\"]);\n *\n * let bundle = new FluentBundle(locales, {useIsolating: false});\n *\n * let bundle = new FluentBundle(locales, {\n * useIsolating: true,\n * functions: {\n * NODE_ENV: () => process.env.NODE_ENV\n * }\n * });\n * ```\n *\n * @param locales - Used to instantiate `Intl` formatters used by translations.\n * @param options - Optional configuration for the bundle.\n */\n constructor(locales, { functions, useIsolating = true, transform = (v) => v, } = {}) {\n /** @ignore */\n this._terms = new Map();\n /** @ignore */\n this._messages = new Map();\n this.locales = Array.isArray(locales) ? locales : [locales];\n this._functions = {\n NUMBER,\n DATETIME,\n ...functions,\n };\n this._useIsolating = useIsolating;\n this._transform = transform;\n this._intls = getMemoizerForLocale(locales);\n }\n /**\n * Check if a message is present in the bundle.\n *\n * @param id - The identifier of the message to check.\n */\n hasMessage(id) {\n return this._messages.has(id);\n }\n /**\n * Return a raw unformatted message object from the bundle.\n *\n * Raw messages are `{value, attributes}` shapes containing translation units\n * called `Patterns`. `Patterns` are implementation-specific; they should be\n * treated as black boxes and formatted with `FluentBundle.formatPattern`.\n *\n * @param id - The identifier of the message to check.\n */\n getMessage(id) {\n return this._messages.get(id);\n }\n /**\n * Add a translation resource to the bundle.\n *\n * @example\n * ```js\n * let res = new FluentResource(\"foo = Foo\");\n * bundle.addResource(res);\n * bundle.getMessage(\"foo\");\n * // → {value: .., attributes: {..}}\n * ```\n *\n * @param res\n * @param options\n */\n addResource(res, { allowOverrides = false, } = {}) {\n const errors = [];\n for (let i = 0; i < res.body.length; i++) {\n let entry = res.body[i];\n if (entry.id.startsWith(\"-\")) {\n // Identifiers starting with a dash (-) define terms. Terms are private\n // and cannot be retrieved from FluentBundle.\n if (allowOverrides === false && this._terms.has(entry.id)) {\n errors.push(new Error(`Attempt to override an existing term: \"${entry.id}\"`));\n continue;\n }\n this._terms.set(entry.id, entry);\n }\n else {\n if (allowOverrides === false && this._messages.has(entry.id)) {\n errors.push(new Error(`Attempt to override an existing message: \"${entry.id}\"`));\n continue;\n }\n this._messages.set(entry.id, entry);\n }\n }\n return errors;\n }\n /**\n * Format a `Pattern` to a string.\n *\n * Format a raw `Pattern` into a string. `args` will be used to resolve\n * references to variables passed as arguments to the translation.\n *\n * In case of errors `formatPattern` will try to salvage as much of the\n * translation as possible and will still return a string. For performance\n * reasons, the encountered errors are not returned but instead are appended\n * to the `errors` array passed as the third argument.\n *\n * If `errors` is omitted, the first encountered error will be thrown.\n *\n * @example\n * ```js\n * let errors = [];\n * bundle.addResource(\n * new FluentResource(\"hello = Hello, {$name}!\"));\n *\n * let hello = bundle.getMessage(\"hello\");\n * if (hello.value) {\n * bundle.formatPattern(hello.value, {name: \"Jane\"}, errors);\n * // Returns \"Hello, Jane!\" and `errors` is empty.\n *\n * bundle.formatPattern(hello.value, undefined, errors);\n * // Returns \"Hello, {$name}!\" and `errors` is now:\n * // []\n * }\n * ```\n */\n formatPattern(pattern, args = null, errors = null) {\n // Resolve a simple pattern without creating a scope. No error handling is\n // required; by definition simple patterns don't have placeables.\n if (typeof pattern === \"string\") {\n return this._transform(pattern);\n }\n // Resolve a complex pattern.\n let scope = new Scope(this, errors, args);\n try {\n let value = resolveComplexPattern(scope, pattern);\n return value.toString(scope);\n }\n catch (err) {\n if (scope.errors && err instanceof Error) {\n scope.errors.push(err);\n return new FluentNone().toString(scope);\n }\n throw err;\n }\n }\n}\n","// This regex is used to iterate through the beginnings of messages and terms.\n// With the /m flag, the ^ matches at the beginning of every line.\nconst RE_MESSAGE_START = /^(-?[a-zA-Z][\\w-]*) *= */gm;\n// Both Attributes and Variants are parsed in while loops. These regexes are\n// used to break out of them.\nconst RE_ATTRIBUTE_START = /\\.([a-zA-Z][\\w-]*) *= */y;\nconst RE_VARIANT_START = /\\*?\\[/y;\nconst RE_NUMBER_LITERAL = /(-?[0-9]+(?:\\.([0-9]+))?)/y;\nconst RE_IDENTIFIER = /([a-zA-Z][\\w-]*)/y;\nconst RE_REFERENCE = /([$-])?([a-zA-Z][\\w-]*)(?:\\.([a-zA-Z][\\w-]*))?/y;\nconst RE_FUNCTION_NAME = /^[A-Z][A-Z0-9_-]*$/;\n// A \"run\" is a sequence of text or string literal characters which don't\n// require any special handling. For TextElements such special characters are: {\n// (starts a placeable), and line breaks which require additional logic to check\n// if the next line is indented. For StringLiterals they are: \\ (starts an\n// escape sequence), \" (ends the literal), and line breaks which are not allowed\n// in StringLiterals. Note that string runs may be empty; text runs may not.\nconst RE_TEXT_RUN = /([^{}\\n\\r]+)/y;\nconst RE_STRING_RUN = /([^\\\\\"\\n\\r]*)/y;\n// Escape sequences.\nconst RE_STRING_ESCAPE = /\\\\([\\\\\"])/y;\nconst RE_UNICODE_ESCAPE = /\\\\u([a-fA-F0-9]{4})|\\\\U([a-fA-F0-9]{6})/y;\n// Used for trimming TextElements and indents.\nconst RE_LEADING_NEWLINES = /^\\n+/;\nconst RE_TRAILING_SPACES = / +$/;\n// Used in makeIndent to strip spaces from blank lines and normalize CRLF to LF.\nconst RE_BLANK_LINES = / *\\r?\\n/g;\n// Used in makeIndent to measure the indentation.\nconst RE_INDENT = /( *)$/;\n// Common tokens.\nconst TOKEN_BRACE_OPEN = /{\\s*/y;\nconst TOKEN_BRACE_CLOSE = /\\s*}/y;\nconst TOKEN_BRACKET_OPEN = /\\[\\s*/y;\nconst TOKEN_BRACKET_CLOSE = /\\s*] */y;\nconst TOKEN_PAREN_OPEN = /\\s*\\(\\s*/y;\nconst TOKEN_ARROW = /\\s*->\\s*/y;\nconst TOKEN_COLON = /\\s*:\\s*/y;\n// Note the optional comma. As a deviation from the Fluent EBNF, the parser\n// doesn't enforce commas between call arguments.\nconst TOKEN_COMMA = /\\s*,?\\s*/y;\nconst TOKEN_BLANK = /\\s+/y;\n/**\n * Fluent Resource is a structure storing parsed localization entries.\n */\nexport class FluentResource {\n constructor(source) {\n this.body = [];\n RE_MESSAGE_START.lastIndex = 0;\n let cursor = 0;\n // Iterate over the beginnings of messages and terms to efficiently skip\n // comments and recover from errors.\n while (true) {\n let next = RE_MESSAGE_START.exec(source);\n if (next === null) {\n break;\n }\n cursor = RE_MESSAGE_START.lastIndex;\n try {\n this.body.push(parseMessage(next[1]));\n }\n catch (err) {\n if (err instanceof SyntaxError) {\n // Don't report any Fluent syntax errors. Skip directly to the\n // beginning of the next message or term.\n continue;\n }\n throw err;\n }\n }\n // The parser implementation is inlined below for performance reasons,\n // as well as for convenience of accessing `source` and `cursor`.\n // The parser focuses on minimizing the number of false negatives at the\n // expense of increasing the risk of false positives. In other words, it\n // aims at parsing valid Fluent messages with a success rate of 100%, but it\n // may also parse a few invalid messages which the reference parser would\n // reject. The parser doesn't perform any validation and may produce entries\n // which wouldn't make sense in the real world. For best results users are\n // advised to validate translations with the fluent-syntax parser\n // pre-runtime.\n // The parser makes an extensive use of sticky regexes which can be anchored\n // to any offset of the source string without slicing it. Errors are thrown\n // to bail out of parsing of ill-formed messages.\n function test(re) {\n re.lastIndex = cursor;\n return re.test(source);\n }\n // Advance the cursor by the char if it matches. May be used as a predicate\n // (was the match found?) or, if errorClass is passed, as an assertion.\n function consumeChar(char, errorClass) {\n if (source[cursor] === char) {\n cursor++;\n return true;\n }\n if (errorClass) {\n throw new errorClass(`Expected ${char}`);\n }\n return false;\n }\n // Advance the cursor by the token if it matches. May be used as a predicate\n // (was the match found?) or, if errorClass is passed, as an assertion.\n function consumeToken(re, errorClass) {\n if (test(re)) {\n cursor = re.lastIndex;\n return true;\n }\n if (errorClass) {\n throw new errorClass(`Expected ${re.toString()}`);\n }\n return false;\n }\n // Execute a regex, advance the cursor, and return all capture groups.\n function match(re) {\n re.lastIndex = cursor;\n let result = re.exec(source);\n if (result === null) {\n throw new SyntaxError(`Expected ${re.toString()}`);\n }\n cursor = re.lastIndex;\n return result;\n }\n // Execute a regex, advance the cursor, and return the capture group.\n function match1(re) {\n return match(re)[1];\n }\n function parseMessage(id) {\n let value = parsePattern();\n let attributes = parseAttributes();\n if (value === null && Object.keys(attributes).length === 0) {\n throw new SyntaxError(\"Expected message value or attributes\");\n }\n return { id, value, attributes };\n }\n function parseAttributes() {\n let attrs = Object.create(null);\n while (test(RE_ATTRIBUTE_START)) {\n let name = match1(RE_ATTRIBUTE_START);\n let value = parsePattern();\n if (value === null) {\n throw new SyntaxError(\"Expected attribute value\");\n }\n attrs[name] = value;\n }\n return attrs;\n }\n function parsePattern() {\n let first;\n // First try to parse any simple text on the same line as the id.\n if (test(RE_TEXT_RUN)) {\n first = match1(RE_TEXT_RUN);\n }\n // If there's a placeable on the first line, parse a complex pattern.\n if (source[cursor] === \"{\" || source[cursor] === \"}\") {\n // Re-use the text parsed above, if possible.\n return parsePatternElements(first ? [first] : [], Infinity);\n }\n // RE_TEXT_VALUE stops at newlines. Only continue parsing the pattern if\n // what comes after the newline is indented.\n let indent = parseIndent();\n if (indent) {\n if (first) {\n // If there's text on the first line, the blank block is part of the\n // translation content in its entirety.\n return parsePatternElements([first, indent], indent.length);\n }\n // Otherwise, we're dealing with a block pattern, i.e. a pattern which\n // starts on a new line. Discrad the leading newlines but keep the\n // inline indent; it will be used by the dedentation logic.\n indent.value = trim(indent.value, RE_LEADING_NEWLINES);\n return parsePatternElements([indent], indent.length);\n }\n if (first) {\n // It was just a simple inline text after all.\n return trim(first, RE_TRAILING_SPACES);\n }\n return null;\n }\n // Parse a complex pattern as an array of elements.\n function parsePatternElements(elements = [], commonIndent) {\n while (true) {\n if (test(RE_TEXT_RUN)) {\n elements.push(match1(RE_TEXT_RUN));\n continue;\n }\n if (source[cursor] === \"{\") {\n elements.push(parsePlaceable());\n continue;\n }\n if (source[cursor] === \"}\") {\n throw new SyntaxError(\"Unbalanced closing brace\");\n }\n let indent = parseIndent();\n if (indent) {\n elements.push(indent);\n commonIndent = Math.min(commonIndent, indent.length);\n continue;\n }\n break;\n }\n let lastIndex = elements.length - 1;\n let lastElement = elements[lastIndex];\n // Trim the trailing spaces in the last element if it's a TextElement.\n if (typeof lastElement === \"string\") {\n elements[lastIndex] = trim(lastElement, RE_TRAILING_SPACES);\n }\n let baked = [];\n for (let element of elements) {\n if (element instanceof Indent) {\n // Dedent indented lines by the maximum common indent.\n element = element.value.slice(0, element.value.length - commonIndent);\n }\n if (element) {\n baked.push(element);\n }\n }\n return baked;\n }\n function parsePlaceable() {\n consumeToken(TOKEN_BRACE_OPEN, SyntaxError);\n let selector = parseInlineExpression();\n if (consumeToken(TOKEN_BRACE_CLOSE)) {\n return selector;\n }\n if (consumeToken(TOKEN_ARROW)) {\n let variants = parseVariants();\n consumeToken(TOKEN_BRACE_CLOSE, SyntaxError);\n return {\n type: \"select\",\n selector,\n ...variants,\n };\n }\n throw new SyntaxError(\"Unclosed placeable\");\n }\n function parseInlineExpression() {\n if (source[cursor] === \"{\") {\n // It's a nested placeable.\n return parsePlaceable();\n }\n if (test(RE_REFERENCE)) {\n let [, sigil, name, attr = null] = match(RE_REFERENCE);\n if (sigil === \"$\") {\n return { type: \"var\", name };\n }\n if (consumeToken(TOKEN_PAREN_OPEN)) {\n let args = parseArguments();\n if (sigil === \"-\") {\n // A parameterized term: -term(...).\n return { type: \"term\", name, attr, args };\n }\n if (RE_FUNCTION_NAME.test(name)) {\n return { type: \"func\", name, args };\n }\n throw new SyntaxError(\"Function names must be all upper-case\");\n }\n if (sigil === \"-\") {\n // A non-parameterized term: -term.\n return {\n type: \"term\",\n name,\n attr,\n args: [],\n };\n }\n return { type: \"mesg\", name, attr };\n }\n return parseLiteral();\n }\n function parseArguments() {\n let args = [];\n while (true) {\n switch (source[cursor]) {\n case \")\": // End of the argument list.\n cursor++;\n return args;\n case undefined: // EOF\n throw new SyntaxError(\"Unclosed argument list\");\n }\n args.push(parseArgument());\n // Commas between arguments are treated as whitespace.\n consumeToken(TOKEN_COMMA);\n }\n }\n function parseArgument() {\n let expr = parseInlineExpression();\n if (expr.type !== \"mesg\") {\n return expr;\n }\n if (consumeToken(TOKEN_COLON)) {\n // The reference is the beginning of a named argument.\n return {\n type: \"narg\",\n name: expr.name,\n value: parseLiteral(),\n };\n }\n // It's a regular message reference.\n return expr;\n }\n function parseVariants() {\n let variants = [];\n let count = 0;\n let star;\n while (test(RE_VARIANT_START)) {\n if (consumeChar(\"*\")) {\n star = count;\n }\n let key = parseVariantKey();\n let value = parsePattern();\n if (value === null) {\n throw new SyntaxError(\"Expected variant value\");\n }\n variants[count++] = { key, value };\n }\n if (count === 0) {\n return null;\n }\n if (star === undefined) {\n throw new SyntaxError(\"Expected default variant\");\n }\n return { variants, star };\n }\n function parseVariantKey() {\n consumeToken(TOKEN_BRACKET_OPEN, SyntaxError);\n let key;\n if (test(RE_NUMBER_LITERAL)) {\n key = parseNumberLiteral();\n }\n else {\n key = {\n type: \"str\",\n value: match1(RE_IDENTIFIER),\n };\n }\n consumeToken(TOKEN_BRACKET_CLOSE, SyntaxError);\n return key;\n }\n function parseLiteral() {\n if (test(RE_NUMBER_LITERAL)) {\n return parseNumberLiteral();\n }\n if (source[cursor] === '\"') {\n return parseStringLiteral();\n }\n throw new SyntaxError(\"Invalid expression\");\n }\n function parseNumberLiteral() {\n let [, value, fraction = \"\"] = match(RE_NUMBER_LITERAL);\n let precision = fraction.length;\n return {\n type: \"num\",\n value: parseFloat(value),\n precision,\n };\n }\n function parseStringLiteral() {\n consumeChar('\"', SyntaxError);\n let value = \"\";\n while (true) {\n value += match1(RE_STRING_RUN);\n if (source[cursor] === \"\\\\\") {\n value += parseEscapeSequence();\n continue;\n }\n if (consumeChar('\"')) {\n return { type: \"str\", value };\n }\n // We've reached an EOL of EOF.\n throw new SyntaxError(\"Unclosed string literal\");\n }\n }\n // Unescape known escape sequences.\n function parseEscapeSequence() {\n if (test(RE_STRING_ESCAPE)) {\n return match1(RE_STRING_ESCAPE);\n }\n if (test(RE_UNICODE_ESCAPE)) {\n let [, codepoint4, codepoint6] = match(RE_UNICODE_ESCAPE);\n let codepoint = parseInt(codepoint4 || codepoint6, 16);\n return codepoint <= 0xd7ff || 0xe000 <= codepoint\n ? // It's a Unicode scalar value.\n String.fromCodePoint(codepoint)\n : // Lonely surrogates can cause trouble when the parsing result is\n // saved using UTF-8. Use U+FFFD REPLACEMENT CHARACTER instead.\n \"ļæ½\";\n }\n throw new SyntaxError(\"Unknown escape sequence\");\n }\n // Parse blank space. Return it if it looks like indent before a pattern\n // line. Skip it othwerwise.\n function parseIndent() {\n let start = cursor;\n consumeToken(TOKEN_BLANK);\n // Check the first non-blank character after the indent.\n switch (source[cursor]) {\n case \".\":\n case \"[\":\n case \"*\":\n case \"}\":\n case undefined: // EOF\n // A special character. End the Pattern.\n return false;\n case \"{\":\n // Placeables don't require indentation (in EBNF: block-placeable).\n // Continue the Pattern.\n return makeIndent(source.slice(start, cursor));\n }\n // If the first character on the line is not one of the special characters\n // listed above, it's a regular text character. Check if there's at least\n // one space of indent before it.\n if (source[cursor - 1] === \" \") {\n // It's an indented text character (in EBNF: indented-char). Continue\n // the Pattern.\n return makeIndent(source.slice(start, cursor));\n }\n // A not-indented text character is likely the identifier of the next\n // message. End the Pattern.\n return false;\n }\n // Trim blanks in text according to the given regex.\n function trim(text, re) {\n return text.replace(re, \"\");\n }\n // Normalize a blank block and extract the indent details.\n function makeIndent(blank) {\n let value = blank.replace(RE_BLANK_LINES, \"\\n\");\n let length = RE_INDENT.exec(blank)[1].length;\n return new Indent(value, length);\n }\n }\n}\nclass Indent {\n constructor(value, length) {\n this.value = value;\n this.length = length;\n }\n}\n","/**\n * A JavaScript implementation of Project Fluent, a localization\n * framework designed to unleash the expressive power of the natural language.\n *\n * @module\n */\nexport { FluentBundle } from \"./bundle.js\";\nexport { FluentResource } from \"./resource.js\";\nexport { FluentType, FluentNone, FluentNumber, FluentDateTime, } from \"./types.js\";\n","/* eslint no-console: [\"error\", {allow: [\"warn\"]}] */\n/* global console */\n// Match the opening angle bracket (<) in HTML tags, and HTML entities like\n// &, &, &.\nconst reOverlay = /<|&#?\\w+;/;\n/**\n * Elements allowed in translations even if they are not present in the source\n * HTML. They are text-level elements as defined by the HTML5 spec:\n * https://www.w3.org/TR/html5/text-level-semantics.html with the exception of:\n *\n * - a - because we don't allow href on it anyways,\n * - ruby, rt, rp - because we don't allow nested elements to be inserted.\n */\nconst TEXT_LEVEL_ELEMENTS = {\n \"http://www.w3.org/1999/xhtml\": [\n \"em\",\n \"strong\",\n \"small\",\n \"s\",\n \"cite\",\n \"q\",\n \"dfn\",\n \"abbr\",\n \"data\",\n \"time\",\n \"code\",\n \"var\",\n \"samp\",\n \"kbd\",\n \"sub\",\n \"sup\",\n \"i\",\n \"b\",\n \"u\",\n \"mark\",\n \"bdi\",\n \"bdo\",\n \"span\",\n \"br\",\n \"wbr\",\n ],\n};\nconst LOCALIZABLE_ATTRIBUTES = {\n \"http://www.w3.org/1999/xhtml\": {\n global: [\"title\", \"aria-description\", \"aria-label\", \"aria-valuetext\"],\n a: [\"download\"],\n area: [\"download\", \"alt\"],\n // value is special-cased in isAttrNameLocalizable\n input: [\"alt\", \"placeholder\"],\n menuitem: [\"label\"],\n menu: [\"label\"],\n optgroup: [\"label\"],\n option: [\"label\"],\n track: [\"label\"],\n img: [\"alt\"],\n textarea: [\"placeholder\"],\n th: [\"abbr\"],\n },\n \"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul\": {\n global: [\n \"accesskey\",\n \"aria-label\",\n \"aria-valuetext\",\n \"label\",\n \"title\",\n \"tooltiptext\",\n ],\n description: [\"value\"],\n key: [\"key\", \"keycode\"],\n label: [\"value\"],\n textbox: [\"placeholder\", \"value\"],\n },\n};\n/**\n * Translate an element.\n *\n * Translate the element's text content and attributes. Some HTML markup is\n * allowed in the translation. The element's children with the data-l10n-name\n * attribute will be treated as arguments to the translation. If the\n * translation defines the same children, their attributes and text contents\n * will be used for translating the matching source child.\n *\n * @param {Element} element\n * @param {Object} translation\n * @private\n */\nexport default function translateElement(element, translation) {\n const { value } = translation;\n if (typeof value === \"string\") {\n if (element.localName === \"title\" &&\n element.namespaceURI === \"http://www.w3.org/1999/xhtml\") {\n // A special case for the HTML title element whose content must be text.\n element.textContent = value;\n }\n else if (!reOverlay.test(value)) {\n // If the translation doesn't contain any markup skip the overlay logic.\n element.textContent = value;\n }\n else {\n // Else parse the translation's HTML using an inert template element,\n // sanitize it and replace the element's content.\n const templateElement = element.ownerDocument.createElementNS(\"http://www.w3.org/1999/xhtml\", \"template\");\n templateElement.innerHTML = value;\n overlayChildNodes(templateElement.content, element);\n }\n }\n // Even if the translation doesn't define any localizable attributes, run\n // overlayAttributes to remove any localizable attributes set by previous\n // translations.\n overlayAttributes(translation, element);\n}\n/**\n * Replace child nodes of an element with child nodes of another element.\n *\n * The contents of the target element will be cleared and fully replaced with\n * sanitized contents of the source element.\n *\n * @param {DocumentFragment} fromFragment - The source of children to overlay.\n * @param {Element} toElement - The target of the overlay.\n * @private\n */\nfunction overlayChildNodes(fromFragment, toElement) {\n for (const childNode of fromFragment.childNodes) {\n if (childNode.nodeType === childNode.TEXT_NODE) {\n // Keep the translated text node.\n continue;\n }\n if (childNode.hasAttribute(\"data-l10n-name\")) {\n const sanitized = getNodeForNamedElement(toElement, childNode);\n fromFragment.replaceChild(sanitized, childNode);\n continue;\n }\n if (isElementAllowed(childNode)) {\n const sanitized = createSanitizedElement(childNode);\n fromFragment.replaceChild(sanitized, childNode);\n continue;\n }\n console.warn(`An element of forbidden type \"${childNode.localName}\" was found in ` +\n \"the translation. Only safe text-level elements and elements with \" +\n \"data-l10n-name are allowed.\");\n // If all else fails, replace the element with its text content.\n fromFragment.replaceChild(createTextNodeFromTextContent(childNode), childNode);\n }\n toElement.textContent = \"\";\n toElement.appendChild(fromFragment);\n}\nfunction hasAttribute(attributes, name) {\n if (!attributes) {\n return false;\n }\n for (let attr of attributes) {\n if (attr.name === name) {\n return true;\n }\n }\n return false;\n}\n/**\n * Transplant localizable attributes of an element to another element.\n *\n * Any localizable attributes already set on the target element will be\n * cleared.\n *\n * @param {Element|Object} fromElement - The source of child nodes to overlay.\n * @param {Element} toElement - The target of the overlay.\n * @private\n */\nfunction overlayAttributes(fromElement, toElement) {\n const explicitlyAllowed = toElement.hasAttribute(\"data-l10n-attrs\")\n ? toElement\n .getAttribute(\"data-l10n-attrs\")\n .split(\",\")\n .map(i => i.trim())\n : null;\n // Remove existing localizable attributes if they\n // will not be used in the new translation.\n for (const attr of Array.from(toElement.attributes)) {\n if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) &&\n !hasAttribute(fromElement.attributes, attr.name)) {\n toElement.removeAttribute(attr.name);\n }\n }\n // fromElement might be a {value, attributes} object as returned by\n // Localization.messageFromBundle. In which case attributes may be null to\n // save GC cycles.\n if (!fromElement.attributes) {\n return;\n }\n // Set localizable attributes.\n for (const attr of Array.from(fromElement.attributes)) {\n if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) &&\n toElement.getAttribute(attr.name) !== attr.value) {\n toElement.setAttribute(attr.name, attr.value);\n }\n }\n}\n/**\n * Sanitize a child element created by the translation.\n *\n * Try to find a corresponding child in sourceElement and use it as the base\n * for the sanitization. This will preserve functional attribtues defined on\n * the child element in the source HTML.\n *\n * @param {Element} sourceElement - The source for data-l10n-name lookups.\n * @param {Element} translatedChild - The translated child to be sanitized.\n * @returns {Element}\n * @private\n */\nfunction getNodeForNamedElement(sourceElement, translatedChild) {\n const childName = translatedChild.getAttribute(\"data-l10n-name\");\n const sourceChild = sourceElement.querySelector(`[data-l10n-name=\"${childName}\"]`);\n if (!sourceChild) {\n console.warn(`An element named \"${childName}\" wasn't found in the source.`);\n return createTextNodeFromTextContent(translatedChild);\n }\n if (sourceChild.localName !== translatedChild.localName) {\n console.warn(`An element named \"${childName}\" was found in the translation ` +\n `but its type ${translatedChild.localName} didn't match the ` +\n `element found in the source (${sourceChild.localName}).`);\n return createTextNodeFromTextContent(translatedChild);\n }\n // Remove it from sourceElement so that the translation cannot use\n // the same reference name again.\n sourceElement.removeChild(sourceChild);\n // We can't currently guarantee that a translation won't remove\n // sourceChild from the element completely, which could break the app if\n // it relies on an event handler attached to the sourceChild. Let's make\n // this limitation explicit for now by breaking the identitiy of the\n // sourceChild by cloning it. This will destroy all event handlers\n // attached to sourceChild via addEventListener and via on\n // properties.\n const clone = sourceChild.cloneNode(false);\n return shallowPopulateUsing(translatedChild, clone);\n}\n/**\n * Sanitize an allowed element.\n *\n * Text-level elements allowed in translations may only use safe attributes\n * and will have any nested markup stripped to text content.\n *\n * @param {Element} element - The element to be sanitized.\n * @returns {Element}\n * @private\n */\nfunction createSanitizedElement(element) {\n // Start with an empty element of the same type to remove nested children\n // and non-localizable attributes defined by the translation.\n const clone = element.ownerDocument.createElement(element.localName);\n return shallowPopulateUsing(element, clone);\n}\n/**\n * Convert an element to a text node.\n *\n * @param {Element} element - The element to be sanitized.\n * @returns {Node}\n * @private\n */\nfunction createTextNodeFromTextContent(element) {\n return element.ownerDocument.createTextNode(element.textContent);\n}\n/**\n * Check if element is allowed in the translation.\n *\n * This method is used by the sanitizer when the translation markup contains\n * an element which is not present in the source code.\n *\n * @param {Element} element\n * @returns {boolean}\n * @private\n */\nfunction isElementAllowed(element) {\n const allowed = TEXT_LEVEL_ELEMENTS[element.namespaceURI];\n return allowed && allowed.includes(element.localName);\n}\n/**\n * Check if attribute is allowed for the given element.\n *\n * This method is used by the sanitizer when the translation markup contains\n * DOM attributes, or when the translation has traits which map to DOM\n * attributes.\n *\n * `explicitlyAllowed` can be passed as a list of attributes explicitly\n * allowed on this element.\n *\n * @param {string} name\n * @param {Element} element\n * @param {Array} explicitlyAllowed\n * @returns {boolean}\n * @private\n */\nfunction isAttrNameLocalizable(name, element, explicitlyAllowed = null) {\n if (explicitlyAllowed && explicitlyAllowed.includes(name)) {\n return true;\n }\n const allowed = LOCALIZABLE_ATTRIBUTES[element.namespaceURI];\n if (!allowed) {\n return false;\n }\n const attrName = name.toLowerCase();\n const elemName = element.localName;\n // Is it a globally safe attribute?\n if (allowed.global.includes(attrName)) {\n return true;\n }\n // Are there no allowed attributes for this element?\n if (!allowed[elemName]) {\n return false;\n }\n // Is it allowed on this element?\n if (allowed[elemName].includes(attrName)) {\n return true;\n }\n // Special case for value on HTML inputs with type button, reset, submit\n if (element.namespaceURI === \"http://www.w3.org/1999/xhtml\" &&\n elemName === \"input\" &&\n attrName === \"value\") {\n const type = element.type.toLowerCase();\n if (type === \"submit\" || type === \"button\" || type === \"reset\") {\n return true;\n }\n }\n return false;\n}\n/**\n * Helper to set textContent and localizable attributes on an element.\n *\n * @param {Element} fromElement\n * @param {Element} toElement\n * @returns {Element}\n * @private\n */\nfunction shallowPopulateUsing(fromElement, toElement) {\n toElement.textContent = fromElement.textContent;\n overlayAttributes(fromElement, toElement);\n return toElement;\n}\n","/*\n * Base CachedIterable class.\n */\nexport default class CachedIterable extends Array {\n /**\n * Create a `CachedIterable` instance from an iterable or, if another\n * instance of `CachedIterable` is passed, return it without any\n * modifications.\n *\n * @param {Iterable} iterable\n * @returns {CachedIterable}\n */\n static from(iterable) {\n if (iterable instanceof this) {\n return iterable;\n }\n\n return new this(iterable);\n }\n}\n","import CachedIterable from \"./cached_iterable.mjs\";\n\n/*\n * CachedSyncIterable caches the elements yielded by an iterable.\n *\n * It can be used to iterate over an iterable many times without depleting the\n * iterable.\n */\nexport default class CachedSyncIterable extends CachedIterable {\n /**\n * Create an `CachedSyncIterable` instance.\n *\n * @param {Iterable} iterable\n * @returns {CachedSyncIterable}\n */\n constructor(iterable) {\n super();\n\n if (Symbol.iterator in Object(iterable)) {\n this.iterator = iterable[Symbol.iterator]();\n } else {\n throw new TypeError(\"Argument must implement the iteration protocol.\");\n }\n }\n\n [Symbol.iterator]() {\n const cached = this;\n let cur = 0;\n\n return {\n next() {\n if (cached.length <= cur) {\n cached.push(cached.iterator.next());\n }\n return cached[cur++];\n }\n };\n }\n\n /**\n * This method allows user to consume the next element from the iterator\n * into the cache.\n *\n * @param {number} count - number of elements to consume\n */\n touchNext(count = 1) {\n let idx = 0;\n while (idx++ < count) {\n const last = this[this.length - 1];\n if (last && last.done) {\n break;\n }\n this.push(this.iterator.next());\n }\n // Return the last cached {value, done} object to allow the calling\n // code to decide if it needs to call touchNext again.\n return this[this.length - 1];\n }\n}\n","import CachedIterable from \"./cached_iterable.mjs\";\n\n/*\n * CachedAsyncIterable caches the elements yielded by an async iterable.\n *\n * It can be used to iterate over an iterable many times without depleting the\n * iterable.\n */\nexport default class CachedAsyncIterable extends CachedIterable {\n /**\n * Create an `CachedAsyncIterable` instance.\n *\n * @param {Iterable} iterable\n * @returns {CachedAsyncIterable}\n */\n constructor(iterable) {\n super();\n\n if (Symbol.asyncIterator in Object(iterable)) {\n this.iterator = iterable[Symbol.asyncIterator]();\n } else if (Symbol.iterator in Object(iterable)) {\n this.iterator = iterable[Symbol.iterator]();\n } else {\n throw new TypeError(\"Argument must implement the iteration protocol.\");\n }\n }\n\n /**\n * Asynchronous iterator caching the yielded elements.\n *\n * Elements yielded by the original iterable will be cached and available\n * synchronously. Returns an async generator object implementing the\n * iterator protocol over the elements of the original (async or sync)\n * iterable.\n */\n [Symbol.asyncIterator]() {\n const cached = this;\n let cur = 0;\n\n return {\n async next() {\n if (cached.length <= cur) {\n cached.push(cached.iterator.next());\n }\n return cached[cur++];\n }\n };\n }\n\n /**\n * This method allows user to consume the next element from the iterator\n * into the cache.\n *\n * @param {number} count - number of elements to consume\n */\n async touchNext(count = 1) {\n let idx = 0;\n while (idx++ < count) {\n const last = this[this.length - 1];\n if (last && (await last).done) {\n break;\n }\n this.push(this.iterator.next());\n }\n // Return the last cached {value, done} object to allow the calling\n // code to decide if it needs to call touchNext again.\n return this[this.length - 1];\n }\n}\n","export {default as CachedSyncIterable} from \"./cached_sync_iterable.mjs\";\nexport {default as CachedAsyncIterable} from \"./cached_async_iterable.mjs\";\n","/* eslint no-console: [\"error\", { allow: [\"warn\", \"error\"] }] */\n/* global console */\nimport { CachedAsyncIterable } from \"cached-iterable\";\n/**\n * The `Localization` class is a central high-level API for vanilla\n * JavaScript use of Fluent.\n * It combines language negotiation, FluentBundle and I/O to\n * provide a scriptable API to format translations.\n */\nexport default class Localization {\n /**\n * @param {Array} resourceIds - List of resource IDs\n * @param {Function} generateBundles - Function that returns a\n * generator over FluentBundles\n *\n * @returns {Localization}\n */\n constructor(resourceIds = [], generateBundles) {\n this.resourceIds = resourceIds;\n this.generateBundles = generateBundles;\n this.onChange(true);\n }\n addResourceIds(resourceIds, eager = false) {\n this.resourceIds.push(...resourceIds);\n this.onChange(eager);\n return this.resourceIds.length;\n }\n removeResourceIds(resourceIds) {\n this.resourceIds = this.resourceIds.filter(r => !resourceIds.includes(r));\n this.onChange();\n return this.resourceIds.length;\n }\n /**\n * Format translations and handle fallback if needed.\n *\n * Format translations for `keys` from `FluentBundle` instances on this\n * DOMLocalization. In case of errors, fetch the next context in the\n * fallback chain.\n *\n * @param {Array} keys - Translation keys to format.\n * @param {Function} method - Formatting function.\n * @returns {Promise>}\n * @private\n */\n async formatWithFallback(keys, method) {\n const translations = [];\n let hasAtLeastOneBundle = false;\n for await (const bundle of this.bundles) {\n hasAtLeastOneBundle = true;\n const missingIds = keysFromBundle(method, bundle, keys, translations);\n if (missingIds.size === 0) {\n break;\n }\n if (typeof console !== \"undefined\") {\n const locale = bundle.locales[0];\n const ids = Array.from(missingIds).join(\", \");\n console.warn(`[fluent] Missing translations in ${locale}: ${ids}`);\n }\n }\n if (!hasAtLeastOneBundle && typeof console !== \"undefined\") {\n console.warn(`[fluent] Request for keys failed because no resource bundles got generated.\n keys: ${JSON.stringify(keys)}.\n resourceIds: ${JSON.stringify(this.resourceIds)}.`);\n }\n return translations;\n }\n /**\n * Format translations into `{value, attributes}` objects.\n *\n * The fallback logic is the same as in `formatValues`\n * but it returns `{value, attributes}` objects\n * which are suitable for the translation of DOM elements.\n *\n * Returns a Promise resolving to an array of the translation strings.\n *\n * @example\n * ```js\n * docL10n.formatMessages([\n * {id: 'hello', args: { who: 'Mary' }},\n * {id: 'welcome'}\n * ]).then(console.log);\n *\n * // [\n * // { value: 'Hello, Mary!', attributes: null },\n * // {\n * // value: 'Welcome!',\n * // attributes: [ { name: \"title\", value: 'Hello' } ]\n * // }\n * // ]\n * ```\n *\n * @param {Array} keys\n * @returns {Promise>}\n * @private\n */\n formatMessages(keys) {\n return this.formatWithFallback(keys, messageFromBundle);\n }\n /**\n * Retrieve translations corresponding to the passed keys.\n *\n * A generalized version of `DOMLocalization.formatValue`. Keys must\n * be `{id, args}` objects.\n *\n * Returns a Promise resolving to an array of the translation strings.\n *\n * @example\n * ```js\n * docL10n.formatValues([\n * {id: 'hello', args: { who: 'Mary' }},\n * {id: 'hello', args: { who: 'John' }},\n * {id: 'welcome'}\n * ]).then(console.log);\n *\n * // ['Hello, Mary!', 'Hello, John!', 'Welcome!']\n * ```\n *\n * @param {Array} keys\n * @returns {Promise>}\n */\n formatValues(keys) {\n return this.formatWithFallback(keys, valueFromBundle);\n }\n /**\n * Retrieve the translation corresponding to the `id` identifier.\n *\n * If passed, `args` is a simple hash object with a list of variables that\n * will be interpolated in the value of the translation.\n *\n * Returns a Promise resolving to the translation string.\n *\n * Use this sparingly for one-off messages which don't need to be\n * retranslated when the user changes their language preferences, e.g. in\n * notifications.\n *\n * @example\n * ```js\n * docL10n.formatValue(\n * 'hello', { who: 'world' }\n * ).then(console.log);\n *\n * // 'Hello, world!'\n * ```\n *\n * @param {string} id - Identifier of the translation to format\n * @param {Object} [args] - Optional external arguments\n * @returns {Promise}\n */\n async formatValue(id, args) {\n const [val] = await this.formatValues([{ id, args }]);\n return val;\n }\n handleEvent() {\n this.onChange();\n }\n /**\n * This method should be called when there's a reason to believe\n * that language negotiation or available resources changed.\n */\n onChange(eager = false) {\n this.bundles = CachedAsyncIterable.from(this.generateBundles(this.resourceIds));\n if (eager) {\n this.bundles.touchNext(2);\n }\n }\n}\n/**\n * Format the value of a message into a string or `null`.\n *\n * This function is passed as a method to `keysFromBundle` and resolve\n * a value of a single L10n Entity using provided `FluentBundle`.\n *\n * If the message doesn't have a value, return `null`.\n *\n * @param {FluentBundle} bundle\n * @param {Array} errors\n * @param {Object} message\n * @param {Object} args\n * @returns {string|null}\n * @private\n */\nfunction valueFromBundle(bundle, errors, message, args) {\n if (message.value) {\n return bundle.formatPattern(message.value, args, errors);\n }\n return null;\n}\n/**\n * Format all public values of a message into a {value, attributes} object.\n *\n * This function is passed as a method to `keysFromBundle` and resolve\n * a single L10n Entity using provided `FluentBundle`.\n *\n * The function will return an object with a value and attributes of the\n * entity.\n *\n * @param {FluentBundle} bundle\n * @param {Array} errors\n * @param {Object} message\n * @param {Object} args\n * @returns {Object}\n * @private\n */\nfunction messageFromBundle(bundle, errors, message, args) {\n const formatted = {\n value: null,\n attributes: null,\n };\n if (message.value) {\n formatted.value = bundle.formatPattern(message.value, args, errors);\n }\n let attrNames = Object.keys(message.attributes);\n if (attrNames.length > 0) {\n formatted.attributes = new Array(attrNames.length);\n for (let [i, name] of attrNames.entries()) {\n let value = bundle.formatPattern(message.attributes[name], args, errors);\n formatted.attributes[i] = { name, value };\n }\n }\n return formatted;\n}\n/**\n * This function is an inner function for `Localization.formatWithFallback`.\n *\n * It takes a `FluentBundle`, list of l10n-ids and a method to be used for\n * key resolution (either `valueFromBundle` or `messageFromBundle`) and\n * optionally a value returned from `keysFromBundle` executed against\n * another `FluentBundle`.\n *\n * The idea here is that if the previous `FluentBundle` did not resolve\n * all keys, we're calling this function with the next context to resolve\n * the remaining ones.\n *\n * In the function, we loop over `keys` and check if we have the `prev`\n * passed and if it has an error entry for the position we're in.\n *\n * If it doesn't, it means that we have a good translation for this key and\n * we return it. If it does, we'll try to resolve the key using the passed\n * `FluentBundle`.\n *\n * In the end, we fill the translations array, and return the Set with\n * missing ids.\n *\n * See `Localization.formatWithFallback` for more info on how this is used.\n *\n * @param {Function} method\n * @param {FluentBundle} bundle\n * @param {Array} keys\n * @param {{Array<{value: string, attributes: Object}>}} translations\n *\n * @returns {Set}\n * @private\n */\nfunction keysFromBundle(method, bundle, keys, translations) {\n const messageErrors = [];\n const missingIds = new Set();\n keys.forEach(({ id, args }, i) => {\n if (translations[i] !== undefined) {\n return;\n }\n let message = bundle.getMessage(id);\n if (message) {\n messageErrors.length = 0;\n translations[i] = method(bundle, messageErrors, message, args);\n if (messageErrors.length > 0 && typeof console !== \"undefined\") {\n const locale = bundle.locales[0];\n const errors = messageErrors.join(\", \");\n console.warn(`[fluent][resolver] errors in ${locale}/${id}: ${errors}.`);\n }\n }\n else {\n missingIds.add(id);\n }\n });\n return missingIds;\n}\n","import translateElement from \"./overlay.js\";\nimport Localization from \"./localization.js\";\nconst L10NID_ATTR_NAME = \"data-l10n-id\";\nconst L10NARGS_ATTR_NAME = \"data-l10n-args\";\nconst L10N_ELEMENT_QUERY = `[${L10NID_ATTR_NAME}]`;\n/**\n * The `DOMLocalization` class is responsible for fetching resources and\n * formatting translations.\n *\n * It implements the fallback strategy in case of errors encountered during the\n * formatting of translations and methods for observing DOM\n * trees with a `MutationObserver`.\n */\nexport default class DOMLocalization extends Localization {\n /**\n * @param {Array} resourceIds - List of resource IDs\n * @param {Function} generateBundles - Function that returns a\n * generator over FluentBundles\n * @returns {DOMLocalization}\n */\n constructor(resourceIds, generateBundles) {\n super(resourceIds, generateBundles);\n // A Set of DOM trees observed by the `MutationObserver`.\n this.roots = new Set();\n // requestAnimationFrame handler.\n this.pendingrAF = null;\n // list of elements pending for translation.\n this.pendingElements = new Set();\n this.windowElement = null;\n this.mutationObserver = null;\n this.observerConfig = {\n attributes: true,\n characterData: false,\n childList: true,\n subtree: true,\n attributeFilter: [L10NID_ATTR_NAME, L10NARGS_ATTR_NAME],\n };\n }\n onChange(eager = false) {\n super.onChange(eager);\n if (this.roots) {\n this.translateRoots();\n }\n }\n /**\n * Set the `data-l10n-id` and `data-l10n-args` attributes on DOM elements.\n * FluentDOM makes use of mutation observers to detect changes\n * to `data-l10n-*` attributes and translate elements asynchronously.\n * `setAttributes` is a convenience method which allows to translate\n * DOM elements declaratively.\n *\n * You should always prefer to use `data-l10n-id` on elements (statically in\n * HTML or dynamically via `setAttributes`) over manually retrieving\n * translations with `format`. The use of attributes ensures that the\n * elements can be retranslated when the user changes their language\n * preferences.\n *\n * ```javascript\n * localization.setAttributes(\n * document.querySelector('#welcome'), 'hello', { who: 'world' }\n * );\n * ```\n *\n * This will set the following attributes on the `#welcome` element.\n * The MutationObserver will pick up this change and will localize the element\n * asynchronously.\n *\n * ```html\n *

    \n *

    \n * ```\n *\n * @param {Element} element - Element to set attributes on\n * @param {string} id - l10n-id string\n * @param {Object} args - KVP list of l10n arguments\n * @returns {Element}\n */\n setAttributes(element, id, args) {\n element.setAttribute(L10NID_ATTR_NAME, id);\n if (args) {\n element.setAttribute(L10NARGS_ATTR_NAME, JSON.stringify(args));\n }\n else {\n element.removeAttribute(L10NARGS_ATTR_NAME);\n }\n return element;\n }\n /**\n * Get the `data-l10n-*` attributes from DOM elements.\n *\n * ```javascript\n * localization.getAttributes(\n * document.querySelector('#welcome')\n * );\n * // -> { id: 'hello', args: { who: 'world' } }\n * ```\n *\n * @param {Element} element - HTML element\n * @returns {{id: string, args: Object}}\n */\n getAttributes(element) {\n return {\n id: element.getAttribute(L10NID_ATTR_NAME),\n args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null),\n };\n }\n /**\n * Add `newRoot` to the list of roots managed by this `DOMLocalization`.\n *\n * Additionally, if this `DOMLocalization` has an observer, start observing\n * `newRoot` in order to translate mutations in it.\n *\n * @param {Element | DocumentFragment} newRoot - Root to observe.\n */\n connectRoot(newRoot) {\n for (const root of this.roots) {\n if (root === newRoot ||\n root.contains(newRoot) ||\n newRoot.contains(root)) {\n throw new Error(\"Cannot add a root that overlaps with existing root.\");\n }\n }\n if (this.windowElement) {\n if (this.windowElement !== newRoot.ownerDocument.defaultView) {\n throw new Error(`Cannot connect a root:\n DOMLocalization already has a root from a different window.`);\n }\n }\n else {\n this.windowElement = newRoot.ownerDocument.defaultView;\n this.mutationObserver = new this.windowElement.MutationObserver(mutations => this.translateMutations(mutations));\n }\n this.roots.add(newRoot);\n this.mutationObserver.observe(newRoot, this.observerConfig);\n }\n /**\n * Remove `root` from the list of roots managed by this `DOMLocalization`.\n *\n * Additionally, if this `DOMLocalization` has an observer, stop observing\n * `root`.\n *\n * Returns `true` if the root was the last one managed by this\n * `DOMLocalization`.\n *\n * @param {Element | DocumentFragment} root - Root to disconnect.\n * @returns {boolean}\n */\n disconnectRoot(root) {\n this.roots.delete(root);\n // Pause the mutation observer to stop observing `root`.\n this.pauseObserving();\n if (this.roots.size === 0) {\n this.mutationObserver = null;\n if (this.windowElement && this.pendingrAF) {\n this.windowElement.cancelAnimationFrame(this.pendingrAF);\n }\n this.windowElement = null;\n this.pendingrAF = null;\n this.pendingElements.clear();\n return true;\n }\n // Resume observing all other roots.\n this.resumeObserving();\n return false;\n }\n /**\n * Translate all roots associated with this `DOMLocalization`.\n *\n * @returns {Promise}\n */\n translateRoots() {\n const roots = Array.from(this.roots);\n return Promise.all(roots.map(root => this.translateFragment(root)));\n }\n /**\n * Pauses the `MutationObserver`.\n */\n pauseObserving() {\n if (!this.mutationObserver) {\n return;\n }\n this.translateMutations(this.mutationObserver.takeRecords());\n this.mutationObserver.disconnect();\n }\n /**\n * Resumes the `MutationObserver`.\n */\n resumeObserving() {\n if (!this.mutationObserver) {\n return;\n }\n for (const root of this.roots) {\n this.mutationObserver.observe(root, this.observerConfig);\n }\n }\n /**\n * Translate mutations detected by the `MutationObserver`.\n *\n * @private\n */\n translateMutations(mutations) {\n for (const mutation of mutations) {\n switch (mutation.type) {\n case \"attributes\":\n if (mutation.target.hasAttribute(\"data-l10n-id\")) {\n this.pendingElements.add(mutation.target);\n }\n break;\n case \"childList\":\n for (const addedNode of mutation.addedNodes) {\n if (addedNode.nodeType === addedNode.ELEMENT_NODE) {\n if (addedNode.childElementCount) {\n for (const element of this.getTranslatables(addedNode)) {\n this.pendingElements.add(element);\n }\n }\n else if (addedNode.hasAttribute(L10NID_ATTR_NAME)) {\n this.pendingElements.add(addedNode);\n }\n }\n }\n break;\n }\n }\n // This fragment allows us to coalesce all pending translations\n // into a single requestAnimationFrame.\n if (this.pendingElements.size > 0) {\n if (this.pendingrAF === null) {\n this.pendingrAF = this.windowElement.requestAnimationFrame(() => {\n this.translateElements(Array.from(this.pendingElements));\n this.pendingElements.clear();\n this.pendingrAF = null;\n });\n }\n }\n }\n /**\n * Translate a DOM element or fragment asynchronously using this\n * `DOMLocalization` object.\n *\n * Manually trigger the translation (or re-translation) of a DOM fragment.\n * Use the `data-l10n-id` and `data-l10n-args` attributes to mark up the DOM\n * with information about which translations to use.\n *\n * Returns a `Promise` that gets resolved once the translation is complete.\n *\n * @param {Element | DocumentFragment} frag - Element or DocumentFragment to be translated\n * @returns {Promise}\n */\n translateFragment(frag) {\n return this.translateElements(this.getTranslatables(frag));\n }\n /**\n * Translate a list of DOM elements asynchronously using this\n * `DOMLocalization` object.\n *\n * Manually trigger the translation (or re-translation) of a list of elements.\n * Use the `data-l10n-id` and `data-l10n-args` attributes to mark up the DOM\n * with information about which translations to use.\n *\n * Returns a `Promise` that gets resolved once the translation is complete.\n *\n * @param {Array} elements - List of elements to be translated\n * @returns {Promise}\n */\n async translateElements(elements) {\n if (!elements.length) {\n return undefined;\n }\n const keys = elements.map(this.getKeysForElement);\n const translations = await this.formatMessages(keys);\n return this.applyTranslations(elements, translations);\n }\n /**\n * Applies translations onto elements.\n *\n * @param {Array} elements\n * @param {Array} translations\n * @private\n */\n applyTranslations(elements, translations) {\n this.pauseObserving();\n for (let i = 0; i < elements.length; i++) {\n if (translations[i] !== undefined) {\n translateElement(elements[i], translations[i]);\n }\n }\n this.resumeObserving();\n }\n /**\n * Collects all translatable child elements of the element.\n *\n * @param {Element | DocumentFragment} element\n * @returns {Array}\n * @private\n */\n getTranslatables(element) {\n const nodes = Array.from(element.querySelectorAll(L10N_ELEMENT_QUERY));\n if (typeof element.hasAttribute === \"function\" &&\n element.hasAttribute(L10NID_ATTR_NAME)) {\n nodes.push(element);\n }\n return nodes;\n }\n /**\n * Get the `data-l10n-*` attributes from DOM elements as a two-element\n * array.\n *\n * @param {Element} element\n * @returns {Object}\n * @private\n */\n getKeysForElement(element) {\n return {\n id: element.getAttribute(L10NID_ATTR_NAME),\n args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null),\n };\n }\n}\n","export { default as DOMLocalization } from \"./dom_localization.js\";\nexport { default as Localization } from \"./localization.js\";\n","/* Copyright 2023 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * NOTE: The L10n-implementations should use lowercase language-codes\n * internally.\n */\nclass L10n {\n #dir;\n\n #elements;\n\n #lang;\n\n #l10n;\n\n constructor({ lang, isRTL }, l10n = null) {\n this.#lang = L10n.#fixupLangCode(lang);\n this.#l10n = l10n;\n this.#dir = (isRTL ?? L10n.#isRTL(this.#lang)) ? \"rtl\" : \"ltr\";\n }\n\n _setL10n(l10n) {\n this.#l10n = l10n;\n if (typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"TESTING\")) {\n document.l10n = l10n;\n }\n }\n\n /** @inheritdoc */\n getLanguage() {\n return this.#lang;\n }\n\n /** @inheritdoc */\n getDirection() {\n return this.#dir;\n }\n\n /** @inheritdoc */\n async get(ids, args = null, fallback) {\n if (Array.isArray(ids)) {\n ids = ids.map(id => ({ id }));\n const messages = await this.#l10n.formatMessages(ids);\n return messages.map(message => message.value);\n }\n\n const messages = await this.#l10n.formatMessages([\n {\n id: ids,\n args,\n },\n ]);\n return messages[0]?.value || fallback;\n }\n\n /** @inheritdoc */\n async translate(element) {\n (this.#elements ||= new Set()).add(element);\n try {\n this.#l10n.connectRoot(element);\n await this.#l10n.translateRoots();\n } catch {\n // Element is under an existing root, so there is no need to add it again.\n }\n }\n\n /** @inheritdoc */\n async translateOnce(element) {\n try {\n await this.#l10n.translateElements([element]);\n } catch (ex) {\n console.error(\"translateOnce:\", ex);\n }\n }\n\n /** @inheritdoc */\n async destroy() {\n if (this.#elements) {\n for (const element of this.#elements) {\n this.#l10n.disconnectRoot(element);\n }\n this.#elements.clear();\n this.#elements = null;\n }\n this.#l10n.pauseObserving();\n }\n\n /** @inheritdoc */\n pause() {\n this.#l10n.pauseObserving();\n }\n\n /** @inheritdoc */\n resume() {\n this.#l10n.resumeObserving();\n }\n\n static #fixupLangCode(langCode) {\n // Use only lowercase language-codes internally, and fallback to English.\n langCode = langCode?.toLowerCase() || \"en-us\";\n\n // Try to support \"incompletely\" specified language codes (see issue 13689).\n const PARTIAL_LANG_CODES = {\n en: \"en-us\",\n es: \"es-es\",\n fy: \"fy-nl\",\n ga: \"ga-ie\",\n gu: \"gu-in\",\n hi: \"hi-in\",\n hy: \"hy-am\",\n nb: \"nb-no\",\n ne: \"ne-np\",\n nn: \"nn-no\",\n pa: \"pa-in\",\n pt: \"pt-pt\",\n sv: \"sv-se\",\n zh: \"zh-cn\",\n };\n return PARTIAL_LANG_CODES[langCode] || langCode;\n }\n\n static #isRTL(lang) {\n const shortCode = lang.split(\"-\", 1)[0];\n return [\"ar\", \"he\", \"fa\", \"ps\", \"ur\"].includes(shortCode);\n }\n}\n\nconst GenericL10n = null;\n\nexport { GenericL10n, L10n };\n","/* Copyright 2017 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FeatureTest, fetchData } from \"pdfjs-lib\";\nimport { FluentBundle, FluentResource } from \"fluent-bundle\";\nimport { DOMLocalization } from \"fluent-dom\";\nimport { L10n } from \"./l10n.js\";\n\nfunction PLATFORM() {\n const { isAndroid, isLinux, isMac, isWindows } = FeatureTest.platform;\n if (isLinux) {\n return \"linux\";\n }\n if (isWindows) {\n return \"windows\";\n }\n if (isMac) {\n return \"macos\";\n }\n if (isAndroid) {\n return \"android\";\n }\n return \"other\";\n}\n\nfunction createBundle(lang, text) {\n const resource = new FluentResource(text);\n const bundle = new FluentBundle(lang, {\n functions: { PLATFORM },\n });\n const errors = bundle.addResource(resource);\n if (errors.length) {\n console.error(\"L10n errors\", errors);\n }\n return bundle;\n}\n\nclass GenericL10n extends L10n {\n constructor(lang) {\n super({ lang });\n\n const generateBundles = !lang\n ? GenericL10n.#generateBundlesFallback.bind(\n GenericL10n,\n this.getLanguage()\n )\n : GenericL10n.#generateBundles.bind(\n GenericL10n,\n \"en-us\",\n this.getLanguage()\n );\n this._setL10n(new DOMLocalization([], generateBundles));\n }\n\n /**\n * Generate the bundles for Fluent.\n * @param {String} defaultLang - The fallback language to use for\n * translations.\n * @param {String} baseLang - The base language to use for translations.\n */\n static async *#generateBundles(defaultLang, baseLang) {\n const { baseURL, paths } = await this.#getPaths();\n\n const langs = [baseLang];\n if (defaultLang !== baseLang) {\n // Also fallback to the short-format of the base language\n // (see issue 17269).\n const shortLang = baseLang.split(\"-\", 1)[0];\n\n if (shortLang !== baseLang) {\n langs.push(shortLang);\n }\n langs.push(defaultLang);\n }\n // Trigger fetching of bundles in parallel, to reduce overall load time.\n const bundles = langs.map(lang => [\n lang,\n this.#createBundle(lang, baseURL, paths),\n ]);\n\n for (const [lang, bundlePromise] of bundles) {\n const bundle = await bundlePromise;\n if (bundle) {\n yield bundle;\n } else if (lang === \"en-us\") {\n yield this.#createBundleFallback(lang);\n }\n }\n }\n\n static async #createBundle(lang, baseURL, paths) {\n const path = paths[lang];\n if (!path) {\n return null;\n }\n const url = new URL(path, baseURL);\n const text = await fetchData(url, /* type = */ \"text\");\n\n return createBundle(lang, text);\n }\n\n static async #getPaths() {\n try {\n const { href } = document.querySelector(`link[type=\"application/l10n\"]`);\n const paths = await fetchData(href, /* type = */ \"json\");\n\n return {\n baseURL: href.substring(0, href.lastIndexOf(\"/\") + 1) || \"./\",\n paths,\n };\n } catch {}\n return { baseURL: \"./\", paths: Object.create(null) };\n }\n\n static async *#generateBundlesFallback(lang) {\n yield this.#createBundleFallback(lang);\n }\n\n static async #createBundleFallback(lang) {\n if (typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"TESTING\")) {\n throw new Error(\"Not implemented: #createBundleFallback\");\n }\n const text =\n typeof PDFJSDev === \"undefined\"\n ? await fetchData(\n new URL(\"../l10n/en-US/viewer.ftl\", window.location.href),\n /* type = */ \"text\"\n )\n : PDFJSDev.eval(\"DEFAULT_FTL\");\n\n return createBundle(lang, text);\n }\n}\n\nexport { GenericL10n };\n","/* Copyright 2020 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getPdfFilenameFromUrl } from \"pdfjs-lib\";\n\nasync function docProperties(pdfDocument) {\n const url = \"\",\n baseUrl = \"\";\n const { info, metadata, contentDispositionFilename, contentLength } =\n await pdfDocument.getMetadata();\n\n return {\n ...info,\n baseURL: baseUrl,\n filesize: contentLength || (await pdfDocument.getDownloadInfo()).length,\n filename: contentDispositionFilename || getPdfFilenameFromUrl(url),\n metadata: metadata?.getRaw(),\n authors: metadata?.get(\"dc:creator\"),\n numPages: pdfDocument.numPages,\n URL: url,\n };\n}\n\nclass GenericScripting {\n constructor(sandboxBundleSrc) {\n this._ready = new Promise((resolve, reject) => {\n const sandbox =\n typeof PDFJSDev === \"undefined\"\n ? import(sandboxBundleSrc) // eslint-disable-line no-unsanitized/method\n : __raw_import__(sandboxBundleSrc);\n sandbox\n .then(pdfjsSandbox => {\n resolve(pdfjsSandbox.QuickJSSandbox());\n })\n .catch(reject);\n });\n }\n\n async createSandbox(data) {\n const sandbox = await this._ready;\n sandbox.create(data);\n }\n\n async dispatchEventInSandbox(event) {\n const sandbox = await this._ready;\n setTimeout(() => sandbox.dispatchEvent(event), 0);\n }\n\n async destroySandbox() {\n const sandbox = await this._ready;\n sandbox.nukeSandbox();\n }\n}\n\nexport { docProperties, GenericScripting };\n","/* Copyright 2025 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getUuid } from \"pdfjs-lib\";\n\nconst KEY_STORAGE = \"pdfjs.signature\";\n\nclass SignatureStorage {\n // TODO: Encrypt the data in using a password and add a UI for entering it.\n // We could use the Web Crypto API for this (see https://bradyjoslin.com/blog/encryption-webcrypto/\n // for an example).\n\n #eventBus;\n\n #signatures = null;\n\n #signal = null;\n\n constructor(eventBus, signal) {\n this.#eventBus = eventBus;\n this.#signal = signal;\n }\n\n #save() {\n localStorage.setItem(\n KEY_STORAGE,\n JSON.stringify(Object.fromEntries(this.#signatures))\n );\n }\n\n async getAll() {\n if (this.#signal) {\n window.addEventListener(\n \"storage\",\n ({ key }) => {\n if (key === KEY_STORAGE) {\n this.#signatures = null;\n this.#eventBus?.dispatch(\"storedsignatureschanged\", {\n source: this,\n });\n }\n },\n { signal: this.#signal }\n );\n this.#signal = null;\n }\n if (!this.#signatures) {\n this.#signatures = new Map();\n const data = localStorage.getItem(KEY_STORAGE);\n if (data) {\n for (const [key, value] of Object.entries(JSON.parse(data))) {\n this.#signatures.set(key, value);\n }\n }\n }\n return this.#signatures;\n }\n\n async isFull() {\n // Only allow 5 signatures to be saved.\n return (await this.size()) === 5;\n }\n\n async size() {\n return (await this.getAll()).size;\n }\n\n async create(data) {\n if (await this.isFull()) {\n return null;\n }\n const uuid = getUuid();\n this.#signatures.set(uuid, data);\n this.#save();\n\n return uuid;\n }\n\n async delete(uuid) {\n const signatures = await this.getAll();\n if (!signatures.has(uuid)) {\n return false;\n }\n signatures.delete(uuid);\n this.#save();\n\n return true;\n }\n}\n\nexport { SignatureStorage };\n","/* Copyright 2017 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppOptions } from \"./app_options.js\";\nimport { BaseExternalServices } from \"./external_services.js\";\nimport { BasePreferences } from \"./preferences.js\";\nimport { GenericL10n } from \"./genericl10n.js\";\nimport { GenericScripting } from \"./generic_scripting.js\";\nimport { SignatureStorage } from \"./generic_signature_storage.js\";\n\nif (typeof PDFJSDev !== \"undefined\" && !PDFJSDev.test(\"GENERIC\")) {\n throw new Error(\n 'Module \"pdfjs-web/genericcom\" shall not be used outside GENERIC build.'\n );\n}\n\nfunction initCom(app) {}\n\nclass Preferences extends BasePreferences {\n async _writeToStorage(prefObj) {\n localStorage.setItem(\"pdfjs.preferences\", JSON.stringify(prefObj));\n }\n\n async _readFromStorage(prefObj) {\n return { prefs: JSON.parse(localStorage.getItem(\"pdfjs.preferences\")) };\n }\n}\n\nclass ExternalServices extends BaseExternalServices {\n async createL10n() {\n return new GenericL10n(AppOptions.get(\"localeProperties\")?.lang);\n }\n\n createScripting() {\n return new GenericScripting(AppOptions.get(\"sandboxBundleSrc\"));\n }\n\n createSignatureStorage(eventBus, signal) {\n return new SignatureStorage(eventBus, signal);\n }\n}\n\nclass MLManager {\n static {\n if (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\")) {\n this.getFakeMLManager = options => new FakeMLManager(options);\n }\n }\n\n async isEnabledFor(_name) {\n return false;\n }\n\n async deleteModel(_service) {\n return null;\n }\n\n isReady(_name) {\n return false;\n }\n\n guess(_data) {}\n\n toggleService(_name, _enabled) {}\n}\n\nif (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\")) {\n // eslint-disable-next-line no-var\n var FakeMLManager = class {\n eventBus = null;\n\n hasProgress = false;\n\n constructor({ enableGuessAltText, enableAltTextModelDownload }) {\n this.enableGuessAltText = enableGuessAltText;\n this.enableAltTextModelDownload = enableAltTextModelDownload;\n }\n\n setEventBus(eventBus, abortSignal) {\n this.eventBus = eventBus;\n }\n\n async isEnabledFor(_name) {\n return this.enableGuessAltText;\n }\n\n async deleteModel(_name) {\n this.enableAltTextModelDownload = false;\n return null;\n }\n\n async loadModel(_name) {}\n\n async downloadModel(_name) {\n // Simulate downloading the model but with progress.\n // The progress can be seen in the new alt-text dialog.\n this.hasProgress = true;\n\n const { promise, resolve } = Promise.withResolvers();\n const total = 1e8;\n const end = 1.5 * total;\n const increment = 5e6;\n let loaded = 0;\n const id = setInterval(() => {\n loaded += increment;\n if (loaded <= end) {\n this.eventBus.dispatch(\"loadaiengineprogress\", {\n source: this,\n detail: {\n total,\n totalLoaded: loaded,\n finished: loaded + increment >= end,\n },\n });\n return;\n }\n clearInterval(id);\n this.hasProgress = false;\n this.enableAltTextModelDownload = true;\n resolve(true);\n }, 900);\n return promise;\n }\n\n isReady(_name) {\n return this.enableAltTextModelDownload;\n }\n\n guess({ request: { data } }) {\n return new Promise(resolve => {\n setTimeout(() => {\n resolve(data ? { output: \"Fake alt text.\" } : { error: true });\n }, 3000);\n });\n }\n\n toggleService(_name, enabled) {\n this.enableGuessAltText = enabled;\n }\n };\n}\n\nexport { ExternalServices, initCom, MLManager, Preferences };\n","/* Copyright 2024 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { noContextMenu } from \"pdfjs-lib\";\n\nclass NewAltTextManager {\n #boundCancel = this.#cancel.bind(this);\n\n #createAutomaticallyButton;\n\n #currentEditor = null;\n\n #cancelButton;\n\n #descriptionContainer;\n\n #dialog;\n\n #disclaimer;\n\n #downloadModel;\n\n #downloadModelDescription;\n\n #eventBus;\n\n #firstTime = false;\n\n #guessedAltText;\n\n #hasAI = null;\n\n #isEditing = null;\n\n #imagePreview;\n\n #imageData;\n\n #isAILoading = false;\n\n #wasAILoading = false;\n\n #learnMore;\n\n #notNowButton;\n\n #overlayManager;\n\n #textarea;\n\n #title;\n\n #uiManager;\n\n #previousAltText = null;\n\n constructor(\n {\n descriptionContainer,\n dialog,\n imagePreview,\n cancelButton,\n disclaimer,\n notNowButton,\n saveButton,\n textarea,\n learnMore,\n errorCloseButton,\n createAutomaticallyButton,\n downloadModel,\n downloadModelDescription,\n title,\n },\n overlayManager,\n eventBus\n ) {\n this.#cancelButton = cancelButton;\n this.#createAutomaticallyButton = createAutomaticallyButton;\n this.#descriptionContainer = descriptionContainer;\n this.#dialog = dialog;\n this.#disclaimer = disclaimer;\n this.#notNowButton = notNowButton;\n this.#imagePreview = imagePreview;\n this.#textarea = textarea;\n this.#learnMore = learnMore;\n this.#title = title;\n this.#downloadModel = downloadModel;\n this.#downloadModelDescription = downloadModelDescription;\n this.#overlayManager = overlayManager;\n this.#eventBus = eventBus;\n\n dialog.addEventListener(\"close\", this.#close.bind(this));\n dialog.addEventListener(\"contextmenu\", event => {\n if (event.target !== this.#textarea) {\n event.preventDefault();\n }\n });\n cancelButton.addEventListener(\"click\", this.#boundCancel);\n notNowButton.addEventListener(\"click\", this.#boundCancel);\n saveButton.addEventListener(\"click\", this.#save.bind(this));\n errorCloseButton.addEventListener(\"click\", () => {\n this.#toggleError(false);\n });\n createAutomaticallyButton.addEventListener(\"click\", async () => {\n const checked =\n createAutomaticallyButton.getAttribute(\"aria-pressed\") !== \"true\";\n this.#currentEditor._reportTelemetry({\n action: \"pdfjs.image.alt_text.ai_generation_check\",\n data: { status: checked },\n });\n\n if (this.#uiManager) {\n const isAltTextEnabled =\n await this.#uiManager.mlManager.isEnabledFor(\"altText\");\n this.#createAutomaticallyButton.disabled = true;\n if (checked && !isAltTextEnabled) {\n this.#textarea.value = \"\";\n this.#setProgress();\n this.#uiManager.setPreference(\"enableGuessAltText\", true);\n await this.#uiManager.mlManager.downloadModel(\"altText\");\n this.#setPref(\"enableAltTextModelDownload\", true);\n } else if (!checked && isAltTextEnabled) {\n this.#uiManager.setPreference(\"enableGuessAltText\", false);\n await this.#uiManager.mlManager.deleteModel(\"altText\");\n this.#setPref(\"enableAltTextModelDownload\", false);\n }\n this.#createAutomaticallyButton.disabled = false;\n await this.#uiManager.mlManager.toggleService(\"altText\", checked);\n }\n this.#toggleGuessAltText(checked, /* isInitial = */ false);\n });\n textarea.addEventListener(\"focus\", () => {\n this.#wasAILoading = this.#isAILoading;\n this.#toggleLoading(false);\n this.#toggleTitleAndDisclaimer();\n });\n textarea.addEventListener(\"blur\", () => {\n if (!textarea.value) {\n this.#toggleLoading(this.#wasAILoading);\n }\n this.#toggleTitleAndDisclaimer();\n });\n textarea.addEventListener(\"input\", () => {\n this.#toggleTitleAndDisclaimer();\n });\n textarea.addEventListener(\"keydown\", e => {\n if (\n (e.ctrlKey || e.metaKey) &&\n e.key === \"Enter\" &&\n !saveButton.disabled\n ) {\n this.#save();\n }\n });\n\n eventBus._on(\"enableguessalttext\", ({ value }) => {\n this.#toggleGuessAltText(value, /* isInitial = */ false);\n });\n\n this.#overlayManager.register(dialog);\n\n this.#learnMore.addEventListener(\"click\", () => {\n this.#currentEditor._reportTelemetry({\n action: \"pdfjs.image.alt_text.info\",\n data: { topic: \"alt_text\" },\n });\n });\n }\n\n #setPref(name, value) {\n this.#eventBus.dispatch(\"setpreference\", {\n source: this,\n name,\n value,\n });\n }\n\n #toggleLoading(value) {\n if (!this.#uiManager || this.#isAILoading === value) {\n return;\n }\n this.#isAILoading = value;\n this.#descriptionContainer.classList.toggle(\"loading\", value);\n }\n\n #toggleError(value) {\n if (!this.#uiManager) {\n return;\n }\n this.#dialog.classList.toggle(\"error\", value);\n }\n\n async #toggleGuessAltText(value, isInitial) {\n if (!this.#uiManager) {\n return;\n }\n this.#dialog.classList.toggle(\"aiDisabled\", !value);\n this.#createAutomaticallyButton.setAttribute(\"aria-pressed\", value);\n\n if (value) {\n const { altTextLearnMoreUrl } = this.#uiManager.mlManager;\n if (altTextLearnMoreUrl) {\n this.#learnMore.href = altTextLearnMoreUrl;\n }\n this.#mlGuessAltText(isInitial);\n } else {\n this.#toggleLoading(false);\n this.#isAILoading = false;\n this.#toggleTitleAndDisclaimer();\n }\n }\n\n #toggleNotNow() {\n this.#notNowButton.classList.toggle(\"hidden\", !this.#firstTime);\n this.#cancelButton.classList.toggle(\"hidden\", this.#firstTime);\n }\n\n #toggleAI(value) {\n if (!this.#uiManager || this.#hasAI === value) {\n return;\n }\n this.#hasAI = value;\n this.#dialog.classList.toggle(\"noAi\", !value);\n this.#toggleTitleAndDisclaimer();\n }\n\n #toggleTitleAndDisclaimer() {\n // Disclaimer is visible when the AI is loading or the user didn't change\n // the guessed alt text.\n const visible =\n this.#isAILoading ||\n (this.#guessedAltText && this.#guessedAltText === this.#textarea.value);\n this.#disclaimer.hidden = !visible;\n\n // The title changes depending if the text area is empty or not.\n const isEditing = this.#isAILoading || !!this.#textarea.value;\n if (this.#isEditing === isEditing) {\n return;\n }\n this.#isEditing = isEditing;\n this.#title.setAttribute(\n \"data-l10n-id\",\n isEditing\n ? \"pdfjs-editor-new-alt-text-dialog-edit-label\"\n : \"pdfjs-editor-new-alt-text-dialog-add-label\"\n );\n }\n\n async #mlGuessAltText(isInitial) {\n if (this.#isAILoading) {\n // We're still loading the previous guess.\n return;\n }\n\n if (this.#textarea.value) {\n // The user has already set an alt text.\n return;\n }\n\n if (isInitial && this.#previousAltText !== null) {\n // The user has already set an alt text (empty or not).\n return;\n }\n\n this.#guessedAltText = this.#currentEditor.guessedAltText;\n if (this.#previousAltText === null && this.#guessedAltText) {\n // We have a guessed alt text and the user didn't change it.\n this.#addAltText(this.#guessedAltText);\n return;\n }\n\n this.#toggleLoading(true);\n this.#toggleTitleAndDisclaimer();\n\n let hasError = false;\n try {\n // When calling #mlGuessAltText we don't wait for it, so we must take care\n // that the alt text dialog can have been closed before the response is.\n\n const altText = await this.#currentEditor.mlGuessAltText(\n this.#imageData,\n /* updateAltTextData = */ false\n );\n if (altText) {\n this.#guessedAltText = altText;\n this.#wasAILoading = this.#isAILoading;\n if (this.#isAILoading) {\n this.#addAltText(altText);\n }\n }\n } catch (e) {\n console.error(e);\n hasError = true;\n }\n\n this.#toggleLoading(false);\n this.#toggleTitleAndDisclaimer();\n\n if (hasError && this.#uiManager) {\n this.#toggleError(true);\n }\n }\n\n #addAltText(altText) {\n if (!this.#uiManager || this.#textarea.value) {\n return;\n }\n this.#textarea.value = altText;\n this.#toggleTitleAndDisclaimer();\n }\n\n #setProgress() {\n // Show the download model progress.\n this.#downloadModel.classList.toggle(\"hidden\", false);\n\n const callback = async ({ detail: { finished, total, totalLoaded } }) => {\n const ONE_MEGA_BYTES = 1e6;\n // totalLoaded can be greater than total if the download is compressed.\n // So we cheat to avoid any confusion.\n totalLoaded = Math.min(0.99 * total, totalLoaded);\n\n // Update the progress.\n const totalSize = (this.#downloadModelDescription.ariaValueMax =\n Math.round(total / ONE_MEGA_BYTES));\n const downloadedSize = (this.#downloadModelDescription.ariaValueNow =\n Math.round(totalLoaded / ONE_MEGA_BYTES));\n this.#downloadModelDescription.setAttribute(\n \"data-l10n-args\",\n JSON.stringify({ totalSize, downloadedSize })\n );\n if (!finished) {\n return;\n }\n\n // We're done, remove the listener and hide the download model progress.\n this.#eventBus._off(\"loadaiengineprogress\", callback);\n this.#downloadModel.classList.toggle(\"hidden\", true);\n\n this.#toggleAI(true);\n if (!this.#uiManager) {\n return;\n }\n const { mlManager } = this.#uiManager;\n\n // The model has been downloaded, we can now enable the AI service.\n mlManager.toggleService(\"altText\", true);\n this.#toggleGuessAltText(\n await mlManager.isEnabledFor(\"altText\"),\n /* isInitial = */ true\n );\n };\n this.#eventBus._on(\"loadaiengineprogress\", callback);\n }\n\n async editAltText(uiManager, editor, firstTime) {\n if (this.#currentEditor || !editor) {\n return;\n }\n\n if (firstTime && editor.hasAltTextData()) {\n editor.altTextFinish();\n return;\n }\n\n this.#firstTime = firstTime;\n const { mlManager } = uiManager;\n const hasAI = !!mlManager;\n this.#toggleTitleAndDisclaimer();\n\n if (mlManager && !mlManager.isReady(\"altText\")) {\n if (mlManager.hasProgress) {\n this.#setProgress();\n } else {\n this.#createAutomaticallyButton.setAttribute(\"aria-pressed\", false);\n }\n } else {\n this.#downloadModel.classList.toggle(\"hidden\", true);\n }\n\n const isAltTextEnabledPromise = mlManager?.isEnabledFor(\"altText\");\n\n this.#currentEditor = editor;\n this.#uiManager = uiManager;\n this.#uiManager.removeEditListeners();\n\n ({ altText: this.#previousAltText } = editor.altTextData);\n this.#textarea.value = this.#previousAltText ?? \"\";\n\n // TODO: get this value from Firefox\n // (https://bugzilla.mozilla.org/show_bug.cgi?id=1908184)\n const AI_MAX_IMAGE_DIMENSION = 224;\n const MAX_PREVIEW_DIMENSION = 180;\n\n // The max dimension of the preview in the dialog is 180px, so we keep 224px\n // and rescale it thanks to css.\n\n let canvas, width, height;\n if (mlManager) {\n ({\n canvas,\n width,\n height,\n imageData: this.#imageData,\n } = editor.copyCanvas(\n AI_MAX_IMAGE_DIMENSION,\n MAX_PREVIEW_DIMENSION,\n /* createImageData = */ true\n ));\n if (hasAI) {\n this.#toggleGuessAltText(\n await isAltTextEnabledPromise,\n /* isInitial = */ true\n );\n }\n } else {\n ({ canvas, width, height } = editor.copyCanvas(\n AI_MAX_IMAGE_DIMENSION,\n MAX_PREVIEW_DIMENSION,\n /* createImageData = */ false\n ));\n }\n\n canvas.setAttribute(\"role\", \"presentation\");\n const { style } = canvas;\n style.width = `${width}px`;\n style.height = `${height}px`;\n this.#imagePreview.append(canvas);\n\n this.#toggleNotNow();\n this.#toggleAI(hasAI);\n this.#toggleError(false);\n\n try {\n await this.#overlayManager.open(this.#dialog);\n } catch (ex) {\n this.#close();\n throw ex;\n }\n }\n\n #cancel() {\n this.#currentEditor.altTextData = {\n cancel: true,\n };\n const altText = this.#textarea.value.trim();\n this.#currentEditor._reportTelemetry({\n action: \"pdfjs.image.alt_text.dismiss\",\n data: {\n alt_text_type: altText ? \"present\" : \"empty\",\n flow: this.#firstTime ? \"image_add\" : \"alt_text_edit\",\n },\n });\n this.#currentEditor._reportTelemetry({\n action: \"pdfjs.image.image_added\",\n data: { alt_text_modal: true, alt_text_type: \"skipped\" },\n });\n this.#finish();\n }\n\n #finish() {\n this.#overlayManager.closeIfActive(this.#dialog);\n }\n\n #close() {\n const canvas = this.#imagePreview.firstElementChild;\n canvas.remove();\n canvas.width = canvas.height = 0;\n this.#imageData = null;\n\n this.#toggleLoading(false);\n\n this.#uiManager?.addEditListeners();\n this.#currentEditor.altTextFinish();\n this.#uiManager?.setSelected(this.#currentEditor);\n this.#currentEditor = null;\n this.#uiManager = null;\n }\n\n #extractWords(text) {\n return new Set(\n text\n .toLowerCase()\n .split(/[^\\p{L}\\p{N}]+/gu)\n .filter(x => !!x)\n );\n }\n\n #save() {\n const altText = this.#textarea.value.trim();\n this.#currentEditor.altTextData = {\n altText,\n decorative: false,\n };\n this.#currentEditor.altTextData.guessedAltText = this.#guessedAltText;\n\n if (this.#guessedAltText && this.#guessedAltText !== altText) {\n const guessedWords = this.#extractWords(this.#guessedAltText);\n const words = this.#extractWords(altText);\n this.#currentEditor._reportTelemetry({\n action: \"pdfjs.image.alt_text.user_edit\",\n data: {\n total_words: guessedWords.size,\n words_removed: guessedWords.difference(words).size,\n words_added: words.difference(guessedWords).size,\n },\n });\n }\n this.#currentEditor._reportTelemetry({\n action: \"pdfjs.image.image_added\",\n data: {\n alt_text_modal: true,\n alt_text_type: altText ? \"present\" : \"empty\",\n },\n });\n\n this.#currentEditor._reportTelemetry({\n action: \"pdfjs.image.alt_text.save\",\n data: {\n alt_text_type: altText ? \"present\" : \"empty\",\n flow: this.#firstTime ? \"image_add\" : \"alt_text_edit\",\n },\n });\n\n this.#finish();\n }\n\n destroy() {\n this.#uiManager = null; // Avoid re-adding the edit listeners.\n this.#finish();\n }\n}\n\nclass ImageAltTextSettings {\n #createModelButton;\n\n #dialog;\n\n #eventBus;\n\n #mlManager;\n\n #overlayManager;\n\n #showAltTextDialogButton;\n\n constructor(\n {\n dialog,\n createModelButton,\n learnMore,\n closeButton,\n showAltTextDialogButton,\n },\n overlayManager,\n eventBus,\n mlManager\n ) {\n this.#dialog = dialog;\n this.#createModelButton = createModelButton;\n this.#showAltTextDialogButton = showAltTextDialogButton;\n this.#overlayManager = overlayManager;\n this.#eventBus = eventBus;\n this.#mlManager = mlManager;\n\n const { altTextLearnMoreUrl } = mlManager;\n if (altTextLearnMoreUrl) {\n learnMore.href = altTextLearnMoreUrl;\n }\n\n dialog.addEventListener(\"contextmenu\", noContextMenu);\n\n createModelButton.addEventListener(\"click\", async e => {\n const checked = this.#togglePref(\"enableGuessAltText\", e);\n await (checked ? this.#download(true) : this.#delete(true));\n await mlManager.toggleService(\"altText\", checked);\n this.#reportTelemetry({\n type: \"stamp\",\n action: \"pdfjs.image.alt_text.settings_ai_generation_check\",\n data: { status: checked },\n });\n });\n\n showAltTextDialogButton.addEventListener(\"click\", e => {\n const checked = this.#togglePref(\"enableNewAltTextWhenAddingImage\", e);\n this.#reportTelemetry({\n type: \"stamp\",\n action: \"pdfjs.image.alt_text.settings_edit_alt_text_check\",\n data: { status: checked },\n });\n });\n\n closeButton.addEventListener(\"click\", this.#finish.bind(this));\n\n learnMore.addEventListener(\"click\", () => {\n this.#reportTelemetry({\n type: \"stamp\",\n action: \"pdfjs.image.alt_text.info\",\n data: { topic: \"ai_generation\" },\n });\n });\n\n eventBus._on(\"enablealttextmodeldownload\", ({ value }) => {\n if (value) {\n this.#download(false);\n } else {\n this.#delete(false);\n }\n });\n\n this.#overlayManager.register(dialog);\n }\n\n #reportTelemetry(data) {\n this.#eventBus.dispatch(\"reporttelemetry\", {\n source: this,\n details: {\n type: \"editing\",\n data,\n },\n });\n }\n\n async #download(isFromUI = false) {\n if (isFromUI) {\n await this.#mlManager.downloadModel(\"altText\");\n\n this.#setPref(\"enableGuessAltText\", true);\n this.#mlManager.toggleService(\"altText\", true);\n this.#setPref(\"enableAltTextModelDownload\", true);\n }\n }\n\n async #delete(isFromUI = false) {\n if (isFromUI) {\n await this.#mlManager.deleteModel(\"altText\");\n this.#setPref(\"enableGuessAltText\", false);\n this.#setPref(\"enableAltTextModelDownload\", false);\n }\n\n this.#createModelButton.setAttribute(\"aria-pressed\", false);\n }\n\n async open({ enableGuessAltText, enableNewAltTextWhenAddingImage }) {\n const { enableAltTextModelDownload } = this.#mlManager;\n this.#createModelButton.setAttribute(\n \"aria-pressed\",\n enableAltTextModelDownload && enableGuessAltText\n );\n this.#showAltTextDialogButton.setAttribute(\n \"aria-pressed\",\n enableNewAltTextWhenAddingImage\n );\n\n await this.#overlayManager.open(this.#dialog);\n this.#reportTelemetry({\n type: \"stamp\",\n action: \"pdfjs.image.alt_text.settings_displayed\",\n });\n }\n\n #togglePref(name, { target }) {\n const checked = target.getAttribute(\"aria-pressed\") !== \"true\";\n this.#setPref(name, checked);\n target.setAttribute(\"aria-pressed\", checked);\n return checked;\n }\n\n #setPref(name, value) {\n this.#eventBus.dispatch(\"setpreference\", {\n source: this,\n name,\n value,\n });\n }\n\n #finish() {\n this.#overlayManager.closeIfActive(this.#dialog);\n }\n}\n\nexport { ImageAltTextSettings, NewAltTextManager };\n","/* Copyright 2023 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DOMSVGFactory } from \"pdfjs-lib\";\n\nclass AltTextManager {\n #clickAC = null;\n\n #currentEditor = null;\n\n #cancelButton;\n\n #dialog;\n\n #eventBus;\n\n #hasUsedPointer = false;\n\n #optionDescription;\n\n #optionDecorative;\n\n #overlayManager;\n\n #saveButton;\n\n #textarea;\n\n #uiManager;\n\n #previousAltText = null;\n\n #resizeAC = null;\n\n #svgElement = null;\n\n #rectElement = null;\n\n #container;\n\n #telemetryData = null;\n\n constructor(\n {\n dialog,\n optionDescription,\n optionDecorative,\n textarea,\n cancelButton,\n saveButton,\n },\n container,\n overlayManager,\n eventBus\n ) {\n this.#dialog = dialog;\n this.#optionDescription = optionDescription;\n this.#optionDecorative = optionDecorative;\n this.#textarea = textarea;\n this.#cancelButton = cancelButton;\n this.#saveButton = saveButton;\n this.#overlayManager = overlayManager;\n this.#eventBus = eventBus;\n this.#container = container;\n\n const onUpdateUIState = this.#updateUIState.bind(this);\n\n dialog.addEventListener(\"close\", this.#close.bind(this));\n dialog.addEventListener(\"contextmenu\", event => {\n if (event.target !== this.#textarea) {\n event.preventDefault();\n }\n });\n cancelButton.addEventListener(\"click\", this.#finish.bind(this));\n saveButton.addEventListener(\"click\", this.#save.bind(this));\n optionDescription.addEventListener(\"change\", onUpdateUIState);\n optionDecorative.addEventListener(\"change\", onUpdateUIState);\n textarea.addEventListener(\"keydown\", e => {\n if (\n (e.ctrlKey || e.metaKey) &&\n e.key === \"Enter\" &&\n !saveButton.disabled\n ) {\n this.#save();\n }\n });\n\n this.#overlayManager.register(dialog);\n }\n\n #createSVGElement() {\n if (this.#svgElement) {\n return;\n }\n\n // We create a mask to add to the dialog backdrop: the idea is to have a\n // darken background everywhere except on the editor to clearly see the\n // picture to describe.\n\n const svgFactory = new DOMSVGFactory();\n const svg = (this.#svgElement = svgFactory.createElement(\"svg\"));\n svg.setAttribute(\"width\", \"0\");\n svg.setAttribute(\"height\", \"0\");\n const defs = svgFactory.createElement(\"defs\");\n svg.append(defs);\n const mask = svgFactory.createElement(\"mask\");\n defs.append(mask);\n mask.setAttribute(\"id\", \"alttext-manager-mask\");\n mask.setAttribute(\"maskContentUnits\", \"objectBoundingBox\");\n let rect = svgFactory.createElement(\"rect\");\n mask.append(rect);\n rect.setAttribute(\"fill\", \"white\");\n rect.setAttribute(\"width\", \"1\");\n rect.setAttribute(\"height\", \"1\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", \"0\");\n\n rect = this.#rectElement = svgFactory.createElement(\"rect\");\n mask.append(rect);\n rect.setAttribute(\"fill\", \"black\");\n this.#dialog.append(svg);\n }\n\n async editAltText(uiManager, editor) {\n if (this.#currentEditor || !editor) {\n return;\n }\n this.#createSVGElement();\n\n this.#hasUsedPointer = false;\n\n this.#clickAC = new AbortController();\n const clickOpts = { signal: this.#clickAC.signal },\n onClick = this.#onClick.bind(this);\n for (const element of [\n this.#optionDescription,\n this.#optionDecorative,\n this.#textarea,\n this.#saveButton,\n this.#cancelButton,\n ]) {\n element.addEventListener(\"click\", onClick, clickOpts);\n }\n\n const { altText, decorative } = editor.altTextData;\n if (decorative === true) {\n this.#optionDecorative.checked = true;\n this.#optionDescription.checked = false;\n } else {\n this.#optionDecorative.checked = false;\n this.#optionDescription.checked = true;\n }\n this.#previousAltText = this.#textarea.value = altText?.trim() || \"\";\n this.#updateUIState();\n\n this.#currentEditor = editor;\n this.#uiManager = uiManager;\n this.#uiManager.removeEditListeners();\n\n this.#resizeAC = new AbortController();\n this.#eventBus._on(\"resize\", this.#setPosition.bind(this), {\n signal: this.#resizeAC.signal,\n });\n\n try {\n await this.#overlayManager.open(this.#dialog);\n this.#setPosition();\n } catch (ex) {\n this.#close();\n throw ex;\n }\n }\n\n #setPosition() {\n if (!this.#currentEditor) {\n return;\n }\n const dialog = this.#dialog;\n const { style } = dialog;\n const {\n x: containerX,\n y: containerY,\n width: containerW,\n height: containerH,\n } = this.#container.getBoundingClientRect();\n const { innerWidth: windowW, innerHeight: windowH } = window;\n const { width: dialogW, height: dialogH } = dialog.getBoundingClientRect();\n const { x, y, width, height } = this.#currentEditor.getClientDimensions();\n const MARGIN = 10;\n const isLTR = this.#uiManager.direction === \"ltr\";\n\n const xs = Math.max(x, containerX);\n const xe = Math.min(x + width, containerX + containerW);\n const ys = Math.max(y, containerY);\n const ye = Math.min(y + height, containerY + containerH);\n this.#rectElement.setAttribute(\"width\", `${(xe - xs) / windowW}`);\n this.#rectElement.setAttribute(\"height\", `${(ye - ys) / windowH}`);\n this.#rectElement.setAttribute(\"x\", `${xs / windowW}`);\n this.#rectElement.setAttribute(\"y\", `${ys / windowH}`);\n\n let left = null;\n let top = Math.max(y, 0);\n top += Math.min(windowH - (top + dialogH), 0);\n\n if (isLTR) {\n // Prefer to position the dialog \"after\" (so on the right) the editor.\n if (x + width + MARGIN + dialogW < windowW) {\n left = x + width + MARGIN;\n } else if (x > dialogW + MARGIN) {\n left = x - dialogW - MARGIN;\n }\n } else if (x > dialogW + MARGIN) {\n left = x - dialogW - MARGIN;\n } else if (x + width + MARGIN + dialogW < windowW) {\n left = x + width + MARGIN;\n }\n\n if (left === null) {\n top = null;\n left = Math.max(x, 0);\n left += Math.min(windowW - (left + dialogW), 0);\n if (y > dialogH + MARGIN) {\n top = y - dialogH - MARGIN;\n } else if (y + height + MARGIN + dialogH < windowH) {\n top = y + height + MARGIN;\n }\n }\n\n if (top !== null) {\n dialog.classList.add(\"positioned\");\n if (isLTR) {\n style.left = `${left}px`;\n } else {\n style.right = `${windowW - left - dialogW}px`;\n }\n style.top = `${top}px`;\n } else {\n dialog.classList.remove(\"positioned\");\n style.left = \"\";\n style.top = \"\";\n }\n }\n\n #finish() {\n this.#overlayManager.closeIfActive(this.#dialog);\n }\n\n #close() {\n this.#currentEditor._reportTelemetry(\n this.#telemetryData || {\n action: \"alt_text_cancel\",\n alt_text_keyboard: !this.#hasUsedPointer,\n }\n );\n this.#telemetryData = null;\n\n this.#removeOnClickListeners();\n this.#uiManager?.addEditListeners();\n this.#resizeAC?.abort();\n this.#resizeAC = null;\n this.#currentEditor.altTextFinish();\n this.#currentEditor = null;\n this.#uiManager = null;\n }\n\n #updateUIState() {\n this.#textarea.disabled = this.#optionDecorative.checked;\n }\n\n #save() {\n const altText = this.#textarea.value.trim();\n const decorative = this.#optionDecorative.checked;\n this.#currentEditor.altTextData = {\n altText,\n decorative,\n };\n this.#telemetryData = {\n action: \"alt_text_save\",\n alt_text_description: !!altText,\n alt_text_edit:\n !!this.#previousAltText && this.#previousAltText !== altText,\n alt_text_decorative: decorative,\n alt_text_keyboard: !this.#hasUsedPointer,\n };\n this.#finish();\n }\n\n #onClick(evt) {\n if (evt.detail === 0) {\n return; // The keyboard was used.\n }\n this.#hasUsedPointer = true;\n this.#removeOnClickListeners();\n }\n\n #removeOnClickListeners() {\n this.#clickAC?.abort();\n this.#clickAC = null;\n }\n\n destroy() {\n this.#uiManager = null; // Avoid re-adding the edit listeners.\n this.#finish();\n this.#svgElement?.remove();\n this.#svgElement = this.#rectElement = null;\n }\n}\n\nexport { AltTextManager };\n","/* Copyright 2022 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** @typedef {import(\"./event_utils.js\").EventBus} EventBus */\n\nimport { AnnotationEditorParamsType } from \"pdfjs-lib\";\n\n/**\n * @typedef {Object} AnnotationEditorParamsOptions\n * @property {HTMLInputElement} editorFreeTextFontSize\n * @property {HTMLInputElement} editorFreeTextColor\n * @property {HTMLInputElement} editorInkColor\n * @property {HTMLInputElement} editorInkThickness\n * @property {HTMLInputElement} editorInkOpacity\n * @property {HTMLButtonElement} editorStampAddImage\n * @property {HTMLInputElement} editorFreeHighlightThickness\n * @property {HTMLButtonElement} editorHighlightShowAll\n * @property {HTMLButtonElement} editorSignatureAddSignature\n */\n\nclass AnnotationEditorParams {\n /**\n * @param {AnnotationEditorParamsOptions} options\n * @param {EventBus} eventBus\n */\n constructor(options, eventBus) {\n this.eventBus = eventBus;\n this.#bindListeners(options);\n }\n\n /**\n * @param {AnnotationEditorParamsOptions} options\n */\n #bindListeners({\n editorFreeTextFontSize,\n editorFreeTextColor,\n editorInkColor,\n editorInkThickness,\n editorInkOpacity,\n editorStampAddImage,\n editorFreeHighlightThickness,\n editorHighlightShowAll,\n editorSignatureAddSignature,\n }) {\n const { eventBus } = this;\n\n const dispatchEvent = (typeStr, value) => {\n eventBus.dispatch(\"switchannotationeditorparams\", {\n source: this,\n type: AnnotationEditorParamsType[typeStr],\n value,\n });\n };\n editorFreeTextFontSize.addEventListener(\"input\", function () {\n dispatchEvent(\"FREETEXT_SIZE\", this.valueAsNumber);\n });\n editorFreeTextColor.addEventListener(\"input\", function () {\n dispatchEvent(\"FREETEXT_COLOR\", this.value);\n });\n editorInkColor.addEventListener(\"input\", function () {\n dispatchEvent(\"INK_COLOR\", this.value);\n });\n editorInkThickness.addEventListener(\"input\", function () {\n dispatchEvent(\"INK_THICKNESS\", this.valueAsNumber);\n });\n editorInkOpacity.addEventListener(\"input\", function () {\n dispatchEvent(\"INK_OPACITY\", this.valueAsNumber);\n });\n editorStampAddImage.addEventListener(\"click\", () => {\n eventBus.dispatch(\"reporttelemetry\", {\n source: this,\n details: {\n type: \"editing\",\n data: { action: \"pdfjs.image.add_image_click\" },\n },\n });\n dispatchEvent(\"CREATE\");\n });\n editorFreeHighlightThickness.addEventListener(\"input\", function () {\n dispatchEvent(\"HIGHLIGHT_THICKNESS\", this.valueAsNumber);\n });\n editorHighlightShowAll.addEventListener(\"click\", function () {\n const checked = this.getAttribute(\"aria-pressed\") === \"true\";\n this.setAttribute(\"aria-pressed\", !checked);\n dispatchEvent(\"HIGHLIGHT_SHOW_ALL\", !checked);\n });\n editorSignatureAddSignature.addEventListener(\"click\", () => {\n dispatchEvent(\"CREATE\");\n });\n\n eventBus._on(\"annotationeditorparamschanged\", evt => {\n for (const [type, value] of evt.details) {\n switch (type) {\n case AnnotationEditorParamsType.FREETEXT_SIZE:\n editorFreeTextFontSize.value = value;\n break;\n case AnnotationEditorParamsType.FREETEXT_COLOR:\n editorFreeTextColor.value = value;\n break;\n case AnnotationEditorParamsType.INK_COLOR:\n editorInkColor.value = value;\n break;\n case AnnotationEditorParamsType.INK_THICKNESS:\n editorInkThickness.value = value;\n break;\n case AnnotationEditorParamsType.INK_OPACITY:\n editorInkOpacity.value = value;\n break;\n case AnnotationEditorParamsType.HIGHLIGHT_COLOR:\n eventBus.dispatch(\"mainhighlightcolorpickerupdatecolor\", {\n source: this,\n value,\n });\n break;\n case AnnotationEditorParamsType.HIGHLIGHT_THICKNESS:\n editorFreeHighlightThickness.value = value;\n break;\n case AnnotationEditorParamsType.HIGHLIGHT_FREE:\n editorFreeHighlightThickness.disabled = !value;\n break;\n case AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL:\n editorHighlightShowAll.setAttribute(\"aria-pressed\", value);\n break;\n }\n }\n });\n }\n}\n\nexport { AnnotationEditorParams };\n","/* Copyright 2024 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Used to compare floats: there is no exact equality due to rounding errors.\nconst PRECISION = 1e-1;\n\nclass CaretBrowsingMode {\n #mainContainer;\n\n #toolBarHeight = 0;\n\n #viewerContainer;\n\n constructor(abortSignal, mainContainer, viewerContainer, toolbarContainer) {\n this.#mainContainer = mainContainer;\n this.#viewerContainer = viewerContainer;\n\n if (!toolbarContainer) {\n return;\n }\n this.#toolBarHeight = toolbarContainer.getBoundingClientRect().height;\n\n const toolbarObserver = new ResizeObserver(entries => {\n for (const entry of entries) {\n if (entry.target === toolbarContainer) {\n this.#toolBarHeight = Math.floor(entry.borderBoxSize[0].blockSize);\n break;\n }\n }\n });\n toolbarObserver.observe(toolbarContainer);\n\n abortSignal.addEventListener(\"abort\", () => toolbarObserver.disconnect(), {\n once: true,\n });\n }\n\n /**\n * Return true if the two rectangles are on the same line.\n * @param {DOMRect} rect1\n * @param {DOMRect} rect2\n * @returns {boolean}\n */\n #isOnSameLine(rect1, rect2) {\n const top1 = rect1.y;\n const bot1 = rect1.bottom;\n const mid1 = rect1.y + rect1.height / 2;\n\n const top2 = rect2.y;\n const bot2 = rect2.bottom;\n const mid2 = rect2.y + rect2.height / 2;\n\n return (top1 <= mid2 && mid2 <= bot1) || (top2 <= mid1 && mid1 <= bot2);\n }\n\n /**\n * Return `true` if the rectangle is:\n * - under the caret when `isUp === false`.\n * - over the caret when `isUp === true`.\n * @param {DOMRect} rect\n * @param {number} x\n * @param {number} y\n * @param {boolean} isUp\n * @returns {boolean}\n */\n #isUnderOver(rect, x, y, isUp) {\n const midY = rect.y + rect.height / 2;\n return (\n (isUp ? y >= midY : y <= midY) &&\n rect.x - PRECISION <= x &&\n x <= rect.right + PRECISION\n );\n }\n\n /**\n * Check if the rectangle is visible.\n * @param {DOMRect} rect\n * @returns {boolean}\n */\n #isVisible(rect) {\n return (\n rect.top >= this.#toolBarHeight &&\n rect.left >= 0 &&\n rect.bottom <=\n (window.innerHeight || document.documentElement.clientHeight) &&\n rect.right <= (window.innerWidth || document.documentElement.clientWidth)\n );\n }\n\n /**\n * Get the position of the caret.\n * @param {Selection} selection\n * @param {boolean} isUp\n * @returns {Array}\n */\n #getCaretPosition(selection, isUp) {\n const { focusNode, focusOffset } = selection;\n const range = document.createRange();\n range.setStart(focusNode, focusOffset);\n range.setEnd(focusNode, focusOffset);\n const rect = range.getBoundingClientRect();\n\n return [rect.x, isUp ? rect.top : rect.bottom];\n }\n\n static #caretPositionFromPoint(x, y) {\n if (\n (typeof PDFJSDev === \"undefined\" || !PDFJSDev.test(\"MOZCENTRAL\")) &&\n !document.caretPositionFromPoint\n ) {\n const { startContainer: offsetNode, startOffset: offset } =\n document.caretRangeFromPoint(x, y);\n return { offsetNode, offset };\n }\n return document.caretPositionFromPoint(x, y);\n }\n\n #setCaretPositionHelper(selection, caretX, select, element, rect) {\n rect ||= element.getBoundingClientRect();\n if (caretX <= rect.x + PRECISION) {\n if (select) {\n selection.extend(element.firstChild, 0);\n } else {\n selection.setPosition(element.firstChild, 0);\n }\n return;\n }\n if (rect.right - PRECISION <= caretX) {\n const { lastChild } = element;\n if (select) {\n selection.extend(lastChild, lastChild.length);\n } else {\n selection.setPosition(lastChild, lastChild.length);\n }\n return;\n }\n\n const midY = rect.y + rect.height / 2;\n let caretPosition = CaretBrowsingMode.#caretPositionFromPoint(caretX, midY);\n let parentElement = caretPosition.offsetNode?.parentElement;\n if (parentElement && parentElement !== element) {\n // There is an element on top of the one in the text layer, so we\n // need to hide all the elements (except the one in the text layer)\n // at this position in order to get the correct caret position.\n const elementsAtPoint = document.elementsFromPoint(caretX, midY);\n const savedVisibilities = [];\n for (const el of elementsAtPoint) {\n if (el === element) {\n break;\n }\n const { style } = el;\n savedVisibilities.push([el, style.visibility]);\n style.visibility = \"hidden\";\n }\n caretPosition = CaretBrowsingMode.#caretPositionFromPoint(caretX, midY);\n parentElement = caretPosition.offsetNode?.parentElement;\n for (const [el, visibility] of savedVisibilities) {\n el.style.visibility = visibility;\n }\n }\n if (parentElement !== element) {\n // The element targeted by caretPositionFromPoint isn't in the text\n // layer.\n if (select) {\n selection.extend(element.firstChild, 0);\n } else {\n selection.setPosition(element.firstChild, 0);\n }\n return;\n }\n if (select) {\n selection.extend(caretPosition.offsetNode, caretPosition.offset);\n } else {\n selection.setPosition(caretPosition.offsetNode, caretPosition.offset);\n }\n }\n\n /**\n * Set the caret position or extend the selection (it depends on the select\n * parameter).\n * @param {boolean} select\n * @param {Selection} selection\n * @param {Element} newLineElement\n * @param {DOMRect} newLineElementRect\n * @param {number} caretX\n */\n #setCaretPosition(\n select,\n selection,\n newLineElement,\n newLineElementRect,\n caretX\n ) {\n if (this.#isVisible(newLineElementRect)) {\n this.#setCaretPositionHelper(\n selection,\n caretX,\n select,\n newLineElement,\n newLineElementRect\n );\n return;\n }\n this.#mainContainer.addEventListener(\n \"scrollend\",\n this.#setCaretPositionHelper.bind(\n this,\n selection,\n caretX,\n select,\n newLineElement,\n null\n ),\n { once: true }\n );\n newLineElement.scrollIntoView();\n }\n\n /**\n * Get the node on the next page.\n * @param {Element} textLayer\n * @param {boolean} isUp\n * @returns {Node}\n */\n #getNodeOnNextPage(textLayer, isUp) {\n while (true) {\n const page = textLayer.closest(\".page\");\n const pageNumber = parseInt(page.getAttribute(\"data-page-number\"));\n const nextPage = isUp ? pageNumber - 1 : pageNumber + 1;\n textLayer = this.#viewerContainer.querySelector(\n `.page[data-page-number=\"${nextPage}\"] .textLayer`\n );\n if (!textLayer) {\n return null;\n }\n const walker = document.createTreeWalker(textLayer, NodeFilter.SHOW_TEXT);\n const node = isUp ? walker.lastChild() : walker.firstChild();\n if (node) {\n return node;\n }\n }\n }\n\n /**\n * Move the caret in the given direction.\n * @param {boolean} isUp\n * @param {boolean} select\n */\n moveCaret(isUp, select) {\n const selection = document.getSelection();\n if (selection.rangeCount === 0) {\n return;\n }\n const { focusNode } = selection;\n const focusElement =\n focusNode.nodeType !== Node.ELEMENT_NODE\n ? focusNode.parentElement\n : focusNode;\n const root = focusElement.closest(\".textLayer\");\n if (!root) {\n return;\n }\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n walker.currentNode = focusNode;\n\n // Move to the next element which is not on the same line as the focus\n // element.\n const focusRect = focusElement.getBoundingClientRect();\n let newLineElement = null;\n const nodeIterator = (\n isUp ? walker.previousSibling : walker.nextSibling\n ).bind(walker);\n while (nodeIterator()) {\n const element = walker.currentNode.parentElement;\n if (!this.#isOnSameLine(focusRect, element.getBoundingClientRect())) {\n newLineElement = element;\n break;\n }\n }\n\n if (!newLineElement) {\n // Need to find the next line on the next page.\n const node = this.#getNodeOnNextPage(root, isUp);\n if (!node) {\n return;\n }\n if (select) {\n const lastNode =\n (isUp ? walker.firstChild() : walker.lastChild()) || focusNode;\n selection.extend(lastNode, isUp ? 0 : lastNode.length);\n const range = document.createRange();\n range.setStart(node, isUp ? node.length : 0);\n range.setEnd(node, isUp ? node.length : 0);\n selection.addRange(range);\n return;\n }\n const [caretX] = this.#getCaretPosition(selection, isUp);\n const { parentElement } = node;\n this.#setCaretPosition(\n select,\n selection,\n parentElement,\n parentElement.getBoundingClientRect(),\n caretX\n );\n return;\n }\n\n // We've a candidate for the next line now we want to find the first element\n // which is under/over the caret.\n const [caretX, caretY] = this.#getCaretPosition(selection, isUp);\n const newLineElementRect = newLineElement.getBoundingClientRect();\n\n // Maybe the element on the new line is a valid candidate.\n if (this.#isUnderOver(newLineElementRect, caretX, caretY, isUp)) {\n this.#setCaretPosition(\n select,\n selection,\n newLineElement,\n newLineElementRect,\n caretX\n );\n return;\n }\n\n while (nodeIterator()) {\n // Search an element on the same line as newLineElement\n // which could be under/over the caret.\n const element = walker.currentNode.parentElement;\n const elementRect = element.getBoundingClientRect();\n if (!this.#isOnSameLine(newLineElementRect, elementRect)) {\n break;\n }\n if (this.#isUnderOver(elementRect, caretX, caretY, isUp)) {\n // We found the element.\n this.#setCaretPosition(select, selection, element, elementRect, caretX);\n return;\n }\n }\n\n // No element has been found so just put the caret on the element on the new\n // line.\n this.#setCaretPosition(\n select,\n selection,\n newLineElement,\n newLineElementRect,\n caretX\n );\n }\n}\n\nexport { CaretBrowsingMode };\n","/* Copyright 2025 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { noContextMenu, stopEvent } from \"pdfjs-lib\";\n\n// Timeout before ending resize operation.\nconst RESIZE_TIMEOUT = 400; // ms\n\n/**\n * Viewer control to display a sidebar with resizer functionality.\n */\nclass Sidebar {\n #initialWidth = 0;\n\n #width = 0;\n\n #coefficient;\n\n #resizeTimeout = null;\n\n #resizer;\n\n #isResizerOnTheLeft;\n\n #isKeyboardResizing = false;\n\n #resizeObserver;\n\n #prevX = 0;\n\n /**\n * @typedef {Object} SidebarElements\n * @property {HTMLElement} sidebar - The sidebar element.\n * @property {HTMLElement} resizer - The sidebar resizer element.\n * @property {HTMLElement} toggleButton - The button used to toggle the\n * sidebar.\n */\n\n /**\n * Create a sidebar with resizer functionality.\n * @param {SidebarElements} sidebarElements\n * @param {boolean} ltr\n * @param {boolean} isResizerOnTheLeft\n */\n constructor({ sidebar, resizer, toggleButton }, ltr, isResizerOnTheLeft) {\n this._sidebar = sidebar;\n this.#coefficient = ltr === isResizerOnTheLeft ? -1 : 1;\n this.#resizer = resizer;\n this.#isResizerOnTheLeft = isResizerOnTheLeft;\n\n const style = window.getComputedStyle(sidebar);\n this.#initialWidth = this.#width = parseFloat(\n style.getPropertyValue(\"--sidebar-width\")\n );\n resizer.ariaValueMin =\n parseFloat(style.getPropertyValue(\"--sidebar-min-width\")) || 0;\n resizer.ariaValueMax =\n parseFloat(style.getPropertyValue(\"--sidebar-max-width\")) || Infinity;\n resizer.ariaValueNow = this.#width;\n\n this.#makeSidebarResizable();\n toggleButton.addEventListener(\"click\", this.toggle.bind(this));\n this._isOpen = false;\n sidebar.hidden = true;\n\n this.#resizeObserver = new ResizeObserver(\n ([\n {\n borderBoxSize: [{ inlineSize }],\n },\n ]) => {\n if (!isNaN(this.#prevX)) {\n this.#prevX += this.#coefficient * (inlineSize - this.#width);\n }\n this.#setWidth(inlineSize);\n }\n );\n this.#resizeObserver.observe(sidebar);\n }\n\n #makeSidebarResizable() {\n const sidebarStyle = this._sidebar.style;\n let pointerMoveAC;\n const cancelResize = () => {\n this.#resizeTimeout = null;\n this._sidebar.classList.remove(\"resizing\");\n pointerMoveAC?.abort();\n pointerMoveAC = null;\n this.#isKeyboardResizing = false;\n this.onStopResizing();\n this.#prevX = NaN;\n };\n this.#resizer.addEventListener(\"pointerdown\", e => {\n if (pointerMoveAC) {\n cancelResize();\n return;\n }\n this.onStartResizing();\n const { clientX } = e;\n stopEvent(e);\n this.#prevX = clientX;\n pointerMoveAC = new AbortController();\n const { signal } = pointerMoveAC;\n const sidebar = this._sidebar;\n sidebar.classList.add(\"resizing\");\n const parentStyle = sidebar.parentElement.style;\n parentStyle.minWidth = 0;\n window.addEventListener(\"contextmenu\", noContextMenu, { signal });\n window.addEventListener(\n \"pointermove\",\n ev => {\n if (!pointerMoveAC || Math.abs(ev.clientX - this.#prevX) < 1) {\n return;\n }\n stopEvent(ev);\n sidebarStyle.width = `${Math.round(this.#width + this.#coefficient * (ev.clientX - this.#prevX))}px`;\n },\n { signal, capture: true }\n );\n window.addEventListener(\"blur\", cancelResize, { signal });\n window.addEventListener(\n \"pointerup\",\n ev => {\n if (pointerMoveAC) {\n cancelResize();\n stopEvent(ev);\n }\n },\n { signal }\n );\n });\n this.#resizer.addEventListener(\"keydown\", e => {\n const { key } = e;\n const isArrowLeft = key === \"ArrowLeft\";\n if (isArrowLeft || key === \"ArrowRight\") {\n if (!this.#isKeyboardResizing) {\n this._sidebar.classList.add(\"resizing\");\n this.#isKeyboardResizing = true;\n this.onStartResizing();\n }\n\n const base = e.ctrlKey || e.metaKey ? 10 : 1;\n const dx = base * (isArrowLeft ? -1 : 1);\n clearTimeout(this.#resizeTimeout);\n this.#resizeTimeout = setTimeout(cancelResize, RESIZE_TIMEOUT);\n sidebarStyle.width = `${Math.round(this.#width + this.#coefficient * dx)}px`;\n stopEvent(e);\n }\n });\n }\n\n #setWidth(newWidth) {\n this.#width = newWidth;\n this.#resizer.ariaValueNow = Math.round(newWidth);\n if (this.#isResizerOnTheLeft) {\n this._sidebar.parentElement.style.insetInlineStart = `${(this.#initialWidth - newWidth).toFixed(3)}px`;\n }\n this.onResizing(newWidth);\n }\n\n /**\n * Get the current width of the sidebar in pixels.\n * @returns {number}\n */\n get width() {\n return this.#width;\n }\n\n /**\n * Set the width of the sidebar in pixels.\n * @param {number} newWidth\n */\n set width(newWidth) {\n this._sidebar.style.width = `${newWidth}px`;\n }\n\n /**\n * Callback to be executed when the user starts resizing the sidebar.\n */\n onStartResizing() {}\n\n /**\n * Callback to be executed when the user stops resizing the sidebar.\n */\n onStopResizing() {}\n\n /**\n * Callback to be executed when the sidebar is being resized.\n * @param {number} newWidth - The new width of the sidebar in pixels.\n */\n onResizing(_newWidth) {}\n\n /**\n * Toggle the sidebar's visibility.\n * @param {boolean} [visibility] - The visibility state to set.\n */\n toggle(visibility = !this._isOpen) {\n this._sidebar.hidden = !(this._isOpen = visibility);\n }\n\n destroy() {\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = null;\n }\n}\n\nexport { Sidebar };\n","/* Copyright 2025 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AnnotationEditorType,\n applyOpacity,\n CSSConstants,\n findContrastColor,\n MathClamp,\n noContextMenu,\n PDFDateString,\n renderRichText,\n shadow,\n stopEvent,\n Util,\n} from \"pdfjs-lib\";\nimport { binarySearchFirstItem } from \"./ui_utils.js\";\nimport { Sidebar } from \"./sidebar.js\";\n\nclass CommentManager {\n #dialog;\n\n #popup;\n\n #sidebar;\n\n static #hasForcedColors = null;\n\n constructor(\n commentDialog,\n sidebar,\n eventBus,\n linkService,\n overlayManager,\n ltr,\n hasForcedColors\n ) {\n const dateFormat = new Intl.DateTimeFormat(undefined, {\n dateStyle: \"long\",\n });\n this.dialogElement = commentDialog.dialog;\n this.#dialog = new CommentDialog(\n commentDialog,\n overlayManager,\n eventBus,\n ltr\n );\n this.#popup = new CommentPopup(\n eventBus,\n dateFormat,\n ltr,\n this.dialogElement\n );\n this.#sidebar = new CommentSidebar(\n sidebar,\n eventBus,\n linkService,\n this.#popup,\n dateFormat,\n ltr\n );\n this.#popup.sidebar = this.#sidebar;\n CommentManager.#hasForcedColors = hasForcedColors;\n }\n\n setSidebarUiManager(uiManager) {\n this.#sidebar.setUIManager(uiManager);\n }\n\n showSidebar(annotations) {\n this.#sidebar.show(annotations);\n }\n\n hideSidebar() {\n this.#sidebar.hide();\n }\n\n removeComments(ids) {\n this.#sidebar.removeComments(ids);\n }\n\n selectComment(id) {\n this.#sidebar.selectComment(null, id);\n }\n\n addComment(annotation) {\n this.#sidebar.addComment(annotation);\n }\n\n updateComment(annotation) {\n this.#sidebar.updateComment(annotation);\n }\n\n toggleCommentPopup(editor, isSelected, visibility, isEditable) {\n if (isSelected) {\n this.selectComment(editor.uid);\n }\n this.#popup.toggle(editor, isSelected, visibility, isEditable);\n }\n\n destroyPopup() {\n this.#popup.destroy();\n }\n\n updatePopupColor(editor) {\n this.#popup.updateColor(editor);\n }\n\n showDialog(uiManager, editor, posX, posY, options) {\n return this.#dialog.open(uiManager, editor, posX, posY, options);\n }\n\n makeCommentColor(color, opacity) {\n return CommentManager._makeCommentColor(color, opacity);\n }\n\n static _makeCommentColor(color, opacity) {\n return this.#hasForcedColors\n ? null\n : findContrastColor(\n applyOpacity(...color, opacity ?? 1),\n CSSConstants.commentForegroundColor\n );\n }\n\n destroy() {\n this.#dialog.destroy();\n this.#sidebar.hide();\n this.#popup.destroy();\n }\n}\n\nclass CommentSidebar extends Sidebar {\n #annotations = null;\n\n #eventBus;\n\n #boundCommentClick = this.#commentClick.bind(this);\n\n #boundCommentKeydown = this.#commentKeydown.bind(this);\n\n #closeButton;\n\n #commentsList;\n\n #commentCount;\n\n #dateFormat;\n\n #sidebarTitle;\n\n #learnMoreUrl;\n\n #linkService;\n\n #popup;\n\n #elementsToAnnotations = null;\n\n #idsToElements = null;\n\n #uiManager = null;\n\n constructor(\n {\n learnMoreUrl,\n sidebar,\n sidebarResizer,\n commentsList,\n commentCount,\n sidebarTitle,\n closeButton,\n commentToolbarButton,\n },\n eventBus,\n linkService,\n popup,\n dateFormat,\n ltr\n ) {\n super(\n { sidebar, resizer: sidebarResizer, toggleButton: commentToolbarButton },\n ltr,\n /* isResizerOnTheLeft = */ true\n );\n this.#sidebarTitle = sidebarTitle;\n this.#commentsList = commentsList;\n this.#commentCount = commentCount;\n this.#learnMoreUrl = learnMoreUrl;\n this.#linkService = linkService;\n this.#closeButton = closeButton;\n this.#popup = popup;\n this.#dateFormat = dateFormat;\n this.#eventBus = eventBus;\n\n closeButton.addEventListener(\"click\", () => {\n eventBus.dispatch(\"switchannotationeditormode\", {\n source: this,\n mode: AnnotationEditorType.NONE,\n });\n });\n const keyDownCallback = e => {\n if (e.key === \"ArrowDown\" || e.key === \"Home\" || e.key === \"F6\") {\n this.#commentsList.firstElementChild.focus();\n stopEvent(e);\n } else if (e.key === \"ArrowUp\" || e.key === \"End\") {\n this.#commentsList.lastElementChild.focus();\n stopEvent(e);\n }\n };\n commentToolbarButton.addEventListener(\"keydown\", keyDownCallback);\n sidebar.addEventListener(\"keydown\", keyDownCallback);\n }\n\n setUIManager(uiManager) {\n this.#uiManager = uiManager;\n }\n\n show(annotations) {\n this.#elementsToAnnotations = new WeakMap();\n this.#idsToElements = new Map();\n this.#annotations = annotations;\n annotations.sort(this.#sortComments.bind(this));\n if (annotations.length !== 0) {\n const fragment = document.createDocumentFragment();\n for (const annotation of annotations) {\n fragment.append(this.#createCommentElement(annotation));\n }\n\n this.#setCommentsCount(fragment);\n this.#commentsList.append(fragment);\n } else {\n this.#setCommentsCount();\n }\n this._sidebar.hidden = false;\n this.#eventBus.dispatch(\"reporttelemetry\", {\n source: this,\n details: {\n type: \"commentSidebar\",\n data: { numberOfAnnotations: annotations.length },\n },\n });\n }\n\n hide() {\n this._sidebar.hidden = true;\n this.#commentsList.replaceChildren();\n this.#elementsToAnnotations = null;\n this.#idsToElements = null;\n this.#annotations = null;\n }\n\n removeComments(ids) {\n if (ids.length === 0 || !this.#idsToElements) {\n return;\n }\n if (\n new Set(this.#idsToElements.keys()).difference(new Set(ids)).size === 0\n ) {\n this.#removeAll();\n return;\n }\n for (const id of ids) {\n this.#removeComment(id);\n }\n }\n\n focusComment(id) {\n const element = this.#idsToElements.get(id);\n if (!element) {\n return;\n }\n this._sidebar.scrollTop = element.offsetTop - this._sidebar.offsetTop;\n for (const el of this.#commentsList.children) {\n el.classList.toggle(\"selected\", el === element);\n }\n }\n\n updateComment(annotation) {\n if (!this.#idsToElements) {\n return;\n }\n const {\n id,\n creationDate,\n modificationDate,\n richText,\n contentsObj,\n popupRef,\n } = annotation;\n\n if (!popupRef || (!richText && !contentsObj?.str)) {\n this.#removeComment(id);\n }\n\n const element = this.#idsToElements.get(id);\n if (!element) {\n return;\n }\n const prevAnnotation = this.#elementsToAnnotations.get(element);\n let index = binarySearchFirstItem(\n this.#annotations,\n a => this.#sortComments(a, prevAnnotation) >= 0\n );\n if (index >= this.#annotations.length) {\n return;\n }\n\n this.#setDate(element.firstElementChild, modificationDate || creationDate);\n this.#setText(element.lastElementChild, richText, contentsObj);\n\n this.#annotations.splice(index, 1);\n index = binarySearchFirstItem(\n this.#annotations,\n a => this.#sortComments(a, annotation) >= 0\n );\n this.#annotations.splice(index, 0, annotation);\n if (index >= this.#commentsList.children.length) {\n this.#commentsList.append(element);\n } else {\n this.#commentsList.insertBefore(\n element,\n this.#commentsList.children[index]\n );\n }\n }\n\n #removeComment(id) {\n const element = this.#idsToElements?.get(id);\n if (!element) {\n return;\n }\n const annotation = this.#elementsToAnnotations.get(element);\n const index = binarySearchFirstItem(\n this.#annotations,\n a => this.#sortComments(a, annotation) >= 0\n );\n if (index >= this.#annotations.length) {\n return;\n }\n this.#annotations.splice(index, 1);\n element.remove();\n this.#idsToElements.delete(id);\n this.#setCommentsCount();\n }\n\n #removeAll() {\n this.#commentsList.replaceChildren();\n this.#elementsToAnnotations = new WeakMap();\n this.#idsToElements.clear();\n this.#annotations.length = 0;\n this.#setCommentsCount();\n }\n\n selectComment(element, id = null) {\n if (!this.#idsToElements) {\n return;\n }\n const hasNoElement = !element;\n element ||= this.#idsToElements.get(id);\n for (const el of this.#commentsList.children) {\n el.classList.toggle(\"selected\", el === element);\n }\n if (hasNoElement) {\n element?.scrollIntoView({ behavior: \"instant\", block: \"center\" });\n }\n }\n\n addComment(annotation) {\n if (this.#idsToElements?.has(annotation.id)) {\n return;\n }\n const { popupRef, contentsObj } = annotation;\n if (!popupRef || !contentsObj?.str) {\n return;\n }\n const commentItem = this.#createCommentElement(annotation);\n if (this.#annotations.length === 0) {\n this.#commentsList.replaceChildren(commentItem);\n this.#annotations.push(annotation);\n this.#setCommentsCount();\n return;\n }\n const index = binarySearchFirstItem(\n this.#annotations,\n a => this.#sortComments(a, annotation) >= 0\n );\n this.#annotations.splice(index, 0, annotation);\n if (index >= this.#commentsList.children.length) {\n this.#commentsList.append(commentItem);\n } else {\n this.#commentsList.insertBefore(\n commentItem,\n this.#commentsList.children[index]\n );\n }\n this.#setCommentsCount();\n }\n\n #setCommentsCount(container = this.#commentsList) {\n const count = this.#idsToElements.size;\n this.#sidebarTitle.setAttribute(\n \"data-l10n-args\",\n JSON.stringify({ count })\n );\n this.#commentCount.textContent = count;\n if (count === 0) {\n container.append(this.#createZeroCommentElement());\n }\n }\n\n #createZeroCommentElement() {\n const commentItem = document.createElement(\"li\");\n commentItem.classList.add(\"sidebarComment\", \"noComments\");\n const textDiv = document.createElement(\"div\");\n textDiv.className = \"sidebarCommentText\";\n textDiv.setAttribute(\n \"data-l10n-id\",\n \"pdfjs-editor-comments-sidebar-no-comments1\"\n );\n commentItem.append(textDiv);\n if (this.#learnMoreUrl) {\n const a = document.createElement(\"a\");\n a.setAttribute(\n \"data-l10n-id\",\n \"pdfjs-editor-comments-sidebar-no-comments-link\"\n );\n a.href = this.#learnMoreUrl;\n a.target = \"_blank\";\n a.rel = \"noopener noreferrer\";\n commentItem.append(a);\n }\n return commentItem;\n }\n\n #setDate(element, date) {\n date = PDFDateString.toDateObject(date);\n element.dateTime = date.toISOString();\n element.textContent = this.#dateFormat.format(date);\n }\n\n #setText(element, richText, contentsObj) {\n element.replaceChildren();\n const html =\n richText?.str && (!contentsObj?.str || richText.str === contentsObj.str)\n ? richText.html\n : contentsObj?.str;\n renderRichText(\n {\n html,\n dir: contentsObj?.dir || \"auto\",\n className: \"richText\",\n },\n element\n );\n }\n\n #createCommentElement(annotation) {\n const {\n id,\n creationDate,\n modificationDate,\n richText,\n contentsObj,\n color,\n opacity,\n } = annotation;\n const commentItem = document.createElement(\"li\");\n commentItem.role = \"button\";\n commentItem.className = \"sidebarComment\";\n commentItem.tabIndex = -1;\n commentItem.style.backgroundColor =\n (color && CommentManager._makeCommentColor(color, opacity)) || \"\";\n const dateDiv = document.createElement(\"time\");\n this.#setDate(dateDiv, modificationDate || creationDate);\n\n const textDiv = document.createElement(\"div\");\n textDiv.className = \"sidebarCommentText\";\n this.#setText(textDiv, richText, contentsObj);\n\n commentItem.append(dateDiv, textDiv);\n commentItem.addEventListener(\"click\", this.#boundCommentClick);\n commentItem.addEventListener(\"keydown\", this.#boundCommentKeydown);\n\n this.#elementsToAnnotations.set(commentItem, annotation);\n this.#idsToElements.set(id, commentItem);\n return commentItem;\n }\n\n async #commentClick({ currentTarget }) {\n if (currentTarget.classList.contains(\"selected\")) {\n currentTarget.classList.remove(\"selected\");\n this.#popup._hide();\n return;\n }\n const annotation = this.#elementsToAnnotations.get(currentTarget);\n if (!annotation) {\n return;\n }\n this.#popup._hide();\n const { id, pageIndex, rect } = annotation;\n const pageNumber = pageIndex + 1;\n const pageVisiblePromise =\n this.#uiManager?.waitForEditorsRendered(pageNumber);\n this.#linkService?.goToXY(pageNumber, rect[0], rect[3], {\n center: \"both\",\n });\n this.selectComment(currentTarget);\n await pageVisiblePromise;\n this.#uiManager?.selectComment(pageIndex, id);\n }\n\n #commentKeydown(e) {\n const { key, currentTarget } = e;\n switch (key) {\n case \"ArrowDown\":\n (\n currentTarget.nextElementSibling ||\n this.#commentsList.firstElementChild\n ).focus();\n stopEvent(e);\n break;\n case \"ArrowUp\":\n (\n currentTarget.previousElementSibling ||\n this.#commentsList.lastElementChild\n ).focus();\n stopEvent(e);\n break;\n case \"Home\":\n this.#commentsList.firstElementChild.focus();\n stopEvent(e);\n break;\n case \"End\":\n this.#commentsList.lastElementChild.focus();\n stopEvent(e);\n break;\n case \"Enter\":\n case \" \":\n this.#commentClick(e);\n stopEvent(e);\n break;\n case \"ShiftTab\":\n this.#closeButton.focus();\n stopEvent(e);\n break;\n }\n }\n\n #sortComments(a, b) {\n const dateA = PDFDateString.toDateObject(\n a.modificationDate || a.creationDate\n );\n const dateB = PDFDateString.toDateObject(\n b.modificationDate || b.creationDate\n );\n if (dateA !== dateB) {\n if (dateA !== null && dateB !== null) {\n return dateB - dateA;\n }\n return dateA !== null ? -1 : 1;\n }\n if (a.pageIndex !== b.pageIndex) {\n return a.pageIndex - b.pageIndex;\n }\n if (a.rect[3] !== b.rect[3]) {\n return b.rect[3] - a.rect[3];\n }\n if (a.rect[0] !== b.rect[0]) {\n return a.rect[0] - b.rect[0];\n }\n if (a.rect[1] !== b.rect[1]) {\n return b.rect[1] - a.rect[1];\n }\n if (a.rect[2] !== b.rect[2]) {\n return a.rect[2] - b.rect[2];\n }\n return a.id.localeCompare(b.id);\n }\n}\n\nclass CommentDialog {\n #dialog;\n\n #editor;\n\n #overlayManager;\n\n #previousText = \"\";\n\n #commentText = \"\";\n\n #textInput;\n\n #title;\n\n #saveButton;\n\n #uiManager;\n\n #prevDragX = 0;\n\n #prevDragY = 0;\n\n #dialogX = 0;\n\n #dialogY = 0;\n\n #isLTR;\n\n #eventBus;\n\n constructor(\n { dialog, toolbar, title, textInput, cancelButton, saveButton },\n overlayManager,\n eventBus,\n ltr\n ) {\n this.#dialog = dialog;\n this.#textInput = textInput;\n this.#overlayManager = overlayManager;\n this.#eventBus = eventBus;\n this.#saveButton = saveButton;\n this.#title = title;\n this.#isLTR = ltr;\n\n const finishBound = this.#finish.bind(this);\n dialog.addEventListener(\"close\", finishBound);\n dialog.addEventListener(\"contextmenu\", e => {\n if (e.target !== this.#textInput) {\n e.preventDefault();\n }\n });\n cancelButton.addEventListener(\"click\", finishBound);\n saveButton.addEventListener(\"click\", this.#save.bind(this));\n\n textInput.addEventListener(\"input\", () => {\n saveButton.disabled = textInput.value === this.#previousText;\n });\n textInput.addEventListener(\"keydown\", e => {\n if (\n (e.ctrlKey || e.metaKey) &&\n e.key === \"Enter\" &&\n !saveButton.disabled\n ) {\n this.#save();\n }\n });\n\n // Make the dialog draggable.\n let pointerMoveAC;\n const cancelDrag = () => {\n dialog.classList.remove(\"dragging\");\n pointerMoveAC?.abort();\n pointerMoveAC = null;\n };\n toolbar.addEventListener(\"pointerdown\", e => {\n if (pointerMoveAC) {\n cancelDrag();\n return;\n }\n const { clientX, clientY } = e;\n stopEvent(e);\n this.#prevDragX = clientX;\n this.#prevDragY = clientY;\n pointerMoveAC = new AbortController();\n const { signal } = pointerMoveAC;\n const { innerHeight, innerWidth } = window;\n dialog.classList.add(\"dragging\");\n window.addEventListener(\n \"pointermove\",\n ev => {\n if (!pointerMoveAC) {\n return;\n }\n const { clientX: x, clientY: y } = ev;\n this.#setPosition(\n this.#dialogX + (x - this.#prevDragX) / innerWidth,\n this.#dialogY + (y - this.#prevDragY) / innerHeight\n );\n this.#prevDragX = x;\n this.#prevDragY = y;\n stopEvent(ev);\n },\n { signal }\n );\n window.addEventListener(\"blur\", cancelDrag, { signal });\n window.addEventListener(\n \"pointerup\",\n ev => {\n if (pointerMoveAC) {\n cancelDrag();\n stopEvent(ev);\n }\n },\n { signal }\n );\n });\n\n overlayManager.register(dialog);\n }\n\n async open(uiManager, editor, posX, posY, options) {\n if (editor) {\n this.#uiManager = uiManager;\n this.#editor = editor;\n }\n const {\n contentsObj: { str },\n color,\n opacity,\n } = editor.getData();\n const { style: dialogStyle } = this.#dialog;\n if (color) {\n dialogStyle.backgroundColor = CommentManager._makeCommentColor(\n color,\n opacity\n );\n dialogStyle.borderColor = Util.makeHexColor(...color);\n } else {\n dialogStyle.backgroundColor = dialogStyle.borderColor = \"\";\n }\n this.#commentText = str || \"\";\n const textInput = this.#textInput;\n textInput.value = this.#previousText = this.#commentText;\n if (str) {\n this.#title.setAttribute(\n \"data-l10n-id\",\n \"pdfjs-editor-edit-comment-dialog-title-when-editing\"\n );\n this.#saveButton.setAttribute(\n \"data-l10n-id\",\n \"pdfjs-editor-edit-comment-dialog-save-button-when-editing\"\n );\n } else {\n this.#title.setAttribute(\n \"data-l10n-id\",\n \"pdfjs-editor-edit-comment-dialog-title-when-adding\"\n );\n this.#saveButton.setAttribute(\n \"data-l10n-id\",\n \"pdfjs-editor-edit-comment-dialog-save-button-when-adding\"\n );\n }\n if (options?.height) {\n textInput.style.height = `${options.height}px`;\n }\n this.#uiManager?.removeEditListeners();\n this.#saveButton.disabled = true;\n const parentDimensions = options?.parentDimensions;\n const { innerHeight, innerWidth } = window;\n if (editor.hasDefaultPopupPosition()) {\n const { dialogWidth, dialogHeight } = this._dialogDimensions;\n if (parentDimensions) {\n if (\n this.#isLTR &&\n posX + dialogWidth >\n Math.min(parentDimensions.x + parentDimensions.width, innerWidth)\n ) {\n const buttonWidth = this.#editor.commentButtonWidth;\n posX -= dialogWidth - buttonWidth * parentDimensions.width;\n } else if (!this.#isLTR) {\n const buttonWidth =\n this.#editor.commentButtonWidth * parentDimensions.width;\n if (posX - dialogWidth < Math.max(0, parentDimensions.x)) {\n posX = Math.max(0, posX);\n } else {\n posX -= dialogWidth - buttonWidth;\n }\n }\n }\n const height = Math.max(dialogHeight, options?.height || 0);\n if (posY + height > innerHeight) {\n posY = innerHeight - height;\n }\n if (posY < 0) {\n posY = 0;\n }\n }\n\n posX = MathClamp(posX / innerWidth, 0, 1);\n posY = MathClamp(posY / innerHeight, 0, 1);\n this.#setPosition(posX, posY);\n\n await this.#overlayManager.open(this.#dialog);\n textInput.focus();\n }\n\n async #save() {\n this.#editor.comment = this.#textInput.value;\n this.#finish();\n }\n\n get _dialogDimensions() {\n const dialog = this.#dialog;\n const { style } = dialog;\n style.opacity = \"0\";\n style.display = \"block\";\n const { width, height } = dialog.getBoundingClientRect();\n style.opacity = style.display = \"\";\n return shadow(this, \"_dialogDimensions\", {\n dialogWidth: width,\n dialogHeight: height,\n });\n }\n\n #setPosition(x, y) {\n this.#dialogX = x;\n this.#dialogY = y;\n const { style } = this.#dialog;\n style.left = `${100 * x}%`;\n style.top = `${100 * y}%`;\n }\n\n #finish() {\n if (!this.#editor) {\n return;\n }\n const edited = this.#textInput.value !== this.#commentText;\n this.#eventBus.dispatch(\"reporttelemetry\", {\n source: this,\n details: {\n type: \"comment\",\n data: {\n edited,\n },\n },\n });\n\n this.#editor?.focusCommentButton();\n this.#editor = null;\n this.#textInput.value = this.#previousText = this.#commentText = \"\";\n this.#overlayManager.closeIfActive(this.#dialog);\n this.#textInput.style.height = \"\";\n this.#uiManager?.addEditListeners();\n this.#uiManager = null;\n }\n\n destroy() {\n this.#uiManager = null;\n this.#editor = null;\n this.#finish();\n }\n}\n\nclass CommentPopup {\n #buttonsContainer = null;\n\n #eventBus;\n\n #commentDialog;\n\n #dateFormat;\n\n #editor = null;\n\n #isLTR;\n\n #container = null;\n\n #text = null;\n\n #time = null;\n\n #prevDragX = 0;\n\n #prevDragY = 0;\n\n #posX = 0;\n\n #posY = 0;\n\n #previousFocusedElement = null;\n\n #selected = false;\n\n #visible = false;\n\n constructor(eventBus, dateFormat, ltr, commentDialog) {\n this.#eventBus = eventBus;\n this.#dateFormat = dateFormat;\n this.#isLTR = ltr;\n this.#commentDialog = commentDialog;\n this.sidebar = null;\n }\n\n get _popupWidth() {\n const container = this.#createPopup();\n const { style } = container;\n style.opacity = \"0\";\n style.display = \"block\";\n document.body.append(container);\n const width = container.getBoundingClientRect().width;\n container.remove();\n style.opacity = style.display = \"\";\n return shadow(this, \"_popupWidth\", width);\n }\n\n #createPopup() {\n if (this.#container) {\n return this.#container;\n }\n const container = (this.#container = document.createElement(\"div\"));\n container.className = \"commentPopup\";\n container.id = \"commentPopup\";\n container.tabIndex = -1;\n container.role = \"dialog\";\n container.ariaModal = \"false\";\n container.addEventListener(\"contextmenu\", noContextMenu);\n container.addEventListener(\"keydown\", e => {\n if (e.key === \"Escape\") {\n this.toggle(this.#editor, true, false);\n this.#previousFocusedElement?.focus();\n stopEvent(e);\n }\n });\n container.addEventListener(\"click\", () => {\n container.focus();\n });\n\n const top = document.createElement(\"div\");\n top.className = \"commentPopupTop\";\n const time = (this.#time = document.createElement(\"time\"));\n time.className = \"commentPopupTime\";\n\n const buttons = (this.#buttonsContainer = document.createElement(\"div\"));\n buttons.className = \"commentPopupButtons\";\n const edit = document.createElement(\"button\");\n edit.classList.add(\"commentPopupEdit\", \"toolbarButton\");\n edit.tabIndex = 0;\n edit.setAttribute(\"data-l10n-id\", \"pdfjs-editor-edit-comment-popup-button\");\n edit.ariaHasPopup = \"dialog\";\n edit.ariaControlsElements = [this.#commentDialog];\n const editLabel = document.createElement(\"span\");\n editLabel.setAttribute(\n \"data-l10n-id\",\n \"pdfjs-editor-edit-comment-popup-button-label\"\n );\n edit.append(editLabel);\n edit.addEventListener(\"click\", () => {\n const editor = this.#editor;\n const height = parseFloat(getComputedStyle(this.#text).height);\n this.toggle(editor, /* isSelected */ true, /* visibility */ false);\n editor.editComment({\n height,\n });\n });\n edit.addEventListener(\"contextmenu\", noContextMenu);\n\n const del = document.createElement(\"button\");\n del.classList.add(\"commentPopupDelete\", \"toolbarButton\");\n del.tabIndex = 0;\n del.setAttribute(\n \"data-l10n-id\",\n \"pdfjs-editor-delete-comment-popup-button\"\n );\n const delLabel = document.createElement(\"span\");\n delLabel.setAttribute(\n \"data-l10n-id\",\n \"pdfjs-editor-delete-comment-popup-button-label\"\n );\n del.append(delLabel);\n del.addEventListener(\"click\", () => {\n this.#eventBus.dispatch(\"reporttelemetry\", {\n source: this,\n details: {\n type: \"comment\",\n data: {\n deleted: true,\n },\n },\n });\n const editor = this.#editor;\n const savedData = editor.comment;\n this.destroy();\n if (savedData?.text) {\n editor._uiManager.deleteComment(editor, savedData);\n } else {\n editor.comment = null;\n }\n editor.focus();\n });\n del.addEventListener(\"contextmenu\", noContextMenu);\n buttons.append(edit, del);\n\n top.append(time, buttons);\n\n const separator = document.createElement(\"hr\");\n\n const text = (this.#text = document.createElement(\"div\"));\n text.className = \"commentPopupText\";\n container.append(top, separator, text);\n\n // Make the dialog draggable.\n let pointerMoveAC;\n const cancelDrag = () => {\n container.classList.remove(\"dragging\");\n pointerMoveAC?.abort();\n pointerMoveAC = null;\n };\n top.addEventListener(\"pointerdown\", e => {\n if (pointerMoveAC) {\n cancelDrag();\n return;\n }\n const { target, clientX, clientY } = e;\n if (buttons.contains(target)) {\n return;\n }\n stopEvent(e);\n const { width: parentWidth, height: parentHeight } =\n this.#editor.parentBoundingClientRect;\n this.#prevDragX = clientX;\n this.#prevDragY = clientY;\n pointerMoveAC = new AbortController();\n const { signal } = pointerMoveAC;\n container.classList.add(\"dragging\");\n window.addEventListener(\n \"pointermove\",\n ev => {\n if (!pointerMoveAC) {\n return; // Not dragging.\n }\n const { clientX: x, clientY: y } = ev;\n this.#setPosition(\n this.#posX + (x - this.#prevDragX) / parentWidth,\n this.#posY + (y - this.#prevDragY) / parentHeight,\n /* correctPosition = */ false\n );\n this.#prevDragX = x;\n this.#prevDragY = y;\n stopEvent(ev);\n },\n { signal }\n );\n window.addEventListener(\"blur\", cancelDrag, { signal });\n window.addEventListener(\n \"pointerup\",\n ev => {\n if (pointerMoveAC) {\n cancelDrag();\n stopEvent(ev);\n }\n },\n { signal }\n );\n });\n\n return container;\n }\n\n updateColor(editor) {\n if (this.#editor !== editor || !this.#visible) {\n return;\n }\n const { color, opacity } = editor.getData();\n this.#container.style.backgroundColor =\n (color && CommentManager._makeCommentColor(color, opacity)) || \"\";\n }\n\n _hide(editor) {\n const container = this.#createPopup();\n\n container.classList.toggle(\"hidden\", true);\n container.classList.toggle(\"selected\", false);\n (editor || this.#editor)?.setCommentButtonStates({\n selected: false,\n hasPopup: false,\n });\n this.#editor = null;\n this.#selected = false;\n this.#visible = false;\n this.#text.replaceChildren();\n this.sidebar.selectComment(null);\n }\n\n toggle(editor, isSelected, visibility = undefined, isEditable = true) {\n if (!editor) {\n this.destroy();\n return;\n }\n\n if (isSelected) {\n visibility ??=\n this.#editor === editor ? !this.#selected || !this.#visible : true;\n } else {\n if (this.#selected) {\n return;\n }\n visibility ??= !this.#visible;\n }\n\n if (!visibility) {\n this._hide(editor);\n return;\n }\n\n this.#visible = true;\n if (this.#editor !== editor) {\n this.#editor?.setCommentButtonStates({\n selected: false,\n hasPopup: false,\n });\n }\n\n const container = this.#createPopup();\n this.#buttonsContainer.classList.toggle(\"hidden\", !isEditable);\n container.classList.toggle(\"hidden\", false);\n container.classList.toggle(\"selected\", isSelected);\n this.#selected = isSelected;\n this.#editor = editor;\n editor.setCommentButtonStates({\n selected: isSelected,\n hasPopup: true,\n });\n\n const {\n contentsObj,\n richText,\n creationDate,\n modificationDate,\n color,\n opacity,\n } = editor.getData();\n container.style.backgroundColor =\n (color && CommentManager._makeCommentColor(color, opacity)) || \"\";\n this.#text.replaceChildren();\n const html =\n richText?.str && (!contentsObj?.str || richText.str === contentsObj.str)\n ? richText.html\n : contentsObj?.str;\n if (html) {\n renderRichText(\n {\n html,\n dir: contentsObj?.dir || \"auto\",\n className: \"richText\",\n },\n this.#text\n );\n }\n this.#time.textContent = this.#dateFormat.format(\n PDFDateString.toDateObject(modificationDate || creationDate)\n );\n this.#setPosition(\n ...editor.commentPopupPosition,\n /* correctPosition = */ editor.hasDefaultPopupPosition()\n );\n editor.elementBeforePopup.after(container);\n container.addEventListener(\n \"focus\",\n ({ relatedTarget }) => {\n this.#previousFocusedElement = relatedTarget;\n },\n { once: true }\n );\n if (isSelected) {\n setTimeout(() => container.focus(), 0);\n }\n }\n\n #setPosition(x, y, correctPosition) {\n if (!correctPosition) {\n this.#editor.commentPopupPosition = [x, y];\n } else {\n const parentRect = this.#editor.parentBoundingClientRect;\n const widthRatio = this._popupWidth / parentRect.width;\n if (\n (this.#isLTR && x + widthRatio > 1) ||\n (!this.#isLTR && x - widthRatio >= 0)\n ) {\n const buttonWidth = this.#editor.commentButtonWidth;\n x -= widthRatio - buttonWidth;\n }\n const margin = 0.01;\n if (this.#isLTR) {\n x = Math.max(x, -parentRect.x / parentRect.width + margin);\n } else {\n x = Math.min(\n x,\n (window.innerWidth - parentRect.x) / parentRect.width -\n widthRatio -\n margin\n );\n }\n }\n this.#posX = x;\n this.#posY = y;\n const { style } = this.#container;\n style.left = `${100 * x}%`;\n style.top = `${100 * y}%`;\n }\n\n destroy() {\n this._hide();\n this.#container?.remove();\n this.#container = this.#text = this.#time = null;\n this.#prevDragX = this.#prevDragY = Infinity;\n this.#posX = this.#posY = 0;\n this.#previousFocusedElement = null;\n }\n}\n\nexport { CommentManager };\n","/* Copyright 2013 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { isPdfFile } from \"pdfjs-lib\";\n\nclass BaseDownloadManager {\n #openBlobUrls = new WeakMap();\n\n constructor() {\n if (\n (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\")) &&\n this.constructor === BaseDownloadManager\n ) {\n throw new Error(\"Cannot initialize BaseDownloadManager.\");\n }\n }\n\n _triggerDownload(blobUrl, originalUrl, filename, isAttachment = false) {\n throw new Error(\"Not implemented: _triggerDownload\");\n }\n\n _getOpenDataUrl(blobUrl, filename, dest = null) {\n throw new Error(\"Not implemented: _getOpenDataUrl\");\n }\n\n /**\n * @param {Uint8Array} data\n * @param {string} filename\n * @param {string} [contentType]\n */\n downloadData(data, filename, contentType) {\n const blobUrl = URL.createObjectURL(\n new Blob([data], { type: contentType })\n );\n\n this._triggerDownload(\n blobUrl,\n /* originalUrl = */ blobUrl,\n filename,\n /* isAttachment = */ true\n );\n }\n\n /**\n * @param {Uint8Array} data\n * @param {string} filename\n * @param {string | null} [dest]\n * @returns {boolean} Indicating if the data was opened.\n */\n openOrDownloadData(data, filename, dest = null) {\n const isPdfData = isPdfFile(filename);\n const contentType = isPdfData ? \"application/pdf\" : \"\";\n\n if (isPdfData) {\n const blobUrl = this.#openBlobUrls.getOrInsertComputed(data, () =>\n URL.createObjectURL(new Blob([data], { type: contentType }))\n );\n try {\n const viewerUrl = this._getOpenDataUrl(blobUrl, filename, dest);\n\n window.open(viewerUrl);\n return true;\n } catch (ex) {\n console.error(\"openOrDownloadData:\", ex);\n // Release the `blobUrl`, since opening it failed, and fallback to\n // downloading the PDF file.\n URL.revokeObjectURL(blobUrl);\n this.#openBlobUrls.delete(data);\n }\n }\n\n this.downloadData(data, filename, contentType);\n return false;\n }\n\n /**\n * @param {Uint8Array} data\n * @param {string} url\n * @param {string} filename\n */\n download(data, url, filename) {\n const blobUrl = data\n ? URL.createObjectURL(new Blob([data], { type: \"application/pdf\" }))\n : null;\n\n this._triggerDownload(blobUrl, /* originalUrl = */ url, filename);\n }\n}\n\nexport { BaseDownloadManager };\n","/* Copyright 2013 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BaseDownloadManager } from \"./base_download_manager.js\";\nimport { createValidAbsoluteUrl } from \"pdfjs-lib\";\n\nif (typeof PDFJSDev !== \"undefined\" && !PDFJSDev.test(\"CHROME || GENERIC\")) {\n throw new Error(\n 'Module \"pdfjs-web/download_manager\" shall not be used ' +\n \"outside CHROME and GENERIC builds.\"\n );\n}\n\nclass DownloadManager extends BaseDownloadManager {\n _triggerDownload(blobUrl, originalUrl, filename, isAttachment = false) {\n if (!blobUrl && !isAttachment) {\n // Fallback to downloading non-attachments by their URL.\n if (!createValidAbsoluteUrl(originalUrl, \"http://example.com\")) {\n throw new Error(`_triggerDownload - not a valid URL: ${originalUrl}`);\n }\n blobUrl = originalUrl + \"#pdfjs.action=download\";\n }\n\n const a = document.createElement(\"a\");\n a.href = blobUrl;\n a.target = \"_parent\";\n // Use a.download if available. This increases the likelihood that\n // the file is downloaded instead of opened by another PDF plugin.\n if (\"download\" in a) {\n a.download = filename;\n }\n // must be in the document for recent Firefox versions,\n // otherwise .click() is ignored.\n (document.body || document.documentElement).append(a);\n a.click();\n a.remove();\n }\n\n _getOpenDataUrl(blobUrl, filename, dest = null) {\n if (typeof PDFJSDev !== \"undefined\" && PDFJSDev.test(\"COMPONENTS\")) {\n throw new Error(\"Opening data is not supported in `COMPONENTS` builds.\");\n }\n // The current URL is the viewer, let's use it and append the file.\n let url = \"?file=\" + encodeURIComponent(blobUrl + \"#\" + filename);\n if (dest) {\n url += `#${escape(dest)}`;\n }\n return url;\n }\n}\n\nexport { DownloadManager };\n","/* Copyright 2024 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { noContextMenu } from \"pdfjs-lib\";\n\nclass EditorUndoBar {\n #closeButton = null;\n\n #container;\n\n #eventBus = null;\n\n #focusTimeout = null;\n\n #initController = null;\n\n isOpen = false;\n\n #message;\n\n #showController = null;\n\n #undoButton;\n\n static #l10nMessages = Object.freeze({\n highlight: \"pdfjs-editor-undo-bar-message-highlight\",\n freetext: \"pdfjs-editor-undo-bar-message-freetext\",\n stamp: \"pdfjs-editor-undo-bar-message-stamp\",\n ink: \"pdfjs-editor-undo-bar-message-ink\",\n signature: \"pdfjs-editor-undo-bar-message-signature\",\n comment: \"pdfjs-editor-undo-bar-message-comment\",\n _multiple: \"pdfjs-editor-undo-bar-message-multiple\",\n });\n\n constructor({ container, message, undoButton, closeButton }, eventBus) {\n this.#container = container;\n this.#message = message;\n this.#undoButton = undoButton;\n this.#closeButton = closeButton;\n this.#eventBus = eventBus;\n }\n\n destroy() {\n this.#initController?.abort();\n this.#initController = null;\n\n this.hide();\n }\n\n show(undoAction, messageData) {\n if (!this.#initController) {\n this.#initController = new AbortController();\n const opts = { signal: this.#initController.signal };\n const boundHide = this.hide.bind(this);\n\n this.#container.addEventListener(\"contextmenu\", noContextMenu, opts);\n this.#closeButton.addEventListener(\"click\", boundHide, opts);\n this.#eventBus._on(\"beforeprint\", boundHide, opts);\n this.#eventBus._on(\"download\", boundHide, opts);\n }\n\n this.hide();\n\n if (typeof messageData === \"string\") {\n this.#message.setAttribute(\n \"data-l10n-id\",\n EditorUndoBar.#l10nMessages[messageData]\n );\n } else {\n this.#message.setAttribute(\n \"data-l10n-id\",\n EditorUndoBar.#l10nMessages._multiple\n );\n this.#message.setAttribute(\n \"data-l10n-args\",\n JSON.stringify({ count: messageData })\n );\n }\n this.isOpen = true;\n this.#container.hidden = false;\n\n this.#showController = new AbortController();\n\n this.#undoButton.addEventListener(\n \"click\",\n () => {\n undoAction();\n this.hide();\n },\n { signal: this.#showController.signal }\n );\n\n // Without the setTimeout, VoiceOver will read out the document title\n // instead of the popup label.\n this.#focusTimeout = setTimeout(() => {\n this.#container.focus();\n this.#focusTimeout = null;\n }, 100);\n }\n\n hide() {\n if (!this.isOpen) {\n return;\n }\n this.isOpen = false;\n this.#container.hidden = true;\n\n this.#showController?.abort();\n this.#showController = null;\n\n if (this.#focusTimeout) {\n clearTimeout(this.#focusTimeout);\n this.#focusTimeout = null;\n }\n }\n}\n\nexport { EditorUndoBar };\n","/* Copyright 2014 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass OverlayManager {\n #overlays = new WeakMap();\n\n #active = null;\n\n get active() {\n return this.#active;\n }\n\n /**\n * @param {HTMLDialogElement} dialog - The overlay's DOM element.\n * @param {boolean} [canForceClose] - Indicates if opening the overlay closes\n * an active overlay. The default is `false`.\n * @returns {Promise} A promise that is resolved when the overlay has been\n * registered.\n */\n async register(dialog, canForceClose = false) {\n if (typeof dialog !== \"object\") {\n throw new Error(\"Not enough parameters.\");\n } else if (this.#overlays.has(dialog)) {\n throw new Error(\"The overlay is already registered.\");\n }\n this.#overlays.set(dialog, { canForceClose });\n\n dialog.addEventListener(\"cancel\", ({ target }) => {\n if (this.#active === target) {\n this.#active = null;\n }\n });\n }\n\n /**\n * @param {HTMLDialogElement} dialog - The overlay's DOM element.\n * @returns {Promise} A promise that is resolved when the overlay has been\n * opened.\n */\n async open(dialog) {\n if (!this.#overlays.has(dialog)) {\n throw new Error(\"The overlay does not exist.\");\n } else if (this.#active) {\n if (this.#active === dialog) {\n throw new Error(\"The overlay is already active.\");\n } else if (this.#overlays.get(dialog).canForceClose) {\n await this.close();\n } else {\n throw new Error(\"Another overlay is currently active.\");\n }\n }\n this.#active = dialog;\n dialog.showModal();\n }\n\n /**\n * @param {HTMLDialogElement} dialog - The overlay's DOM element.\n * @returns {Promise} A promise that is resolved when the overlay has been\n * closed.\n */\n async close(dialog = this.#active) {\n if (!this.#overlays.has(dialog)) {\n throw new Error(\"The overlay does not exist.\");\n } else if (!this.#active) {\n throw new Error(\"The overlay is currently not active.\");\n } else if (this.#active !== dialog) {\n throw new Error(\"Another overlay is currently active.\");\n }\n dialog.close();\n this.#active = null;\n }\n\n /**\n * @param {HTMLDialogElement} dialog - The overlay's DOM element.\n * @returns {Promise} A promise that is resolved when the overlay has been\n * closed.\n */\n async closeIfActive(dialog) {\n if (this.#active === dialog) {\n await this.close(dialog);\n }\n }\n}\n\nexport { OverlayManager };\n","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** @typedef {import(\"./overlay_manager.js\").OverlayManager} OverlayManager */\n\nimport { PasswordResponses } from \"pdfjs-lib\";\n\n/**\n * @typedef {Object} PasswordPromptOptions\n * @property {HTMLDialogElement} dialog - The overlay's DOM element.\n * @property {HTMLParagraphElement} label - Label containing instructions for\n * entering the password.\n * @property {HTMLInputElement} input - Input field for entering the password.\n * @property {HTMLButtonElement} submitButton - Button for submitting the\n * password.\n * @property {HTMLButtonElement} cancelButton - Button for cancelling password\n * entry.\n */\n\nclass PasswordPrompt {\n #activeCapability = null;\n\n #updateCallback = null;\n\n #reason = null;\n\n /**\n * @param {PasswordPromptOptions} options\n * @param {OverlayManager} overlayManager - Manager for the viewer overlays.\n * @param {boolean} [isViewerEmbedded] - If the viewer is embedded, in e.g.\n * an