From 74dcaf5142bbfadd79296e75b59624e1a8485153 Mon Sep 17 00:00:00 2001 From: maziggy Date: Sun, 17 May 2026 13:48:05 +0200 Subject: [PATCH] refactor(settings): Spool Catalog now identical in internal and Spoolman modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the Spoolman-mode hijack that replaced the local spool tare catalog with an inline filament editor — two unrelated concepts that should never have shared a card. Spool Catalog now renders the same way in both modes; Spoolman users edit filament name and spool_weight in Spoolman's own UI. Also eliminates the GET /spoolman/inventory/filaments 400 probe that fired on the Filament settings page whenever Spoolman was disabled. - frontend/src/components/SpoolCatalogSettings.tsx rewritten (752 -> 444 lines) - frontend/src/components/SpoolWeightUpdateModal.tsx deleted (orphan) - SpoolCatalogSettings test file rewritten to match the simplified component - PATCH /spoolman/inventory/filaments/{id} backend route left in place --- CHANGELOG.md | 3 + .../components/SpoolCatalogSettings.test.tsx | 429 +----------- .../SpoolWeightUpdateModal.test.tsx | 97 --- .../src/components/SpoolCatalogSettings.tsx | 622 ++++++------------ .../src/components/SpoolWeightUpdateModal.tsx | 102 --- static/assets/index-Baw5c3Hn.css | 1 - static/assets/index-CLI--QzS.css | 1 + .../{index-CfUZn1UK.js => index-CdDo4ToZ.js} | 190 +++--- static/index.html | 4 +- 9 files changed, 300 insertions(+), 1149 deletions(-) delete mode 100644 frontend/src/__tests__/components/SpoolWeightUpdateModal.test.tsx delete mode 100644 frontend/src/components/SpoolWeightUpdateModal.tsx delete mode 100644 static/assets/index-Baw5c3Hn.css create mode 100644 static/assets/index-CLI--QzS.css rename static/assets/{index-CfUZn1UK.js => index-CdDo4ToZ.js} (91%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e78a2aa5..2a678ec40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to Bambuddy will be documented in this file. ## [0.2.5b1] - Unreleased +### Changed +- **Settings → Filament: "Spool Catalog" now shows the same UI in Spoolman mode as in internal-inventory mode** — Previously, switching to Spoolman mode hijacked the Spool Catalog card and replaced it with a Spoolman filament list (Vendor — Name / Material / Weight / Spool Weight) with inline edit for name + spool_weight. Two separate concepts had been merged into one card: a Bambuddy-local **spool tare catalog** (the actual purpose of the card — name + weight definitions used to compute spool tare) vs a **filament editor** for Spoolman's `Filament` entity. The filament-editor view replaced the spool tare table entirely in Spoolman mode, with no way to see or manage the spool catalog. Now the card always renders the local Spool Catalog (Add / Edit / Delete / Export / Import / Reset / bulk-delete) regardless of inventory mode. The Spoolman-filament inline editor is removed — Spoolman users edit filament name / spool_weight in Spoolman's own UI. Side effect of the rewrite: the noisy `GET /api/v1/spoolman/inventory/filaments → 400 Bad Request` that fired on the Filament settings page even when Spoolman is disabled is gone, because the component no longer issues the probe at all. Files affected: `frontend/src/components/SpoolCatalogSettings.tsx` (rewrite, ~750 → ~445 lines), `frontend/src/components/SpoolWeightUpdateModal.tsx` (deleted — only used by the removed editor), test file rewritten to match the simplified component. No backend changes — `PATCH /spoolman/inventory/filaments/{id}` route still exists for API consumers, just no longer wired to a UI. + ### Fixed - **Upload validation rejects unprintable 3MF / raw-gcode files at the upload step instead of letting them fail at the printer (#1401, reported by @iitazz)** — Reporter sliced in OrcaSlicer, uploaded the result to Bambuddy, clicked Print, and the printer rejected with "Printing stopped because the printer was unable to parse the 3mf file" — every time, for multiple files, on both library uploads and SD-card-browsed files. Trace through the support bundle showed: (a) the stored library file ended in `.gcode` (not `.gcode.3mf`), and (b) `background_dispatch.py` constructs the FTP destination filename by appending `.3mf` when the source doesn't already end in `.gcode.3mf` / `.3mf` — so raw gcode gets shipped to the printer named `whatever.gcode.3mf` and the firmware's 3MF parser chokes on the missing zip header. The same shape also manifests as `Failed to parse plates from archive ... File is not a zip file` warnings on Bambuddy's side. Whether the user manually re-extensioned a file or their slicer saved as `.gcode` instead of `.gcode.3mf`, the right place to catch this is the upload, not the printer 30 seconds later. **New `validate_print_file_upload()` helper** in `backend/app/api/routes/library.py` runs two checks: (1) reject any filename ending in `.gcode` (but not `.gcode.3mf`) with a clear message — "Raw .gcode files can't be printed on Bambu printers in network mode — they need a .gcode.3mf zip container (gcode plus metadata). Re-export from your slicer and make sure the file ends in '.gcode.3mf', not just '.gcode'. If your OS hides extensions, double-check the file with the extension visible." (2) For any filename ending in `.3mf` (incl. the compound `.gcode.3mf`), verify the file body starts with `PK\x03\x04` (ZIP magic bytes); reject otherwise with a message pointing at the slicer's "Export Plate Sliced File" action. Suffix-based check rather than `os.path.splitext` because compound extensions like `.gcode.3mf` show up as just `.3mf` after splitext — both must trigger the same validation. **Applied to every relevant upload route**: `POST /library/files` (covers File Manager upload AND the printer-card drag-drop, which routes through the same endpoint), `POST /archives/upload` (single archive), `POST /archives/upload-bulk` (rejects bad files per-row instead of aborting the batch — one bad file in a 10-file drag-drop doesn't lose the other nine), `POST /archives/{archive_id}/source` (per-archive source 3MF), `POST /archives/upload-source` (slicer-post-processing match-by-name). Validation runs AFTER `_resolve_upload_destination` so folder-permission rejections (403 readonly, 400 missing-path, 409 collision) still take precedence — preserves existing error ordering. STL / image / other non-print uploads bypass the validator entirely; Bambuddy is also a library, not just a print dispatcher. **Frontend visibility fix** in `FileUploadModal.tsx` (same component used by File Manager + Printers page + Archives): the modal auto-closed after `setIsUploading(false)` regardless of per-file results, so a 400 rejection from the new validator was technically captured but never shown — the modal vanished too quickly. Now (a) errors render inline as red text under the file row instead of as a hover-only `title` tooltip, and (b) the modal stays open if any file ended with status='error', so the user can read the backend's actual remediation message before clicking Close. The bulk archive `UploadModal.tsx` was already showing inline errors and not auto-closing — that one didn't need the fix. **Tests**: 7 new integration tests in `TestPrintFileUploadValidation` cover: raw `.gcode` rejection at the library route (asserts the error message names the remedy), non-zip `.3mf` rejection, non-zip `.gcode.3mf` rejection (compound-extension code path), happy-path valid `.gcode.3mf` accepted, STL / non-print extensions still bypass, `POST /archives/upload` non-zip rejection, `POST /archives/upload-bulk` per-file error collection with mixed good/bad files in one request. Plus one fixture update in `test_external_folders_api.py` — `test_upload_persists_correct_db_shape` was uploading `model.3mf` with placeholder bytes `b"x"` to exercise the DB-shape path; updated to use a minimal real zip so the new validator doesn't block the unrelated test. 4968 backend tests green, 41 FileUploadModal frontend tests green, ruff + frontend build clean. diff --git a/frontend/src/__tests__/components/SpoolCatalogSettings.test.tsx b/frontend/src/__tests__/components/SpoolCatalogSettings.test.tsx index 6fba3b960..8e70fc150 100644 --- a/frontend/src/__tests__/components/SpoolCatalogSettings.test.tsx +++ b/frontend/src/__tests__/components/SpoolCatalogSettings.test.tsx @@ -1,6 +1,5 @@ -import React from 'react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { screen, waitFor, fireEvent } from '@testing-library/react'; +import { screen, waitFor } from '@testing-library/react'; import { render } from '../utils'; import { SpoolCatalogSettings } from '../../components/SpoolCatalogSettings'; @@ -20,17 +19,6 @@ vi.mock('../../api/client', () => ({ api: { getSettings: vi.fn().mockResolvedValue({}), getSpoolCatalog: vi.fn().mockResolvedValue([]), - getSpoolmanInventoryFilaments: vi.fn().mockResolvedValue([]), - patchSpoolmanFilament: vi.fn().mockResolvedValue({ - id: 1, - name: 'PLA Basic', - material: 'PLA', - color_hex: 'FF0000', - color_name: 'Red', - weight: 1000, - spool_weight: 196, - vendor: { id: 1, name: 'Bambu Lab' }, - }), }, ApiError: class ApiError extends Error { status: number; @@ -41,87 +29,15 @@ vi.mock('../../api/client', () => ({ }, })); -import { api, ApiError } from '../../api/client'; +import { api } from '../../api/client'; -const sampleFilament = { - id: 1, - name: 'PLA Basic', - material: 'PLA', - color_hex: 'FF0000', - color_name: 'Red', - weight: 1000, - spool_weight: 196, - vendor: { id: 1, name: 'Bambu Lab' }, -}; - -describe('SpoolCatalogSettings — mode switching', () => { +describe('SpoolCatalogSettings — local catalog UI', () => { beforeEach(() => { vi.clearAllMocks(); vi.mocked(api.getSpoolCatalog).mockResolvedValue([]); }); - it('hides Spoolman table and shows local CRUD buttons when Spoolman is disabled (400)', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockRejectedValue( - new ApiError('disabled', 400) - ); - - render(); - - await waitFor(() => { - // Local mode: Add button visible - expect(screen.getByText('common.add')).toBeTruthy(); - }); - - // Spoolman table columns must NOT appear - expect(screen.queryByText('settings.catalog.material')).toBeNull(); - expect(screen.queryByText('settings.catalog.spoolWeight')).toBeNull(); - // Spoolman catalog title must NOT appear - expect(screen.queryByText('settings.spoolmanFilamentCatalogTitle')).toBeNull(); - }); - - it('shows Spoolman error row when Spoolman is unreachable (503)', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockRejectedValue( - new ApiError('unreachable', 503) - ); - - render(); - - await waitFor(() => { - expect(screen.getByText('inventory.spoolmanCatalogLoadFailed')).toBeTruthy(); - }); - - // Local CRUD buttons must NOT appear in Spoolman mode - expect(screen.queryByText('common.add')).toBeNull(); - }); - - it('shows empty state when Spoolman returns an empty list', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([]); - - render(); - - await waitFor(() => { - expect(screen.getByText('inventory.noSpoolmanFilaments')).toBeTruthy(); - }); - - // Local CRUD buttons must NOT appear - expect(screen.queryByText('common.add')).toBeNull(); - }); - - it('renders Spoolman filament rows with vendor and name combined', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByText(/Bambu Lab — PLA Basic/)).toBeTruthy(); - }); - }); - - it('(local mode) shows Export, Import, Reset, Add buttons when Spoolman disabled', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockRejectedValue( - new ApiError('disabled', 400) - ); - + it('shows local CRUD buttons regardless of Spoolman state', async () => { render(); await waitFor(() => { @@ -133,341 +49,20 @@ describe('SpoolCatalogSettings — mode switching', () => { expect(screen.getByText('common.reset')).toBeTruthy(); }); - it('(spoolman mode) hides Export, Import, Reset, Add buttons when Spoolman is enabled', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - + it('renders the local Spool Catalog header and column layout', async () => { render(); await waitFor(() => { - expect(screen.getByText(/Bambu Lab — PLA Basic/)).toBeTruthy(); + expect(screen.getByText('settings.catalog.spoolCatalog')).toBeTruthy(); }); - expect(screen.queryByText('common.add')).toBeNull(); - expect(screen.queryByText('common.export')).toBeNull(); - expect(screen.queryByText('common.import')).toBeNull(); - expect(screen.queryByText('common.reset')).toBeNull(); - }); - - it('(spoolman mode) renders correct column headers — Name, Material, Weight, Spool Weight', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByText('common.name')).toBeTruthy(); - }); - - expect(screen.getByText('settings.catalog.material')).toBeTruthy(); + expect(screen.getByText('common.name')).toBeTruthy(); expect(screen.getByText('settings.catalog.weight')).toBeTruthy(); - expect(screen.getByText('settings.catalog.spoolWeight')).toBeTruthy(); - }); + expect(screen.getByText('settings.catalog.type')).toBeTruthy(); - it('(spoolman mode) renders all data fields for a filament row', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByText(/Bambu Lab — PLA Basic/)).toBeTruthy(); - }); - - // Material column - expect(screen.getByText('PLA')).toBeTruthy(); - // Filament weight - expect(screen.getByText('1000g')).toBeTruthy(); - // Spool (empty) weight - expect(screen.getByText('196g')).toBeTruthy(); - }); - - it('(spoolman mode) renders color swatch with correct background color', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([ - { ...sampleFilament, color_hex: 'FF5500' }, - ]); - - render(); - - await waitFor(() => { - expect(screen.getByText(/Bambu Lab — PLA Basic/)).toBeTruthy(); - }); - - const swatch = screen.getByLabelText('inventory.spoolmanFilamentColorSwatch'); - const bg = (swatch as HTMLElement).style.backgroundColor; - // Accepts both hex-like and rgb() representations - expect(bg).toBeTruthy(); - expect(bg).not.toBe(''); - }); - - it('(spoolman mode) renders fallback color when color_hex is null', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([ - { ...sampleFilament, color_hex: null }, - ]); - - render(); - - await waitFor(() => { - expect(screen.getByText(/Bambu Lab — PLA Basic/)).toBeTruthy(); - }); - - const swatch = screen.getByLabelText('inventory.spoolmanFilamentColorSwatch'); - expect((swatch as HTMLElement).style.backgroundColor).toContain('128'); - }); - - it('(spoolman mode) renders dash for null material, weight, and spool_weight', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([ - { ...sampleFilament, material: null, weight: null, spool_weight: null }, - ]); - - render(); - - await waitFor(() => { - expect(screen.getByText(/Bambu Lab — PLA Basic/)).toBeTruthy(); - }); - - // All three nullable fields must show '—', not 'nullg' or empty string - const dashes = screen.getAllByText('—'); - expect(dashes.length).toBeGreaterThanOrEqual(3); - }); - - it('(spoolman mode) shows Spoolman catalog title, not local catalog title', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByText('settings.spoolmanFilamentCatalogTitle')).toBeTruthy(); - }); - - expect(screen.queryByText('settings.catalog.spoolCatalog')).toBeNull(); - }); - - it('(spoolman mode) shows pencil edit button in each filament row', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByText(/Bambu Lab — PLA Basic/)).toBeTruthy(); - }); - - const editButtons = screen.getAllByLabelText('common.edit'); - expect(editButtons.length).toBeGreaterThanOrEqual(1); - }); - - it('(spoolman mode) clicking pencil shows name and weight inputs', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByLabelText('common.edit')).toBeTruthy(); - }); - - fireEvent.click(screen.getByLabelText('common.edit')); - - await waitFor(() => { - expect(screen.getByLabelText('common.name')).toBeTruthy(); - expect(screen.getByLabelText('settings.catalog.spoolWeight')).toBeTruthy(); - }); - }); - - it('(spoolman mode) name input is pre-filled with current name', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByLabelText('common.edit')).toBeTruthy(); - }); - - fireEvent.click(screen.getByLabelText('common.edit')); - - await waitFor(() => { - const nameInput = screen.getByLabelText('common.name') as HTMLInputElement; - expect(nameInput.value).toBe('PLA Basic'); - }); - }); - - it('(spoolman mode) weight input is pre-filled with current spool_weight', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByLabelText('common.edit')).toBeTruthy(); - }); - - fireEvent.click(screen.getByLabelText('common.edit')); - - await waitFor(() => { - const weightInput = screen.getByLabelText('settings.catalog.spoolWeight') as HTMLInputElement; - expect(weightInput.value).toBe('196'); - }); - }); - - it('(spoolman mode) cancel edit restores read-only display', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByLabelText('common.edit')).toBeTruthy(); - }); - - fireEvent.click(screen.getByLabelText('common.edit')); - - await waitFor(() => { - expect(screen.getByLabelText('common.cancel')).toBeTruthy(); - }); - - fireEvent.click(screen.getByLabelText('common.cancel')); - - await waitFor(() => { - expect(screen.queryByLabelText('common.name')).toBeNull(); - expect(screen.getByLabelText('common.edit')).toBeTruthy(); - }); - }); - - it('(spoolman mode) empty name input disables save button', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByLabelText('common.edit')).toBeTruthy(); - }); - - fireEvent.click(screen.getByLabelText('common.edit')); - - await waitFor(() => { - expect(screen.getByLabelText('common.name')).toBeTruthy(); - }); - - const nameInput = screen.getByLabelText('common.name'); - fireEvent.change(nameInput, { target: { value: '' } }); - - const saveBtn = screen.getByLabelText('common.save') as HTMLButtonElement; - expect(saveBtn.disabled).toBe(true); - }); - - it('(spoolman mode) saving name-only calls patchSpoolmanFilament without modal', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByLabelText('common.edit')).toBeTruthy(); - }); - - fireEvent.click(screen.getByLabelText('common.edit')); - - await waitFor(() => { - expect(screen.getByLabelText('common.name')).toBeTruthy(); - }); - - const nameInput = screen.getByLabelText('common.name'); - fireEvent.change(nameInput, { target: { value: 'PLA Basic Renamed' } }); - - fireEvent.click(screen.getByLabelText('common.save')); - - await waitFor(() => { - expect(vi.mocked(api.patchSpoolmanFilament)).toHaveBeenCalledWith(1, { name: 'PLA Basic Renamed' }); - }); - - // Modal must NOT appear - expect(screen.queryByText('settings.catalog.updateSpoolWeight')).toBeNull(); - }); - - it('(spoolman mode) saving changed spool_weight opens SpoolWeightUpdateModal', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { - expect(screen.getByLabelText('common.edit')).toBeTruthy(); - }); - - fireEvent.click(screen.getByLabelText('common.edit')); - - await waitFor(() => { - expect(screen.getByLabelText('settings.catalog.spoolWeight')).toBeTruthy(); - }); - - const weightInput = screen.getByLabelText('settings.catalog.spoolWeight'); - fireEvent.change(weightInput, { target: { value: '100' } }); - - fireEvent.click(screen.getByLabelText('common.save')); - - await waitFor(() => { - expect(screen.getByText('settings.catalog.updateSpoolWeight')).toBeTruthy(); - }); - }); - - it('(spoolman mode) confirming option B calls patchSpoolmanFilament with keep_existing_spools=false', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { expect(screen.getByLabelText('common.edit')).toBeTruthy(); }); - fireEvent.click(screen.getByLabelText('common.edit')); - - await waitFor(() => { expect(screen.getByLabelText('settings.catalog.spoolWeight')).toBeTruthy(); }); - fireEvent.change(screen.getByLabelText('settings.catalog.spoolWeight'), { target: { value: '100' } }); - fireEvent.click(screen.getByLabelText('common.save')); - - await waitFor(() => { expect(screen.getByText('settings.catalog.updateSpoolWeight')).toBeTruthy(); }); - - // Confirm with option B selected by default - fireEvent.click(screen.getByText('common.confirm')); - - await waitFor(() => { - expect(vi.mocked(api.patchSpoolmanFilament)).toHaveBeenCalledWith( - 1, - expect.objectContaining({ spool_weight: 100, keep_existing_spools: false }), - ); - }); - }); - - it('(spoolman mode) confirming option A calls patchSpoolmanFilament with keep_existing_spools=true', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { expect(screen.getByLabelText('common.edit')).toBeTruthy(); }); - fireEvent.click(screen.getByLabelText('common.edit')); - - await waitFor(() => { expect(screen.getByLabelText('settings.catalog.spoolWeight')).toBeTruthy(); }); - fireEvent.change(screen.getByLabelText('settings.catalog.spoolWeight'), { target: { value: '100' } }); - fireEvent.click(screen.getByLabelText('common.save')); - - await waitFor(() => { expect(screen.getByText('settings.catalog.updateSpoolWeight')).toBeTruthy(); }); - - // Select option A (keep existing) - const radios = screen.getAllByRole('radio'); - fireEvent.click(radios[1]); // Option A = second radio = keepExisting=true - - fireEvent.click(screen.getByText('common.confirm')); - - await waitFor(() => { - expect(vi.mocked(api.patchSpoolmanFilament)).toHaveBeenCalledWith( - 1, - expect.objectContaining({ spool_weight: 100, keep_existing_spools: true }), - ); - }); - }); - - it('(spoolman mode) negative weight input disables save button', async () => { - vi.mocked(api.getSpoolmanInventoryFilaments).mockResolvedValue([sampleFilament]); - - render(); - - await waitFor(() => { expect(screen.getByLabelText('common.edit')).toBeTruthy(); }); - fireEvent.click(screen.getByLabelText('common.edit')); - - await waitFor(() => { expect(screen.getByLabelText('settings.catalog.spoolWeight')).toBeTruthy(); }); - - fireEvent.change(screen.getByLabelText('settings.catalog.spoolWeight'), { target: { value: '-5' } }); - - const saveBtn = screen.getByLabelText('common.save') as HTMLButtonElement; - expect(saveBtn.disabled).toBe(true); + // No Spoolman-only columns leak in + expect(screen.queryByText('settings.catalog.material')).toBeNull(); + expect(screen.queryByText('settings.catalog.spoolWeight')).toBeNull(); + expect(screen.queryByText('settings.spoolmanFilamentCatalogTitle')).toBeNull(); }); }); diff --git a/frontend/src/__tests__/components/SpoolWeightUpdateModal.test.tsx b/frontend/src/__tests__/components/SpoolWeightUpdateModal.test.tsx deleted file mode 100644 index 620abfd32..000000000 --- a/frontend/src/__tests__/components/SpoolWeightUpdateModal.test.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import React from 'react'; -import { describe, it, expect, vi } from 'vitest'; -import { screen, fireEvent } from '@testing-library/react'; -import { render } from '../utils'; -import { SpoolWeightUpdateModal } from '../../components/SpoolWeightUpdateModal'; - -vi.mock('react-i18next', () => ({ - useTranslation: () => ({ - t: (key: string) => key, - }), -})); - -const defaultProps = { - isOpen: true, - filamentName: 'PLA Basic', - oldWeight: 250, - newWeight: 196, - onConfirm: vi.fn(), - onClose: vi.fn(), -}; - -describe('SpoolWeightUpdateModal', () => { - it('renders filament name, old weight, and new weight', () => { - render(); - - expect(screen.getByText('settings.catalog.updateSpoolWeight')).toBeTruthy(); - expect(screen.getByText(/PLA Basic/)).toBeTruthy(); - expect(screen.getByText(/250g → 196g/)).toBeTruthy(); - }); - - it('renders option labels', () => { - render(); - - expect(screen.getByText('settings.catalog.applyToAllSpools')).toBeTruthy(); - expect(screen.getByText('settings.catalog.keepExistingSpoolWeight')).toBeTruthy(); - }); - - it('option B (apply to all) is selected by default', () => { - render(); - - const radios = screen.getAllByRole('radio') as HTMLInputElement[]; - // First radio = apply-to-all (Option B, keepExisting=false) - expect(radios[0].checked).toBe(true); - expect(radios[1].checked).toBe(false); - }); - - it('calls onConfirm(false) when option B is selected and Confirm clicked', () => { - const onConfirm = vi.fn(); - render(); - - fireEvent.click(screen.getByText('common.confirm')); - - expect(onConfirm).toHaveBeenCalledWith(false); - }); - - it('calls onConfirm(true) when option A is selected and Confirm clicked', () => { - const onConfirm = vi.fn(); - render(); - - const radios = screen.getAllByRole('radio'); - fireEvent.click(radios[1]); // Option A: keep existing - - fireEvent.click(screen.getByText('common.confirm')); - - expect(onConfirm).toHaveBeenCalledWith(true); - }); - - it('calls onClose on Cancel click', () => { - const onClose = vi.fn(); - render(); - - fireEvent.click(screen.getByText('common.cancel')); - - expect(onClose).toHaveBeenCalled(); - }); - - it('does not call onConfirm on Cancel click', () => { - const onConfirm = vi.fn(); - render(); - - fireEvent.click(screen.getByText('common.cancel')); - - expect(onConfirm).not.toHaveBeenCalled(); - }); - - it('renders dash when oldWeight is null', () => { - render(); - - expect(screen.getByText(/— → 196g/)).toBeTruthy(); - }); - - it('returns null when isOpen is false', () => { - render(); - - expect(screen.queryByText('settings.catalog.updateSpoolWeight')).toBeNull(); - }); -}); diff --git a/frontend/src/components/SpoolCatalogSettings.tsx b/frontend/src/components/SpoolCatalogSettings.tsx index 7a29c1c13..342442fce 100644 --- a/frontend/src/components/SpoolCatalogSettings.tsx +++ b/frontend/src/components/SpoolCatalogSettings.tsx @@ -1,34 +1,20 @@ import { useState, useEffect, useCallback, useRef } from 'react'; -import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { Database, Plus, Trash2, RotateCcw, Loader2, Pencil, Check, X, Search, Download, Upload } from 'lucide-react'; -import { api, ApiError } from '../api/client'; -import type { SpoolCatalogEntry, SpoolmanFilamentEntry } from '../api/client'; +import { api } from '../api/client'; +import type { SpoolCatalogEntry } from '../api/client'; import { useToast } from '../contexts/ToastContext'; import { Card, CardHeader, CardContent } from './Card'; import { ConfirmModal } from './ConfirmModal'; -import { SpoolWeightUpdateModal } from './SpoolWeightUpdateModal'; export function SpoolCatalogSettings() { const { t } = useTranslation(); const { showToast } = useToast(); - const queryClient = useQueryClient(); const [catalog, setCatalog] = useState([]); const [loading, setLoading] = useState(true); const [search, setSearch] = useState(''); const fileInputRef = useRef(null); - // Spoolman inline-edit state - const [editingFilamentId, setEditingFilamentId] = useState(null); - const [editingFilamentName, setEditingFilamentName] = useState(''); - const [editingFilamentWeight, setEditingFilamentWeight] = useState(''); - const [pendingWeightEdit, setPendingWeightEdit] = useState<{ - filamentId: number; - name: string; - oldWeight: number | null; - newWeight: number; - } | null>(null); - // Add/Edit form state const [showAddForm, setShowAddForm] = useState(false); const [editingId, setEditingId] = useState(null); @@ -44,86 +30,6 @@ export function SpoolCatalogSettings() { const [deleteEntry, setDeleteEntry] = useState(null); const [showResetConfirm, setShowResetConfirm] = useState(false); - // Spoolman filament query — hoisted to determine display mode - const { - data: spoolmanFilaments, - isLoading: spoolmanLoading, - error: spoolmanError, - } = useQuery({ - queryKey: ['spoolman-inventory-filaments'], - queryFn: () => api.getSpoolmanInventoryFilaments(), - retry: false, // Spoolman may be intentionally disabled (400) — don't retry - staleTime: 60_000, - }); - - // 400 = Spoolman explicitly disabled; all other states (data / 503 / …) mean Spoolman mode - const isSpoolmanDisabled = - !spoolmanLoading && - spoolmanError instanceof ApiError && - spoolmanError.status === 400; - const isSpoolmanMode = !spoolmanLoading && !isSpoolmanDisabled; - - const patchFilamentMutation = useMutation< - SpoolmanFilamentEntry, - Error, - { filamentId: number; data: { name?: string; spool_weight?: number | null; keep_existing_spools?: boolean } } - >({ - mutationFn: ({ filamentId, data }) => api.patchSpoolmanFilament(filamentId, data), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['spoolman-inventory-filaments'] }); - showToast(t('settings.catalog.filamentUpdated'), 'success'); - setEditingFilamentId(null); - setEditingFilamentName(''); - setEditingFilamentWeight(''); - setPendingWeightEdit(null); - }, - onError: (error: Error) => { - if (error instanceof ApiError && error.status === 503) { - showToast(t('inventory.spoolmanUnreachable'), 'error'); - } else if (error instanceof ApiError && error.status === 422) { - showToast(t('settings.catalog.filamentUpdateInvalid'), 'error'); - } else { - showToast(t('settings.catalog.filamentUpdateFailed'), 'error'); - } - }, - }); - - const handleFilamentSave = (f: SpoolmanFilamentEntry) => { - const nameChanged = editingFilamentName.trim() !== f.name; - const weightChanged = editingFilamentWeight !== '' && editingFilamentWeight !== String(f.spool_weight ?? ''); - const parsedWeight = editingFilamentWeight !== '' ? parseFloat(editingFilamentWeight) : null; - - if (weightChanged && parsedWeight !== null && !isNaN(parsedWeight) && parsedWeight > 0) { - setPendingWeightEdit({ - filamentId: f.id, - name: nameChanged ? editingFilamentName.trim() : f.name, - oldWeight: f.spool_weight, - newWeight: parsedWeight, - }); - } else { - const data: { name?: string } = {}; - if (nameChanged && editingFilamentName.trim()) data.name = editingFilamentName.trim(); - if (Object.keys(data).length > 0) { - patchFilamentMutation.mutate({ filamentId: f.id, data }); - } else { - setEditingFilamentId(null); - } - } - }; - - const handleWeightModalConfirm = (keepExisting: boolean) => { - if (!pendingWeightEdit) return; - const { filamentId, name, newWeight } = pendingWeightEdit; - const currentFilament = spoolmanFilaments?.find(f => f.id === filamentId); - const nameChanged = currentFilament && name !== currentFilament.name; - const data: { name?: string; spool_weight: number; keep_existing_spools: boolean } = { - spool_weight: newWeight, - keep_existing_spools: keepExisting, - }; - if (nameChanged) data.name = name; - patchFilamentMutation.mutate({ filamentId, data }); - }; - const loadCatalog = useCallback(async () => { try { const entries = await api.getSpoolCatalog(); @@ -144,11 +50,6 @@ export function SpoolCatalogSettings() { entry.name.toLowerCase().includes(search.toLowerCase()) ); - const filteredSpoolmanFilaments = (spoolmanFilaments ?? []).filter(f => - f.name.toLowerCase().includes(search.toLowerCase()) || - (f.vendor?.name ?? '').toLowerCase().includes(search.toLowerCase()) - ); - const handleAdd = async () => { if (!formName.trim() || !formWeight) { showToast(t('settings.catalog.nameWeightRequired'), 'error'); @@ -313,55 +214,47 @@ export function SpoolCatalogSettings() {

- {isSpoolmanMode - ? t('settings.spoolmanFilamentCatalogTitle') - : t('settings.catalog.spoolCatalog')} + {t('settings.catalog.spoolCatalog')}

- - ({spoolmanLoading ? '…' : isSpoolmanMode ? (spoolmanFilaments?.length ?? 0) : catalog.length}) - + ({catalog.length})
- {/* CRUD buttons — local mode only */} - {!isSpoolmanMode && !spoolmanLoading && ( -
- - - - - -
- )} +
+ + + + + +
- {/* Bulk-delete bar — local mode only */} - {!isSpoolmanMode && selectedIds.size > 0 && ( + {selectedIds.size > 0 && (
{t('settings.catalog.selectedCount', { count: selectedIds.size })} @@ -384,14 +277,10 @@ export function SpoolCatalogSettings() { - {/* Description */}

- {isSpoolmanMode - ? t('settings.spoolmanFilamentCatalogDesc') - : t('settings.catalog.spoolCatalogDescription')} + {t('settings.catalog.spoolCatalogDescription')}

- {/* Search — always shown */}
- {/* Mode-determination loading spinner */} - {spoolmanLoading && ( + {showAddForm && ( +
+

{t('settings.catalog.addNewEntry')}

+
+
+ setFormName(e.target.value)} + /> +
+ setFormWeight(e.target.value)} + /> + g + + +
+
+ )} + + {loading ? (
{t('common.loading')}
- )} - - {/* ── LOCAL MODE ── */} - {!spoolmanLoading && !isSpoolmanMode && ( - <> - {/* Add form */} - {showAddForm && ( -
-

{t('settings.catalog.addNewEntry')}

-
-
- setFormName(e.target.value)} - /> -
- setFormWeight(e.target.value)} - /> - g - - -
-
- )} - - {/* Local catalog table */} - {loading ? ( -
- - {t('common.loading')} -
- ) : ( -
- - - - - - - - - - - - {filteredCatalog.length === 0 ? ( - - - - ) : ( - filteredCatalog.map(entry => ( - - {editingId === entry.id ? ( - <> - - - - - - - ) : ( - <> - - - - - - - )} - - )) - )} - -
- 0 && selectedIds.size === filteredCatalog.length} - onChange={toggleSelectAll} - className="w-4 h-4 accent-bambu-green cursor-pointer" - /> - {t('common.name')}{t('settings.catalog.weight')}{t('settings.catalog.type')}
- {search ? t('settings.catalog.noMatch') : t('settings.catalog.empty')} -
- toggleSelect(entry.id)} - className="w-4 h-4 accent-bambu-green cursor-pointer" - /> - - setFormName(e.target.value)} - /> - - setFormWeight(e.target.value)} - /> - - - - -
- - -
-
- toggleSelect(entry.id)} - className="w-4 h-4 accent-bambu-green cursor-pointer" - /> - {entry.name}{entry.weight}g - {entry.is_default ? ( - - {t('settings.catalog.default')} - - ) : ( - - {t('settings.catalog.custom')} - - )} - -
- - -
-
-
- )} - - )} - - {/* ── SPOOLMAN MODE ── */} - {!spoolmanLoading && isSpoolmanMode && ( + ) : (
- {spoolmanError ? ( -

- {t('inventory.spoolmanCatalogLoadFailed')} -

- ) : filteredSpoolmanFilaments.length === 0 ? ( -

- {t('inventory.noSpoolmanFilaments')} -

- ) : ( - - +
+ + + + + + + + + + + {filteredCatalog.length === 0 ? ( - - - - - - + - - - {filteredSpoolmanFilaments.map(f => { - const isEditing = editingFilamentId === f.id; - const isSaving = patchFilamentMutation.isPending && editingFilamentId === f.id; - return ( - - - + {editingId === entry.id ? ( + <> + + - - - + - + + - - ); - })} - -
+ 0 && selectedIds.size === filteredCatalog.length} + onChange={toggleSelectAll} + className="w-4 h-4 accent-bambu-green cursor-pointer" + /> + {t('common.name')}{t('settings.catalog.weight')}{t('settings.catalog.type')}
{t('common.name')}{t('settings.catalog.material')}{t('settings.catalog.weight')}{t('settings.catalog.spoolWeight')} + {search ? t('settings.catalog.noMatch') : t('settings.catalog.empty')} +
- - - {isEditing ? ( + ) : ( + filteredCatalog.map(entry => ( +
+ toggleSelect(entry.id)} + className="w-4 h-4 accent-bambu-green cursor-pointer" + /> + setEditingFilamentName(e.target.value)} - className="w-full bg-bambu-dark-tertiary text-white rounded px-2 py-0.5 text-sm border border-bambu-dark-secondary focus:outline-none focus:border-bambu-green" - aria-label={t('common.name')} + className="w-full px-2 py-1 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded text-white focus:border-bambu-green focus:outline-none" + value={formName} + onChange={(e) => setFormName(e.target.value)} /> - ) : ( - - {f.vendor?.name ? `${f.vendor.name} — ` : ''}{f.name} - - )} - {f.material ?? '—'} - {f.weight ? `${f.weight}g` : '—'} - - {isEditing ? ( + setEditingFilamentWeight(e.target.value)} - min="0" - step="1" - className="w-20 bg-bambu-dark-tertiary text-white rounded px-2 py-0.5 text-sm border border-bambu-dark-secondary focus:outline-none focus:border-bambu-green text-right" - aria-label={t('settings.catalog.spoolWeight')} + className="w-full px-2 py-1 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded text-white text-right focus:border-bambu-green focus:outline-none" + value={formWeight} + onChange={(e) => setFormWeight(e.target.value)} /> - ) : ( - f.spool_weight != null ? `${f.spool_weight}g` : '—' - )} - - {isEditing ? ( -
+
+ - + +
-
- ) : ( - - )} -
- )} + + + ) : ( + <> + + toggleSelect(entry.id)} + className="w-4 h-4 accent-bambu-green cursor-pointer" + /> + + {entry.name} + {entry.weight}g + + {entry.is_default ? ( + + {t('settings.catalog.default')} + + ) : ( + + {t('settings.catalog.custom')} + + )} + + +
+ + +
+ + + )} + + )) + )} + +
)}
- {/* Confirmation modals — local mode only */} - {!isSpoolmanMode && deleteEntry && ( + {deleteEntry && ( )} - {!isSpoolmanMode && showBulkDeleteConfirm && ( + {showBulkDeleteConfirm && ( )} - {!isSpoolmanMode && showResetConfirm && ( + {showResetConfirm && ( setShowResetConfirm(false)} /> )} - - setPendingWeightEdit(null)} - /> ); } diff --git a/frontend/src/components/SpoolWeightUpdateModal.tsx b/frontend/src/components/SpoolWeightUpdateModal.tsx deleted file mode 100644 index f21bb08c9..000000000 --- a/frontend/src/components/SpoolWeightUpdateModal.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { Card, CardContent } from './Card'; -import { Button } from './Button'; - -interface SpoolWeightUpdateModalProps { - isOpen: boolean; - filamentName: string; - oldWeight: number | null; - newWeight: number; - onConfirm: (keepExisting: boolean) => void; - onClose: () => void; -} - -export function SpoolWeightUpdateModal({ - isOpen, - filamentName, - oldWeight, - newWeight, - onConfirm, - onClose, -}: SpoolWeightUpdateModalProps) { - const { t } = useTranslation(); - const [keepExisting, setKeepExisting] = useState(false); - - useEffect(() => { - if (isOpen) setKeepExisting(false); - }, [isOpen]); - - if (!isOpen) return null; - - const oldWeightLabel = oldWeight !== null ? `${oldWeight}g` : '—'; - const newWeightLabel = `${newWeight}g`; - - return ( -
- e.stopPropagation()}> - -

- {t('settings.catalog.updateSpoolWeight')} -

-

- {filamentName}: {oldWeightLabel} → {newWeightLabel} -

- -
- - - -
- -
- - -
-
-
-
- ); -} diff --git a/static/assets/index-Baw5c3Hn.css b/static/assets/index-Baw5c3Hn.css deleted file mode 100644 index b48a0bfe4..000000000 --- a/static/assets/index-Baw5c3Hn.css +++ /dev/null @@ -1 +0,0 @@ -@import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";@layer properties,theme,base,components,utilities;@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-red-950:oklch(25.8% .092 26.042);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-300:oklch(83.7% .128 66.29);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-300:oklch(90.5% .182 98.111);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-lime-400:oklch(84.1% .238 128.85);--color-lime-500:oklch(76.8% .233 130.85);--color-green-100:oklch(96.2% .044 156.743);--color-green-200:oklch(92.5% .084 155.995);--color-green-300:oklch(87.1% .15 154.449);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-green-800:oklch(44.8% .119 151.328);--color-green-900:oklch(39.3% .095 152.535);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-teal-400:oklch(77.7% .152 181.912);--color-teal-500:oklch(70.4% .14 182.503);--color-cyan-300:oklch(86.5% .127 207.078);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-cyan-600:oklch(60.9% .126 221.723);--color-sky-400:oklch(74.6% .16 232.661);--color-sky-500:oklch(68.5% .169 237.323);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-indigo-300:oklch(78.5% .115 274.713);--color-indigo-400:oklch(67.3% .182 276.935);--color-indigo-500:oklch(58.5% .233 277.117);--color-violet-500:oklch(60.6% .25 292.717);--color-purple-300:oklch(82.7% .119 306.383);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-fuchsia-500:oklch(66.7% .295 322.15);--color-rose-300:oklch(81% .117 11.638);--color-rose-400:oklch(71.2% .194 13.428);--color-rose-500:oklch(64.5% .246 16.439);--color-rose-600:oklch(58.6% .253 17.585);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-500:oklch(55.4% .046 257.417);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-200:oklch(92% .004 286.32);--color-zinc-300:oklch(87.1% .006 286.286);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-500:oklch(55.2% .016 285.938);--color-zinc-600:oklch(44.2% .017 285.786);--color-zinc-700:oklch(37% .013 285.805);--color-zinc-800:oklch(27.4% .006 286.033);--color-zinc-900:oklch(21% .006 285.885);--color-black:#000;--color-white:#fff;--spacing:.25rem;--breakpoint-2xl:96rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--drop-shadow-md:0 3px 3px #0000001f;--drop-shadow-lg:0 4px 4px #00000026;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-ping:ping 1s cubic-bezier(0,0,.2,1)infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-sm:8px;--blur-2xl:40px;--aspect-video:16/9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bambu-green:var(--accent);--color-bambu-green-light:var(--accent-light);--color-bambu-green-dark:var(--accent-dark);--color-status-ok:var(--status-ok);--color-status-error:var(--status-error);--color-status-warning:var(--status-warning);--color-bambu-dark:var(--bg-primary);--color-bambu-dark-secondary:var(--bg-secondary);--color-bambu-dark-tertiary:var(--bg-tertiary);--color-bambu-gray:var(--text-muted);--color-bambu-gray-light:var(--text-secondary);--color-bambu-gray-dark:var(--text-tertiary)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.inset-2{inset:calc(var(--spacing)*2)}.inset-x-0{inset-inline:calc(var(--spacing)*0)}.inset-y-0{inset-block:calc(var(--spacing)*0)}.-top-0\.5{top:calc(var(--spacing)*-.5)}.-top-1{top:calc(var(--spacing)*-1)}.-top-1\.5{top:calc(var(--spacing)*-1.5)}.top-0{top:calc(var(--spacing)*0)}.top-0\.5{top:calc(var(--spacing)*.5)}.top-1{top:calc(var(--spacing)*1)}.top-1\.5{top:calc(var(--spacing)*1.5)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-2\.5{top:calc(var(--spacing)*2.5)}.top-3{top:calc(var(--spacing)*3)}.top-4{top:calc(var(--spacing)*4)}.top-8{top:calc(var(--spacing)*8)}.top-\[2px\]{top:2px}.top-\[3px\]{top:3px}.top-\[52px\]{top:52px}.top-full{top:100%}.-right-0\.5{right:calc(var(--spacing)*-.5)}.-right-1{right:calc(var(--spacing)*-1)}.-right-1\.5{right:calc(var(--spacing)*-1.5)}.-right-2{right:calc(var(--spacing)*-2)}.right-0{right:calc(var(--spacing)*0)}.right-0\.5{right:calc(var(--spacing)*.5)}.right-1{right:calc(var(--spacing)*1)}.right-1\.5{right:calc(var(--spacing)*1.5)}.right-2{right:calc(var(--spacing)*2)}.right-3{right:calc(var(--spacing)*3)}.right-4{right:calc(var(--spacing)*4)}.right-6{right:calc(var(--spacing)*6)}.right-12{right:calc(var(--spacing)*12)}.right-20{right:calc(var(--spacing)*20)}.right-\[5\.5rem\]{right:5.5rem}.right-full{right:100%}.-bottom-0\.5{bottom:calc(var(--spacing)*-.5)}.-bottom-1{bottom:calc(var(--spacing)*-1)}.-bottom-2{bottom:calc(var(--spacing)*-2)}.-bottom-7{bottom:calc(var(--spacing)*-7)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-0\.5{bottom:calc(var(--spacing)*.5)}.bottom-1{bottom:calc(var(--spacing)*1)}.bottom-2{bottom:calc(var(--spacing)*2)}.bottom-3{bottom:calc(var(--spacing)*3)}.bottom-4{bottom:calc(var(--spacing)*4)}.bottom-6{bottom:calc(var(--spacing)*6)}.bottom-8{bottom:calc(var(--spacing)*8)}.bottom-20{bottom:calc(var(--spacing)*20)}.bottom-full{bottom:100%}.-left-2{left:calc(var(--spacing)*-2)}.-left-\[9999px\]{left:-9999px}.left-0{left:calc(var(--spacing)*0)}.left-0\.5{left:calc(var(--spacing)*.5)}.left-1{left:calc(var(--spacing)*1)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-2\.5{left:calc(var(--spacing)*2.5)}.left-3{left:calc(var(--spacing)*3)}.left-4{left:calc(var(--spacing)*4)}.left-10{left:calc(var(--spacing)*10)}.left-12{left:calc(var(--spacing)*12)}.left-\[2px\]{left:2px}.left-\[3px\]{left:3px}.left-full{left:100%}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-60{z-index:60}.z-\[1\]{z-index:1}.z-\[60\]{z-index:60}.z-\[100\]{z-index:100}.z-\[101\]{z-index:101}.z-\[110\]{z-index:110}.z-\[9998\]{z-index:9998}.z-\[9999\]{z-index:9999}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.col-span-3{grid-column:span 3/span 3}.col-span-4{grid-column:span 4/span 4}.col-span-full{grid-column:1/-1}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.-m-4{margin:calc(var(--spacing)*-4)}.-mx-2{margin-inline:calc(var(--spacing)*-2)}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-1\.5{margin-inline:calc(var(--spacing)*1.5)}.mx-2{margin-inline:calc(var(--spacing)*2)}.mx-4{margin-inline:calc(var(--spacing)*4)}.mx-5{margin-inline:calc(var(--spacing)*5)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-2{margin-block:calc(var(--spacing)*2)}.my-8{margin-block:calc(var(--spacing)*8)}.my-auto{margin-block:auto}.-mt-0\.5{margin-top:calc(var(--spacing)*-.5)}.-mt-2{margin-top:calc(var(--spacing)*-2)}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-14{margin-top:calc(var(--spacing)*14)}.mt-auto{margin-top:auto}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-1\.5{margin-right:calc(var(--spacing)*1.5)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-3{margin-right:calc(var(--spacing)*3)}.mr-4{margin-right:calc(var(--spacing)*4)}.mr-auto{margin-right:auto}.-mb-px{margin-bottom:-1px}.mb-0{margin-bottom:calc(var(--spacing)*0)}.mb-0\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-2\.5{margin-bottom:calc(var(--spacing)*2.5)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.-ml-1{margin-left:calc(var(--spacing)*-1)}.-ml-2{margin-left:calc(var(--spacing)*-2)}.ml-0\.5{margin-left:calc(var(--spacing)*.5)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-6{margin-left:calc(var(--spacing)*6)}.ml-7{margin-left:calc(var(--spacing)*7)}.ml-16{margin-left:calc(var(--spacing)*16)}.ml-64{margin-left:calc(var(--spacing)*64)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.table-row{display:table-row}.aspect-square{aspect-ratio:1}.aspect-video{aspect-ratio:var(--aspect-video)}.\!h-8{height:calc(var(--spacing)*8)!important}.h-0{height:calc(var(--spacing)*0)}.h-0\.5{height:calc(var(--spacing)*.5)}.h-1{height:calc(var(--spacing)*1)}.h-1\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-4\.5{height:calc(var(--spacing)*4.5)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-14{height:calc(var(--spacing)*14)}.h-16{height:calc(var(--spacing)*16)}.h-20{height:calc(var(--spacing)*20)}.h-24{height:calc(var(--spacing)*24)}.h-32{height:calc(var(--spacing)*32)}.h-48{height:calc(var(--spacing)*48)}.h-64{height:calc(var(--spacing)*64)}.h-80{height:calc(var(--spacing)*80)}.h-96{height:calc(var(--spacing)*96)}.h-\[18px\]{height:18px}.h-\[38px\]{height:38px}.h-\[40px\]{height:40px}.h-\[48px\]{height:48px}.h-\[80vh\]{height:80vh}.h-\[160px\]{height:160px}.h-\[300px\]{height:300px}.h-\[calc\(100\%-40px\)\]{height:calc(100% - 40px)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-40{max-height:calc(var(--spacing)*40)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-56{max-height:calc(var(--spacing)*56)}.max-h-60{max-height:calc(var(--spacing)*60)}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-80{max-height:calc(var(--spacing)*80)}.max-h-96{max-height:calc(var(--spacing)*96)}.max-h-\[3\.75rem\]{max-height:3.75rem}.max-h-\[28rem\]{max-height:28rem}.max-h-\[50vh\]{max-height:50vh}.max-h-\[60vh\]{max-height:60vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[300px\]{max-height:300px}.max-h-\[400px\]{max-height:400px}.max-h-\[500px\]{max-height:500px}.max-h-\[600px\]{max-height:600px}.max-h-\[calc\(90vh-80px\)\]{max-height:calc(90vh - 80px)}.max-h-\[calc\(100vh-2rem\)\]{max-height:calc(100vh - 2rem)}.max-h-\[calc\(100vh-320px\)\]{max-height:calc(100vh - 320px)}.max-h-full{max-height:100%}.\!min-h-8{min-height:calc(var(--spacing)*8)!important}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\[8rem\]{min-height:8rem}.min-h-\[36px\]{min-height:36px}.min-h-\[40px\]{min-height:40px}.min-h-\[44px\]{min-height:44px}.min-h-\[48px\]{min-height:48px}.min-h-\[80px\]{min-height:80px}.min-h-\[120px\]{min-height:120px}.min-h-\[300px\]{min-height:300px}.min-h-\[400px\]{min-height:400px}.min-h-\[calc\(100vh-64px\)\]{min-height:calc(100vh - 64px)}.min-h-screen{min-height:100vh}.w-0{width:calc(var(--spacing)*0)}.w-0\.5{width:calc(var(--spacing)*.5)}.w-1{width:calc(var(--spacing)*1)}.w-1\.5{width:calc(var(--spacing)*1.5)}.w-1\/2{width:50%}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-4\.5{width:calc(var(--spacing)*4.5)}.w-5{width:calc(var(--spacing)*5)}.w-5\/12{width:41.6667%}.w-6{width:calc(var(--spacing)*6)}.w-7{width:calc(var(--spacing)*7)}.w-7\/12{width:58.3333%}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-12{width:calc(var(--spacing)*12)}.w-14{width:calc(var(--spacing)*14)}.w-16{width:calc(var(--spacing)*16)}.w-20{width:calc(var(--spacing)*20)}.w-24{width:calc(var(--spacing)*24)}.w-28{width:calc(var(--spacing)*28)}.w-32{width:calc(var(--spacing)*32)}.w-36{width:calc(var(--spacing)*36)}.w-40{width:calc(var(--spacing)*40)}.w-44{width:calc(var(--spacing)*44)}.w-48{width:calc(var(--spacing)*48)}.w-52{width:calc(var(--spacing)*52)}.w-56{width:calc(var(--spacing)*56)}.w-64{width:calc(var(--spacing)*64)}.w-72{width:calc(var(--spacing)*72)}.w-96{width:calc(var(--spacing)*96)}.w-\[240px\]{width:240px}.w-\[340px\]{width:340px}.w-\[420px\]{width:420px}.w-\[560px\]{width:560px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-max{width:max-content}.w-px{width:1px}.w-screen{width:100vw}.max-w-0{max-width:calc(var(--spacing)*0)}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-32{max-width:calc(var(--spacing)*32)}.max-w-\[40\%\]{max-width:40%}.max-w-\[50\%\]{max-width:50%}.max-w-\[80px\]{max-width:80px}.max-w-\[90vw\]{max-width:90vw}.max-w-\[100px\]{max-width:100px}.max-w-\[120px\]{max-width:120px}.max-w-\[150px\]{max-width:150px}.max-w-\[160px\]{max-width:160px}.max-w-\[200px\]{max-width:200px}.max-w-\[220px\]{max-width:220px}.max-w-\[280px\]{max-width:280px}.max-w-\[600px\]{max-width:600px}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-screen-2xl{max-width:var(--breakpoint-2xl)}.max-w-sm{max-width:var(--container-sm)}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-28{min-width:calc(var(--spacing)*28)}.min-w-40{min-width:calc(var(--spacing)*40)}.min-w-48{min-width:calc(var(--spacing)*48)}.min-w-\[16px\]{min-width:16px}.min-w-\[18px\]{min-width:18px}.min-w-\[32px\]{min-width:32px}.min-w-\[40px\]{min-width:40px}.min-w-\[48px\]{min-width:48px}.min-w-\[50px\]{min-width:50px}.min-w-\[80px\]{min-width:80px}.min-w-\[100px\]{min-width:100px}.min-w-\[120px\]{min-width:120px}.min-w-\[130px\]{min-width:130px}.min-w-\[140px\]{min-width:140px}.min-w-\[150px\]{min-width:150px}.min-w-\[160px\]{min-width:160px}.min-w-\[180px\]{min-width:180px}.min-w-\[200px\]{min-width:200px}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-\[2_1_190px\]{flex:2 190px}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing)*.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-1{--tw-translate-x:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-3\.5{--tw-translate-x:calc(var(--spacing)*3.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-4{--tw-translate-x:calc(var(--spacing)*4);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing)*5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-6{--tw-translate-x:calc(var(--spacing)*6);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-105{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-110{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-\[1\.02\]{scale:1.02}.-rotate-90{rotate:-90deg}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-ping{animation:var(--animate-ping)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-ew-resize{cursor:ew-resize}.cursor-grab{cursor:grab}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-row-resize{cursor:row-resize}.cursor-se-resize{cursor:se-resize}.touch-manipulation{touch-action:manipulation}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.\[appearance\:textfield\]{appearance:textfield}.appearance-none{appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.grid-cols-\[auto_1fr_100px_100px_100px_80px\]{grid-template-columns:auto 1fr 100px 100px 100px 80px}.grid-cols-\[auto_1fr_120px_100px_100px_100px_80px\]{grid-template-columns:auto 1fr 120px 100px 100px 100px 80px}.grid-cols-\[repeat\(auto-fill\,minmax\(130px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(130px,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0{gap:calc(var(--spacing)*0)}.gap-0\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-5{gap:calc(var(--spacing)*5)}.gap-6{gap:calc(var(--spacing)*6)}.gap-8{gap:calc(var(--spacing)*8)}.gap-\[3px\]{gap:3px}:where(.space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*0)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*0)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}.gap-x-2{column-gap:calc(var(--spacing)*2)}.gap-x-3{column-gap:calc(var(--spacing)*3)}.gap-x-4{column-gap:calc(var(--spacing)*4)}.gap-x-6{column-gap:calc(var(--spacing)*6)}.gap-y-1{row-gap:calc(var(--spacing)*1)}.gap-y-1\.5{row-gap:calc(var(--spacing)*1.5)}.gap-y-2{row-gap:calc(var(--spacing)*2)}.gap-y-3{row-gap:calc(var(--spacing)*3)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-bambu-dark-tertiary>:not(:last-child)),:where(.divide-bambu-dark-tertiary\/30>:not(:last-child)){border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){:where(.divide-bambu-dark-tertiary\/30>:not(:last-child)){border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}:where(.divide-bambu-gray\/20>:not(:last-child)){border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){:where(.divide-bambu-gray\/20>:not(:last-child)){border-color:color-mix(in oklab,var(--color-bambu-gray)20%,transparent)}}:where(.divide-gray-100>:not(:last-child)){border-color:var(--color-gray-100)}.self-stretch{align-self:stretch}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-none{border-radius:0}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-lg{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.rounded-t-xl{border-top-left-radius:var(--radius-xl);border-top-right-radius:var(--radius-xl)}.\!rounded-l-none{border-top-left-radius:0!important;border-bottom-left-radius:0!important}.rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-l-lg{border-top-left-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.rounded-tl{border-top-left-radius:.25rem}.\!rounded-r-none{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.rounded-r-lg{border-top-right-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.rounded-b-2xl{border-bottom-right-radius:var(--radius-2xl);border-bottom-left-radius:var(--radius-2xl)}.rounded-b-lg{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-4{border-style:var(--tw-border-style);border-width:4px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-t-\[5px\]{border-top-style:var(--tw-border-style);border-top-width:5px}.border-t-\[6px\]{border-top-style:var(--tw-border-style);border-top-width:6px}.\!border-r-0{border-right-style:var(--tw-border-style)!important;border-right-width:0!important}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-r-\[5px\]{border-right-style:var(--tw-border-style);border-right-width:5px}.border-r-\[6px\]{border-right-style:var(--tw-border-style);border-right-width:6px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-b-\[6px\]{border-bottom-style:var(--tw-border-style);border-bottom-width:6px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-l-\[3px\]{border-left-style:var(--tw-border-style);border-left-width:3px}.border-l-\[5px\]{border-left-style:var(--tw-border-style);border-left-width:5px}.border-l-\[6px\]{border-left-style:var(--tw-border-style);border-left-width:6px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.\!border-green-500{border-color:var(--color-green-500)!important}.\!border-yellow-500{border-color:var(--color-yellow-500)!important}.border-amber-200{border-color:var(--color-amber-200)}.border-amber-300{border-color:var(--color-amber-300)}.border-amber-500{border-color:var(--color-amber-500)}.border-amber-500\/20{border-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/20{border-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/30{border-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.border-amber-700{border-color:var(--color-amber-700)}.border-amber-700\/40{border-color:#b7500066}@supports (color:color-mix(in lab,red,red)){.border-amber-700\/40{border-color:color-mix(in oklab,var(--color-amber-700)40%,transparent)}}.border-bambu-dark-secondary{border-color:var(--color-bambu-dark-secondary)}.border-bambu-dark-tertiary,.border-bambu-dark-tertiary\/20{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/20{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)20%,transparent)}}.border-bambu-dark-tertiary\/30{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/30{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.border-bambu-dark-tertiary\/40{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/40{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)40%,transparent)}}.border-bambu-dark-tertiary\/50{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/50{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.border-bambu-dark-tertiary\/60{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/60{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)60%,transparent)}}.border-bambu-gray,.border-bambu-gray\/20{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.border-bambu-gray\/20{border-color:color-mix(in oklab,var(--color-bambu-gray)20%,transparent)}}.border-bambu-gray\/30{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.border-bambu-gray\/30{border-color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.border-bambu-gray\/50{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.border-bambu-gray\/50{border-color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.border-bambu-green,.border-bambu-green\/20{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/20{border-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.border-bambu-green\/30{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/30{border-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.border-bambu-green\/40{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/40{border-color:color-mix(in oklab,var(--color-bambu-green)40%,transparent)}}.border-bambu-green\/50{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/50{border-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.border-black\/20{border-color:#0003}@supports (color:color-mix(in lab,red,red)){.border-black\/20{border-color:color-mix(in oklab,var(--color-black)20%,transparent)}}.border-blue-400{border-color:var(--color-blue-400)}.border-blue-400\/20{border-color:#54a2ff33}@supports (color:color-mix(in lab,red,red)){.border-blue-400\/20{border-color:color-mix(in oklab,var(--color-blue-400)20%,transparent)}}.border-blue-400\/50{border-color:#54a2ff80}@supports (color:color-mix(in lab,red,red)){.border-blue-400\/50{border-color:color-mix(in oklab,var(--color-blue-400)50%,transparent)}}.border-blue-500{border-color:var(--color-blue-500)}.border-blue-500\/20{border-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/20{border-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/30{border-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.border-blue-500\/40{border-color:#3080ff66}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/40{border-color:color-mix(in oklab,var(--color-blue-500)40%,transparent)}}.border-blue-500\/50{border-color:#3080ff80}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/50{border-color:color-mix(in oklab,var(--color-blue-500)50%,transparent)}}.border-current{border-color:currentColor}.border-emerald-500\/20{border-color:#00bb7f33}@supports (color:color-mix(in lab,red,red)){.border-emerald-500\/20{border-color:color-mix(in oklab,var(--color-emerald-500)20%,transparent)}}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-400\/20{border-color:#99a1af33}@supports (color:color-mix(in lab,red,red)){.border-gray-400\/20{border-color:color-mix(in oklab,var(--color-gray-400)20%,transparent)}}.border-gray-500{border-color:var(--color-gray-500)}.border-gray-500\/30{border-color:#6a72824d}@supports (color:color-mix(in lab,red,red)){.border-gray-500\/30{border-color:color-mix(in oklab,var(--color-gray-500)30%,transparent)}}.border-gray-500\/40{border-color:#6a728266}@supports (color:color-mix(in lab,red,red)){.border-gray-500\/40{border-color:color-mix(in oklab,var(--color-gray-500)40%,transparent)}}.border-gray-700{border-color:var(--color-gray-700)}.border-gray-800{border-color:var(--color-gray-800)}.border-green-300{border-color:var(--color-green-300)}.border-green-400{border-color:var(--color-green-400)}.border-green-500{border-color:var(--color-green-500)}.border-green-500\/30{border-color:#00c7584d}@supports (color:color-mix(in lab,red,red)){.border-green-500\/30{border-color:color-mix(in oklab,var(--color-green-500)30%,transparent)}}.border-green-500\/40{border-color:#00c75866}@supports (color:color-mix(in lab,red,red)){.border-green-500\/40{border-color:color-mix(in oklab,var(--color-green-500)40%,transparent)}}.border-green-500\/50{border-color:#00c75880}@supports (color:color-mix(in lab,red,red)){.border-green-500\/50{border-color:color-mix(in oklab,var(--color-green-500)50%,transparent)}}.border-green-800{border-color:var(--color-green-800)}.border-orange-400\/20{border-color:#ff8b1a33}@supports (color:color-mix(in lab,red,red)){.border-orange-400\/20{border-color:color-mix(in oklab,var(--color-orange-400)20%,transparent)}}.border-orange-400\/50{border-color:#ff8b1a80}@supports (color:color-mix(in lab,red,red)){.border-orange-400\/50{border-color:color-mix(in oklab,var(--color-orange-400)50%,transparent)}}.border-orange-500\/20{border-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.border-orange-500\/20{border-color:color-mix(in oklab,var(--color-orange-500)20%,transparent)}}.border-orange-500\/30{border-color:#fe6e004d}@supports (color:color-mix(in lab,red,red)){.border-orange-500\/30{border-color:color-mix(in oklab,var(--color-orange-500)30%,transparent)}}.border-purple-400\/20{border-color:#c07eff33}@supports (color:color-mix(in lab,red,red)){.border-purple-400\/20{border-color:color-mix(in oklab,var(--color-purple-400)20%,transparent)}}.border-purple-500{border-color:var(--color-purple-500)}.border-purple-500\/20{border-color:#ac4bff33}@supports (color:color-mix(in lab,red,red)){.border-purple-500\/20{border-color:color-mix(in oklab,var(--color-purple-500)20%,transparent)}}.border-purple-500\/30{border-color:#ac4bff4d}@supports (color:color-mix(in lab,red,red)){.border-purple-500\/30{border-color:color-mix(in oklab,var(--color-purple-500)30%,transparent)}}.border-red-300{border-color:var(--color-red-300)}.border-red-400{border-color:var(--color-red-400)}.border-red-500{border-color:var(--color-red-500)}.border-red-500\/20{border-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.border-red-500\/20{border-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.border-red-500\/30{border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.border-red-500\/30{border-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.border-red-500\/40{border-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.border-red-500\/40{border-color:color-mix(in oklab,var(--color-red-500)40%,transparent)}}.border-red-500\/50{border-color:#fb2c3680}@supports (color:color-mix(in lab,red,red)){.border-red-500\/50{border-color:color-mix(in oklab,var(--color-red-500)50%,transparent)}}.border-red-800{border-color:var(--color-red-800)}.border-red-800\/70{border-color:#9f0712b3}@supports (color:color-mix(in lab,red,red)){.border-red-800\/70{border-color:color-mix(in oklab,var(--color-red-800)70%,transparent)}}.border-red-900\/40{border-color:#82181a66}@supports (color:color-mix(in lab,red,red)){.border-red-900\/40{border-color:color-mix(in oklab,var(--color-red-900)40%,transparent)}}.border-slate-500{border-color:var(--color-slate-500)}.border-status-error\/20{border-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.border-status-error\/20{border-color:color-mix(in oklab,var(--color-status-error)20%,transparent)}}.border-status-ok,.border-status-ok\/20{border-color:var(--color-status-ok)}@supports (color:color-mix(in lab,red,red)){.border-status-ok\/20{border-color:color-mix(in oklab,var(--color-status-ok)20%,transparent)}}.border-status-warning\/20{border-color:var(--color-status-warning)}@supports (color:color-mix(in lab,red,red)){.border-status-warning\/20{border-color:color-mix(in oklab,var(--color-status-warning)20%,transparent)}}.border-transparent{border-color:#0000}.border-white{border-color:var(--color-white)}.border-white\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.border-white\/10{border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.border-white\/20{border-color:#fff3}@supports (color:color-mix(in lab,red,red)){.border-white\/20{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.border-white\/30{border-color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.border-white\/30{border-color:color-mix(in oklab,var(--color-white)30%,transparent)}}.border-yellow-400{border-color:var(--color-yellow-400)}.border-yellow-400\/20{border-color:#fac80033}@supports (color:color-mix(in lab,red,red)){.border-yellow-400\/20{border-color:color-mix(in oklab,var(--color-yellow-400)20%,transparent)}}.border-yellow-400\/40{border-color:#fac80066}@supports (color:color-mix(in lab,red,red)){.border-yellow-400\/40{border-color:color-mix(in oklab,var(--color-yellow-400)40%,transparent)}}.border-yellow-400\/50{border-color:#fac80080}@supports (color:color-mix(in lab,red,red)){.border-yellow-400\/50{border-color:color-mix(in oklab,var(--color-yellow-400)50%,transparent)}}.border-yellow-500{border-color:var(--color-yellow-500)}.border-yellow-500\/20{border-color:#edb20033}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/20{border-color:color-mix(in oklab,var(--color-yellow-500)20%,transparent)}}.border-yellow-500\/30{border-color:#edb2004d}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/30{border-color:color-mix(in oklab,var(--color-yellow-500)30%,transparent)}}.border-yellow-500\/50{border-color:#edb20080}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/50{border-color:color-mix(in oklab,var(--color-yellow-500)50%,transparent)}}.border-zinc-500{border-color:var(--color-zinc-500)}.border-zinc-600{border-color:var(--color-zinc-600)}.border-zinc-700{border-color:var(--color-zinc-700)}.border-zinc-700\/50{border-color:#3f3f4680}@supports (color:color-mix(in lab,red,red)){.border-zinc-700\/50{border-color:color-mix(in oklab,var(--color-zinc-700)50%,transparent)}}.border-zinc-800{border-color:var(--color-zinc-800)}.border-t-bambu-dark-tertiary{border-top-color:var(--color-bambu-dark-tertiary)}.border-t-transparent{border-top-color:#0000}.border-r-transparent{border-right-color:#0000}.border-b-bambu-dark-tertiary{border-bottom-color:var(--color-bambu-dark-tertiary)}.border-l-blue-500{border-left-color:var(--color-blue-500)}.border-l-emerald-500{border-left-color:var(--color-emerald-500)}.border-l-gray-500{border-left-color:var(--color-gray-500)}.border-l-red-500{border-left-color:var(--color-red-500)}.border-l-transparent{border-left-color:#0000}.border-l-yellow-500{border-left-color:var(--color-yellow-500)}.\!bg-bambu-green{background-color:var(--color-bambu-green)!important}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-500{background-color:var(--color-amber-500)}.bg-amber-500\/5{background-color:#f99c000d}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/5{background-color:color-mix(in oklab,var(--color-amber-500)5%,transparent)}}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/10{background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.bg-amber-500\/20{background-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/20{background-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.bg-amber-600{background-color:var(--color-amber-600)}.bg-amber-600\/20{background-color:#dd740033}@supports (color:color-mix(in lab,red,red)){.bg-amber-600\/20{background-color:color-mix(in oklab,var(--color-amber-600)20%,transparent)}}.bg-amber-900\/20{background-color:#7b330633}@supports (color:color-mix(in lab,red,red)){.bg-amber-900\/20{background-color:color-mix(in oklab,var(--color-amber-900)20%,transparent)}}.bg-amber-900\/30{background-color:#7b33064d}@supports (color:color-mix(in lab,red,red)){.bg-amber-900\/30{background-color:color-mix(in oklab,var(--color-amber-900)30%,transparent)}}.bg-bambu-dark{background-color:var(--color-bambu-dark)}.bg-bambu-dark-secondary,.bg-bambu-dark-secondary\/30{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/30{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)30%,transparent)}}.bg-bambu-dark-secondary\/50{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/50{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)50%,transparent)}}.bg-bambu-dark-secondary\/60{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/60{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)60%,transparent)}}.bg-bambu-dark-secondary\/90{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/90{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)90%,transparent)}}.bg-bambu-dark-secondary\/95{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/95{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)95%,transparent)}}.bg-bambu-dark-tertiary,.bg-bambu-dark-tertiary\/10{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/10{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)10%,transparent)}}.bg-bambu-dark-tertiary\/20{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/20{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)20%,transparent)}}.bg-bambu-dark-tertiary\/30{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/30{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.bg-bambu-dark-tertiary\/40{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/40{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)40%,transparent)}}.bg-bambu-dark-tertiary\/50{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/50{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.bg-bambu-dark-tertiary\/70{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/70{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)70%,transparent)}}.bg-bambu-dark-tertiary\/80{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/80{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.bg-bambu-dark\/20{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/20{background-color:color-mix(in oklab,var(--color-bambu-dark)20%,transparent)}}.bg-bambu-dark\/30{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/30{background-color:color-mix(in oklab,var(--color-bambu-dark)30%,transparent)}}.bg-bambu-dark\/40{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/40{background-color:color-mix(in oklab,var(--color-bambu-dark)40%,transparent)}}.bg-bambu-dark\/50{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/50{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.bg-bambu-dark\/80{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/80{background-color:color-mix(in oklab,var(--color-bambu-dark)80%,transparent)}}.bg-bambu-dark\/90{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/90{background-color:color-mix(in oklab,var(--color-bambu-dark)90%,transparent)}}.bg-bambu-gray,.bg-bambu-gray\/10{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/10{background-color:color-mix(in oklab,var(--color-bambu-gray)10%,transparent)}}.bg-bambu-gray\/20{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/20{background-color:color-mix(in oklab,var(--color-bambu-gray)20%,transparent)}}.bg-bambu-gray\/30{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/30{background-color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.bg-bambu-gray\/40{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/40{background-color:color-mix(in oklab,var(--color-bambu-gray)40%,transparent)}}.bg-bambu-gray\/50{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/50{background-color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.bg-bambu-gray\/60{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/60{background-color:color-mix(in oklab,var(--color-bambu-gray)60%,transparent)}}.bg-bambu-gray\/90{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/90{background-color:color-mix(in oklab,var(--color-bambu-gray)90%,transparent)}}.bg-bambu-green,.bg-bambu-green\/5{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/5{background-color:color-mix(in oklab,var(--color-bambu-green)5%,transparent)}}.bg-bambu-green\/10{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/10{background-color:color-mix(in oklab,var(--color-bambu-green)10%,transparent)}}.bg-bambu-green\/15{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/15{background-color:color-mix(in oklab,var(--color-bambu-green)15%,transparent)}}.bg-bambu-green\/20{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/20{background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.bg-bambu-green\/30{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/30{background-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.bg-bambu-green\/40{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/40{background-color:color-mix(in oklab,var(--color-bambu-green)40%,transparent)}}.bg-bambu-green\/50{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/50{background-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.bg-bambu-green\/75{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/75{background-color:color-mix(in oklab,var(--color-bambu-green)75%,transparent)}}.bg-bambu-green\/90{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/90{background-color:color-mix(in oklab,var(--color-bambu-green)90%,transparent)}}.bg-black{background-color:var(--color-black)}.bg-black\/15{background-color:#00000026}@supports (color:color-mix(in lab,red,red)){.bg-black\/15{background-color:color-mix(in oklab,var(--color-black)15%,transparent)}}.bg-black\/20{background-color:#0003}@supports (color:color-mix(in lab,red,red)){.bg-black\/20{background-color:color-mix(in oklab,var(--color-black)20%,transparent)}}.bg-black\/30{background-color:#0000004d}@supports (color:color-mix(in lab,red,red)){.bg-black\/30{background-color:color-mix(in oklab,var(--color-black)30%,transparent)}}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.bg-black\/40{background-color:color-mix(in oklab,var(--color-black)40%,transparent)}}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black)60%,transparent)}}.bg-black\/70{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.bg-black\/70{background-color:color-mix(in oklab,var(--color-black)70%,transparent)}}.bg-black\/80{background-color:#000c}@supports (color:color-mix(in lab,red,red)){.bg-black\/80{background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.bg-black\/90{background-color:#000000e6}@supports (color:color-mix(in lab,red,red)){.bg-black\/90{background-color:color-mix(in oklab,var(--color-black)90%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-400{background-color:var(--color-blue-400)}.bg-blue-400\/10{background-color:#54a2ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-400\/10{background-color:color-mix(in oklab,var(--color-blue-400)10%,transparent)}}.bg-blue-400\/15{background-color:#54a2ff26}@supports (color:color-mix(in lab,red,red)){.bg-blue-400\/15{background-color:color-mix(in oklab,var(--color-blue-400)15%,transparent)}}.bg-blue-400\/20{background-color:#54a2ff33}@supports (color:color-mix(in lab,red,red)){.bg-blue-400\/20{background-color:color-mix(in oklab,var(--color-blue-400)20%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-500\/5{background-color:#3080ff0d}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/5{background-color:color-mix(in oklab,var(--color-blue-500)5%,transparent)}}.bg-blue-500\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/10{background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.bg-blue-500\/15{background-color:#3080ff26}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/15{background-color:color-mix(in oklab,var(--color-blue-500)15%,transparent)}}.bg-blue-500\/20{background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/20{background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.bg-blue-500\/30{background-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/30{background-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.bg-blue-500\/90{background-color:#3080ffe6}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/90{background-color:color-mix(in oklab,var(--color-blue-500)90%,transparent)}}.bg-blue-600{background-color:var(--color-blue-600)}.bg-blue-600\/20{background-color:#155dfc33}@supports (color:color-mix(in lab,red,red)){.bg-blue-600\/20{background-color:color-mix(in oklab,var(--color-blue-600)20%,transparent)}}.bg-blue-700{background-color:var(--color-blue-700)}.bg-cyan-500{background-color:var(--color-cyan-500)}.bg-cyan-500\/10{background-color:#00b7d71a}@supports (color:color-mix(in lab,red,red)){.bg-cyan-500\/10{background-color:color-mix(in oklab,var(--color-cyan-500)10%,transparent)}}.bg-cyan-500\/20{background-color:#00b7d733}@supports (color:color-mix(in lab,red,red)){.bg-cyan-500\/20{background-color:color-mix(in oklab,var(--color-cyan-500)20%,transparent)}}.bg-cyan-600\/20{background-color:#0092b533}@supports (color:color-mix(in lab,red,red)){.bg-cyan-600\/20{background-color:color-mix(in oklab,var(--color-cyan-600)20%,transparent)}}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab,red,red)){.bg-emerald-500\/10{background-color:color-mix(in oklab,var(--color-emerald-500)10%,transparent)}}.bg-emerald-500\/20{background-color:#00bb7f33}@supports (color:color-mix(in lab,red,red)){.bg-emerald-500\/20{background-color:color-mix(in oklab,var(--color-emerald-500)20%,transparent)}}.bg-emerald-600\/20{background-color:#00976733}@supports (color:color-mix(in lab,red,red)){.bg-emerald-600\/20{background-color:color-mix(in oklab,var(--color-emerald-600)20%,transparent)}}.bg-emerald-700{background-color:var(--color-emerald-700)}.bg-fuchsia-500{background-color:var(--color-fuchsia-500)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-400\/10{background-color:#99a1af1a}@supports (color:color-mix(in lab,red,red)){.bg-gray-400\/10{background-color:color-mix(in oklab,var(--color-gray-400)10%,transparent)}}.bg-gray-500{background-color:var(--color-gray-500)}.bg-gray-500\/15{background-color:#6a728226}@supports (color:color-mix(in lab,red,red)){.bg-gray-500\/15{background-color:color-mix(in oklab,var(--color-gray-500)15%,transparent)}}.bg-gray-500\/20{background-color:#6a728233}@supports (color:color-mix(in lab,red,red)){.bg-gray-500\/20{background-color:color-mix(in oklab,var(--color-gray-500)20%,transparent)}}.bg-gray-600{background-color:var(--color-gray-600)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-400{background-color:var(--color-green-400)}.bg-green-400\/10{background-color:#05df721a}@supports (color:color-mix(in lab,red,red)){.bg-green-400\/10{background-color:color-mix(in oklab,var(--color-green-400)10%,transparent)}}.bg-green-500{background-color:var(--color-green-500)}.bg-green-500\/10{background-color:#00c7581a}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/10{background-color:color-mix(in oklab,var(--color-green-500)10%,transparent)}}.bg-green-500\/15{background-color:#00c75826}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/15{background-color:color-mix(in oklab,var(--color-green-500)15%,transparent)}}.bg-green-500\/20{background-color:#00c75833}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/20{background-color:color-mix(in oklab,var(--color-green-500)20%,transparent)}}.bg-green-600{background-color:var(--color-green-600)}.bg-green-600\/20{background-color:#00a54433}@supports (color:color-mix(in lab,red,red)){.bg-green-600\/20{background-color:color-mix(in oklab,var(--color-green-600)20%,transparent)}}.bg-green-600\/40{background-color:#00a54466}@supports (color:color-mix(in lab,red,red)){.bg-green-600\/40{background-color:color-mix(in oklab,var(--color-green-600)40%,transparent)}}.bg-green-700{background-color:var(--color-green-700)}.bg-green-900\/30{background-color:#0d542b4d}@supports (color:color-mix(in lab,red,red)){.bg-green-900\/30{background-color:color-mix(in oklab,var(--color-green-900)30%,transparent)}}.bg-green-900\/50{background-color:#0d542b80}@supports (color:color-mix(in lab,red,red)){.bg-green-900\/50{background-color:color-mix(in oklab,var(--color-green-900)50%,transparent)}}.bg-indigo-500\/10{background-color:#625fff1a}@supports (color:color-mix(in lab,red,red)){.bg-indigo-500\/10{background-color:color-mix(in oklab,var(--color-indigo-500)10%,transparent)}}.bg-indigo-500\/15{background-color:#625fff26}@supports (color:color-mix(in lab,red,red)){.bg-indigo-500\/15{background-color:color-mix(in oklab,var(--color-indigo-500)15%,transparent)}}.bg-indigo-500\/20{background-color:#625fff33}@supports (color:color-mix(in lab,red,red)){.bg-indigo-500\/20{background-color:color-mix(in oklab,var(--color-indigo-500)20%,transparent)}}.bg-lime-500{background-color:var(--color-lime-500)}.bg-lime-500\/20{background-color:#80cd0033}@supports (color:color-mix(in lab,red,red)){.bg-lime-500\/20{background-color:color-mix(in oklab,var(--color-lime-500)20%,transparent)}}.bg-orange-400\/10{background-color:#ff8b1a1a}@supports (color:color-mix(in lab,red,red)){.bg-orange-400\/10{background-color:color-mix(in oklab,var(--color-orange-400)10%,transparent)}}.bg-orange-500{background-color:var(--color-orange-500)}.bg-orange-500\/10{background-color:#fe6e001a}@supports (color:color-mix(in lab,red,red)){.bg-orange-500\/10{background-color:color-mix(in oklab,var(--color-orange-500)10%,transparent)}}.bg-orange-500\/20{background-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.bg-orange-500\/20{background-color:color-mix(in oklab,var(--color-orange-500)20%,transparent)}}.bg-orange-600{background-color:var(--color-orange-600)}.bg-orange-600\/20{background-color:#f0510033}@supports (color:color-mix(in lab,red,red)){.bg-orange-600\/20{background-color:color-mix(in oklab,var(--color-orange-600)20%,transparent)}}.bg-purple-400\/10{background-color:#c07eff1a}@supports (color:color-mix(in lab,red,red)){.bg-purple-400\/10{background-color:color-mix(in oklab,var(--color-purple-400)10%,transparent)}}.bg-purple-500{background-color:var(--color-purple-500)}.bg-purple-500\/10{background-color:#ac4bff1a}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/10{background-color:color-mix(in oklab,var(--color-purple-500)10%,transparent)}}.bg-purple-500\/20{background-color:#ac4bff33}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/20{background-color:color-mix(in oklab,var(--color-purple-500)20%,transparent)}}.bg-purple-500\/80{background-color:#ac4bffcc}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/80{background-color:color-mix(in oklab,var(--color-purple-500)80%,transparent)}}.bg-purple-500\/90{background-color:#ac4bffe6}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/90{background-color:color-mix(in oklab,var(--color-purple-500)90%,transparent)}}.bg-purple-700{background-color:var(--color-purple-700)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-400{background-color:var(--color-red-400)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/5{background-color:#fb2c360d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/5{background-color:color-mix(in oklab,var(--color-red-500)5%,transparent)}}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/10{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.bg-red-500\/15{background-color:#fb2c3626}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/15{background-color:color-mix(in oklab,var(--color-red-500)15%,transparent)}}.bg-red-500\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/20{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.bg-red-500\/30{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/30{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.bg-red-500\/40{background-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/40{background-color:color-mix(in oklab,var(--color-red-500)40%,transparent)}}.bg-red-500\/80{background-color:#fb2c36cc}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/80{background-color:color-mix(in oklab,var(--color-red-500)80%,transparent)}}.bg-red-600{background-color:var(--color-red-600)}.bg-red-600\/20{background-color:#e4001433}@supports (color:color-mix(in lab,red,red)){.bg-red-600\/20{background-color:color-mix(in oklab,var(--color-red-600)20%,transparent)}}.bg-red-900\/20{background-color:#82181a33}@supports (color:color-mix(in lab,red,red)){.bg-red-900\/20{background-color:color-mix(in oklab,var(--color-red-900)20%,transparent)}}.bg-red-900\/30{background-color:#82181a4d}@supports (color:color-mix(in lab,red,red)){.bg-red-900\/30{background-color:color-mix(in oklab,var(--color-red-900)30%,transparent)}}.bg-red-950\/70{background-color:#460809b3}@supports (color:color-mix(in lab,red,red)){.bg-red-950\/70{background-color:color-mix(in oklab,var(--color-red-950)70%,transparent)}}.bg-rose-500\/20{background-color:#ff235733}@supports (color:color-mix(in lab,red,red)){.bg-rose-500\/20{background-color:color-mix(in oklab,var(--color-rose-500)20%,transparent)}}.bg-rose-600\/20{background-color:#e7004433}@supports (color:color-mix(in lab,red,red)){.bg-rose-600\/20{background-color:color-mix(in oklab,var(--color-rose-600)20%,transparent)}}.bg-sky-500{background-color:var(--color-sky-500)}.bg-sky-500\/10{background-color:#00a5ef1a}@supports (color:color-mix(in lab,red,red)){.bg-sky-500\/10{background-color:color-mix(in oklab,var(--color-sky-500)10%,transparent)}}.bg-sky-500\/20{background-color:#00a5ef33}@supports (color:color-mix(in lab,red,red)){.bg-sky-500\/20{background-color:color-mix(in oklab,var(--color-sky-500)20%,transparent)}}.bg-status-error,.bg-status-error\/10{background-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.bg-status-error\/10{background-color:color-mix(in oklab,var(--color-status-error)10%,transparent)}}.bg-status-error\/20{background-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.bg-status-error\/20{background-color:color-mix(in oklab,var(--color-status-error)20%,transparent)}}.bg-status-error\/80{background-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.bg-status-error\/80{background-color:color-mix(in oklab,var(--color-status-error)80%,transparent)}}.bg-status-ok,.bg-status-ok\/10{background-color:var(--color-status-ok)}@supports (color:color-mix(in lab,red,red)){.bg-status-ok\/10{background-color:color-mix(in oklab,var(--color-status-ok)10%,transparent)}}.bg-status-ok\/20{background-color:var(--color-status-ok)}@supports (color:color-mix(in lab,red,red)){.bg-status-ok\/20{background-color:color-mix(in oklab,var(--color-status-ok)20%,transparent)}}.bg-status-warning,.bg-status-warning\/10{background-color:var(--color-status-warning)}@supports (color:color-mix(in lab,red,red)){.bg-status-warning\/10{background-color:color-mix(in oklab,var(--color-status-warning)10%,transparent)}}.bg-status-warning\/20{background-color:var(--color-status-warning)}@supports (color:color-mix(in lab,red,red)){.bg-status-warning\/20{background-color:color-mix(in oklab,var(--color-status-warning)20%,transparent)}}.bg-teal-500{background-color:var(--color-teal-500)}.bg-teal-500\/20{background-color:#00baa733}@supports (color:color-mix(in lab,red,red)){.bg-teal-500\/20{background-color:color-mix(in oklab,var(--color-teal-500)20%,transparent)}}.bg-transparent{background-color:#0000}.bg-violet-500{background-color:var(--color-violet-500)}.bg-white{background-color:var(--color-white)}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.bg-white\/10{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.bg-white\/20{background-color:#fff3}@supports (color:color-mix(in lab,red,red)){.bg-white\/20{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.bg-white\/50{background-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.bg-white\/50{background-color:color-mix(in oklab,var(--color-white)50%,transparent)}}.bg-white\/70{background-color:#ffffffb3}@supports (color:color-mix(in lab,red,red)){.bg-white\/70{background-color:color-mix(in oklab,var(--color-white)70%,transparent)}}.bg-white\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.bg-white\/90{background-color:color-mix(in oklab,var(--color-white)90%,transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-400\/10{background-color:#fac8001a}@supports (color:color-mix(in lab,red,red)){.bg-yellow-400\/10{background-color:color-mix(in oklab,var(--color-yellow-400)10%,transparent)}}.bg-yellow-400\/20{background-color:#fac80033}@supports (color:color-mix(in lab,red,red)){.bg-yellow-400\/20{background-color:color-mix(in oklab,var(--color-yellow-400)20%,transparent)}}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-yellow-500\/5{background-color:#edb2000d}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/5{background-color:color-mix(in oklab,var(--color-yellow-500)5%,transparent)}}.bg-yellow-500\/10{background-color:#edb2001a}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/10{background-color:color-mix(in oklab,var(--color-yellow-500)10%,transparent)}}.bg-yellow-500\/15{background-color:#edb20026}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/15{background-color:color-mix(in oklab,var(--color-yellow-500)15%,transparent)}}.bg-yellow-500\/20{background-color:#edb20033}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/20{background-color:color-mix(in oklab,var(--color-yellow-500)20%,transparent)}}.bg-yellow-700{background-color:var(--color-yellow-700)}.bg-zinc-600{background-color:var(--color-zinc-600)}.bg-zinc-700{background-color:var(--color-zinc-700)}.bg-zinc-800{background-color:var(--color-zinc-800)}.bg-zinc-800\/50{background-color:#27272a80}@supports (color:color-mix(in lab,red,red)){.bg-zinc-800\/50{background-color:color-mix(in oklab,var(--color-zinc-800)50%,transparent)}}.bg-zinc-800\/60{background-color:#27272a99}@supports (color:color-mix(in lab,red,red)){.bg-zinc-800\/60{background-color:color-mix(in oklab,var(--color-zinc-800)60%,transparent)}}.bg-zinc-900{background-color:var(--color-zinc-900)}.bg-zinc-900\/50{background-color:#18181b80}@supports (color:color-mix(in lab,red,red)){.bg-zinc-900\/50{background-color:color-mix(in oklab,var(--color-zinc-900)50%,transparent)}}.bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-bambu-dark-secondary{--tw-gradient-from:var(--color-bambu-dark-secondary);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-black\/80{--tw-gradient-from:#000c}@supports (color:color-mix(in lab,red,red)){.from-black\/80{--tw-gradient-from:color-mix(in oklab,var(--color-black)80%,transparent)}}.from-black\/80{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-500\/5{--tw-gradient-from:#3080ff0d}@supports (color:color-mix(in lab,red,red)){.from-blue-500\/5{--tw-gradient-from:color-mix(in oklab,var(--color-blue-500)5%,transparent)}}.from-blue-500\/5{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-white\/10{--tw-gradient-from:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.from-white\/10{--tw-gradient-from:color-mix(in oklab,var(--color-white)10%,transparent)}}.from-white\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.via-black\/60{--tw-gradient-via:#0009}@supports (color:color-mix(in lab,red,red)){.via-black\/60{--tw-gradient-via:color-mix(in oklab,var(--color-black)60%,transparent)}}.via-black\/60{--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-bambu-dark-secondary{--tw-gradient-to:var(--color-bambu-dark-secondary);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-bambu-dark-tertiary{--tw-gradient-to:var(--color-bambu-dark-tertiary);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.bg-cover{background-size:cover}.bg-center{background-position:50%}.fill-yellow-400{fill:var(--color-yellow-400)}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.object-left{object-position:left}.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-2\.5{padding:calc(var(--spacing)*2.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.p-12{padding:calc(var(--spacing)*12)}.\!px-1\.5{padding-inline:calc(var(--spacing)*1.5)!important}.\!px-3{padding-inline:calc(var(--spacing)*3)!important}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.py-12{padding-block:calc(var(--spacing)*12)}.py-16{padding-block:calc(var(--spacing)*16)}.py-20{padding-block:calc(var(--spacing)*20)}.py-24{padding-block:calc(var(--spacing)*24)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-5{padding-top:calc(var(--spacing)*5)}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-3{padding-right:calc(var(--spacing)*3)}.pr-4{padding-right:calc(var(--spacing)*4)}.pr-6{padding-right:calc(var(--spacing)*6)}.pr-7{padding-right:calc(var(--spacing)*7)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-10{padding-right:calc(var(--spacing)*10)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-3{padding-left:calc(var(--spacing)*3)}.pl-4{padding-left:calc(var(--spacing)*4)}.pl-5{padding-left:calc(var(--spacing)*5)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-7{padding-left:calc(var(--spacing)*7)}.pl-8{padding-left:calc(var(--spacing)*8)}.pl-9{padding-left:calc(var(--spacing)*9)}.pl-10{padding-left:calc(var(--spacing)*10)}.pl-20{padding-left:calc(var(--spacing)*20)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[6px\]{font-size:6px}.text-\[7px\]{font-size:7px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.\!text-green-400{color:var(--color-green-400)!important}.\!text-white{color:var(--color-white)!important}.\!text-yellow-400{color:var(--color-yellow-400)!important}.text-amber-200{color:var(--color-amber-200)}.text-amber-200\/80{color:#fee685cc}@supports (color:color-mix(in lab,red,red)){.text-amber-200\/80{color:color-mix(in oklab,var(--color-amber-200)80%,transparent)}}.text-amber-300{color:var(--color-amber-300)}.text-amber-300\/60{color:#ffd23699}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/60{color:color-mix(in oklab,var(--color-amber-300)60%,transparent)}}.text-amber-300\/70{color:#ffd236b3}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/70{color:color-mix(in oklab,var(--color-amber-300)70%,transparent)}}.text-amber-300\/80{color:#ffd236cc}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/80{color:color-mix(in oklab,var(--color-amber-300)80%,transparent)}}.text-amber-400{color:var(--color-amber-400)}.text-amber-400\/70{color:#fcbb00b3}@supports (color:color-mix(in lab,red,red)){.text-amber-400\/70{color:color-mix(in oklab,var(--color-amber-400)70%,transparent)}}.text-amber-500{color:var(--color-amber-500)}.text-amber-500\/80{color:#f99c00cc}@supports (color:color-mix(in lab,red,red)){.text-amber-500\/80{color:color-mix(in oklab,var(--color-amber-500)80%,transparent)}}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-amber-900{color:var(--color-amber-900)}.text-bambu-dark{color:var(--color-bambu-dark)}.text-bambu-dark-tertiary{color:var(--color-bambu-dark-tertiary)}.text-bambu-gray{color:var(--color-bambu-gray)}.text-bambu-gray-dark{color:var(--color-bambu-gray-dark)}.text-bambu-gray-light{color:var(--color-bambu-gray-light)}.text-bambu-gray\/30{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/30{color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.text-bambu-gray\/40{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/40{color:color-mix(in oklab,var(--color-bambu-gray)40%,transparent)}}.text-bambu-gray\/50{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/50{color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.text-bambu-gray\/60{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/60{color:color-mix(in oklab,var(--color-bambu-gray)60%,transparent)}}.text-bambu-gray\/70{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/70{color:color-mix(in oklab,var(--color-bambu-gray)70%,transparent)}}.text-bambu-gray\/80{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/80{color:color-mix(in oklab,var(--color-bambu-gray)80%,transparent)}}.text-bambu-green,.text-bambu-green\/50{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.text-bambu-green\/50{color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.text-bambu-green\/60{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.text-bambu-green\/60{color:color-mix(in oklab,var(--color-bambu-green)60%,transparent)}}.text-bambu-green\/70{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.text-bambu-green\/70{color:color-mix(in oklab,var(--color-bambu-green)70%,transparent)}}.text-black{color:var(--color-black)}.text-black\/80{color:#000c}@supports (color:color-mix(in lab,red,red)){.text-black\/80{color:color-mix(in oklab,var(--color-black)80%,transparent)}}.text-blue-100{color:var(--color-blue-100)}.text-blue-300{color:var(--color-blue-300)}.text-blue-300\/70{color:#90c5ffb3}@supports (color:color-mix(in lab,red,red)){.text-blue-300\/70{color:color-mix(in oklab,var(--color-blue-300)70%,transparent)}}.text-blue-300\/80{color:#90c5ffcc}@supports (color:color-mix(in lab,red,red)){.text-blue-300\/80{color:color-mix(in oklab,var(--color-blue-300)80%,transparent)}}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-blue-500\/70{color:#3080ffb3}@supports (color:color-mix(in lab,red,red)){.text-blue-500\/70{color:color-mix(in oklab,var(--color-blue-500)70%,transparent)}}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-cyan-300{color:var(--color-cyan-300)}.text-cyan-400{color:var(--color-cyan-400)}.text-emerald-100{color:var(--color-emerald-100)}.text-emerald-300{color:var(--color-emerald-300)}.text-emerald-400{color:var(--color-emerald-400)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-200{color:var(--color-green-200)}.text-green-300{color:var(--color-green-300)}.text-green-400{color:var(--color-green-400)}.text-green-400\/60{color:#05df7299}@supports (color:color-mix(in lab,red,red)){.text-green-400\/60{color:color-mix(in oklab,var(--color-green-400)60%,transparent)}}.text-green-400\/70{color:#05df72b3}@supports (color:color-mix(in lab,red,red)){.text-green-400\/70{color:color-mix(in oklab,var(--color-green-400)70%,transparent)}}.text-green-500{color:var(--color-green-500)}.text-green-500\/60{color:#00c75899}@supports (color:color-mix(in lab,red,red)){.text-green-500\/60{color:color-mix(in oklab,var(--color-green-500)60%,transparent)}}.text-green-600{color:var(--color-green-600)}.text-green-700{color:var(--color-green-700)}.text-indigo-300{color:var(--color-indigo-300)}.text-indigo-400{color:var(--color-indigo-400)}.text-lime-400{color:var(--color-lime-400)}.text-orange-200{color:var(--color-orange-200)}.text-orange-300{color:var(--color-orange-300)}.text-orange-400{color:var(--color-orange-400)}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-purple-300{color:var(--color-purple-300)}.text-purple-300\/70{color:#d9b3ffb3}@supports (color:color-mix(in lab,red,red)){.text-purple-300\/70{color:color-mix(in oklab,var(--color-purple-300)70%,transparent)}}.text-purple-400{color:var(--color-purple-400)}.text-purple-400\/80{color:#c07effcc}@supports (color:color-mix(in lab,red,red)){.text-purple-400\/80{color:color-mix(in oklab,var(--color-purple-400)80%,transparent)}}.text-red-200{color:var(--color-red-200)}.text-red-300{color:var(--color-red-300)}.text-red-300\/80{color:#ffa3a3cc}@supports (color:color-mix(in lab,red,red)){.text-red-300\/80{color:color-mix(in oklab,var(--color-red-300)80%,transparent)}}.text-red-400{color:var(--color-red-400)}.text-red-400\/50{color:#ff656880}@supports (color:color-mix(in lab,red,red)){.text-red-400\/50{color:color-mix(in oklab,var(--color-red-400)50%,transparent)}}.text-red-400\/60{color:#ff656899}@supports (color:color-mix(in lab,red,red)){.text-red-400\/60{color:color-mix(in oklab,var(--color-red-400)60%,transparent)}}.text-red-400\/70{color:#ff6568b3}@supports (color:color-mix(in lab,red,red)){.text-red-400\/70{color:color-mix(in oklab,var(--color-red-400)70%,transparent)}}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-rose-300{color:var(--color-rose-300)}.text-rose-400{color:var(--color-rose-400)}.text-sky-400{color:var(--color-sky-400)}.text-slate-300{color:var(--color-slate-300)}.text-status-error{color:var(--color-status-error)}.text-status-ok{color:var(--color-status-ok)}.text-status-warning{color:var(--color-status-warning)}.text-teal-400{color:var(--color-teal-400)}.text-white{color:var(--color-white)}.text-white\/30{color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.text-white\/30{color:color-mix(in oklab,var(--color-white)30%,transparent)}}.text-white\/40{color:#fff6}@supports (color:color-mix(in lab,red,red)){.text-white\/40{color:color-mix(in oklab,var(--color-white)40%,transparent)}}.text-white\/50{color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.text-white\/50{color:color-mix(in oklab,var(--color-white)50%,transparent)}}.text-white\/60{color:#fff9}@supports (color:color-mix(in lab,red,red)){.text-white\/60{color:color-mix(in oklab,var(--color-white)60%,transparent)}}.text-white\/70{color:#ffffffb3}@supports (color:color-mix(in lab,red,red)){.text-white\/70{color:color-mix(in oklab,var(--color-white)70%,transparent)}}.text-white\/80{color:#fffc}@supports (color:color-mix(in lab,red,red)){.text-white\/80{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.text-white\/90{color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.text-white\/90{color:color-mix(in oklab,var(--color-white)90%,transparent)}}.text-yellow-100{color:var(--color-yellow-100)}.text-yellow-200{color:var(--color-yellow-200)}.text-yellow-200\/70{color:#fff085b3}@supports (color:color-mix(in lab,red,red)){.text-yellow-200\/70{color:color-mix(in oklab,var(--color-yellow-200)70%,transparent)}}.text-yellow-300{color:var(--color-yellow-300)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500{color:var(--color-yellow-500)}.text-yellow-500\/70{color:#edb200b3}@supports (color:color-mix(in lab,red,red)){.text-yellow-500\/70{color:color-mix(in oklab,var(--color-yellow-500)70%,transparent)}}.text-yellow-500\/80{color:#edb200cc}@supports (color:color-mix(in lab,red,red)){.text-yellow-500\/80{color:color-mix(in oklab,var(--color-yellow-500)80%,transparent)}}.text-yellow-600{color:var(--color-yellow-600)}.text-yellow-700{color:var(--color-yellow-700)}.text-zinc-100{color:var(--color-zinc-100)}.text-zinc-200{color:var(--color-zinc-200)}.text-zinc-300{color:var(--color-zinc-300)}.text-zinc-400{color:var(--color-zinc-400)}.text-zinc-500{color:var(--color-zinc-500)}.text-zinc-600{color:var(--color-zinc-600)}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.placeholder-bambu-gray::placeholder{color:var(--color-bambu-gray)}.placeholder-bambu-gray-dark::placeholder{color:var(--color-bambu-gray-dark)}.placeholder-bambu-gray\/40::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder-bambu-gray\/40::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)40%,transparent)}}.placeholder-bambu-gray\/50::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder-bambu-gray\/50::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.placeholder-bambu-gray\/60::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder-bambu-gray\/60::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)60%,transparent)}}.placeholder-gray-400::placeholder{color:var(--color-gray-400)}.placeholder-white\/30::placeholder{color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.placeholder-white\/30::placeholder{color:color-mix(in oklab,var(--color-white)30%,transparent)}}.placeholder-zinc-500::placeholder{color:var(--color-zinc-500)}.accent-amber-500{accent-color:var(--color-amber-500)}.accent-bambu-green{accent-color:var(--color-bambu-green)}.accent-green-500{accent-color:var(--color-green-500)}.accent-red-500{accent-color:var(--color-red-500)}.\[color-scheme\:dark\]{color-scheme:dark}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_6px_rgba\(34\,197\,94\,0\.5\)\]{--tw-shadow:0 0 6px var(--tw-shadow-color,#22c55e80);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow\/depth{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-bambu-green\/20{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.shadow-bambu-green\/20{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)20%,transparent)var(--tw-shadow-alpha),transparent)}}.shadow-bambu-green\/25{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.shadow-bambu-green\/25{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)25%,transparent)var(--tw-shadow-alpha),transparent)}}.ring-bambu-green,.ring-bambu-green\/30{--tw-ring-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.ring-bambu-green\/30{--tw-ring-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.ring-blue-400\/50{--tw-ring-color:#54a2ff80}@supports (color:color-mix(in lab,red,red)){.ring-blue-400\/50{--tw-ring-color:color-mix(in oklab,var(--color-blue-400)50%,transparent)}}.ring-green-500{--tw-ring-color:var(--color-green-500)}.ring-white{--tw-ring-color:var(--color-white)}.ring-offset-1{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.ring-offset-2{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.ring-offset-bambu-dark{--tw-ring-offset-color:var(--color-bambu-dark)}.ring-offset-bambu-dark-secondary{--tw-ring-offset-color:var(--color-bambu-dark-secondary)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.blur-2xl{--tw-blur:blur(var(--blur-2xl));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.drop-shadow-lg{--tw-drop-shadow-size:drop-shadow(0 4px 4px var(--tw-drop-shadow-color,#00000026));--tw-drop-shadow:drop-shadow(var(--drop-shadow-lg));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.drop-shadow-md{--tw-drop-shadow-size:drop-shadow(0 3px 3px var(--tw-drop-shadow-color,#0000001f));--tw-drop-shadow:drop-shadow(var(--drop-shadow-md));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.\!filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)!important}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:bg-bambu-green\/20:is(:where(.group):hover *){background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.group-hover\:bg-bambu-green\/20:is(:where(.group):hover *){background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.group-hover\:break-all:is(:where(.group):hover *){word-break:break-all}.group-hover\:whitespace-normal:is(:where(.group):hover *){white-space:normal}.group-hover\:text-bambu-gray:is(:where(.group):hover *){color:var(--color-bambu-gray)}.group-hover\:text-bambu-green:is(:where(.group):hover *){color:var(--color-bambu-green)}.group-hover\:opacity-50:is(:where(.group):hover *){opacity:.5}.group-hover\:opacity-100:is(:where(.group):hover *),.group-hover\/resize\:opacity-100:is(:where(.group\/resize):hover *){opacity:1}.group-hover\/thumb\:block:is(:where(.group\/thumb):hover *){display:block}}.peer-checked\:bg-amber-500:is(:where(.peer):checked~*){background-color:var(--color-amber-500)}.peer-checked\:bg-bambu-green:is(:where(.peer):checked~*){background-color:var(--color-bambu-green)}.peer-focus\:ring-2:is(:where(.peer):focus~*){--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.peer-focus\:ring-bambu-green\/50:is(:where(.peer):focus~*){--tw-ring-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.peer-focus\:ring-bambu-green\/50:is(:where(.peer):focus~*){--tw-ring-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.peer-focus\:outline-none:is(:where(.peer):focus~*){--tw-outline-style:none;outline-style:none}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.placeholder\:text-bambu-gray::placeholder,.placeholder\:text-bambu-gray\/40::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder\:text-bambu-gray\/40::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)40%,transparent)}}.placeholder\:text-bambu-gray\/50::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder\:text-bambu-gray\/50::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:top-0:before{content:var(--tw-content);top:calc(var(--spacing)*0)}.before\:right-0:before{content:var(--tw-content);right:calc(var(--spacing)*0)}.before\:left-0:before{content:var(--tw-content);left:calc(var(--spacing)*0)}.before\:h-0\.5:before{content:var(--tw-content);height:calc(var(--spacing)*.5)}.before\:bg-bambu-green:before{content:var(--tw-content);background-color:var(--color-bambu-green)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:top-0\.5:after{content:var(--tw-content);top:calc(var(--spacing)*.5)}.after\:top-\[2px\]:after{content:var(--tw-content);top:2px}.after\:left-0\.5:after{content:var(--tw-content);left:calc(var(--spacing)*.5)}.after\:left-\[2px\]:after{content:var(--tw-content);left:2px}.after\:h-4:after{content:var(--tw-content);height:calc(var(--spacing)*4)}.after\:h-5:after{content:var(--tw-content);height:calc(var(--spacing)*5)}.after\:w-4:after{content:var(--tw-content);width:calc(var(--spacing)*4)}.after\:w-5:after{content:var(--tw-content);width:calc(var(--spacing)*5)}.after\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.after\:border:after{content:var(--tw-content);border-style:var(--tw-border-style);border-width:1px}.after\:border-gray-300:after{content:var(--tw-content);border-color:var(--color-gray-300)}.after\:bg-white:after{content:var(--tw-content);background-color:var(--color-white)}.after\:transition-all:after{content:var(--tw-content);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.after\:transition-transform:after{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}.peer-checked\:after\:translate-x-5:is(:where(.peer):checked~*):after{content:var(--tw-content);--tw-translate-x:calc(var(--spacing)*5);translate:var(--tw-translate-x)var(--tw-translate-y)}.peer-checked\:after\:translate-x-full:is(:where(.peer):checked~*):after{content:var(--tw-content);--tw-translate-x:100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.peer-checked\:after\:border-white:is(:where(.peer):checked~*):after{content:var(--tw-content);border-color:var(--color-white)}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.focus-within\:border-bambu-green:focus-within{border-color:var(--color-bambu-green)}@media(hover:hover){.hover\:z-20:hover{z-index:20}.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:scale-110:hover{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:border-amber-500:hover{border-color:var(--color-amber-500)}.hover\:border-bambu-dark-tertiary\/80:hover{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-dark-tertiary\/80:hover{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.hover\:border-bambu-gray:hover{border-color:var(--color-bambu-gray)}.hover\:border-bambu-gray-dark:hover{border-color:var(--color-bambu-gray-dark)}.hover\:border-bambu-gray\/50:hover{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-gray\/50:hover{border-color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.hover\:border-bambu-green:hover,.hover\:border-bambu-green\/40:hover{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-green\/40:hover{border-color:color-mix(in oklab,var(--color-bambu-green)40%,transparent)}}.hover\:border-bambu-green\/50:hover{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-green\/50:hover{border-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.hover\:border-gray-400:hover{border-color:var(--color-gray-400)}.hover\:border-green-500\/50:hover{border-color:#00c75880}@supports (color:color-mix(in lab,red,red)){.hover\:border-green-500\/50:hover{border-color:color-mix(in oklab,var(--color-green-500)50%,transparent)}}.hover\:border-white:hover{border-color:var(--color-white)}.hover\:border-white\/40:hover{border-color:#fff6}@supports (color:color-mix(in lab,red,red)){.hover\:border-white\/40:hover{border-color:color-mix(in oklab,var(--color-white)40%,transparent)}}.hover\:\!bg-bambu-green\/80:hover{background-color:var(--color-bambu-green)!important}@supports (color:color-mix(in lab,red,red)){.hover\:\!bg-bambu-green\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-green)80%,transparent)!important}}.hover\:\!bg-green-500\/20:hover{background-color:#00c75833!important}@supports (color:color-mix(in lab,red,red)){.hover\:\!bg-green-500\/20:hover{background-color:color-mix(in oklab,var(--color-green-500)20%,transparent)!important}}.hover\:\!bg-yellow-500\/20:hover{background-color:#edb20033!important}@supports (color:color-mix(in lab,red,red)){.hover\:\!bg-yellow-500\/20:hover{background-color:color-mix(in oklab,var(--color-yellow-500)20%,transparent)!important}}.hover\:bg-amber-400:hover{background-color:var(--color-amber-400)}.hover\:bg-amber-500\/20:hover{background-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-500\/20:hover{background-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.hover\:bg-amber-500\/30:hover{background-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-500\/30:hover{background-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.hover\:bg-amber-700:hover{background-color:var(--color-amber-700)}.hover\:bg-amber-900\/50:hover{background-color:#7b330680}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-900\/50:hover{background-color:color-mix(in oklab,var(--color-amber-900)50%,transparent)}}.hover\:bg-bambu-dark:hover{background-color:var(--color-bambu-dark)}.hover\:bg-bambu-dark-secondary:hover,.hover\:bg-bambu-dark-secondary\/50:hover{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-secondary\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)50%,transparent)}}.hover\:bg-bambu-dark-secondary\/80:hover{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-secondary\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)80%,transparent)}}.hover\:bg-bambu-dark-tertiary:hover,.hover\:bg-bambu-dark-tertiary\/30:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/30:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.hover\:bg-bambu-dark-tertiary\/40:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/40:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)40%,transparent)}}.hover\:bg-bambu-dark-tertiary\/50:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.hover\:bg-bambu-dark-tertiary\/70:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/70:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)70%,transparent)}}.hover\:bg-bambu-dark-tertiary\/80:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.hover\:bg-bambu-dark\/50:hover{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.hover\:bg-bambu-dark\/80:hover{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-dark)80%,transparent)}}.hover\:bg-bambu-gray-dark:hover{background-color:var(--color-bambu-gray-dark)}.hover\:bg-bambu-green:hover{background-color:var(--color-bambu-green)}.hover\:bg-bambu-green-dark:hover{background-color:var(--color-bambu-green-dark)}.hover\:bg-bambu-green-light:hover{background-color:var(--color-bambu-green-light)}.hover\:bg-bambu-green\/10:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/10:hover{background-color:color-mix(in oklab,var(--color-bambu-green)10%,transparent)}}.hover\:bg-bambu-green\/20:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/20:hover{background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.hover\:bg-bambu-green\/30:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/30:hover{background-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.hover\:bg-bambu-green\/50:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.hover\:bg-bambu-green\/80:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-green)80%,transparent)}}.hover\:bg-bambu-green\/90:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/90:hover{background-color:color-mix(in oklab,var(--color-bambu-green)90%,transparent)}}.hover\:bg-black\/40:hover{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/40:hover{background-color:color-mix(in oklab,var(--color-black)40%,transparent)}}.hover\:bg-black\/70:hover{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/70:hover{background-color:color-mix(in oklab,var(--color-black)70%,transparent)}}.hover\:bg-black\/80:hover{background-color:#000c}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/80:hover{background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.hover\:bg-blue-500\/20:hover{background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-blue-500\/20:hover{background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.hover\:bg-blue-500\/30:hover{background-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-blue-500\/30:hover{background-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.hover\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-emerald-600:hover{background-color:var(--color-emerald-600)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.hover\:bg-green-500\/20:hover{background-color:#00c75833}@supports (color:color-mix(in lab,red,red)){.hover\:bg-green-500\/20:hover{background-color:color-mix(in oklab,var(--color-green-500)20%,transparent)}}.hover\:bg-green-600:hover{background-color:var(--color-green-600)}.hover\:bg-green-700:hover{background-color:var(--color-green-700)}.hover\:bg-indigo-500\/20:hover{background-color:#625fff33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-indigo-500\/20:hover{background-color:color-mix(in oklab,var(--color-indigo-500)20%,transparent)}}.hover\:bg-indigo-500\/30:hover{background-color:#625fff4d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-indigo-500\/30:hover{background-color:color-mix(in oklab,var(--color-indigo-500)30%,transparent)}}.hover\:bg-orange-400\/20:hover{background-color:#ff8b1a33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-orange-400\/20:hover{background-color:color-mix(in oklab,var(--color-orange-400)20%,transparent)}}.hover\:bg-orange-500\/20:hover{background-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.hover\:bg-orange-500\/20:hover{background-color:color-mix(in oklab,var(--color-orange-500)20%,transparent)}}.hover\:bg-purple-600\/90:hover{background-color:#9810fae6}@supports (color:color-mix(in lab,red,red)){.hover\:bg-purple-600\/90:hover{background-color:color-mix(in oklab,var(--color-purple-600)90%,transparent)}}.hover\:bg-red-200:hover{background-color:var(--color-red-200)}.hover\:bg-red-400\/10:hover{background-color:#ff65681a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-400\/10:hover{background-color:color-mix(in oklab,var(--color-red-400)10%,transparent)}}.hover\:bg-red-500\/10:hover{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/10:hover{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.hover\:bg-red-500\/20:hover{background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/20:hover{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.hover\:bg-red-500\/25:hover{background-color:#fb2c3640}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/25:hover{background-color:color-mix(in oklab,var(--color-red-500)25%,transparent)}}.hover\:bg-red-500\/30:hover{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/30:hover{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:bg-red-600\/30:hover{background-color:#e400144d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-600\/30:hover{background-color:color-mix(in oklab,var(--color-red-600)30%,transparent)}}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:bg-red-900\/50:hover{background-color:#82181a80}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-900\/50:hover{background-color:color-mix(in oklab,var(--color-red-900)50%,transparent)}}.hover\:bg-sky-500\/20:hover{background-color:#00a5ef33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sky-500\/20:hover{background-color:color-mix(in oklab,var(--color-sky-500)20%,transparent)}}.hover\:bg-white\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/5:hover{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.hover\:bg-white\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\:bg-white\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/20:hover{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.hover\:bg-white\/80:hover{background-color:#fffc}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/80:hover{background-color:color-mix(in oklab,var(--color-white)80%,transparent)}}.hover\:bg-yellow-500\/25:hover{background-color:#edb20040}@supports (color:color-mix(in lab,red,red)){.hover\:bg-yellow-500\/25:hover{background-color:color-mix(in oklab,var(--color-yellow-500)25%,transparent)}}.hover\:bg-yellow-500\/30:hover{background-color:#edb2004d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-yellow-500\/30:hover{background-color:color-mix(in oklab,var(--color-yellow-500)30%,transparent)}}.hover\:bg-yellow-600:hover{background-color:var(--color-yellow-600)}.hover\:bg-zinc-600:hover{background-color:var(--color-zinc-600)}.hover\:bg-zinc-700:hover{background-color:var(--color-zinc-700)}.hover\:bg-zinc-700\/50:hover{background-color:#3f3f4680}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-700\/50:hover{background-color:color-mix(in oklab,var(--color-zinc-700)50%,transparent)}}.hover\:bg-zinc-700\/60:hover{background-color:#3f3f4699}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-700\/60:hover{background-color:color-mix(in oklab,var(--color-zinc-700)60%,transparent)}}.hover\:bg-zinc-800:hover{background-color:var(--color-zinc-800)}.hover\:text-amber-300:hover{color:var(--color-amber-300)}.hover\:text-amber-800:hover{color:var(--color-amber-800)}.hover\:text-bambu-gray:hover{color:var(--color-bambu-gray)}.hover\:text-bambu-green:hover{color:var(--color-bambu-green)}.hover\:text-bambu-green-light:hover{color:var(--color-bambu-green-light)}.hover\:text-bambu-green\/70:hover{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:text-bambu-green\/70:hover{color:color-mix(in oklab,var(--color-bambu-green)70%,transparent)}}.hover\:text-bambu-green\/80:hover{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:text-bambu-green\/80:hover{color:color-mix(in oklab,var(--color-bambu-green)80%,transparent)}}.hover\:text-blue-300:hover{color:var(--color-blue-300)}.hover\:text-blue-400:hover{color:var(--color-blue-400)}.hover\:text-blue-600:hover{color:var(--color-blue-600)}.hover\:text-blue-800:hover{color:var(--color-blue-800)}.hover\:text-gray-600:hover{color:var(--color-gray-600)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-orange-300:hover{color:var(--color-orange-300)}.hover\:text-red-200:hover{color:var(--color-red-200)}.hover\:text-red-300:hover{color:var(--color-red-300)}.hover\:text-red-400:hover{color:var(--color-red-400)}.hover\:text-red-800:hover{color:var(--color-red-800)}.hover\:text-white:hover{color:var(--color-white)}.hover\:text-white\/60:hover{color:#fff9}@supports (color:color-mix(in lab,red,red)){.hover\:text-white\/60:hover{color:color-mix(in oklab,var(--color-white)60%,transparent)}}.hover\:text-white\/70:hover{color:#ffffffb3}@supports (color:color-mix(in lab,red,red)){.hover\:text-white\/70:hover{color:color-mix(in oklab,var(--color-white)70%,transparent)}}.hover\:text-white\/80:hover{color:#fffc}@supports (color:color-mix(in lab,red,red)){.hover\:text-white\/80:hover{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.hover\:text-yellow-400:hover{color:var(--color-yellow-400)}.hover\:text-zinc-200:hover{color:var(--color-zinc-200)}.hover\:text-zinc-300:hover{color:var(--color-zinc-300)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-70:hover{opacity:.7}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-xl:hover{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-bambu-green\/5:hover{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-bambu-green\/5:hover{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)5%,transparent)var(--tw-shadow-alpha),transparent)}}.hover\:shadow-bambu-green\/30:hover{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-bambu-green\/30:hover{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)30%,transparent)var(--tw-shadow-alpha),transparent)}}}.focus\:border-amber-500\/50:focus{border-color:#f99c0080}@supports (color:color-mix(in lab,red,red)){.focus\:border-amber-500\/50:focus{border-color:color-mix(in oklab,var(--color-amber-500)50%,transparent)}}.focus\:border-bambu-gray:focus{border-color:var(--color-bambu-gray)}.focus\:border-bambu-green:focus{border-color:var(--color-bambu-green)}.focus\:border-red-500:focus{border-color:var(--color-red-500)}.focus\:border-transparent:focus{border-color:#0000}.focus\:ring-0:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-bambu-gray:focus{--tw-ring-color:var(--color-bambu-gray)}.focus\:ring-bambu-green:focus,.focus\:ring-bambu-green\/50:focus{--tw-ring-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.focus\:ring-bambu-green\/50:focus{--tw-ring-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\:ring-red-500:focus{--tw-ring-color:var(--color-red-500)}.focus\:ring-offset-0:focus{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-bambu-dark:focus{--tw-ring-offset-color:var(--color-bambu-dark)}.focus\:ring-offset-bambu-dark-secondary:focus{--tw-ring-offset-color:var(--color-bambu-dark-secondary)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}.active\:cursor-grabbing:active{cursor:grabbing}.active\:bg-amber-500\/30:active{background-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.active\:bg-amber-500\/30:active{background-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.active\:opacity-50:active{opacity:.5}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:cursor-wait:disabled{cursor:wait}.disabled\:bg-gray-600:disabled{background-color:var(--color-gray-600)}.disabled\:bg-zinc-700:disabled{background-color:var(--color-zinc-700)}.disabled\:no-underline:disabled{text-decoration-line:none}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media(hover:hover){.disabled\:hover\:border-bambu-dark-tertiary:disabled:hover{border-color:var(--color-bambu-dark-tertiary)}.disabled\:hover\:bg-bambu-dark:disabled:hover{background-color:var(--color-bambu-dark)}.disabled\:hover\:bg-bambu-green:disabled:hover{background-color:var(--color-bambu-green)}}@media not all and (min-width:640px){.max-\[640px\]\:hidden{display:none}.max-\[640px\]\:w-full{width:100%}.max-\[640px\]\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.max-\[640px\]\:flex-col{flex-direction:column}.max-\[640px\]\:flex-wrap{flex-wrap:wrap}.max-\[640px\]\:items-center{align-items:center}.max-\[640px\]\:items-start{align-items:flex-start}}@media not all and (min-width:550px){.max-\[550px\]\:order-1{order:1}.max-\[550px\]\:order-2{order:2}.max-\[550px\]\:order-3{order:3}.max-\[550px\]\:order-4{order:4}.max-\[550px\]\:mt-1{margin-top:calc(var(--spacing)*1)}.max-\[550px\]\:w-full{width:100%}.max-\[550px\]\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.max-\[550px\]\:flex-col{flex-direction:column}.max-\[550px\]\:flex-wrap{flex-wrap:wrap}.max-\[550px\]\:items-center{align-items:center}.max-\[550px\]\:items-start{align-items:flex-start}.max-\[550px\]\:justify-end{justify-content:flex-end}.max-\[550px\]\:gap-3{gap:calc(var(--spacing)*3)}.max-\[550px\]\:self-start{align-self:flex-start}}@media(min-width:40rem){.sm\:mt-0{margin-top:calc(var(--spacing)*0)}.sm\:mt-2{margin-top:calc(var(--spacing)*2)}.sm\:mt-3{margin-top:calc(var(--spacing)*3)}.sm\:mr-1{margin-right:calc(var(--spacing)*1)}.sm\:mb-4{margin-bottom:calc(var(--spacing)*4)}.sm\:ml-\[68px\]{margin-left:68px}.sm\:ml-auto{margin-left:auto}.sm\:block{display:block}.sm\:flex{display:flex}.sm\:grid{display:grid}.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:h-2{height:calc(var(--spacing)*2)}.sm\:h-3{height:calc(var(--spacing)*3)}.sm\:h-3\.5{height:calc(var(--spacing)*3.5)}.sm\:h-4{height:calc(var(--spacing)*4)}.sm\:h-5{height:calc(var(--spacing)*5)}.sm\:h-6{height:calc(var(--spacing)*6)}.sm\:h-14{height:calc(var(--spacing)*14)}.sm\:w-3{width:calc(var(--spacing)*3)}.sm\:w-3\.5{width:calc(var(--spacing)*3.5)}.sm\:w-4{width:calc(var(--spacing)*4)}.sm\:w-5{width:calc(var(--spacing)*5)}.sm\:w-6{width:calc(var(--spacing)*6)}.sm\:w-14{width:calc(var(--spacing)*14)}.sm\:w-16{width:calc(var(--spacing)*16)}.sm\:w-40{width:calc(var(--spacing)*40)}.sm\:w-72{width:calc(var(--spacing)*72)}.sm\:w-auto{width:auto}.sm\:max-w-none{max-width:none}.sm\:max-w-xs{max-width:var(--container-xs)}.sm\:flex-1{flex:1}.sm\:flex-none{flex:none}.sm\:cursor-default{cursor:default}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}.sm\:gap-1{gap:calc(var(--spacing)*1)}.sm\:gap-1\.5{gap:calc(var(--spacing)*1.5)}.sm\:gap-2{gap:calc(var(--spacing)*2)}.sm\:gap-3{gap:calc(var(--spacing)*3)}.sm\:gap-4{gap:calc(var(--spacing)*4)}.sm\:gap-5{gap:calc(var(--spacing)*5)}.sm\:gap-6{gap:calc(var(--spacing)*6)}:where(.sm\:space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}.sm\:border-bambu-dark-tertiary{border-color:var(--color-bambu-dark-tertiary)}.sm\:p-1\.5{padding:calc(var(--spacing)*1.5)}.sm\:p-2{padding:calc(var(--spacing)*2)}.sm\:p-3{padding:calc(var(--spacing)*3)}.sm\:p-4{padding:calc(var(--spacing)*4)}.sm\:px-2{padding-inline:calc(var(--spacing)*2)}.sm\:px-3{padding-inline:calc(var(--spacing)*3)}.sm\:px-4{padding-inline:calc(var(--spacing)*4)}.sm\:text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.sm\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.sm\:text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}}@media(min-width:48rem){.md\:top-\[2px\]{top:2px}.md\:left-\[2px\]{left:2px}.md\:col-span-2{grid-column:span 2/span 2}.md\:mx-0{margin-inline:calc(var(--spacing)*0)}.md\:block{display:block}.md\:inline{display:inline}.md\:h-4{height:calc(var(--spacing)*4)}.md\:h-5{height:calc(var(--spacing)*5)}.md\:min-h-0{min-height:calc(var(--spacing)*0)}.md\:w-4{width:calc(var(--spacing)*4)}.md\:w-9{width:calc(var(--spacing)*9)}.md\:min-w-\[200px\]{min-width:200px}.md\:flex-1{flex:1}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:grid-cols-\[1fr_140px_auto\]{grid-template-columns:1fr 140px auto}.md\:flex-row{flex-direction:row}.md\:flex-wrap{flex-wrap:wrap}.md\:items-center{align-items:center}.md\:gap-4{gap:calc(var(--spacing)*4)}.md\:p-6{padding:calc(var(--spacing)*6)}.md\:p-8{padding:calc(var(--spacing)*8)}.md\:px-0{padding-inline:calc(var(--spacing)*0)}.md\:py-2{padding-block:calc(var(--spacing)*2)}.md\:pb-0{padding-bottom:calc(var(--spacing)*0)}}@media(min-width:64rem){.lg\:static{position:static}.lg\:sticky{position:sticky}.lg\:top-4{top:calc(var(--spacing)*4)}.lg\:top-6{top:calc(var(--spacing)*6)}.lg\:col-span-2{grid-column:span 2/span 2}.lg\:mb-0{margin-bottom:calc(var(--spacing)*0)}.lg\:-ml-px{margin-left:-1px}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:h-\[calc\(100vh-64px\)\]{height:calc(100vh - 64px)}.lg\:w-1\/2{width:50%}.lg\:w-1\/3{width:33.3333%}.lg\:w-2\/3{width:66.6667%}.lg\:w-48{width:calc(var(--spacing)*48)}.lg\:w-80{width:calc(var(--spacing)*80)}.lg\:w-\[480px\]{width:480px}.lg\:max-w-md{max-width:var(--container-md)}.lg\:max-w-sm{max-width:var(--container-sm)}.lg\:max-w-xl{max-width:var(--container-xl)}.lg\:flex-shrink-0{flex-shrink:0}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:grid-cols-\[1fr_20rem\]{grid-template-columns:1fr 20rem}.lg\:flex-col{flex-direction:column}.lg\:flex-row{flex-direction:row}.lg\:flex-nowrap{flex-wrap:nowrap}.lg\:justify-start{justify-content:flex-start}.lg\:gap-0{gap:calc(var(--spacing)*0)}.lg\:gap-6{gap:calc(var(--spacing)*6)}.lg\:gap-8{gap:calc(var(--spacing)*8)}.lg\:self-start{align-self:flex-start}.lg\:overflow-y-auto{overflow-y:auto}.lg\:border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.lg\:border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.lg\:border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}}@media(min-width:80rem){.xl\:inline{display:inline}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}@media(min-width:96rem){.\32xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}:where(.dark\:divide-gray-800:where(.dark,.dark *)>:not(:last-child)){border-color:var(--color-gray-800)}.dark\:border-amber-700:where(.dark,.dark *){border-color:var(--color-amber-700)}.dark\:border-amber-800:where(.dark,.dark *){border-color:var(--color-amber-800)}.dark\:border-bambu-dark-tertiary:where(.dark,.dark *),.dark\:border-bambu-dark-tertiary\/50:where(.dark,.dark *){border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.dark\:border-bambu-dark-tertiary\/50:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.dark\:border-bambu-green\/40:where(.dark,.dark *){border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:border-bambu-green\/40:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-bambu-green)40%,transparent)}}.dark\:border-gray-600:where(.dark,.dark *){border-color:var(--color-gray-600)}.dark\:border-gray-700:where(.dark,.dark *){border-color:var(--color-gray-700)}.dark\:border-red-500\/30:where(.dark,.dark *){border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.dark\:border-red-500\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.dark\:border-red-500\/40:where(.dark,.dark *){border-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.dark\:border-red-500\/40:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-red-500)40%,transparent)}}.dark\:bg-amber-500\/10:where(.dark,.dark *){background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.dark\:bg-amber-900\/20:where(.dark,.dark *){background-color:#7b330633}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-900\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-amber-900)20%,transparent)}}.dark\:bg-bambu-dark:where(.dark,.dark *){background-color:var(--color-bambu-dark)}.dark\:bg-bambu-dark-secondary:where(.dark,.dark *){background-color:var(--color-bambu-dark-secondary)}.dark\:bg-bambu-green\/20:where(.dark,.dark *){background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-bambu-green\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.dark\:bg-black\/80:where(.dark,.dark *){background-color:#000c}@supports (color:color-mix(in lab,red,red)){.dark\:bg-black\/80:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.dark\:bg-blue-500\/10:where(.dark,.dark *){background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.dark\:bg-blue-500\/20:where(.dark,.dark *){background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-500\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.dark\:bg-blue-900\/20:where(.dark,.dark *){background-color:#1c398e33}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-900\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-blue-900)20%,transparent)}}.dark\:bg-gray-700:where(.dark,.dark *){background-color:var(--color-gray-700)}.dark\:bg-gray-800:where(.dark,.dark *){background-color:var(--color-gray-800)}.dark\:bg-gray-800\/30:where(.dark,.dark *){background-color:#1e29394d}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-800\/30:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-gray-800)30%,transparent)}}.dark\:bg-gray-800\/40:where(.dark,.dark *){background-color:#1e293966}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-800\/40:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-gray-800)40%,transparent)}}.dark\:bg-gray-800\/50:where(.dark,.dark *){background-color:#1e293980}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-800\/50:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-gray-800)50%,transparent)}}.dark\:bg-gray-900:where(.dark,.dark *){background-color:var(--color-gray-900)}.dark\:bg-red-500\/10:where(.dark,.dark *){background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.dark\:bg-red-500\/20:where(.dark,.dark *){background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-500\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.dark\:text-amber-100:where(.dark,.dark *){color:var(--color-amber-100)}.dark\:text-amber-200:where(.dark,.dark *){color:var(--color-amber-200)}.dark\:text-amber-300:where(.dark,.dark *){color:var(--color-amber-300)}.dark\:text-amber-400:where(.dark,.dark *){color:var(--color-amber-400)}.dark\:text-bambu-gray:where(.dark,.dark *),.dark\:text-bambu-gray\/30:where(.dark,.dark *){color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-gray\/30:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.dark\:text-bambu-gray\/50:where(.dark,.dark *){color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-gray\/50:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.dark\:text-bambu-green:where(.dark,.dark *),.dark\:text-bambu-green\/60:where(.dark,.dark *){color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-green\/60:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-green)60%,transparent)}}.dark\:text-blue-200:where(.dark,.dark *){color:var(--color-blue-200)}.dark\:text-blue-200\/80:where(.dark,.dark *){color:#bedbffcc}@supports (color:color-mix(in lab,red,red)){.dark\:text-blue-200\/80:where(.dark,.dark *){color:color-mix(in oklab,var(--color-blue-200)80%,transparent)}}.dark\:text-blue-300:where(.dark,.dark *){color:var(--color-blue-300)}.dark\:text-blue-300\/60:where(.dark,.dark *){color:#90c5ff99}@supports (color:color-mix(in lab,red,red)){.dark\:text-blue-300\/60:where(.dark,.dark *){color:color-mix(in oklab,var(--color-blue-300)60%,transparent)}}.dark\:text-blue-400:where(.dark,.dark *){color:var(--color-blue-400)}.dark\:text-emerald-300:where(.dark,.dark *){color:var(--color-emerald-300)}.dark\:text-emerald-400:where(.dark,.dark *){color:var(--color-emerald-400)}.dark\:text-gray-100:where(.dark,.dark *){color:var(--color-gray-100)}.dark\:text-gray-300:where(.dark,.dark *){color:var(--color-gray-300)}.dark\:text-gray-400:where(.dark,.dark *){color:var(--color-gray-400)}.dark\:text-gray-500:where(.dark,.dark *){color:var(--color-gray-500)}.dark\:text-gray-600:where(.dark,.dark *){color:var(--color-gray-600)}.dark\:text-green-400:where(.dark,.dark *){color:var(--color-green-400)}.dark\:text-orange-200:where(.dark,.dark *){color:var(--color-orange-200)}.dark\:text-orange-400:where(.dark,.dark *){color:var(--color-orange-400)}.dark\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.dark\:text-red-400\/70:where(.dark,.dark *){color:#ff6568b3}@supports (color:color-mix(in lab,red,red)){.dark\:text-red-400\/70:where(.dark,.dark *){color:color-mix(in oklab,var(--color-red-400)70%,transparent)}}.dark\:text-white:where(.dark,.dark *){color:var(--color-white)}.dark\:text-yellow-200:where(.dark,.dark *){color:var(--color-yellow-200)}.dark\:text-yellow-200\/70:where(.dark,.dark *){color:#fff085b3}@supports (color:color-mix(in lab,red,red)){.dark\:text-yellow-200\/70:where(.dark,.dark *){color:color-mix(in oklab,var(--color-yellow-200)70%,transparent)}}@media(hover:hover){.dark\:hover\:border-gray-500:where(.dark,.dark *):hover{border-color:var(--color-gray-500)}.dark\:hover\:bg-bambu-dark-tertiary:where(.dark,.dark *):hover{background-color:var(--color-bambu-dark-tertiary)}.dark\:hover\:bg-bambu-dark\/50:where(.dark,.dark *):hover{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-bambu-dark\/50:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.dark\:hover\:bg-gray-600:where(.dark,.dark *):hover{background-color:var(--color-gray-600)}.dark\:hover\:bg-gray-800\/50:where(.dark,.dark *):hover{background-color:#1e293980}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-gray-800\/50:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-gray-800)50%,transparent)}}.dark\:hover\:bg-red-500\/30:where(.dark,.dark *):hover{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-red-500\/30:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.dark\:hover\:text-amber-200:where(.dark,.dark *):hover{color:var(--color-amber-200)}.dark\:hover\:text-blue-300:where(.dark,.dark *):hover{color:var(--color-blue-300)}.dark\:hover\:text-gray-200:where(.dark,.dark *):hover{color:var(--color-gray-200)}.dark\:hover\:text-gray-300:where(.dark,.dark *):hover{color:var(--color-gray-300)}.dark\:hover\:text-red-300:where(.dark,.dark *):hover{color:var(--color-red-300)}.dark\:hover\:text-white:where(.dark,.dark *):hover{color:var(--color-white)}}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{appearance:none}.\[\&\:\:-webkit-outer-spin-button\]\:appearance-none::-webkit-outer-spin-button{appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:h-3::-webkit-slider-thumb{height:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:w-3::-webkit-slider-thumb{width:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:cursor-pointer::-webkit-slider-thumb{cursor:pointer}.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb{appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb{border-radius:3.40282e38px}.\[\&\:\:-webkit-slider-thumb\]\:bg-bambu-green::-webkit-slider-thumb{background-color:var(--color-bambu-green)}.\[\&\>\*\]\:shrink-0>*{flex-shrink:0}}html{font-size:14.4px}:root{--accent:#00ae42;--accent-light:#00c64d;--accent-dark:#009438;--status-ok:#22c55e;--status-error:#ef4444;--status-warning:#f59e0b;--bg-primary:#f5f5f5;--bg-secondary:#fff;--bg-tertiary:#e5e5e5;--text-primary:#1a1a1a;--text-secondary:#4a4a4a;--text-muted:#6b6b6b;--text-tertiary:gray;--border-color:#d4d4d4;--card-shadow:0 2px 8px #00000014;--glow-color:transparent;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,system-ui,sans-serif;font-weight:400;line-height:1.5}.dark{--bg-primary:#1a1a1a;--bg-secondary:#2d2d2d;--bg-tertiary:#3d3d3d;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:gray;--text-tertiary:#4a4a4a;--border-color:#3d3d3d;--card-shadow:0 4px 16px #0006}.bg-warm{--bg-primary:#faf8f5;--bg-secondary:#fffefa;--bg-tertiary:#e8e4dd;--text-primary:#2d2a26;--text-secondary:#5c5750;--text-muted:#7a756c;--text-tertiary:#9a9590;--border-color:#d8d4cc}.bg-cool{--bg-primary:#f0f4f8;--bg-secondary:#fff;--bg-tertiary:#dce4ec;--text-primary:#1a2530;--text-secondary:#4a5568;--text-muted:#6b7a8a;--text-tertiary:#8a9aaa;--border-color:#c8d4e0}.dark.bg-neutral{--bg-primary:#1a1a1a;--bg-secondary:#2d2d2d;--bg-tertiary:#3d3d3d;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:gray;--text-tertiary:#4a4a4a;--border-color:#3d3d3d}.dark.bg-warm{--bg-primary:#1c1a18;--bg-secondary:#2e2a26;--bg-tertiary:#3e3a36;--text-primary:#f5f0ea;--text-secondary:#b0a898;--text-muted:#8a8278;--text-tertiary:#5a5248;--border-color:#3e3a36}.dark.bg-cool{--bg-primary:#181c20;--bg-secondary:#262c32;--bg-tertiary:#363e46;--text-primary:#f0f4f8;--text-secondary:#98a8b8;--text-muted:#788898;--text-tertiary:#4a5a6a;--border-color:#363e46}.dark.bg-oled{--bg-primary:#000;--bg-secondary:#141414;--bg-tertiary:#1f1f1f;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:#707070;--text-tertiary:#404040;--border-color:#2a2a2a}.dark.bg-slate{--bg-primary:#0f172a;--bg-secondary:#1e293b;--bg-tertiary:#334155;--text-primary:#f1f5f9;--text-secondary:#94a3b8;--text-muted:#64748b;--text-tertiary:#475569;--border-color:#334155}.dark.bg-forest{--bg-primary:#121a16;--bg-secondary:#1c2a22;--bg-tertiary:#2a3d30;--text-primary:#e8f5ec;--text-secondary:#8aa894;--text-muted:#6a8874;--text-tertiary:#4a6854;--border-color:#2a3d30}.printer-control-buttons-container{container-type:inline-size}@container (max-width:220px){.printer-control-buttons{flex-direction:column;align-items:stretch}.printer-control-buttons>button{width:100%}}.style-glow{--card-shadow:0 2px 8px #00000014,0 0 25px var(--accent)}@supports (color:color-mix(in lab,red,red)){.style-glow{--card-shadow:0 2px 8px #00000014,0 0 25px color-mix(in srgb,var(--accent)12%,transparent)}}.dark.style-glow{--card-shadow:0 4px 20px #00000080,0 0 40px var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark.style-glow{--card-shadow:0 4px 20px #00000080,0 0 40px color-mix(in srgb,var(--accent)15%,transparent)}}.style-vibrant{--card-shadow:0 8px 30px #00000026,0 2px 8px #0000001a}.dark.style-vibrant{--card-shadow:0 10px 40px #0009,0 4px 12px #0006}.accent-green{--accent:#00ae42;--accent-light:#00c64d;--accent-dark:#009438}.accent-teal{--accent:#14b8a6;--accent-light:#2dd4bf;--accent-dark:#0d9488}.accent-blue{--accent:#3b82f6;--accent-light:#60a5fa;--accent-dark:#2563eb}.accent-orange{--accent:#f97316;--accent-light:#fb923c;--accent-dark:#ea580c}.accent-purple{--accent:#8b5cf6;--accent-light:#a78bfa;--accent-dark:#7c3aed}.accent-red{--accent:#ef4444;--accent-light:#f87171;--accent-dark:#dc2626}body{background-color:var(--bg-primary);color:var(--text-primary);min-height:100vh;margin:0;transition:background-color .2s,color .2s}#root{min-height:100vh}.text-white{color:var(--text-primary)}.bg-bambu-dark,.bg-bambu-dark-secondary,.bg-bambu-dark-tertiary,.border-bambu-dark-tertiary{transition:background-color .2s,border-color .2s}@keyframes slide-in{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}.animate-slide-in{animation:.2s ease-out slide-in}.icon-theme{opacity:.5}.dark .icon-theme{filter:invert();opacity:.4}.icon-green{filter:invert(48%)sepia(89%)saturate(459%)hue-rotate(93deg)brightness(95%)contrast(92%);opacity:1}.icon-heating{filter:invert(50%)sepia()saturate(1000%)hue-rotate(360deg)brightness()contrast();opacity:1}.dark .jogpad-theme{filter:brightness(.35)contrast(1.2)}.ams-empty-slot{background:repeating-linear-gradient(45deg,#444,#444 2px,#222 2px 4px)}.dark .ams-empty-slot{background:repeating-linear-gradient(45deg,#555,#555 2px,#333 2px 4px)}.touch-manipulation{touch-action:manipulation}.safe-area-bottom{padding-bottom:env(safe-area-inset-bottom,0)}.safe-area-top{padding-top:env(safe-area-inset-top,0)}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}@keyframes slide-in-left{0%{transform:translate(-100%)}to{transform:translate(0)}}.animate-slide-in-left{animation:.3s ease-out slide-in-left}@keyframes spoolbuddy-optimized-ping{0%{opacity:.8;transform:scale(.8)}80%,to{opacity:0;transform:scale(2.2)}}.spoolbuddy-optimized-ping{will-change:auto;contain:layout;animation:3.5s cubic-bezier(0,0,.2,1) infinite spoolbuddy-optimized-ping}.spoolbuddy-spool-glow{will-change:auto;transform:scale(2)}@media(prefers-reduced-motion:reduce){.spoolbuddy-optimized-ping{opacity:.25;animation:none;transform:scale(1.2)}.spoolbuddy-spool-glow{transition:none}}@keyframes slide-down{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.animate-slide-down{animation:.25s ease-out slide-down}.card-shadow{box-shadow:var(--card-shadow)}[data-spoolbuddy-kiosk] .fixed .relative.max-w-2xl{flex-direction:column;height:90vh;max-height:90vh;display:flex}[data-spoolbuddy-kiosk] .fixed .relative.max-w-2xl>div:first-child,[data-spoolbuddy-kiosk] .fixed .relative.max-w-2xl>div:last-child{flex-shrink:0}[data-spoolbuddy-kiosk] .fixed .relative.max-w-2xl>div:nth-child(2){flex:auto;min-height:0;overflow-y:auto}[data-spoolbuddy-kiosk] .fixed .relative.max-w-2xl .max-h-96{max-height:none}.calendar-scroll{scrollbar-width:thin;scrollbar-color:var(--text-muted)transparent}@supports (color:color-mix(in lab,red,red)){.calendar-scroll{scrollbar-color:color-mix(in srgb,var(--text-muted)60%,transparent)transparent}}.calendar-scroll::-webkit-scrollbar{width:8px}.calendar-scroll::-webkit-scrollbar-track{background:0 0}.calendar-scroll::-webkit-scrollbar-thumb{background-color:var(--text-muted)}@supports (color:color-mix(in lab,red,red)){.calendar-scroll::-webkit-scrollbar-thumb{background-color:color-mix(in srgb,var(--text-muted)60%,transparent)}}.calendar-scroll::-webkit-scrollbar-thumb{border:2px solid var(--bg-secondary);border-radius:999px}@supports (color:color-mix(in lab,red,red)){.calendar-scroll::-webkit-scrollbar-thumb{border:2px solid color-mix(in srgb,var(--bg-secondary)70%,transparent)}}.calendar-scroll::-webkit-scrollbar-thumb:hover{background-color:var(--text-muted)}@supports (color:color-mix(in lab,red,red)){.calendar-scroll::-webkit-scrollbar-thumb:hover{background-color:color-mix(in srgb,var(--text-muted)80%,transparent)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes pulse{50%{opacity:.5}}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}}.hg-theme-default{background-color:#ececec;border-radius:5px;box-sizing:border-box;font-family:HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif;overflow:hidden;padding:5px;touch-action:manipulation;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.hg-theme-default .hg-button span,.hg-theme-default .hg-button span svg{pointer-events:none}.hg-theme-default button.hg-button{border-width:0;font-size:inherit}.hg-theme-default .hg-button{display:inline-block;flex-grow:1}.hg-theme-default .hg-row{display:flex}.hg-theme-default .hg-row:not(:last-child){margin-bottom:5px}.hg-theme-default .hg-row .hg-button-container,.hg-theme-default .hg-row .hg-button:not(:last-child){margin-right:5px}.hg-theme-default .hg-row>div:last-child{margin-right:0}.hg-theme-default .hg-row .hg-button-container{display:flex}.hg-theme-default .hg-button{align-items:center;background:#fff;border-bottom:1px solid #b5b5b5;border-radius:5px;box-shadow:0 0 3px -1px #0000004d;box-sizing:border-box;cursor:pointer;display:flex;height:40px;justify-content:center;padding:5px;-webkit-tap-highlight-color:rgba(0,0,0,0)}.hg-theme-default .hg-button.hg-standardBtn{width:20px}.hg-theme-default .hg-button.hg-activeButton{background:#efefef}.hg-theme-default.hg-layout-numeric .hg-button{align-items:center;display:flex;height:60px;justify-content:center;width:33.3%}.hg-theme-default .hg-button.hg-button-numpadadd,.hg-theme-default .hg-button.hg-button-numpadenter{height:85px}.hg-theme-default .hg-button.hg-button-numpad0{width:105px}.hg-theme-default .hg-button.hg-button-com{max-width:85px}.hg-theme-default .hg-button.hg-standardBtn.hg-button-at{max-width:45px}.hg-theme-default .hg-button.hg-selectedButton{background:#05194687;color:#fff}.hg-theme-default .hg-button.hg-standardBtn[data-skbtn=".com"]{max-width:82px}.hg-theme-default .hg-button.hg-standardBtn[data-skbtn="@"]{max-width:60px}.hg-candidate-box{background:#ececec;border-bottom:2px solid #b5b5b5;border-radius:5px;display:inline-flex;margin-top:-10px;position:absolute;transform:translateY(-100%);-webkit-user-select:none;-moz-user-select:none;user-select:none}ul.hg-candidate-box-list{display:flex;flex:1;list-style:none;margin:0;padding:0}li.hg-candidate-box-list-item{align-items:center;display:flex;height:40px;justify-content:center;width:40px}li.hg-candidate-box-list-item:hover{background:#00000008;cursor:pointer}li.hg-candidate-box-list-item:active{background:#0000001a}.hg-candidate-box-prev:before{content:"◄"}.hg-candidate-box-next:before{content:"►"}.hg-candidate-box-next,.hg-candidate-box-prev{align-items:center;color:#969696;cursor:pointer;display:flex;padding:0 10px}.hg-candidate-box-next{border-bottom-right-radius:5px;border-top-right-radius:5px}.hg-candidate-box-prev{border-bottom-left-radius:5px;border-top-left-radius:5px}.hg-candidate-box-btn-active{color:#444}.simple-keyboard.vkb-theme{background:#1a1a1a;border-top:1px solid #333;padding:8px 4px;font-family:inherit}.simple-keyboard.vkb-theme .hg-row{display:flex!important;flex-direction:row!important;flex-wrap:nowrap!important;gap:4px;margin-bottom:4px}.simple-keyboard.vkb-theme .hg-row:last-child{margin-bottom:0}.simple-keyboard.vkb-theme .hg-button{display:inline-flex!important;align-items:center;justify-content:center;flex-grow:1;flex-shrink:1;flex-basis:auto;background:#2d2d2d;color:#e0e0e0;border:none;border-radius:6px;height:44px;font-size:16px;font-weight:500;box-shadow:0 1px 2px #0000004d;transition:background .1s;cursor:pointer;padding:0 2px;min-width:0}.simple-keyboard.vkb-theme .hg-button:active{background:#00ae42;color:#fff}.simple-keyboard.vkb-theme .hg-button-bksp,.simple-keyboard.vkb-theme .hg-button-shift,.simple-keyboard.vkb-theme .hg-button-lock{background:#3a3a3a;color:#aaa;flex-grow:1.5}.simple-keyboard.vkb-theme .hg-button-close{background:#3a3a3a;color:#aaa;flex-grow:2;font-weight:600}.simple-keyboard.vkb-theme .hg-button-close:active{background:#555}.simple-keyboard.vkb-theme .hg-button-space{flex-grow:7}.simple-keyboard.vkb-theme .hg-activeButton{background:#00ae42;color:#fff} diff --git a/static/assets/index-CLI--QzS.css b/static/assets/index-CLI--QzS.css new file mode 100644 index 000000000..b06dc1118 --- /dev/null +++ b/static/assets/index-CLI--QzS.css @@ -0,0 +1 @@ +@import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";@layer properties,theme,base,components,utilities;@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-red-950:oklch(25.8% .092 26.042);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-300:oklch(83.7% .128 66.29);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-300:oklch(90.5% .182 98.111);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-lime-400:oklch(84.1% .238 128.85);--color-lime-500:oklch(76.8% .233 130.85);--color-green-100:oklch(96.2% .044 156.743);--color-green-200:oklch(92.5% .084 155.995);--color-green-300:oklch(87.1% .15 154.449);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-green-800:oklch(44.8% .119 151.328);--color-green-900:oklch(39.3% .095 152.535);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-teal-400:oklch(77.7% .152 181.912);--color-teal-500:oklch(70.4% .14 182.503);--color-cyan-300:oklch(86.5% .127 207.078);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-cyan-600:oklch(60.9% .126 221.723);--color-sky-400:oklch(74.6% .16 232.661);--color-sky-500:oklch(68.5% .169 237.323);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-indigo-300:oklch(78.5% .115 274.713);--color-indigo-400:oklch(67.3% .182 276.935);--color-indigo-500:oklch(58.5% .233 277.117);--color-violet-500:oklch(60.6% .25 292.717);--color-purple-300:oklch(82.7% .119 306.383);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-fuchsia-500:oklch(66.7% .295 322.15);--color-rose-300:oklch(81% .117 11.638);--color-rose-400:oklch(71.2% .194 13.428);--color-rose-500:oklch(64.5% .246 16.439);--color-rose-600:oklch(58.6% .253 17.585);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-500:oklch(55.4% .046 257.417);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-200:oklch(92% .004 286.32);--color-zinc-300:oklch(87.1% .006 286.286);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-500:oklch(55.2% .016 285.938);--color-zinc-600:oklch(44.2% .017 285.786);--color-zinc-700:oklch(37% .013 285.805);--color-zinc-800:oklch(27.4% .006 286.033);--color-zinc-900:oklch(21% .006 285.885);--color-black:#000;--color-white:#fff;--spacing:.25rem;--breakpoint-2xl:96rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--drop-shadow-md:0 3px 3px #0000001f;--drop-shadow-lg:0 4px 4px #00000026;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-ping:ping 1s cubic-bezier(0,0,.2,1)infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-sm:8px;--blur-2xl:40px;--aspect-video:16/9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bambu-green:var(--accent);--color-bambu-green-light:var(--accent-light);--color-bambu-green-dark:var(--accent-dark);--color-status-ok:var(--status-ok);--color-status-error:var(--status-error);--color-status-warning:var(--status-warning);--color-bambu-dark:var(--bg-primary);--color-bambu-dark-secondary:var(--bg-secondary);--color-bambu-dark-tertiary:var(--bg-tertiary);--color-bambu-gray:var(--text-muted);--color-bambu-gray-light:var(--text-secondary);--color-bambu-gray-dark:var(--text-tertiary)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.inset-2{inset:calc(var(--spacing)*2)}.inset-x-0{inset-inline:calc(var(--spacing)*0)}.inset-y-0{inset-block:calc(var(--spacing)*0)}.-top-0\.5{top:calc(var(--spacing)*-.5)}.-top-1{top:calc(var(--spacing)*-1)}.-top-1\.5{top:calc(var(--spacing)*-1.5)}.top-0{top:calc(var(--spacing)*0)}.top-0\.5{top:calc(var(--spacing)*.5)}.top-1{top:calc(var(--spacing)*1)}.top-1\.5{top:calc(var(--spacing)*1.5)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-2\.5{top:calc(var(--spacing)*2.5)}.top-3{top:calc(var(--spacing)*3)}.top-4{top:calc(var(--spacing)*4)}.top-8{top:calc(var(--spacing)*8)}.top-\[2px\]{top:2px}.top-\[3px\]{top:3px}.top-\[52px\]{top:52px}.top-full{top:100%}.-right-0\.5{right:calc(var(--spacing)*-.5)}.-right-1{right:calc(var(--spacing)*-1)}.-right-1\.5{right:calc(var(--spacing)*-1.5)}.-right-2{right:calc(var(--spacing)*-2)}.right-0{right:calc(var(--spacing)*0)}.right-0\.5{right:calc(var(--spacing)*.5)}.right-1{right:calc(var(--spacing)*1)}.right-1\.5{right:calc(var(--spacing)*1.5)}.right-2{right:calc(var(--spacing)*2)}.right-3{right:calc(var(--spacing)*3)}.right-4{right:calc(var(--spacing)*4)}.right-6{right:calc(var(--spacing)*6)}.right-12{right:calc(var(--spacing)*12)}.right-20{right:calc(var(--spacing)*20)}.right-\[5\.5rem\]{right:5.5rem}.right-full{right:100%}.-bottom-0\.5{bottom:calc(var(--spacing)*-.5)}.-bottom-1{bottom:calc(var(--spacing)*-1)}.-bottom-2{bottom:calc(var(--spacing)*-2)}.-bottom-7{bottom:calc(var(--spacing)*-7)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-0\.5{bottom:calc(var(--spacing)*.5)}.bottom-1{bottom:calc(var(--spacing)*1)}.bottom-2{bottom:calc(var(--spacing)*2)}.bottom-3{bottom:calc(var(--spacing)*3)}.bottom-4{bottom:calc(var(--spacing)*4)}.bottom-6{bottom:calc(var(--spacing)*6)}.bottom-8{bottom:calc(var(--spacing)*8)}.bottom-20{bottom:calc(var(--spacing)*20)}.bottom-full{bottom:100%}.-left-2{left:calc(var(--spacing)*-2)}.-left-\[9999px\]{left:-9999px}.left-0{left:calc(var(--spacing)*0)}.left-0\.5{left:calc(var(--spacing)*.5)}.left-1{left:calc(var(--spacing)*1)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-2\.5{left:calc(var(--spacing)*2.5)}.left-3{left:calc(var(--spacing)*3)}.left-4{left:calc(var(--spacing)*4)}.left-10{left:calc(var(--spacing)*10)}.left-12{left:calc(var(--spacing)*12)}.left-\[2px\]{left:2px}.left-\[3px\]{left:3px}.left-full{left:100%}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-60{z-index:60}.z-\[1\]{z-index:1}.z-\[60\]{z-index:60}.z-\[100\]{z-index:100}.z-\[101\]{z-index:101}.z-\[110\]{z-index:110}.z-\[9998\]{z-index:9998}.z-\[9999\]{z-index:9999}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.col-span-3{grid-column:span 3/span 3}.col-span-4{grid-column:span 4/span 4}.col-span-full{grid-column:1/-1}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.-m-4{margin:calc(var(--spacing)*-4)}.-mx-2{margin-inline:calc(var(--spacing)*-2)}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-1\.5{margin-inline:calc(var(--spacing)*1.5)}.mx-2{margin-inline:calc(var(--spacing)*2)}.mx-4{margin-inline:calc(var(--spacing)*4)}.mx-5{margin-inline:calc(var(--spacing)*5)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-2{margin-block:calc(var(--spacing)*2)}.my-8{margin-block:calc(var(--spacing)*8)}.my-auto{margin-block:auto}.-mt-0\.5{margin-top:calc(var(--spacing)*-.5)}.-mt-2{margin-top:calc(var(--spacing)*-2)}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-14{margin-top:calc(var(--spacing)*14)}.mt-auto{margin-top:auto}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-1\.5{margin-right:calc(var(--spacing)*1.5)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-3{margin-right:calc(var(--spacing)*3)}.mr-4{margin-right:calc(var(--spacing)*4)}.mr-auto{margin-right:auto}.-mb-px{margin-bottom:-1px}.mb-0{margin-bottom:calc(var(--spacing)*0)}.mb-0\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-2\.5{margin-bottom:calc(var(--spacing)*2.5)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.-ml-1{margin-left:calc(var(--spacing)*-1)}.-ml-2{margin-left:calc(var(--spacing)*-2)}.ml-0\.5{margin-left:calc(var(--spacing)*.5)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-6{margin-left:calc(var(--spacing)*6)}.ml-7{margin-left:calc(var(--spacing)*7)}.ml-16{margin-left:calc(var(--spacing)*16)}.ml-64{margin-left:calc(var(--spacing)*64)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.table-row{display:table-row}.aspect-square{aspect-ratio:1}.aspect-video{aspect-ratio:var(--aspect-video)}.\!h-8{height:calc(var(--spacing)*8)!important}.h-0{height:calc(var(--spacing)*0)}.h-0\.5{height:calc(var(--spacing)*.5)}.h-1{height:calc(var(--spacing)*1)}.h-1\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-4\.5{height:calc(var(--spacing)*4.5)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-14{height:calc(var(--spacing)*14)}.h-16{height:calc(var(--spacing)*16)}.h-20{height:calc(var(--spacing)*20)}.h-24{height:calc(var(--spacing)*24)}.h-32{height:calc(var(--spacing)*32)}.h-48{height:calc(var(--spacing)*48)}.h-64{height:calc(var(--spacing)*64)}.h-80{height:calc(var(--spacing)*80)}.h-96{height:calc(var(--spacing)*96)}.h-\[18px\]{height:18px}.h-\[38px\]{height:38px}.h-\[40px\]{height:40px}.h-\[48px\]{height:48px}.h-\[80vh\]{height:80vh}.h-\[160px\]{height:160px}.h-\[300px\]{height:300px}.h-\[calc\(100\%-40px\)\]{height:calc(100% - 40px)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-40{max-height:calc(var(--spacing)*40)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-56{max-height:calc(var(--spacing)*56)}.max-h-60{max-height:calc(var(--spacing)*60)}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-80{max-height:calc(var(--spacing)*80)}.max-h-96{max-height:calc(var(--spacing)*96)}.max-h-\[3\.75rem\]{max-height:3.75rem}.max-h-\[28rem\]{max-height:28rem}.max-h-\[50vh\]{max-height:50vh}.max-h-\[60vh\]{max-height:60vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[300px\]{max-height:300px}.max-h-\[400px\]{max-height:400px}.max-h-\[500px\]{max-height:500px}.max-h-\[600px\]{max-height:600px}.max-h-\[calc\(90vh-80px\)\]{max-height:calc(90vh - 80px)}.max-h-\[calc\(100vh-2rem\)\]{max-height:calc(100vh - 2rem)}.max-h-\[calc\(100vh-320px\)\]{max-height:calc(100vh - 320px)}.max-h-full{max-height:100%}.\!min-h-8{min-height:calc(var(--spacing)*8)!important}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\[8rem\]{min-height:8rem}.min-h-\[36px\]{min-height:36px}.min-h-\[40px\]{min-height:40px}.min-h-\[44px\]{min-height:44px}.min-h-\[48px\]{min-height:48px}.min-h-\[80px\]{min-height:80px}.min-h-\[120px\]{min-height:120px}.min-h-\[300px\]{min-height:300px}.min-h-\[400px\]{min-height:400px}.min-h-\[calc\(100vh-64px\)\]{min-height:calc(100vh - 64px)}.min-h-screen{min-height:100vh}.w-0{width:calc(var(--spacing)*0)}.w-0\.5{width:calc(var(--spacing)*.5)}.w-1{width:calc(var(--spacing)*1)}.w-1\.5{width:calc(var(--spacing)*1.5)}.w-1\/2{width:50%}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-4\.5{width:calc(var(--spacing)*4.5)}.w-5{width:calc(var(--spacing)*5)}.w-5\/12{width:41.6667%}.w-6{width:calc(var(--spacing)*6)}.w-7{width:calc(var(--spacing)*7)}.w-7\/12{width:58.3333%}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-12{width:calc(var(--spacing)*12)}.w-14{width:calc(var(--spacing)*14)}.w-16{width:calc(var(--spacing)*16)}.w-20{width:calc(var(--spacing)*20)}.w-24{width:calc(var(--spacing)*24)}.w-32{width:calc(var(--spacing)*32)}.w-36{width:calc(var(--spacing)*36)}.w-40{width:calc(var(--spacing)*40)}.w-44{width:calc(var(--spacing)*44)}.w-48{width:calc(var(--spacing)*48)}.w-52{width:calc(var(--spacing)*52)}.w-56{width:calc(var(--spacing)*56)}.w-64{width:calc(var(--spacing)*64)}.w-72{width:calc(var(--spacing)*72)}.w-96{width:calc(var(--spacing)*96)}.w-\[240px\]{width:240px}.w-\[340px\]{width:340px}.w-\[420px\]{width:420px}.w-\[560px\]{width:560px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-max{width:max-content}.w-px{width:1px}.w-screen{width:100vw}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-32{max-width:calc(var(--spacing)*32)}.max-w-\[40\%\]{max-width:40%}.max-w-\[50\%\]{max-width:50%}.max-w-\[80px\]{max-width:80px}.max-w-\[90vw\]{max-width:90vw}.max-w-\[100px\]{max-width:100px}.max-w-\[120px\]{max-width:120px}.max-w-\[150px\]{max-width:150px}.max-w-\[160px\]{max-width:160px}.max-w-\[200px\]{max-width:200px}.max-w-\[220px\]{max-width:220px}.max-w-\[280px\]{max-width:280px}.max-w-\[600px\]{max-width:600px}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-screen-2xl{max-width:var(--breakpoint-2xl)}.max-w-sm{max-width:var(--container-sm)}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-28{min-width:calc(var(--spacing)*28)}.min-w-40{min-width:calc(var(--spacing)*40)}.min-w-48{min-width:calc(var(--spacing)*48)}.min-w-\[16px\]{min-width:16px}.min-w-\[18px\]{min-width:18px}.min-w-\[32px\]{min-width:32px}.min-w-\[40px\]{min-width:40px}.min-w-\[48px\]{min-width:48px}.min-w-\[50px\]{min-width:50px}.min-w-\[80px\]{min-width:80px}.min-w-\[100px\]{min-width:100px}.min-w-\[120px\]{min-width:120px}.min-w-\[130px\]{min-width:130px}.min-w-\[140px\]{min-width:140px}.min-w-\[150px\]{min-width:150px}.min-w-\[160px\]{min-width:160px}.min-w-\[180px\]{min-width:180px}.min-w-\[200px\]{min-width:200px}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-\[2_1_190px\]{flex:2 190px}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing)*.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-1{--tw-translate-x:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-3\.5{--tw-translate-x:calc(var(--spacing)*3.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-4{--tw-translate-x:calc(var(--spacing)*4);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing)*5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-6{--tw-translate-x:calc(var(--spacing)*6);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-105{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-110{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-\[1\.02\]{scale:1.02}.-rotate-90{rotate:-90deg}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-ping{animation:var(--animate-ping)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-ew-resize{cursor:ew-resize}.cursor-grab{cursor:grab}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-row-resize{cursor:row-resize}.cursor-se-resize{cursor:se-resize}.touch-manipulation{touch-action:manipulation}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.\[appearance\:textfield\]{appearance:textfield}.appearance-none{appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.grid-cols-\[auto_1fr_100px_100px_100px_80px\]{grid-template-columns:auto 1fr 100px 100px 100px 80px}.grid-cols-\[auto_1fr_120px_100px_100px_100px_80px\]{grid-template-columns:auto 1fr 120px 100px 100px 100px 80px}.grid-cols-\[repeat\(auto-fill\,minmax\(130px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(130px,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0{gap:calc(var(--spacing)*0)}.gap-0\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-5{gap:calc(var(--spacing)*5)}.gap-6{gap:calc(var(--spacing)*6)}.gap-8{gap:calc(var(--spacing)*8)}.gap-\[3px\]{gap:3px}:where(.space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*0)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*0)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}.gap-x-2{column-gap:calc(var(--spacing)*2)}.gap-x-3{column-gap:calc(var(--spacing)*3)}.gap-x-4{column-gap:calc(var(--spacing)*4)}.gap-x-6{column-gap:calc(var(--spacing)*6)}.gap-y-1{row-gap:calc(var(--spacing)*1)}.gap-y-1\.5{row-gap:calc(var(--spacing)*1.5)}.gap-y-2{row-gap:calc(var(--spacing)*2)}.gap-y-3{row-gap:calc(var(--spacing)*3)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-bambu-dark-tertiary>:not(:last-child)),:where(.divide-bambu-dark-tertiary\/30>:not(:last-child)){border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){:where(.divide-bambu-dark-tertiary\/30>:not(:last-child)){border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}:where(.divide-bambu-gray\/20>:not(:last-child)){border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){:where(.divide-bambu-gray\/20>:not(:last-child)){border-color:color-mix(in oklab,var(--color-bambu-gray)20%,transparent)}}:where(.divide-gray-100>:not(:last-child)){border-color:var(--color-gray-100)}.self-stretch{align-self:stretch}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-none{border-radius:0}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-lg{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.rounded-t-xl{border-top-left-radius:var(--radius-xl);border-top-right-radius:var(--radius-xl)}.\!rounded-l-none{border-top-left-radius:0!important;border-bottom-left-radius:0!important}.rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-l-lg{border-top-left-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.rounded-tl{border-top-left-radius:.25rem}.\!rounded-r-none{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.rounded-r-lg{border-top-right-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.rounded-b-2xl{border-bottom-right-radius:var(--radius-2xl);border-bottom-left-radius:var(--radius-2xl)}.rounded-b-lg{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-4{border-style:var(--tw-border-style);border-width:4px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-t-\[5px\]{border-top-style:var(--tw-border-style);border-top-width:5px}.border-t-\[6px\]{border-top-style:var(--tw-border-style);border-top-width:6px}.\!border-r-0{border-right-style:var(--tw-border-style)!important;border-right-width:0!important}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-r-\[5px\]{border-right-style:var(--tw-border-style);border-right-width:5px}.border-r-\[6px\]{border-right-style:var(--tw-border-style);border-right-width:6px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-b-\[6px\]{border-bottom-style:var(--tw-border-style);border-bottom-width:6px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-l-\[3px\]{border-left-style:var(--tw-border-style);border-left-width:3px}.border-l-\[5px\]{border-left-style:var(--tw-border-style);border-left-width:5px}.border-l-\[6px\]{border-left-style:var(--tw-border-style);border-left-width:6px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.\!border-green-500{border-color:var(--color-green-500)!important}.\!border-yellow-500{border-color:var(--color-yellow-500)!important}.border-amber-200{border-color:var(--color-amber-200)}.border-amber-300{border-color:var(--color-amber-300)}.border-amber-500{border-color:var(--color-amber-500)}.border-amber-500\/20{border-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/20{border-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/30{border-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.border-amber-700{border-color:var(--color-amber-700)}.border-amber-700\/40{border-color:#b7500066}@supports (color:color-mix(in lab,red,red)){.border-amber-700\/40{border-color:color-mix(in oklab,var(--color-amber-700)40%,transparent)}}.border-bambu-dark-secondary{border-color:var(--color-bambu-dark-secondary)}.border-bambu-dark-tertiary,.border-bambu-dark-tertiary\/20{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/20{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)20%,transparent)}}.border-bambu-dark-tertiary\/30{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/30{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.border-bambu-dark-tertiary\/40{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/40{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)40%,transparent)}}.border-bambu-dark-tertiary\/50{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/50{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.border-bambu-dark-tertiary\/60{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.border-bambu-dark-tertiary\/60{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)60%,transparent)}}.border-bambu-gray,.border-bambu-gray\/20{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.border-bambu-gray\/20{border-color:color-mix(in oklab,var(--color-bambu-gray)20%,transparent)}}.border-bambu-gray\/30{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.border-bambu-gray\/30{border-color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.border-bambu-gray\/50{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.border-bambu-gray\/50{border-color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.border-bambu-green,.border-bambu-green\/20{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/20{border-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.border-bambu-green\/30{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/30{border-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.border-bambu-green\/40{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/40{border-color:color-mix(in oklab,var(--color-bambu-green)40%,transparent)}}.border-bambu-green\/50{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.border-bambu-green\/50{border-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.border-black\/20{border-color:#0003}@supports (color:color-mix(in lab,red,red)){.border-black\/20{border-color:color-mix(in oklab,var(--color-black)20%,transparent)}}.border-blue-400{border-color:var(--color-blue-400)}.border-blue-400\/20{border-color:#54a2ff33}@supports (color:color-mix(in lab,red,red)){.border-blue-400\/20{border-color:color-mix(in oklab,var(--color-blue-400)20%,transparent)}}.border-blue-400\/50{border-color:#54a2ff80}@supports (color:color-mix(in lab,red,red)){.border-blue-400\/50{border-color:color-mix(in oklab,var(--color-blue-400)50%,transparent)}}.border-blue-500{border-color:var(--color-blue-500)}.border-blue-500\/20{border-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/20{border-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/30{border-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.border-blue-500\/40{border-color:#3080ff66}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/40{border-color:color-mix(in oklab,var(--color-blue-500)40%,transparent)}}.border-blue-500\/50{border-color:#3080ff80}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/50{border-color:color-mix(in oklab,var(--color-blue-500)50%,transparent)}}.border-current{border-color:currentColor}.border-emerald-500\/20{border-color:#00bb7f33}@supports (color:color-mix(in lab,red,red)){.border-emerald-500\/20{border-color:color-mix(in oklab,var(--color-emerald-500)20%,transparent)}}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-400\/20{border-color:#99a1af33}@supports (color:color-mix(in lab,red,red)){.border-gray-400\/20{border-color:color-mix(in oklab,var(--color-gray-400)20%,transparent)}}.border-gray-500{border-color:var(--color-gray-500)}.border-gray-500\/30{border-color:#6a72824d}@supports (color:color-mix(in lab,red,red)){.border-gray-500\/30{border-color:color-mix(in oklab,var(--color-gray-500)30%,transparent)}}.border-gray-500\/40{border-color:#6a728266}@supports (color:color-mix(in lab,red,red)){.border-gray-500\/40{border-color:color-mix(in oklab,var(--color-gray-500)40%,transparent)}}.border-gray-700{border-color:var(--color-gray-700)}.border-gray-800{border-color:var(--color-gray-800)}.border-green-300{border-color:var(--color-green-300)}.border-green-400{border-color:var(--color-green-400)}.border-green-500{border-color:var(--color-green-500)}.border-green-500\/30{border-color:#00c7584d}@supports (color:color-mix(in lab,red,red)){.border-green-500\/30{border-color:color-mix(in oklab,var(--color-green-500)30%,transparent)}}.border-green-500\/40{border-color:#00c75866}@supports (color:color-mix(in lab,red,red)){.border-green-500\/40{border-color:color-mix(in oklab,var(--color-green-500)40%,transparent)}}.border-green-500\/50{border-color:#00c75880}@supports (color:color-mix(in lab,red,red)){.border-green-500\/50{border-color:color-mix(in oklab,var(--color-green-500)50%,transparent)}}.border-green-800{border-color:var(--color-green-800)}.border-orange-400\/20{border-color:#ff8b1a33}@supports (color:color-mix(in lab,red,red)){.border-orange-400\/20{border-color:color-mix(in oklab,var(--color-orange-400)20%,transparent)}}.border-orange-400\/50{border-color:#ff8b1a80}@supports (color:color-mix(in lab,red,red)){.border-orange-400\/50{border-color:color-mix(in oklab,var(--color-orange-400)50%,transparent)}}.border-orange-500\/20{border-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.border-orange-500\/20{border-color:color-mix(in oklab,var(--color-orange-500)20%,transparent)}}.border-orange-500\/30{border-color:#fe6e004d}@supports (color:color-mix(in lab,red,red)){.border-orange-500\/30{border-color:color-mix(in oklab,var(--color-orange-500)30%,transparent)}}.border-purple-400\/20{border-color:#c07eff33}@supports (color:color-mix(in lab,red,red)){.border-purple-400\/20{border-color:color-mix(in oklab,var(--color-purple-400)20%,transparent)}}.border-purple-500{border-color:var(--color-purple-500)}.border-purple-500\/20{border-color:#ac4bff33}@supports (color:color-mix(in lab,red,red)){.border-purple-500\/20{border-color:color-mix(in oklab,var(--color-purple-500)20%,transparent)}}.border-purple-500\/30{border-color:#ac4bff4d}@supports (color:color-mix(in lab,red,red)){.border-purple-500\/30{border-color:color-mix(in oklab,var(--color-purple-500)30%,transparent)}}.border-red-300{border-color:var(--color-red-300)}.border-red-400{border-color:var(--color-red-400)}.border-red-500{border-color:var(--color-red-500)}.border-red-500\/20{border-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.border-red-500\/20{border-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.border-red-500\/30{border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.border-red-500\/30{border-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.border-red-500\/40{border-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.border-red-500\/40{border-color:color-mix(in oklab,var(--color-red-500)40%,transparent)}}.border-red-500\/50{border-color:#fb2c3680}@supports (color:color-mix(in lab,red,red)){.border-red-500\/50{border-color:color-mix(in oklab,var(--color-red-500)50%,transparent)}}.border-red-800{border-color:var(--color-red-800)}.border-red-800\/70{border-color:#9f0712b3}@supports (color:color-mix(in lab,red,red)){.border-red-800\/70{border-color:color-mix(in oklab,var(--color-red-800)70%,transparent)}}.border-red-900\/40{border-color:#82181a66}@supports (color:color-mix(in lab,red,red)){.border-red-900\/40{border-color:color-mix(in oklab,var(--color-red-900)40%,transparent)}}.border-slate-500{border-color:var(--color-slate-500)}.border-status-error\/20{border-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.border-status-error\/20{border-color:color-mix(in oklab,var(--color-status-error)20%,transparent)}}.border-status-ok,.border-status-ok\/20{border-color:var(--color-status-ok)}@supports (color:color-mix(in lab,red,red)){.border-status-ok\/20{border-color:color-mix(in oklab,var(--color-status-ok)20%,transparent)}}.border-status-warning\/20{border-color:var(--color-status-warning)}@supports (color:color-mix(in lab,red,red)){.border-status-warning\/20{border-color:color-mix(in oklab,var(--color-status-warning)20%,transparent)}}.border-transparent{border-color:#0000}.border-white{border-color:var(--color-white)}.border-white\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.border-white\/10{border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.border-white\/20{border-color:#fff3}@supports (color:color-mix(in lab,red,red)){.border-white\/20{border-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.border-white\/30{border-color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.border-white\/30{border-color:color-mix(in oklab,var(--color-white)30%,transparent)}}.border-yellow-400{border-color:var(--color-yellow-400)}.border-yellow-400\/20{border-color:#fac80033}@supports (color:color-mix(in lab,red,red)){.border-yellow-400\/20{border-color:color-mix(in oklab,var(--color-yellow-400)20%,transparent)}}.border-yellow-400\/40{border-color:#fac80066}@supports (color:color-mix(in lab,red,red)){.border-yellow-400\/40{border-color:color-mix(in oklab,var(--color-yellow-400)40%,transparent)}}.border-yellow-400\/50{border-color:#fac80080}@supports (color:color-mix(in lab,red,red)){.border-yellow-400\/50{border-color:color-mix(in oklab,var(--color-yellow-400)50%,transparent)}}.border-yellow-500{border-color:var(--color-yellow-500)}.border-yellow-500\/20{border-color:#edb20033}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/20{border-color:color-mix(in oklab,var(--color-yellow-500)20%,transparent)}}.border-yellow-500\/30{border-color:#edb2004d}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/30{border-color:color-mix(in oklab,var(--color-yellow-500)30%,transparent)}}.border-yellow-500\/50{border-color:#edb20080}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/50{border-color:color-mix(in oklab,var(--color-yellow-500)50%,transparent)}}.border-zinc-500{border-color:var(--color-zinc-500)}.border-zinc-600{border-color:var(--color-zinc-600)}.border-zinc-700{border-color:var(--color-zinc-700)}.border-zinc-700\/50{border-color:#3f3f4680}@supports (color:color-mix(in lab,red,red)){.border-zinc-700\/50{border-color:color-mix(in oklab,var(--color-zinc-700)50%,transparent)}}.border-zinc-800{border-color:var(--color-zinc-800)}.border-t-bambu-dark-tertiary{border-top-color:var(--color-bambu-dark-tertiary)}.border-t-transparent{border-top-color:#0000}.border-r-transparent{border-right-color:#0000}.border-b-bambu-dark-tertiary{border-bottom-color:var(--color-bambu-dark-tertiary)}.border-l-blue-500{border-left-color:var(--color-blue-500)}.border-l-emerald-500{border-left-color:var(--color-emerald-500)}.border-l-gray-500{border-left-color:var(--color-gray-500)}.border-l-red-500{border-left-color:var(--color-red-500)}.border-l-transparent{border-left-color:#0000}.border-l-yellow-500{border-left-color:var(--color-yellow-500)}.\!bg-bambu-green{background-color:var(--color-bambu-green)!important}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-500{background-color:var(--color-amber-500)}.bg-amber-500\/5{background-color:#f99c000d}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/5{background-color:color-mix(in oklab,var(--color-amber-500)5%,transparent)}}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/10{background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.bg-amber-500\/20{background-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/20{background-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.bg-amber-600{background-color:var(--color-amber-600)}.bg-amber-600\/20{background-color:#dd740033}@supports (color:color-mix(in lab,red,red)){.bg-amber-600\/20{background-color:color-mix(in oklab,var(--color-amber-600)20%,transparent)}}.bg-amber-900\/20{background-color:#7b330633}@supports (color:color-mix(in lab,red,red)){.bg-amber-900\/20{background-color:color-mix(in oklab,var(--color-amber-900)20%,transparent)}}.bg-amber-900\/30{background-color:#7b33064d}@supports (color:color-mix(in lab,red,red)){.bg-amber-900\/30{background-color:color-mix(in oklab,var(--color-amber-900)30%,transparent)}}.bg-bambu-dark{background-color:var(--color-bambu-dark)}.bg-bambu-dark-secondary,.bg-bambu-dark-secondary\/30{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/30{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)30%,transparent)}}.bg-bambu-dark-secondary\/50{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/50{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)50%,transparent)}}.bg-bambu-dark-secondary\/60{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/60{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)60%,transparent)}}.bg-bambu-dark-secondary\/90{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/90{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)90%,transparent)}}.bg-bambu-dark-secondary\/95{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-secondary\/95{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)95%,transparent)}}.bg-bambu-dark-tertiary,.bg-bambu-dark-tertiary\/10{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/10{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)10%,transparent)}}.bg-bambu-dark-tertiary\/20{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/20{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)20%,transparent)}}.bg-bambu-dark-tertiary\/30{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/30{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.bg-bambu-dark-tertiary\/40{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/40{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)40%,transparent)}}.bg-bambu-dark-tertiary\/50{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/50{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.bg-bambu-dark-tertiary\/70{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/70{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)70%,transparent)}}.bg-bambu-dark-tertiary\/80{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark-tertiary\/80{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.bg-bambu-dark\/20{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/20{background-color:color-mix(in oklab,var(--color-bambu-dark)20%,transparent)}}.bg-bambu-dark\/30{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/30{background-color:color-mix(in oklab,var(--color-bambu-dark)30%,transparent)}}.bg-bambu-dark\/40{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/40{background-color:color-mix(in oklab,var(--color-bambu-dark)40%,transparent)}}.bg-bambu-dark\/50{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/50{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.bg-bambu-dark\/80{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/80{background-color:color-mix(in oklab,var(--color-bambu-dark)80%,transparent)}}.bg-bambu-dark\/90{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-dark\/90{background-color:color-mix(in oklab,var(--color-bambu-dark)90%,transparent)}}.bg-bambu-gray,.bg-bambu-gray\/10{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/10{background-color:color-mix(in oklab,var(--color-bambu-gray)10%,transparent)}}.bg-bambu-gray\/20{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/20{background-color:color-mix(in oklab,var(--color-bambu-gray)20%,transparent)}}.bg-bambu-gray\/30{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/30{background-color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.bg-bambu-gray\/40{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/40{background-color:color-mix(in oklab,var(--color-bambu-gray)40%,transparent)}}.bg-bambu-gray\/50{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/50{background-color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.bg-bambu-gray\/60{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/60{background-color:color-mix(in oklab,var(--color-bambu-gray)60%,transparent)}}.bg-bambu-gray\/90{background-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-gray\/90{background-color:color-mix(in oklab,var(--color-bambu-gray)90%,transparent)}}.bg-bambu-green,.bg-bambu-green\/5{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/5{background-color:color-mix(in oklab,var(--color-bambu-green)5%,transparent)}}.bg-bambu-green\/10{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/10{background-color:color-mix(in oklab,var(--color-bambu-green)10%,transparent)}}.bg-bambu-green\/15{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/15{background-color:color-mix(in oklab,var(--color-bambu-green)15%,transparent)}}.bg-bambu-green\/20{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/20{background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.bg-bambu-green\/30{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/30{background-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.bg-bambu-green\/40{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/40{background-color:color-mix(in oklab,var(--color-bambu-green)40%,transparent)}}.bg-bambu-green\/50{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/50{background-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.bg-bambu-green\/75{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/75{background-color:color-mix(in oklab,var(--color-bambu-green)75%,transparent)}}.bg-bambu-green\/90{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.bg-bambu-green\/90{background-color:color-mix(in oklab,var(--color-bambu-green)90%,transparent)}}.bg-black{background-color:var(--color-black)}.bg-black\/15{background-color:#00000026}@supports (color:color-mix(in lab,red,red)){.bg-black\/15{background-color:color-mix(in oklab,var(--color-black)15%,transparent)}}.bg-black\/20{background-color:#0003}@supports (color:color-mix(in lab,red,red)){.bg-black\/20{background-color:color-mix(in oklab,var(--color-black)20%,transparent)}}.bg-black\/30{background-color:#0000004d}@supports (color:color-mix(in lab,red,red)){.bg-black\/30{background-color:color-mix(in oklab,var(--color-black)30%,transparent)}}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.bg-black\/40{background-color:color-mix(in oklab,var(--color-black)40%,transparent)}}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black)60%,transparent)}}.bg-black\/70{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.bg-black\/70{background-color:color-mix(in oklab,var(--color-black)70%,transparent)}}.bg-black\/80{background-color:#000c}@supports (color:color-mix(in lab,red,red)){.bg-black\/80{background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.bg-black\/90{background-color:#000000e6}@supports (color:color-mix(in lab,red,red)){.bg-black\/90{background-color:color-mix(in oklab,var(--color-black)90%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-400{background-color:var(--color-blue-400)}.bg-blue-400\/10{background-color:#54a2ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-400\/10{background-color:color-mix(in oklab,var(--color-blue-400)10%,transparent)}}.bg-blue-400\/15{background-color:#54a2ff26}@supports (color:color-mix(in lab,red,red)){.bg-blue-400\/15{background-color:color-mix(in oklab,var(--color-blue-400)15%,transparent)}}.bg-blue-400\/20{background-color:#54a2ff33}@supports (color:color-mix(in lab,red,red)){.bg-blue-400\/20{background-color:color-mix(in oklab,var(--color-blue-400)20%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-500\/5{background-color:#3080ff0d}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/5{background-color:color-mix(in oklab,var(--color-blue-500)5%,transparent)}}.bg-blue-500\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/10{background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.bg-blue-500\/15{background-color:#3080ff26}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/15{background-color:color-mix(in oklab,var(--color-blue-500)15%,transparent)}}.bg-blue-500\/20{background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/20{background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.bg-blue-500\/30{background-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/30{background-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.bg-blue-500\/90{background-color:#3080ffe6}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/90{background-color:color-mix(in oklab,var(--color-blue-500)90%,transparent)}}.bg-blue-600{background-color:var(--color-blue-600)}.bg-blue-600\/20{background-color:#155dfc33}@supports (color:color-mix(in lab,red,red)){.bg-blue-600\/20{background-color:color-mix(in oklab,var(--color-blue-600)20%,transparent)}}.bg-blue-700{background-color:var(--color-blue-700)}.bg-cyan-500{background-color:var(--color-cyan-500)}.bg-cyan-500\/10{background-color:#00b7d71a}@supports (color:color-mix(in lab,red,red)){.bg-cyan-500\/10{background-color:color-mix(in oklab,var(--color-cyan-500)10%,transparent)}}.bg-cyan-500\/20{background-color:#00b7d733}@supports (color:color-mix(in lab,red,red)){.bg-cyan-500\/20{background-color:color-mix(in oklab,var(--color-cyan-500)20%,transparent)}}.bg-cyan-600\/20{background-color:#0092b533}@supports (color:color-mix(in lab,red,red)){.bg-cyan-600\/20{background-color:color-mix(in oklab,var(--color-cyan-600)20%,transparent)}}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab,red,red)){.bg-emerald-500\/10{background-color:color-mix(in oklab,var(--color-emerald-500)10%,transparent)}}.bg-emerald-500\/20{background-color:#00bb7f33}@supports (color:color-mix(in lab,red,red)){.bg-emerald-500\/20{background-color:color-mix(in oklab,var(--color-emerald-500)20%,transparent)}}.bg-emerald-600\/20{background-color:#00976733}@supports (color:color-mix(in lab,red,red)){.bg-emerald-600\/20{background-color:color-mix(in oklab,var(--color-emerald-600)20%,transparent)}}.bg-emerald-700{background-color:var(--color-emerald-700)}.bg-fuchsia-500{background-color:var(--color-fuchsia-500)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-400\/10{background-color:#99a1af1a}@supports (color:color-mix(in lab,red,red)){.bg-gray-400\/10{background-color:color-mix(in oklab,var(--color-gray-400)10%,transparent)}}.bg-gray-500{background-color:var(--color-gray-500)}.bg-gray-500\/15{background-color:#6a728226}@supports (color:color-mix(in lab,red,red)){.bg-gray-500\/15{background-color:color-mix(in oklab,var(--color-gray-500)15%,transparent)}}.bg-gray-500\/20{background-color:#6a728233}@supports (color:color-mix(in lab,red,red)){.bg-gray-500\/20{background-color:color-mix(in oklab,var(--color-gray-500)20%,transparent)}}.bg-gray-600{background-color:var(--color-gray-600)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-400{background-color:var(--color-green-400)}.bg-green-400\/10{background-color:#05df721a}@supports (color:color-mix(in lab,red,red)){.bg-green-400\/10{background-color:color-mix(in oklab,var(--color-green-400)10%,transparent)}}.bg-green-500{background-color:var(--color-green-500)}.bg-green-500\/10{background-color:#00c7581a}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/10{background-color:color-mix(in oklab,var(--color-green-500)10%,transparent)}}.bg-green-500\/15{background-color:#00c75826}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/15{background-color:color-mix(in oklab,var(--color-green-500)15%,transparent)}}.bg-green-500\/20{background-color:#00c75833}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/20{background-color:color-mix(in oklab,var(--color-green-500)20%,transparent)}}.bg-green-600{background-color:var(--color-green-600)}.bg-green-600\/20{background-color:#00a54433}@supports (color:color-mix(in lab,red,red)){.bg-green-600\/20{background-color:color-mix(in oklab,var(--color-green-600)20%,transparent)}}.bg-green-600\/40{background-color:#00a54466}@supports (color:color-mix(in lab,red,red)){.bg-green-600\/40{background-color:color-mix(in oklab,var(--color-green-600)40%,transparent)}}.bg-green-700{background-color:var(--color-green-700)}.bg-green-900\/30{background-color:#0d542b4d}@supports (color:color-mix(in lab,red,red)){.bg-green-900\/30{background-color:color-mix(in oklab,var(--color-green-900)30%,transparent)}}.bg-green-900\/50{background-color:#0d542b80}@supports (color:color-mix(in lab,red,red)){.bg-green-900\/50{background-color:color-mix(in oklab,var(--color-green-900)50%,transparent)}}.bg-indigo-500\/10{background-color:#625fff1a}@supports (color:color-mix(in lab,red,red)){.bg-indigo-500\/10{background-color:color-mix(in oklab,var(--color-indigo-500)10%,transparent)}}.bg-indigo-500\/15{background-color:#625fff26}@supports (color:color-mix(in lab,red,red)){.bg-indigo-500\/15{background-color:color-mix(in oklab,var(--color-indigo-500)15%,transparent)}}.bg-indigo-500\/20{background-color:#625fff33}@supports (color:color-mix(in lab,red,red)){.bg-indigo-500\/20{background-color:color-mix(in oklab,var(--color-indigo-500)20%,transparent)}}.bg-lime-500{background-color:var(--color-lime-500)}.bg-lime-500\/20{background-color:#80cd0033}@supports (color:color-mix(in lab,red,red)){.bg-lime-500\/20{background-color:color-mix(in oklab,var(--color-lime-500)20%,transparent)}}.bg-orange-400\/10{background-color:#ff8b1a1a}@supports (color:color-mix(in lab,red,red)){.bg-orange-400\/10{background-color:color-mix(in oklab,var(--color-orange-400)10%,transparent)}}.bg-orange-500{background-color:var(--color-orange-500)}.bg-orange-500\/10{background-color:#fe6e001a}@supports (color:color-mix(in lab,red,red)){.bg-orange-500\/10{background-color:color-mix(in oklab,var(--color-orange-500)10%,transparent)}}.bg-orange-500\/20{background-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.bg-orange-500\/20{background-color:color-mix(in oklab,var(--color-orange-500)20%,transparent)}}.bg-orange-600{background-color:var(--color-orange-600)}.bg-orange-600\/20{background-color:#f0510033}@supports (color:color-mix(in lab,red,red)){.bg-orange-600\/20{background-color:color-mix(in oklab,var(--color-orange-600)20%,transparent)}}.bg-purple-400\/10{background-color:#c07eff1a}@supports (color:color-mix(in lab,red,red)){.bg-purple-400\/10{background-color:color-mix(in oklab,var(--color-purple-400)10%,transparent)}}.bg-purple-500{background-color:var(--color-purple-500)}.bg-purple-500\/10{background-color:#ac4bff1a}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/10{background-color:color-mix(in oklab,var(--color-purple-500)10%,transparent)}}.bg-purple-500\/20{background-color:#ac4bff33}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/20{background-color:color-mix(in oklab,var(--color-purple-500)20%,transparent)}}.bg-purple-500\/80{background-color:#ac4bffcc}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/80{background-color:color-mix(in oklab,var(--color-purple-500)80%,transparent)}}.bg-purple-500\/90{background-color:#ac4bffe6}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/90{background-color:color-mix(in oklab,var(--color-purple-500)90%,transparent)}}.bg-purple-700{background-color:var(--color-purple-700)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-400{background-color:var(--color-red-400)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/5{background-color:#fb2c360d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/5{background-color:color-mix(in oklab,var(--color-red-500)5%,transparent)}}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/10{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.bg-red-500\/15{background-color:#fb2c3626}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/15{background-color:color-mix(in oklab,var(--color-red-500)15%,transparent)}}.bg-red-500\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/20{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.bg-red-500\/30{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/30{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.bg-red-500\/40{background-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/40{background-color:color-mix(in oklab,var(--color-red-500)40%,transparent)}}.bg-red-500\/80{background-color:#fb2c36cc}@supports (color:color-mix(in lab,red,red)){.bg-red-500\/80{background-color:color-mix(in oklab,var(--color-red-500)80%,transparent)}}.bg-red-600{background-color:var(--color-red-600)}.bg-red-600\/20{background-color:#e4001433}@supports (color:color-mix(in lab,red,red)){.bg-red-600\/20{background-color:color-mix(in oklab,var(--color-red-600)20%,transparent)}}.bg-red-900\/20{background-color:#82181a33}@supports (color:color-mix(in lab,red,red)){.bg-red-900\/20{background-color:color-mix(in oklab,var(--color-red-900)20%,transparent)}}.bg-red-900\/30{background-color:#82181a4d}@supports (color:color-mix(in lab,red,red)){.bg-red-900\/30{background-color:color-mix(in oklab,var(--color-red-900)30%,transparent)}}.bg-red-950\/70{background-color:#460809b3}@supports (color:color-mix(in lab,red,red)){.bg-red-950\/70{background-color:color-mix(in oklab,var(--color-red-950)70%,transparent)}}.bg-rose-500\/20{background-color:#ff235733}@supports (color:color-mix(in lab,red,red)){.bg-rose-500\/20{background-color:color-mix(in oklab,var(--color-rose-500)20%,transparent)}}.bg-rose-600\/20{background-color:#e7004433}@supports (color:color-mix(in lab,red,red)){.bg-rose-600\/20{background-color:color-mix(in oklab,var(--color-rose-600)20%,transparent)}}.bg-sky-500{background-color:var(--color-sky-500)}.bg-sky-500\/10{background-color:#00a5ef1a}@supports (color:color-mix(in lab,red,red)){.bg-sky-500\/10{background-color:color-mix(in oklab,var(--color-sky-500)10%,transparent)}}.bg-sky-500\/20{background-color:#00a5ef33}@supports (color:color-mix(in lab,red,red)){.bg-sky-500\/20{background-color:color-mix(in oklab,var(--color-sky-500)20%,transparent)}}.bg-status-error,.bg-status-error\/10{background-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.bg-status-error\/10{background-color:color-mix(in oklab,var(--color-status-error)10%,transparent)}}.bg-status-error\/20{background-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.bg-status-error\/20{background-color:color-mix(in oklab,var(--color-status-error)20%,transparent)}}.bg-status-error\/80{background-color:var(--color-status-error)}@supports (color:color-mix(in lab,red,red)){.bg-status-error\/80{background-color:color-mix(in oklab,var(--color-status-error)80%,transparent)}}.bg-status-ok,.bg-status-ok\/10{background-color:var(--color-status-ok)}@supports (color:color-mix(in lab,red,red)){.bg-status-ok\/10{background-color:color-mix(in oklab,var(--color-status-ok)10%,transparent)}}.bg-status-ok\/20{background-color:var(--color-status-ok)}@supports (color:color-mix(in lab,red,red)){.bg-status-ok\/20{background-color:color-mix(in oklab,var(--color-status-ok)20%,transparent)}}.bg-status-warning,.bg-status-warning\/10{background-color:var(--color-status-warning)}@supports (color:color-mix(in lab,red,red)){.bg-status-warning\/10{background-color:color-mix(in oklab,var(--color-status-warning)10%,transparent)}}.bg-status-warning\/20{background-color:var(--color-status-warning)}@supports (color:color-mix(in lab,red,red)){.bg-status-warning\/20{background-color:color-mix(in oklab,var(--color-status-warning)20%,transparent)}}.bg-teal-500{background-color:var(--color-teal-500)}.bg-teal-500\/20{background-color:#00baa733}@supports (color:color-mix(in lab,red,red)){.bg-teal-500\/20{background-color:color-mix(in oklab,var(--color-teal-500)20%,transparent)}}.bg-transparent{background-color:#0000}.bg-violet-500{background-color:var(--color-violet-500)}.bg-white{background-color:var(--color-white)}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.bg-white\/10{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.bg-white\/20{background-color:#fff3}@supports (color:color-mix(in lab,red,red)){.bg-white\/20{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.bg-white\/50{background-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.bg-white\/50{background-color:color-mix(in oklab,var(--color-white)50%,transparent)}}.bg-white\/70{background-color:#ffffffb3}@supports (color:color-mix(in lab,red,red)){.bg-white\/70{background-color:color-mix(in oklab,var(--color-white)70%,transparent)}}.bg-white\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.bg-white\/90{background-color:color-mix(in oklab,var(--color-white)90%,transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-400\/10{background-color:#fac8001a}@supports (color:color-mix(in lab,red,red)){.bg-yellow-400\/10{background-color:color-mix(in oklab,var(--color-yellow-400)10%,transparent)}}.bg-yellow-400\/20{background-color:#fac80033}@supports (color:color-mix(in lab,red,red)){.bg-yellow-400\/20{background-color:color-mix(in oklab,var(--color-yellow-400)20%,transparent)}}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-yellow-500\/5{background-color:#edb2000d}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/5{background-color:color-mix(in oklab,var(--color-yellow-500)5%,transparent)}}.bg-yellow-500\/10{background-color:#edb2001a}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/10{background-color:color-mix(in oklab,var(--color-yellow-500)10%,transparent)}}.bg-yellow-500\/15{background-color:#edb20026}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/15{background-color:color-mix(in oklab,var(--color-yellow-500)15%,transparent)}}.bg-yellow-500\/20{background-color:#edb20033}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/20{background-color:color-mix(in oklab,var(--color-yellow-500)20%,transparent)}}.bg-yellow-700{background-color:var(--color-yellow-700)}.bg-zinc-600{background-color:var(--color-zinc-600)}.bg-zinc-700{background-color:var(--color-zinc-700)}.bg-zinc-800{background-color:var(--color-zinc-800)}.bg-zinc-800\/50{background-color:#27272a80}@supports (color:color-mix(in lab,red,red)){.bg-zinc-800\/50{background-color:color-mix(in oklab,var(--color-zinc-800)50%,transparent)}}.bg-zinc-800\/60{background-color:#27272a99}@supports (color:color-mix(in lab,red,red)){.bg-zinc-800\/60{background-color:color-mix(in oklab,var(--color-zinc-800)60%,transparent)}}.bg-zinc-900{background-color:var(--color-zinc-900)}.bg-zinc-900\/50{background-color:#18181b80}@supports (color:color-mix(in lab,red,red)){.bg-zinc-900\/50{background-color:color-mix(in oklab,var(--color-zinc-900)50%,transparent)}}.bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-bambu-dark-secondary{--tw-gradient-from:var(--color-bambu-dark-secondary);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-black\/80{--tw-gradient-from:#000c}@supports (color:color-mix(in lab,red,red)){.from-black\/80{--tw-gradient-from:color-mix(in oklab,var(--color-black)80%,transparent)}}.from-black\/80{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-500\/5{--tw-gradient-from:#3080ff0d}@supports (color:color-mix(in lab,red,red)){.from-blue-500\/5{--tw-gradient-from:color-mix(in oklab,var(--color-blue-500)5%,transparent)}}.from-blue-500\/5{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-white\/10{--tw-gradient-from:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.from-white\/10{--tw-gradient-from:color-mix(in oklab,var(--color-white)10%,transparent)}}.from-white\/10{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.via-black\/60{--tw-gradient-via:#0009}@supports (color:color-mix(in lab,red,red)){.via-black\/60{--tw-gradient-via:color-mix(in oklab,var(--color-black)60%,transparent)}}.via-black\/60{--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-bambu-dark-secondary{--tw-gradient-to:var(--color-bambu-dark-secondary);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-bambu-dark-tertiary{--tw-gradient-to:var(--color-bambu-dark-tertiary);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.bg-cover{background-size:cover}.bg-center{background-position:50%}.fill-yellow-400{fill:var(--color-yellow-400)}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.object-left{object-position:left}.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-2\.5{padding:calc(var(--spacing)*2.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.p-12{padding:calc(var(--spacing)*12)}.\!px-1\.5{padding-inline:calc(var(--spacing)*1.5)!important}.\!px-3{padding-inline:calc(var(--spacing)*3)!important}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.py-12{padding-block:calc(var(--spacing)*12)}.py-16{padding-block:calc(var(--spacing)*16)}.py-20{padding-block:calc(var(--spacing)*20)}.py-24{padding-block:calc(var(--spacing)*24)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-5{padding-top:calc(var(--spacing)*5)}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-3{padding-right:calc(var(--spacing)*3)}.pr-4{padding-right:calc(var(--spacing)*4)}.pr-6{padding-right:calc(var(--spacing)*6)}.pr-7{padding-right:calc(var(--spacing)*7)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-10{padding-right:calc(var(--spacing)*10)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-3{padding-left:calc(var(--spacing)*3)}.pl-4{padding-left:calc(var(--spacing)*4)}.pl-5{padding-left:calc(var(--spacing)*5)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-7{padding-left:calc(var(--spacing)*7)}.pl-8{padding-left:calc(var(--spacing)*8)}.pl-9{padding-left:calc(var(--spacing)*9)}.pl-10{padding-left:calc(var(--spacing)*10)}.pl-20{padding-left:calc(var(--spacing)*20)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[6px\]{font-size:6px}.text-\[7px\]{font-size:7px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.\!text-green-400{color:var(--color-green-400)!important}.\!text-white{color:var(--color-white)!important}.\!text-yellow-400{color:var(--color-yellow-400)!important}.text-amber-200{color:var(--color-amber-200)}.text-amber-200\/80{color:#fee685cc}@supports (color:color-mix(in lab,red,red)){.text-amber-200\/80{color:color-mix(in oklab,var(--color-amber-200)80%,transparent)}}.text-amber-300{color:var(--color-amber-300)}.text-amber-300\/60{color:#ffd23699}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/60{color:color-mix(in oklab,var(--color-amber-300)60%,transparent)}}.text-amber-300\/70{color:#ffd236b3}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/70{color:color-mix(in oklab,var(--color-amber-300)70%,transparent)}}.text-amber-300\/80{color:#ffd236cc}@supports (color:color-mix(in lab,red,red)){.text-amber-300\/80{color:color-mix(in oklab,var(--color-amber-300)80%,transparent)}}.text-amber-400{color:var(--color-amber-400)}.text-amber-400\/70{color:#fcbb00b3}@supports (color:color-mix(in lab,red,red)){.text-amber-400\/70{color:color-mix(in oklab,var(--color-amber-400)70%,transparent)}}.text-amber-500{color:var(--color-amber-500)}.text-amber-500\/80{color:#f99c00cc}@supports (color:color-mix(in lab,red,red)){.text-amber-500\/80{color:color-mix(in oklab,var(--color-amber-500)80%,transparent)}}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-amber-900{color:var(--color-amber-900)}.text-bambu-dark{color:var(--color-bambu-dark)}.text-bambu-dark-tertiary{color:var(--color-bambu-dark-tertiary)}.text-bambu-gray{color:var(--color-bambu-gray)}.text-bambu-gray-dark{color:var(--color-bambu-gray-dark)}.text-bambu-gray-light{color:var(--color-bambu-gray-light)}.text-bambu-gray\/30{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/30{color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.text-bambu-gray\/40{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/40{color:color-mix(in oklab,var(--color-bambu-gray)40%,transparent)}}.text-bambu-gray\/50{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/50{color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.text-bambu-gray\/60{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/60{color:color-mix(in oklab,var(--color-bambu-gray)60%,transparent)}}.text-bambu-gray\/70{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/70{color:color-mix(in oklab,var(--color-bambu-gray)70%,transparent)}}.text-bambu-gray\/80{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.text-bambu-gray\/80{color:color-mix(in oklab,var(--color-bambu-gray)80%,transparent)}}.text-bambu-green,.text-bambu-green\/50{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.text-bambu-green\/50{color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.text-bambu-green\/60{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.text-bambu-green\/60{color:color-mix(in oklab,var(--color-bambu-green)60%,transparent)}}.text-bambu-green\/70{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.text-bambu-green\/70{color:color-mix(in oklab,var(--color-bambu-green)70%,transparent)}}.text-black{color:var(--color-black)}.text-black\/80{color:#000c}@supports (color:color-mix(in lab,red,red)){.text-black\/80{color:color-mix(in oklab,var(--color-black)80%,transparent)}}.text-blue-100{color:var(--color-blue-100)}.text-blue-300{color:var(--color-blue-300)}.text-blue-300\/70{color:#90c5ffb3}@supports (color:color-mix(in lab,red,red)){.text-blue-300\/70{color:color-mix(in oklab,var(--color-blue-300)70%,transparent)}}.text-blue-300\/80{color:#90c5ffcc}@supports (color:color-mix(in lab,red,red)){.text-blue-300\/80{color:color-mix(in oklab,var(--color-blue-300)80%,transparent)}}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-blue-500\/70{color:#3080ffb3}@supports (color:color-mix(in lab,red,red)){.text-blue-500\/70{color:color-mix(in oklab,var(--color-blue-500)70%,transparent)}}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-cyan-300{color:var(--color-cyan-300)}.text-cyan-400{color:var(--color-cyan-400)}.text-emerald-100{color:var(--color-emerald-100)}.text-emerald-300{color:var(--color-emerald-300)}.text-emerald-400{color:var(--color-emerald-400)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-200{color:var(--color-green-200)}.text-green-300{color:var(--color-green-300)}.text-green-400{color:var(--color-green-400)}.text-green-400\/60{color:#05df7299}@supports (color:color-mix(in lab,red,red)){.text-green-400\/60{color:color-mix(in oklab,var(--color-green-400)60%,transparent)}}.text-green-400\/70{color:#05df72b3}@supports (color:color-mix(in lab,red,red)){.text-green-400\/70{color:color-mix(in oklab,var(--color-green-400)70%,transparent)}}.text-green-500{color:var(--color-green-500)}.text-green-500\/60{color:#00c75899}@supports (color:color-mix(in lab,red,red)){.text-green-500\/60{color:color-mix(in oklab,var(--color-green-500)60%,transparent)}}.text-green-600{color:var(--color-green-600)}.text-green-700{color:var(--color-green-700)}.text-indigo-300{color:var(--color-indigo-300)}.text-indigo-400{color:var(--color-indigo-400)}.text-lime-400{color:var(--color-lime-400)}.text-orange-200{color:var(--color-orange-200)}.text-orange-300{color:var(--color-orange-300)}.text-orange-400{color:var(--color-orange-400)}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-purple-300{color:var(--color-purple-300)}.text-purple-300\/70{color:#d9b3ffb3}@supports (color:color-mix(in lab,red,red)){.text-purple-300\/70{color:color-mix(in oklab,var(--color-purple-300)70%,transparent)}}.text-purple-400{color:var(--color-purple-400)}.text-purple-400\/80{color:#c07effcc}@supports (color:color-mix(in lab,red,red)){.text-purple-400\/80{color:color-mix(in oklab,var(--color-purple-400)80%,transparent)}}.text-red-200{color:var(--color-red-200)}.text-red-300{color:var(--color-red-300)}.text-red-300\/80{color:#ffa3a3cc}@supports (color:color-mix(in lab,red,red)){.text-red-300\/80{color:color-mix(in oklab,var(--color-red-300)80%,transparent)}}.text-red-400{color:var(--color-red-400)}.text-red-400\/50{color:#ff656880}@supports (color:color-mix(in lab,red,red)){.text-red-400\/50{color:color-mix(in oklab,var(--color-red-400)50%,transparent)}}.text-red-400\/60{color:#ff656899}@supports (color:color-mix(in lab,red,red)){.text-red-400\/60{color:color-mix(in oklab,var(--color-red-400)60%,transparent)}}.text-red-400\/70{color:#ff6568b3}@supports (color:color-mix(in lab,red,red)){.text-red-400\/70{color:color-mix(in oklab,var(--color-red-400)70%,transparent)}}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-rose-300{color:var(--color-rose-300)}.text-rose-400{color:var(--color-rose-400)}.text-sky-400{color:var(--color-sky-400)}.text-slate-300{color:var(--color-slate-300)}.text-status-error{color:var(--color-status-error)}.text-status-ok{color:var(--color-status-ok)}.text-status-warning{color:var(--color-status-warning)}.text-teal-400{color:var(--color-teal-400)}.text-white{color:var(--color-white)}.text-white\/30{color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.text-white\/30{color:color-mix(in oklab,var(--color-white)30%,transparent)}}.text-white\/40{color:#fff6}@supports (color:color-mix(in lab,red,red)){.text-white\/40{color:color-mix(in oklab,var(--color-white)40%,transparent)}}.text-white\/50{color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.text-white\/50{color:color-mix(in oklab,var(--color-white)50%,transparent)}}.text-white\/60{color:#fff9}@supports (color:color-mix(in lab,red,red)){.text-white\/60{color:color-mix(in oklab,var(--color-white)60%,transparent)}}.text-white\/70{color:#ffffffb3}@supports (color:color-mix(in lab,red,red)){.text-white\/70{color:color-mix(in oklab,var(--color-white)70%,transparent)}}.text-white\/80{color:#fffc}@supports (color:color-mix(in lab,red,red)){.text-white\/80{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.text-white\/90{color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.text-white\/90{color:color-mix(in oklab,var(--color-white)90%,transparent)}}.text-yellow-100{color:var(--color-yellow-100)}.text-yellow-200{color:var(--color-yellow-200)}.text-yellow-200\/70{color:#fff085b3}@supports (color:color-mix(in lab,red,red)){.text-yellow-200\/70{color:color-mix(in oklab,var(--color-yellow-200)70%,transparent)}}.text-yellow-300{color:var(--color-yellow-300)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500{color:var(--color-yellow-500)}.text-yellow-500\/70{color:#edb200b3}@supports (color:color-mix(in lab,red,red)){.text-yellow-500\/70{color:color-mix(in oklab,var(--color-yellow-500)70%,transparent)}}.text-yellow-500\/80{color:#edb200cc}@supports (color:color-mix(in lab,red,red)){.text-yellow-500\/80{color:color-mix(in oklab,var(--color-yellow-500)80%,transparent)}}.text-yellow-600{color:var(--color-yellow-600)}.text-yellow-700{color:var(--color-yellow-700)}.text-zinc-100{color:var(--color-zinc-100)}.text-zinc-200{color:var(--color-zinc-200)}.text-zinc-300{color:var(--color-zinc-300)}.text-zinc-400{color:var(--color-zinc-400)}.text-zinc-500{color:var(--color-zinc-500)}.text-zinc-600{color:var(--color-zinc-600)}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.placeholder-bambu-gray::placeholder{color:var(--color-bambu-gray)}.placeholder-bambu-gray-dark::placeholder{color:var(--color-bambu-gray-dark)}.placeholder-bambu-gray\/40::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder-bambu-gray\/40::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)40%,transparent)}}.placeholder-bambu-gray\/50::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder-bambu-gray\/50::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.placeholder-bambu-gray\/60::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder-bambu-gray\/60::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)60%,transparent)}}.placeholder-gray-400::placeholder{color:var(--color-gray-400)}.placeholder-white\/30::placeholder{color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.placeholder-white\/30::placeholder{color:color-mix(in oklab,var(--color-white)30%,transparent)}}.placeholder-zinc-500::placeholder{color:var(--color-zinc-500)}.accent-amber-500{accent-color:var(--color-amber-500)}.accent-bambu-green{accent-color:var(--color-bambu-green)}.accent-green-500{accent-color:var(--color-green-500)}.accent-red-500{accent-color:var(--color-red-500)}.\[color-scheme\:dark\]{color-scheme:dark}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_6px_rgba\(34\,197\,94\,0\.5\)\]{--tw-shadow:0 0 6px var(--tw-shadow-color,#22c55e80);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow\/depth{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-bambu-green\/20{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.shadow-bambu-green\/20{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)20%,transparent)var(--tw-shadow-alpha),transparent)}}.shadow-bambu-green\/25{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.shadow-bambu-green\/25{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)25%,transparent)var(--tw-shadow-alpha),transparent)}}.ring-bambu-green,.ring-bambu-green\/30{--tw-ring-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.ring-bambu-green\/30{--tw-ring-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.ring-blue-400\/50{--tw-ring-color:#54a2ff80}@supports (color:color-mix(in lab,red,red)){.ring-blue-400\/50{--tw-ring-color:color-mix(in oklab,var(--color-blue-400)50%,transparent)}}.ring-green-500{--tw-ring-color:var(--color-green-500)}.ring-white{--tw-ring-color:var(--color-white)}.ring-offset-1{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.ring-offset-2{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.ring-offset-bambu-dark{--tw-ring-offset-color:var(--color-bambu-dark)}.ring-offset-bambu-dark-secondary{--tw-ring-offset-color:var(--color-bambu-dark-secondary)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.blur-2xl{--tw-blur:blur(var(--blur-2xl));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.drop-shadow-lg{--tw-drop-shadow-size:drop-shadow(0 4px 4px var(--tw-drop-shadow-color,#00000026));--tw-drop-shadow:drop-shadow(var(--drop-shadow-lg));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.drop-shadow-md{--tw-drop-shadow-size:drop-shadow(0 3px 3px var(--tw-drop-shadow-color,#0000001f));--tw-drop-shadow:drop-shadow(var(--drop-shadow-md));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.\!filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)!important}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:bg-bambu-green\/20:is(:where(.group):hover *){background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.group-hover\:bg-bambu-green\/20:is(:where(.group):hover *){background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.group-hover\:break-all:is(:where(.group):hover *){word-break:break-all}.group-hover\:whitespace-normal:is(:where(.group):hover *){white-space:normal}.group-hover\:text-bambu-gray:is(:where(.group):hover *){color:var(--color-bambu-gray)}.group-hover\:text-bambu-green:is(:where(.group):hover *){color:var(--color-bambu-green)}.group-hover\:opacity-50:is(:where(.group):hover *){opacity:.5}.group-hover\:opacity-100:is(:where(.group):hover *),.group-hover\/resize\:opacity-100:is(:where(.group\/resize):hover *){opacity:1}.group-hover\/thumb\:block:is(:where(.group\/thumb):hover *){display:block}}.peer-checked\:bg-amber-500:is(:where(.peer):checked~*){background-color:var(--color-amber-500)}.peer-checked\:bg-bambu-green:is(:where(.peer):checked~*){background-color:var(--color-bambu-green)}.peer-focus\:ring-2:is(:where(.peer):focus~*){--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.peer-focus\:ring-bambu-green\/50:is(:where(.peer):focus~*){--tw-ring-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.peer-focus\:ring-bambu-green\/50:is(:where(.peer):focus~*){--tw-ring-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.peer-focus\:outline-none:is(:where(.peer):focus~*){--tw-outline-style:none;outline-style:none}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.placeholder\:text-bambu-gray::placeholder,.placeholder\:text-bambu-gray\/40::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder\:text-bambu-gray\/40::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)40%,transparent)}}.placeholder\:text-bambu-gray\/50::placeholder{color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.placeholder\:text-bambu-gray\/50::placeholder{color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:top-0:before{content:var(--tw-content);top:calc(var(--spacing)*0)}.before\:right-0:before{content:var(--tw-content);right:calc(var(--spacing)*0)}.before\:left-0:before{content:var(--tw-content);left:calc(var(--spacing)*0)}.before\:h-0\.5:before{content:var(--tw-content);height:calc(var(--spacing)*.5)}.before\:bg-bambu-green:before{content:var(--tw-content);background-color:var(--color-bambu-green)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:top-0\.5:after{content:var(--tw-content);top:calc(var(--spacing)*.5)}.after\:top-\[2px\]:after{content:var(--tw-content);top:2px}.after\:left-0\.5:after{content:var(--tw-content);left:calc(var(--spacing)*.5)}.after\:left-\[2px\]:after{content:var(--tw-content);left:2px}.after\:h-4:after{content:var(--tw-content);height:calc(var(--spacing)*4)}.after\:h-5:after{content:var(--tw-content);height:calc(var(--spacing)*5)}.after\:w-4:after{content:var(--tw-content);width:calc(var(--spacing)*4)}.after\:w-5:after{content:var(--tw-content);width:calc(var(--spacing)*5)}.after\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.after\:border:after{content:var(--tw-content);border-style:var(--tw-border-style);border-width:1px}.after\:border-gray-300:after{content:var(--tw-content);border-color:var(--color-gray-300)}.after\:bg-white:after{content:var(--tw-content);background-color:var(--color-white)}.after\:transition-all:after{content:var(--tw-content);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.after\:transition-transform:after{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}.peer-checked\:after\:translate-x-5:is(:where(.peer):checked~*):after{content:var(--tw-content);--tw-translate-x:calc(var(--spacing)*5);translate:var(--tw-translate-x)var(--tw-translate-y)}.peer-checked\:after\:translate-x-full:is(:where(.peer):checked~*):after{content:var(--tw-content);--tw-translate-x:100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.peer-checked\:after\:border-white:is(:where(.peer):checked~*):after{content:var(--tw-content);border-color:var(--color-white)}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.focus-within\:border-bambu-green:focus-within{border-color:var(--color-bambu-green)}@media(hover:hover){.hover\:z-20:hover{z-index:20}.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:scale-110:hover{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:border-amber-500:hover{border-color:var(--color-amber-500)}.hover\:border-bambu-dark-tertiary\/80:hover{border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-dark-tertiary\/80:hover{border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.hover\:border-bambu-gray:hover{border-color:var(--color-bambu-gray)}.hover\:border-bambu-gray-dark:hover{border-color:var(--color-bambu-gray-dark)}.hover\:border-bambu-gray\/50:hover{border-color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-gray\/50:hover{border-color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.hover\:border-bambu-green:hover,.hover\:border-bambu-green\/40:hover{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-green\/40:hover{border-color:color-mix(in oklab,var(--color-bambu-green)40%,transparent)}}.hover\:border-bambu-green\/50:hover{border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:border-bambu-green\/50:hover{border-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.hover\:border-gray-400:hover{border-color:var(--color-gray-400)}.hover\:border-green-500\/50:hover{border-color:#00c75880}@supports (color:color-mix(in lab,red,red)){.hover\:border-green-500\/50:hover{border-color:color-mix(in oklab,var(--color-green-500)50%,transparent)}}.hover\:border-white:hover{border-color:var(--color-white)}.hover\:border-white\/40:hover{border-color:#fff6}@supports (color:color-mix(in lab,red,red)){.hover\:border-white\/40:hover{border-color:color-mix(in oklab,var(--color-white)40%,transparent)}}.hover\:\!bg-bambu-green\/80:hover{background-color:var(--color-bambu-green)!important}@supports (color:color-mix(in lab,red,red)){.hover\:\!bg-bambu-green\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-green)80%,transparent)!important}}.hover\:\!bg-green-500\/20:hover{background-color:#00c75833!important}@supports (color:color-mix(in lab,red,red)){.hover\:\!bg-green-500\/20:hover{background-color:color-mix(in oklab,var(--color-green-500)20%,transparent)!important}}.hover\:\!bg-yellow-500\/20:hover{background-color:#edb20033!important}@supports (color:color-mix(in lab,red,red)){.hover\:\!bg-yellow-500\/20:hover{background-color:color-mix(in oklab,var(--color-yellow-500)20%,transparent)!important}}.hover\:bg-amber-400:hover{background-color:var(--color-amber-400)}.hover\:bg-amber-500\/20:hover{background-color:#f99c0033}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-500\/20:hover{background-color:color-mix(in oklab,var(--color-amber-500)20%,transparent)}}.hover\:bg-amber-500\/30:hover{background-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-500\/30:hover{background-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.hover\:bg-amber-700:hover{background-color:var(--color-amber-700)}.hover\:bg-amber-900\/50:hover{background-color:#7b330680}@supports (color:color-mix(in lab,red,red)){.hover\:bg-amber-900\/50:hover{background-color:color-mix(in oklab,var(--color-amber-900)50%,transparent)}}.hover\:bg-bambu-dark:hover{background-color:var(--color-bambu-dark)}.hover\:bg-bambu-dark-secondary:hover,.hover\:bg-bambu-dark-secondary\/50:hover{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-secondary\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)50%,transparent)}}.hover\:bg-bambu-dark-secondary\/80:hover{background-color:var(--color-bambu-dark-secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-secondary\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-secondary)80%,transparent)}}.hover\:bg-bambu-dark-tertiary:hover,.hover\:bg-bambu-dark-tertiary\/30:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/30:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)30%,transparent)}}.hover\:bg-bambu-dark-tertiary\/40:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/40:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)40%,transparent)}}.hover\:bg-bambu-dark-tertiary\/50:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.hover\:bg-bambu-dark-tertiary\/70:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/70:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)70%,transparent)}}.hover\:bg-bambu-dark-tertiary\/80:hover{background-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark-tertiary\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)80%,transparent)}}.hover\:bg-bambu-dark\/50:hover{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.hover\:bg-bambu-dark\/80:hover{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-dark\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-dark)80%,transparent)}}.hover\:bg-bambu-gray-dark:hover{background-color:var(--color-bambu-gray-dark)}.hover\:bg-bambu-green:hover{background-color:var(--color-bambu-green)}.hover\:bg-bambu-green-dark:hover{background-color:var(--color-bambu-green-dark)}.hover\:bg-bambu-green-light:hover{background-color:var(--color-bambu-green-light)}.hover\:bg-bambu-green\/10:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/10:hover{background-color:color-mix(in oklab,var(--color-bambu-green)10%,transparent)}}.hover\:bg-bambu-green\/20:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/20:hover{background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.hover\:bg-bambu-green\/30:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/30:hover{background-color:color-mix(in oklab,var(--color-bambu-green)30%,transparent)}}.hover\:bg-bambu-green\/50:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/50:hover{background-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.hover\:bg-bambu-green\/80:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/80:hover{background-color:color-mix(in oklab,var(--color-bambu-green)80%,transparent)}}.hover\:bg-bambu-green\/90:hover{background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-bambu-green\/90:hover{background-color:color-mix(in oklab,var(--color-bambu-green)90%,transparent)}}.hover\:bg-black\/40:hover{background-color:#0006}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/40:hover{background-color:color-mix(in oklab,var(--color-black)40%,transparent)}}.hover\:bg-black\/70:hover{background-color:#000000b3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/70:hover{background-color:color-mix(in oklab,var(--color-black)70%,transparent)}}.hover\:bg-black\/80:hover{background-color:#000c}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/80:hover{background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.hover\:bg-blue-500\/20:hover{background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-blue-500\/20:hover{background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.hover\:bg-blue-500\/30:hover{background-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-blue-500\/30:hover{background-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.hover\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-emerald-600:hover{background-color:var(--color-emerald-600)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.hover\:bg-green-500\/20:hover{background-color:#00c75833}@supports (color:color-mix(in lab,red,red)){.hover\:bg-green-500\/20:hover{background-color:color-mix(in oklab,var(--color-green-500)20%,transparent)}}.hover\:bg-green-600:hover{background-color:var(--color-green-600)}.hover\:bg-green-700:hover{background-color:var(--color-green-700)}.hover\:bg-indigo-500\/20:hover{background-color:#625fff33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-indigo-500\/20:hover{background-color:color-mix(in oklab,var(--color-indigo-500)20%,transparent)}}.hover\:bg-indigo-500\/30:hover{background-color:#625fff4d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-indigo-500\/30:hover{background-color:color-mix(in oklab,var(--color-indigo-500)30%,transparent)}}.hover\:bg-orange-400\/20:hover{background-color:#ff8b1a33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-orange-400\/20:hover{background-color:color-mix(in oklab,var(--color-orange-400)20%,transparent)}}.hover\:bg-orange-500\/20:hover{background-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.hover\:bg-orange-500\/20:hover{background-color:color-mix(in oklab,var(--color-orange-500)20%,transparent)}}.hover\:bg-purple-600\/90:hover{background-color:#9810fae6}@supports (color:color-mix(in lab,red,red)){.hover\:bg-purple-600\/90:hover{background-color:color-mix(in oklab,var(--color-purple-600)90%,transparent)}}.hover\:bg-red-200:hover{background-color:var(--color-red-200)}.hover\:bg-red-400\/10:hover{background-color:#ff65681a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-400\/10:hover{background-color:color-mix(in oklab,var(--color-red-400)10%,transparent)}}.hover\:bg-red-500\/10:hover{background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/10:hover{background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.hover\:bg-red-500\/20:hover{background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/20:hover{background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.hover\:bg-red-500\/25:hover{background-color:#fb2c3640}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/25:hover{background-color:color-mix(in oklab,var(--color-red-500)25%,transparent)}}.hover\:bg-red-500\/30:hover{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-500\/30:hover{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:bg-red-600\/30:hover{background-color:#e400144d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-600\/30:hover{background-color:color-mix(in oklab,var(--color-red-600)30%,transparent)}}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:bg-red-900\/50:hover{background-color:#82181a80}@supports (color:color-mix(in lab,red,red)){.hover\:bg-red-900\/50:hover{background-color:color-mix(in oklab,var(--color-red-900)50%,transparent)}}.hover\:bg-sky-500\/20:hover{background-color:#00a5ef33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sky-500\/20:hover{background-color:color-mix(in oklab,var(--color-sky-500)20%,transparent)}}.hover\:bg-white\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/5:hover{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.hover\:bg-white\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/10:hover{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.hover\:bg-white\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/20:hover{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}.hover\:bg-white\/80:hover{background-color:#fffc}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/80:hover{background-color:color-mix(in oklab,var(--color-white)80%,transparent)}}.hover\:bg-yellow-500\/25:hover{background-color:#edb20040}@supports (color:color-mix(in lab,red,red)){.hover\:bg-yellow-500\/25:hover{background-color:color-mix(in oklab,var(--color-yellow-500)25%,transparent)}}.hover\:bg-yellow-500\/30:hover{background-color:#edb2004d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-yellow-500\/30:hover{background-color:color-mix(in oklab,var(--color-yellow-500)30%,transparent)}}.hover\:bg-yellow-600:hover{background-color:var(--color-yellow-600)}.hover\:bg-zinc-600:hover{background-color:var(--color-zinc-600)}.hover\:bg-zinc-700:hover{background-color:var(--color-zinc-700)}.hover\:bg-zinc-700\/50:hover{background-color:#3f3f4680}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-700\/50:hover{background-color:color-mix(in oklab,var(--color-zinc-700)50%,transparent)}}.hover\:bg-zinc-700\/60:hover{background-color:#3f3f4699}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-700\/60:hover{background-color:color-mix(in oklab,var(--color-zinc-700)60%,transparent)}}.hover\:bg-zinc-800:hover{background-color:var(--color-zinc-800)}.hover\:text-amber-300:hover{color:var(--color-amber-300)}.hover\:text-amber-800:hover{color:var(--color-amber-800)}.hover\:text-bambu-gray:hover{color:var(--color-bambu-gray)}.hover\:text-bambu-green:hover{color:var(--color-bambu-green)}.hover\:text-bambu-green-light:hover{color:var(--color-bambu-green-light)}.hover\:text-bambu-green\/70:hover{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:text-bambu-green\/70:hover{color:color-mix(in oklab,var(--color-bambu-green)70%,transparent)}}.hover\:text-bambu-green\/80:hover{color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:text-bambu-green\/80:hover{color:color-mix(in oklab,var(--color-bambu-green)80%,transparent)}}.hover\:text-blue-300:hover{color:var(--color-blue-300)}.hover\:text-blue-400:hover{color:var(--color-blue-400)}.hover\:text-blue-600:hover{color:var(--color-blue-600)}.hover\:text-blue-800:hover{color:var(--color-blue-800)}.hover\:text-gray-600:hover{color:var(--color-gray-600)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-orange-300:hover{color:var(--color-orange-300)}.hover\:text-red-200:hover{color:var(--color-red-200)}.hover\:text-red-300:hover{color:var(--color-red-300)}.hover\:text-red-400:hover{color:var(--color-red-400)}.hover\:text-red-800:hover{color:var(--color-red-800)}.hover\:text-white:hover{color:var(--color-white)}.hover\:text-white\/60:hover{color:#fff9}@supports (color:color-mix(in lab,red,red)){.hover\:text-white\/60:hover{color:color-mix(in oklab,var(--color-white)60%,transparent)}}.hover\:text-white\/70:hover{color:#ffffffb3}@supports (color:color-mix(in lab,red,red)){.hover\:text-white\/70:hover{color:color-mix(in oklab,var(--color-white)70%,transparent)}}.hover\:text-white\/80:hover{color:#fffc}@supports (color:color-mix(in lab,red,red)){.hover\:text-white\/80:hover{color:color-mix(in oklab,var(--color-white)80%,transparent)}}.hover\:text-yellow-400:hover{color:var(--color-yellow-400)}.hover\:text-zinc-200:hover{color:var(--color-zinc-200)}.hover\:text-zinc-300:hover{color:var(--color-zinc-300)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-70:hover{opacity:.7}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-xl:hover{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-bambu-green\/5:hover{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-bambu-green\/5:hover{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)5%,transparent)var(--tw-shadow-alpha),transparent)}}.hover\:shadow-bambu-green\/30:hover{--tw-shadow-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.hover\:shadow-bambu-green\/30:hover{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-bambu-green)30%,transparent)var(--tw-shadow-alpha),transparent)}}}.focus\:border-amber-500\/50:focus{border-color:#f99c0080}@supports (color:color-mix(in lab,red,red)){.focus\:border-amber-500\/50:focus{border-color:color-mix(in oklab,var(--color-amber-500)50%,transparent)}}.focus\:border-bambu-gray:focus{border-color:var(--color-bambu-gray)}.focus\:border-bambu-green:focus{border-color:var(--color-bambu-green)}.focus\:border-red-500:focus{border-color:var(--color-red-500)}.focus\:border-transparent:focus{border-color:#0000}.focus\:ring-0:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-bambu-gray:focus{--tw-ring-color:var(--color-bambu-gray)}.focus\:ring-bambu-green:focus,.focus\:ring-bambu-green\/50:focus{--tw-ring-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.focus\:ring-bambu-green\/50:focus{--tw-ring-color:color-mix(in oklab,var(--color-bambu-green)50%,transparent)}}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\:ring-red-500:focus{--tw-ring-color:var(--color-red-500)}.focus\:ring-offset-0:focus{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-bambu-dark:focus{--tw-ring-offset-color:var(--color-bambu-dark)}.focus\:ring-offset-bambu-dark-secondary:focus{--tw-ring-offset-color:var(--color-bambu-dark-secondary)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}.active\:cursor-grabbing:active{cursor:grabbing}.active\:bg-amber-500\/30:active{background-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.active\:bg-amber-500\/30:active{background-color:color-mix(in oklab,var(--color-amber-500)30%,transparent)}}.active\:opacity-50:active{opacity:.5}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:cursor-wait:disabled{cursor:wait}.disabled\:bg-gray-600:disabled{background-color:var(--color-gray-600)}.disabled\:bg-zinc-700:disabled{background-color:var(--color-zinc-700)}.disabled\:no-underline:disabled{text-decoration-line:none}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media(hover:hover){.disabled\:hover\:border-bambu-dark-tertiary:disabled:hover{border-color:var(--color-bambu-dark-tertiary)}.disabled\:hover\:bg-bambu-dark:disabled:hover{background-color:var(--color-bambu-dark)}.disabled\:hover\:bg-bambu-green:disabled:hover{background-color:var(--color-bambu-green)}}@media not all and (min-width:640px){.max-\[640px\]\:hidden{display:none}.max-\[640px\]\:w-full{width:100%}.max-\[640px\]\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.max-\[640px\]\:flex-col{flex-direction:column}.max-\[640px\]\:flex-wrap{flex-wrap:wrap}.max-\[640px\]\:items-center{align-items:center}.max-\[640px\]\:items-start{align-items:flex-start}}@media not all and (min-width:550px){.max-\[550px\]\:order-1{order:1}.max-\[550px\]\:order-2{order:2}.max-\[550px\]\:order-3{order:3}.max-\[550px\]\:order-4{order:4}.max-\[550px\]\:mt-1{margin-top:calc(var(--spacing)*1)}.max-\[550px\]\:w-full{width:100%}.max-\[550px\]\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.max-\[550px\]\:flex-col{flex-direction:column}.max-\[550px\]\:flex-wrap{flex-wrap:wrap}.max-\[550px\]\:items-center{align-items:center}.max-\[550px\]\:items-start{align-items:flex-start}.max-\[550px\]\:justify-end{justify-content:flex-end}.max-\[550px\]\:gap-3{gap:calc(var(--spacing)*3)}.max-\[550px\]\:self-start{align-self:flex-start}}@media(min-width:40rem){.sm\:mt-0{margin-top:calc(var(--spacing)*0)}.sm\:mt-2{margin-top:calc(var(--spacing)*2)}.sm\:mt-3{margin-top:calc(var(--spacing)*3)}.sm\:mr-1{margin-right:calc(var(--spacing)*1)}.sm\:mb-4{margin-bottom:calc(var(--spacing)*4)}.sm\:ml-\[68px\]{margin-left:68px}.sm\:ml-auto{margin-left:auto}.sm\:block{display:block}.sm\:flex{display:flex}.sm\:grid{display:grid}.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:h-2{height:calc(var(--spacing)*2)}.sm\:h-3{height:calc(var(--spacing)*3)}.sm\:h-3\.5{height:calc(var(--spacing)*3.5)}.sm\:h-4{height:calc(var(--spacing)*4)}.sm\:h-5{height:calc(var(--spacing)*5)}.sm\:h-6{height:calc(var(--spacing)*6)}.sm\:h-14{height:calc(var(--spacing)*14)}.sm\:w-3{width:calc(var(--spacing)*3)}.sm\:w-3\.5{width:calc(var(--spacing)*3.5)}.sm\:w-4{width:calc(var(--spacing)*4)}.sm\:w-5{width:calc(var(--spacing)*5)}.sm\:w-6{width:calc(var(--spacing)*6)}.sm\:w-14{width:calc(var(--spacing)*14)}.sm\:w-16{width:calc(var(--spacing)*16)}.sm\:w-40{width:calc(var(--spacing)*40)}.sm\:w-72{width:calc(var(--spacing)*72)}.sm\:w-auto{width:auto}.sm\:max-w-none{max-width:none}.sm\:max-w-xs{max-width:var(--container-xs)}.sm\:flex-1{flex:1}.sm\:flex-none{flex:none}.sm\:cursor-default{cursor:default}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}.sm\:gap-1{gap:calc(var(--spacing)*1)}.sm\:gap-1\.5{gap:calc(var(--spacing)*1.5)}.sm\:gap-2{gap:calc(var(--spacing)*2)}.sm\:gap-3{gap:calc(var(--spacing)*3)}.sm\:gap-4{gap:calc(var(--spacing)*4)}.sm\:gap-5{gap:calc(var(--spacing)*5)}.sm\:gap-6{gap:calc(var(--spacing)*6)}:where(.sm\:space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}.sm\:border-bambu-dark-tertiary{border-color:var(--color-bambu-dark-tertiary)}.sm\:p-1\.5{padding:calc(var(--spacing)*1.5)}.sm\:p-2{padding:calc(var(--spacing)*2)}.sm\:p-3{padding:calc(var(--spacing)*3)}.sm\:p-4{padding:calc(var(--spacing)*4)}.sm\:px-2{padding-inline:calc(var(--spacing)*2)}.sm\:px-3{padding-inline:calc(var(--spacing)*3)}.sm\:px-4{padding-inline:calc(var(--spacing)*4)}.sm\:text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.sm\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.sm\:text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}}@media(min-width:48rem){.md\:top-\[2px\]{top:2px}.md\:left-\[2px\]{left:2px}.md\:col-span-2{grid-column:span 2/span 2}.md\:mx-0{margin-inline:calc(var(--spacing)*0)}.md\:block{display:block}.md\:inline{display:inline}.md\:h-4{height:calc(var(--spacing)*4)}.md\:h-5{height:calc(var(--spacing)*5)}.md\:min-h-0{min-height:calc(var(--spacing)*0)}.md\:w-4{width:calc(var(--spacing)*4)}.md\:w-9{width:calc(var(--spacing)*9)}.md\:min-w-\[200px\]{min-width:200px}.md\:flex-1{flex:1}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:grid-cols-\[1fr_140px_auto\]{grid-template-columns:1fr 140px auto}.md\:flex-row{flex-direction:row}.md\:flex-wrap{flex-wrap:wrap}.md\:items-center{align-items:center}.md\:gap-4{gap:calc(var(--spacing)*4)}.md\:p-6{padding:calc(var(--spacing)*6)}.md\:p-8{padding:calc(var(--spacing)*8)}.md\:px-0{padding-inline:calc(var(--spacing)*0)}.md\:py-2{padding-block:calc(var(--spacing)*2)}.md\:pb-0{padding-bottom:calc(var(--spacing)*0)}}@media(min-width:64rem){.lg\:static{position:static}.lg\:sticky{position:sticky}.lg\:top-4{top:calc(var(--spacing)*4)}.lg\:top-6{top:calc(var(--spacing)*6)}.lg\:col-span-2{grid-column:span 2/span 2}.lg\:mb-0{margin-bottom:calc(var(--spacing)*0)}.lg\:-ml-px{margin-left:-1px}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:h-\[calc\(100vh-64px\)\]{height:calc(100vh - 64px)}.lg\:w-1\/2{width:50%}.lg\:w-1\/3{width:33.3333%}.lg\:w-2\/3{width:66.6667%}.lg\:w-48{width:calc(var(--spacing)*48)}.lg\:w-80{width:calc(var(--spacing)*80)}.lg\:w-\[480px\]{width:480px}.lg\:max-w-md{max-width:var(--container-md)}.lg\:max-w-sm{max-width:var(--container-sm)}.lg\:max-w-xl{max-width:var(--container-xl)}.lg\:flex-shrink-0{flex-shrink:0}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:grid-cols-\[1fr_20rem\]{grid-template-columns:1fr 20rem}.lg\:flex-col{flex-direction:column}.lg\:flex-row{flex-direction:row}.lg\:flex-nowrap{flex-wrap:nowrap}.lg\:justify-start{justify-content:flex-start}.lg\:gap-0{gap:calc(var(--spacing)*0)}.lg\:gap-6{gap:calc(var(--spacing)*6)}.lg\:gap-8{gap:calc(var(--spacing)*8)}.lg\:self-start{align-self:flex-start}.lg\:overflow-y-auto{overflow-y:auto}.lg\:border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.lg\:border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.lg\:border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}}@media(min-width:80rem){.xl\:inline{display:inline}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}@media(min-width:96rem){.\32xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}:where(.dark\:divide-gray-800:where(.dark,.dark *)>:not(:last-child)){border-color:var(--color-gray-800)}.dark\:border-amber-700:where(.dark,.dark *){border-color:var(--color-amber-700)}.dark\:border-amber-800:where(.dark,.dark *){border-color:var(--color-amber-800)}.dark\:border-bambu-dark-tertiary:where(.dark,.dark *),.dark\:border-bambu-dark-tertiary\/50:where(.dark,.dark *){border-color:var(--color-bambu-dark-tertiary)}@supports (color:color-mix(in lab,red,red)){.dark\:border-bambu-dark-tertiary\/50:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-bambu-dark-tertiary)50%,transparent)}}.dark\:border-bambu-green\/40:where(.dark,.dark *){border-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:border-bambu-green\/40:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-bambu-green)40%,transparent)}}.dark\:border-gray-600:where(.dark,.dark *){border-color:var(--color-gray-600)}.dark\:border-gray-700:where(.dark,.dark *){border-color:var(--color-gray-700)}.dark\:border-red-500\/30:where(.dark,.dark *){border-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.dark\:border-red-500\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.dark\:border-red-500\/40:where(.dark,.dark *){border-color:#fb2c3666}@supports (color:color-mix(in lab,red,red)){.dark\:border-red-500\/40:where(.dark,.dark *){border-color:color-mix(in oklab,var(--color-red-500)40%,transparent)}}.dark\:bg-amber-500\/10:where(.dark,.dark *){background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-amber-500)10%,transparent)}}.dark\:bg-amber-900\/20:where(.dark,.dark *){background-color:#7b330633}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-900\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-amber-900)20%,transparent)}}.dark\:bg-bambu-dark:where(.dark,.dark *){background-color:var(--color-bambu-dark)}.dark\:bg-bambu-dark-secondary:where(.dark,.dark *){background-color:var(--color-bambu-dark-secondary)}.dark\:bg-bambu-green\/20:where(.dark,.dark *){background-color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-bambu-green\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-bambu-green)20%,transparent)}}.dark\:bg-black\/80:where(.dark,.dark *){background-color:#000c}@supports (color:color-mix(in lab,red,red)){.dark\:bg-black\/80:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-black)80%,transparent)}}.dark\:bg-blue-500\/10:where(.dark,.dark *){background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.dark\:bg-blue-500\/20:where(.dark,.dark *){background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-500\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.dark\:bg-blue-900\/20:where(.dark,.dark *){background-color:#1c398e33}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-900\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-blue-900)20%,transparent)}}.dark\:bg-gray-700:where(.dark,.dark *){background-color:var(--color-gray-700)}.dark\:bg-gray-800:where(.dark,.dark *){background-color:var(--color-gray-800)}.dark\:bg-gray-800\/30:where(.dark,.dark *){background-color:#1e29394d}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-800\/30:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-gray-800)30%,transparent)}}.dark\:bg-gray-800\/40:where(.dark,.dark *){background-color:#1e293966}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-800\/40:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-gray-800)40%,transparent)}}.dark\:bg-gray-800\/50:where(.dark,.dark *){background-color:#1e293980}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-800\/50:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-gray-800)50%,transparent)}}.dark\:bg-gray-900:where(.dark,.dark *){background-color:var(--color-gray-900)}.dark\:bg-red-500\/10:where(.dark,.dark *){background-color:#fb2c361a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-500\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-red-500)10%,transparent)}}.dark\:bg-red-500\/20:where(.dark,.dark *){background-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-500\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--color-red-500)20%,transparent)}}.dark\:text-amber-100:where(.dark,.dark *){color:var(--color-amber-100)}.dark\:text-amber-200:where(.dark,.dark *){color:var(--color-amber-200)}.dark\:text-amber-300:where(.dark,.dark *){color:var(--color-amber-300)}.dark\:text-amber-400:where(.dark,.dark *){color:var(--color-amber-400)}.dark\:text-bambu-gray:where(.dark,.dark *),.dark\:text-bambu-gray\/30:where(.dark,.dark *){color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-gray\/30:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-gray)30%,transparent)}}.dark\:text-bambu-gray\/50:where(.dark,.dark *){color:var(--color-bambu-gray)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-gray\/50:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-gray)50%,transparent)}}.dark\:text-bambu-green:where(.dark,.dark *),.dark\:text-bambu-green\/60:where(.dark,.dark *){color:var(--color-bambu-green)}@supports (color:color-mix(in lab,red,red)){.dark\:text-bambu-green\/60:where(.dark,.dark *){color:color-mix(in oklab,var(--color-bambu-green)60%,transparent)}}.dark\:text-blue-200:where(.dark,.dark *){color:var(--color-blue-200)}.dark\:text-blue-200\/80:where(.dark,.dark *){color:#bedbffcc}@supports (color:color-mix(in lab,red,red)){.dark\:text-blue-200\/80:where(.dark,.dark *){color:color-mix(in oklab,var(--color-blue-200)80%,transparent)}}.dark\:text-blue-300:where(.dark,.dark *){color:var(--color-blue-300)}.dark\:text-blue-300\/60:where(.dark,.dark *){color:#90c5ff99}@supports (color:color-mix(in lab,red,red)){.dark\:text-blue-300\/60:where(.dark,.dark *){color:color-mix(in oklab,var(--color-blue-300)60%,transparent)}}.dark\:text-blue-400:where(.dark,.dark *){color:var(--color-blue-400)}.dark\:text-emerald-300:where(.dark,.dark *){color:var(--color-emerald-300)}.dark\:text-emerald-400:where(.dark,.dark *){color:var(--color-emerald-400)}.dark\:text-gray-100:where(.dark,.dark *){color:var(--color-gray-100)}.dark\:text-gray-300:where(.dark,.dark *){color:var(--color-gray-300)}.dark\:text-gray-400:where(.dark,.dark *){color:var(--color-gray-400)}.dark\:text-gray-500:where(.dark,.dark *){color:var(--color-gray-500)}.dark\:text-gray-600:where(.dark,.dark *){color:var(--color-gray-600)}.dark\:text-green-400:where(.dark,.dark *){color:var(--color-green-400)}.dark\:text-orange-200:where(.dark,.dark *){color:var(--color-orange-200)}.dark\:text-orange-400:where(.dark,.dark *){color:var(--color-orange-400)}.dark\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.dark\:text-red-400\/70:where(.dark,.dark *){color:#ff6568b3}@supports (color:color-mix(in lab,red,red)){.dark\:text-red-400\/70:where(.dark,.dark *){color:color-mix(in oklab,var(--color-red-400)70%,transparent)}}.dark\:text-white:where(.dark,.dark *){color:var(--color-white)}.dark\:text-yellow-200:where(.dark,.dark *){color:var(--color-yellow-200)}.dark\:text-yellow-200\/70:where(.dark,.dark *){color:#fff085b3}@supports (color:color-mix(in lab,red,red)){.dark\:text-yellow-200\/70:where(.dark,.dark *){color:color-mix(in oklab,var(--color-yellow-200)70%,transparent)}}@media(hover:hover){.dark\:hover\:border-gray-500:where(.dark,.dark *):hover{border-color:var(--color-gray-500)}.dark\:hover\:bg-bambu-dark-tertiary:where(.dark,.dark *):hover{background-color:var(--color-bambu-dark-tertiary)}.dark\:hover\:bg-bambu-dark\/50:where(.dark,.dark *):hover{background-color:var(--color-bambu-dark)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-bambu-dark\/50:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-bambu-dark)50%,transparent)}}.dark\:hover\:bg-gray-600:where(.dark,.dark *):hover{background-color:var(--color-gray-600)}.dark\:hover\:bg-gray-800\/50:where(.dark,.dark *):hover{background-color:#1e293980}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-gray-800\/50:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-gray-800)50%,transparent)}}.dark\:hover\:bg-red-500\/30:where(.dark,.dark *):hover{background-color:#fb2c364d}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-red-500\/30:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--color-red-500)30%,transparent)}}.dark\:hover\:text-amber-200:where(.dark,.dark *):hover{color:var(--color-amber-200)}.dark\:hover\:text-blue-300:where(.dark,.dark *):hover{color:var(--color-blue-300)}.dark\:hover\:text-gray-200:where(.dark,.dark *):hover{color:var(--color-gray-200)}.dark\:hover\:text-gray-300:where(.dark,.dark *):hover{color:var(--color-gray-300)}.dark\:hover\:text-red-300:where(.dark,.dark *):hover{color:var(--color-red-300)}.dark\:hover\:text-white:where(.dark,.dark *):hover{color:var(--color-white)}}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{appearance:none}.\[\&\:\:-webkit-outer-spin-button\]\:appearance-none::-webkit-outer-spin-button{appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:h-3::-webkit-slider-thumb{height:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:w-3::-webkit-slider-thumb{width:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:cursor-pointer::-webkit-slider-thumb{cursor:pointer}.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb{appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb{border-radius:3.40282e38px}.\[\&\:\:-webkit-slider-thumb\]\:bg-bambu-green::-webkit-slider-thumb{background-color:var(--color-bambu-green)}.\[\&\>\*\]\:shrink-0>*{flex-shrink:0}}html{font-size:14.4px}:root{--accent:#00ae42;--accent-light:#00c64d;--accent-dark:#009438;--status-ok:#22c55e;--status-error:#ef4444;--status-warning:#f59e0b;--bg-primary:#f5f5f5;--bg-secondary:#fff;--bg-tertiary:#e5e5e5;--text-primary:#1a1a1a;--text-secondary:#4a4a4a;--text-muted:#6b6b6b;--text-tertiary:gray;--border-color:#d4d4d4;--card-shadow:0 2px 8px #00000014;--glow-color:transparent;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,system-ui,sans-serif;font-weight:400;line-height:1.5}.dark{--bg-primary:#1a1a1a;--bg-secondary:#2d2d2d;--bg-tertiary:#3d3d3d;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:gray;--text-tertiary:#4a4a4a;--border-color:#3d3d3d;--card-shadow:0 4px 16px #0006}.bg-warm{--bg-primary:#faf8f5;--bg-secondary:#fffefa;--bg-tertiary:#e8e4dd;--text-primary:#2d2a26;--text-secondary:#5c5750;--text-muted:#7a756c;--text-tertiary:#9a9590;--border-color:#d8d4cc}.bg-cool{--bg-primary:#f0f4f8;--bg-secondary:#fff;--bg-tertiary:#dce4ec;--text-primary:#1a2530;--text-secondary:#4a5568;--text-muted:#6b7a8a;--text-tertiary:#8a9aaa;--border-color:#c8d4e0}.dark.bg-neutral{--bg-primary:#1a1a1a;--bg-secondary:#2d2d2d;--bg-tertiary:#3d3d3d;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:gray;--text-tertiary:#4a4a4a;--border-color:#3d3d3d}.dark.bg-warm{--bg-primary:#1c1a18;--bg-secondary:#2e2a26;--bg-tertiary:#3e3a36;--text-primary:#f5f0ea;--text-secondary:#b0a898;--text-muted:#8a8278;--text-tertiary:#5a5248;--border-color:#3e3a36}.dark.bg-cool{--bg-primary:#181c20;--bg-secondary:#262c32;--bg-tertiary:#363e46;--text-primary:#f0f4f8;--text-secondary:#98a8b8;--text-muted:#788898;--text-tertiary:#4a5a6a;--border-color:#363e46}.dark.bg-oled{--bg-primary:#000;--bg-secondary:#141414;--bg-tertiary:#1f1f1f;--text-primary:#fff;--text-secondary:#a0a0a0;--text-muted:#707070;--text-tertiary:#404040;--border-color:#2a2a2a}.dark.bg-slate{--bg-primary:#0f172a;--bg-secondary:#1e293b;--bg-tertiary:#334155;--text-primary:#f1f5f9;--text-secondary:#94a3b8;--text-muted:#64748b;--text-tertiary:#475569;--border-color:#334155}.dark.bg-forest{--bg-primary:#121a16;--bg-secondary:#1c2a22;--bg-tertiary:#2a3d30;--text-primary:#e8f5ec;--text-secondary:#8aa894;--text-muted:#6a8874;--text-tertiary:#4a6854;--border-color:#2a3d30}.printer-control-buttons-container{container-type:inline-size}@container (max-width:220px){.printer-control-buttons{flex-direction:column;align-items:stretch}.printer-control-buttons>button{width:100%}}.style-glow{--card-shadow:0 2px 8px #00000014,0 0 25px var(--accent)}@supports (color:color-mix(in lab,red,red)){.style-glow{--card-shadow:0 2px 8px #00000014,0 0 25px color-mix(in srgb,var(--accent)12%,transparent)}}.dark.style-glow{--card-shadow:0 4px 20px #00000080,0 0 40px var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark.style-glow{--card-shadow:0 4px 20px #00000080,0 0 40px color-mix(in srgb,var(--accent)15%,transparent)}}.style-vibrant{--card-shadow:0 8px 30px #00000026,0 2px 8px #0000001a}.dark.style-vibrant{--card-shadow:0 10px 40px #0009,0 4px 12px #0006}.accent-green{--accent:#00ae42;--accent-light:#00c64d;--accent-dark:#009438}.accent-teal{--accent:#14b8a6;--accent-light:#2dd4bf;--accent-dark:#0d9488}.accent-blue{--accent:#3b82f6;--accent-light:#60a5fa;--accent-dark:#2563eb}.accent-orange{--accent:#f97316;--accent-light:#fb923c;--accent-dark:#ea580c}.accent-purple{--accent:#8b5cf6;--accent-light:#a78bfa;--accent-dark:#7c3aed}.accent-red{--accent:#ef4444;--accent-light:#f87171;--accent-dark:#dc2626}body{background-color:var(--bg-primary);color:var(--text-primary);min-height:100vh;margin:0;transition:background-color .2s,color .2s}#root{min-height:100vh}.text-white{color:var(--text-primary)}.bg-bambu-dark,.bg-bambu-dark-secondary,.bg-bambu-dark-tertiary,.border-bambu-dark-tertiary{transition:background-color .2s,border-color .2s}@keyframes slide-in{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}.animate-slide-in{animation:.2s ease-out slide-in}.icon-theme{opacity:.5}.dark .icon-theme{filter:invert();opacity:.4}.icon-green{filter:invert(48%)sepia(89%)saturate(459%)hue-rotate(93deg)brightness(95%)contrast(92%);opacity:1}.icon-heating{filter:invert(50%)sepia()saturate(1000%)hue-rotate(360deg)brightness()contrast();opacity:1}.dark .jogpad-theme{filter:brightness(.35)contrast(1.2)}.ams-empty-slot{background:repeating-linear-gradient(45deg,#444,#444 2px,#222 2px 4px)}.dark .ams-empty-slot{background:repeating-linear-gradient(45deg,#555,#555 2px,#333 2px 4px)}.touch-manipulation{touch-action:manipulation}.safe-area-bottom{padding-bottom:env(safe-area-inset-bottom,0)}.safe-area-top{padding-top:env(safe-area-inset-top,0)}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}@keyframes slide-in-left{0%{transform:translate(-100%)}to{transform:translate(0)}}.animate-slide-in-left{animation:.3s ease-out slide-in-left}@keyframes spoolbuddy-optimized-ping{0%{opacity:.8;transform:scale(.8)}80%,to{opacity:0;transform:scale(2.2)}}.spoolbuddy-optimized-ping{will-change:auto;contain:layout;animation:3.5s cubic-bezier(0,0,.2,1) infinite spoolbuddy-optimized-ping}.spoolbuddy-spool-glow{will-change:auto;transform:scale(2)}@media(prefers-reduced-motion:reduce){.spoolbuddy-optimized-ping{opacity:.25;animation:none;transform:scale(1.2)}.spoolbuddy-spool-glow{transition:none}}@keyframes slide-down{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.animate-slide-down{animation:.25s ease-out slide-down}.card-shadow{box-shadow:var(--card-shadow)}[data-spoolbuddy-kiosk] .fixed .relative.max-w-2xl{flex-direction:column;height:90vh;max-height:90vh;display:flex}[data-spoolbuddy-kiosk] .fixed .relative.max-w-2xl>div:first-child,[data-spoolbuddy-kiosk] .fixed .relative.max-w-2xl>div:last-child{flex-shrink:0}[data-spoolbuddy-kiosk] .fixed .relative.max-w-2xl>div:nth-child(2){flex:auto;min-height:0;overflow-y:auto}[data-spoolbuddy-kiosk] .fixed .relative.max-w-2xl .max-h-96{max-height:none}.calendar-scroll{scrollbar-width:thin;scrollbar-color:var(--text-muted)transparent}@supports (color:color-mix(in lab,red,red)){.calendar-scroll{scrollbar-color:color-mix(in srgb,var(--text-muted)60%,transparent)transparent}}.calendar-scroll::-webkit-scrollbar{width:8px}.calendar-scroll::-webkit-scrollbar-track{background:0 0}.calendar-scroll::-webkit-scrollbar-thumb{background-color:var(--text-muted)}@supports (color:color-mix(in lab,red,red)){.calendar-scroll::-webkit-scrollbar-thumb{background-color:color-mix(in srgb,var(--text-muted)60%,transparent)}}.calendar-scroll::-webkit-scrollbar-thumb{border:2px solid var(--bg-secondary);border-radius:999px}@supports (color:color-mix(in lab,red,red)){.calendar-scroll::-webkit-scrollbar-thumb{border:2px solid color-mix(in srgb,var(--bg-secondary)70%,transparent)}}.calendar-scroll::-webkit-scrollbar-thumb:hover{background-color:var(--text-muted)}@supports (color:color-mix(in lab,red,red)){.calendar-scroll::-webkit-scrollbar-thumb:hover{background-color:color-mix(in srgb,var(--text-muted)80%,transparent)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes pulse{50%{opacity:.5}}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}}.hg-theme-default{background-color:#ececec;border-radius:5px;box-sizing:border-box;font-family:HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif;overflow:hidden;padding:5px;touch-action:manipulation;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.hg-theme-default .hg-button span,.hg-theme-default .hg-button span svg{pointer-events:none}.hg-theme-default button.hg-button{border-width:0;font-size:inherit}.hg-theme-default .hg-button{display:inline-block;flex-grow:1}.hg-theme-default .hg-row{display:flex}.hg-theme-default .hg-row:not(:last-child){margin-bottom:5px}.hg-theme-default .hg-row .hg-button-container,.hg-theme-default .hg-row .hg-button:not(:last-child){margin-right:5px}.hg-theme-default .hg-row>div:last-child{margin-right:0}.hg-theme-default .hg-row .hg-button-container{display:flex}.hg-theme-default .hg-button{align-items:center;background:#fff;border-bottom:1px solid #b5b5b5;border-radius:5px;box-shadow:0 0 3px -1px #0000004d;box-sizing:border-box;cursor:pointer;display:flex;height:40px;justify-content:center;padding:5px;-webkit-tap-highlight-color:rgba(0,0,0,0)}.hg-theme-default .hg-button.hg-standardBtn{width:20px}.hg-theme-default .hg-button.hg-activeButton{background:#efefef}.hg-theme-default.hg-layout-numeric .hg-button{align-items:center;display:flex;height:60px;justify-content:center;width:33.3%}.hg-theme-default .hg-button.hg-button-numpadadd,.hg-theme-default .hg-button.hg-button-numpadenter{height:85px}.hg-theme-default .hg-button.hg-button-numpad0{width:105px}.hg-theme-default .hg-button.hg-button-com{max-width:85px}.hg-theme-default .hg-button.hg-standardBtn.hg-button-at{max-width:45px}.hg-theme-default .hg-button.hg-selectedButton{background:#05194687;color:#fff}.hg-theme-default .hg-button.hg-standardBtn[data-skbtn=".com"]{max-width:82px}.hg-theme-default .hg-button.hg-standardBtn[data-skbtn="@"]{max-width:60px}.hg-candidate-box{background:#ececec;border-bottom:2px solid #b5b5b5;border-radius:5px;display:inline-flex;margin-top:-10px;position:absolute;transform:translateY(-100%);-webkit-user-select:none;-moz-user-select:none;user-select:none}ul.hg-candidate-box-list{display:flex;flex:1;list-style:none;margin:0;padding:0}li.hg-candidate-box-list-item{align-items:center;display:flex;height:40px;justify-content:center;width:40px}li.hg-candidate-box-list-item:hover{background:#00000008;cursor:pointer}li.hg-candidate-box-list-item:active{background:#0000001a}.hg-candidate-box-prev:before{content:"◄"}.hg-candidate-box-next:before{content:"►"}.hg-candidate-box-next,.hg-candidate-box-prev{align-items:center;color:#969696;cursor:pointer;display:flex;padding:0 10px}.hg-candidate-box-next{border-bottom-right-radius:5px;border-top-right-radius:5px}.hg-candidate-box-prev{border-bottom-left-radius:5px;border-top-left-radius:5px}.hg-candidate-box-btn-active{color:#444}.simple-keyboard.vkb-theme{background:#1a1a1a;border-top:1px solid #333;padding:8px 4px;font-family:inherit}.simple-keyboard.vkb-theme .hg-row{display:flex!important;flex-direction:row!important;flex-wrap:nowrap!important;gap:4px;margin-bottom:4px}.simple-keyboard.vkb-theme .hg-row:last-child{margin-bottom:0}.simple-keyboard.vkb-theme .hg-button{display:inline-flex!important;align-items:center;justify-content:center;flex-grow:1;flex-shrink:1;flex-basis:auto;background:#2d2d2d;color:#e0e0e0;border:none;border-radius:6px;height:44px;font-size:16px;font-weight:500;box-shadow:0 1px 2px #0000004d;transition:background .1s;cursor:pointer;padding:0 2px;min-width:0}.simple-keyboard.vkb-theme .hg-button:active{background:#00ae42;color:#fff}.simple-keyboard.vkb-theme .hg-button-bksp,.simple-keyboard.vkb-theme .hg-button-shift,.simple-keyboard.vkb-theme .hg-button-lock{background:#3a3a3a;color:#aaa;flex-grow:1.5}.simple-keyboard.vkb-theme .hg-button-close{background:#3a3a3a;color:#aaa;flex-grow:2;font-weight:600}.simple-keyboard.vkb-theme .hg-button-close:active{background:#555}.simple-keyboard.vkb-theme .hg-button-space{flex-grow:7}.simple-keyboard.vkb-theme .hg-activeButton{background:#00ae42;color:#fff} diff --git a/static/assets/index-CfUZn1UK.js b/static/assets/index-CdDo4ToZ.js similarity index 91% rename from static/assets/index-CfUZn1UK.js rename to static/assets/index-CdDo4ToZ.js index 9660871f3..68bac5f0c 100644 --- a/static/assets/index-CfUZn1UK.js +++ b/static/assets/index-CdDo4ToZ.js @@ -1,12 +1,12 @@ -function Eue(t,e){for(var n=0;na[i]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))a(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const o of s.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&a(o)}).observe(document,{childList:!0,subtree:!0});function n(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function a(i){if(i.ep)return;i.ep=!0;const s=n(i);fetch(i.href,s)}})();var Sk=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Tc(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var WM={exports:{}},Qv={};var hH;function Due(){if(hH)return Qv;hH=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(a,i,s){var o=null;if(s!==void 0&&(o=""+s),i.key!==void 0&&(o=""+i.key),"key"in i){s={};for(var l in i)l!=="key"&&(s[l]=i[l])}else s=i;return i=s.ref,{$$typeof:t,type:a,key:o,ref:i!==void 0?i:null,props:s}}return Qv.Fragment=e,Qv.jsx=n,Qv.jsxs=n,Qv}var fH;function Fue(){return fH||(fH=1,WM.exports=Due()),WM.exports}var r=Fue(),KM={exports:{}},Qn={};var gH;function Lue(){if(gH)return Qn;gH=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),s=Symbol.for("react.consumer"),o=Symbol.for("react.context"),l=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),d=Symbol.for("react.memo"),u=Symbol.for("react.lazy"),m=Symbol.for("react.activity"),p=Symbol.iterator;function f(K){return K===null||typeof K!="object"?null:(K=p&&K[p]||K["@@iterator"],typeof K=="function"?K:null)}var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},w=Object.assign,b={};function x(K,ie,me){this.props=K,this.context=ie,this.refs=b,this.updater=me||g}x.prototype.isReactComponent={},x.prototype.setState=function(K,ie){if(typeof K!="object"&&typeof K!="function"&&K!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,K,ie,"setState")},x.prototype.forceUpdate=function(K){this.updater.enqueueForceUpdate(this,K,"forceUpdate")};function S(){}S.prototype=x.prototype;function N(K,ie,me){this.props=K,this.context=ie,this.refs=b,this.updater=me||g}var C=N.prototype=new S;C.constructor=N,w(C,x.prototype),C.isPureReactComponent=!0;var P=Array.isArray;function T(){}var A={H:null,A:null,T:null,S:null},F=Object.prototype.hasOwnProperty;function _(K,ie,me){var fe=me.ref;return{$$typeof:t,type:K,key:ie,ref:fe!==void 0?fe:null,props:me}}function M(K,ie){return _(K.type,ie,K.props)}function H(K){return typeof K=="object"&&K!==null&&K.$$typeof===t}function I(K){var ie={"=":"=0",":":"=2"};return"$"+K.replace(/[=:]/g,function(me){return ie[me]})}var U=/\/+/g;function R(K,ie){return typeof K=="object"&&K!==null&&K.key!=null?I(""+K.key):ie.toString(36)}function Y(K){switch(K.status){case"fulfilled":return K.value;case"rejected":throw K.reason;default:switch(typeof K.status=="string"?K.then(T,T):(K.status="pending",K.then(function(ie){K.status==="pending"&&(K.status="fulfilled",K.value=ie)},function(ie){K.status==="pending"&&(K.status="rejected",K.reason=ie)})),K.status){case"fulfilled":return K.value;case"rejected":throw K.reason}}throw K}function re(K,ie,me,fe,Ce){var $=typeof K;($==="undefined"||$==="boolean")&&(K=null);var W=!1;if(K===null)W=!0;else switch($){case"bigint":case"string":case"number":W=!0;break;case"object":switch(K.$$typeof){case t:case e:W=!0;break;case u:return W=K._init,re(W(K._payload),ie,me,fe,Ce)}}if(W)return Ce=Ce(K),W=fe===""?"."+R(K,0):fe,P(Ce)?(me="",W!=null&&(me=W.replace(U,"$&/")+"/"),re(Ce,ie,me,"",function(B){return B})):Ce!=null&&(H(Ce)&&(Ce=M(Ce,me+(Ce.key==null||K&&K.key===Ce.key?"":(""+Ce.key).replace(U,"$&/")+"/")+W)),ie.push(Ce)),1;W=0;var D=fe===""?".":fe+":";if(P(K))for(var j=0;j>>1,ue=re[pe];if(0>>1;pei(me,de))fei(Ce,me)?(re[pe]=Ce,re[fe]=de,pe=fe):(re[pe]=me,re[ie]=de,pe=ie);else if(fei(Ce,de))re[pe]=Ce,re[fe]=de,pe=fe;else break e}}return J}function i(re,J){var de=re.sortIndex-J.sortIndex;return de!==0?de:re.id-J.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var s=performance;t.unstable_now=function(){return s.now()}}else{var o=Date,l=o.now();t.unstable_now=function(){return o.now()-l}}var c=[],d=[],u=1,m=null,p=3,f=!1,g=!1,w=!1,b=!1,x=typeof setTimeout=="function"?setTimeout:null,S=typeof clearTimeout=="function"?clearTimeout:null,N=typeof setImmediate<"u"?setImmediate:null;function C(re){for(var J=n(d);J!==null;){if(J.callback===null)a(d);else if(J.startTime<=re)a(d),J.sortIndex=J.expirationTime,e(c,J);else break;J=n(d)}}function P(re){if(w=!1,C(re),!g)if(n(c)!==null)g=!0,T||(T=!0,I());else{var J=n(d);J!==null&&Y(P,J.startTime-re)}}var T=!1,A=-1,F=5,_=-1;function M(){return b?!0:!(t.unstable_now()-_re&&M());){var pe=m.callback;if(typeof pe=="function"){m.callback=null,p=m.priorityLevel;var ue=pe(m.expirationTime<=re);if(re=t.unstable_now(),typeof ue=="function"){m.callback=ue,C(re),J=!0;break t}m===n(c)&&a(c),C(re)}else a(c);m=n(c)}if(m!==null)J=!0;else{var K=n(d);K!==null&&Y(P,K.startTime-re),J=!1}}break e}finally{m=null,p=de,f=!1}J=void 0}}finally{J?I():T=!1}}}var I;if(typeof N=="function")I=function(){N(H)};else if(typeof MessageChannel<"u"){var U=new MessageChannel,R=U.port2;U.port1.onmessage=H,I=function(){R.postMessage(null)}}else I=function(){x(H,0)};function Y(re,J){A=x(function(){re(t.unstable_now())},J)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(re){re.callback=null},t.unstable_forceFrameRate=function(re){0>re||125pe?(re.sortIndex=de,e(d,re),n(c)===null&&re===n(d)&&(w?(S(A),A=-1):w=!0,Y(P,de-pe))):(re.sortIndex=ue,e(c,re),g||f||(g=!0,T||(T=!0,I()))),re},t.unstable_shouldYield=M,t.unstable_wrapCallback=function(re){var J=p;return function(){var de=p;p=J;try{return re.apply(this,arguments)}finally{p=de}}}})(YM)),YM}var yH;function Oue(){return yH||(yH=1,XM.exports=Iue()),XM.exports}var ZM={exports:{}},Vs={};var vH;function zue(){if(vH)return Vs;vH=1;var t=tb();function e(c){var d="https://react.dev/errors/"+c;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(e){console.error(e)}}return t(),ZM.exports=zue(),ZM.exports}var SH;function Uue(){if(SH)return Xv;SH=1;var t=Oue(),e=tb(),n=DY();function a(h){var v="https://react.dev/errors/"+h;if(1ue||(h.current=pe[ue],pe[ue]=null,ue--)}function me(h,v){ue++,pe[ue]=h.current,h.current=v}var fe=K(null),Ce=K(null),$=K(null),W=K(null);function D(h,v){switch(me($,v),me(Ce,h),me(fe,null),v.nodeType){case 9:case 11:h=(h=v.documentElement)&&(h=h.namespaceURI)?I8(h):0;break;default:if(h=v.tagName,v=v.namespaceURI)v=I8(v),h=O8(v,h);else switch(h){case"svg":h=1;break;case"math":h=2;break;default:h=0}}ie(fe),me(fe,h)}function j(){ie(fe),ie(Ce),ie($)}function B(h){h.memoizedState!==null&&me(W,h);var v=fe.current,k=O8(v,h.type);v!==k&&(me(Ce,h),me(fe,k))}function X(h){Ce.current===h&&(ie(fe),ie(Ce)),W.current===h&&(ie(W),Vv._currentValue=de)}var O,se;function z(h){if(O===void 0)try{throw Error()}catch(k){var v=k.stack.trim().match(/\n( *(at )?)/);O=v&&v[1]||"",se=-1a[i]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))a(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const o of s.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&a(o)}).observe(document,{childList:!0,subtree:!0});function n(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function a(i){if(i.ep)return;i.ep=!0;const s=n(i);fetch(i.href,s)}})();var Sk=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Tc(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var WM={exports:{}},Qv={};var hH;function Due(){if(hH)return Qv;hH=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(a,i,s){var o=null;if(s!==void 0&&(o=""+s),i.key!==void 0&&(o=""+i.key),"key"in i){s={};for(var l in i)l!=="key"&&(s[l]=i[l])}else s=i;return i=s.ref,{$$typeof:t,type:a,key:o,ref:i!==void 0?i:null,props:s}}return Qv.Fragment=e,Qv.jsx=n,Qv.jsxs=n,Qv}var fH;function Fue(){return fH||(fH=1,WM.exports=Due()),WM.exports}var r=Fue(),KM={exports:{}},Qn={};var gH;function Lue(){if(gH)return Qn;gH=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),s=Symbol.for("react.consumer"),o=Symbol.for("react.context"),l=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),d=Symbol.for("react.memo"),u=Symbol.for("react.lazy"),m=Symbol.for("react.activity"),p=Symbol.iterator;function f(K){return K===null||typeof K!="object"?null:(K=p&&K[p]||K["@@iterator"],typeof K=="function"?K:null)}var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},w=Object.assign,b={};function x(K,ie,ue){this.props=K,this.context=ie,this.refs=b,this.updater=ue||g}x.prototype.isReactComponent={},x.prototype.setState=function(K,ie){if(typeof K!="object"&&typeof K!="function"&&K!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,K,ie,"setState")},x.prototype.forceUpdate=function(K){this.updater.enqueueForceUpdate(this,K,"forceUpdate")};function S(){}S.prototype=x.prototype;function N(K,ie,ue){this.props=K,this.context=ie,this.refs=b,this.updater=ue||g}var C=N.prototype=new S;C.constructor=N,w(C,x.prototype),C.isPureReactComponent=!0;var P=Array.isArray;function T(){}var A={H:null,A:null,T:null,S:null},F=Object.prototype.hasOwnProperty;function _(K,ie,ue){var he=ue.ref;return{$$typeof:t,type:K,key:ie,ref:he!==void 0?he:null,props:ue}}function E(K,ie){return _(K.type,ie,K.props)}function H(K){return typeof K=="object"&&K!==null&&K.$$typeof===t}function I(K){var ie={"=":"=0",":":"=2"};return"$"+K.replace(/[=:]/g,function(ue){return ie[ue]})}var U=/\/+/g;function R(K,ie){return typeof K=="object"&&K!==null&&K.key!=null?I(""+K.key):ie.toString(36)}function Y(K){switch(K.status){case"fulfilled":return K.value;case"rejected":throw K.reason;default:switch(typeof K.status=="string"?K.then(T,T):(K.status="pending",K.then(function(ie){K.status==="pending"&&(K.status="fulfilled",K.value=ie)},function(ie){K.status==="pending"&&(K.status="rejected",K.reason=ie)})),K.status){case"fulfilled":return K.value;case"rejected":throw K.reason}}throw K}function ne(K,ie,ue,he,Se){var $=typeof K;($==="undefined"||$==="boolean")&&(K=null);var W=!1;if(K===null)W=!0;else switch($){case"bigint":case"string":case"number":W=!0;break;case"object":switch(K.$$typeof){case t:case e:W=!0;break;case u:return W=K._init,ne(W(K._payload),ie,ue,he,Se)}}if(W)return Se=Se(K),W=he===""?"."+R(K,0):he,P(Se)?(ue="",W!=null&&(ue=W.replace(U,"$&/")+"/"),ne(Se,ie,ue,"",function(B){return B})):Se!=null&&(H(Se)&&(Se=E(Se,ue+(Se.key==null||K&&K.key===Se.key?"":(""+Se.key).replace(U,"$&/")+"/")+W)),ie.push(Se)),1;W=0;var D=he===""?".":he+":";if(P(K))for(var j=0;j>>1,de=ne[me];if(0>>1;mei(ue,le))hei(Se,ue)?(ne[me]=Se,ne[he]=le,me=he):(ne[me]=ue,ne[ie]=le,me=ie);else if(hei(Se,le))ne[me]=Se,ne[he]=le,me=he;else break e}}return J}function i(ne,J){var le=ne.sortIndex-J.sortIndex;return le!==0?le:ne.id-J.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var s=performance;t.unstable_now=function(){return s.now()}}else{var o=Date,l=o.now();t.unstable_now=function(){return o.now()-l}}var c=[],d=[],u=1,m=null,p=3,f=!1,g=!1,w=!1,b=!1,x=typeof setTimeout=="function"?setTimeout:null,S=typeof clearTimeout=="function"?clearTimeout:null,N=typeof setImmediate<"u"?setImmediate:null;function C(ne){for(var J=n(d);J!==null;){if(J.callback===null)a(d);else if(J.startTime<=ne)a(d),J.sortIndex=J.expirationTime,e(c,J);else break;J=n(d)}}function P(ne){if(w=!1,C(ne),!g)if(n(c)!==null)g=!0,T||(T=!0,I());else{var J=n(d);J!==null&&Y(P,J.startTime-ne)}}var T=!1,A=-1,F=5,_=-1;function E(){return b?!0:!(t.unstable_now()-_ne&&E());){var me=m.callback;if(typeof me=="function"){m.callback=null,p=m.priorityLevel;var de=me(m.expirationTime<=ne);if(ne=t.unstable_now(),typeof de=="function"){m.callback=de,C(ne),J=!0;break t}m===n(c)&&a(c),C(ne)}else a(c);m=n(c)}if(m!==null)J=!0;else{var K=n(d);K!==null&&Y(P,K.startTime-ne),J=!1}}break e}finally{m=null,p=le,f=!1}J=void 0}}finally{J?I():T=!1}}}var I;if(typeof N=="function")I=function(){N(H)};else if(typeof MessageChannel<"u"){var U=new MessageChannel,R=U.port2;U.port1.onmessage=H,I=function(){R.postMessage(null)}}else I=function(){x(H,0)};function Y(ne,J){A=x(function(){ne(t.unstable_now())},J)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(ne){ne.callback=null},t.unstable_forceFrameRate=function(ne){0>ne||125me?(ne.sortIndex=le,e(d,ne),n(c)===null&&ne===n(d)&&(w?(S(A),A=-1):w=!0,Y(P,le-me))):(ne.sortIndex=de,e(c,ne),g||f||(g=!0,T||(T=!0,I()))),ne},t.unstable_shouldYield=E,t.unstable_wrapCallback=function(ne){var J=p;return function(){var le=p;p=J;try{return ne.apply(this,arguments)}finally{p=le}}}})(YM)),YM}var yH;function Oue(){return yH||(yH=1,XM.exports=Iue()),XM.exports}var ZM={exports:{}},Vs={};var vH;function zue(){if(vH)return Vs;vH=1;var t=tb();function e(c){var d="https://react.dev/errors/"+c;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(e){console.error(e)}}return t(),ZM.exports=zue(),ZM.exports}var SH;function Uue(){if(SH)return Xv;SH=1;var t=Oue(),e=tb(),n=DY();function a(h){var v="https://react.dev/errors/"+h;if(1de||(h.current=me[de],me[de]=null,de--)}function ue(h,v){de++,me[de]=h.current,h.current=v}var he=K(null),Se=K(null),$=K(null),W=K(null);function D(h,v){switch(ue($,v),ue(Se,h),ue(he,null),v.nodeType){case 9:case 11:h=(h=v.documentElement)&&(h=h.namespaceURI)?I8(h):0;break;default:if(h=v.tagName,v=v.namespaceURI)v=I8(v),h=O8(v,h);else switch(h){case"svg":h=1;break;case"math":h=2;break;default:h=0}}ie(he),ue(he,h)}function j(){ie(he),ie(Se),ie($)}function B(h){h.memoizedState!==null&&ue(W,h);var v=he.current,k=O8(v,h.type);v!==k&&(ue(Se,h),ue(he,k))}function X(h){Se.current===h&&(ie(he),ie(Se)),W.current===h&&(ie(W),Vv._currentValue=le)}var O,se;function z(h){if(O===void 0)try{throw Error()}catch(k){var v=k.stack.trim().match(/\n( *(at )?)/);O=v&&v[1]||"",se=-1)":-1V||ht[E]!==jt[V]){var Bt=` -`+ht[E].replace(" at new "," at ");return h.displayName&&Bt.includes("")&&(Bt=Bt.replace("",h.displayName)),Bt}while(1<=E&&0<=V);break}}}finally{G=!1,Error.prepareStackTrace=k}return(k=h?h.displayName||h.name:"")?z(k):""}function Z(h,v){switch(h.tag){case 26:case 27:case 5:return z(h.type);case 16:return z("Lazy");case 13:return h.child!==v&&v!==null?z("Suspense Fallback"):z("Suspense");case 19:return z("SuspenseList");case 0:case 15:return Q(h.type,!1);case 11:return Q(h.type.render,!1);case 1:return Q(h.type,!0);case 31:return z("Activity");default:return""}}function oe(h){try{var v="",k=null;do v+=Z(h,k),k=h,h=h.return;while(h);return v}catch(E){return` -Error generating stack: `+E.message+` -`+E.stack}}var te=Object.prototype.hasOwnProperty,he=t.unstable_scheduleCallback,ce=t.unstable_cancelCallback,le=t.unstable_shouldYield,q=t.unstable_requestPaint,L=t.unstable_now,ne=t.unstable_getCurrentPriorityLevel,be=t.unstable_ImmediatePriority,ve=t.unstable_UserBlockingPriority,_e=t.unstable_NormalPriority,xe=t.unstable_LowPriority,ge=t.unstable_IdlePriority,Ee=t.log,Oe=t.unstable_setDisableYieldValue,Ie=null,Be=null;function ze(h){if(typeof Ee=="function"&&Oe(h),Be&&typeof Be.setStrictMode=="function")try{Be.setStrictMode(Ie,h)}catch{}}var We=Math.clz32?Math.clz32:Fe,He=Math.log,st=Math.LN2;function Fe(h){return h>>>=0,h===0?32:31-(He(h)/st|0)|0}var tt=256,ke=262144,Ye=4194304;function Ue(h){var v=h&42;if(v!==0)return v;switch(h&-h){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return h&261888;case 262144:case 524288:case 1048576:case 2097152:return h&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return h&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return h}}function Se(h,v,k){var E=h.pendingLanes;if(E===0)return 0;var V=0,ee=h.suspendedLanes,we=h.pingedLanes;h=h.warmLanes;var qe=E&134217727;return qe!==0?(E=qe&~ee,E!==0?V=Ue(E):(we&=qe,we!==0?V=Ue(we):k||(k=qe&~h,k!==0&&(V=Ue(k))))):(qe=E&~ee,qe!==0?V=Ue(qe):we!==0?V=Ue(we):k||(k=E&~h,k!==0&&(V=Ue(k)))),V===0?0:v!==0&&v!==V&&(v&ee)===0&&(ee=V&-V,k=v&-v,ee>=k||ee===32&&(k&4194048)!==0)?v:V}function De(h,v){return(h.pendingLanes&~(h.suspendedLanes&~h.pingedLanes)&v)===0}function Xe(h,v){switch(h){case 1:case 2:case 4:case 8:case 64:return v+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return v+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function lt(){var h=Ye;return Ye<<=1,(Ye&62914560)===0&&(Ye=4194304),h}function Ae(h){for(var v=[],k=0;31>k;k++)v.push(h);return v}function et(h,v){h.pendingLanes|=v,v!==268435456&&(h.suspendedLanes=0,h.pingedLanes=0,h.warmLanes=0)}function ct(h,v,k,E,V,ee){var we=h.pendingLanes;h.pendingLanes=k,h.suspendedLanes=0,h.pingedLanes=0,h.warmLanes=0,h.expiredLanes&=k,h.entangledLanes&=k,h.errorRecoveryDisabledLanes&=k,h.shellSuspendCounter=0;var qe=h.entanglements,ht=h.expirationTimes,jt=h.hiddenUpdates;for(k=we&~k;0"u")return null;try{return h.activeElement||h.body}catch{return h.body}}var Er=/[\n"\\]/g;function Gn(h){return h.replace(Er,function(v){return"\\"+v.charCodeAt(0).toString(16)+" "})}function mi(h,v,k,E,V,ee,we,qe){h.name="",we!=null&&typeof we!="function"&&typeof we!="symbol"&&typeof we!="boolean"?h.type=we:h.removeAttribute("type"),v!=null?we==="number"?(v===0&&h.value===""||h.value!=v)&&(h.value=""+un(v)):h.value!==""+un(v)&&(h.value=""+un(v)):we!=="submit"&&we!=="reset"||h.removeAttribute("value"),v!=null?vr(h,we,un(v)):k!=null?vr(h,we,un(k)):E!=null&&h.removeAttribute("value"),V==null&&ee!=null&&(h.defaultChecked=!!ee),V!=null&&(h.checked=V&&typeof V!="function"&&typeof V!="symbol"),qe!=null&&typeof qe!="function"&&typeof qe!="symbol"&&typeof qe!="boolean"?h.name=""+un(qe):h.removeAttribute("name")}function Un(h,v,k,E,V,ee,we,qe){if(ee!=null&&typeof ee!="function"&&typeof ee!="symbol"&&typeof ee!="boolean"&&(h.type=ee),v!=null||k!=null){if(!(ee!=="submit"&&ee!=="reset"||v!=null)){Sn(h);return}k=k!=null?""+un(k):"",v=v!=null?""+un(v):k,qe||v===h.value||(h.value=v),h.defaultValue=v}E=E??V,E=typeof E!="function"&&typeof E!="symbol"&&!!E,h.checked=qe?h.checked:!!E,h.defaultChecked=!!E,we!=null&&typeof we!="function"&&typeof we!="symbol"&&typeof we!="boolean"&&(h.name=we),Sn(h)}function vr(h,v,k){v==="number"&&or(h.ownerDocument)===h||h.defaultValue===""+k||(h.defaultValue=""+k)}function la(h,v,k,E){if(h=h.options,v){v={};for(var V=0;V"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),qs=!1;if(Eo)try{var Lc={};Object.defineProperty(Lc,"passive",{get:function(){qs=!0}}),window.addEventListener("test",Lc,Lc),window.removeEventListener("test",Lc,Lc)}catch{qs=!1}var Ma=null,cp=null,dp=null;function pi(){if(dp)return dp;var h,v=cp,k=v.length,E,V="value"in Ma?Ma.value:Ma.textContent,ee=V.length;for(h=0;h=Fl),ye=" ",Ot=!1;function cn(h,v){switch(h){case"keyup":return ys.indexOf(v.keyCode)!==-1;case"keydown":return v.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function An(h){return h=h.detail,typeof h=="object"&&"data"in h?h.data:null}var zn=!1;function ut(h,v){switch(h){case"compositionend":return An(v);case"keypress":return v.which!==32?null:(Ot=!0,ye);case"textInput":return h=v.data,h===ye&&Ot?null:h;default:return null}}function Ht(h,v){if(zn)return h==="compositionend"||!Xi&&cn(h,v)?(h=pi(),dp=cp=Ma=null,zn=!1,h):null;switch(h){case"paste":return null;case"keypress":if(!(v.ctrlKey||v.altKey||v.metaKey)||v.ctrlKey&&v.altKey){if(v.char&&1=v)return{node:k,offset:v-h};h=E}e:{for(;k;){if(k.nextSibling){k=k.nextSibling;break e}k=k.parentNode}k=void 0}k=Zi(k)}}function Hc(h,v){return h&&v?h===v?!0:h&&h.nodeType===3?!1:v&&v.nodeType===3?Hc(h,v.parentNode):"contains"in h?h.contains(v):h.compareDocumentPosition?!!(h.compareDocumentPosition(v)&16):!1:!1}function Ss(h){h=h!=null&&h.ownerDocument!=null&&h.ownerDocument.defaultView!=null?h.ownerDocument.defaultView:window;for(var v=or(h.document);v instanceof h.HTMLIFrameElement;){try{var k=typeof v.contentWindow.location.href=="string"}catch{k=!1}if(k)h=v.contentWindow;else break;v=or(h.document)}return v}function mr(h){var v=h&&h.nodeName&&h.nodeName.toLowerCase();return v&&(v==="input"&&(h.type==="text"||h.type==="search"||h.type==="tel"||h.type==="url"||h.type==="password")||v==="textarea"||h.contentEditable==="true")}var $r=Eo&&"documentMode"in document&&11>=document.documentMode,ka=null,ju=null,sn=null,fp=!1;function ca(h,v,k){var E=k.window===k?k.document:k.nodeType===9?k:k.ownerDocument;fp||ka==null||ka!==or(E)||(E=ka,"selectionStart"in E&&mr(E)?E={start:E.selectionStart,end:E.selectionEnd}:(E=(E.ownerDocument&&E.ownerDocument.defaultView||window).getSelection(),E={anchorNode:E.anchorNode,anchorOffset:E.anchorOffset,focusNode:E.focusNode,focusOffset:E.focusOffset}),sn&&Ba(sn,E)||(sn=E,E=ok(ju,"onSelect"),0>=we,V-=we,Ad=1<<32-We(v)+V|k<Jn?(Sr=Pn,Pn=null):Sr=Pn.sibling;var Lr=Et(wt,Pn,At[Jn],qt);if(Lr===null){Pn===null&&(Pn=Sr);break}h&&Pn&&Lr.alternate===null&&v(wt,Pn),yt=ee(Lr,yt,Jn),Fr===null?Fn=Lr:Fr.sibling=Lr,Fr=Lr,Pn=Sr}if(Jn===At.length)return k(wt,Pn),Pr&&Du(wt,Jn),Fn;if(Pn===null){for(;JnJn?(Sr=Pn,Pn=null):Sr=Pn.sibling;var Ip=Et(wt,Pn,Lr.value,qt);if(Ip===null){Pn===null&&(Pn=Sr);break}h&&Pn&&Ip.alternate===null&&v(wt,Pn),yt=ee(Ip,yt,Jn),Fr===null?Fn=Ip:Fr.sibling=Ip,Fr=Ip,Pn=Sr}if(Lr.done)return k(wt,Pn),Pr&&Du(wt,Jn),Fn;if(Pn===null){for(;!Lr.done;Jn++,Lr=At.next())Lr=Vt(wt,Lr.value,qt),Lr!==null&&(yt=ee(Lr,yt,Jn),Fr===null?Fn=Lr:Fr.sibling=Lr,Fr=Lr);return Pr&&Du(wt,Jn),Fn}for(Pn=E(Pn);!Lr.done;Jn++,Lr=At.next())Lr=It(Pn,wt,Jn,Lr.value,qt),Lr!==null&&(h&&Lr.alternate!==null&&Pn.delete(Lr.key===null?Jn:Lr.key),yt=ee(Lr,yt,Jn),Fr===null?Fn=Lr:Fr.sibling=Lr,Fr=Lr);return h&&Pn.forEach(function(Mue){return v(wt,Mue)}),Pr&&Du(wt,Jn),Fn}function Jr(wt,yt,At,qt){if(typeof At=="object"&&At!==null&&At.type===w&&At.key===null&&(At=At.props.children),typeof At=="object"&&At!==null){switch(At.$$typeof){case f:e:{for(var Fn=At.key;yt!==null;){if(yt.key===Fn){if(Fn=At.type,Fn===w){if(yt.tag===7){k(wt,yt.sibling),qt=V(yt,At.props.children),qt.return=wt,wt=qt;break e}}else if(yt.elementType===Fn||typeof Fn=="object"&&Fn!==null&&Fn.$$typeof===F&&Nf(Fn)===yt.type){k(wt,yt.sibling),qt=V(yt,At.props),Sv(qt,At),qt.return=wt,wt=qt;break e}k(wt,yt);break}else v(wt,yt);yt=yt.sibling}At.type===w?(qt=vf(At.props.children,wt.mode,qt,At.key),qt.return=wt,wt=qt):(qt=k_(At.type,At.key,At.props,null,wt.mode,qt),Sv(qt,At),qt.return=wt,wt=qt)}return we(wt);case g:e:{for(Fn=At.key;yt!==null;){if(yt.key===Fn)if(yt.tag===4&&yt.stateNode.containerInfo===At.containerInfo&&yt.stateNode.implementation===At.implementation){k(wt,yt.sibling),qt=V(yt,At.children||[]),qt.return=wt,wt=qt;break e}else{k(wt,yt);break}else v(wt,yt);yt=yt.sibling}qt=uj(At,wt.mode,qt),qt.return=wt,wt=qt}return we(wt);case F:return At=Nf(At),Jr(wt,yt,At,qt)}if(Y(At))return yn(wt,yt,At,qt);if(I(At)){if(Fn=I(At),typeof Fn!="function")throw Error(a(150));return At=Fn.call(At),Bn(wt,yt,At,qt)}if(typeof At.then=="function")return Jr(wt,yt,M_(At),qt);if(At.$$typeof===N)return Jr(wt,yt,P_(wt,At),qt);E_(wt,At)}return typeof At=="string"&&At!==""||typeof At=="number"||typeof At=="bigint"?(At=""+At,yt!==null&&yt.tag===6?(k(wt,yt.sibling),qt=V(yt,At),qt.return=wt,wt=qt):(k(wt,yt),qt=dj(At,wt.mode,qt),qt.return=wt,wt=qt),we(wt)):k(wt,yt)}return function(wt,yt,At,qt){try{wv=0;var Fn=Jr(wt,yt,At,qt);return jb=null,Fn}catch(Pn){if(Pn===Ab||Pn===A_)throw Pn;var Fr=il(29,Pn,null,wt.mode);return Fr.lanes=qt,Fr.return=wt,Fr}}}var Pf=TU(!0),AU=TU(!1),vp=!1;function _j(h){h.updateQueue={baseState:h.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function kj(h,v){h=h.updateQueue,v.updateQueue===h&&(v.updateQueue={baseState:h.baseState,firstBaseUpdate:h.firstBaseUpdate,lastBaseUpdate:h.lastBaseUpdate,shared:h.shared,callbacks:null})}function wp(h){return{lane:h,tag:0,payload:null,callback:null,next:null}}function Sp(h,v,k){var E=h.updateQueue;if(E===null)return null;if(E=E.shared,(zr&2)!==0){var V=E.pending;return V===null?v.next=v:(v.next=V.next,V.next=v),E.pending=v,v=__(h),mU(h,null,k),v}return S_(h,E,v,k),__(h)}function _v(h,v,k){if(v=v.updateQueue,v!==null&&(v=v.shared,(k&4194048)!==0)){var E=v.lanes;E&=h.pendingLanes,k|=E,v.lanes=k,zt(h,k)}}function Nj(h,v){var k=h.updateQueue,E=h.alternate;if(E!==null&&(E=E.updateQueue,k===E)){var V=null,ee=null;if(k=k.firstBaseUpdate,k!==null){do{var we={lane:k.lane,tag:k.tag,payload:k.payload,callback:null,next:null};ee===null?V=ee=we:ee=ee.next=we,k=k.next}while(k!==null);ee===null?V=ee=v:ee=ee.next=v}else V=ee=v;k={baseState:E.baseState,firstBaseUpdate:V,lastBaseUpdate:ee,shared:E.shared,callbacks:E.callbacks},h.updateQueue=k;return}h=k.lastBaseUpdate,h===null?k.firstBaseUpdate=v:h.next=v,k.lastBaseUpdate=v}var Cj=!1;function kv(){if(Cj){var h=Tb;if(h!==null)throw h}}function Nv(h,v,k,E){Cj=!1;var V=h.updateQueue;vp=!1;var ee=V.firstBaseUpdate,we=V.lastBaseUpdate,qe=V.shared.pending;if(qe!==null){V.shared.pending=null;var ht=qe,jt=ht.next;ht.next=null,we===null?ee=jt:we.next=jt,we=ht;var Bt=h.alternate;Bt!==null&&(Bt=Bt.updateQueue,qe=Bt.lastBaseUpdate,qe!==we&&(qe===null?Bt.firstBaseUpdate=jt:qe.next=jt,Bt.lastBaseUpdate=ht))}if(ee!==null){var Vt=V.baseState;we=0,Bt=jt=ht=null,qe=ee;do{var Et=qe.lane&-536870913,It=Et!==qe.lane;if(It?(wr&Et)===Et:(E&Et)===Et){Et!==0&&Et===Pb&&(Cj=!0),Bt!==null&&(Bt=Bt.next={lane:0,tag:qe.tag,payload:qe.payload,callback:null,next:null});e:{var yn=h,Bn=qe;Et=v;var Jr=k;switch(Bn.tag){case 1:if(yn=Bn.payload,typeof yn=="function"){Vt=yn.call(Jr,Vt,Et);break e}Vt=yn;break e;case 3:yn.flags=yn.flags&-65537|128;case 0:if(yn=Bn.payload,Et=typeof yn=="function"?yn.call(Jr,Vt,Et):yn,Et==null)break e;Vt=m({},Vt,Et);break e;case 2:vp=!0}}Et=qe.callback,Et!==null&&(h.flags|=64,It&&(h.flags|=8192),It=V.callbacks,It===null?V.callbacks=[Et]:It.push(Et))}else It={lane:Et,tag:qe.tag,payload:qe.payload,callback:qe.callback,next:null},Bt===null?(jt=Bt=It,ht=Vt):Bt=Bt.next=It,we|=Et;if(qe=qe.next,qe===null){if(qe=V.shared.pending,qe===null)break;It=qe,qe=It.next,It.next=null,V.lastBaseUpdate=It,V.shared.pending=null}}while(!0);Bt===null&&(ht=Vt),V.baseState=ht,V.firstBaseUpdate=jt,V.lastBaseUpdate=Bt,ee===null&&(V.shared.lanes=0),Pp|=we,h.lanes=we,h.memoizedState=Vt}}function jU(h,v){if(typeof h!="function")throw Error(a(191,h));h.call(v)}function MU(h,v){var k=h.callbacks;if(k!==null)for(h.callbacks=null,h=0;hee?ee:8;var we=re.T,qe={};re.T=qe,Vj(h,!1,v,k);try{var ht=V(),jt=re.S;if(jt!==null&&jt(qe,ht),ht!==null&&typeof ht=="object"&&typeof ht.then=="function"){var Bt=vde(ht,E);Tv(h,v,Bt,dl(h))}else Tv(h,v,E,dl(h))}catch(Vt){Tv(h,v,{then:function(){},status:"rejected",reason:Vt},dl())}finally{J.p=ee,we!==null&&qe.types!==null&&(we.types=qe.types),re.T=we}}function Cde(){}function qj(h,v,k,E){if(h.tag!==5)throw Error(a(476));var V=cB(h).queue;lB(h,V,v,de,k===null?Cde:function(){return dB(h),k(E)})}function cB(h){var v=h.memoizedState;if(v!==null)return v;v={memoizedState:de,baseState:de,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Iu,lastRenderedState:de},next:null};var k={};return v.next={memoizedState:k,baseState:k,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Iu,lastRenderedState:k},next:null},h.memoizedState=v,h=h.alternate,h!==null&&(h.memoizedState=v),v}function dB(h){var v=cB(h);v.next===null&&(v=h.alternate.memoizedState),Tv(h,v.next.queue,{},dl())}function $j(){return ks(Vv)}function uB(){return ci().memoizedState}function mB(){return ci().memoizedState}function Pde(h){for(var v=h.return;v!==null;){switch(v.tag){case 24:case 3:var k=dl();h=wp(k);var E=Sp(v,h,k);E!==null&&(zo(E,v,k),_v(E,v,k)),v={cache:yj()},h.payload=v;return}v=v.return}}function Tde(h,v,k){var E=dl();k={lane:E,revertLane:0,gesture:null,action:k,hasEagerState:!1,eagerState:null,next:null},H_(h)?hB(v,k):(k=lj(h,v,k,E),k!==null&&(zo(k,h,E),fB(k,v,E)))}function pB(h,v,k){var E=dl();Tv(h,v,k,E)}function Tv(h,v,k,E){var V={lane:E,revertLane:0,gesture:null,action:k,hasEagerState:!1,eagerState:null,next:null};if(H_(h))hB(v,V);else{var ee=h.alternate;if(h.lanes===0&&(ee===null||ee.lanes===0)&&(ee=v.lastRenderedReducer,ee!==null))try{var we=v.lastRenderedState,qe=ee(we,k);if(V.hasEagerState=!0,V.eagerState=qe,qr(qe,we))return S_(h,v,V,0),da===null&&w_(),!1}catch{}if(k=lj(h,v,V,E),k!==null)return zo(k,h,E),fB(k,v,E),!0}return!1}function Vj(h,v,k,E){if(E={lane:2,revertLane:_M(),gesture:null,action:E,hasEagerState:!1,eagerState:null,next:null},H_(h)){if(v)throw Error(a(479))}else v=lj(h,k,E,2),v!==null&&zo(v,h,2)}function H_(h){var v=h.alternate;return h===Yn||v!==null&&v===Yn}function hB(h,v){Eb=L_=!0;var k=h.pending;k===null?v.next=v:(v.next=k.next,k.next=v),h.pending=v}function fB(h,v,k){if((k&4194048)!==0){var E=v.lanes;E&=h.pendingLanes,k|=E,v.lanes=k,zt(h,k)}}var Av={readContext:ks,use:O_,useCallback:Xa,useContext:Xa,useEffect:Xa,useImperativeHandle:Xa,useLayoutEffect:Xa,useInsertionEffect:Xa,useMemo:Xa,useReducer:Xa,useRef:Xa,useState:Xa,useDebugValue:Xa,useDeferredValue:Xa,useTransition:Xa,useSyncExternalStore:Xa,useId:Xa,useHostTransitionStatus:Xa,useFormState:Xa,useActionState:Xa,useOptimistic:Xa,useMemoCache:Xa,useCacheRefresh:Xa};Av.useEffectEvent=Xa;var gB={readContext:ks,use:O_,useCallback:function(h,v){return ho().memoizedState=[h,v===void 0?null:v],h},useContext:ks,useEffect:JU,useImperativeHandle:function(h,v,k){k=k!=null?k.concat([h]):null,U_(4194308,4,rB.bind(null,v,h),k)},useLayoutEffect:function(h,v){return U_(4194308,4,h,v)},useInsertionEffect:function(h,v){U_(4,2,h,v)},useMemo:function(h,v){var k=ho();v=v===void 0?null:v;var E=h();if(Tf){ze(!0);try{h()}finally{ze(!1)}}return k.memoizedState=[E,v],E},useReducer:function(h,v,k){var E=ho();if(k!==void 0){var V=k(v);if(Tf){ze(!0);try{k(v)}finally{ze(!1)}}}else V=v;return E.memoizedState=E.baseState=V,h={pending:null,lanes:0,dispatch:null,lastRenderedReducer:h,lastRenderedState:V},E.queue=h,h=h.dispatch=Tde.bind(null,Yn,h),[E.memoizedState,h]},useRef:function(h){var v=ho();return h={current:h},v.memoizedState=h},useState:function(h){h=Oj(h);var v=h.queue,k=pB.bind(null,Yn,v);return v.dispatch=k,[h.memoizedState,k]},useDebugValue:Bj,useDeferredValue:function(h,v){var k=ho();return Hj(k,h,v)},useTransition:function(){var h=Oj(!1);return h=lB.bind(null,Yn,h.queue,!0,!1),ho().memoizedState=h,[!1,h]},useSyncExternalStore:function(h,v,k){var E=Yn,V=ho();if(Pr){if(k===void 0)throw Error(a(407));k=k()}else{if(k=v(),da===null)throw Error(a(349));(wr&127)!==0||IU(E,v,k)}V.memoizedState=k;var ee={value:k,getSnapshot:v};return V.queue=ee,JU(zU.bind(null,E,ee,h),[h]),E.flags|=2048,Fb(9,{destroy:void 0},OU.bind(null,E,ee,k,v),null),k},useId:function(){var h=ho(),v=da.identifierPrefix;if(Pr){var k=jd,E=Ad;k=(E&~(1<<32-We(E)-1)).toString(32)+k,v="_"+v+"R_"+k,k=R_++,0<\/script>",ee=ee.removeChild(ee.firstChild);break;case"select":ee=typeof E.is=="string"?we.createElement("select",{is:E.is}):we.createElement("select"),E.multiple?ee.multiple=!0:E.size&&(ee.size=E.size);break;default:ee=typeof E.is=="string"?we.createElement(V,{is:E.is}):we.createElement(V)}}ee[kt]=v,ee[Nt]=E;e:for(we=v.child;we!==null;){if(we.tag===5||we.tag===6)ee.appendChild(we.stateNode);else if(we.tag!==4&&we.tag!==27&&we.child!==null){we.child.return=we,we=we.child;continue}if(we===v)break e;for(;we.sibling===null;){if(we.return===null||we.return===v)break e;we=we.return}we.sibling.return=we.return,we=we.sibling}v.stateNode=ee;e:switch(Cs(ee,V,E),V){case"button":case"input":case"select":case"textarea":E=!!E.autoFocus;break e;case"img":E=!0;break e;default:E=!1}E&&zu(v)}}return Ca(v),iM(v,v.type,h===null?null:h.memoizedProps,v.pendingProps,k),null;case 6:if(h&&v.stateNode!=null)h.memoizedProps!==E&&zu(v);else{if(typeof E!="string"&&v.stateNode===null)throw Error(a(166));if(h=$.current,Nb(v)){if(h=v.stateNode,k=v.memoizedProps,E=null,V=_s,V!==null)switch(V.tag){case 27:case 5:E=V.memoizedProps}h[kt]=v,h=!!(h.nodeValue===k||E!==null&&E.suppressHydrationWarning===!0||L8(h.nodeValue,k)),h||xp(v,!0)}else h=lk(h).createTextNode(E),h[kt]=v,v.stateNode=h}return Ca(v),null;case 31:if(k=v.memoizedState,h===null||h.memoizedState!==null){if(E=Nb(v),k!==null){if(h===null){if(!E)throw Error(a(318));if(h=v.memoizedState,h=h!==null?h.dehydrated:null,!h)throw Error(a(557));h[kt]=v}else wf(),(v.flags&128)===0&&(v.memoizedState=null),v.flags|=4;Ca(v),h=!1}else k=fj(),h!==null&&h.memoizedState!==null&&(h.memoizedState.hydrationErrors=k),h=!0;if(!h)return v.flags&256?(ol(v),v):(ol(v),null);if((v.flags&128)!==0)throw Error(a(558))}return Ca(v),null;case 13:if(E=v.memoizedState,h===null||h.memoizedState!==null&&h.memoizedState.dehydrated!==null){if(V=Nb(v),E!==null&&E.dehydrated!==null){if(h===null){if(!V)throw Error(a(318));if(V=v.memoizedState,V=V!==null?V.dehydrated:null,!V)throw Error(a(317));V[kt]=v}else wf(),(v.flags&128)===0&&(v.memoizedState=null),v.flags|=4;Ca(v),V=!1}else V=fj(),h!==null&&h.memoizedState!==null&&(h.memoizedState.hydrationErrors=V),V=!0;if(!V)return v.flags&256?(ol(v),v):(ol(v),null)}return ol(v),(v.flags&128)!==0?(v.lanes=k,v):(k=E!==null,h=h!==null&&h.memoizedState!==null,k&&(E=v.child,V=null,E.alternate!==null&&E.alternate.memoizedState!==null&&E.alternate.memoizedState.cachePool!==null&&(V=E.alternate.memoizedState.cachePool.pool),ee=null,E.memoizedState!==null&&E.memoizedState.cachePool!==null&&(ee=E.memoizedState.cachePool.pool),ee!==V&&(E.flags|=2048)),k!==h&&k&&(v.child.flags|=8192),W_(v,v.updateQueue),Ca(v),null);case 4:return j(),h===null&&PM(v.stateNode.containerInfo),Ca(v),null;case 10:return Lu(v.type),Ca(v),null;case 19:if(ie(li),E=v.memoizedState,E===null)return Ca(v),null;if(V=(v.flags&128)!==0,ee=E.rendering,ee===null)if(V)Mv(E,!1);else{if(Ya!==0||h!==null&&(h.flags&128)!==0)for(h=v.child;h!==null;){if(ee=F_(h),ee!==null){for(v.flags|=128,Mv(E,!1),h=ee.updateQueue,v.updateQueue=h,W_(v,h),v.subtreeFlags=0,h=k,k=v.child;k!==null;)pU(k,h),k=k.sibling;return me(li,li.current&1|2),Pr&&Du(v,E.treeForkCount),v.child}h=h.sibling}E.tail!==null&&L()>Z_&&(v.flags|=128,V=!0,Mv(E,!1),v.lanes=4194304)}else{if(!V)if(h=F_(ee),h!==null){if(v.flags|=128,V=!0,h=h.updateQueue,v.updateQueue=h,W_(v,h),Mv(E,!0),E.tail===null&&E.tailMode==="hidden"&&!ee.alternate&&!Pr)return Ca(v),null}else 2*L()-E.renderingStartTime>Z_&&k!==536870912&&(v.flags|=128,V=!0,Mv(E,!1),v.lanes=4194304);E.isBackwards?(ee.sibling=v.child,v.child=ee):(h=E.last,h!==null?h.sibling=ee:v.child=ee,E.last=ee)}return E.tail!==null?(h=E.tail,E.rendering=h,E.tail=h.sibling,E.renderingStartTime=L(),h.sibling=null,k=li.current,me(li,V?k&1|2:k&1),Pr&&Du(v,E.treeForkCount),h):(Ca(v),null);case 22:case 23:return ol(v),Tj(),E=v.memoizedState!==null,h!==null?h.memoizedState!==null!==E&&(v.flags|=8192):E&&(v.flags|=8192),E?(k&536870912)!==0&&(v.flags&128)===0&&(Ca(v),v.subtreeFlags&6&&(v.flags|=8192)):Ca(v),k=v.updateQueue,k!==null&&W_(v,k.retryQueue),k=null,h!==null&&h.memoizedState!==null&&h.memoizedState.cachePool!==null&&(k=h.memoizedState.cachePool.pool),E=null,v.memoizedState!==null&&v.memoizedState.cachePool!==null&&(E=v.memoizedState.cachePool.pool),E!==k&&(v.flags|=2048),h!==null&&ie(kf),null;case 24:return k=null,h!==null&&(k=h.memoizedState.cache),v.memoizedState.cache!==k&&(v.flags|=2048),Lu(fi),Ca(v),null;case 25:return null;case 30:return null}throw Error(a(156,v.tag))}function Dde(h,v){switch(pj(v),v.tag){case 1:return h=v.flags,h&65536?(v.flags=h&-65537|128,v):null;case 3:return Lu(fi),j(),h=v.flags,(h&65536)!==0&&(h&128)===0?(v.flags=h&-65537|128,v):null;case 26:case 27:case 5:return X(v),null;case 31:if(v.memoizedState!==null){if(ol(v),v.alternate===null)throw Error(a(340));wf()}return h=v.flags,h&65536?(v.flags=h&-65537|128,v):null;case 13:if(ol(v),h=v.memoizedState,h!==null&&h.dehydrated!==null){if(v.alternate===null)throw Error(a(340));wf()}return h=v.flags,h&65536?(v.flags=h&-65537|128,v):null;case 19:return ie(li),null;case 4:return j(),null;case 10:return Lu(v.type),null;case 22:case 23:return ol(v),Tj(),h!==null&&ie(kf),h=v.flags,h&65536?(v.flags=h&-65537|128,v):null;case 24:return Lu(fi),null;case 25:return null;default:return null}}function UB(h,v){switch(pj(v),v.tag){case 3:Lu(fi),j();break;case 26:case 27:case 5:X(v);break;case 4:j();break;case 31:v.memoizedState!==null&&ol(v);break;case 13:ol(v);break;case 19:ie(li);break;case 10:Lu(v.type);break;case 22:case 23:ol(v),Tj(),h!==null&&ie(kf);break;case 24:Lu(fi)}}function Ev(h,v){try{var k=v.updateQueue,E=k!==null?k.lastEffect:null;if(E!==null){var V=E.next;k=V;do{if((k.tag&h)===h){E=void 0;var ee=k.create,we=k.inst;E=ee(),we.destroy=E}k=k.next}while(k!==V)}}catch(qe){Gr(v,v.return,qe)}}function Np(h,v,k){try{var E=v.updateQueue,V=E!==null?E.lastEffect:null;if(V!==null){var ee=V.next;E=ee;do{if((E.tag&h)===h){var we=E.inst,qe=we.destroy;if(qe!==void 0){we.destroy=void 0,V=v;var ht=k,jt=qe;try{jt()}catch(Bt){Gr(V,ht,Bt)}}}E=E.next}while(E!==ee)}}catch(Bt){Gr(v,v.return,Bt)}}function BB(h){var v=h.updateQueue;if(v!==null){var k=h.stateNode;try{MU(v,k)}catch(E){Gr(h,h.return,E)}}}function HB(h,v,k){k.props=Af(h.type,h.memoizedProps),k.state=h.memoizedState;try{k.componentWillUnmount()}catch(E){Gr(h,v,E)}}function Dv(h,v){try{var k=h.ref;if(k!==null){switch(h.tag){case 26:case 27:case 5:var E=h.stateNode;break;case 30:E=h.stateNode;break;default:E=h.stateNode}typeof k=="function"?h.refCleanup=k(E):k.current=E}}catch(V){Gr(h,v,V)}}function Md(h,v){var k=h.ref,E=h.refCleanup;if(k!==null)if(typeof E=="function")try{E()}catch(V){Gr(h,v,V)}finally{h.refCleanup=null,h=h.alternate,h!=null&&(h.refCleanup=null)}else if(typeof k=="function")try{k(null)}catch(V){Gr(h,v,V)}else k.current=null}function qB(h){var v=h.type,k=h.memoizedProps,E=h.stateNode;try{e:switch(v){case"button":case"input":case"select":case"textarea":k.autoFocus&&E.focus();break e;case"img":k.src?E.src=k.src:k.srcSet&&(E.srcset=k.srcSet)}}catch(V){Gr(h,h.return,V)}}function sM(h,v,k){try{var E=h.stateNode;tue(E,h.type,k,v),E[Nt]=v}catch(V){Gr(h,h.return,V)}}function $B(h){return h.tag===5||h.tag===3||h.tag===26||h.tag===27&&Ep(h.type)||h.tag===4}function oM(h){e:for(;;){for(;h.sibling===null;){if(h.return===null||$B(h.return))return null;h=h.return}for(h.sibling.return=h.return,h=h.sibling;h.tag!==5&&h.tag!==6&&h.tag!==18;){if(h.tag===27&&Ep(h.type)||h.flags&2||h.child===null||h.tag===4)continue e;h.child.return=h,h=h.child}if(!(h.flags&2))return h.stateNode}}function lM(h,v,k){var E=h.tag;if(E===5||E===6)h=h.stateNode,v?(k.nodeType===9?k.body:k.nodeName==="HTML"?k.ownerDocument.body:k).insertBefore(h,v):(v=k.nodeType===9?k.body:k.nodeName==="HTML"?k.ownerDocument.body:k,v.appendChild(h),k=k._reactRootContainer,k!=null||v.onclick!==null||(v.onclick=Wt));else if(E!==4&&(E===27&&Ep(h.type)&&(k=h.stateNode,v=null),h=h.child,h!==null))for(lM(h,v,k),h=h.sibling;h!==null;)lM(h,v,k),h=h.sibling}function K_(h,v,k){var E=h.tag;if(E===5||E===6)h=h.stateNode,v?k.insertBefore(h,v):k.appendChild(h);else if(E!==4&&(E===27&&Ep(h.type)&&(k=h.stateNode),h=h.child,h!==null))for(K_(h,v,k),h=h.sibling;h!==null;)K_(h,v,k),h=h.sibling}function VB(h){var v=h.stateNode,k=h.memoizedProps;try{for(var E=h.type,V=v.attributes;V.length;)v.removeAttributeNode(V[0]);Cs(v,E,k),v[kt]=h,v[Nt]=k}catch(ee){Gr(h,h.return,ee)}}var Uu=!1,xi=!1,cM=!1,GB=typeof WeakSet=="function"?WeakSet:Set,Ji=null;function Fde(h,v){if(h=h.containerInfo,jM=fk,h=Ss(h),mr(h)){if("selectionStart"in h)var k={start:h.selectionStart,end:h.selectionEnd};else e:{k=(k=h.ownerDocument)&&k.defaultView||window;var E=k.getSelection&&k.getSelection();if(E&&E.rangeCount!==0){k=E.anchorNode;var V=E.anchorOffset,ee=E.focusNode;E=E.focusOffset;try{k.nodeType,ee.nodeType}catch{k=null;break e}var we=0,qe=-1,ht=-1,jt=0,Bt=0,Vt=h,Et=null;t:for(;;){for(var It;Vt!==k||V!==0&&Vt.nodeType!==3||(qe=we+V),Vt!==ee||E!==0&&Vt.nodeType!==3||(ht=we+E),Vt.nodeType===3&&(we+=Vt.nodeValue.length),(It=Vt.firstChild)!==null;)Et=Vt,Vt=It;for(;;){if(Vt===h)break t;if(Et===k&&++jt===V&&(qe=we),Et===ee&&++Bt===E&&(ht=we),(It=Vt.nextSibling)!==null)break;Vt=Et,Et=Vt.parentNode}Vt=It}k=qe===-1||ht===-1?null:{start:qe,end:ht}}else k=null}k=k||{start:0,end:0}}else k=null;for(MM={focusedElem:h,selectionRange:k},fk=!1,Ji=v;Ji!==null;)if(v=Ji,h=v.child,(v.subtreeFlags&1028)!==0&&h!==null)h.return=v,Ji=h;else for(;Ji!==null;){switch(v=Ji,ee=v.alternate,h=v.flags,v.tag){case 0:if((h&4)!==0&&(h=v.updateQueue,h=h!==null?h.events:null,h!==null))for(k=0;k title"))),Cs(ee,E,k),ee[kt]=h,rt(ee),E=ee;break e;case"link":var we=Z8("link","href",V).get(E+(k.href||""));if(we){for(var qe=0;qeJr&&(we=Jr,Jr=Bn,Bn=we);var wt=Fi(qe,Bn),yt=Fi(qe,Jr);if(wt&&yt&&(It.rangeCount!==1||It.anchorNode!==wt.node||It.anchorOffset!==wt.offset||It.focusNode!==yt.node||It.focusOffset!==yt.offset)){var At=Vt.createRange();At.setStart(wt.node,wt.offset),It.removeAllRanges(),Bn>Jr?(It.addRange(At),It.extend(yt.node,yt.offset)):(At.setEnd(yt.node,yt.offset),It.addRange(At))}}}}for(Vt=[],It=qe;It=It.parentNode;)It.nodeType===1&&Vt.push({element:It,left:It.scrollLeft,top:It.scrollTop});for(typeof qe.focus=="function"&&qe.focus(),qe=0;qek?32:k,re.T=null,k=gM,gM=null;var ee=Ap,we=Vu;if(Li=0,zb=Ap=null,Vu=0,(zr&6)!==0)throw Error(a(331));var qe=zr;if(zr|=4,r8(ee.current),e8(ee,ee.current,we,k),zr=qe,zv(0,!1),Be&&typeof Be.onPostCommitFiberRoot=="function")try{Be.onPostCommitFiberRoot(Ie,ee)}catch{}return!0}finally{J.p=V,re.T=E,w8(h,v)}}function _8(h,v,k){v=Ol(k,v),v=Qj(h.stateNode,v,2),h=Sp(h,v,2),h!==null&&(et(h,2),Ed(h))}function Gr(h,v,k){if(h.tag===3)_8(h,h,k);else for(;v!==null;){if(v.tag===3){_8(v,h,k);break}else if(v.tag===1){var E=v.stateNode;if(typeof v.type.getDerivedStateFromError=="function"||typeof E.componentDidCatch=="function"&&(Tp===null||!Tp.has(E))){h=Ol(k,h),k=kB(2),E=Sp(v,k,2),E!==null&&(NB(k,E,v,h),et(E,2),Ed(E));break}}v=v.return}}function vM(h,v,k){var E=h.pingCache;if(E===null){E=h.pingCache=new Ide;var V=new Set;E.set(v,V)}else V=E.get(v),V===void 0&&(V=new Set,E.set(v,V));V.has(k)||(mM=!0,V.add(k),h=Hde.bind(null,h,v,k),v.then(h,h))}function Hde(h,v,k){var E=h.pingCache;E!==null&&E.delete(v),h.pingedLanes|=h.suspendedLanes&k,h.warmLanes&=~k,da===h&&(wr&k)===k&&(Ya===4||Ya===3&&(wr&62914560)===wr&&300>L()-Y_?(zr&2)===0&&Ub(h,0):pM|=k,Ob===wr&&(Ob=0)),Ed(h)}function k8(h,v){v===0&&(v=lt()),h=yf(h,v),h!==null&&(et(h,v),Ed(h))}function qde(h){var v=h.memoizedState,k=0;v!==null&&(k=v.retryLane),k8(h,k)}function $de(h,v){var k=0;switch(h.tag){case 31:case 13:var E=h.stateNode,V=h.memoizedState;V!==null&&(k=V.retryLane);break;case 19:E=h.stateNode;break;case 22:E=h.stateNode._retryCache;break;default:throw Error(a(314))}E!==null&&E.delete(v),k8(h,k)}function Vde(h,v){return he(h,v)}var ak=null,Hb=null,wM=!1,ik=!1,SM=!1,Mp=0;function Ed(h){h!==Hb&&h.next===null&&(Hb===null?ak=Hb=h:Hb=Hb.next=h),ik=!0,wM||(wM=!0,Wde())}function zv(h,v){if(!SM&&ik){SM=!0;do for(var k=!1,E=ak;E!==null;){if(h!==0){var V=E.pendingLanes;if(V===0)var ee=0;else{var we=E.suspendedLanes,qe=E.pingedLanes;ee=(1<<31-We(42|h)+1)-1,ee&=V&~(we&~qe),ee=ee&201326741?ee&201326741|1:ee?ee|2:0}ee!==0&&(k=!0,T8(E,ee))}else ee=wr,ee=Se(E,E===da?ee:0,E.cancelPendingCommit!==null||E.timeoutHandle!==-1),(ee&3)===0||De(E,ee)||(k=!0,T8(E,ee));E=E.next}while(k);SM=!1}}function Gde(){N8()}function N8(){ik=wM=!1;var h=0;Mp!==0&&rue()&&(h=Mp);for(var v=L(),k=null,E=ak;E!==null;){var V=E.next,ee=C8(E,v);ee===0?(E.next=null,k===null?ak=V:k.next=V,V===null&&(Hb=k)):(k=E,(h!==0||(ee&3)!==0)&&(ik=!0)),E=V}Li!==0&&Li!==5||zv(h),Mp!==0&&(Mp=0)}function C8(h,v){for(var k=h.suspendedLanes,E=h.pingedLanes,V=h.expirationTimes,ee=h.pendingLanes&-62914561;0qe)break;var Bt=ht.transferSize,Vt=ht.initiatorType;Bt&&R8(Vt)&&(ht=ht.responseEnd,we+=Bt*(ht"u"?null:document;function K8(h,v,k){var E=qb;if(E&&typeof v=="string"&&v){var V=Gn(v);V='link[rel="'+h+'"][href="'+V+'"]',typeof k=="string"&&(V+='[crossorigin="'+k+'"]'),W8.has(V)||(W8.add(V),h={rel:h,crossOrigin:k,href:v},E.querySelector(V)===null&&(v=E.createElement("link"),Cs(v,"link",h),rt(v),E.head.appendChild(v)))}}function mue(h){Gu.D(h),K8("dns-prefetch",h,null)}function pue(h,v){Gu.C(h,v),K8("preconnect",h,v)}function hue(h,v,k){Gu.L(h,v,k);var E=qb;if(E&&h&&v){var V='link[rel="preload"][as="'+Gn(v)+'"]';v==="image"&&k&&k.imageSrcSet?(V+='[imagesrcset="'+Gn(k.imageSrcSet)+'"]',typeof k.imageSizes=="string"&&(V+='[imagesizes="'+Gn(k.imageSizes)+'"]')):V+='[href="'+Gn(h)+'"]';var ee=V;switch(v){case"style":ee=$b(h);break;case"script":ee=Vb(h)}$l.has(ee)||(h=m({rel:"preload",href:v==="image"&&k&&k.imageSrcSet?void 0:h,as:v},k),$l.set(ee,h),E.querySelector(V)!==null||v==="style"&&E.querySelector(qv(ee))||v==="script"&&E.querySelector($v(ee))||(v=E.createElement("link"),Cs(v,"link",h),rt(v),E.head.appendChild(v)))}}function fue(h,v){Gu.m(h,v);var k=qb;if(k&&h){var E=v&&typeof v.as=="string"?v.as:"script",V='link[rel="modulepreload"][as="'+Gn(E)+'"][href="'+Gn(h)+'"]',ee=V;switch(E){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":ee=Vb(h)}if(!$l.has(ee)&&(h=m({rel:"modulepreload",href:h},v),$l.set(ee,h),k.querySelector(V)===null)){switch(E){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(k.querySelector($v(ee)))return}E=k.createElement("link"),Cs(E,"link",h),rt(E),k.head.appendChild(E)}}}function gue(h,v,k){Gu.S(h,v,k);var E=qb;if(E&&h){var V=nt(E).hoistableStyles,ee=$b(h);v=v||"default";var we=V.get(ee);if(!we){var qe={loading:0,preload:null};if(we=E.querySelector(qv(ee)))qe.loading=5;else{h=m({rel:"stylesheet",href:h,"data-precedence":v},k),(k=$l.get(ee))&&OM(h,k);var ht=we=E.createElement("link");rt(ht),Cs(ht,"link",h),ht._p=new Promise(function(jt,Bt){ht.onload=jt,ht.onerror=Bt}),ht.addEventListener("load",function(){qe.loading|=1}),ht.addEventListener("error",function(){qe.loading|=2}),qe.loading|=4,dk(we,v,E)}we={type:"stylesheet",instance:we,count:1,state:qe},V.set(ee,we)}}}function bue(h,v){Gu.X(h,v);var k=qb;if(k&&h){var E=nt(k).hoistableScripts,V=Vb(h),ee=E.get(V);ee||(ee=k.querySelector($v(V)),ee||(h=m({src:h,async:!0},v),(v=$l.get(V))&&zM(h,v),ee=k.createElement("script"),rt(ee),Cs(ee,"link",h),k.head.appendChild(ee)),ee={type:"script",instance:ee,count:1,state:null},E.set(V,ee))}}function xue(h,v){Gu.M(h,v);var k=qb;if(k&&h){var E=nt(k).hoistableScripts,V=Vb(h),ee=E.get(V);ee||(ee=k.querySelector($v(V)),ee||(h=m({src:h,async:!0,type:"module"},v),(v=$l.get(V))&&zM(h,v),ee=k.createElement("script"),rt(ee),Cs(ee,"link",h),k.head.appendChild(ee)),ee={type:"script",instance:ee,count:1,state:null},E.set(V,ee))}}function Q8(h,v,k,E){var V=(V=$.current)?ck(V):null;if(!V)throw Error(a(446));switch(h){case"meta":case"title":return null;case"style":return typeof k.precedence=="string"&&typeof k.href=="string"?(v=$b(k.href),k=nt(V).hoistableStyles,E=k.get(v),E||(E={type:"style",instance:null,count:0,state:null},k.set(v,E)),E):{type:"void",instance:null,count:0,state:null};case"link":if(k.rel==="stylesheet"&&typeof k.href=="string"&&typeof k.precedence=="string"){h=$b(k.href);var ee=nt(V).hoistableStyles,we=ee.get(h);if(we||(V=V.ownerDocument||V,we={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},ee.set(h,we),(ee=V.querySelector(qv(h)))&&!ee._p&&(we.instance=ee,we.state.loading=5),$l.has(h)||(k={rel:"preload",as:"style",href:k.href,crossOrigin:k.crossOrigin,integrity:k.integrity,media:k.media,hrefLang:k.hrefLang,referrerPolicy:k.referrerPolicy},$l.set(h,k),ee||yue(V,h,k,we.state))),v&&E===null)throw Error(a(528,""));return we}if(v&&E!==null)throw Error(a(529,""));return null;case"script":return v=k.async,k=k.src,typeof k=="string"&&v&&typeof v!="function"&&typeof v!="symbol"?(v=Vb(k),k=nt(V).hoistableScripts,E=k.get(v),E||(E={type:"script",instance:null,count:0,state:null},k.set(v,E)),E):{type:"void",instance:null,count:0,state:null};default:throw Error(a(444,h))}}function $b(h){return'href="'+Gn(h)+'"'}function qv(h){return'link[rel="stylesheet"]['+h+"]"}function X8(h){return m({},h,{"data-precedence":h.precedence,precedence:null})}function yue(h,v,k,E){h.querySelector('link[rel="preload"][as="style"]['+v+"]")?E.loading=1:(v=h.createElement("link"),E.preload=v,v.addEventListener("load",function(){return E.loading|=1}),v.addEventListener("error",function(){return E.loading|=2}),Cs(v,"link",k),rt(v),h.head.appendChild(v))}function Vb(h){return'[src="'+Gn(h)+'"]'}function $v(h){return"script[async]"+h}function Y8(h,v,k){if(v.count++,v.instance===null)switch(v.type){case"style":var E=h.querySelector('style[data-href~="'+Gn(k.href)+'"]');if(E)return v.instance=E,rt(E),E;var V=m({},k,{"data-href":k.href,"data-precedence":k.precedence,href:null,precedence:null});return E=(h.ownerDocument||h).createElement("style"),rt(E),Cs(E,"style",V),dk(E,k.precedence,h),v.instance=E;case"stylesheet":V=$b(k.href);var ee=h.querySelector(qv(V));if(ee)return v.state.loading|=4,v.instance=ee,rt(ee),ee;E=X8(k),(V=$l.get(V))&&OM(E,V),ee=(h.ownerDocument||h).createElement("link"),rt(ee);var we=ee;return we._p=new Promise(function(qe,ht){we.onload=qe,we.onerror=ht}),Cs(ee,"link",E),v.state.loading|=4,dk(ee,k.precedence,h),v.instance=ee;case"script":return ee=Vb(k.src),(V=h.querySelector($v(ee)))?(v.instance=V,rt(V),V):(E=k,(V=$l.get(ee))&&(E=m({},k),zM(E,V)),h=h.ownerDocument||h,V=h.createElement("script"),rt(V),Cs(V,"link",E),h.head.appendChild(V),v.instance=V);case"void":return null;default:throw Error(a(443,v.type))}else v.type==="stylesheet"&&(v.state.loading&4)===0&&(E=v.instance,v.state.loading|=4,dk(E,k.precedence,h));return v.instance}function dk(h,v,k){for(var E=k.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),V=E.length?E[E.length-1]:null,ee=V,we=0;we title"):null)}function vue(h,v,k){if(k===1||v.itemProp!=null)return!1;switch(h){case"meta":case"title":return!0;case"style":if(typeof v.precedence!="string"||typeof v.href!="string"||v.href==="")break;return!0;case"link":if(typeof v.rel!="string"||typeof v.href!="string"||v.href===""||v.onLoad||v.onError)break;return v.rel==="stylesheet"?(h=v.disabled,typeof v.precedence=="string"&&h==null):!0;case"script":if(v.async&&typeof v.async!="function"&&typeof v.async!="symbol"&&!v.onLoad&&!v.onError&&v.src&&typeof v.src=="string")return!0}return!1}function eH(h){return!(h.type==="stylesheet"&&(h.state.loading&3)===0)}function wue(h,v,k,E){if(k.type==="stylesheet"&&(typeof E.media!="string"||matchMedia(E.media).matches!==!1)&&(k.state.loading&4)===0){if(k.instance===null){var V=$b(E.href),ee=v.querySelector(qv(V));if(ee){v=ee._p,v!==null&&typeof v=="object"&&typeof v.then=="function"&&(h.count++,h=mk.bind(h),v.then(h,h)),k.state.loading|=4,k.instance=ee,rt(ee);return}ee=v.ownerDocument||v,E=X8(E),(V=$l.get(V))&&OM(E,V),ee=ee.createElement("link"),rt(ee);var we=ee;we._p=new Promise(function(qe,ht){we.onload=qe,we.onerror=ht}),Cs(ee,"link",E),k.instance=ee}h.stylesheets===null&&(h.stylesheets=new Map),h.stylesheets.set(k,v),(v=k.state.preload)&&(k.state.loading&3)===0&&(h.count++,k=mk.bind(h),v.addEventListener("load",k),v.addEventListener("error",k))}}var UM=0;function Sue(h,v){return h.stylesheets&&h.count===0&&hk(h,h.stylesheets),0UM?50:800)+v);return h.unsuspend=k,function(){h.unsuspend=null,clearTimeout(E),clearTimeout(V)}}:null}function mk(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)hk(this,this.stylesheets);else if(this.unsuspend){var h=this.unsuspend;this.unsuspend=null,h()}}}var pk=null;function hk(h,v){h.stylesheets=null,h.unsuspend!==null&&(h.count++,pk=new Map,v.forEach(_ue,h),pk=null,mk.call(h))}function _ue(h,v){if(!(v.state.loading&4)){var k=pk.get(h);if(k)var E=k.get(null);else{k=new Map,pk.set(h,k);for(var V=h.querySelectorAll("link[data-precedence],style[data-precedence]"),ee=0;ee"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(e){console.error(e)}}return t(),QM.exports=Uue(),QM.exports}var Hue=Bue();const qn=t=>typeof t=="string",Yv=()=>{let t,e;const n=new Promise((a,i)=>{t=a,e=i});return n.resolve=t,n.reject=e,n},kH=t=>t==null?"":""+t,que=(t,e,n)=>{t.forEach(a=>{e[a]&&(n[a]=e[a])})},$ue=/###/g,NH=t=>t&&t.indexOf("###")>-1?t.replace($ue,"."):t,CH=t=>!t||qn(t),K0=(t,e,n)=>{const a=qn(e)?e.split("."):e;let i=0;for(;i{const{obj:a,k:i}=K0(t,e,Object);if(a!==void 0||e.length===1){a[i]=n;return}let s=e[e.length-1],o=e.slice(0,e.length-1),l=K0(t,o,Object);for(;l.obj===void 0&&o.length;)s=`${o[o.length-1]}.${s}`,o=o.slice(0,o.length-1),l=K0(t,o,Object),l?.obj&&typeof l.obj[`${l.k}.${s}`]<"u"&&(l.obj=void 0);l.obj[`${l.k}.${s}`]=n},Vue=(t,e,n,a)=>{const{obj:i,k:s}=K0(t,e,Object);i[s]=i[s]||[],i[s].push(n)},VN=(t,e)=>{const{obj:n,k:a}=K0(t,e);if(n&&Object.prototype.hasOwnProperty.call(n,a))return n[a]},Gue=(t,e,n)=>{const a=VN(t,n);return a!==void 0?a:VN(e,n)},FY=(t,e,n)=>{for(const a in e)a!=="__proto__"&&a!=="constructor"&&(a in t?qn(t[a])||t[a]instanceof String||qn(e[a])||e[a]instanceof String?n&&(t[a]=e[a]):FY(t[a],e[a],n):t[a]=e[a]);return t},Wb=t=>t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");var Wue={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};const Kue=t=>qn(t)?t.replace(/[&<>"'\/]/g,e=>Wue[e]):t;class Que{constructor(e){this.capacity=e,this.regExpMap=new Map,this.regExpQueue=[]}getRegExp(e){const n=this.regExpMap.get(e);if(n!==void 0)return n;const a=new RegExp(e);return this.regExpQueue.length===this.capacity&&this.regExpMap.delete(this.regExpQueue.shift()),this.regExpMap.set(e,a),this.regExpQueue.push(e),a}}const Xue=[" ",",","?","!",";"],Yue=new Que(20),Zue=(t,e,n)=>{e=e||"",n=n||"";const a=Xue.filter(o=>e.indexOf(o)<0&&n.indexOf(o)<0);if(a.length===0)return!0;const i=Yue.getRegExp(`(${a.map(o=>o==="?"?"\\?":o).join("|")})`);let s=!i.test(t);if(!s){const o=t.indexOf(n);o>0&&!i.test(t.substring(0,o))&&(s=!0)}return s},CF=(t,e,n=".")=>{if(!t)return;if(t[e])return Object.prototype.hasOwnProperty.call(t,e)?t[e]:void 0;const a=e.split(n);let i=t;for(let s=0;s-1&&ct?.replace("_","-"),Jue={type:"logger",log(t){this.output("log",t)},warn(t){this.output("warn",t)},error(t){this.output("error",t)},output(t,e){console?.[t]?.apply?.(console,e)}};class GN{constructor(e,n={}){this.init(e,n)}init(e,n={}){this.prefix=n.prefix||"i18next:",this.logger=e||Jue,this.options=n,this.debug=n.debug}log(...e){return this.forward(e,"log","",!0)}warn(...e){return this.forward(e,"warn","",!0)}error(...e){return this.forward(e,"error","")}deprecate(...e){return this.forward(e,"warn","WARNING DEPRECATED: ",!0)}forward(e,n,a,i){return i&&!this.debug?null:(qn(e[0])&&(e[0]=`${a}${this.prefix} ${e[0]}`),this.logger[n](e))}create(e){return new GN(this.logger,{prefix:`${this.prefix}:${e}:`,...this.options})}clone(e){return e=e||this.options,e.prefix=e.prefix||this.prefix,new GN(this.logger,e)}}var Xd=new GN;let xT=class{constructor(){this.observers={}}on(e,n){return e.split(" ").forEach(a=>{this.observers[a]||(this.observers[a]=new Map);const i=this.observers[a].get(n)||0;this.observers[a].set(n,i+1)}),this}off(e,n){if(this.observers[e]){if(!n){delete this.observers[e];return}this.observers[e].delete(n)}}emit(e,...n){this.observers[e]&&Array.from(this.observers[e].entries()).forEach(([i,s])=>{for(let o=0;o{for(let o=0;o-1&&this.options.ns.splice(n,1)}getResource(e,n,a,i={}){const s=i.keySeparator!==void 0?i.keySeparator:this.options.keySeparator,o=i.ignoreJSONStructure!==void 0?i.ignoreJSONStructure:this.options.ignoreJSONStructure;let l;e.indexOf(".")>-1?l=e.split("."):(l=[e,n],a&&(Array.isArray(a)?l.push(...a):qn(a)&&s?l.push(...a.split(s)):l.push(a)));const c=VN(this.data,l);return!c&&!n&&!a&&e.indexOf(".")>-1&&(e=l[0],n=l[1],a=l.slice(2).join(".")),c||!o||!qn(a)?c:CF(this.data?.[e]?.[n],a,s)}addResource(e,n,a,i,s={silent:!1}){const o=s.keySeparator!==void 0?s.keySeparator:this.options.keySeparator;let l=[e,n];a&&(l=l.concat(o?a.split(o):a)),e.indexOf(".")>-1&&(l=e.split("."),i=n,n=l[1]),this.addNamespaces(n),PH(this.data,l,i),s.silent||this.emit("added",e,n,a,i)}addResources(e,n,a,i={silent:!1}){for(const s in a)(qn(a[s])||Array.isArray(a[s]))&&this.addResource(e,n,s,a[s],{silent:!0});i.silent||this.emit("added",e,n,a)}addResourceBundle(e,n,a,i,s,o={silent:!1,skipCopy:!1}){let l=[e,n];e.indexOf(".")>-1&&(l=e.split("."),i=a,a=n,n=l[1]),this.addNamespaces(n);let c=VN(this.data,l)||{};o.skipCopy||(a=JSON.parse(JSON.stringify(a))),i?FY(c,a,s):c={...c,...a},PH(this.data,l,c),o.silent||this.emit("added",e,n,a)}removeResourceBundle(e,n){this.hasResourceBundle(e,n)&&delete this.data[e][n],this.removeNamespaces(n),this.emit("removed",e,n)}hasResourceBundle(e,n){return this.getResource(e,n)!==void 0}getResourceBundle(e,n){return n||(n=this.options.defaultNS),this.getResource(e,n)}getDataByLanguage(e){return this.data[e]}hasLanguageSomeTranslations(e){const n=this.getDataByLanguage(e);return!!(n&&Object.keys(n)||[]).find(i=>n[i]&&Object.keys(n[i]).length>0)}toJSON(){return this.data}}var LY={processors:{},addPostProcessor(t){this.processors[t.name]=t},handle(t,e,n,a,i){return t.forEach(s=>{e=this.processors[s]?.process(e,n,a,i)??e}),e}};const RY=Symbol("i18next/PATH_KEY");function eme(){const t=[],e=Object.create(null);let n;return e.get=(a,i)=>(n?.revoke?.(),i===RY?t:(t.push(i),n=Proxy.revocable(a,e),n.proxy)),Proxy.revocable(Object.create(null),e).proxy}function PF(t,e){const{[RY]:n}=t(eme());return n.join(e?.keySeparator??".")}const AH={},JM=t=>!qn(t)&&typeof t!="boolean"&&typeof t!="number";class WN extends xT{constructor(e,n={}){super(),que(["resourceStore","languageUtils","pluralResolver","interpolator","backendConnector","i18nFormat","utils"],e,this),this.options=n,this.options.keySeparator===void 0&&(this.options.keySeparator="."),this.logger=Xd.create("translator")}changeLanguage(e){e&&(this.language=e)}exists(e,n={interpolation:{}}){const a={...n};if(e==null)return!1;const i=this.resolve(e,a);if(i?.res===void 0)return!1;const s=JM(i.res);return!(a.returnObjects===!1&&s)}extractFromKey(e,n){let a=n.nsSeparator!==void 0?n.nsSeparator:this.options.nsSeparator;a===void 0&&(a=":");const i=n.keySeparator!==void 0?n.keySeparator:this.options.keySeparator;let s=n.ns||this.options.defaultNS||[];const o=a&&e.indexOf(a)>-1,l=!this.options.userDefinedKeySeparator&&!n.keySeparator&&!this.options.userDefinedNsSeparator&&!n.nsSeparator&&!Zue(e,a,i);if(o&&!l){const c=e.match(this.interpolator.nestingRegexp);if(c&&c.length>0)return{key:e,namespaces:qn(s)?[s]:s};const d=e.split(a);(a!==i||a===i&&this.options.ns.indexOf(d[0])>-1)&&(s=d.shift()),e=d.join(i)}return{key:e,namespaces:qn(s)?[s]:s}}translate(e,n,a){let i=typeof n=="object"?{...n}:n;if(typeof i!="object"&&this.options.overloadTranslationOptionHandler&&(i=this.options.overloadTranslationOptionHandler(arguments)),typeof i=="object"&&(i={...i}),i||(i={}),e==null)return"";typeof e=="function"&&(e=PF(e,{...this.options,...i})),Array.isArray(e)||(e=[String(e)]);const s=i.returnDetails!==void 0?i.returnDetails:this.options.returnDetails,o=i.keySeparator!==void 0?i.keySeparator:this.options.keySeparator,{key:l,namespaces:c}=this.extractFromKey(e[e.length-1],i),d=c[c.length-1];let u=i.nsSeparator!==void 0?i.nsSeparator:this.options.nsSeparator;u===void 0&&(u=":");const m=i.lng||this.language,p=i.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if(m?.toLowerCase()==="cimode")return p?s?{res:`${d}${u}${l}`,usedKey:l,exactUsedKey:l,usedLng:m,usedNS:d,usedParams:this.getUsedParamsDetails(i)}:`${d}${u}${l}`:s?{res:l,usedKey:l,exactUsedKey:l,usedLng:m,usedNS:d,usedParams:this.getUsedParamsDetails(i)}:l;const f=this.resolve(e,i);let g=f?.res;const w=f?.usedKey||l,b=f?.exactUsedKey||l,x=["[object Number]","[object Function]","[object RegExp]"],S=i.joinArrays!==void 0?i.joinArrays:this.options.joinArrays,N=!this.i18nFormat||this.i18nFormat.handleAsObject,C=i.count!==void 0&&!qn(i.count),P=WN.hasDefaultValue(i),T=C?this.pluralResolver.getSuffix(m,i.count,i):"",A=i.ordinal&&C?this.pluralResolver.getSuffix(m,i.count,{ordinal:!1}):"",F=C&&!i.ordinal&&i.count===0,_=F&&i[`defaultValue${this.options.pluralSeparator}zero`]||i[`defaultValue${T}`]||i[`defaultValue${A}`]||i.defaultValue;let M=g;N&&!g&&P&&(M=_);const H=JM(M),I=Object.prototype.toString.apply(M);if(N&&M&&H&&x.indexOf(I)<0&&!(qn(S)&&Array.isArray(M))){if(!i.returnObjects&&!this.options.returnObjects){this.options.returnedObjectHandler||this.logger.warn("accessing an object - but returnObjects options is not enabled!");const U=this.options.returnedObjectHandler?this.options.returnedObjectHandler(w,M,{...i,ns:c}):`key '${l} (${this.language})' returned an object instead of string.`;return s?(f.res=U,f.usedParams=this.getUsedParamsDetails(i),f):U}if(o){const U=Array.isArray(M),R=U?[]:{},Y=U?b:w;for(const re in M)if(Object.prototype.hasOwnProperty.call(M,re)){const J=`${Y}${o}${re}`;P&&!g?R[re]=this.translate(J,{...i,defaultValue:JM(_)?_[re]:void 0,joinArrays:!1,ns:c}):R[re]=this.translate(J,{...i,joinArrays:!1,ns:c}),R[re]===J&&(R[re]=M[re])}g=R}}else if(N&&qn(S)&&Array.isArray(g))g=g.join(S),g&&(g=this.extendTranslation(g,e,i,a));else{let U=!1,R=!1;!this.isValidLookup(g)&&P&&(U=!0,g=_),this.isValidLookup(g)||(R=!0,g=l);const re=(i.missingKeyNoValueFallbackToKey||this.options.missingKeyNoValueFallbackToKey)&&R?void 0:g,J=P&&_!==g&&this.options.updateMissing;if(R||U||J){if(this.logger.log(J?"updateKey":"missingKey",m,d,l,J?_:g),o){const K=this.resolve(l,{...i,keySeparator:!1});K&&K.res&&this.logger.warn("Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.")}let de=[];const pe=this.languageUtils.getFallbackCodes(this.options.fallbackLng,i.lng||this.language);if(this.options.saveMissingTo==="fallback"&&pe&&pe[0])for(let K=0;K{const fe=P&&me!==g?me:re;this.options.missingKeyHandler?this.options.missingKeyHandler(K,d,ie,fe,J,i):this.backendConnector?.saveMissing&&this.backendConnector.saveMissing(K,d,ie,fe,J,i),this.emit("missingKey",K,d,ie,g)};this.options.saveMissing&&(this.options.saveMissingPlurals&&C?de.forEach(K=>{const ie=this.pluralResolver.getSuffixes(K,i);F&&i[`defaultValue${this.options.pluralSeparator}zero`]&&ie.indexOf(`${this.options.pluralSeparator}zero`)<0&&ie.push(`${this.options.pluralSeparator}zero`),ie.forEach(me=>{ue([K],l+me,i[`defaultValue${me}`]||_)})}):ue(de,l,_))}g=this.extendTranslation(g,e,i,f,a),R&&g===l&&this.options.appendNamespaceToMissingKey&&(g=`${d}${u}${l}`),(R||U)&&this.options.parseMissingKeyHandler&&(g=this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey?`${d}${u}${l}`:l,U?g:void 0,i))}return s?(f.res=g,f.usedParams=this.getUsedParamsDetails(i),f):g}extendTranslation(e,n,a,i,s){if(this.i18nFormat?.parse)e=this.i18nFormat.parse(e,{...this.options.interpolation.defaultVariables,...a},a.lng||this.language||i.usedLng,i.usedNS,i.usedKey,{resolved:i});else if(!a.skipInterpolation){a.interpolation&&this.interpolator.init({...a,interpolation:{...this.options.interpolation,...a.interpolation}});const c=qn(e)&&(a?.interpolation?.skipOnVariables!==void 0?a.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables);let d;if(c){const m=e.match(this.interpolator.nestingRegexp);d=m&&m.length}let u=a.replace&&!qn(a.replace)?a.replace:a;if(this.options.interpolation.defaultVariables&&(u={...this.options.interpolation.defaultVariables,...u}),e=this.interpolator.interpolate(e,u,a.lng||this.language||i.usedLng,a),c){const m=e.match(this.interpolator.nestingRegexp),p=m&&m.length;ds?.[0]===m[0]&&!a.context?(this.logger.warn(`It seems you are nesting recursively key: ${m[0]} in key: ${n[0]}`),null):this.translate(...m,n),a)),a.interpolation&&this.interpolator.reset()}const o=a.postProcess||this.options.postProcess,l=qn(o)?[o]:o;return e!=null&&l?.length&&a.applyPostProcessor!==!1&&(e=LY.handle(l,e,n,this.options&&this.options.postProcessPassResolved?{i18nResolved:{...i,usedParams:this.getUsedParamsDetails(a)},...a}:a,this)),e}resolve(e,n={}){let a,i,s,o,l;return qn(e)&&(e=[e]),e.forEach(c=>{if(this.isValidLookup(a))return;const d=this.extractFromKey(c,n),u=d.key;i=u;let m=d.namespaces;this.options.fallbackNS&&(m=m.concat(this.options.fallbackNS));const p=n.count!==void 0&&!qn(n.count),f=p&&!n.ordinal&&n.count===0,g=n.context!==void 0&&(qn(n.context)||typeof n.context=="number")&&n.context!=="",w=n.lngs?n.lngs:this.languageUtils.toResolveHierarchy(n.lng||this.language,n.fallbackLng);m.forEach(b=>{this.isValidLookup(a)||(l=b,!AH[`${w[0]}-${b}`]&&this.utils?.hasLoadedNamespace&&!this.utils?.hasLoadedNamespace(l)&&(AH[`${w[0]}-${b}`]=!0,this.logger.warn(`key "${i}" for languages "${w.join(", ")}" won't get resolved as namespace "${l}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!")),w.forEach(x=>{if(this.isValidLookup(a))return;o=x;const S=[u];if(this.i18nFormat?.addLookupKeys)this.i18nFormat.addLookupKeys(S,u,x,b,n);else{let C;p&&(C=this.pluralResolver.getSuffix(x,n.count,n));const P=`${this.options.pluralSeparator}zero`,T=`${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;if(p&&(n.ordinal&&C.indexOf(T)===0&&S.push(u+C.replace(T,this.options.pluralSeparator)),S.push(u+C),f&&S.push(u+P)),g){const A=`${u}${this.options.contextSeparator||"_"}${n.context}`;S.push(A),p&&(n.ordinal&&C.indexOf(T)===0&&S.push(A+C.replace(T,this.options.pluralSeparator)),S.push(A+C),f&&S.push(A+P))}}let N;for(;N=S.pop();)this.isValidLookup(a)||(s=N,a=this.getResource(x,b,N,n))}))})}),{res:a,usedKey:i,exactUsedKey:s,usedLng:o,usedNS:l}}isValidLookup(e){return e!==void 0&&!(!this.options.returnNull&&e===null)&&!(!this.options.returnEmptyString&&e==="")}getResource(e,n,a,i={}){return this.i18nFormat?.getResource?this.i18nFormat.getResource(e,n,a,i):this.resourceStore.getResource(e,n,a,i)}getUsedParamsDetails(e={}){const n=["defaultValue","ordinal","context","replace","lng","lngs","fallbackLng","ns","keySeparator","nsSeparator","returnObjects","returnDetails","joinArrays","postProcess","interpolation"],a=e.replace&&!qn(e.replace);let i=a?e.replace:e;if(a&&typeof e.count<"u"&&(i.count=e.count),this.options.interpolation.defaultVariables&&(i={...this.options.interpolation.defaultVariables,...i}),!a){i={...i};for(const s of n)delete i[s]}return i}static hasDefaultValue(e){const n="defaultValue";for(const a in e)if(Object.prototype.hasOwnProperty.call(e,a)&&n===a.substring(0,n.length)&&e[a]!==void 0)return!0;return!1}}class jH{constructor(e){this.options=e,this.supportedLngs=this.options.supportedLngs||!1,this.logger=Xd.create("languageUtils")}getScriptPartFromCode(e){if(e=Cw(e),!e||e.indexOf("-")<0)return null;const n=e.split("-");return n.length===2||(n.pop(),n[n.length-1].toLowerCase()==="x")?null:this.formatLanguageCode(n.join("-"))}getLanguagePartFromCode(e){if(e=Cw(e),!e||e.indexOf("-")<0)return e;const n=e.split("-");return this.formatLanguageCode(n[0])}formatLanguageCode(e){if(qn(e)&&e.indexOf("-")>-1){let n;try{n=Intl.getCanonicalLocales(e)[0]}catch{}return n&&this.options.lowerCaseLng&&(n=n.toLowerCase()),n||(this.options.lowerCaseLng?e.toLowerCase():e)}return this.options.cleanCode||this.options.lowerCaseLng?e.toLowerCase():e}isSupportedCode(e){return(this.options.load==="languageOnly"||this.options.nonExplicitSupportedLngs)&&(e=this.getLanguagePartFromCode(e)),!this.supportedLngs||!this.supportedLngs.length||this.supportedLngs.indexOf(e)>-1}getBestMatchFromCodes(e){if(!e)return null;let n;return e.forEach(a=>{if(n)return;const i=this.formatLanguageCode(a);(!this.options.supportedLngs||this.isSupportedCode(i))&&(n=i)}),!n&&this.options.supportedLngs&&e.forEach(a=>{if(n)return;const i=this.getScriptPartFromCode(a);if(this.isSupportedCode(i))return n=i;const s=this.getLanguagePartFromCode(a);if(this.isSupportedCode(s))return n=s;n=this.options.supportedLngs.find(o=>{if(o===s)return o;if(!(o.indexOf("-")<0&&s.indexOf("-")<0)&&(o.indexOf("-")>0&&s.indexOf("-")<0&&o.substring(0,o.indexOf("-"))===s||o.indexOf(s)===0&&s.length>1))return o})}),n||(n=this.getFallbackCodes(this.options.fallbackLng)[0]),n}getFallbackCodes(e,n){if(!e)return[];if(typeof e=="function"&&(e=e(n)),qn(e)&&(e=[e]),Array.isArray(e))return e;if(!n)return e.default||[];let a=e[n];return a||(a=e[this.getScriptPartFromCode(n)]),a||(a=e[this.formatLanguageCode(n)]),a||(a=e[this.getLanguagePartFromCode(n)]),a||(a=e.default),a||[]}toResolveHierarchy(e,n){const a=this.getFallbackCodes((n===!1?[]:n)||this.options.fallbackLng||[],e),i=[],s=o=>{o&&(this.isSupportedCode(o)?i.push(o):this.logger.warn(`rejecting language code not found in supportedLngs: ${o}`))};return qn(e)&&(e.indexOf("-")>-1||e.indexOf("_")>-1)?(this.options.load!=="languageOnly"&&s(this.formatLanguageCode(e)),this.options.load!=="languageOnly"&&this.options.load!=="currentOnly"&&s(this.getScriptPartFromCode(e)),this.options.load!=="currentOnly"&&s(this.getLanguagePartFromCode(e))):qn(e)&&s(this.formatLanguageCode(e)),a.forEach(o=>{i.indexOf(o)<0&&s(this.formatLanguageCode(o))}),i}}const MH={zero:0,one:1,two:2,few:3,many:4,other:5},EH={select:t=>t===1?"one":"other",resolvedOptions:()=>({pluralCategories:["one","other"]})};class tme{constructor(e,n={}){this.languageUtils=e,this.options=n,this.logger=Xd.create("pluralResolver"),this.pluralRulesCache={}}addRule(e,n){this.rules[e]=n}clearCache(){this.pluralRulesCache={}}getRule(e,n={}){const a=Cw(e==="dev"?"en":e),i=n.ordinal?"ordinal":"cardinal",s=JSON.stringify({cleanedCode:a,type:i});if(s in this.pluralRulesCache)return this.pluralRulesCache[s];let o;try{o=new Intl.PluralRules(a,{type:i})}catch{if(!Intl)return this.logger.error("No Intl support, please use an Intl polyfill!"),EH;if(!e.match(/-|_/))return EH;const c=this.languageUtils.getLanguagePartFromCode(e);o=this.getRule(c,n)}return this.pluralRulesCache[s]=o,o}needsPlural(e,n={}){let a=this.getRule(e,n);return a||(a=this.getRule("dev",n)),a?.resolvedOptions().pluralCategories.length>1}getPluralFormsOfKey(e,n,a={}){return this.getSuffixes(e,a).map(i=>`${n}${i}`)}getSuffixes(e,n={}){let a=this.getRule(e,n);return a||(a=this.getRule("dev",n)),a?a.resolvedOptions().pluralCategories.sort((i,s)=>MH[i]-MH[s]).map(i=>`${this.options.prepend}${n.ordinal?`ordinal${this.options.prepend}`:""}${i}`):[]}getSuffix(e,n,a={}){const i=this.getRule(e,a);return i?`${this.options.prepend}${a.ordinal?`ordinal${this.options.prepend}`:""}${i.select(n)}`:(this.logger.warn(`no plural rule found for: ${e}`),this.getSuffix("dev",n,a))}}const DH=(t,e,n,a=".",i=!0)=>{let s=Gue(t,e,n);return!s&&i&&qn(n)&&(s=CF(t,n,a),s===void 0&&(s=CF(e,n,a))),s},eE=t=>t.replace(/\$/g,"$$$$");class nme{constructor(e={}){this.logger=Xd.create("interpolator"),this.options=e,this.format=e?.interpolation?.format||(n=>n),this.init(e)}init(e={}){e.interpolation||(e.interpolation={escapeValue:!0});const{escape:n,escapeValue:a,useRawValueToEscape:i,prefix:s,prefixEscaped:o,suffix:l,suffixEscaped:c,formatSeparator:d,unescapeSuffix:u,unescapePrefix:m,nestingPrefix:p,nestingPrefixEscaped:f,nestingSuffix:g,nestingSuffixEscaped:w,nestingOptionsSeparator:b,maxReplaces:x,alwaysFormat:S}=e.interpolation;this.escape=n!==void 0?n:Kue,this.escapeValue=a!==void 0?a:!0,this.useRawValueToEscape=i!==void 0?i:!1,this.prefix=s?Wb(s):o||"{{",this.suffix=l?Wb(l):c||"}}",this.formatSeparator=d||",",this.unescapePrefix=u?"":m||"-",this.unescapeSuffix=this.unescapePrefix?"":u||"",this.nestingPrefix=p?Wb(p):f||Wb("$t("),this.nestingSuffix=g?Wb(g):w||Wb(")"),this.nestingOptionsSeparator=b||",",this.maxReplaces=x||1e3,this.alwaysFormat=S!==void 0?S:!1,this.resetRegExp()}reset(){this.options&&this.init(this.options)}resetRegExp(){const e=(n,a)=>n?.source===a?(n.lastIndex=0,n):new RegExp(a,"g");this.regexp=e(this.regexp,`${this.prefix}(.+?)${this.suffix}`),this.regexpUnescape=e(this.regexpUnescape,`${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`),this.nestingRegexp=e(this.nestingRegexp,`${this.nestingPrefix}((?:[^()"']+|"[^"]*"|'[^']*'|\\((?:[^()]|"[^"]*"|'[^']*')*\\))*?)${this.nestingSuffix}`)}interpolate(e,n,a,i){let s,o,l;const c=this.options&&this.options.interpolation&&this.options.interpolation.defaultVariables||{},d=f=>{if(f.indexOf(this.formatSeparator)<0){const x=DH(n,c,f,this.options.keySeparator,this.options.ignoreJSONStructure);return this.alwaysFormat?this.format(x,void 0,a,{...i,...n,interpolationkey:f}):x}const g=f.split(this.formatSeparator),w=g.shift().trim(),b=g.join(this.formatSeparator).trim();return this.format(DH(n,c,w,this.options.keySeparator,this.options.ignoreJSONStructure),b,a,{...i,...n,interpolationkey:w})};this.resetRegExp();const u=i?.missingInterpolationHandler||this.options.missingInterpolationHandler,m=i?.interpolation?.skipOnVariables!==void 0?i.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables;return[{regex:this.regexpUnescape,safeValue:f=>eE(f)},{regex:this.regexp,safeValue:f=>this.escapeValue?eE(this.escape(f)):eE(f)}].forEach(f=>{for(l=0;s=f.regex.exec(e);){const g=s[1].trim();if(o=d(g),o===void 0)if(typeof u=="function"){const b=u(e,s,i);o=qn(b)?b:""}else if(i&&Object.prototype.hasOwnProperty.call(i,g))o="";else if(m){o=s[0];continue}else this.logger.warn(`missed to pass in variable ${g} for interpolating ${e}`),o="";else!qn(o)&&!this.useRawValueToEscape&&(o=kH(o));const w=f.safeValue(o);if(e=e.replace(s[0],w),m?(f.regex.lastIndex+=o.length,f.regex.lastIndex-=s[0].length):f.regex.lastIndex=0,l++,l>=this.maxReplaces)break}}),e}nest(e,n,a={}){let i,s,o;const l=(c,d)=>{const u=this.nestingOptionsSeparator;if(c.indexOf(u)<0)return c;const m=c.split(new RegExp(`${u}[ ]*{`));let p=`{${m[1]}`;c=m[0],p=this.interpolate(p,o);const f=p.match(/'/g),g=p.match(/"/g);((f?.length??0)%2===0&&!g||g.length%2!==0)&&(p=p.replace(/'/g,'"'));try{o=JSON.parse(p),d&&(o={...d,...o})}catch(w){return this.logger.warn(`failed parsing options string in nesting for key ${c}`,w),`${c}${u}${p}`}return o.defaultValue&&o.defaultValue.indexOf(this.prefix)>-1&&delete o.defaultValue,c};for(;i=this.nestingRegexp.exec(e);){let c=[];o={...a},o=o.replace&&!qn(o.replace)?o.replace:o,o.applyPostProcessor=!1,delete o.defaultValue;const d=/{.*}/.test(i[1])?i[1].lastIndexOf("}")+1:i[1].indexOf(this.formatSeparator);if(d!==-1&&(c=i[1].slice(d).split(this.formatSeparator).map(u=>u.trim()).filter(Boolean),i[1]=i[1].slice(0,d)),s=n(l.call(this,i[1].trim(),o),o),s&&i[0]===e&&!qn(s))return s;qn(s)||(s=kH(s)),s||(this.logger.warn(`missed to resolve ${i[1]} for nesting ${e}`),s=""),c.length&&(s=c.reduce((u,m)=>this.format(u,m,a.lng,{...a,interpolationkey:i[1].trim()}),s.trim())),e=e.replace(i[0],s),this.regexp.lastIndex=0}return e}}const rme=t=>{let e=t.toLowerCase().trim();const n={};if(t.indexOf("(")>-1){const a=t.split("(");e=a[0].toLowerCase().trim();const i=a[1].substring(0,a[1].length-1);e==="currency"&&i.indexOf(":")<0?n.currency||(n.currency=i.trim()):e==="relativetime"&&i.indexOf(":")<0?n.range||(n.range=i.trim()):i.split(";").forEach(o=>{if(o){const[l,...c]=o.split(":"),d=c.join(":").trim().replace(/^'+|'+$/g,""),u=l.trim();n[u]||(n[u]=d),d==="false"&&(n[u]=!1),d==="true"&&(n[u]=!0),isNaN(d)||(n[u]=parseInt(d,10))}})}return{formatName:e,formatOptions:n}},FH=t=>{const e={};return(n,a,i)=>{let s=i;i&&i.interpolationkey&&i.formatParams&&i.formatParams[i.interpolationkey]&&i[i.interpolationkey]&&(s={...s,[i.interpolationkey]:void 0});const o=a+JSON.stringify(s);let l=e[o];return l||(l=t(Cw(a),i),e[o]=l),l(n)}},ame=t=>(e,n,a)=>t(Cw(n),a)(e);class ime{constructor(e={}){this.logger=Xd.create("formatter"),this.options=e,this.init(e)}init(e,n={interpolation:{}}){this.formatSeparator=n.interpolation.formatSeparator||",";const a=n.cacheInBuiltFormats?FH:ame;this.formats={number:a((i,s)=>{const o=new Intl.NumberFormat(i,{...s});return l=>o.format(l)}),currency:a((i,s)=>{const o=new Intl.NumberFormat(i,{...s,style:"currency"});return l=>o.format(l)}),datetime:a((i,s)=>{const o=new Intl.DateTimeFormat(i,{...s});return l=>o.format(l)}),relativetime:a((i,s)=>{const o=new Intl.RelativeTimeFormat(i,{...s});return l=>o.format(l,s.range||"day")}),list:a((i,s)=>{const o=new Intl.ListFormat(i,{...s});return l=>o.format(l)})}}add(e,n){this.formats[e.toLowerCase().trim()]=n}addCached(e,n){this.formats[e.toLowerCase().trim()]=FH(n)}format(e,n,a,i={}){const s=n.split(this.formatSeparator);if(s.length>1&&s[0].indexOf("(")>1&&s[0].indexOf(")")<0&&s.find(l=>l.indexOf(")")>-1)){const l=s.findIndex(c=>c.indexOf(")")>-1);s[0]=[s[0],...s.splice(1,l)].join(this.formatSeparator)}return s.reduce((l,c)=>{const{formatName:d,formatOptions:u}=rme(c);if(this.formats[d]){let m=l;try{const p=i?.formatParams?.[i.interpolationkey]||{},f=p.locale||p.lng||i.locale||i.lng||a;m=this.formats[d](l,f,{...u,...i,...p})}catch(p){this.logger.warn(p)}return m}else this.logger.warn(`there was no format function for ${d}`);return l},e)}}const sme=(t,e)=>{t.pending[e]!==void 0&&(delete t.pending[e],t.pendingCount--)};class ome extends xT{constructor(e,n,a,i={}){super(),this.backend=e,this.store=n,this.services=a,this.languageUtils=a.languageUtils,this.options=i,this.logger=Xd.create("backendConnector"),this.waitingReads=[],this.maxParallelReads=i.maxParallelReads||10,this.readingCalls=0,this.maxRetries=i.maxRetries>=0?i.maxRetries:5,this.retryTimeout=i.retryTimeout>=1?i.retryTimeout:350,this.state={},this.queue=[],this.backend?.init?.(a,i.backend,i)}queueLoad(e,n,a,i){const s={},o={},l={},c={};return e.forEach(d=>{let u=!0;n.forEach(m=>{const p=`${d}|${m}`;!a.reload&&this.store.hasResourceBundle(d,m)?this.state[p]=2:this.state[p]<0||(this.state[p]===1?o[p]===void 0&&(o[p]=!0):(this.state[p]=1,u=!1,o[p]===void 0&&(o[p]=!0),s[p]===void 0&&(s[p]=!0),c[m]===void 0&&(c[m]=!0)))}),u||(l[d]=!0)}),(Object.keys(s).length||Object.keys(o).length)&&this.queue.push({pending:o,pendingCount:Object.keys(o).length,loaded:{},errors:[],callback:i}),{toLoad:Object.keys(s),pending:Object.keys(o),toLoadLanguages:Object.keys(l),toLoadNamespaces:Object.keys(c)}}loaded(e,n,a){const i=e.split("|"),s=i[0],o=i[1];n&&this.emit("failedLoading",s,o,n),!n&&a&&this.store.addResourceBundle(s,o,a,void 0,void 0,{skipCopy:!0}),this.state[e]=n?-1:2,n&&a&&(this.state[e]=0);const l={};this.queue.forEach(c=>{Vue(c.loaded,[s],o),sme(c,e),n&&c.errors.push(n),c.pendingCount===0&&!c.done&&(Object.keys(c.loaded).forEach(d=>{l[d]||(l[d]={});const u=c.loaded[d];u.length&&u.forEach(m=>{l[d][m]===void 0&&(l[d][m]=!0)})}),c.done=!0,c.errors.length?c.callback(c.errors):c.callback())}),this.emit("loaded",l),this.queue=this.queue.filter(c=>!c.done)}read(e,n,a,i=0,s=this.retryTimeout,o){if(!e.length)return o(null,{});if(this.readingCalls>=this.maxParallelReads){this.waitingReads.push({lng:e,ns:n,fcName:a,tried:i,wait:s,callback:o});return}this.readingCalls++;const l=(d,u)=>{if(this.readingCalls--,this.waitingReads.length>0){const m=this.waitingReads.shift();this.read(m.lng,m.ns,m.fcName,m.tried,m.wait,m.callback)}if(d&&u&&i{this.read.call(this,e,n,a,i+1,s*2,o)},s);return}o(d,u)},c=this.backend[a].bind(this.backend);if(c.length===2){try{const d=c(e,n);d&&typeof d.then=="function"?d.then(u=>l(null,u)).catch(l):l(null,d)}catch(d){l(d)}return}return c(e,n,l)}prepareLoading(e,n,a={},i){if(!this.backend)return this.logger.warn("No backend was added via i18next.use. Will not load resources."),i&&i();qn(e)&&(e=this.languageUtils.toResolveHierarchy(e)),qn(n)&&(n=[n]);const s=this.queueLoad(e,n,a,i);if(!s.toLoad.length)return s.pending.length||i(),null;s.toLoad.forEach(o=>{this.loadOne(o)})}load(e,n,a){this.prepareLoading(e,n,{},a)}reload(e,n,a){this.prepareLoading(e,n,{reload:!0},a)}loadOne(e,n=""){const a=e.split("|"),i=a[0],s=a[1];this.read(i,s,"read",void 0,void 0,(o,l)=>{o&&this.logger.warn(`${n}loading namespace ${s} for language ${i} failed`,o),!o&&l&&this.logger.log(`${n}loaded namespace ${s} for language ${i}`,l),this.loaded(e,o,l)})}saveMissing(e,n,a,i,s,o={},l=()=>{}){if(this.services?.utils?.hasLoadedNamespace&&!this.services?.utils?.hasLoadedNamespace(n)){this.logger.warn(`did not save key "${a}" as the namespace "${n}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");return}if(!(a==null||a==="")){if(this.backend?.create){const c={...o,isUpdate:s},d=this.backend.create.bind(this.backend);if(d.length<6)try{let u;d.length===5?u=d(e,n,a,i,c):u=d(e,n,a,i),u&&typeof u.then=="function"?u.then(m=>l(null,m)).catch(l):l(null,u)}catch(u){l(u)}else d(e,n,a,i,l,c)}!e||!e[0]||this.store.addResource(e[0],n,a,i)}}}const LH=()=>({debug:!1,initAsync:!0,ns:["translation"],defaultNS:["translation"],fallbackLng:["dev"],fallbackNS:!1,supportedLngs:!1,nonExplicitSupportedLngs:!1,load:"all",preload:!1,simplifyPluralSuffix:!0,keySeparator:".",nsSeparator:":",pluralSeparator:"_",contextSeparator:"_",partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:"fallback",saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,postProcessPassResolved:!1,returnNull:!1,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:!1,parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:t=>{let e={};if(typeof t[1]=="object"&&(e=t[1]),qn(t[1])&&(e.defaultValue=t[1]),qn(t[2])&&(e.tDescription=t[2]),typeof t[2]=="object"||typeof t[3]=="object"){const n=t[3]||t[2];Object.keys(n).forEach(a=>{e[a]=n[a]})}return e},interpolation:{escapeValue:!0,format:t=>t,prefix:"{{",suffix:"}}",formatSeparator:",",unescapePrefix:"-",nestingPrefix:"$t(",nestingSuffix:")",nestingOptionsSeparator:",",maxReplaces:1e3,skipOnVariables:!0},cacheInBuiltFormats:!0}),RH=t=>(qn(t.ns)&&(t.ns=[t.ns]),qn(t.fallbackLng)&&(t.fallbackLng=[t.fallbackLng]),qn(t.fallbackNS)&&(t.fallbackNS=[t.fallbackNS]),t.supportedLngs?.indexOf?.("cimode")<0&&(t.supportedLngs=t.supportedLngs.concat(["cimode"])),typeof t.initImmediate=="boolean"&&(t.initAsync=t.initImmediate),t),_k=()=>{},lme=t=>{Object.getOwnPropertyNames(Object.getPrototypeOf(t)).forEach(n=>{typeof t[n]=="function"&&(t[n]=t[n].bind(t))})};class Q0 extends xT{constructor(e={},n){if(super(),this.options=RH(e),this.services={},this.logger=Xd,this.modules={external:[]},lme(this),n&&!this.isInitialized&&!e.isClone){if(!this.options.initAsync)return this.init(e,n),this;setTimeout(()=>{this.init(e,n)},0)}}init(e={},n){this.isInitializing=!0,typeof e=="function"&&(n=e,e={}),e.defaultNS==null&&e.ns&&(qn(e.ns)?e.defaultNS=e.ns:e.ns.indexOf("translation")<0&&(e.defaultNS=e.ns[0]));const a=LH();this.options={...a,...this.options,...RH(e)},this.options.interpolation={...a.interpolation,...this.options.interpolation},e.keySeparator!==void 0&&(this.options.userDefinedKeySeparator=e.keySeparator),e.nsSeparator!==void 0&&(this.options.userDefinedNsSeparator=e.nsSeparator);const i=d=>d?typeof d=="function"?new d:d:null;if(!this.options.isClone){this.modules.logger?Xd.init(i(this.modules.logger),this.options):Xd.init(null,this.options);let d;this.modules.formatter?d=this.modules.formatter:d=ime;const u=new jH(this.options);this.store=new TH(this.options.resources,this.options);const m=this.services;m.logger=Xd,m.resourceStore=this.store,m.languageUtils=u,m.pluralResolver=new tme(u,{prepend:this.options.pluralSeparator,simplifyPluralSuffix:this.options.simplifyPluralSuffix}),this.options.interpolation.format&&this.options.interpolation.format!==a.interpolation.format&&this.logger.deprecate("init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting"),d&&(!this.options.interpolation.format||this.options.interpolation.format===a.interpolation.format)&&(m.formatter=i(d),m.formatter.init&&m.formatter.init(m,this.options),this.options.interpolation.format=m.formatter.format.bind(m.formatter)),m.interpolator=new nme(this.options),m.utils={hasLoadedNamespace:this.hasLoadedNamespace.bind(this)},m.backendConnector=new ome(i(this.modules.backend),m.resourceStore,m,this.options),m.backendConnector.on("*",(f,...g)=>{this.emit(f,...g)}),this.modules.languageDetector&&(m.languageDetector=i(this.modules.languageDetector),m.languageDetector.init&&m.languageDetector.init(m,this.options.detection,this.options)),this.modules.i18nFormat&&(m.i18nFormat=i(this.modules.i18nFormat),m.i18nFormat.init&&m.i18nFormat.init(this)),this.translator=new WN(this.services,this.options),this.translator.on("*",(f,...g)=>{this.emit(f,...g)}),this.modules.external.forEach(f=>{f.init&&f.init(this)})}if(this.format=this.options.interpolation.format,n||(n=_k),this.options.fallbackLng&&!this.services.languageDetector&&!this.options.lng){const d=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);d.length>0&&d[0]!=="dev"&&(this.options.lng=d[0])}!this.services.languageDetector&&!this.options.lng&&this.logger.warn("init: no languageDetector is used and no lng is defined"),["getResource","hasResourceBundle","getResourceBundle","getDataByLanguage"].forEach(d=>{this[d]=(...u)=>this.store[d](...u)}),["addResource","addResources","addResourceBundle","removeResourceBundle"].forEach(d=>{this[d]=(...u)=>(this.store[d](...u),this)});const l=Yv(),c=()=>{const d=(u,m)=>{this.isInitializing=!1,this.isInitialized&&!this.initializedStoreOnce&&this.logger.warn("init: i18next is already initialized. You should call init just once!"),this.isInitialized=!0,this.options.isClone||this.logger.log("initialized",this.options),this.emit("initialized",this.options),l.resolve(m),n(u,m)};if(this.languages&&!this.isInitialized)return d(null,this.t.bind(this));this.changeLanguage(this.options.lng,d)};return this.options.resources||!this.options.initAsync?c():setTimeout(c,0),l}loadResources(e,n=_k){let a=n;const i=qn(e)?e:this.language;if(typeof e=="function"&&(a=e),!this.options.resources||this.options.partialBundledLanguages){if(i?.toLowerCase()==="cimode"&&(!this.options.preload||this.options.preload.length===0))return a();const s=[],o=l=>{if(!l||l==="cimode")return;this.services.languageUtils.toResolveHierarchy(l).forEach(d=>{d!=="cimode"&&s.indexOf(d)<0&&s.push(d)})};i?o(i):this.services.languageUtils.getFallbackCodes(this.options.fallbackLng).forEach(c=>o(c)),this.options.preload?.forEach?.(l=>o(l)),this.services.backendConnector.load(s,this.options.ns,l=>{!l&&!this.resolvedLanguage&&this.language&&this.setResolvedLanguage(this.language),a(l)})}else a(null)}reloadResources(e,n,a){const i=Yv();return typeof e=="function"&&(a=e,e=void 0),typeof n=="function"&&(a=n,n=void 0),e||(e=this.languages),n||(n=this.options.ns),a||(a=_k),this.services.backendConnector.reload(e,n,s=>{i.resolve(),a(s)}),i}use(e){if(!e)throw new Error("You are passing an undefined module! Please check the object you are passing to i18next.use()");if(!e.type)throw new Error("You are passing a wrong module! Please check the object you are passing to i18next.use()");return e.type==="backend"&&(this.modules.backend=e),(e.type==="logger"||e.log&&e.warn&&e.error)&&(this.modules.logger=e),e.type==="languageDetector"&&(this.modules.languageDetector=e),e.type==="i18nFormat"&&(this.modules.i18nFormat=e),e.type==="postProcessor"&&LY.addPostProcessor(e),e.type==="formatter"&&(this.modules.formatter=e),e.type==="3rdParty"&&this.modules.external.push(e),this}setResolvedLanguage(e){if(!(!e||!this.languages)&&!(["cimode","dev"].indexOf(e)>-1)){for(let n=0;n-1)&&this.store.hasLanguageSomeTranslations(a)){this.resolvedLanguage=a;break}}!this.resolvedLanguage&&this.languages.indexOf(e)<0&&this.store.hasLanguageSomeTranslations(e)&&(this.resolvedLanguage=e,this.languages.unshift(e))}}changeLanguage(e,n){this.isLanguageChangingTo=e;const a=Yv();this.emit("languageChanging",e);const i=l=>{this.language=l,this.languages=this.services.languageUtils.toResolveHierarchy(l),this.resolvedLanguage=void 0,this.setResolvedLanguage(l)},s=(l,c)=>{c?this.isLanguageChangingTo===e&&(i(c),this.translator.changeLanguage(c),this.isLanguageChangingTo=void 0,this.emit("languageChanged",c),this.logger.log("languageChanged",c)):this.isLanguageChangingTo=void 0,a.resolve((...d)=>this.t(...d)),n&&n(l,(...d)=>this.t(...d))},o=l=>{!e&&!l&&this.services.languageDetector&&(l=[]);const c=qn(l)?l:l&&l[0],d=this.store.hasLanguageSomeTranslations(c)?c:this.services.languageUtils.getBestMatchFromCodes(qn(l)?[l]:l);d&&(this.language||i(d),this.translator.language||this.translator.changeLanguage(d),this.services.languageDetector?.cacheUserLanguage?.(d)),this.loadResources(d,u=>{s(u,d)})};return!e&&this.services.languageDetector&&!this.services.languageDetector.async?o(this.services.languageDetector.detect()):!e&&this.services.languageDetector&&this.services.languageDetector.async?this.services.languageDetector.detect.length===0?this.services.languageDetector.detect().then(o):this.services.languageDetector.detect(o):o(e),a}getFixedT(e,n,a){const i=(s,o,...l)=>{let c;typeof o!="object"?c=this.options.overloadTranslationOptionHandler([s,o].concat(l)):c={...o},c.lng=c.lng||i.lng,c.lngs=c.lngs||i.lngs,c.ns=c.ns||i.ns,c.keyPrefix!==""&&(c.keyPrefix=c.keyPrefix||a||i.keyPrefix);const d=this.options.keySeparator||".";let u;return c.keyPrefix&&Array.isArray(s)?u=s.map(m=>(typeof m=="function"&&(m=PF(m,{...this.options,...o})),`${c.keyPrefix}${d}${m}`)):(typeof s=="function"&&(s=PF(s,{...this.options,...o})),u=c.keyPrefix?`${c.keyPrefix}${d}${s}`:s),this.t(u,c)};return qn(e)?i.lng=e:i.lngs=e,i.ns=n,i.keyPrefix=a,i}t(...e){return this.translator?.translate(...e)}exists(...e){return this.translator?.exists(...e)}setDefaultNamespace(e){this.options.defaultNS=e}hasLoadedNamespace(e,n={}){if(!this.isInitialized)return this.logger.warn("hasLoadedNamespace: i18next was not initialized",this.languages),!1;if(!this.languages||!this.languages.length)return this.logger.warn("hasLoadedNamespace: i18n.languages were undefined or empty",this.languages),!1;const a=n.lng||this.resolvedLanguage||this.languages[0],i=this.options?this.options.fallbackLng:!1,s=this.languages[this.languages.length-1];if(a.toLowerCase()==="cimode")return!0;const o=(l,c)=>{const d=this.services.backendConnector.state[`${l}|${c}`];return d===-1||d===0||d===2};if(n.precheck){const l=n.precheck(this,o);if(l!==void 0)return l}return!!(this.hasResourceBundle(a,e)||!this.services.backendConnector.backend||this.options.resources&&!this.options.partialBundledLanguages||o(a,e)&&(!i||o(s,e)))}loadNamespaces(e,n){const a=Yv();return this.options.ns?(qn(e)&&(e=[e]),e.forEach(i=>{this.options.ns.indexOf(i)<0&&this.options.ns.push(i)}),this.loadResources(i=>{a.resolve(),n&&n(i)}),a):(n&&n(),Promise.resolve())}loadLanguages(e,n){const a=Yv();qn(e)&&(e=[e]);const i=this.options.preload||[],s=e.filter(o=>i.indexOf(o)<0&&this.services.languageUtils.isSupportedCode(o));return s.length?(this.options.preload=i.concat(s),this.loadResources(o=>{a.resolve(),n&&n(o)}),a):(n&&n(),Promise.resolve())}dir(e){if(e||(e=this.resolvedLanguage||(this.languages?.length>0?this.languages[0]:this.language)),!e)return"rtl";try{const i=new Intl.Locale(e);if(i&&i.getTextInfo){const s=i.getTextInfo();if(s&&s.direction)return s.direction}}catch{}const n=["ar","shu","sqr","ssh","xaa","yhd","yud","aao","abh","abv","acm","acq","acw","acx","acy","adf","ads","aeb","aec","afb","ajp","apc","apd","arb","arq","ars","ary","arz","auz","avl","ayh","ayl","ayn","ayp","bbz","pga","he","iw","ps","pbt","pbu","pst","prp","prd","ug","ur","ydd","yds","yih","ji","yi","hbo","men","xmn","fa","jpr","peo","pes","prs","dv","sam","ckb"],a=this.services?.languageUtils||new jH(LH());return e.toLowerCase().indexOf("-latn")>1?"ltr":n.indexOf(a.getLanguagePartFromCode(e))>-1||e.toLowerCase().indexOf("-arab")>1?"rtl":"ltr"}static createInstance(e={},n){const a=new Q0(e,n);return a.createInstance=Q0.createInstance,a}cloneInstance(e={},n=_k){const a=e.forkResourceStore;a&&delete e.forkResourceStore;const i={...this.options,...e,isClone:!0},s=new Q0(i);if((e.debug!==void 0||e.prefix!==void 0)&&(s.logger=s.logger.clone(e)),["store","services","language"].forEach(l=>{s[l]=this[l]}),s.services={...this.services},s.services.utils={hasLoadedNamespace:s.hasLoadedNamespace.bind(s)},a){const l=Object.keys(this.store.data).reduce((c,d)=>(c[d]={...this.store.data[d]},c[d]=Object.keys(c[d]).reduce((u,m)=>(u[m]={...c[d][m]},u),c[d]),c),{});s.store=new TH(l,i),s.services.resourceStore=s.store}return s.translator=new WN(s.services,i),s.translator.on("*",(l,...c)=>{s.emit(l,...c)}),s.init(i,n),s.translator.options=i,s.translator.backendConnector.services.utils={hasLoadedNamespace:s.hasLoadedNamespace.bind(s)},s}toJSON(){return{options:this.options,store:this.store,language:this.language,languages:this.languages,resolvedLanguage:this.resolvedLanguage}}}const Mo=Q0.createInstance();Mo.createInstance;Mo.dir;Mo.init;Mo.loadResources;Mo.reloadResources;Mo.use;Mo.changeLanguage;Mo.getFixedT;Mo.t;Mo.exists;Mo.setDefaultNamespace;Mo.hasLoadedNamespace;Mo.loadNamespaces;Mo.loadLanguages;const cme=(t,e,n,a)=>{const i=[n,{code:e,...a||{}}];if(t?.services?.logger?.forward)return t.services.logger.forward(i,"warn","react-i18next::",!0);Pg(i[0])&&(i[0]=`react-i18next:: ${i[0]}`),t?.services?.logger?.warn?t.services.logger.warn(...i):console?.warn&&console.warn(...i)},IH={},IY=(t,e,n,a)=>{Pg(n)&&IH[n]||(Pg(n)&&(IH[n]=new Date),cme(t,e,n,a))},OY=(t,e)=>()=>{if(t.isInitialized)e();else{const n=()=>{setTimeout(()=>{t.off("initialized",n)},0),e()};t.on("initialized",n)}},TF=(t,e,n)=>{t.loadNamespaces(e,OY(t,n))},OH=(t,e,n,a)=>{if(Pg(n)&&(n=[n]),t.options.preload&&t.options.preload.indexOf(e)>-1)return TF(t,n,a);n.forEach(i=>{t.options.ns.indexOf(i)<0&&t.options.ns.push(i)}),t.loadLanguages(e,OY(t,a))},dme=(t,e,n={})=>!e.languages||!e.languages.length?(IY(e,"NO_LANGUAGES","i18n.languages were undefined or empty",{languages:e.languages}),!0):e.hasLoadedNamespace(t,{lng:n.lng,precheck:(a,i)=>{if(n.bindI18n&&n.bindI18n.indexOf("languageChanging")>-1&&a.services.backendConnector.backend&&a.isLanguageChangingTo&&!i(a.isLanguageChangingTo,t))return!1}}),Pg=t=>typeof t=="string",ume=t=>typeof t=="object"&&t!==null,mme=/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g,pme={"&":"&","&":"&","<":"<","<":"<",">":">",">":">","'":"'","'":"'",""":'"',""":'"'," ":" "," ":" ","©":"©","©":"©","®":"®","®":"®","…":"…","…":"…","/":"/","/":"/"},hme=t=>pme[t],fme=t=>t.replace(mme,hme);let AF={bindI18n:"languageChanged",bindI18nStore:"",transEmptyNodeValue:"",transSupportBasicHtmlNodes:!0,transWrapTextNodes:"",transKeepBasicHtmlNodesFor:["br","strong","i","p"],useSuspense:!0,unescape:fme,transDefaultProps:void 0};const gme=(t={})=>{AF={...AF,...t}},bme=()=>AF;let zY;const xme=t=>{zY=t},yme=()=>zY,vme={type:"3rdParty",init(t){gme(t.options.react),xme(t)}},wme=y.createContext();class Sme{constructor(){this.usedNamespaces={}}addUsedNamespaces(e){e.forEach(n=>{this.usedNamespaces[n]||(this.usedNamespaces[n]=!0)})}getUsedNamespaces(){return Object.keys(this.usedNamespaces)}}var tE={exports:{}},nE={};var zH;function _me(){if(zH)return nE;zH=1;var t=tb();function e(m,p){return m===p&&(m!==0||1/m===1/p)||m!==m&&p!==p}var n=typeof Object.is=="function"?Object.is:e,a=t.useState,i=t.useEffect,s=t.useLayoutEffect,o=t.useDebugValue;function l(m,p){var f=p(),g=a({inst:{value:f,getSnapshot:p}}),w=g[0].inst,b=g[1];return s(function(){w.value=f,w.getSnapshot=p,c(w)&&b({inst:w})},[m,f,p]),i(function(){return c(w)&&b({inst:w}),m(function(){c(w)&&b({inst:w})})},[m]),o(f),f}function c(m){var p=m.getSnapshot;m=m.value;try{var f=p();return!n(m,f)}catch{return!0}}function d(m,p){return p()}var u=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?d:l;return nE.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:u,nE}var UH;function UY(){return UH||(UH=1,tE.exports=_me()),tE.exports}var eO=UY();const kme=(t,e)=>Pg(e)?e:ume(e)&&Pg(e.defaultValue)?e.defaultValue:Array.isArray(t)?t[t.length-1]:t,Nme={t:kme,ready:!1},Cme=()=>()=>{},St=(t,e={})=>{const{i18n:n}=e,{i18n:a,defaultNS:i}=y.useContext(wme)||{},s=n||a||yme();s&&!s.reportNamespaces&&(s.reportNamespaces=new Sme),s||IY(s,"NO_I18NEXT_INSTANCE","useTranslation: You will need to pass in an i18next instance by using initReactI18next");const o=y.useMemo(()=>({...bme(),...s?.options?.react,...e}),[s,e]),{useSuspense:l,keyPrefix:c}=o,d=i||s?.options?.defaultNS,u=Pg(d)?[d]:d||["translation"],m=y.useMemo(()=>u,u);s?.reportNamespaces?.addUsedNamespaces?.(m);const p=y.useRef(0),f=y.useCallback(_=>{if(!s)return Cme;const{bindI18n:M,bindI18nStore:H}=o,I=()=>{p.current+=1,_()};return M&&s.on(M,I),H&&s.store.on(H,I),()=>{M&&M.split(" ").forEach(U=>s.off(U,I)),H&&H.split(" ").forEach(U=>s.store.off(U,I))}},[s,o]),g=y.useRef(),w=y.useCallback(()=>{if(!s)return Nme;const _=!!(s.isInitialized||s.initializedStoreOnce)&&m.every(Y=>dme(Y,s,o)),M=e.lng||s.language,H=p.current,I=g.current;if(I&&I.ready===_&&I.lng===M&&I.keyPrefix===c&&I.revision===H)return I;const R={t:s.getFixedT(M,o.nsMode==="fallback"?m:m[0],c),ready:_,lng:M,keyPrefix:c,revision:H};return g.current=R,R},[s,m,c,o,e.lng]),[b,x]=y.useState(0),{t:S,ready:N}=eO.useSyncExternalStore(f,w,w);y.useEffect(()=>{if(s&&!N&&!l){const _=()=>x(M=>M+1);e.lng?OH(s,e.lng,m,_):TF(s,m,_)}},[s,e.lng,m,N,l,b]);const C=s||{},P=y.useRef(null),T=y.useRef(),A=_=>{const M=Object.getOwnPropertyDescriptors(_);M.__original&&delete M.__original;const H=Object.create(Object.getPrototypeOf(_),M);if(!Object.prototype.hasOwnProperty.call(H,"__original"))try{Object.defineProperty(H,"__original",{value:_,writable:!1,enumerable:!1,configurable:!1})}catch{}return H},F=y.useMemo(()=>{const _=C,M=_?.language;let H=_;_&&(P.current&&P.current.__original===_?T.current!==M?(H=A(_),P.current=H,T.current=M):H=P.current:(H=A(_),P.current=H,T.current=M));const I=[S,H,N];return I.t=S,I.i18n=H,I.ready=N,I},[S,C,N,C.resolvedLanguage,C.language,C.languages]);if(s&&l&&!N)throw new Promise(_=>{const M=()=>_();e.lng?OH(s,e.lng,m,M):TF(s,m,M)});return F},{slice:Pme,forEach:Tme}=[];function Ame(t){return Tme.call(Pme.call(arguments,1),e=>{if(e)for(const n in e)t[n]===void 0&&(t[n]=e[n])}),t}function jme(t){return typeof t!="string"?!1:[/<\s*script.*?>/i,/<\s*\/\s*script\s*>/i,/<\s*img.*?on\w+\s*=/i,/<\s*\w+\s*on\w+\s*=.*?>/i,/javascript\s*:/i,/vbscript\s*:/i,/expression\s*\(/i,/eval\s*\(/i,/alert\s*\(/i,/document\.cookie/i,/document\.write\s*\(/i,/window\.location/i,/innerHTML/i].some(n=>n.test(t))}const BH=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/,Mme=function(t,e){const a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{path:"/"},i=encodeURIComponent(e);let s=`${t}=${i}`;if(a.maxAge>0){const o=a.maxAge-0;if(Number.isNaN(o))throw new Error("maxAge should be a Number");s+=`; Max-Age=${Math.floor(o)}`}if(a.domain){if(!BH.test(a.domain))throw new TypeError("option domain is invalid");s+=`; Domain=${a.domain}`}if(a.path){if(!BH.test(a.path))throw new TypeError("option path is invalid");s+=`; Path=${a.path}`}if(a.expires){if(typeof a.expires.toUTCString!="function")throw new TypeError("option expires is invalid");s+=`; Expires=${a.expires.toUTCString()}`}if(a.httpOnly&&(s+="; HttpOnly"),a.secure&&(s+="; Secure"),a.sameSite)switch(typeof a.sameSite=="string"?a.sameSite.toLowerCase():a.sameSite){case!0:s+="; SameSite=Strict";break;case"lax":s+="; SameSite=Lax";break;case"strict":s+="; SameSite=Strict";break;case"none":s+="; SameSite=None";break;default:throw new TypeError("option sameSite is invalid")}return a.partitioned&&(s+="; Partitioned"),s},HH={create(t,e,n,a){let i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:{path:"/",sameSite:"strict"};n&&(i.expires=new Date,i.expires.setTime(i.expires.getTime()+n*60*1e3)),a&&(i.domain=a),document.cookie=Mme(t,e,i)},read(t){const e=`${t}=`,n=document.cookie.split(";");for(let a=0;a-1&&(a=window.location.hash.substring(window.location.hash.indexOf("?")));const s=a.substring(1).split("&");for(let o=0;o0&&s[o].substring(0,l)===e&&(n=s[o].substring(l+1))}}return n}},Fme={name:"hash",lookup(t){let{lookupHash:e,lookupFromHashIndex:n}=t,a;if(typeof window<"u"){const{hash:i}=window.location;if(i&&i.length>2){const s=i.substring(1);if(e){const o=s.split("&");for(let l=0;l0&&o[l].substring(0,c)===e&&(a=o[l].substring(c+1))}}if(a)return a;if(!a&&n>-1){const o=i.match(/\/([a-zA-Z-]*)/g);return Array.isArray(o)?o[typeof n=="number"?n:0]?.replace("/",""):void 0}}}return a}};let Kb=null;const qH=()=>{if(Kb!==null)return Kb;try{if(Kb=typeof window<"u"&&window.localStorage!==null,!Kb)return!1;const t="i18next.translate.boo";window.localStorage.setItem(t,"foo"),window.localStorage.removeItem(t)}catch{Kb=!1}return Kb};var Lme={name:"localStorage",lookup(t){let{lookupLocalStorage:e}=t;if(e&&qH())return window.localStorage.getItem(e)||void 0},cacheUserLanguage(t,e){let{lookupLocalStorage:n}=e;n&&qH()&&window.localStorage.setItem(n,t)}};let Qb=null;const $H=()=>{if(Qb!==null)return Qb;try{if(Qb=typeof window<"u"&&window.sessionStorage!==null,!Qb)return!1;const t="i18next.translate.boo";window.sessionStorage.setItem(t,"foo"),window.sessionStorage.removeItem(t)}catch{Qb=!1}return Qb};var Rme={name:"sessionStorage",lookup(t){let{lookupSessionStorage:e}=t;if(e&&$H())return window.sessionStorage.getItem(e)||void 0},cacheUserLanguage(t,e){let{lookupSessionStorage:n}=e;n&&$H()&&window.sessionStorage.setItem(n,t)}},Ime={name:"navigator",lookup(t){const e=[];if(typeof navigator<"u"){const{languages:n,userLanguage:a,language:i}=navigator;if(n)for(let s=0;s0?e:void 0}},Ome={name:"htmlTag",lookup(t){let{htmlTag:e}=t,n;const a=e||(typeof document<"u"?document.documentElement:null);return a&&typeof a.getAttribute=="function"&&(n=a.getAttribute("lang")),n}},zme={name:"path",lookup(t){let{lookupFromPathIndex:e}=t;if(typeof window>"u")return;const n=window.location.pathname.match(/\/([a-zA-Z-]*)/g);return Array.isArray(n)?n[typeof e=="number"?e:0]?.replace("/",""):void 0}},Ume={name:"subdomain",lookup(t){let{lookupFromSubdomainIndex:e}=t;const n=typeof e=="number"?e+1:1,a=typeof window<"u"&&window.location?.hostname?.match(/^(\w{2,5})\.(([a-z0-9-]{1,63}\.[a-z]{2,6})|localhost)/i);if(a)return a[n]}};let BY=!1;try{document.cookie,BY=!0}catch{}const HY=["querystring","cookie","localStorage","sessionStorage","navigator","htmlTag"];BY||HY.splice(1,1);const Bme=()=>({order:HY,lookupQuerystring:"lng",lookupCookie:"i18next",lookupLocalStorage:"i18nextLng",lookupSessionStorage:"i18nextLng",caches:["localStorage"],excludeCacheFor:["cimode"],convertDetectedLanguage:t=>t});class qY{constructor(e){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};this.type="languageDetector",this.detectors={},this.init(e,n)}init(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{languageUtils:{}},n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};this.services=e,this.options=Ame(n,this.options||{},Bme()),typeof this.options.convertDetectedLanguage=="string"&&this.options.convertDetectedLanguage.indexOf("15897")>-1&&(this.options.convertDetectedLanguage=i=>i.replace("-","_")),this.options.lookupFromUrlIndex&&(this.options.lookupFromPathIndex=this.options.lookupFromUrlIndex),this.i18nOptions=a,this.addDetector(Eme),this.addDetector(Dme),this.addDetector(Lme),this.addDetector(Rme),this.addDetector(Ime),this.addDetector(Ome),this.addDetector(zme),this.addDetector(Ume),this.addDetector(Fme)}addDetector(e){return this.detectors[e.name]=e,this}detect(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:this.options.order,n=[];return e.forEach(a=>{if(this.detectors[a]){let i=this.detectors[a].lookup(this.options);i&&typeof i=="string"&&(i=[i]),i&&(n=n.concat(i))}}),n=n.filter(a=>a!=null&&!jme(a)).map(a=>this.options.convertDetectedLanguage(a)),this.services&&this.services.languageUtils&&this.services.languageUtils.getBestMatchFromCodes?n:n.length>0?n[0]:null}cacheUserLanguage(e){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.options.caches;n&&(this.options.excludeCacheFor&&this.options.excludeCacheFor.indexOf(e)>-1||n.forEach(a=>{this.detectors[a]&&this.detectors[a].cacheUserLanguage(e,this.options)}))}}qY.type="languageDetector";const Hme={nav:{printers:"Printers",archives:"Archives",queue:"Print Queue",stats:"Statistics",profiles:"Profiles",maintenance:"Maintenance",projects:"Projects",inventory:"Filament",files:"File Manager",makerworld:"MakerWorld",notifications:"Notifications",settings:"Settings",system:"System",collapseSidebar:"Collapse sidebar",expandSidebar:"Expand sidebar",update:"Update",updateAvailable:"Update available: v{{version}}",updateAvailableBanner:"Version {{version}} is available!",viewUpdate:"View update",viewOnGithub:"View on GitHub",keyboardShortcuts:"Keyboard shortcuts (?)",switchToLight:"Switch to light mode",switchToDark:"Switch to dark mode",smartSwitches:"Smart Switches",logout:"Logout"},common:{save:"Save",saving:"Saving...",cancel:"Cancel",delete:"Delete",edit:"Edit",add:"Add",close:"Close",confirm:"Confirm",loading:"Loading...",error:"Error",errorLoading:"Error loading data",retry:"Retry",success:"Success",warning:"Warning",enabled:"Enabled",disabled:"Disabled",yes:"Yes",no:"No",on:"On",off:"Off",all:"All",none:"None",search:"Search",filter:"Filter",sort:"Sort",refresh:"Refresh",download:"Download",upload:"Upload",uploading:"Uploading...",uploadFailed:"Upload failed",actions:"Actions",status:"Status",name:"Name",description:"Description",date:"Date",time:"Time",hours:"hours",minutes:"minutes",seconds:"seconds",days:"days",enable:"Enable",disable:"Disable",permissions:"Permissions",noPrinters:"No printers configured",noData:"No data available",linkNotFound:"Link not found",required:"Required",optional:"Optional",dismiss:"Dismiss",apply:"Apply",reset:"Reset",export:"Export",import:"Import",clear:"Clear",selectAll:"Select All",deselectAll:"Deselect All",noChange:"— No change —",unchanged:"Unchanged",unassigned:"Unassigned",unknown:"Unknown",unknownError:"Unknown error",today:"Today",tomorrow:"Tomorrow",asap:"ASAP",overdue:"Overdue",now:"Now",collapse:"Collapse",expand:"Expand",viewArchive:"View archive",viewInFileManager:"View in File Manager",addedBy:"Added by {{username}}",prints:"prints",more:"+{{count}} more",ascending:"Ascending",descending:"Descending",back:"Back",copy:"Copy",copied:"Copied!",printer:"Printer",remove:"Remove",type:"Type",print:"Print",rename:"Rename",move:"Move",create:"Create",duplicate:"Duplicate",left:"Left",right:"Right"},printers:{title:"Printers",addPrinter:"Add Printer",editPrinter:"Edit Printer",deletePrinter:"Delete Printer",printerName:"Printer Name",serialNumber:"Serial Number",ipAddress:"IP Address / Hostname",accessCode:"Access Code",model:"Model",nozzleCount:"Nozzle Count",autoArchive:"Auto Archive",status:{available:"Available",idle:"Idle",printing:"Printing",paused:"Paused",offline:"Offline",problem:"Problem",error:"Error",finished:"Finished",unknown:"Unknown"},temperatures:{nozzle:"Nozzle",bed:"Bed",chamber:"Chamber"},progress:"{{percent}}% complete",timeRemaining:"{{time}} remaining",deleteConfirm:'Are you sure you want to delete "{{name}}"?',maintenanceOk:"Maintenance OK",maintenanceWarning:"{{count}} warning",maintenanceWarning_plural:"{{count}} warnings",maintenanceDue:"{{count}} due",maintenanceDue_plural:"{{count}} due",sort:{name:"Name",status:"Status",model:"Model",location:"Location",ascending:"Sort ascending",descending:"Sort descending"},cardSize:{small:"Small cards",medium:"Medium cards",large:"Large cards",extraLarge:"Extra large cards"},hideOffline:"Hide offline",nextAvailable:"Next available",powerOn:"Power On",offlinePrintersWithPlugs:"Offline printers with smart plugs",noPrintersConfigured:"No printers configured yet",search:"Search printers...",noSearchResults:"No printers match your search or filters",filter:{allStatuses:"All statuses",allLocations:"All locations"},toolbar:{filters:"Filters",view:"View",actions:"Actions"},readyToPrint:"Ready to print",external:"External",extL:"Ext-L",extR:"Ext-R",deleteArchives:"Delete print archives",noLabel:"No label",printPreview:"Print preview",width:"Width",height:"Height",noObjectsFound:"No objects found",objectsLoadedOnPrintStart:"Objects are loaded when a print starts",willBeSkipped:"Will be skipped",name:"Name",serialCannotBeChanged:"Serial number cannot be changed",locationHelp:"Used to group printers and filter queue jobs",wifiSignal:{veryWeak:"Very weak",weak:"Weak",fair:"Fair",good:"Good",excellent:"Excellent"},maintenanceUpToDate:"All maintenance up to date - Click to view",chamberLightOn:"Turn on chamber light",chamberLightOff:"Turn off chamber light",files:"Files",browseFiles:"Browse printer files",autoOffAfterPrint:"Auto power-off after print",autoOffExecuted:"Auto-off was executed - turn printer on to reset",hmsErrors:"HMS Errors",viewHmsErrors:"View {{count}} HMS error(s)",resume:"Resume",pause:"Pause",stop:"Stop",camera:"Camera",skipObject:"Skip Object",reconnect:"Reconnect",forceRefresh:"Force Refresh",forceRefreshSuccess:"Refresh requested",mqttDebug:"MQTT Debug",printerInformation:"Printer Information",copyToClipboard:"Copy",copied:"Copied!",state:"State",wifiSignalLabel:"WiFi Signal",developerMode:"Developer Mode",enabled:"Enabled",disabled:"Disabled",addedOn:"Added",sdCard:"SD Card",inserted:"Inserted",notInserted:"Not inserted",totalPrintHours:"Print Hours",activeNozzle:"Active: {{nozzle}} nozzle",nozzleRack:"Nozzle Rack",nozzleDocked:"Docked",nozzleMounted:"Mounted",nozzleActive:"Active",nozzleIdle:"Idle",nozzleDiameter:"Diameter",nozzleType:"Type",nozzleStatus:"Status",nozzleFilament:"Filament",nozzleWear:"Wear",nozzleMaxTemp:"Max Temp",nozzleSerial:"Serial",nozzleHardenedSteel:"Hardened Steel",nozzleStainlessSteel:"Stainless Steel",nozzleTungstenCarbide:"Tungsten Carbide",nozzleFlow:"Flow",nozzleHighFlow:"High Flow",nozzleStandardFlow:"Standard",firmwareUpdate:"Firmware Update",firmwareInstructions:"On the printer's touchscreen, go to",firmwareNav:"Navigate to",settings:"Settings",firmware:"Firmware",discoverPrinters:"Discover Printers",searching:"Searching...",manualEntry:"Manual Entry",addFromCloud:"Add from Cloud",toast:{printerDeleted:"Printer deleted",missingSpoolAssignment:"Print started on {{printer}}. Missing spool assignment for: {{slots}}",printerAdded:"Printer added",printerUpdated:"Printer updated",failedToDelete:"Failed to delete printer",failedToAdd:"Failed to add printer",failedToUpdate:"Failed to update printer",commandSent:"Command sent",failedToSendCommand:"Failed to send command",turnedOn:"{{name}} turned on",failedToPowerOn:"Failed to power on {{name}}",scriptTriggered:"Script triggered",printStopped:"Print stopped",printPaused:"Print paused",printResumed:"Print resumed",referenceDeleted:"Reference deleted",detectionAreaSaved:"Detection area saved",failedToRunScript:"Failed to run script",failedToStopPrint:"Failed to stop print",failedToPausePrint:"Failed to pause print",failedToResumePrint:"Failed to resume print",failedToControlChamberLight:"Failed to control chamber light",failedToSetSpeed:"Failed to set print speed",failedToUpdateSetting:"Failed to update setting",failedToSkipObjects:"Failed to skip objects",failedToRereadRfid:"Failed to re-read RFID",failedToCheckPlate:"Failed to check plate",failedToUpdateLabel:"Failed to update label",failedToDeleteReference:"Failed to delete reference",failedToSaveDetectionArea:"Failed to save detection area",plateCheckEnabled:"Plate check enabled",plateCheckDisabled:"Plate check disabled",calibrationSaved:"Calibration saved!",calibrationFailed:"Calibration failed",rfidRereadInitiated:"RFID re-read initiated",loadInitiated:"Loading filament…",unloadInitiated:"Unloading filament…",failedToLoad:"Failed to load filament",failedToUnload:"Failed to unload filament"},connection:{connected:"Connected",offline:"Offline"},plateStatus:{markCleared:"Mark plate as cleared",cleared:"Plate Clear",notCleared:"Plate not Clear",inUse:"Plate in Use"},queue:{inQueue:"{{count}} print in queue",inQueue_plural:"{{count}} prints in queue"},controls:"Controls",rfid:{reread:"Re-read RFID"},ams:{load:"Load",unload:"Unload"},bedJog:{title:"Move build plate",bed:"Bed",step:"Step (mm)",up:"Move plate up",down:"Move plate down",disabledWhilePrinting:"Disabled while printing",notHomedTitle:"Printer is not homed",notHomedMessage:"The printer has not been homed since the last print. Run auto-home first for safe positioning (parks the toolhead, then homes X, Y, and Z), or move anyway — soft endstops will be bypassed.",homeZ:"Auto Home",moveAnyway:"Move anyway",homingStarted:"Auto-homing printer…"},permission:{noAdd:"You do not have permission to add printers",noEdit:"You do not have permission to edit printers",noDelete:"You do not have permission to delete printers",noControl:"You do not have permission to control printers",noFiles:"You do not have permission to access printer files",noAmsRfid:"You do not have permission to re-read AMS RFID",noSmartPlugControl:"You do not have permission to control smart plugs",noCamera:"You do not have permission to view cameras"},modal:{addTitle:"Add Printer",editTitle:"Edit Printer",myPrinter:"My Printer",selectModel:"Select model...",locationGroup:"Location / Group (optional)",locationPlaceholder:"e.g., Workshop, Office, Basement",autoArchiveLabel:"Auto-archive completed prints",fromPrinterSettings:"From printer settings",modelOptional:"Model (optional)",saveChanges:"Save Changes"},skipObjects:{tooltip:"Skip objects",onlyWhilePrinting:"Skip objects (only while printing)",requiresMultiple:"Skip objects (requires 2+ objects)",title:"Skip Objects",matchIdsInfo:"Match IDs with your printer display",printerShowsIds:"The printer screen shows object IDs on the build plate",skipSelected:"Skip Selected",skipping:"Skipping...",noObjectsSelected:"No objects selected",selectObjectsToSkip:"Select objects you want to skip from the current print",skipped:"skipped",objectsSkipped:"Objects skipped",activeCount:"{{count}} active",waitForLayer:"Wait for layer 2+ to skip objects (currently layer {{layer}})",skip:"Skip",confirmTitle:"Skip Object?",confirmMessage:'Are you sure you want to skip "{{name}}"? This cannot be undone.'},confirm:{deleteTitle:"Delete Printer",deleteMessage:'Are you sure you want to delete "{{name}}"? This will remove all connection settings.',deleteArchivesNote:"All print history for this printer will be permanently deleted.",keepArchivesNote:"Print history will be kept but no longer associated with this printer.",stopTitle:"Stop Print",stopMessage:'Are you sure you want to stop the current print on "{{name}}"? This will cancel the print job.',stopButton:"Stop Print",pauseTitle:"Pause Print",pauseMessage:'Are you sure you want to pause the current print on "{{name}}"?',pauseButton:"Pause Print",resumeTitle:"Resume Print",resumeMessage:'Are you sure you want to resume the print on "{{name}}"?',resumeButton:"Resume Print",powerOnTitle:"Power On Printer",powerOnMessage:'Are you sure you want to turn ON the power for "{{name}}"?',powerOnButton:"Power On",powerOffTitle:"Power Off Printer",powerOffMessage:'Are you sure you want to turn OFF the power for "{{name}}"?',powerOffWarning:'WARNING: "{{name}}" is currently printing! Are you sure you want to turn OFF the power? This will interrupt the print and may damage the printer.',powerOffButton:"Power Off",haToggleTitle:'Toggle "{{name}}"',haToggleMessage:"Toggle the Home Assistant entity {{entity}}? This may turn power off if it is currently on.",haToggleWarning:'WARNING: "{{name}}" is currently printing! Toggling {{entity}} may cut power and interrupt the print. Continue?',haToggleButton:"Toggle"},bulk:{select:"Select",selectAll:"Select All",selectByLocation:"Select by Location",selected:"{{count}} selected",actions:{stop:"Stop",pause:"Pause",resume:"Resume",clearPlate:"Clear Bed",clearHMS:"Clear Notifications"},confirm:{stopTitle:"Stop {{count}} Prints",stopMessage:"This will cancel active prints on {{count}} printer(s). This action cannot be undone.",stopButton:"Stop All",pauseTitle:"Pause {{count}} Prints",pauseMessage:"This will pause active prints on {{count}} printer(s).",pauseButton:"Pause All",clearPlateTitle:"Clear {{count}} Print Beds",clearPlateMessage:"This will clear the print bed on {{count}} printer(s) and may trigger queued jobs.",clearPlateButton:"Clear All"},success:"{{action}} completed on {{count}} printer(s)",partial:"{{succeeded}} succeeded, {{failed}} failed",noneApplicable:"No selected printers are in the right state for this action",selectByState:"Select by State"},discovery:{title:"Discover Printers",searching:"Searching...",scanning:"Scanning...",scanProgress:"Scanning... {{scanned}}/{{total}}",foundPrinters:"Found {{count}} printer(s)",noPrintersFound:"No printers found",noPrintersFoundSubnet:"No printers found in the specified subnet.",noPrintersFoundNetwork:"No printers found on the network.",allConfigured:"All discovered printers are already configured.",alreadyAdded:"Already added",select:"Select",manualEntry:"Manual Entry",addFromCloud:"Add from Cloud",subnetToScan:"Subnet to scan",dockerNote:"Docker detected. Enter your printer's subnet in CIDR notation. Requires network_mode: host in docker-compose.yml.",scanSubnet:"Scan Subnet for Printers",discoverNetwork:"Discover Printers on Network",scanningSubnet:"Scanning subnet for Bambu printers...",scanningNetwork:"Scanning network...",serialRequired:"Serial required",unknown:"Unknown",failedToStart:"Failed to start discovery"},drying:{start:"Start Drying",stop:"Stop Drying",temperature:"Temperature",duration:"Duration",hours:"hours",timeRemaining:"{{time}} left",active:"Drying",notSupported:"Drying not supported",powerRequired:"Connect AMS power adapter to enable drying",startingDrying:"Starting drying...",stoppingDrying:"Stopping drying...",rotateTray:"Rotate spool during drying"},filaments:"Filaments",openCameraOverlay:"Open camera overlay",openCameraWindow:"Open camera in new window",firmwareUpdateAvailable:"Firmware update available: {{current}} → {{latest}}",firmwareUpToDate:"Firmware {{version}} — Up to date",firmwareUpdateButton:"Update",plateDetection:{noPermission:"You do not have permission to update printers",enabledClick:"Plate check enabled - Click to disable",disabledClick:"Plate check disabled - Click to enable",manageCalibration:"Manage plate detection calibration",calibrationRequired:"Calibration Required",calibrationInstructions:"Please ensure the build plate is completely empty, then click Calibrate.",calibrationDescription:"Calibration captures a reference image of the empty plate. Future checks will compare against this reference to detect objects.",calibrationTip:"Tip: You can store up to 5 calibrations for different plates. The system automatically uses the best match when checking.",plateEmpty:"Plate appears empty",objectsDetected:"Objects detected on plate",confidence:"Confidence",difference:"Difference",analysisPreview:"Analysis preview:",analysisLegend:"Green box = detection area, Red overlay = differences from calibration",savedReferences:"Saved References ({{count}}/{{max}})",deleteReference:"Delete reference",labelPlaceholder:"Label...",clickToEdit:"{{label}} - Click to edit",clickToAddLabel:"Click to add label"},speed:{title:"Print Speed",silent:"Silent (50%)",standard:"Standard (100%)",sport:"Sport (124%)",ludicrous:"Ludicrous (166%)"},airduct:{title:"Airduct Mode",cooling:"Cooling",heating:"Heating"},noSdCard:"No SD",door:{open:"Open",closed:"Closed"},fans:{partCooling:"Part Cooling Fan",auxiliary:"Auxiliary Fan",chamber:"Chamber Fan"},clickToViewHmsErrors:"Click to view HMS errors",estimatedCompletion:"Estimated completion time",plateNumber:"Plate {{number}}",slotOptions:"Slot options",amsPopup:{friendlyName:"AMS Name",friendlyNamePlaceholder:"e.g. AMS Friendly Name",serialNumber:"Serial Number",firmwareVersion:"Firmware",save:"Save",clear:"Clear",noEditPermission:"You do not have permission to rename AMS units"},firmwareModal:{title:"Firmware Update",titleUpToDate:"Firmware Info",currentVersion:"Current:",latestVersion:"Latest:",releaseNotes:"Release Notes",checkingPrereqs:"Checking prerequisites...",sdCardReady:"SD card ready. Click below to upload firmware.",uploadedSuccess:"Firmware uploaded to SD card!",applyInstructions:"To apply the update on your printer:",step1:"On the printer's touchscreen, go to Settings",step2:"Navigate to Firmware",step3:"Select Update from SD card",step4:"The update will take 10-20 minutes",done:"Done",starting:"Starting...",uploadFirmware:"Upload Firmware",uploadFailed:"Failed to start upload: {{error}}",uploadedToast:"Firmware uploaded! Trigger update from printer screen.",availableVersions:"Available versions",usable:"Usable",unavailable:"Unavailable",installed:"Installed",newerBadge:"newer",olderBadge:"older",currentBadge:"current"},accessCodePlaceholder:"Leave empty to keep current",roi:{title:"Detection Area (ROI)",xStart:"X Start",yStart:"Y Start",width:"Width",height:"Height",instruction:"Adjust the detection area to focus on the build plate. The green box in the preview shows the current area."},developerModeWarning:"Developer LAN mode is not enabled on: {{names}}. Some features may not work.",howToEnable:"How to enable",incompatibleFile:"This file was sliced for {{slicedFor}}, but this printer is a {{printerModel}}",dropNotPrintable:"Only .gcode and .gcode.3mf files can be printed",dropToPrint:"Drop to print",cannotPrint:"Printer busy"},archives:{title:"Print Archives",searchPlaceholder:"Search archives...",filterByPrinter:"Filter by printer",filterByStatus:"Filter by status",sortBy:"Sort by",sortNewest:"Newest first",sortOldest:"Oldest first",sortName:"Name",sortDuration:"Duration",sortLargest:"Largest first",sortSmallest:"Smallest first",sortSize:"Size",noArchives:"No archives found",noArchivesSearch:"No archives match your search",originalPrintNotVisible:"Original print not visible - try clearing filters",noArchivesYet:"No archives yet",prints:"prints",pagination:{showing:"Showing",to:"to",of:"of",show:"Show",page:"Page",all:"All"},loadingArchives:"Loading archives...",releaseToUpload:"Release to upload",showAll:"Show all",showFavoritesOnly:"Show favorites only",gridView:"Grid view",listView:"List view",calendarView:"Calendar view",logView:"Print Log",manageTags:"Manage Tags",showFailedPrints:"Show failed prints",hideFailedPrints:"Hide failed prints",hideDuplicates:"Hide Duplicates",viewOriginalPrint:"Click to view original print (#{{id}})",printTime:"Print Time",filamentUsed:"Filament Used",cost:"Cost",reprint:"Reprint",preview:"Preview",deleteArchive:"Delete Archive",deleteConfirm:"Are you sure you want to delete this archive?",favorite:"Favorite",unfavorite:"Remove from favorites",viewDetails:"View Details",status:{completed:"Completed",failed:"Failed",stopped:"Stopped"},toast:{source3mfAttached:"Source 3MF attached: {{filename}}",failedUploadSource3mf:"Failed to upload source 3MF",source3mfRemoved:"Source 3MF removed",failedRemoveSource3mf:"Failed to remove source 3MF",f3dAttached:"F3D attached: {{filename}}",failedUploadF3d:"Failed to upload F3D",f3dRemoved:"F3D removed",failedRemoveF3d:"Failed to remove F3D",timelapseAttached:"Timelapse attached: {{filename}}",timelapseAlreadyAttached:"Timelapse already attached",noMatchingTimelapse:"No matching timelapse found",failedScanTimelapse:"Failed to scan for timelapse",failedAttachTimelapse:"Failed to attach timelapse",timelapseRemoved:"Timelapse removed",failedRemoveTimelapse:"Failed to remove timelapse",timelapseUploaded:"Timelapse uploaded: {{filename}}",failedUploadTimelapse:"Failed to upload timelapse",archiveDeleted:"Archive deleted",failedDeleteArchive:"Failed to delete archive",addedToFavorites:"Added to favorites",removedFromFavorites:"Removed from favorites",projectUpdated:"Project updated",failedUpdateProject:"Failed to update project",linkCopied:"Link copied to clipboard",failedCopyLink:"Failed to copy link",photoDeleted:"Photo deleted",failedDeletePhoto:"Failed to delete photo",failedDeleteArchives:"Failed to delete archives",failedUpdateFavorites:"Failed to update favorites",exportDownloaded:"Export downloaded",exportFailed:"Export failed"},menu:{print:"Print",schedule:"Schedule",openInBambuStudio:"Open in Slicer",slice:"Slice",externalLink:"External Link",viewOnMakerWorld:"View on MakerWorld",preview3d:"3D Preview",viewTimelapse:"View Timelapse",scanForTimelapse:"Scan for Timelapse",uploadTimelapse:"Upload Timelapse",removeTimelapse:"Remove Timelapse",downloadSource3mf:"Download Source 3MF",uploadSource3mf:"Upload Source 3MF",replaceSource3mf:"Replace Source 3MF",removeSource3mf:"Remove Source 3MF",uploadF3d:"Upload F3D",replaceF3d:"Replace F3D",downloadF3d:"Download F3D",removeF3d:"Remove F3D",download:"Download",copyDownloadLink:"Copy Download Link",qrCode:"QR Code",viewPhotos:"View Photos",viewPhotosCount:"View Photos ({{count}})",projectPage:"Project Page",addToFavorites:"Add to Favorites",removeFromFavorites:"Remove from Favorites",edit:"Edit",printLog:"Print Log",goToProject:"Go to Project: {{name}}",addToProject:"Add to Project",removeFromProject:"Remove from Project",loading:"Loading...",noProjectsAvailable:"No projects available",searchProjects:"Search projects…",select:"Select",deselect:"Deselect",delete:"Delete"},permission:{noReprint:"You do not have permission to reprint this archive",noAddToQueue:"You do not have permission to add to queue",noUpdateArchives:"You do not have permission to update archives",noUploadFiles:"You do not have permission to upload files",noDownload:"You do not have permission to download archives",noCopyLink:"You do not have permission to copy download links",noDelete:"You do not have permission to delete this archive",noCreate:"You do not have permission to create archives"},platePicker:{title:"Select plate to preview",hint:"This archive has multiple plates. Pick one to open in the GCode viewer.",plateLabel:"Plate {{index}}",objectCount:"{{count}} object",objectCount_plural:"{{count}} objects",noGcode:"This archive has no sliced G-code to preview. Open it in Bambu Studio to slice first."},card:{previousPlate:"Previous plate",nextPlate:"Next plate",plateNumber:"Plate {{index}}",moreOptions:"Right-click for more options",addToFavorites:"Add to favorites",removeFromFavorites:"Remove from favorites",cancelled:"cancelled",failed:"failed",duplicate:"duplicate",duplicateTitle:"This model has been printed before",openSource3mf:"Open source 3MF in Bambu Studio (right-click for more options)",downloadF3d:"Download Fusion 360 design file",viewTimelapse:"View timelapse",viewPhoto:"View 1 photo",viewPhotos:"View {{count}} photos",openFolder:"Open folder: {{name}}",slicedFile:"Sliced file - ready to print",sourceFile:"Source file only - no AMS mapping available",gcode:"GCODE",source:"SOURCE",project:"Project: {{name}}",runsBadge:"{{count}} prints",runsBadgeTitle:"{{count}} prints total — {{successful}} successful, {{failed}} failed. Click to see the full print log.",estimated:"Estimated: {{time}}",actual:"Actual: {{time}}",accuracy:"Accuracy: {{percent}}%",filament:"{{weight}}g",layer:"{{count}} layer",layers:"{{count}} layers",object:"{{count}} object",objects:"{{count}} objects",slicedFor:"Sliced for {{model}}",uploadedBy:"Uploaded By",noPermissionReprint:"You do not have permission to reprint",noFileForReprint:"No 3MF file available — the file could not be downloaded from the printer when the print was recorded",noPermissionEdit:"You do not have permission to edit archives",noPermissionDelete:"You do not have permission to delete archives",reprint:"Reprint",schedulePrint:"Schedule Print",schedule:"Schedule",openInBambuStudio:"Open in Slicer",openInBambuStudioToSlice:"Open in Slicer to slice",slice:"Slice",externalLink:"External Link",makerWorld:"MakerWorld: {{designer}}",viewProject:"View project",noExternalLink:"No external link",preview3d:"3D Preview",download:"Download",edit:"Edit",delete:"Delete"},runLog:{title:"Print Log",modalTitle:"Print Log — {{name}}",modalTitleFallback:"this archive",empty:"No print events recorded for this archive yet.",col:{date:"Date",status:"Status",duration:"Duration",filament:"Filament",cost:"Cost"},status:{completed:"Completed",failed:"Failed",cancelled:"Cancelled",stopped:"Stopped",skipped:"Skipped",printing:"Printing"}},modal:{deleteArchive:"Delete Archive",deleteConfirm:'Are you sure you want to delete "{{name}}"? This action cannot be undone.',deleteButton:"Delete",deletePurgeStats:"Also remove this print from Quick Stats (filament, time, cost, energy)",removeSource3mf:"Remove Source 3MF",removeSource3mfConfirm:'Are you sure you want to remove the source 3MF file from "{{name}}"? This will delete the original slicer project file.',removeButton:"Remove",removeF3d:"Remove F3D",removeF3dConfirm:'Are you sure you want to remove the Fusion 360 design file from "{{name}}"?',removeTimelapse:"Remove Timelapse",removeTimelapseConfirm:'Are you sure you want to remove the timelapse video from "{{name}}"?',timelapse:"{{name}} - Timelapse",selectTimelapse:"Select Timelapse",selectTimelapseDesc:"No auto-match found. Select the timelapse for this print:",deleteArchives:"Delete Archives",deleteArchivesConfirm:"Are you sure you want to delete {{count}} archive(s)? This action cannot be undone.",deleteCount:"Delete {{count}}"},page:{title:"Archives",printsCount:"{{filtered}} of {{total}} prints",dropFilesHere:"Drop .3mf files here",releaseToUpload:"Release to upload",only3mfSupported:"Only .3mf files are supported",close:"Close",selected:"{{count}} selected",selectAll:"Select All",tags:"Tags",project:"Project",favorite:"Favorite",delete:"Delete",toggledFavorites:"Toggled favorites for {{count}} archive(s)",failedUpdateFavorites:"Failed to update favorites",archivesDeleted:"{{count}} archive(s) deleted",failedDeleteArchives:"Failed to delete archives",photoDeleted:"Photo deleted",failedDeletePhoto:"Failed to delete photo"},list:{name:"Name",printer:"Printer",date:"Date",size:"Size",actions:"Actions",hasTimelapse:"Has timelapse"},log:{date:"Date",printName:"Print Name",printer:"Printer",user:"User",status:"Status",duration:"Duration",filament:"Filament",allPrinters:"All Printers",allUsers:"All Users",allStatuses:"All Statuses",cancelled:"Cancelled",skipped:"Skipped",dateFrom:"From",dateTo:"To",noEntries:"No print log entries found",showing:"Showing {{count}} of {{total}} entries",rowsPerPage:"Rows",page:"Page",prev:"Prev",next:"Next",clearLog:"Clear Log",clearLogTitle:"Clear Print Log",clearLogConfirm:"All print log entries will be permanently deleted. Archives and queue items are not affected. This action cannot be undone. Are you sure?",clearLogButton:"Clear All",cleared:"{{count}} log entries cleared",clearFailed:"Failed to clear print log"}},queue:{title:"Print Queue",subtitle:"Schedule and manage your print jobs",addToQueue:"Add to Queue",print:"Print",reprint:"Re-print",schedulePrint:"Schedule Print",editQueueItem:"Edit Queue Item",printToPrinters:"Print to {{count}} Printers",queueToPrinters:"Queue to {{count}} Printers",queueSelectedPlates:"Queue {{count}} Plates",selectAllPlates:"Select All {{count}} Plates",deselectAll:"Deselect All",printQueued:"Print queued",itemsQueued:"{{count}} items queued",sending:"Sending...",sendingProgress:"Sending {{current}}/{{total}}...",adding:"Adding...",addingProgress:"Adding {{current}}/{{total}}...",savingProgress:"Saving {{current}}/{{total}}...",clearQueue:"Clear Queue",clearHistory:"Clear History",emptyQueue:"Queue is empty",position:"Position",scheduledTime:"Scheduled Time",moveUp:"Move Up",moveDown:"Move Down",startNow:"Start Now",printingInProgress:"Printing in progress...",viewArchive:"View archive",viewInFileManager:"View in File Manager",itemCount:"{{count}} item",itemCount_plural:"{{count}} items",dragToReorder:"Drag to reorder (ASAP only)",reorderHint:"Position only affects ASAP items. Scheduled items run at their set time.",sjf:{label:"SJF",tooltip:"Shortest Job First — scheduler prioritizes shorter prints"},addedBy:"Added by {{name}}",nextInQueue:"Next in queue",clearPlateSuccess:"Plate cleared — ready for next print",plateNumber:"Plate {{index}}",quantity:"Quantity",quantityHint:"Creates {{count}} queue items",activeBatches:"Active Batches",batchProgress:"{{completed}} of {{total}} completed",cancelBatch:"Cancel Remaining",batchCancelled:"Remaining batch items cancelled",cancelBatchConfirmTitle:"Cancel Batch",cancelBatchConfirmMessage:"Cancel all remaining pending items in this batch?",batch:"Batch",sections:{currentlyPrinting:"Currently Printing",queued:"Queued",history:"History"},status:{pending:"Pending",waiting:"Waiting",printing:"Printing",paused:"Paused",completed:"Completed",failed:"Failed",skipped:"Skipped",cancelled:"Cancelled"},summary:{printing:"Printing",queued:"Queued",totalTime:"Total Queue Time",totalWeight:"Total Queue Weight",history:"History"},filter:{allPrinters:"All Printers",unassigned:"Unassigned",allStatus:"All Status",allLocations:"All Locations",any:"Any"},sort:{byPosition:"Sort by Position",byName:"Sort by Name",byPrinter:"Sort by Printer",bySchedule:"Sort by Schedule",byDate:"Sort by Date",ascendingOldest:"Ascending (oldest first)",descendingNewest:"Descending (newest first)"},badges:{staged:"Staged",requiresPrevious:"Requires previous success",autoPowerOff:"Auto power off",gcodeInjection:"G-code"},empty:{title:"No prints scheduled",description:'Schedule a print from the Archives page using the "Schedule" option in the context menu, or drag and drop files to get started.'},time:{asap:"ASAP",overdue:"Overdue",now:"Now",lessThanMinute:"In less than a minute",inMinutes:"In {{count}} min",inHours:"In {{count}} hours"},actions:{stopPrint:"Stop Print",startPrint:"Start Print",requeue:"Re-queue"},bulkEdit:{title:"Edit {{count}} Item",title_plural:"Edit {{count}} Items",description:"Only changed settings will be applied to selected items.",printer:"Printer",noChange:"— No change —",queueOptions:"Queue Options",staged:"Staged (manual start)",autoPowerOff:"Auto power off after print",requirePrevious:"Require previous success",printOptions:"Print Options",bedLevelling:"Bed levelling",flowCalibration:"Flow calibration",vibrationCalibration:"Vibration calibration",layerInspection:"First layer inspection",timelapse:"Timelapse",useAms:"Use AMS",applyChanges:"Apply Changes",selectAll:"Select All",deselectAll:"Deselect All",selected:"{{count}} selected",editSelected:"Edit Selected",cancelSelected:"Cancel Selected"},confirm:{cancelTitle:"Cancel Scheduled Print",cancelMessage:'Are you sure you want to cancel "{{name}}"?',stopTitle:"Stop Print",stopMessage:'Are you sure you want to stop the current print "{{name}}"? This will cancel the print job on the printer.',removeTitle:"Remove from History",removeMessage:'Are you sure you want to remove "{{name}}" from the queue history?',clearHistoryTitle:"Clear History",clearHistoryMessage:"Are you sure you want to remove all {{count}} item(s) from the history?",cancelButton:"Cancel Print",stopButton:"Stop Print",thisPrint:"this print",thisItem:"this item"},toast:{cancelled:"Queue item cancelled",cancelFailed:"Failed to cancel item",removed:"Queue item removed",removeFailed:"Failed to remove item",stopped:"Print stopped",stopFailed:"Failed to stop print",released:"Print released to queue",startFailed:"Failed to start print",reorderFailed:"Failed to reorder queue",historyCleared:"Cleared {{count}} history item(s)",clearHistoryFailed:"Failed to clear history",updateFailed:"Failed to update items",bulkCancelled:"Cancelled {{count}} item(s)",bulkCancelFailed:"Failed to cancel items"},timeline:{listView:"List",timelineView:"Timeline",unassigned:"Unassigned",noData:"No scheduled prints for this day",allDoneBy:"All prints estimated done by {{time}}",staged:"Staged",filterAll:"Show All",filterPrinting:"Printing",filterQueued:"Queued",time:{anyMoment:"any moment",minutesLeft:"{{minutes}}m left",hoursLeft:"{{hours}}h left",hoursMinutesLeft:"{{hours}}h {{minutes}}m left"},day:{previous:"Previous day",next:"Next day",today:"Today"}},permissions:{noStopPrint:"You do not have permission to stop prints",noStartPrint:"You do not have permission to start prints",noEdit:"You do not have permission to edit this queue item",noCancel:"You do not have permission to cancel this queue item",noRequeue:"You do not have permission to re-queue items",noRemove:"You do not have permission to remove this queue item",noClearHistory:"You do not have permission to clear all history",noEditItems:"You do not have permission to edit queue items",noCancelItems:"You do not have permission to cancel queue items"}},backgroundDispatch:{unknownFile:"Unknown file",unknownPrinter:"Unknown printer",startingPrints:"Starting prints",progressSummary:"{{complete}}/{{total}} complete • Dispatched: {{dispatched}} • Processing: {{processing}}",expandDetails:"Expand dispatch details",collapseDetails:"Collapse dispatch details",dismissToast:"Dismiss dispatch toast",cancelDispatchJob:"Cancel dispatch job",cancel:"Cancel",cancelling:"Cancelling…",awaitingPrinter:"Awaiting printer…",status:{dispatched:"Dispatched",processing:"Processing",completed:"Completed",failed:"Failed",cancelled:"Cancelled"},toast:{cancellingUpload:"Cancelling upload...",cancelled:"Dispatch cancelled",cancelFailed:"Failed to cancel dispatch",completeWithFailures:"Background dispatch complete: {{completed}} succeeded, {{failed}} failed",completeSuccess:"Background dispatch complete: {{completed}} succeeded",printStartedRemaining:"{{completed}} print(s) started, {{remaining}} more sending..."}},stats:{title:"Statistics",subtitle:"Drag widgets to rearrange. Click the eye icon to hide.",overview:"Overview",totalPrints:"Total Prints",successRate:"Success Rate",totalPrintTime:"Total Print Time",printTime:"Print Time",totalFilament:"Total Filament Used",filamentUsed:"Filament Used",filamentCost:"Filament Cost",totalCost:"Total Cost",energyUsed:"Energy Used",energyCost:"Energy Cost",energyWarmingUpTooltip:"Energy tracking is still collecting hourly snapshots. Date-range totals will become accurate once at least one snapshot exists before the selected range. Early values may undercount.",averagePrintTime:"Average Print Time",printsPerDay:"Prints per Day",byPrinter:"By Printer",printsByPrinter:"Prints by Printer",byMaterial:"By Material",byMonth:"By Month",last7Days:"Last 7 Days",last30Days:"Last 30 Days",last90Days:"Last 90 Days",allTime:"All Time",quickStats:"Quick Stats",printActivity:"Print Activity",filamentTypes:"Filament Types",filamentTrends:"Filament Trends",failureAnalysis:"Failure Analysis",timeAccuracy:"Time Accuracy",successful:"Successful:",failed:"Failed:",perfectEstimate:"100% = perfect estimate",noTimeAccuracyData:"No time accuracy data yet",noFilamentData:"No filament data available",noPrinterData:"No printer data available",noPrintData:"No print data available",noPrintDataLast30Days:"No print data in the last 30 days",failureReasons:"Failure Reasons",topFailureReasons:"Top Failure Reasons",failedPrintsCount:"{{failed}} / {{total}} prints failed",lastWeekRate:"Last week: {{rate}}%",resetLayout:"Reset Layout",recalculateCosts:"Recalculate Costs",recalculateCostsHint:"Recalculate all archive costs using current filament prices",exportStats:"Export Stats",exportAsCsv:"Export as CSV",exportAsExcel:"Export as Excel",hiddenCount:"{{count}} Hidden",exportDownloaded:"Export downloaded",exportFailed:"Export failed",layoutReset:"Layout reset",recalculatedCosts:"Recalculated costs for {{count}} archives",recalculateFailed:"Failed to recalculate costs",loadingStats:"Loading statistics...",noPermissionResetLayout:"You do not have permission to reset layout",noPermissionRecalculate:"You do not have permission to recalculate costs",noPrintDataInRange:"No print data in selected range",periodFilament:"Period Filament",periodCost:"Period Cost",avgPerPrint:"Avg per Print",usageOverTime:"Usage Over Time",filamentByWeight:"Weight",printDuration:"Print Duration",printerUtilization:"Printer Utilization",filamentSuccess:"Success by Material",printHabits:"Print Habits",printTimeOfDay:"Print Time of Day",colorDistribution:"Color Distribution",noColorData:"No color data available",records:"Records",longestPrint:"Longest Print",heaviestPrint:"Heaviest Print",mostExpensivePrint:"Most Expensive",busiestDay:"Busiest Day",successStreak:"Success Streak",streakPrint:"consecutive print",streakPrints:"{{count}} consecutive prints",printerStats:"Printer Stats",hours:"hours",avgPrints:"Avg. prints",noArchiveData:"No print data available",filamentByTime:"Time",avgWeight:"Avg. weight",avgTime:"Avg. time",filamentByPrints:"Prints",timeframe:{today:"Today","this-week":"This Week","this-month":"This Month","last-7":"Last 7 Days","last-30":"Last 30 Days","last-90":"Last 90 Days","this-year":"This Year","all-time":"All Time",custom:"Custom Range",from:"From",to:"To"},allUsers:"All Users",noUser:"No User (System)",filterByUser:"Filter by User"},maintenance:{title:"Maintenance",overview:"Overview",allOk:"All maintenance up to date",dueCount:"{{count}} item due",dueCount_plural:"{{count}} items due",warningCount:"{{count}} warning",warningCount_plural:"{{count}} warnings",totalPrintTime:"Total Print Time",nextMaintenance:"Next Maintenance",nothingDue:"Nothing due",tasks:"Tasks",lastPerformed:"Last performed",interval:"Interval",hoursRemaining:"{{hours}}h remaining",hoursOverdue:"{{hours}}h overdue",markDone:"Mark as Done",performMaintenance:"Perform Maintenance",history:"History",noHistory:"No maintenance history",editPrintHours:"Edit Print Hours",currentHours:"Current Hours",statusTab:"Status",settingsTab:"Settings",overdueCount:"{{count}} overdue",dueSoonCount:"{{count}} due soon",dueSoon:"Due soon",allGood:"All good",overdueBy:"Overdue by {{duration}}",dueIn:"Due in {{duration}}",timeLeft:"{{duration}} left",day:"1 day",days:"{{count}} days",week:"1 week",weeks:"{{count}} weeks",month:"1 month",months:"{{count}} months",year:"1 year",maintenanceTypes:"Maintenance Types",maintenanceTypesDescription:"System types and your custom maintenance tasks",addCustomType:"Add Custom Type",restoreDefaults:"Restore Default Tasks",intervalType:"Interval Type",intervalValue:"Interval ({{type}})",icon:"Icon",documentationLink:"Documentation Link (optional)",assignToPrinters:"Assign to Printers",selectAtLeastOnePrinter:"Select at least one printer",addType:"Add Type",custom:"Custom",printHours:"Print Hours",calendarDays:"Calendar Days",exampleName:"e.g., Replace HEPA Filter",viewDocumentation:"View documentation",timeBasedInterval:"Time-based interval",intervalOverrides:"Interval Overrides",intervalOverridesDescription:"Customize intervals for specific printers",assignedToPrinters:"Assigned to printers:",noPrintersAssigned:"No printers assigned",addPrinterShort:"Add:",printersAssignedClick:"{{count}} printer(s) assigned - click to manage",removeFromPrinter:"Remove from this printer",types:{lubricateCarbonRods:"Lubricate Carbon Rods",lubricateRails:"Lubricate Linear Rails",cleanNozzle:"Clean Nozzle/Hotend",checkBelts:"Check Belt Tension",cleanBuildPlate:"Clean Build Plate",checkExtruder:"Check Extruder Gears",checkCooling:"Check Cooling Fans",generalInspection:"General Inspection",cleanCarbonRods:"Clean Carbon Rods",lubricateSteelRods:"Lubricate Steel Rods",cleanSteelRods:"Clean Steel Rods",cleanLinearRails:"Clean Linear Rails",checkPtfeTube:"Check PTFE Tube",replaceHepaFilter:"Replace HEPA Filter",replaceCarbonFilter:"Replace Carbon Filter",lubricateLeftNozzleRail:"Lubricate Left Nozzle Rail"},maintenanceComplete:"Maintenance marked as complete",typeUpdated:"Maintenance type updated",typeDeleted:"Maintenance type deleted",defaultsRestored:"Restored {{count}} default task(s)",printHoursUpdated:"Print hours updated",printerAssigned:"Printer assigned",printerRemoved:"Printer removed",deleteTypeConfirm:'Delete "{{name}}"?',deleteSystemTypeTitle:"Delete default maintenance task?",deleteSystemTypeMessage:'Are you sure you want to delete the default maintenance task "{{name}}"?',noPermissionUpdate:"You do not have permission to update maintenance items",noPermissionPerform:"You do not have permission to perform maintenance",noPermissionEditTypes:"You do not have permission to edit maintenance types",noPermissionDeleteTypes:"You do not have permission to delete maintenance types",noPermissionEditHours:"You do not have permission to edit print hours",noPermissionRemovePrinter:"You do not have permission to remove printer assignments",noPermissionAssignPrinter:"You do not have permission to assign printers",noPermissionEditIntervals:"You do not have permission to edit intervals",configureSettings:"Configure maintenance types and intervals"},settings:{title:"Settings",general:"General",tabs:{general:"General",smartPlugs:"Smart Plugs",notifications:"Notifications",queue:"Workflow",filament:"Filament",network:"Network",apiKeys:"API Keys",virtualPrinter:"Virtual Printer",spoolbuddy:"SpoolBuddy",failureDetection:"Failure Detection",users:"Authentication",backup:"Backup",emailAuth:"Email Authentication",ldap:"LDAP",twoFa:"Two-Factor Auth",oidc:"SSO / OIDC",security:"Security"},spoolbuddy:{infoTitle:"SpoolBuddy devices",infoBody:"SpoolBuddy kiosks register themselves automatically via heartbeat. Unregister a device here if it is no longer in use or if a stale duplicate was left behind by a daemon crash.",duplicatesTitle:"{{count}} devices registered",duplicatesBody:"Only the first registered device is used by the kiosk UI. If one of these is a stale duplicate from a crash, unregister it — an online device will re-register itself on its next heartbeat.",empty:"No SpoolBuddy devices registered yet.",online:"Online",offline:"Offline",unregister:"Unregister",unregisterSuccess:"Device unregistered",unregisterError:"Failed to unregister device",confirmTitle:"Unregister SpoolBuddy device?",confirmBody:'This will remove "{{hostname}}" ({{deviceId}}) from the database. If the device is online, it will re-register itself on its next heartbeat.',ipAddress:"IP address",firmware:"Firmware",lastSeen:"Last seen",daemonUptime:"Daemon uptime",systemUptime:"System uptime",never:"never",nfc:"NFC",scale:"Scale",cpuTemp:"CPU temp",memory:"Memory",disk:"Disk",update:"Update",updateConfirmTitle:"Update Spoolbuddy daemon?",updateConfirmBody:'Trigger a software update on "{{hostname}}"? The daemon will restart once the update is applied.',restartBrowser:"Restart Browser",restartBrowserConfirmTitle:"Restart kiosk browser?",restartBrowserConfirmBody:'Restart the kiosk browser on "{{hostname}}"? The display will blank briefly.',restartDaemon:"Restart Daemon",restartDaemonConfirmTitle:"Restart Spoolbuddy daemon?",restartDaemonConfirmBody:'Restart the Spoolbuddy daemon on "{{hostname}}"? The device will go offline for a few seconds.',reboot:"Reboot",rebootConfirmTitle:"Reboot device?",rebootConfirmBody:'Reboot "{{hostname}}"? The device will be offline for around a minute.',shutdown:"Shutdown",shutdownConfirmTitle:"Shutdown device?",shutdownConfirmBody:'Shutdown "{{hostname}}"? You will need physical access to power it back on.',commandConfirm:"Confirm",commandQueued:"Command queued",commandError:"Failed to send command"},ldap:{title:"LDAP Authentication",enabledDesc:"LDAP authentication is enabled",disabledDesc:"LDAP authentication is disabled",disabledHint:"Configure and save LDAP settings below, then enable.",enabled:"LDAP authentication enabled",disabled:"LDAP authentication disabled",feature1:"Users can login with LDAP credentials",feature2:"Local admin account remains as fallback",feature3:"LDAP groups are mapped to BamBuddy groups on login",serverConfig:"LDAP Server Configuration",serverUrl:"Server URL",serverUrlHint:"Use ldaps:// for SSL or ldap:// with StartTLS",security:"Security",securityHint:"StartTLS upgrades a plain connection to TLS. LDAPS uses TLS from the start.",bindDn:"Bind DN (Service Account)",bindPassword:"Bind Password",searchBase:"Search Base DN",userFilter:"User Search Filter",userFilterHint:"{username} is replaced with the login username. Use (uid={username}) for OpenLDAP.",advanced:"Advanced",autoProvision:"Auto-provision users",autoProvisionHint:"Automatically create a BamBuddy account on first LDAP login",defaultGroup:"Default group",defaultGroupNone:"— None (no fallback) —",defaultGroupHint:"Fallback group assigned when an LDAP user authenticates but is not listed in any mapped LDAP group. Leave empty to leave unmapped users without permissions.",groupMapping:"Group Mapping (JSON)",groupMappingHint:"Map LDAP group DNs to BamBuddy groups. Available groups: ",testConnection:"Test Connection",settingsSaved:"LDAP settings saved",errors:{serverRequired:"LDAP server URL is required",searchBaseRequired:"Search base DN is required",enableAuthFirst:"Enable authentication first",configureLdapFirst:"Save LDAP settings first"}},email:{smtpSettings:"SMTP Configuration",smtpHost:"SMTP Server",smtpPort:"SMTP Port",security:"Security",authentication:"Authentication",username:"Username",password:"Password",fromEmail:"From Email",fromName:"From Name",testConnection:"Test SMTP Connection",testRecipient:"Test Recipient Email",sendTest:"Send Test Email",sending:"Sending...",save:"Save Settings",saving:"Saving...",advancedAuth:"Advanced Authentication",advancedAuthEnabled:"Advanced Authentication is enabled",advancedAuthEnabledDesc:"Email-based user management features are active. New users will receive auto-generated passwords via email, and users can reset their passwords through the forgot password feature.",advancedAuthDisabled:"Advanced Authentication is disabled",advancedAuthDisabledDesc:"Enable advanced authentication to activate email-based features for user management.",enable:"Enable",disable:"Disable",feature1:"Passwords are auto-generated and emailed to new users",feature2:"Users can login with username or email",feature3:"Forgot password feature is available",feature4:"Admins can reset user passwords via email",errors:{requiredFields:"Please fill in all required fields",usernameRequired:"Username is required when authentication is enabled",enterTestEmail:"Please enter a test email address",smtpServerAndEmail:"Please fill in SMTP Server and From Email before testing",usernamePasswordRequired:"Username and Password are required when authentication is enabled",configureSmtpFirst:"Please configure and test SMTP settings first",enableAuthFirst:"Please enable authentication first to use email-based features."},success:{settingsSaved:"SMTP settings saved successfully"},securityOptions:{starttls:"STARTTLS (Port 587)",ssl:"SSL/TLS (Port 465)",none:"None (Port 25)"},authOptions:{enabled:"Enabled",disabled:"Disabled"}},appearance:"Appearance",notifications:"Notifications",smartPlugs:"Smart Plugs",spoolman:"Spoolman",updates:"Updates",language:"Language",languageDescription:"Select your preferred language",theme:"Theme",themeLight:"Light",themeDark:"Dark",themeSystem:"System",defaultView:"Default View",defaultViewDescription:"Page to show when opening the app",checkForUpdates:"Check for Updates",autoUpdate:"Auto Update",currentVersion:"Current Version",latestVersion:"Latest Version",upToDate:"You are up to date",updateAvailable:"Update available",notificationLanguage:"Notification Language",notificationLanguageDescription:"Language for push notifications",bedCooledThreshold:"Bed Cooled Threshold",bedCooledThresholdDescription:"Temperature below which the bed is considered cooled after a print",userNotificationsEnabled:"User Notifications",userNotificationsEnabledDescription:"Enable the user notifications menu and email notifications for print job events. Requires Advanced Authentication.",userNotificationsDisabledHint:"Enable Advanced Authentication to use user notifications.",notificationProviders:"Notification Providers",addProvider:"Add Provider",editProvider:"Edit Provider",providerType:"Provider Type",testNotification:"Test Notification",testSuccess:"Test notification sent successfully",testFailed:"Failed to send test notification",quietHours:"Quiet Hours",quietHoursDescription:"Do not disturb during these hours",quietHoursStart:"Start",quietHoursEnd:"End",events:{title:"Notification Events",printStart:"Print Started",printComplete:"Print Completed",printFailed:"Print Failed",printStopped:"Print Stopped",printProgress:"Progress Milestones",printProgressDescription:"Notify at 25%, 50%, 75%",printerOffline:"Printer Offline",printerError:"Printer Error",filamentLow:"Low Filament",maintenanceDue:"Maintenance Due",maintenanceDueDescription:"Notify when maintenance is needed"},smartPlug:{title:"Smart Plugs",add:"Add Smart Plug",edit:"Edit Smart Plug",name:"Name",ipAddress:"IP Address",linkedPrinter:"Linked Printer",autoOn:"Auto Power On",autoOnDescription:"Turn on when print starts",autoOff:"Auto Power Off",autoOffDescription:"Turn off after print completes",offDelay:"Off Delay",offDelayMinutes:"Minutes after print",offDelayTemp:"When nozzle below temperature",currentState:"Current State",turnOn:"Turn On",turnOff:"Turn Off"},filamentTracking:"Filament Tracking",filamentTrackingDesc:"Choose how to track your filament spools. You can use the built-in inventory or connect an external Spoolman server.",filamentChecks:"Filament checks",disableFilamentWarnings:"Disable filament warnings",disableFilamentWarningsDesc:"Don't show warnings about insufficient filament when printing or queueing",preferLowestFilament:"Prefer lowest remaining filament",preferLowestFilamentDesc:"When multiple spools match, use the one with the least filament remaining",trackingModeBuiltIn:"Built-in Inventory",trackingModeBuiltInDesc:"RFID auto-matching and usage tracking included",trackingModeSpoolmanDesc:"External filament management server",builtInFeatureRfid:"Automatically detects Bambu Lab RFID spools in AMS",builtInFeatureUsage:"Tracks filament consumption per print",builtInFeatureCatalog:"Manage spools, colors, and K-factor profiles",builtInFeatureThirdParty:"Third-party spools can be assigned to inventory spools",amsSyncButton:"Sync Weights from AMS",amsSyncTitle:"Sync Spool Weights from AMS",amsSyncMessage:"This will overwrite all inventory spool weights with the current AMS remain% values from connected printers. Use this to recover from corrupted weight data. Printers must be online.",amsSyncing:"Syncing...",amsSyncSuccess:"{{synced}} spool(s) synced, {{skipped}} skipped",amsSyncError:"Failed to sync weights from AMS",spoolmanAmsSyncButton:"Sync Spoolman Weights from AMS",spoolmanAmsSyncTitle:"Sync Spoolman Spool Weights from AMS",spoolmanAmsSyncMessage:"This will update all Spoolman spool weights based on the current AMS remain% values from connected printers. Printers must be online.",spoolmanAmsSyncing:"Syncing...",spoolmanAmsSyncSuccess:"{{synced}} spool(s) synced, {{skipped}} skipped",spoolmanAmsSyncError:"Failed to sync Spoolman weights from AMS",spoolmanAmsSyncErrorUnreachable:"Failed to sync Spoolman weights (Spoolman unreachable)",spoolmanAmsSyncErrorNotConfigured:"Failed to sync Spoolman weights (Spoolman not configured)",spoolmanNotConfigured:"Spoolman not configured",spoolmanFilamentCatalogTitle:"Spoolman Filament Catalog",spoolmanFilamentCatalogDesc:"Filament names and tare weights from your Spoolman instance. Name and spool weight are editable here; all other properties are managed directly in Spoolman.",spoolmanUrl:"Spoolman URL",spoolmanUrlHint:"URL of your Spoolman server (e.g., http://localhost:7912)",spoolmanConnected:"Connected",spoolmanDisconnected:"Disconnected",status:"Status",connect:"Connect",disconnect:"Disconnect",howSyncWorks:"How Sync Works",syncInfoRfidOnly:"Only official Bambu Lab spools with RFID are synced",syncInfoAutoCreate:"New spools are auto-created in Spoolman on first sync",syncInfoThirdPartySkipped:"Non-Bambu Lab spools (third-party, refilled) are skipped",linkingExistingSpools:"Linking Existing Spools",linkingExistingSpoolsDesc:'To link existing Spoolman spools to your AMS, hover over an AMS slot and click "Link to Spoolman".',syncMode:"Sync Mode",syncModeAuto:"Automatic",syncModeManual:"Manual Only",syncModeAutoDesc:"AMS data syncs automatically when changes are detected",syncModeManualDesc:"Only sync when manually triggered",syncAmsData:"Sync AMS Data",syncAmsDataDesc:"Manually sync printer AMS data to Spoolman",allPrinters:"All Printers",noDefaultPrinter:"No default (ask each time)",sidebarOrder:"Sidebar order",saveThumbnails:"Save thumbnails",captureFinishPhoto:"Capture finish photo",noPrintersConfigured:"No printers configured",archiveMode:{always:"Always create archive entry",never:"Never create archive entry",ask:"Ask each time"},checkForUpdatesLabel:"Check for updates",checkPrinterFirmware:"Check printer firmware",includeBetaUpdates:"Include beta versions",includeBetaUpdatesDesc:"Notify about beta and prerelease versions when checking for updates",enableRetry:"Enable retry",homeAssistantDescription:"Control smart plugs via Home Assistant",environmentManagedLabel:"(Environment Managed)",autoEnabledViaEnv:"Automatically enabled via environment variables",urlFromEnvReadOnly:"Value set by HA_URL environment variable (read-only)",tokenFromEnvReadOnly:"Value set by HA_TOKEN environment variable (read-only)",mqttConnectedTo:"Connected to",prometheusDescription:"Expose printer data in Prometheus format",noSmartPlugsTitle:"No smart plugs configured",noSmartPlugsDescription:"Add a Tasmota-based smart plug to track energy usage and automate power control.",noProvidersTitle:"No providers configured",noProvidersDescription:"Add a provider to receive alerts.",noTemplatesAvailable:"No templates available. Restart the backend to seed default templates.",apiPermissionView:"View printer status and queue",apiPermissionEdit:"Add and remove items from print queue",apiKeysEmptyTitle:"No API keys",apiKeysEmptyDescription:"Create an API key to integrate with external services.",noUsersFound:"No users found",noGroupsFound:"No groups found",noGroupsAvailable:"No groups available",passwordsDoNotMatch:"Passwords do not match",systemGroupWarning:"System group names cannot be changed",authDisabledTitle:"Authentication is Disabled",authDisabledFeature1:"Require login to access the system",authDisabledFeature2:"Create multiple users with group-based permissions",authDisabledFeature3:"Control access with 50+ granular permissions",userHasCreated:"This user has created:",userItemsQuestion:"What would you like to do with these items?",deleteUserConfirm:"Are you sure you want to delete this user?",actionCannotBeUndone:"This action cannot be undone.",addFirstSmartPlug:"Add Your First Smart Plug",providers:"Providers",log:"Log",testAll:"Test All",testResults:"Test Results",testPassedCount:"{{count}} passed",testFailedCount:"{{count}} failed",messageTemplates:"Message Templates",messageTemplatesDescription:"Customize notification messages for each event.",apiKeys:"API Keys",apiKeysDescription:"Create API keys for external integrations and webhooks.",createKey:"Create Key",apiKeyCreated:"API Key Created Successfully",apiKeyCopyWarning:"Copy this key now - it won't be shown again!",useInApiBrowser:"Use in API Browser",createNewApiKey:"Create New API Key",keyName:"Key Name",keyNamePlaceholder:"e.g., Home Assistant, OctoPrint",readStatus:"Read Status",readStatusDescription:"View printer status and queue",manageQueue:"Manage Queue",manageQueueDescription:"Add and remove items from print queue",controlPrinter:"Control Printer",controlPrinterDescription:"Pause, resume, and stop prints",cloudAccess:"Allow cloud access",cloudAccessDescription:"Read Bambu Cloud presets and filaments on your behalf. Requires you to be signed into Bambu Cloud.",cloudBadge:"Cloud",updateEnergyCost:"Update electricity price",updateEnergyCostDescription:"Allow this key to POST a new per-kWh electricity price to /settings/electricity-price. Useful for Home Assistant dynamic-tariff automations (Tibber, Octopus, etc.). This is the only settings field writable via API key.",energyCostBadge:"Energy",legacyKey:"Legacy",legacyKeyTooltip:"Created before per-user ownership; recreate to use cloud access",unnamedKey:"Unnamed Key",lastUsed:"Last used",read:"Read",control:"Control",createFirstKey:"Create Your First Key",webhookEndpoints:"Webhook Endpoints",webhookApiKeyHint:"Use your API key in the X-API-Key header.",webhook:{getAllStatus:"Get all printer status",getSpecificStatus:"Get specific printer status",addToQueue:"Add to print queue",pausePrint:"Pause print",resumePrint:"Resume print",stopPrint:"Stop print"},apiBrowser:"API Browser",apiBrowserDescription:"Explore and test all available API endpoints.",apiKeyForTesting:"API Key for Testing",apiKeyPlaceholder:"Paste your API key here to test authenticated endpoints...",apiKeyHint:"This key will be sent as X-API-Key header with requests.",deleteApiKeyTitle:"Delete API Key",deleteApiKeyMessage:"Are you sure you want to delete this API key? Any integrations using this key will stop working.",deleteKey:"Delete Key",amsDisplayThresholds:"AMS Display Thresholds",amsThresholdsDescription:"Configure color thresholds for AMS humidity and temperature indicators.",humidity:"Humidity",goodGreen:"Good (green)",fairOrange:"Fair (orange)",aboveFairBad:"Above fair threshold shows as red (bad)",fairAlsoDryingThreshold:"This threshold is also used to trigger auto-drying when enabled",temperature:"Temperature",goodBlue:"Good (blue)",aboveFairHot:"Above fair threshold shows as red (hot)",historyRetention:"History Retention",keepSensorHistory:"Keep sensor history for",historyRetentionDescription:"Older humidity and temperature data will be automatically deleted",defaultPrintOptions:"Default Print Options",defaultPrintOptionsDescription:"Set default values for print options when starting new prints. These can be overridden per print in the print dialog.",defaultBedLevelling:"Bed Levelling",defaultBedLevellingDesc:"Auto-level bed before print",defaultFlowCali:"Flow Calibration",defaultFlowCaliDesc:"Calibrate extrusion flow",defaultVibrationCali:"Vibration Calibration",defaultVibrationCaliDesc:"Reduce ringing artifacts",defaultLayerInspect:"First Layer Inspection",defaultLayerInspectDesc:"AI inspection of first layer",defaultTimelapse:"Timelapse",defaultTimelapseDesc:"Record timelapse video",staggeredStart:"Staggered Start",staggeredStartDescription:"Default group size and interval when staggering multi-printer batch starts. Can be overridden per batch in the print modal.",plateClear:"Plate-Clear Confirmation",requirePlateClear:"Require plate-clear confirmation",requirePlateClearDescription:'When enabled, the scheduler waits for per-printer plate-clear confirmation before starting queued prints on printers with finished jobs. Disabling this also hides the plate status badge and the "Mark plate as cleared" button on printer cards.',gcodeInjection:"G-code Injection",gcodeInjectionDescription:'Configure custom G-code to inject at the start and/or end of prints for auto-print systems like Farmloop, SwapMod, AutoClear, and Printflow 3D. Snippets are configured per printer model and applied when "Inject G-code" is enabled on a queue item.',gcodeInjectionNoPrinters:"No printers found. Add printers to configure G-code snippets.",gcodeStartLabel:"Start G-code",gcodeEndLabel:"End G-code",gcodeStartPlaceholder:"G-code prepended before the print starts...",gcodeEndPlaceholder:"G-code appended after the print ends...",staggerGroupSize:"Group size",staggerGroupSizeHelp:"Printers to start simultaneously per group",staggerInterval:"Interval (minutes)",staggerIntervalHelp:"Delay between each group starting",queueDrying:"Queue Auto-Drying",queueDryingDescription:"Automatically dry AMS filament when printer is idle between queued prints. Uses humidity threshold above to trigger drying.",queueDryingEnabled:"Enable auto-drying",queueDryingEnabledDescription:"Start AMS drying automatically when printer is idle and humidity is above threshold",queueDryingBlock:"Wait for drying to complete",queueDryingBlockDescription:"Block the print queue until drying finishes. When off, prints take priority over drying.",ambientDryingEnabled:"Ambient drying",ambientDryingEnabledDescription:"Automatically dry filament on idle printers when humidity exceeds threshold, even without queued prints.",dryingPresets:"Drying Presets",dryingPresetsDescription:"Temperature and duration per filament type. AMS 2 Pro uses lower temps, AMS-HT supports higher temps.",dryingFilament:"Filament",printModal:"Print Modal",expandCustomMapping:"Expand custom mapping by default",expandCustomMappingDescription:"When printing to multiple printers, show per-printer AMS mapping expanded",authentication:"Authentication",authEnabledDescription:"Your instance is secured with user authentication",authDisabledDescription:"Enable to require login and manage user access",authDisabledMessage:"Enable authentication to create user accounts, manage permissions, and secure your Bambuddy instance.",enableAuthentication:"Enable Authentication",currentUser:"Current User",changePassword:"Change Password",admin:"Admin",users:"Users",addUser:"Add User",groups:"Groups",addGroup:"Add Group",system:"System",noDescription:"No description",userCount:"{{count}} users",permissionCount:"{{count}} permissions",createUser:"Create User",username:"Username",enterUsername:"Enter username",password:"Password",enterPassword:"Enter password",passwordRequirements:"At least 8 characters, with one uppercase, one lowercase, one digit, and one special character.",confirmPassword:"Confirm Password",confirmPasswordPlaceholder:"Confirm password",viewReleaseOnGitHub:"View release on GitHub",turnAllPlugsOn:"Turn all plugs on",turnAllPlugsOff:"Turn all plugs off",clearNotificationLogs:"Clear Notification Logs",clearLogsMessage:"This will permanently delete all notification logs older than 30 days. This action cannot be undone.",clearLogs:"Clear Logs",resetUiPreferences:"Reset UI Preferences",resetUiPreferencesMessage:"This will reset all UI preferences to defaults: sidebar order, theme, dashboard layout, view modes, and sorting preferences. Your printers, archives, and server settings will NOT be affected. The page will reload after clearing.",resetPreferences:"Reset Preferences",deleteGroupTitle:"Delete Group",deleteGroupMessage:"Are you sure you want to delete this group? Users in this group will lose these permissions.",deleteGroup:"Delete Group",disableAuthenticationTitle:"Disable Authentication",disableAuthenticationMessage:"Are you sure you want to disable authentication? This will make your Bambuddy instance accessible without login. All users will remain in the database but authentication will be disabled.",disableAuthentication:"Disable Authentication",configureBambuddy:"Configure Bambuddy",systemDefault:"System Default",archiveSettings:"Archive Settings",newWindow:"New Window",embeddedOverlay:"Embedded Overlay",preferredSlicer:"Preferred Slicer",preferredSlicerDescription:"Choose which slicer application to open files with",orcaslicerKnownIssuesWarning:"OrcaSlicer 2.3.2 / 2.4.0-dev have known CLI bugs that block slicing many Bambu-authored 3MFs — see upstream issues #12426 (segfault on painted multi-extruder files) and #13386 (parameter-range strict-validation reject). Bambu Studio is recommended until the upstream fixes land.",useSlicerApi:"Use Slicer API",useSlicerApiDescription:'When on, "Slice" actions open the in-app slicer modal and call the slicer-API sidecar. When off (default), they hand off to the desktop slicer via URI scheme.',slicerCard:"Slicer",orcaslicerApiUrl:"OrcaSlicer sidecar URL",bambuStudioApiUrl:"Bambu Studio sidecar URL",slicerApiUrlDescription:"URL of the slicer-API sidecar container. Leave blank to use the SLICER_API_URL / BAMBU_STUDIO_API_URL env var defaults.",slicerBundles:{title:"Slicer Bundles",description:'Import a Printer Preset Bundle (.bbscfg) exported from BambuStudio (File → Export → Export Preset Bundle → "Printer preset bundle"). Once imported, slice requests can pick presets from the bundle by name without re-uploading the JSON profile triplet.',uploadButton:"Upload bundle",uploading:"Uploading…",loading:"Loading bundles…",empty:"No bundles imported yet.",summary:"{{processCount}} process · {{filamentCount}} filament presets",delete:"Delete",uploadSuccess:"Imported {{name}}",uploadError:"Bundle upload failed: {{message}}",deleteSuccess:"Bundle removed",deleteError:"Bundle delete failed: {{message}}",confirmDeleteTitle:"Remove this bundle?",confirmDeleteMessage:'Slice requests that reference "{{name}}" will fail until the bundle is re-imported.'},externalCameras:"External Cameras",costTracking:"Cost Tracking",printsOnly:"Prints Only",totalConsumption:"Total Consumption",dataManagement:"Data Management",storageUsage:"Storage Usage",storageUsageDescription:"Breakdown of data usage by category",storageUsageTotal:"Total",storageUsageErrors:"Errors",storageUsageOtherBreakdown:"Other (includes static assets, scripts, and configuration files)",storageUsageSystem:"System",storageUsageData:"Data",storageUsageUnavailable:"Storage usage information unavailable",clearNotificationLogsDescription:"Delete notification logs older than 30 days",resetUiPreferencesDescription:"Reset sidebar order, theme, view modes, and layout preferences. Printers, archives, and settings are not affected.",enableHomeAssistant:"Enable Home Assistant",enableMqtt:"Enable MQTT",useTls:"Use TLS",enableMetricsEndpoint:"Enable Metrics Endpoint",availableMetrics:"Available Metrics",editUser:"Edit User",deleteUserTitle:"Delete User",groupName:"Group Name",leaveEmptyForAnonymous:"Leave empty for anonymous",leaveEmptyForNoAuth:"Leave empty for no authentication",enterNewPassword:"Enter new password",confirmNewPassword:"Confirm new password",enterGroupName:"Enter group name",enterDescriptionOptional:"Enter description (optional)",enterCurrentPassword:"Enter current password",enterNewPasswordMin6:"Enter new password (min 6 characters)",toast:{keyCopied:"Key copied to clipboard",copyFailed:"Failed to copy key",keyAddedToBrowser:"Key added to API Browser",clearLogsFailed:"Failed to clear logs",uiPreferencesReset:"UI preferences reset. Refreshing...",authDisabled:"Authentication disabled successfully",authDisableFailed:"Failed to disable authentication",apiKeyCreated:"API key created",apiKeyDeleted:"API key deleted",userCreated:"User created successfully",userUpdated:"User updated successfully",userDeleted:"User deleted successfully",groupCreated:"Group created successfully",groupUpdated:"Group updated successfully",groupDeleted:"Group deleted successfully",fillRequiredFields:"Please fill in all required fields",passwordsDoNotMatch:"Passwords do not match",passwordTooShort:"Password must be at least 8 characters",passwordNeedsUppercase:"Password must contain at least one uppercase letter",passwordNeedsLowercase:"Password must contain at least one lowercase letter",passwordNeedsDigit:"Password must contain at least one digit",passwordNeedsSpecial:"Password must contain at least one special character",enterGroupName:"Please enter a group name",settingsSaved:"Settings saved",noPermissionUpdate:"You do not have permission to change settings",cameraSettingsSaved:"Camera settings saved",enterCameraUrl:"Please enter a camera URL",passwordChanged:"Password changed successfully",connectionFailed:"Connection failed",testFailed:"Test failed",cameraConnected:"Camera connected{{resolution}}"},testConnection:"Test Connection",catalog:{spoolCatalog:"Spool Catalog",spoolCatalogDescription:"Empty spool weights by brand/type. Used for automatic weight lookup when adding spools.",searchCatalog:"Search catalog...",addNewEntry:"Add New Entry",namePlaceholder:"Name (e.g., Bambu Lab - Plastic)",weight:"Weight",type:"Type",default:"Default",custom:"Custom",noMatch:"No entries match your search",empty:"No entries in catalog",deleteEntry:"Delete Entry",deleteConfirm:'Are you sure you want to delete "{{name}}"?',resetCatalog:"Reset Catalog",resetConfirm:"Reset catalog to defaults? This will remove all custom entries.",loadFailed:"Failed to load spool catalog",nameWeightRequired:"Name and weight are required",entryAdded:"Entry added",addFailed:"Failed to add entry",entryUpdated:"Entry updated",updateFailed:"Failed to update entry",entryDeleted:"Entry deleted",deleteFailed:"Failed to delete entry",resetSuccess:"Catalog reset to defaults",resetFailed:"Failed to reset catalog",exported:"Exported {{count}} entries",imported:"Imported {{added}} entries ({{skipped}} skipped)",importFailed:"Failed to import: invalid JSON format",exportTooltip:"Export catalog to JSON",importTooltip:"Import catalog from JSON",resetTooltip:"Reset to defaults",selectedCount:"{{count}} selected",deleteSelected:"Delete Selected",bulkDeleteConfirm:"Are you sure you want to delete {{count}} entries?",bulkDeleted:"Deleted {{count}} entries",bulkDeleteFailed:"Failed to delete entries",material:"Material",spoolWeight:"Spool Weight",color:"Color",updateSpoolWeight:"Update Spool Weight",filamentUpdated:"Filament updated",filamentUpdateFailed:"Failed to update filament",filamentUpdateInvalid:"Invalid filament data",keepExistingSpoolWeight:"Keep old weight for existing spools",keepExistingSpoolWeightDesc:"Spools already created with this filament type retain the old tare weight. New spools use the updated value.",applyToAllSpools:"Apply to all spools",applyToAllSpoolsDesc:"All weight calculations for this filament type immediately use the new tare weight."},colorCatalog:{title:"Color Catalog",description:"Filament colors by manufacturer/material. Used for automatic color lookup when adding spools.",searchColors:"Search colors...",allManufacturers:"All manufacturers",addNewColor:"Add New Color",manufacturer:"Manufacturer",colorName:"Color Name",hex:"Hex",materialOptional:"Material (optional)",showing:"Showing {{filtered}} of {{total}} colors",noMatch:"No colors match your search",empty:"No colors in catalog",deleteColor:"Delete Color",deleteConfirm:'Are you sure you want to delete "{{name}}"?',resetCatalog:"Reset Color Catalog",resetConfirm:"Reset catalog to defaults? This will remove all custom colors.",sync:"Sync",starting:"Starting...",syncTooltip:"Sync from FilamentColors.xyz (2000+ colors, may take a minute)",loadFailed:"Failed to load color catalog",fieldsRequired:"Manufacturer, color name, and hex color are required",colorAdded:"Color added",addFailed:"Failed to add color",colorUpdated:"Color updated",updateFailed:"Failed to update color",colorDeleted:"Color deleted",deleteFailed:"Failed to delete color",resetSuccess:"Color catalog reset to defaults",resetFailed:"Failed to reset catalog",syncUpToDate:"Already up to date ({{count}} colors checked)",syncComplete:"Added {{added}} new colors ({{skipped}} already existed)",syncError:"Sync error",syncFailed:"Failed to sync from FilamentColors.xyz",exported:"Exported {{count}} colors",imported:"Imported {{added}} colors ({{skipped}} skipped)",importFailed:"Failed to import: invalid JSON format",selectedCount:"{{count}} selected",deleteSelected:"Delete Selected",bulkDeleteConfirm:"Are you sure you want to delete {{count}} colors?",bulkDeleted:"Deleted {{count}} colors",bulkDeleteFailed:"Failed to delete colors"},dateFormat:"Date Format",dateFormatUs:"US (MM/DD/YYYY)",dateFormatEu:"EU (DD/MM/YYYY)",dateFormatIso:"ISO (YYYY-MM-DD)",timeFormat:"Time Format",timeFormat12:"12-hour (3:30 PM)",timeFormat24:"24-hour (15:30)",defaultPrinter:"Default Printer",defaultPrinterDescription:"Pre-select this printer for uploads, reprints, and other operations.",slicerBambuStudio:"Bambu Studio",slicerOrcaSlicer:"OrcaSlicer",sidebarOrderDescription:"Drag items in the sidebar to reorder. Reset to default order here.",setDefault:"Set Default",sidebarOrderSetDefaultHint:"Set default applies the current menu order to users who haven't customized theirs.",sidebarDefaultSet:"Default menu order has been set.",sidebarDefaultCleared:"Default menu order cleared.",sidebarDefaultFailed:"Failed to set default menu order.",reset:"Reset",darkMode:"Dark Mode",lightMode:"Light Mode",active:"(active)",background:"Background",accent:"Accent",style:"Style",bgNeutral:"Neutral",bgWarm:"Warm",bgCool:"Cool",bgOled:"OLED Black",bgSlate:"Slate Blue",bgForest:"Forest Green",accentGreen:"Green",accentTeal:"Teal",accentBlue:"Blue",accentOrange:"Orange",accentPurple:"Purple",accentRed:"Red",styleClassic:"Classic",styleGlow:"Glow",styleVibrant:"Vibrant",themeToggleHint:"Toggle between dark and light mode using the sun/moon icon in the sidebar.",autoArchivePrints:"Auto-archive prints",autoArchiveDescription:"Automatically save 3MF files when prints complete",saveThumbnailsDescription:"Extract and save preview images from 3MF files",captureFinishPhotoDescription:"Take a photo from printer camera when print completes",ffmpegNotInstalled:"ffmpeg not installed",ffmpegRequired:"Camera capture requires ffmpeg. Install it via brew install ffmpeg (macOS) or apt install ffmpeg (Linux).",camera:"Camera",cameraViewMode:"Camera View Mode",cameraOverlayDescription:"Camera opens in a resizable overlay on the main screen",cameraWindowDescription:"Camera opens in a separate browser window",externalCamerasDescription:"Configure external cameras to replace the built-in printer camera. Supports MJPEG streams, RTSP, HTTP snapshots, and USB cameras (V4L2). When enabled, the external camera is used for live view and finish photos.",cameraPlaceholderUsb:"Device path (/dev/video0)",cameraPlaceholderUrl:"Camera URL (rtsp://... or http://...)",cameraTypeMjpeg:"MJPEG Stream",cameraTypeRtsp:"RTSP Stream",cameraTypeSnapshot:"HTTP Snapshot",cameraTypeUsb:"USB Camera (V4L2)",cameraSnapshotUrl:"Snapshot URL (optional)",cameraSnapshotUrlPlaceholder:"http://192.168.1.61:1984/api/frame.jpeg?src=printer",cameraSnapshotUrlHelp:"Single-frame URL used for notification thumbnails, finish photos, layer-timelapse frames, and plate detection. Timelapse and plate detection each require their own per-printer toggle — this URL is just the image source they pull from when active. Leave blank to capture from the live stream above. Useful for go2rtc (/api/frame.jpeg) and IP cameras with a dedicated snapshot endpoint.",cameraRotation:"Rotation",test:"Test",connected:"Connected",disconnected:"Disconnected",currency:"Currency",defaultFilamentCost:"Default filament cost (per kg)",electricityCost:"Electricity cost per kWh",energyDisplayMode:"Energy display mode",energyModePrintDescription:"Dashboard shows sum of energy used during prints",energyModeTotalDescription:"Dashboard shows lifetime energy from smart plugs",fileManager:"File Manager",createArchiveEntry:"Create Archive Entry When Printing",createArchiveEntryDescription:"When printing from File Manager, optionally create an archive entry",lowDiskSpaceWarning:"Low Disk Space Warning",lowDiskSpaceDescription:"Show warning when free disk space falls below this threshold",printerFirmware:"Printer Firmware",checkFirmwareDescription:"Check for printer firmware updates from Bambu Lab",bambuddySoftware:"Bambuddy Software",autoCheckDescription:"Automatically check for new versions on startup",checkNow:"Check now",updateAvailableVersion:"Update available: v{{version}}",releaseNotes:"Release Notes",updateViaDocker:"Update via Docker Compose:",updateViaHomeAssistant:"Updates are managed by the Home Assistant Supervisor. Open Settings → Add-ons → Bambuddy in Home Assistant to install the new version.",installUpdate:"Install Update",latestVersionRunning:"You're running the latest version",failedToCheckUpdates:"Failed to check for updates: {{error}}",backupRestore:"Backup & Restore",backupRestoreDescription:"Export/import settings and configure GitHub backup",goToBackup:"Go to Backup",externalUrl:"External URL",externalUrlDescription:"The external URL where Bambuddy is accessible. Used for notification images and external integrations.",bambuddyUrl:"Bambuddy URL",externalUrlHint:"Include protocol and port (e.g., http://192.168.1.100:8000)",ftpRetry:"FTP Retry",ftpRetryDescription:"Retry FTP operations when printer WiFi is unreliable. Applies to 3MF downloads, print uploads, timelapse downloads, and firmware updates.",autoRetryDescription:"Automatically retry failed FTP operations",retryAttempts:"Retry attempts",retryDelay:"Retry delay",connectionTimeout:"Connection timeout",time_one:"{{count}} time",time_other:"{{count}} times",second_one:"{{count}} second",second_other:"{{count}} seconds",nSeconds:"{{count}} seconds",increaseForWeakWifi:"Increase for printers with weak WiFi",homeAssistant:"Home Assistant",homeAssistantFullDescription:"Connect to Home Assistant to control smart plugs via HA's REST API. Supports switch, light, input_boolean, and script entities.",homeAssistantUrl:"Home Assistant URL",longLivedAccessToken:"Long-Lived Access Token",haTokenHint:"Create a token in HA: Profile → Long-Lived Access Tokens → Create Token",connectionSuccessful:"Connection Successful",connectionFailed:"Connection Failed",haConnectionSuccess:"Successfully connected to Home Assistant.",haConnectionFailed:"Failed to connect to Home Assistant.",mqttPublishing:"MQTT Publishing",mqttDescription:"Publish BamBuddy events to an external MQTT broker for integration with Node-RED, Home Assistant, and other automation systems.",mqttEnableDescription:"Publish events to external MQTT broker",brokerHostname:"Broker hostname",port:"Port",usernameOptional:"Username (optional)",passwordOptional:"Password (optional)",topicPrefix:"Topic prefix",topicPrefixHint:"Topics will be: {{prefix}}/printers//status, etc.",prometheusMetrics:"Prometheus Metrics",prometheusEndpointDescription:"Expose printer metrics at /api/v1/metrics for Prometheus/Grafana monitoring.",bearerTokenOptional:"Bearer Token (optional)",bearerTokenHint:"If set, requests must include Authorization: Bearer ",metricsConnectionStatus:"Connection status",metricsPrinterState:"Printer state (idle/printing/etc)",metricsPrintProgress:"Print progress 0-100%",metricsBedTemp:"Bed temperature",metricsNozzleTemp:"Nozzle temperature",metricsPrintsTotal:"Total prints by result",metricsMore:"...and more (layers, fans, queue, filament usage)",smartPlugsDescription:"Connect smart plugs (Tasmota or Home Assistant) to automate power control and track energy usage for your printers.",allOn:"All On",allOff:"All Off",addSmartPlug:"Add Smart Plug",energySummary:"Energy Summary",currentPower:"Current Power",plugsOnline:"{{reachable}}/{{total}} plugs online",today:"Today",yesterday:"Yesterday",total:"Total",enablePlugsForSummary:"Enable plugs to see energy summary",addNotificationProvider:"Add",systemBadge:"(System)",creating:"Creating...",changing:"Changing...",deleteUserAndItems:"Delete user AND their items",deleteUserKeepItems:"Delete user, keep items (become ownerless)",ok:"OK",twoFa:{totpTitle:"Authenticator App (TOTP)",totpDesc:"Use an authenticator app like Google Authenticator, Aegis or Authy.",emailOtpTitle:"Email OTP",emailOtpDesc:"Send a one-time code to {{email}} when you log in.",emailOtpNoEmail:"Add an email address to your account to enable this method.",addEmailFirst:"Your account has no email address. Ask an admin to add one before enabling Email OTP.",setupTotp:"Set up Authenticator App",setupAuthApp:"Set up Authenticator App",setupInstructions:"Scan the QR code below with your authenticator app, then confirm with a code.",manualEntry:"Can't scan? Enter this secret manually:",scannedContinue:"I've scanned the code — continue",enterCodeToConfirm:"Enter the 6-digit code from your authenticator app to confirm setup.",activate:"Activate",disableTotp:"Disable Authenticator",disableConfirmHint:"Enter a valid TOTP code or a backup code to disable the authenticator.",totpDisabled:"Authenticator app disabled.",emailOtpEnabled:"Email OTP enabled.",emailOtpDisabled:"Email OTP disabled.",smtpRequired:"Please configure and test SMTP settings first.",invalidCode:"Invalid code. Please try again.",enableEmailOtp:"Enable Email OTP",disableEmailOtp:"Disable Email OTP",emailSetupEnterCode:"A verification code has been sent to your email address. Enter it below to confirm you own this inbox.",verifyAndEnable:"Verify & Enable",emailDisablePasswordHint:"Enter your account password to confirm disabling email OTP.",passwordPlaceholder:"Enter your password",backupCodesTitle:"Save your backup codes",backupCodesWarning:"Save these codes somewhere safe. Each code can only be used once and they will not be shown again.",backupCodesRemaining:"{{count}} backup codes remaining",savedCodes:"I've saved my codes",regenBackup:"Regenerate Backup Codes",regenBackupHint:"Enter your current TOTP code to generate 10 new backup codes. All existing backup codes will be invalidated.",newBackupCodes:"New backup codes",linkedAccounts:"Linked SSO Accounts",linkedAccountsDesc:"These external identity providers are linked to your account.",oidcUnlinked:"Account unlinked."},oidc:{title:"SSO / OIDC Providers",desc:"Configure OpenID Connect providers to allow single sign-on via external identity providers.",addProvider:"Add Provider",newProvider:"New Provider",empty:"No OIDC providers configured yet.",created:"Provider created.",updated:"Provider updated.",deleted:"Provider deleted.",refreshIcon:"Refresh icon",removeIcon:"Remove icon",iconRefreshed:"Icon refreshed.",iconRemoved:"Icon removed.",iconFetchFailed:"Icon could not be fetched from the provider URL.",deleteTitle:"Delete Provider",deleteMessage:'Delete "{{name}}"? All linked user accounts will be disconnected.',form:{name:"Display Name",issuerUrl:"Issuer URL",clientId:"Client ID",clientSecret:"Client Secret",scopes:"Scopes",iconUrl:"Icon URL (optional)",enabled:"Enabled",autoCreate:"Auto-create users",autoCreateDesc:"Automatically create a local account on first login.",autoLink:"Auto-link existing accounts",autoLinkDesc:"Link existing local accounts by matching email on first login.",secretHint:"leave blank to keep current",secretPlaceholder:"new secret",emailClaim:"Email Claim",emailClaimDesc:"JWT claim used as email identity. Use 'preferred_username' or 'upn' for Azure Entra ID (which does not send email_verified). Only use trusted claim names.",emailClaimPlaceholder:"email",emailClaimCustomClaimAutoLinkWarning:"Custom claims are safe for auto-link only when the value is tenant-administered (e.g. Azure Entra ID upn / preferred_username). Do not enable auto-link if your IdP allows users to self-assert this claim.",requireEmailVerified:"Require email verified",requireEmailVerifiedDesc:"Only accept the email claim when the provider marks it as verified.",requireEmailVerifiedWarning:"Warning: email will be accepted even without verification. Use only with trusted providers.",requireEmailVerifiedAutoLink:"Disable auto-link first to change this setting.",defaultGroup:"Default Group",defaultGroupDesc:"Group assigned to auto-created users. Falls back to Viewers if not set.",defaultGroupViewersFallback:"Viewers (default)"}},encryption:{title:"MFA Encryption Status",enabledFromEnv:"At-rest encryption enabled (key from MFA_ENCRYPTION_KEY environment variable)",enabledFromFile:"At-rest encryption enabled (key loaded from data directory)",enabledGenerated:"At-rest encryption enabled with auto-generated key",notConfigured:"At-rest encryption not configured",notConfiguredDesc:"TOTP secrets and OIDC client_secrets are stored in plaintext. Set MFA_ENCRYPTION_KEY or restart Bambuddy with a writable data directory to auto-generate one.",allEncrypted:"All MFA secrets are encrypted at rest.",legacyRowsLabel:"Legacy plaintext rows",encryptedRowsLabel:"Encrypted rows",legacyRowsWarning:"{{count}} legacy plaintext row(s) detected. Re-save the OIDC provider or re-enroll the user’s authenticator app to migrate to encrypted storage.",backupHint:"The auto-generated key is stored at DATA_DIR/.mfa_encryption_key and is included in local backup ZIPs. Keep your backups secure or set MFA_ENCRYPTION_KEY explicitly.",decryptionBrokenTitle:"Encryption key missing",decryptionBrokenError:"{{count}} encrypted record(s) cannot be decrypted because the encryption key is no longer available. Restore the previous MFA_ENCRYPTION_KEY or DATA_DIR/.mfa_encryption_key to recover.",migrationErrorWarning:"{{count}} legacy row(s) failed to re-encrypt at startup. Check server logs and restart Bambuddy to retry."}},notification:{printStarted:{title:"Print Started",body:"{{printer}}: {{filename}} has started printing"},printCompleted:{title:"Print Completed",body:"{{printer}}: {{filename}} completed successfully"},printFailed:{title:"Print Failed",body:"{{printer}}: {{filename}} has failed"},printStopped:{title:"Print Stopped",body:"{{printer}}: {{filename}} was stopped"},printProgress:{title:"Print Progress",body:"{{printer}}: {{filename}} is {{percent}}% complete"},printerOffline:{title:"Printer Offline",body:"{{printer}} is offline"},printerError:{title:"Printer Error",body:"{{printer}}: {{error}}"},filamentLow:{title:"Low Filament",body:"{{printer}}: Filament is running low"},maintenanceDue:{title:"Maintenance Due",body:"{{printer}}: {{items}} need attention"}},errors:{generic:"Something went wrong",networkError:"Network error. Please check your connection.",notFound:"Not found",unauthorized:"Unauthorized",serverError:"Server error",validationError:"Please check your input",printerConnectionFailed:"Failed to connect to printer",saveFailed:"Failed to save changes",deleteFailed:"Failed to delete",loadFailed:"Failed to load data"},hmsErrors:{title:"Errors - {{name}}",noErrors:"No errors",viewOnWiki:"View on Bambu Lab Wiki",clearInstructions:"Clear errors on the printer to dismiss them here.",clearErrors:"Clear Errors",clearSuccess:"HMS errors cleared",clearFailed:"Failed to clear HMS errors"},mqttDebug:{title:"MQTT Debug Log",searchPlaceholder:"Search topic or payload...",noMessages:"No messages logged yet",startLoggingHint:'Click "Start Logging" to begin capturing MQTT messages',noMessagesMatch:"No messages match your filter",adjustFilterHint:"Try adjusting your search or filter criteria",incoming:"Incoming",outgoing:"Outgoing",loggingStopped:"Logging stopped",loggingActive:"Logging active - messages will auto-refresh",startLogging:"Start Logging",stopLogging:"Stop Logging",clearLog:"Clear Log",topic:"Topic",timestamp:"Timestamp",direction:"Direction",all:"All"},printerFiles:{title:"File Manager",storageUsed:"Used:",storageFree:"Free:",filterPlaceholder:"Filter files...",deleteButton:"Delete",deleteFiles:"Delete {{count}} Files",deleteFileConfirm:'Delete "{{name}}"? This cannot be undone.',deleteFilesConfirm:"Delete {{count}} selected files? This cannot be undone.",noFiles:"No files on printer",loadingFiles:"Loading files...",failedToLoad:"Failed to load files",toast:{filesDeleted:"Deleted {{count}} file(s)",deleteFailed:"Delete failed: {{error}}"}},confirm:{delete:"Are you sure you want to delete this?",unsavedChanges:"You have unsaved changes. Are you sure you want to leave?",clearQueue:"Are you sure you want to clear the queue?"},login:{title:"Bambuddy Login",subtitle:"Sign in to your account",username:"Username",usernamePlaceholder:"Enter your username",usernameOrEmail:"Username or Email",usernameOrEmailPlaceholder:"Username or @ Email",password:"Password",passwordPlaceholder:"Enter your password",signIn:"Sign in",signingIn:"Logging in...",rememberMe:"Remember Me",forgotPassword:"Forgot your password?",loginSuccess:"Logged in successfully",loginFailed:"Login failed",enterCredentials:"Please enter username and password",enterEmail:"Please enter your email address",oidcLoginFailed:"OIDC login failed",oidcErrors:{providerError:"The identity provider returned an error",missingParameters:"OIDC callback is missing required parameters",invalidState:"OIDC state is invalid or has already been used",stateExpired:"OIDC login session expired — please try again",providerNotFound:"OIDC provider not found",discoveryFailed:"Failed to fetch OIDC discovery document",invalidDiscovery:"OIDC discovery document is invalid",networkError:"Network error during OIDC token exchange",badResponse:"Unexpected response during OIDC token exchange",noIdToken:"OIDC provider did not return an ID token",validationFailed:"OIDC token validation failed",nonceMismatch:"OIDC nonce mismatch — possible replay attack",missingSubClaim:"OIDC token is missing the sub claim",noLinkedAccount:"No local account is linked to this OIDC identity",accountInactive:"Your account is inactive",userResolutionFailed:"Failed to resolve your account",internalError:"An internal error occurred during OIDC login",tokenExchangeFailed:"OIDC token exchange failed"},forgotPasswordTitle:"Forgot Password",forgotPasswordMessage:"If you've forgotten your password, please contact your system administrator to reset it.",forgotPasswordEmailMessage:"Enter your email address and we'll send you a new password.",emailAddress:"Email Address",emailPlaceholder:"your.email@example.com",cancel:"Cancel",sending:"Sending...",sendResetEmail:"Send Reset Email",howToReset:"How to reset your password:",resetStep1:"Contact your Bambuddy administrator",resetStep2:"Ask them to reset your password in User Management",resetStep3:"They can set a new temporary password for you",resetStep4:"Log in with the new password and change it in Settings",gotIt:"Got it",resetPassword:{title:"Set New Password",subtitle:"Enter and confirm your new password below.",newPassword:"New Password",newPasswordPlaceholder:"At least 8 characters",confirmPassword:"Confirm Password",confirmPasswordPlaceholder:"Repeat new password",saving:"Saving…",submit:"Set New Password",backToLogin:"Back to login",passwordsDoNotMatch:"Passwords do not match",passwordTooShort:"Password must be at least 8 characters",resetFailed:"Password reset failed. The link may have expired."},twoFA:{title:"Two-Factor Authentication",subtitle:"Your account is protected with 2FA. Enter the verification code below.",methodAuthenticator:"Authenticator App",methodEmail:"Email Code",methodBackup:"Backup Code",instructionsTotp:"Open your authenticator app and enter the 6-digit code for Bambuddy.",instructionsEmail:"A 6-digit code has been sent to your email address. It expires in 10 minutes.",instructionsEmailNotSent:"Click the button below to receive a verification code via email.",instructionsBackup:"Enter one of your 8-character backup recovery codes. Each code can only be used once.",sendCodeButton:"Send Code via Email",sendingCode:"Sending...",resendCode:"Resend code",codeLabel:"Verification Code",backupCodeLabel:"Backup Code",codePlaceholder:"000000",backupCodePlaceholder:"XXXXXXXX",verifyButton:"Verify",verifyingButton:"Verifying...",backToLogin:"← Back to login",orContinueWith:"or continue with",signInWith:"Sign in with {{provider}}",enterCode:"Please enter the verification code",sendCodeFailed:"Failed to send verification code",invalidCode:"Invalid code. Please try again."}},setup:{title:"Bambuddy Setup",subtitle:"Configure authentication for your Bambuddy instance",enableAuth:"Enable Authentication",adminAccount:"Admin Account",adminAccountDesc:"If admin users already exist, authentication will be enabled using the existing admin accounts. Leave the fields below empty to use existing admins, or enter new credentials to create a new admin user.",adminUsername:"Admin Username",adminPassword:"Admin Password",optionalIfAdminExists:"(optional if admin users exist)",adminUsernamePlaceholder:"Enter admin username (optional)",adminPasswordPlaceholder:"Enter admin password (optional)",confirmPassword:"Confirm Password",confirmPasswordPlaceholder:"Confirm admin password",settingUp:"Setting up...",completeSetup:"Complete Setup",toast:{authEnabledAdminCreated:"Authentication enabled and admin user created",authEnabledExistingAdmins:"Authentication enabled using existing admin users",setupCompleted:"Setup completed",enterBothCredentials:"Please enter both admin username and password, or leave both empty to use existing admin users",passwordsDoNotMatch:"Passwords do not match",passwordTooShort:"Password must be at least 6 characters"}},changePassword:{title:"Change Password",currentPassword:"Current Password",currentPasswordPlaceholder:"Enter current password",newPassword:"New Password",newPasswordPlaceholder:"Enter new password (min 6 characters)",confirmPassword:"Confirm New Password",confirmPasswordPlaceholder:"Confirm new password",passwordsDoNotMatch:"Passwords do not match",passwordTooShort:"Password must be at least 6 characters",changing:"Changing...",success:"Password changed successfully",failed:"Failed to change password"},plateAlert:{title:"Print Paused!",message:"Objects detected on build plate. The print has been automatically paused. Please clear the plate and resume the print.",understand:"I Understand"},camera:{title:"Camera View",invalidPrinterId:"Invalid printer ID",live:"Live",snapshot:"Snapshot",restartStream:"Restart stream",refreshSnapshot:"Refresh snapshot",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",connectingToCamera:"Connecting to camera...",capturingSnapshot:"Capturing snapshot...",connectionLost:"Connection lost",connectionFailed:"Camera connection failed",reconnecting:"Reconnecting in {{countdown}}s... (attempt {{attempt}}/{{max}})",reconnectNow:"Reconnect now",cameraUnavailable:"Camera unavailable",cameraUnavailableDesc:"Make sure the printer is powered on and connected.",noCamera:"No camera available",retry:"Retry",cameraStream:"Camera stream",zoomOut:"Zoom out",zoomIn:"Zoom in",resetZoom:"Reset zoom",recording:"Recording",startRecording:"Start Recording",stopRecording:"Stop Recording",chamberLight:"Toggle chamber light"},groups:{title:"Group Management",subtitle:"Manage permission groups for access control",backToSettings:"Back to Settings",createGroup:"Create Group",noPermission:"You do not have permission to access this page.",system:"System",noDescription:"No description",usersCount:"{{count}} users",permissionsCount:"{{count}} permissions",edit:"Edit",delete:"Delete",toast:{created:"Group created successfully",updated:"Group updated successfully",deleted:"Group deleted successfully",enterGroupName:"Please enter a group name"},modal:{editGroup:"Edit Group",createGroup:"Create Group",cancel:"Cancel",saving:"Saving...",creating:"Creating...",saveChanges:"Save Changes"},form:{groupName:"Group Name",groupNamePlaceholder:"Enter group name",systemGroupWarning:"System group names cannot be changed",description:"Description",descriptionPlaceholder:"Enter description (optional)",permissions:"Permissions ({{count}} selected)"},deleteModal:{title:"Delete Group",message:"Are you sure you want to delete this group? Users in this group will lose these permissions.",confirm:"Delete Group"},editor:{title:"Edit Group",createTitle:"Create Group",search:"Search permissions...",selectAll:"Select All",clearAll:"Clear All",permissionsSelected:"{{count}} selected",noResults:"No permissions match your search"}},users:{title:"User Management",subtitle:"Manage users and their access to your Bambuddy instance",backToSettings:"Back to Settings",createUser:"Create User",noPermission:"You do not have permission to access this page.",admin:"Admin",noGroups:"No groups",active:"Active",inactive:"Inactive",edit:"Edit",delete:"Delete",system:"System",noGroupsAvailable:"No groups available",table:{username:"Username",groups:"Groups",status:"Status",actions:"Actions"},toast:{created:"User created successfully",updated:"User updated successfully",deleted:"User deleted successfully",fillRequired:"Please fill in all required fields",passwordsDoNotMatch:"Passwords do not match",passwordTooShort:"Password must be at least 6 characters",ldapProvisioned:'Provisioned LDAP user "{{username}}"'},modal:{createUser:"Create User",editUser:"Edit User",cancel:"Cancel",creating:"Creating...",saving:"Saving...",saveChanges:"Save Changes",advancedAuthSubtitle:"with Advanced Authentication",tabsAriaLabel:"User source",localTab:"Local",ldapTab:"LDAP",ldapSearchLabel:"Search directory",ldapSearchPlaceholder:"Type a username, name, or email...",ldapMinChars:"Type at least 2 characters to search",ldapTypeToSearch:"Start typing to search the LDAP directory",ldapSearching:"Searching directory...",ldapNoResults:"No matching users in the directory",ldapSearchError:"Directory search failed. Check the LDAP server status.",ldapAlreadyProvisioned:"Already provisioned",ldapSelectedLabel:"Selected",ldapProvision:"Provision user",ldapProvisioning:"Provisioning...",ldapErrorProvision:"Provisioning failed. Check the LDAP server status and try again."},form:{username:"Username",usernamePlaceholder:"Enter username",email:"Email",emailPlaceholder:"user@example.com",password:"Password",passwordPlaceholder:"Enter password",confirmPassword:"Confirm Password",confirmPasswordPlaceholder:"Confirm password",newPasswordPlaceholder:"Enter new password",confirmNewPasswordPlaceholder:"Confirm new password",leaveBlankToKeep:"leave blank to keep current",groups:"Groups",optional:"optional",autoGeneratedPassword:"A secure password will be automatically generated and emailed to the user.",passwordManagedByAdvancedAuth:'Password is managed by Advanced Authentication. Use "Reset Password" to send a new password to the user via email.',resetPassword:"Reset Password",resettingPassword:"Resetting Password..."},deleteModal:{title:"Delete User",message:"Are you sure you want to delete this user? This action cannot be undone.",confirm:"Delete User"}},streamOverlay:{title:"Stream Overlay",invalidPrinterId:"Invalid printer ID",cameraStream:"Camera stream",progress:"Progress",eta:"ETA",printerIdle:"Printer is idle",printerOffline:"Printer offline",status:{printing:"Printing",paused:"Paused",finished:"Finished",failed:"Failed",idle:"Idle",unknown:"Unknown"}},profiles:{title:"Profiles",subtitle:"Manage your slicer presets and pressure advance calibrations",tabs:{cloud:"Cloud Profiles",local:"Local Profiles",kprofiles:"K-Profiles"},localProfiles:{title:"Local Profiles",subtitle:"Import and manage slicer presets from OrcaSlicer",import:"Import Profiles",importDesc:"Drop .bbscfg, .bbsflmt, .orca_filament, .zip, or .json files here",importing:"Importing...",search:"Search local presets...",noPresets:"No local presets yet",badge:"Local",edit:"Edit",delete:"Delete",cancel:"Cancel",deleteConfirmTitle:"Delete Preset",deleteConfirm:"Are you sure you want to delete this preset? This cannot be undone.",source:"Source",inheritsFrom:"Inherits",filamentType:"Type",vendor:"Vendor",compatiblePrinters:"Printers",nozzleTemp:"Nozzle Temp",cost:"Cost",density:"Density",pressureAdvance:"Pressure Advance",filament:"Filament",process:"Process",printer:"Printer",toast:{importSuccess:"{{count}} preset(s) imported",importSkipped:"{{count}} preset(s) skipped (duplicates)",importError:"{{count}} error(s) during import",deleted:"Preset deleted",updated:"Preset updated"}},connectedAs:"Connected as",logout:"Logout",noLogoutPermission:"You do not have permission to logout",failedToLoad:"Failed to load profiles",retry:"Retry",time:{justNow:"Just now",minsAgo:"{{count}}m ago",hoursAgo:"{{count}}h ago",daysAgo:"{{count}}d ago"},toast:{loggedOut:"Logged out"},login:{title:"Connect to Bambu Cloud",subtitle:"Sync your slicer presets across devices",email:"Email",password:"Password",region:"Region",regionGlobal:"Global",regionChina:"China",verificationCode:"Verification Code",totpCode:"Authenticator Code",checkEmail:"Check your email ({{email}}) for a 6-digit code",enterTotpHint:"Enter the 6-digit code from your authenticator app",accessToken:"Access Token",accessTokenHint:"Paste your Bambu Cloud access token. China-region accounts must use this path (phone-bound — email login unavailable). See the wiki for how to retrieve the token from MakerWorld cookies.",back:"Back",loginButton:"Login",verifyButton:"Verify",setTokenButton:"Set Token",useToken:"Use access token instead",useEmail:"Login with email instead",toast:{loggedIn:"Logged in successfully",codeSent:"Verification code sent to your email",enterTotp:"Enter code from your authenticator app",tokenSet:"Token set successfully"}},presets:{myPreset:"My preset (editable)",duplicate:"Duplicate",editable:"Editable",failedToLoadDetails:"Failed to load preset details",deleteConfirm:"Delete this preset?",deleteWarning:'This will permanently delete "{{name}}" from Bambu Cloud. This cannot be undone.',noDuplicatePermission:"You do not have permission to duplicate presets",noEditPermission:"You do not have permission to edit presets",noDeletePermission:"You do not have permission to delete presets",types:{filament:"Filament preset",printer:"Printer preset",process:"Process preset"},toast:{deleted:"Preset deleted",created:"Preset created",updated:"Preset updated",duplicated:"Preset duplicated",fieldAdded:'Field "{{key}}" added',exported:"Preset exported"},baseLabel:"Base: {{name}}",currentLabel:"Current: {{name}}",newPreset:"New Preset",editPreset:"Edit Preset",duplicatePreset:"Duplicate Preset",createNewPreset:"Create New Preset",customizeSettings:"Customize settings for your new preset",compareWithBase:"Compare with base preset",compare:"Compare",basePreset:"Base Preset",selectBasePreset:"Select base preset...",presetName:"Preset Name",myCustomPreset:"My custom preset",inheritsFrom:"Inherits from",dropJsonToImport:"Drop JSON to import",tabs:{common:"Common",allFields:"All Fields"},availableFields:"Available Fields",searchFieldsPlaceholder:"Search fields...",noMatchingFields:"No matching fields",allFieldsAdded:"All fields added",addCustomField:"Add custom field",yourOverrides:"Your Overrides",noOverridesYet:"No overrides yet",clickFieldsToAdd:"Click fields on the left to add them",saveAsTemplate:"Save as template",jsonTip:"Tip: Drag & drop a .json file anywhere on this modal to import settings"},cloudView:{searchPlaceholder:"Search presets...",templates:"Templates",refresh:"Refresh",newPreset:"New Preset",clearFilters:"Clear filters",compareMode:"Compare Mode",selectAnotherPreset:"Select another {{type}} preset",clickTwoPresets:"Click two presets of the same type to compare",selectFirst:"1. Select first",selectSecond:"2. Select second",compareNow:"Compare Now",lastSynced:"Last synced:",showingCount:"Showing {{showing}} of {{total}} presets",noPresetsFound:"No presets found",columns:{filament:"Filament",process:"Process",printer:"Printer"},noFilamentPresets:"No filament presets",noProcessPresets:"No process presets",noPrinterPresets:"No printer presets",filters:{type:"Type",owner:"Owner",printer:"Printer",nozzle:"Nozzle",filament:"Filament",layer:"Layer",all:"All",myPresets:"My Presets",builtIn:"Built-in",process:"Process"},noTemplatesPermission:"You do not have permission to manage templates",noRefreshPermission:"You do not have permission to refresh profiles",noCreatePermission:"You do not have permission to create presets"},templates:{title:"Quick Templates",noTemplates:"No templates yet",createFirst:"Create templates from the preset editor",typeFilter:"Type:",deleteTitle:"Delete Template",deleteWarning:"This action cannot be undone",deleteConfirm:'Are you sure you want to delete "{{name}}"?',namePlaceholder:"Template name",descriptionPlaceholder:"Description",settingsJson:"Settings (JSON)",fieldsCount:"{{count}} fields",shownInModals:"Shown in modals",hiddenInModals:"Hidden in modals",apply:"Apply",toast:{deleted:"Template deleted",updated:"Template updated",created:"Template created",applied:"Template applied"}}},support:{debugLoggingActive:"Debug logging is active",manageLogs:"Manage",collectItem7:"Printer connectivity and firmware versions",collectItem8:"Integration status (Spoolman, MQTT, HA)",collectItem9:"Network interfaces (subnets only)",collectItem10:"Python package versions",collectItem11:"Database health checks",collectItem12:"Docker environment details"},fileManager:{title:"File Manager",subtitle:"Organize and manage your print files",uploadFiles:"Upload Files",newFolder:"New Folder",folderName:"Folder Name",folderNamePlaceholder:"e.g., Functional Parts",renameFile:"Rename File",renameFolder:"Rename Folder",moveFiles:"Move {{count}} File(s)",rootNoFolder:"Root (No Folder)",current:"current",linkFolder:"Link Folder",linkFolderDescription:'Link "{{name}}" to a project or archive for quick access.',project:"Project",archive:"Archive",noProjectsFound:"No projects found",noArchivesFound:"No archives found",unlink:"Unlink",link:"Link",dragDropFiles:"Drag & drop files here",dropFilesHere:"Drop files here",orClickToBrowse:"or click to browse",allFileTypesSupported:"All file types supported. ZIP files will be extracted.",zipFilesDetected:"ZIP files detected",zipExtractOptions:"ZIP files will be extracted. Choose how to handle folder structure:",preserveZipStructure:"Preserve folder structure from ZIP",createFolderFromZip:"Create folder from ZIP filename",stlThumbnailGeneration:"STL thumbnail generation",zipMayContainStl:"ZIP files may contain STL files. Thumbnails can be generated during extraction.",thumbnailsCanBeGenerated:"Thumbnails can be generated for STL files. Large models may take longer to process.",generateThumbnailsForStl:"Generate thumbnails for STL files",threemfDetected:"3MF files detected",threemfExtractionInfo:"Printer model, material, color, and print settings will be automatically extracted from 3MF files.",willBeExtracted:"Will be extracted",filesExtracted:"{{count}} files extracted",uploadComplete:"Upload complete: {{succeeded}} succeeded",uploadFailed:"Upload failed",zipFilesFailed:"{{count}} files failed",uploading:"Uploading...",changeLink:"Change Link...",linkTo:"Link to...",linkToProjectOrArchive:"Link to project or archive",addToQueue:"Add to Queue",schedulePrint:"Schedule",generateThumbnail:"Generate Thumbnail",generateThumbnails:"Generate Thumbnails",generateThumbnailsForMissing:"Generate thumbnails for STL files missing them",gridView:"Grid view",listView:"List view",lowDiskSpaceWarning:"Low disk space warning",lowDiskSpaceDetails:"Only {{free}} free of {{total}} total. Threshold is set to {{threshold}} GB in settings.",files:"Files",folders:"Folders",size:"Size",free:"Free",allFiles:"All Files",wrap:"Wrap",enableTextWrapping:"Enable text wrapping",disableTextWrapping:"Disable text wrapping",collapse:"Collapse",collapseFoldersByDefault:"Collapse folders by default",expandFoldersByDefault:"Expand folders by default",dragToResizeTooltip:"Drag to resize, double-click to reset",searchFiles:"Search files...",allTypes:"All types",prints:"Prints",ascending:"Ascending",descending:"Descending",resultsCount:"{{showing}} of {{total}} files",selectAll:"Select All",deselectAll:"Deselect All",selected:"{{count}} selected",adding:"Adding...",loadingFiles:"Loading files...",folderIsEmpty:"Folder is empty",noFilesYet:"No files yet",folderEmptyDescription:"Upload files or move files into this folder to get started.",noFilesDescription:"Upload files to start organizing your print-related files.",noMatchingFiles:"No matching files",noMatchingFilesDescription:"No files match your current search or filter criteria.",clearFilters:"Clear filters",printedCount:"Printed {{count}}x",uploadedBy:"Uploaded By",deleteFolder:"Delete Folder",deleteFile:"Delete File",deleteFilesCount:"Delete {{count}} Files",deleteFolderConfirm:"Are you sure you want to delete this folder? All files inside will also be deleted.",deleteFileConfirm:"Are you sure you want to delete this file?",deleteFilesConfirm:"Are you sure you want to delete {{count}} selected files? This action cannot be undone.",deleting:"Deleting...",noPermissionRenameFolder:"You do not have permission to rename folders",noPermissionLinkFolder:"You do not have permission to link folders",noPermissionDeleteFolder:"You do not have permission to delete folders",noPermissionPrint:"You do not have permission to print",noPermissionAddToQueue:"You do not have permission to add to queue",noPermissionSlice:"You do not have permission to slice files",noPermissionDownload:"You do not have permission to download files",noPermissionRenameFile:"You do not have permission to rename this file",noPermissionGenerateThumbnail:"You do not have permission to generate thumbnails",noPermissionDeleteFile:"You do not have permission to delete this file",noPermissionCreateFolder:"You do not have permission to create folders",noPermissionUpload:"You do not have permission to upload files",noPermissionMoveFiles:"You do not have permission to move files",noPermissionDeleteFiles:"You do not have permission to delete files",linkExternal:"Link External",linkExternalFolder:"Link External Folder",linkExternalFolderDescription:"Mount a host directory (NAS, USB, network share) into the File Manager. Files are not copied — they are accessed directly from the original path.",externalFolderNamePlaceholder:"e.g., NAS Prints",externalPath:"Host Path",externalPathHelp:"Absolute path to the directory on the Docker host. Must be bind-mounted into the container.",readOnly:"Read Only",readOnlyHelp:"prevents uploads and deletions",showHiddenFiles:"Show hidden files (dotfiles)",externalFolder:"External Folder",scanFolder:"Scan",toast:{folderCreated:"Folder created",folderDeleted:"Folder deleted",fileDeleted:"File deleted",filesDeleted:"Deleted {{count}} files",filesMoved:"Files moved",folderLinked:"Folder linked",folderUnlinked:"Folder unlinked",externalFolderLinked:"External folder linked and scanned",folderScanned:"Scan complete: {{added}} added, {{removed}} removed",addedToQueue:"Added {{count}} file(s) to queue",addedToQueuePartial:"Added {{added}} file(s), {{failed}} failed",failedToAddToQueue:"Failed to add files: {{error}}",fileRenamed:"File renamed",folderRenamed:"Folder renamed",thumbnailsGenerated:"Generated {{count}} thumbnail(s)",thumbnailsGeneratedPartial:"Generated {{succeeded}} thumbnail(s), {{failed}} failed",noStlMissingThumbnails:"No STL files missing thumbnails",failedToGenerateThumbnails:"Failed to generate thumbnails: {{error}}",thumbnailGenerated:"Thumbnail generated",failedToGenerateThumbnail:"Failed to generate thumbnail: {{error}}"}},projects:{title:"Projects",subtitle:"Organize and track your 3D printing projects",newProject:"New Project",editProject:"Edit Project",deleteProject:"Delete Project",projectName:"Project Name",description:"Description",noProjects:"No projects yet",noProjectsFiltered:"No {{status}} projects",noProjectsFilteredHelp:"You don't have any {{status}} projects. Projects will appear here when their status changes.",createFirst:"Create your first project to start organizing related prints, tracking progress, and managing your builds.",createFirstButton:"Create Your First Project",create:"Create",files:"Files",prints:"Prints",plates:"plates",parts:"parts",lastModified:"Last Modified",deleteConfirm:"Are you sure you want to delete this project? Archives and queue items will be unlinked but not deleted.",addFiles:"Add Files",removeFile:"Remove File",viewDetails:"View Details",namePlaceholder:"e.g., Voron 2.4 Build",descriptionPlaceholder:"Optional description...",urlLabel:"URL",urlPlaceholder:"https://makerworld.com/...",urlInvalid:"URL must start with http:// or https://",openExternalUrl:"Open project URL",coverImageLabel:"Cover photo",coverImageAlt:"Project cover photo",coverImageUpload:"Upload",coverImageReplace:"Replace",coverImageRemove:"Remove",color:"Color",targetPlates:"Target Plates",targetPlatesPlaceholder:"e.g., 25",targetPlatesHelp:"Number of print jobs",targetParts:"Target Parts",targetPartsPlaceholder:"e.g., 150",targetPartsHelp:"Total objects needed",tagsLabel:"Tags (comma-separated)",tagsPlaceholder:"e.g., voron, functional, gift",dueDate:"Due Date",priority:"Priority",priorityLow:"Low",priorityNormal:"Normal",priorityHigh:"High",priorityUrgent:"Urgent",statusActive:"Active",statusCompleted:"Completed",statusArchived:"Archived",done:"Done",completed:"completed",failed:"failed",inQueue:"in queue",noPrintsYet:"No prints yet",printJobs:"Print jobs (plates)",partsPrinted:"Parts printed",failedParts:"Failed parts",import:"Import",export:"Export",importProject:"Import project",exportAll:"Export all projects",loading:"Loading projects...",noEditPermission:"You do not have permission to edit projects",noDeletePermission:"You do not have permission to delete projects",noCreatePermission:"You do not have permission to create projects",noImportPermission:"You do not have permission to import projects",noExportPermission:"You do not have permission to export projects",toast:{created:"Project created",updated:"Project updated",deleted:"Project deleted",imported:"Project imported",multipleImported:"{{count}} projects imported",importFailed:"Import failed",exported:"Projects exported (metadata only)"}},projectDetail:{notFound:"Project not found",backToProjects:"Back to Projects",export:"Export",exportProject:"Export project",noExportPermission:"You do not have permission to export projects",noEditPermission:"You do not have permission to edit projects",partOf:"Part of:",priorityLabel:"Priority:",noPrints:"No prints in this project yet",status:{active:"Active",completed:"Completed",archived:"Archived"},priority:{low:"Low",normal:"Normal",high:"High",urgent:"Urgent"},dueDate:{overdue:"Overdue",today:"Due today",daysLeft:"{{count}} days left"},progress:{platesProgress:"Plates Progress",partsProgress:"Parts Progress",printJobs:"print jobs",parts:"parts",percentComplete:"{{percent}}% complete",remaining:"{{count}} remaining"},stats:{printJobs:"Print Jobs",total:"total",failed:"{{count}} failed",partsPrinted:"{{count}} parts printed",printTime:"Print Time",filamentUsed:"Filament Used"},cost:{title:"Cost Tracking",filamentCost:"Filament Cost",energy:"Energy",totalCost:"Total Cost",total:"Total",includesBom:"incl. BOM",budget:"Budget",remaining:"Remaining"},subProjects:{title:"Sub-projects ({{count}})"},notes:{title:"Notes",noEditPermission:"You do not have permission to edit notes",placeholder:"Add notes about this project...",empty:"No notes yet. Click Edit to add notes."},files:{title:"Files",linkFolders:"Link folders from the File Manager",forQuickAccess:"to this project for quick access.",fileCount:"{{count}} file(s)",empty:"No folders linked. Go to File Manager and link a folder to this project.",noFiles:"No files in this folder.",print:"Print Now",addToQueue:"Add to Queue"},bom:{title:"Bill of Materials",acquired:"{{completed}}/{{total}} acquired",showAll:"Show all",hideDone:"Hide done",addPart:"Add Part",noAddPermission:"You do not have permission to add parts",partNamePlaceholder:"Part name (e.g., M3x8 screws)",partName:"Part name",qty:"Qty",price:"Price ({{currency}})",sourcingUrlPlaceholder:"Sourcing URL (optional)",remarksPlaceholder:"Remarks (optional)",deletePart:"Delete Part",deleteConfirm:'Are you sure you want to delete "{{name}}"?',noUpdatePermission:"You do not have permission to update parts",noEditPermission:"You do not have permission to edit parts",noDeletePermission:"You do not have permission to delete parts",totalCost:"Total cost:",empty:"No parts in the bill of materials. Add hardware, electronics, or other components to track what needs to be sourced."},timeline:{title:"Activity Timeline",empty:"No activity yet."},template:{saveAsTemplate:"Save as Template",noCreatePermission:"You do not have permission to create templates"},queue:{title:"Queue",viewAll:"View all",printing:"{{count}} printing",queued:"{{count}} queued"},prints:{title:"Prints ({{count}})"},toast:{projectUpdated:"Project updated",partAdded:"Part added",partRemoved:"Part removed",exportFailed:"Export failed",projectExported:"Project exported",templateCreated:"Template created"}},system:{title:"System Information",version:"Version",uptime:"Uptime",cpuUsage:"CPU Usage",memoryUsage:"Memory Usage",diskUsage:"Disk Usage",networkInfo:"Network Info",logs:"Logs",debugMode:"Debug Mode",enableDebug:"Enable Debug Logging",disableDebug:"Disable Debug Logging",downloadLogs:"Download Logs",clearLogs:"Clear Logs",dockerInfo:"Docker Info",containerName:"Container Name",imageName:"Image Name",platform:"Platform",architecture:"Architecture"},library:{title:"Filament Library",addFilament:"Add Filament",editFilament:"Edit Filament",deleteFilament:"Delete Filament",vendor:"Vendor",material:"Material",color:"Color",kFactor:"K Factor",temperature:"Temperature",noFilaments:"No filaments in library",deleteConfirm:"Are you sure you want to delete this filament?",importFromPrinter:"Import from Printer",exportToFile:"Export to File"},slice:{title:"Slice model",action:"Slice",slicing:"Slicing…",printer:"Printer profile",process:"Process profile",filament:"Filament profile",filamentSlot:"Filament {{index}} ({{type}})",selectPreset:"— Select a preset —",loadingPresets:"Loading presets…",analyzingPlateFilaments:"Analyzing plate filaments…",analyzingPlateFilamentsHint:"Running a preview slice to discover which AMS slots this plate uses. Cached after — re-opening is instant.",previewToast:"Analyzing {{name}} — {{elapsed}}",previewWithProgress:"Analyzing {{name}} — {{stage}} ({{percent}}%) — {{elapsed}}",notUsedByPlate:"— not used by this plate",printerMismatch:"This 3MF was sliced for {{source}}, but you picked {{target}}. The slicer CLI cannot re-slice a 3MF for a different printer — open the source in Bambu Studio, change the printer, and re-export.",noPresetsForSlot:"No presets available",presetsLoadFailed:"Failed to load presets. Open Settings → Profiles to import them first.",allPresetsRequired:"All presets must be selected",enqueuing:"Submitting slice job…",queued:"Queued…",failed:"Slicing failed. Check the slicer sidecar logs.",startedToast:"Slicing {{name}} in the background…",queuedToast:"Queued: {{name}} — {{elapsed}}",runningToast:"Slicing {{name}} — {{elapsed}}",runningWithProgress:"{{name}} — {{stage}} ({{percent}}%) — {{elapsed}}",completedToast:"Sliced {{name}}",failedToast:"Slicing {{name}} failed: {{detail}}",tier:{local:"Imported",cloud:"Cloud",standard:"Standard"},cloud:{notAuthenticated:"Sign in to Bambu Cloud (Settings → Profiles → Cloud) to see your cloud presets.",expired:"Bambu Cloud session expired — sign in again to refresh your cloud presets.",unreachable:"Bambu Cloud is unreachable right now. Local and standard presets still work."},bedType:{label:"Build plate",auto:"Auto (use process preset)",coolPlate:"Cool Plate",coolPlateSuperTack:"Cool Plate SuperTack",engineering:"Engineering Plate",highTemp:"High Temp Plate",texturedPEI:"Textured PEI Plate",smoothPEI:"Smooth PEI Plate"}},spoolman:{title:"Spoolman Integration",enabled:"Spoolman Enabled",url:"Spoolman URL",connected:"Connected",disconnected:"Not Connected",testConnection:"Test Connection",sync:"Sync",syncing:"Syncing...",lastSync:"Last Sync",linkToSpoolman:"Link to Spoolman",openInSpoolman:"Open in Spoolman",unlinkSpool:"Unlink Spool",unlinkConfirmTitle:"Unassign Spool?",unlinkConfirmMessage:"This will remove the spool from this slot. The spool data itself will remain unchanged.",selectSpool:"Select Spool",noUnlinkedSpools:"No unassigned spools available",linkSuccess:"Spool assigned successfully",linkFailed:"Failed to assign spool",unlinkSuccess:"Spool unassigned successfully",unlinkFailed:"Failed to unassign spool",linkedSpool:"Assigned spool",spoolId:"Spool ID",fillSourceLabel:"(Spoolman)",weight:"Weight",remaining:"Remaining",disableWeightSync:"Disable AMS Estimated Weight Sync",disableWeightSyncDesc:"Don't update remaining capacity from AMS estimates. Use this if you prefer Spoolman's usage tracking over AMS percentage-based estimates. New spools will still use the AMS estimate as their initial weight.",reportPartialUsage:"Report Partial Usage for Failed Prints",reportPartialUsageDesc:"When a print fails or is cancelled, report the estimated filament used up to that point based on layer progress."},inventory:{title:"Spool Inventory",subtitle:"Manage your spools",spoolmanMixedContentTitle:"Spoolman can't load over HTTPS — mixed-content blocked by your browser",spoolmanMixedContentBody:"Bambuddy is served over HTTPS (via your reverse proxy), but your Spoolman URL is still plain HTTP. Browsers block mixed content for security, so the embedded Spoolman UI can't render. Spoolman needs to be reachable over HTTPS for this to work.",spoolmanMixedContentFixReverseProxy:"Put Spoolman behind the same reverse proxy as Bambuddy (Traefik / Nginx / Caddy) with HTTPS, then update the Spoolman URL in Settings to the new HTTPS address.",spoolmanMixedContentFixOpenNewTab:"As a workaround, open Spoolman in a new browser tab over HTTP — mixed-content rules only apply to embedded frames, so a standalone tab still works.",spoolmanOpenInNewTab:"Open Spoolman in a new tab",labels:{title:"Print spool labels",selectedCount:"{{count}} selected",pickSpools:"Pick which spools to print labels for:",searchPlaceholder:"Search name, brand, or #ID",filterByMaterial:"Material:",allMaterials:"All",selectVisible:"Select all visible ({{count}})",deselectVisible:"Deselect visible",clearAll:"Clear all",noSpoolsToShow:"No spools to show. Adjust your filter and try again.",noMatches:"No spools match the current search or filter.",printOne:"Print label for this spool",printLabels:"Print labels…",bulkTitle:"Pick spools to print labels for from the {{count}} currently shown",noSpoolsTitle:"No spools to label",error:"Could not generate labels: {{msg}}",templates:{ams:{label:"AMS holder (30 × 15 mm)",hint:"Single label per page; fits the popular AMS filament label holder."},box40x30:{label:"Box label (40 × 30 mm)",hint:"Single label per page; common DK/Brother roll size, good for filament-bag and storage-bin labels."},box:{label:"Box label (62 × 29 mm)",hint:"Single label per page; sized for Brother PT/QL and Dymo small labels."},averyL7160:{label:"Avery L7160 — A4 sheet (38.1 × 63.5 mm × 21)",hint:"EU sheet stock; 21 labels per A4 page."},avery5160:{label:"Avery 5160 — US Letter sheet (25.4 × 66.7 mm × 30)",hint:"US sheet stock; 30 labels per Letter page."}}},addSpool:"Add Spool",editSpool:"Edit Spool",copySpool:"Copy Spool",material:"Material",selectMaterial:"Select material...",subtype:"Subtype",brand:"Brand",searchBrand:"Search brand...",useCustomBrand:'Use "{{brand}}"',useCustomMaterial:"Use custom material: {{material}}",colorName:"Color Name",colorNamePlaceholder:"Jade White, Fire Red...",color:"Color",hexColor:"Hex Color",pickColor:"Pick custom color",labelWeight:"Label Weight",coreWeight:"Empty Spool Weight",searchSpoolWeight:"Search spool weight...",weightUsed:"Used",currentWeight:"Remaining Weight",measuredWeight:"Measured Weight",spoolName:"Spool",costPerKg:"Cost per kg",storageLocation:"Storage Location",storageLocationPlaceholder:"e.g. Shelf A, Drawer 1",openInInventory:"Open in Inventory",measuredWeightError:"Measured weight must be between {{min}}g and {{max}}g.",slicerFilament:"Slicer Filament",slicerFilamentName:"Slicer Preset Name",slicerPreset:"Slicer Preset",searchPresets:"Search filament presets...",selectedPreset:"Selected",noPresetsFound:"No presets found",tempOverrides:"Temperature Overrides",note:"Note",notePlaceholder:"Any additional notes about this spool...",category:"Category",categoryPlaceholder:"e.g. Production, Prototype, Client A",categoryNone:"Uncategorized",storageLocationNone:"No location set",lowStockThresholdOverride:"Low-stock threshold (this spool)",lowStockThresholdOverrideHelp:"Leave blank to use the global threshold ({{global}}%).",clearRfid:"Clear RFID Tag",rfidCleared:"RFID tag cleared",archive:"Archive",restore:"Restore",noSpools:"No spools yet. Add your first spool to get started.",noAvailableSpools:"No spools available. Add a spool to your inventory or unassign one from another slot first.",kProfiles:"K-Profiles",addKProfile:"Add K-Profile",assignSpool:"Assign Spool",unassignSpool:"Unassign",assignSuccess:"Spool assigned and AMS slot configured",assignFailed:"Failed to assign spool",selectSpool:"Select a spool to assign to this slot",assigned:"Assigned",assigning:"Assigning...",searchSpools:"Search spools...",showAllSpools:"Show all spools",spoolmanSpools:"Spoolman Spools",allMaterials:"All Materials",filterByBrand:"Filter by brand...",showArchived:"Show archived",quickAdd:"Quick Add (Stock)",quantity:"Quantity",stock:"Stock",configured:"Configured",spoolsCreated:"{{count}} spools created",spoolsPartiallyCreated:"{{created}} of {{total}} spools created (some failed)",spoolCreated:"Spool created",spoolUpdated:"Spool updated",spoolDeleted:"Spool deleted",deepLinkSpoolNotFound:"Spool not found",deepLinkFetchFailed:"Could not load spool — try again",spoolArchived:"Spool archived",spoolRestored:"Spool restored",kProfileSaveFailed:"K-profile settings could not be saved",syncWeightSpoolNotFound:"Spool not found — it may have been deleted",syncWeightSpoolmanUnreachable:"Spoolman is unreachable — try again later",syncWeightFailed:"Failed to sync weight",spoolmanUnreachable:"Spoolman is not reachable — please try again later",deleteSpoolNotFound:"Spool not found — it may have already been deleted",deleteFailed:"Failed to delete spool",archiveSpoolNotFound:"Spool not found — it may have already been deleted",archiveFailed:"Failed to archive spool",restoreSpoolNotFound:"Spool not found — it may have already been deleted",restoreFailed:"Failed to restore spool",saveFailed:"Failed to save changes",tagClearFailed:"Failed to clear tag",deleteConfirm:"Are you sure you want to delete this spool? This cannot be undone.",archiveConfirm:"Are you sure you want to archive this spool?",advancedSettings:"Advanced Settings",filamentInfoTab:"Filament Info",paProfileTab:"PA Profile",filamentInfo:"Filament",additional:"Additional",loadingPresets:"Loading cloud presets...",cloudConnected:"Cloud connected",cloudNotConnected:"Cloud not connected (using defaults)",recentColors:"Recent",searchColors:"Search colors...",searchResults:"Search results",allColors:"All colors",commonColors:"Common colors",showLess:"Show less",showAll:"Show all",noColorsFound:"No colors match your search",noResults:"No matches found",extraColorsLabel:"Extra colors",extraColorsPlaceholder:"EC984C,#6CD4BC,A66EB9,D87694",extraColorsHint:"Paste 2 to 8 hex stops, separated by commas. Renders as a gradient.",extraColorsInvalid:"Ignored invalid hex: {{tokens}}",colorEffectLabel:"Effect",colorEffect:{none:"None",sparkle:"Sparkle",wood:"Wood",marble:"Marble",glow:"Glow",matte:"Matte",silk:"Silk",galaxy:"Galaxy",rainbow:"Rainbow",metal:"Metal",translucent:"Translucent",gradient:"Gradient",dualColor:"Dual Color",triColor:"Tri Color",multicolor:"Multicolor"},selectMaterialFirst:"Please select a material first in the Filament Info tab.",noPrintersConfigured:"No printers configured. Add printers to use PA profiles.",matchingFilter:"Matching",anyBrand:"Any brand",anyVariant:"Any variant",autoSelect:"Auto-select",matches:"matches",match:"match",noMatches:"No matches",connected:"Connected",offline:"Offline",printerOffline:"Printer is offline. Connect to view calibration profiles.",noKProfilesMatch:"No K-profiles match the selected filament.",leftNozzle:"Left Nozzle",rightNozzle:"Right Nozzle",profilesSelected:"calibration profile(s) selected",totalInventory:"Total Inventory",totalConsumed:"Total Consumed",byMaterial:"By Material",inPrinter:"In Printer",lowStock:"Low Stock",sinceTracking:"Since tracking started",loadedInAms:"Loaded in AMS/Ext",remaining:"Remaining",weightCheck:"Weight Check",lastWeighed:"Last weighed",neverWeighed:"Never weighed",search:"Search spools...",showing:"Showing",to:"to",of:"of",show:"Show",spools:"spools",spool:"spool",page:"Page",noSpoolsMatch:"No results found",noSpoolsMatchDesc:"Try adjusting your search or filters to find what you're looking for.",active:"Active",archived:"Archived",all:"All",used:"Used",new:"New",clearFilters:"Clear filters",table:"Table",cards:"Cards",net:"Net",groupSimilar:"Group",groupedSpools:"{{count}} identical spools",groupedRows:"rows",columns:"Columns",configureColumns:"Configure Columns",configureColumnsDesc:"Drag to reorder columns or use arrows. Toggle visibility with the eye icon.",visible:"visible",reset:"Reset",cancel:"Cancel",applyChanges:"Apply Changes",moveUp:"Move up",moveDown:"Move down",hideColumn:"Hide column",showColumn:"Show column",linkToSpool:"Link to Spool",tagLinked:"Tag linked to spool",tagLinkFailed:"Failed to link tag",tagAlreadyLinked:"Tag already linked to another spool",unknownTag:"Unknown RFID tag detected",usageHistory:"Usage History",noUsageHistory:"No usage recorded yet",printName:"Print Name",weightConsumed:"Weight Consumed",clearHistory:"Clear",historyCleared:"Usage history cleared",fillSourceLabel:"(Inv)",lowStockThresholdError:"Threshold must be between 0.1 and 99.9",assignMismatchTitle:"Material mismatch",assignMismatchMessage:'The selected spool material "{{spoolMaterial}}" does not match the tray material "{{trayMaterial}}" for {{location}}. Assign anyway?',assignMismatchConfirm:"Assign Anyway",assignPartialMismatchMessage:'The spool material "{{spoolMaterial}}" is similar to but not exactly matching "{{trayMaterial}}" in {{location}}. Do you want to proceed?',assignProfileMismatchMessage:'The spool profile "{{spoolProfile}}" does not match the tray profile "{{trayProfile}}" in {{location}}. Do you want to proceed?',spoolmanFilamentCatalog:"Spoolman Filament Catalog",pickFromSpoolmanCatalog:"Pick from Spoolman catalog…",spoolmanFilamentSelected:"Filament selected from Spoolman catalog",spoolmanFilamentUnlinked:"Filament catalog link cleared",noSpoolmanFilaments:"No filaments found in Spoolman catalog",spoolmanFilamentColorSwatch:"Filament color",spoolWeightManagedBySpoolman:"Empty spool weight is managed per filament type in Spoolman",spoolmanCatalogLoadFailed:"Failed to load Spoolman filament catalog"},timelapse:{title:"Timelapse",create:"Create Timelapse",download:"Download",delete:"Delete",preview:"Preview",frameRate:"Frame Rate",quality:"Quality",processing:"Processing...",noTimelapses:"No timelapses available"},ams:{title:"AMS",slot:"Slot",empty:"Empty",emptySlot:"Empty slot",unknown:"Unknown",humidity:"Humidity",temperature:"Temperature",filamentType:"Filament Type",filamentColor:"Color",remaining:"Remaining",history:"AMS History",noHistory:"No history available",configureSlot:"Configure Slot",externalSpool:"External Spool",profile:"Profile",kFactor:"K Factor",fill:"Fill",configure:"Configure",used:"used",remainingUnit:"remaining"},printModal:{title:"Start Print",selectPrinter:"Select Printer",selectPlate:"Select Plate",filamentMapping:"Filament Mapping",totalCost:"Total cost:",slotRemainingShort:" - {{grams}}g left",printSettings:"Print Settings",bedLeveling:"Bed Leveling",flowCalibration:"Flow Calibration",vibrationCalibration:"Vibration Calibration",layerInspection:"First Layer Inspection",timelapse:"Timelapse",startPrint:"Start Print",addToQueue:"Add to Queue",cancel:"Cancel",noPrintersAvailable:"No printers available",printerBusy:"Printer is busy",printerOffline:"Printer is offline",sameTypeDifferentColor:"Same type, different color",filamentTypeNotLoaded:"Filament type not loaded",openCalendar:"Open calendar",leftNozzle:"L",rightNozzle:"R",leftNozzleTooltip:"Left nozzle",rightNozzleTooltip:"Right nozzle",filamentOverride:"Filament Override",filamentOverrideHint:"Optionally override filaments for model-based assignment. The scheduler will match against your selected filaments instead of the original 3MF values.",originalFilament:"Original",overrideWith:"Override with",resetToOriginal:"Reset to original",insufficientFilamentTitle:"Not enough filament",insufficientFilamentMessage:"Some assigned spools have less filament remaining than this print needs:",insufficientFilamentLine:"{{printer}} - {{slot}}: needs {{required}}g, remaining {{remaining}}g",printAnyway:"Print anyway",forceColorMatch:"Force color match",staggerPrinterStarts:"Stagger printer starts",staggerGroupSize:"Group size",staggerInterval:"Interval (min)",staggerPreview:"{{printers}} printers → {{groups}} groups of {{size}}, starting every {{interval}} min",staggerLastGroup:"last group: {{count}}",staggerTotal:"total: {{minutes}} min",staggerToPrinters:"Stagger to {{count}} printers",gcodeInjection:"Inject auto-print G-code"},backup:{includesEncryptionKey:"Local backups include the MFA encryption key file (DATA_DIR/.mfa_encryption_key) so a backup ZIP is self-contained. Treat the ZIP as sensitive — anyone with the file can decrypt the OIDC client secrets and TOTP secrets stored inside.",title:"Backup & Restore",createBackup:"Create Backup",restoreBackup:"Restore Backup",restoreDescription:"Replace all data from a backup file",downloadBackup:"Download Backup",uploadBackup:"Upload Backup",lastBackup:"Last Backup",autoBackup:"Auto Backup",backupNow:"Backup Now",restoreWarning:"Warning: Restoring a backup will overwrite all current data.",includeArchives:"Include Archives",includeSettings:"Include Settings",includeProfiles:"Include Profiles",backupSuccess:"Backup created successfully",restoreSuccess:"Backup restored successfully",backupFailed:"Backup failed",restoreFailed:"Restore failed",restoreNote:"Virtual Printer will be stopped during restore",githubBackup:"Git Backup",enabled:"Enabled",cloudLoginRequired:"Bambu Cloud login required. Sign in under Profiles → Cloud Profiles to enable GitHub backup.",cloudLoginRequiredShort:"Cloud login required",githubDescription:"Automatically sync your profiles to a private GitHub repository for backup and version history.",repositoryUrl:"Repository URL",repoUrlPlaceholderGitHub:"https://github.com/username/repo-name",repoUrlPlaceholderGitea:"https://gitea.example.com/username/repo-name",repoUrlPlaceholderForgejo:"https://forgejo.example.com/username/repo-name",repoUrlPlaceholderGitLab:"https://gitlab.com/username/repo-name",allowInsecureHttp:"Allow insecure HTTP",allowInsecureHttpHint:"Enable for self-hosted instances on private networks without TLS",personalAccessToken:"Personal Access Token",tokenSaved:"(saved)",enterNewToken:"Enter new token to update",tokenHint:"Fine-grained token with Contents read/write permission",branch:"Branch",provider:"Git Provider",providerGitHub:"GitHub",providerGitLab:"GitLab",providerGitea:"Gitea",providerForgejo:"Forgejo",manualOnly:"Manual only",hourly:"Hourly",daily:"Daily",weekly:"Weekly",includeInBackup:"Include in backup",kProfiles:"K-Profiles",kProfilesDescription:"Pressure advance calibration from connected printers",noPrintersConnected:"No printers connected",printersConnected:"{{connected}}/{{total}} connected",cloudProfiles:"Cloud Profiles",cloudProfilesDescription:"Filament, printer, and process presets from Bambu Cloud",appSettings:"App Settings",appSettingsDescription:"Bambuddy configuration (complete database)",spoolInventory:"Spool Inventory",spoolInventoryDescription:"Filament spools, usage history, and cost tracking",printArchives:"Print Archives",printArchivesDescription:"Print history metadata (no gcode/3MF files)",lastBackupAt:"Last backup:",noBackupsYet:"No backups yet",next:"Next:",startingBackup:"Starting backup...",test:"Test",enableBackup:"Enable Backup",testConnection:"Test Connection",enterRepoUrl:"Enter repository URL",enterRepoAndToken:"Enter repository URL and access token",repoRequired:"Repository URL is required",tokenRequired:"Access token is required",githubBackupEnabled:"GitHub backup enabled",tokenUpdated:"Token updated",settingsSaved:"Settings saved",failedToSave:"Failed to save: {{message}}",backupCompleteFiles:"Backup complete - {{count}} files updated",backupSkippedNoChanges:"Backup skipped - no changes",backupFailed2:"Backup failed: {{message}}",clearedLogs:"Cleared {{count}} logs",failedToClearLogs:"Failed to clear logs: {{message}}",history:"History",clear:"Clear",date:"Date",status:"Status",commit:"Commit",localBackup:"Local Backup",localBackupDescription:"Create a complete backup of your Bambuddy data including the database, archives, uploads, and all files.",downloadBackupLabel:"Download Backup",completeBackupZip:"Complete backup: database + all files (ZIP)",download:"Download",preparingBackup:"Preparing backup...",creatingArchive:"Creating backup archive... This may take a while for large archives.",downloadingFile:"Downloading backup file...",backupDownloaded:"Backup downloaded successfully",failedToCreateBackup:"Failed to create backup: {{message}}",restore:"Restore",restoreReplacesAll:"Restore replaces all data.",restoreReplacesAllDetail:"Your current database and files will be completely replaced. A restart is required after restore.",restoreConfirmTitle:"Restore Backup",restoreConfirmMessage:'Are you sure you want to restore from "{{filename}}"? This will completely replace your current database and all files. The application will need to be restarted after restore.',restoreConfirmButton:"Restore Backup",uploadingFile:"Uploading backup file...",backupRestoredRestart:"Backup restored. Please restart Bambuddy.",failedToRestore:"Failed to restore backup. Please check the file format.",reloadNow:"Reload Now",creatingBackup:"Creating Backup",restoringBackup:"Restoring Backup",preparing:"Preparing...",processing:"Processing...",doNotClosePage:"Please do not close this page or navigate away. This operation may take several minutes for large backups.",restoring:"Restoring...",restoreComplete:"Restore Complete",restoreFailed2:"Restore Failed",importSettings:"Import settings from a backup file",pleaseWaitRestoring:"Please wait while your data is being restored",selectBackupFile:"Click to select backup file (.json or .zip)",duplicateHandling:"How duplicate handling works:",matchPrinters:"Printers",matchPrintersBy:"matched by serial number",matchSmartPlugs:"Smart Plugs",matchSmartPlugsBy:"matched by IP address",matchNotificationProviders:"Notification Providers",matchNotificationProvidersBy:"matched by name",matchFilaments:"Filaments",matchFilamentsBy:"matched by name + type + brand",matchArchives:"Archives",matchArchivesBy:"matched by content hash (always skipped)",matchPendingUploads:"Pending Uploads",matchPendingUploadsBy:"matched by filename",matchSettingsTemplates:"Settings & Templates",matchSettingsTemplatesBy:"always overwritten",replaceExisting:"Replace existing data",keepExisting:"Keep existing data",overwriteDescription:"Overwrite items that already exist with backup data",keepDescription:"Only restore items that don't already exist",overwriteCaution:"Caution:",overwriteWarning:"Overwriting will replace your current configurations with data from the backup. Printer access codes are never overwritten for security.",cancel:"Cancel",processingBackup:"Processing backup file...",itemsRestored:"Items Restored",itemsSkipped:"Items Skipped",restored:"Restored",skippedAlreadyExist:"Skipped (already exist)",filesCategory:"Files (3MF, thumbnails, etc.)",andMore:"...and {{count}} more",newApiKeysGenerated:"New API Keys Generated",keysShownOnce:"These keys are only shown once. Copy them now!",copy:"Copy",noDataFound:"No data was found to restore in the backup file.",close:"Close",scheduledBackup:"Scheduled Backups",scheduledBackupDescription:"Automatically create backup snapshots on a schedule. Output directory can be mounted to a NAS or external storage.",frequency:"Frequency",backupTime:"Time",retention:"Retention",retentionDescription:"Number of backups to keep",outputPath:"Output Path",outputPathPlaceholder:"Default: {{path}}",outputPathDescription:"Leave empty for default location",runNow:"Run Now",backupFiles:"Backup Files",noScheduledBackups:"No backups yet",deleteBackup:"Delete",deleteBackupConfirm:"Delete this backup file?",backupRunning:"Backup in progress...",scheduledBackupComplete:"Backup completed successfully",scheduledBackupFailed:"Backup failed",nextBackup:"Next backup",backupSize:"Size",utc:"UTC",defaultPathLabel:"Default:",categories:{settings:"Settings",notification_providers:"Notification Providers",notification_templates:"Notification Templates",smart_plugs:"Smart Plugs",printers:"Printers",filaments:"Filaments",maintenance_types:"Maintenance Types",archives:"Archives",projects:"Projects",pending_uploads:"Pending Uploads",external_links:"External Links",api_keys:"API Keys"}},tags:{title:"Tags",addTag:"Add Tag",editTag:"Edit Tag",deleteTag:"Delete Tag",tagName:"Tag Name",tagColor:"Tag Color",noTags:"No tags",deleteConfirm:"Are you sure you want to delete this tag?",manageTags:"Manage Tags"},uploadModal:{title:"Upload 3MF Files",dragDrop:"Drag & drop .3mf files here",or:"or",browseFiles:"Browse Files",extractionInfo:"The printer model will be automatically extracted from the 3MF file metadata.",uploaded:"uploaded",failed:"failed",uploading:"Uploading...",upload:"Upload",uploadFailed:"Upload failed"},editArchive:{title:"Edit Archive",name:"Name",namePlaceholder:"Print name",printer:"Printer",noPrinter:"No printer",project:"Project",noProject:"No project",itemsPrinted:"Items Printed",itemsPrintedHelp:"Number of items produced in this print job",notes:"Notes",notesPlaceholder:"Add notes about this print...",externalLink:"External Link",externalLinkPlaceholder:"https://printables.com/model/...",externalLinkHelp:"Link to Printables, Thingiverse, or other source",tags:"Tags",tagsPlaceholder:"Add tags...",addMoreTags:"Add more tags...",matchingTags:'Matching "{{query}}"',existingTags:"Existing tags",clickToAdd:"(click to add)",status:"Status",failureReason:"Failure Reason",selectReason:"Select reason...",photos:"Photos of Printed Result",photosHelp:"Click + to add photos of your printed result",printResult:"Print result",saving:"Saving...",failureReasons:{adhesionFailure:"Adhesion failure",spaghettiDetached:"Spaghetti / Detached",layerShift:"Layer shift",cloggedNozzle:"Clogged nozzle",filamentRunout:"Filament runout",warping:"Warping",stringing:"Stringing",underExtrusion:"Under-extrusion",powerFailure:"Power failure",userCancelled:"User cancelled",other:"Other"},statuses:{completed:"Completed",failed:"Failed",aborted:"Cancelled",printing:"Printing"}},kProfiles:{title:"K-Profiles",noPrintersConfigured:"No Printers Configured",addPrinterInSettings:"Add a printer in Settings to manage K-profiles",noActivePrinters:"No Active Printers",enablePrinterConnection:"Enable a printer connection to view its K-profiles",loadingProfiles:"Loading K-Profiles...",printerOffline:"Printer Offline",printerOfflineDesc:"The selected printer is not connected. Power it on to view K-profiles.",noMatchingProfiles:"No Matching Profiles",noMatchingProfilesDesc:"No profiles match your search criteria",noKProfiles:"No K-Profiles",noKProfilesDesc:"No pressure advance profiles found for {{diameter}}mm nozzle",createFirstProfile:"Create First Profile",printer:"Printer",nozzle:"Nozzle",refresh:"Refresh",addProfile:"Add Profile",export:"Export",import:"Import",select:"Select",selectAll:"Select All",delete:"Delete",searchPlaceholder:"Search by name or filament...",allExtruders:"All Extruders",leftOnly:"Left Only",rightOnly:"Right Only",allFlow:"All Flow",hfOnly:"HF Only",sOnly:"S Only",sortName:"Sort: Name",sortKValue:"Sort: K-Value",sortFilament:"Sort: Filament",leftExtruder:"Left Extruder",rightExtruder:"Right Extruder",modal:{addTitle:"Add K-Profile",editTitle:"Edit K-Profile",profileName:"Profile Name",profileNamePlaceholder:"My PLA Profile",kValue:"K-Value",kValuePlaceholder:"0.020",kValueHelp:"Typical range: 0.01 - 0.06 for PLA, 0.02 - 0.10 for PETG",filament:"Filament",selectFilament:"Select filament...",noFilamentsHelp:"No filaments found. Create a K-profile in Bambu Studio first.",flowType:"Flow Type",highFlow:"High Flow",standard:"Standard",nozzleSize:"Nozzle Size",extruder:"Extruder",extruders:"Extruders",left:"Left",right:"Right",notes:"Notes (stored locally)",notesPlaceholder:"Add notes about this profile...",notesHelp:"Notes are saved in Bambuddy, not on the printer",syncing:"Syncing with printer...",savingExtruder:"Saving to extruder {{current}}/{{total}}...",pleaseWait:"Please wait"},deleteConfirm:{title:"Delete Profile",cannotUndo:"This cannot be undone",message:'Are you sure you want to delete "{{name}}" from the printer?'},bulkDelete:{title:"Delete Profiles",cannotUndo:"This cannot be undone",message:"Are you sure you want to delete {{count}} selected profiles from the printer?"},toast:{profileSaved:"K-profile saved",profilesSaved:"K-profile saved to {{count}} extruders",selectAtLeastOneExtruder:"Please select at least one extruder",profileDeleted:"K-profile deleted",profilesDeleted:"Deleted {{count}} profiles",exportedProfiles:"Exported {{count}} profiles",importedProfiles:"Imported {{count}} of {{total}} profiles",noProfilesToExport:"No profiles to export",invalidFileFormat:"Invalid file format",failedToParseImport:"Failed to parse import file",failedToSaveBatch:"Failed to save K-profiles",noteSaved:"Note saved",failedToSaveNote:"Failed to save note"},permission:{noRead:"You do not have permission to refresh profiles",noCreate:"You do not have permission to add profiles",noUpdate:"You do not have permission to update K-profiles",noDelete:"You do not have permission to delete K-profiles",noExport:"You do not have permission to export profiles",noImport:"You do not have permission to import profiles"}},virtualPrinter:{title:"Virtual Printer",running:"Running",stopped:"Stopped",description:{default:"Enable a virtual printer that appears in Bambu Studio and OrcaSlicer. Files sent to this printer will be archived directly without printing.",proxy:"Enable a proxy that relays slicer traffic to a real printer, allowing remote printing over any network."},enable:{title:"Enable Virtual Printer",visibleInSlicer:'Visible as "Bambuddy" in slicer discovery',proxyingTo:"Proxying to {{name}}",notActive:"Not active"},model:{title:"Printer Model",description:"Select which printer model to emulate.",restartWarning:"Changing the model will restart the virtual printer"},accessCode:{title:"Access Code",isSet:"Access code is set",notSet:"No access code set - required to enable",placeholder:"Enter 8-char code",placeholderChange:"Enter new code to change",hint:"Must be exactly 8 characters. Used by slicers to authenticate.",charCount:"({{count}}/8)"},targetPrinter:{title:"Target Printer",configured:"Proxy target configured",notConfigured:"No target printer selected - required for proxy mode",placeholder:"Select a printer...",hint:"Select the printer to proxy slicer traffic to. The printer must be in LAN mode.",noPrinters:"No printers configured. Add a printer first to use proxy mode."},remoteInterface:{title:"Network Interface Override",configured:"Interface override active",optional:"Optional - use if auto-detected IP is wrong (e.g. multiple NICs, Docker, VPN)",placeholder:"Auto-detect (default)...",hint:"Override the IP address advertised via SSDP and used in the TLS certificate. Useful when Bambuddy has multiple network interfaces."},mode:{title:"Mode",archive:"Archive",archiveDesc:"Archive files immediately",review:"Review",reviewDesc:"Review before archiving",queue:"Queue",queueDesc:"Archive and add to queue",proxy:"Proxy",proxyDesc:"Relay to real printer"},autoDispatch:{title:"Auto-dispatch",description:"Automatically start prints when added to queue. When off, prints wait for manual dispatch."},queueForceColorMatch:{title:"Force color match",description:"Refuse to dispatch onto a printer that does not have the exact filament type and color loaded. Off by default — without this, the queue uses model-only matching and may pick a printer with the wrong color loaded."},tailscaleDisabled:{title:"Tailscale integration",description:"Enable to mark this VP as exposed over Tailscale. Shows the host's Tailscale address so you know which IP to paste into the slicer. The CA-import step is unchanged — this toggle has no effect on certificates."},setupRequired:{title:"Setup Required",description:"The virtual printer feature requires additional system configuration before it will work. This includes port forwarding, firewall rules, and platform-specific settings.",readGuide:"Read the setup guide before enabling"},archiveNameSource:{title:"Archive name source",description:'Choose how new archives are named when files arrive via the virtual printer. "Metadata" uses the slicer-embedded title from the 3MF (default). "Filename" uses the filename Bambu Studio sent over FTP — handy if you renamed the job in the "send to printer" dialog.',metadata:"Metadata",filename:"Filename"},howItWorks:{title:"How it works",step1:"On the same LAN, virtual printers appear in your slicer (Bambu Studio / OrcaSlicer) automatically via discovery. From other networks, add them manually by IP address and access code.",step2:'In Archive, Review, and Queue modes, use the "Send" button in your slicer to upload 3MF files to Bambuddy. The slicer will show "Print success" — the file is stored, not printed.',step3:"In Proxy mode, the virtual printer relays all traffic to a real printer — prints start immediately as if connected directly."},status:{title:"Status Details",printerName:"Printer Name",model:"Model",serialNumber:"Serial Number",mode:"Mode",pendingFiles:"Pending Files",targetPrinter:"Target Printer",ftpPort:"FTP Port",mqttPort:"MQTT Port",ftpConnections:"FTP Connections",mqttConnections:"MQTT Connections"},toast:{updated:"Virtual printer settings updated",failedToUpdate:"Failed to update settings",copyFailed:"Failed to copy — try selecting the text manually",accessCodeRequired:"Please set an access code first",targetPrinterRequired:"Please select a target printer first",bindIpRequired:"Please set a bind IP first",accessCodeEmpty:"Access code cannot be empty",accessCodeLength:"Access code must be exactly 8 characters",created:"Virtual printer created",failedToCreate:"Failed to create virtual printer",deleted:"Virtual printer deleted",failedToDelete:"Failed to delete virtual printer"},list:{title:"Virtual Printers",add:"Add",addFirst:"Add Virtual Printer",empty:"No virtual printers configured. Add one to get started."},bindIp:{title:"Bind Interface",placeholder:"Select interface...",hint:"Network interface for this virtual printer to bind to. Must be unique per printer."},proxy:{accessCodeHint:"In proxy mode, use your target printer's access code in the slicer. The connection is forwarded transparently to the real printer."},addDialog:{title:"Add Virtual Printer",name:"Name",hint:"You can configure access code, target printer, and other settings after creating.",create:"Create"},deleteConfirm:{title:"Delete Virtual Printer",message:'Are you sure you want to delete "{{name}}"? This will stop all services for this printer.'}},modelViewer:{openInSlicer:"Open in Slicer",tabs:{model:"3D Model",gcode:"G-code Preview"},notAvailable:"not available",notSliced:"not sliced",plates:"Plates",allPlates:"All Plates",plateNumber:"Plate {{number}}",plateCount:"{{count}} plate",plateCount_other:"{{count}} plates",objectCount:"{{count}} object",objectCount_other:"{{count}} objects",filamentCount:"{{count}} filament",filamentCount_other:"{{count}} filaments",eta:"ETA {{minutes}} min",noPreview:"No preview available for this file",pagination:{pageOf:"Page {{current}} of {{total}}",prev:"Prev",next:"Next"},errors:{failedToLoad:"Failed to load file",noMeshes:"No meshes found in 3MF file",unsupportedFormat:"Unsupported file format"}},maintenanceDescriptions:{lubricateCarbonRods:"Apply lubricant to carbon rods for smooth motion",lubricateRails:"Apply lubricant to linear rails for smooth motion",cleanNozzle:"Clean hotend and nozzle to prevent clogs",checkBelts:"Verify belt tension for accurate prints",cleanBuildPlate:"Clean build plate for better adhesion",checkExtruder:"Inspect extruder gears for wear",checkCooling:"Ensure cooling fans are working properly",generalInspection:"General printer inspection",cleanCarbonRods:"Clean carbon rods to reduce friction",lubricateSteelRods:"Apply lubricant to steel rods for smooth motion",cleanSteelRods:"Clean steel rods to reduce friction",cleanLinearRails:"Wipe linear rails to remove dust and debris",checkPtfeTube:"Inspect PTFE tube for wear or damage",replaceHepaFilter:"Replace HEPA filter for air quality",replaceCarbonFilter:"Replace activated carbon filter",lubricateLeftNozzleRail:"Lubricate left nozzle rail (H2 series)"},smartPlugs:{offline:"Offline",admin:"Admin",openPlugAdminPage:"Open plug admin page",deleteSmartPlug:"Delete Smart Plug",turnOnSmartPlug:"Turn On Smart Plug",turnOffSmartPlug:"Turn Off Smart Plug",turnOn:"Turn On",turnOff:"Turn Off",addSmartPlug:{scanningNetwork:"Scanning network...",chooseEntity:"Choose an entity...",connectionFailed:"Connection failed",searchEntities:"Search entities...",searchPowerSensors:"Search power sensors...",searchEnergySensors:"Search energy sensors...",placeholders:{plugName:"Living Room Plug",mqttStateOnValue:"ON, true, 1",mqttSameAsPower:"Same as power topic, or different"}},linkedTo:"Linked to:",monitorOnly:"Monitor Only",alerts:"Alerts",scheduleOn:"On {{time}}",scheduleOff:"Off {{time}}",on:"On",off:"Off",power:"Power",kwhToday:"kWh Today",settings:"Settings",automationSettings:"Automation Settings",showInSwitchbar:"Show in Switchbar",quickAccessSidebar:"Quick access from sidebar",enabled:"Enabled",enableAutomation:"Enable automation for this plug",autoOn:"Auto On",autoOnDescription:"Turn on when print starts",autoOff:"Auto Off",autoOffDescription:"Turn off when print completes (one-shot)",autoOffPersistent:"Keep Enabled",autoOffPersistentDescription:"Stay enabled between prints instead of one-shot",autoOffAfterDrying:"Auto Off After Drying",autoOffAfterDryingDescription:"Turn off when AMS drying completes",delayAfterDryingMinutes:"Drying delay (minutes)",turnOffDelayMode:"Turn Off Delay Mode",time:"Time",temp:"Temp",delayMinutes:"Delay (minutes)",tempThreshold:"Temperature threshold (°C)",tempThresholdDescription:"Turns off when nozzle cools below this temperature",edit:"Edit",deleteConfirm:'Are you sure you want to delete "{{name}}"? This cannot be undone.',turnOnConfirm:'Are you sure you want to turn on "{{name}}"?',turnOffConfirm:'Are you sure you want to turn off "{{name}}"? This will cut power to the connected device.',failedToTurn:'Failed to turn {{action}} "{{name}}"',unknown:"Unknown",addTitle:"Add Smart Plug",editTitle:"Edit Smart Plug",stopScanning:"Stop Scanning",discoverTasmota:"Discover Tasmota Devices",foundDevices:"Found {{count}} device(s) - click to select:",noDevicesFound:"No Tasmota devices found on your network",haNotConfigured:"Home Assistant is not configured. Set it up in",haSettingsPath:"Settings → Network → Home Assistant",selectEntity:"Select Entity *",ipAddress:"IP Address *",nameLabel:"Name *",username:"Username",password:"Password",authHint:"Leave empty if your Tasmota device doesn't require authentication",linkToPrinter:"Link to Printer",noPrinter:"No printer (manual control only)",linkingDescription:"Linking enables automatic on/off when prints start/complete",powerAlerts:"Power Alerts",alertAbove:"Alert if above (W)",alertBelow:"Alert if below (W)",alertDescription:"Get notified when power consumption crosses these thresholds. Leave empty to disable that direction.",dailySchedule:"Daily Schedule",turnOnAt:"Turn On at",turnOffAt:"Turn Off at",scheduleDescription:"Automatically turn the plug on/off at these times daily. Leave empty to skip that action.",showOnPrinterCard:"Show on Printer Card",displayOnPrinterCard:"Display button on printer card",connectedResult:"Connected!",deviceLabel:"Device: {{name}} - ",stateLabel:"State: {{state}}",test:"Test",delete:"Delete",save:"Save",add:"Add",cancel:"Cancel",failedToStartScan:"Failed to start scan",nameRequired:"Name is required",entityRequired:"Entity is required for Home Assistant plugs",mqttTopicRequired:"At least one MQTT topic must be configured for power, energy, or state monitoring",loadingEntities:"Loading entities...",loading:"Loading...",failedToLoadEntities:"Failed to load entities: {{error}}",noEntitiesMatching:'No entities found matching "{{search}}"',noEntitiesAvailable:"No entities available",searchingEntities:"Searching all entities ({{count}} found)",showingEntities:"Showing switch, light, input_boolean ({{count}} available)",energyMonitoringOptional:"Energy Monitoring (Optional)",energyMonitoringHint:"Search and select sensors that provide power/energy data.",powerSensorW:"Power Sensor (W)",energyTodayKwh:"Energy Today (kWh)",totalEnergyKwh:"Total Energy (kWh)",noMatchingSensors:"No matching sensors",none:"None",mqttNotConfigured:"MQTT broker not configured. Set broker address in",mqttSettingsPath:"Settings → Network → MQTT Publishing",mqttNotConfiguredSuffix:"(you don't need to enable publishing, just fill in the broker details).",mqttMonitorOnlyDescription:"MQTT plugs receive power/energy data via MQTT subscription. On/off control is not available - use your MQTT broker or home automation system.",powerMonitoring:"Power Monitoring",energyMonitoring:"Energy Monitoring",stateMonitoring:"State Monitoring",optional:"optional",topic:"Topic",jsonPath:"JSON Path",multiplier:"Multiplier",onValue:"ON Value",mqttPowerHint:`JSON path extracts value from JSON payload (e.g., "power_l1"). Leave empty if topic publishes raw numeric values. +`);for(V=M=0;MV||ht[M]!==jt[V]){var Bt=` +`+ht[M].replace(" at new "," at ");return h.displayName&&Bt.includes("")&&(Bt=Bt.replace("",h.displayName)),Bt}while(1<=M&&0<=V);break}}}finally{G=!1,Error.prepareStackTrace=k}return(k=h?h.displayName||h.name:"")?z(k):""}function Z(h,v){switch(h.tag){case 26:case 27:case 5:return z(h.type);case 16:return z("Lazy");case 13:return h.child!==v&&v!==null?z("Suspense Fallback"):z("Suspense");case 19:return z("SuspenseList");case 0:case 15:return Q(h.type,!1);case 11:return Q(h.type.render,!1);case 1:return Q(h.type,!0);case 31:return z("Activity");default:return""}}function oe(h){try{var v="",k=null;do v+=Z(h,k),k=h,h=h.return;while(h);return v}catch(M){return` +Error generating stack: `+M.message+` +`+M.stack}}var te=Object.prototype.hasOwnProperty,fe=t.unstable_scheduleCallback,ce=t.unstable_cancelCallback,pe=t.unstable_shouldYield,q=t.unstable_requestPaint,L=t.unstable_now,re=t.unstable_getCurrentPriorityLevel,be=t.unstable_ImmediatePriority,ve=t.unstable_UserBlockingPriority,Ce=t.unstable_NormalPriority,xe=t.unstable_LowPriority,ge=t.unstable_IdlePriority,De=t.log,Oe=t.unstable_setDisableYieldValue,Ie=null,Be=null;function ze(h){if(typeof De=="function"&&Oe(h),Be&&typeof Be.setStrictMode=="function")try{Be.setStrictMode(Ie,h)}catch{}}var We=Math.clz32?Math.clz32:Fe,He=Math.log,st=Math.LN2;function Fe(h){return h>>>=0,h===0?32:31-(He(h)/st|0)|0}var tt=256,ke=262144,Ye=4194304;function Ue(h){var v=h&42;if(v!==0)return v;switch(h&-h){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return h&261888;case 262144:case 524288:case 1048576:case 2097152:return h&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return h&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return h}}function _e(h,v,k){var M=h.pendingLanes;if(M===0)return 0;var V=0,ee=h.suspendedLanes,we=h.pingedLanes;h=h.warmLanes;var qe=M&134217727;return qe!==0?(M=qe&~ee,M!==0?V=Ue(M):(we&=qe,we!==0?V=Ue(we):k||(k=qe&~h,k!==0&&(V=Ue(k))))):(qe=M&~ee,qe!==0?V=Ue(qe):we!==0?V=Ue(we):k||(k=M&~h,k!==0&&(V=Ue(k)))),V===0?0:v!==0&&v!==V&&(v&ee)===0&&(ee=V&-V,k=v&-v,ee>=k||ee===32&&(k&4194048)!==0)?v:V}function Ee(h,v){return(h.pendingLanes&~(h.suspendedLanes&~h.pingedLanes)&v)===0}function Xe(h,v){switch(h){case 1:case 2:case 4:case 8:case 64:return v+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return v+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function ot(){var h=Ye;return Ye<<=1,(Ye&62914560)===0&&(Ye=4194304),h}function Ae(h){for(var v=[],k=0;31>k;k++)v.push(h);return v}function et(h,v){h.pendingLanes|=v,v!==268435456&&(h.suspendedLanes=0,h.pingedLanes=0,h.warmLanes=0)}function ct(h,v,k,M,V,ee){var we=h.pendingLanes;h.pendingLanes=k,h.suspendedLanes=0,h.pingedLanes=0,h.warmLanes=0,h.expiredLanes&=k,h.entangledLanes&=k,h.errorRecoveryDisabledLanes&=k,h.shellSuspendCounter=0;var qe=h.entanglements,ht=h.expirationTimes,jt=h.hiddenUpdates;for(k=we&~k;0"u")return null;try{return h.activeElement||h.body}catch{return h.body}}var Er=/[\n"\\]/g;function Gn(h){return h.replace(Er,function(v){return"\\"+v.charCodeAt(0).toString(16)+" "})}function mi(h,v,k,M,V,ee,we,qe){h.name="",we!=null&&typeof we!="function"&&typeof we!="symbol"&&typeof we!="boolean"?h.type=we:h.removeAttribute("type"),v!=null?we==="number"?(v===0&&h.value===""||h.value!=v)&&(h.value=""+un(v)):h.value!==""+un(v)&&(h.value=""+un(v)):we!=="submit"&&we!=="reset"||h.removeAttribute("value"),v!=null?vr(h,we,un(v)):k!=null?vr(h,we,un(k)):M!=null&&h.removeAttribute("value"),V==null&&ee!=null&&(h.defaultChecked=!!ee),V!=null&&(h.checked=V&&typeof V!="function"&&typeof V!="symbol"),qe!=null&&typeof qe!="function"&&typeof qe!="symbol"&&typeof qe!="boolean"?h.name=""+un(qe):h.removeAttribute("name")}function Un(h,v,k,M,V,ee,we,qe){if(ee!=null&&typeof ee!="function"&&typeof ee!="symbol"&&typeof ee!="boolean"&&(h.type=ee),v!=null||k!=null){if(!(ee!=="submit"&&ee!=="reset"||v!=null)){Sn(h);return}k=k!=null?""+un(k):"",v=v!=null?""+un(v):k,qe||v===h.value||(h.value=v),h.defaultValue=v}M=M??V,M=typeof M!="function"&&typeof M!="symbol"&&!!M,h.checked=qe?h.checked:!!M,h.defaultChecked=!!M,we!=null&&typeof we!="function"&&typeof we!="symbol"&&typeof we!="boolean"&&(h.name=we),Sn(h)}function vr(h,v,k){v==="number"&&or(h.ownerDocument)===h||h.defaultValue===""+k||(h.defaultValue=""+k)}function la(h,v,k,M){if(h=h.options,v){v={};for(var V=0;V"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),qs=!1;if(Eo)try{var Lc={};Object.defineProperty(Lc,"passive",{get:function(){qs=!0}}),window.addEventListener("test",Lc,Lc),window.removeEventListener("test",Lc,Lc)}catch{qs=!1}var Ma=null,cp=null,dp=null;function pi(){if(dp)return dp;var h,v=cp,k=v.length,M,V="value"in Ma?Ma.value:Ma.textContent,ee=V.length;for(h=0;h=Fl),ye=" ",Ot=!1;function cn(h,v){switch(h){case"keyup":return xs.indexOf(v.keyCode)!==-1;case"keydown":return v.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function An(h){return h=h.detail,typeof h=="object"&&"data"in h?h.data:null}var zn=!1;function ut(h,v){switch(h){case"compositionend":return An(v);case"keypress":return v.which!==32?null:(Ot=!0,ye);case"textInput":return h=v.data,h===ye&&Ot?null:h;default:return null}}function Ht(h,v){if(zn)return h==="compositionend"||!Qi&&cn(h,v)?(h=pi(),dp=cp=Ma=null,zn=!1,h):null;switch(h){case"paste":return null;case"keypress":if(!(v.ctrlKey||v.altKey||v.metaKey)||v.ctrlKey&&v.altKey){if(v.char&&1=v)return{node:k,offset:v-h};h=M}e:{for(;k;){if(k.nextSibling){k=k.nextSibling;break e}k=k.parentNode}k=void 0}k=Yi(k)}}function Hc(h,v){return h&&v?h===v?!0:h&&h.nodeType===3?!1:v&&v.nodeType===3?Hc(h,v.parentNode):"contains"in h?h.contains(v):h.compareDocumentPosition?!!(h.compareDocumentPosition(v)&16):!1:!1}function ws(h){h=h!=null&&h.ownerDocument!=null&&h.ownerDocument.defaultView!=null?h.ownerDocument.defaultView:window;for(var v=or(h.document);v instanceof h.HTMLIFrameElement;){try{var k=typeof v.contentWindow.location.href=="string"}catch{k=!1}if(k)h=v.contentWindow;else break;v=or(h.document)}return v}function mr(h){var v=h&&h.nodeName&&h.nodeName.toLowerCase();return v&&(v==="input"&&(h.type==="text"||h.type==="search"||h.type==="tel"||h.type==="url"||h.type==="password")||v==="textarea"||h.contentEditable==="true")}var $r=Eo&&"documentMode"in document&&11>=document.documentMode,ka=null,ju=null,sn=null,fp=!1;function ca(h,v,k){var M=k.window===k?k.document:k.nodeType===9?k:k.ownerDocument;fp||ka==null||ka!==or(M)||(M=ka,"selectionStart"in M&&mr(M)?M={start:M.selectionStart,end:M.selectionEnd}:(M=(M.ownerDocument&&M.ownerDocument.defaultView||window).getSelection(),M={anchorNode:M.anchorNode,anchorOffset:M.anchorOffset,focusNode:M.focusNode,focusOffset:M.focusOffset}),sn&&Ba(sn,M)||(sn=M,M=ok(ju,"onSelect"),0>=we,V-=we,Ad=1<<32-We(v)+V|k<Jn?(Sr=Pn,Pn=null):Sr=Pn.sibling;var Lr=Et(wt,Pn,At[Jn],qt);if(Lr===null){Pn===null&&(Pn=Sr);break}h&&Pn&&Lr.alternate===null&&v(wt,Pn),yt=ee(Lr,yt,Jn),Fr===null?Fn=Lr:Fr.sibling=Lr,Fr=Lr,Pn=Sr}if(Jn===At.length)return k(wt,Pn),Cr&&Du(wt,Jn),Fn;if(Pn===null){for(;JnJn?(Sr=Pn,Pn=null):Sr=Pn.sibling;var Ip=Et(wt,Pn,Lr.value,qt);if(Ip===null){Pn===null&&(Pn=Sr);break}h&&Pn&&Ip.alternate===null&&v(wt,Pn),yt=ee(Ip,yt,Jn),Fr===null?Fn=Ip:Fr.sibling=Ip,Fr=Ip,Pn=Sr}if(Lr.done)return k(wt,Pn),Cr&&Du(wt,Jn),Fn;if(Pn===null){for(;!Lr.done;Jn++,Lr=At.next())Lr=Vt(wt,Lr.value,qt),Lr!==null&&(yt=ee(Lr,yt,Jn),Fr===null?Fn=Lr:Fr.sibling=Lr,Fr=Lr);return Cr&&Du(wt,Jn),Fn}for(Pn=M(Pn);!Lr.done;Jn++,Lr=At.next())Lr=It(Pn,wt,Jn,Lr.value,qt),Lr!==null&&(h&&Lr.alternate!==null&&Pn.delete(Lr.key===null?Jn:Lr.key),yt=ee(Lr,yt,Jn),Fr===null?Fn=Lr:Fr.sibling=Lr,Fr=Lr);return h&&Pn.forEach(function(Mue){return v(wt,Mue)}),Cr&&Du(wt,Jn),Fn}function Jr(wt,yt,At,qt){if(typeof At=="object"&&At!==null&&At.type===w&&At.key===null&&(At=At.props.children),typeof At=="object"&&At!==null){switch(At.$$typeof){case f:e:{for(var Fn=At.key;yt!==null;){if(yt.key===Fn){if(Fn=At.type,Fn===w){if(yt.tag===7){k(wt,yt.sibling),qt=V(yt,At.props.children),qt.return=wt,wt=qt;break e}}else if(yt.elementType===Fn||typeof Fn=="object"&&Fn!==null&&Fn.$$typeof===F&&Nf(Fn)===yt.type){k(wt,yt.sibling),qt=V(yt,At.props),Sv(qt,At),qt.return=wt,wt=qt;break e}k(wt,yt);break}else v(wt,yt);yt=yt.sibling}At.type===w?(qt=vf(At.props.children,wt.mode,qt,At.key),qt.return=wt,wt=qt):(qt=k_(At.type,At.key,At.props,null,wt.mode,qt),Sv(qt,At),qt.return=wt,wt=qt)}return we(wt);case g:e:{for(Fn=At.key;yt!==null;){if(yt.key===Fn)if(yt.tag===4&&yt.stateNode.containerInfo===At.containerInfo&&yt.stateNode.implementation===At.implementation){k(wt,yt.sibling),qt=V(yt,At.children||[]),qt.return=wt,wt=qt;break e}else{k(wt,yt);break}else v(wt,yt);yt=yt.sibling}qt=uj(At,wt.mode,qt),qt.return=wt,wt=qt}return we(wt);case F:return At=Nf(At),Jr(wt,yt,At,qt)}if(Y(At))return yn(wt,yt,At,qt);if(I(At)){if(Fn=I(At),typeof Fn!="function")throw Error(a(150));return At=Fn.call(At),Bn(wt,yt,At,qt)}if(typeof At.then=="function")return Jr(wt,yt,M_(At),qt);if(At.$$typeof===N)return Jr(wt,yt,P_(wt,At),qt);E_(wt,At)}return typeof At=="string"&&At!==""||typeof At=="number"||typeof At=="bigint"?(At=""+At,yt!==null&&yt.tag===6?(k(wt,yt.sibling),qt=V(yt,At),qt.return=wt,wt=qt):(k(wt,yt),qt=dj(At,wt.mode,qt),qt.return=wt,wt=qt),we(wt)):k(wt,yt)}return function(wt,yt,At,qt){try{wv=0;var Fn=Jr(wt,yt,At,qt);return jb=null,Fn}catch(Pn){if(Pn===Ab||Pn===A_)throw Pn;var Fr=il(29,Pn,null,wt.mode);return Fr.lanes=qt,Fr.return=wt,Fr}}}var Pf=TU(!0),AU=TU(!1),vp=!1;function _j(h){h.updateQueue={baseState:h.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function kj(h,v){h=h.updateQueue,v.updateQueue===h&&(v.updateQueue={baseState:h.baseState,firstBaseUpdate:h.firstBaseUpdate,lastBaseUpdate:h.lastBaseUpdate,shared:h.shared,callbacks:null})}function wp(h){return{lane:h,tag:0,payload:null,callback:null,next:null}}function Sp(h,v,k){var M=h.updateQueue;if(M===null)return null;if(M=M.shared,(zr&2)!==0){var V=M.pending;return V===null?v.next=v:(v.next=V.next,V.next=v),M.pending=v,v=__(h),mU(h,null,k),v}return S_(h,M,v,k),__(h)}function _v(h,v,k){if(v=v.updateQueue,v!==null&&(v=v.shared,(k&4194048)!==0)){var M=v.lanes;M&=h.pendingLanes,k|=M,v.lanes=k,zt(h,k)}}function Nj(h,v){var k=h.updateQueue,M=h.alternate;if(M!==null&&(M=M.updateQueue,k===M)){var V=null,ee=null;if(k=k.firstBaseUpdate,k!==null){do{var we={lane:k.lane,tag:k.tag,payload:k.payload,callback:null,next:null};ee===null?V=ee=we:ee=ee.next=we,k=k.next}while(k!==null);ee===null?V=ee=v:ee=ee.next=v}else V=ee=v;k={baseState:M.baseState,firstBaseUpdate:V,lastBaseUpdate:ee,shared:M.shared,callbacks:M.callbacks},h.updateQueue=k;return}h=k.lastBaseUpdate,h===null?k.firstBaseUpdate=v:h.next=v,k.lastBaseUpdate=v}var Cj=!1;function kv(){if(Cj){var h=Tb;if(h!==null)throw h}}function Nv(h,v,k,M){Cj=!1;var V=h.updateQueue;vp=!1;var ee=V.firstBaseUpdate,we=V.lastBaseUpdate,qe=V.shared.pending;if(qe!==null){V.shared.pending=null;var ht=qe,jt=ht.next;ht.next=null,we===null?ee=jt:we.next=jt,we=ht;var Bt=h.alternate;Bt!==null&&(Bt=Bt.updateQueue,qe=Bt.lastBaseUpdate,qe!==we&&(qe===null?Bt.firstBaseUpdate=jt:qe.next=jt,Bt.lastBaseUpdate=ht))}if(ee!==null){var Vt=V.baseState;we=0,Bt=jt=ht=null,qe=ee;do{var Et=qe.lane&-536870913,It=Et!==qe.lane;if(It?(wr&Et)===Et:(M&Et)===Et){Et!==0&&Et===Pb&&(Cj=!0),Bt!==null&&(Bt=Bt.next={lane:0,tag:qe.tag,payload:qe.payload,callback:null,next:null});e:{var yn=h,Bn=qe;Et=v;var Jr=k;switch(Bn.tag){case 1:if(yn=Bn.payload,typeof yn=="function"){Vt=yn.call(Jr,Vt,Et);break e}Vt=yn;break e;case 3:yn.flags=yn.flags&-65537|128;case 0:if(yn=Bn.payload,Et=typeof yn=="function"?yn.call(Jr,Vt,Et):yn,Et==null)break e;Vt=m({},Vt,Et);break e;case 2:vp=!0}}Et=qe.callback,Et!==null&&(h.flags|=64,It&&(h.flags|=8192),It=V.callbacks,It===null?V.callbacks=[Et]:It.push(Et))}else It={lane:Et,tag:qe.tag,payload:qe.payload,callback:qe.callback,next:null},Bt===null?(jt=Bt=It,ht=Vt):Bt=Bt.next=It,we|=Et;if(qe=qe.next,qe===null){if(qe=V.shared.pending,qe===null)break;It=qe,qe=It.next,It.next=null,V.lastBaseUpdate=It,V.shared.pending=null}}while(!0);Bt===null&&(ht=Vt),V.baseState=ht,V.firstBaseUpdate=jt,V.lastBaseUpdate=Bt,ee===null&&(V.shared.lanes=0),Pp|=we,h.lanes=we,h.memoizedState=Vt}}function jU(h,v){if(typeof h!="function")throw Error(a(191,h));h.call(v)}function MU(h,v){var k=h.callbacks;if(k!==null)for(h.callbacks=null,h=0;hee?ee:8;var we=ne.T,qe={};ne.T=qe,Vj(h,!1,v,k);try{var ht=V(),jt=ne.S;if(jt!==null&&jt(qe,ht),ht!==null&&typeof ht=="object"&&typeof ht.then=="function"){var Bt=vde(ht,M);Tv(h,v,Bt,dl(h))}else Tv(h,v,M,dl(h))}catch(Vt){Tv(h,v,{then:function(){},status:"rejected",reason:Vt},dl())}finally{J.p=ee,we!==null&&qe.types!==null&&(we.types=qe.types),ne.T=we}}function Cde(){}function qj(h,v,k,M){if(h.tag!==5)throw Error(a(476));var V=cB(h).queue;lB(h,V,v,le,k===null?Cde:function(){return dB(h),k(M)})}function cB(h){var v=h.memoizedState;if(v!==null)return v;v={memoizedState:le,baseState:le,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Iu,lastRenderedState:le},next:null};var k={};return v.next={memoizedState:k,baseState:k,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Iu,lastRenderedState:k},next:null},h.memoizedState=v,h=h.alternate,h!==null&&(h.memoizedState=v),v}function dB(h){var v=cB(h);v.next===null&&(v=h.alternate.memoizedState),Tv(h,v.next.queue,{},dl())}function $j(){return _s(Vv)}function uB(){return li().memoizedState}function mB(){return li().memoizedState}function Pde(h){for(var v=h.return;v!==null;){switch(v.tag){case 24:case 3:var k=dl();h=wp(k);var M=Sp(v,h,k);M!==null&&(zo(M,v,k),_v(M,v,k)),v={cache:yj()},h.payload=v;return}v=v.return}}function Tde(h,v,k){var M=dl();k={lane:M,revertLane:0,gesture:null,action:k,hasEagerState:!1,eagerState:null,next:null},H_(h)?hB(v,k):(k=lj(h,v,k,M),k!==null&&(zo(k,h,M),fB(k,v,M)))}function pB(h,v,k){var M=dl();Tv(h,v,k,M)}function Tv(h,v,k,M){var V={lane:M,revertLane:0,gesture:null,action:k,hasEagerState:!1,eagerState:null,next:null};if(H_(h))hB(v,V);else{var ee=h.alternate;if(h.lanes===0&&(ee===null||ee.lanes===0)&&(ee=v.lastRenderedReducer,ee!==null))try{var we=v.lastRenderedState,qe=ee(we,k);if(V.hasEagerState=!0,V.eagerState=qe,qr(qe,we))return S_(h,v,V,0),da===null&&w_(),!1}catch{}if(k=lj(h,v,V,M),k!==null)return zo(k,h,M),fB(k,v,M),!0}return!1}function Vj(h,v,k,M){if(M={lane:2,revertLane:_M(),gesture:null,action:M,hasEagerState:!1,eagerState:null,next:null},H_(h)){if(v)throw Error(a(479))}else v=lj(h,k,M,2),v!==null&&zo(v,h,2)}function H_(h){var v=h.alternate;return h===Yn||v!==null&&v===Yn}function hB(h,v){Eb=L_=!0;var k=h.pending;k===null?v.next=v:(v.next=k.next,k.next=v),h.pending=v}function fB(h,v,k){if((k&4194048)!==0){var M=v.lanes;M&=h.pendingLanes,k|=M,v.lanes=k,zt(h,k)}}var Av={readContext:_s,use:O_,useCallback:Xa,useContext:Xa,useEffect:Xa,useImperativeHandle:Xa,useLayoutEffect:Xa,useInsertionEffect:Xa,useMemo:Xa,useReducer:Xa,useRef:Xa,useState:Xa,useDebugValue:Xa,useDeferredValue:Xa,useTransition:Xa,useSyncExternalStore:Xa,useId:Xa,useHostTransitionStatus:Xa,useFormState:Xa,useActionState:Xa,useOptimistic:Xa,useMemoCache:Xa,useCacheRefresh:Xa};Av.useEffectEvent=Xa;var gB={readContext:_s,use:O_,useCallback:function(h,v){return ho().memoizedState=[h,v===void 0?null:v],h},useContext:_s,useEffect:JU,useImperativeHandle:function(h,v,k){k=k!=null?k.concat([h]):null,U_(4194308,4,rB.bind(null,v,h),k)},useLayoutEffect:function(h,v){return U_(4194308,4,h,v)},useInsertionEffect:function(h,v){U_(4,2,h,v)},useMemo:function(h,v){var k=ho();v=v===void 0?null:v;var M=h();if(Tf){ze(!0);try{h()}finally{ze(!1)}}return k.memoizedState=[M,v],M},useReducer:function(h,v,k){var M=ho();if(k!==void 0){var V=k(v);if(Tf){ze(!0);try{k(v)}finally{ze(!1)}}}else V=v;return M.memoizedState=M.baseState=V,h={pending:null,lanes:0,dispatch:null,lastRenderedReducer:h,lastRenderedState:V},M.queue=h,h=h.dispatch=Tde.bind(null,Yn,h),[M.memoizedState,h]},useRef:function(h){var v=ho();return h={current:h},v.memoizedState=h},useState:function(h){h=Oj(h);var v=h.queue,k=pB.bind(null,Yn,v);return v.dispatch=k,[h.memoizedState,k]},useDebugValue:Bj,useDeferredValue:function(h,v){var k=ho();return Hj(k,h,v)},useTransition:function(){var h=Oj(!1);return h=lB.bind(null,Yn,h.queue,!0,!1),ho().memoizedState=h,[!1,h]},useSyncExternalStore:function(h,v,k){var M=Yn,V=ho();if(Cr){if(k===void 0)throw Error(a(407));k=k()}else{if(k=v(),da===null)throw Error(a(349));(wr&127)!==0||IU(M,v,k)}V.memoizedState=k;var ee={value:k,getSnapshot:v};return V.queue=ee,JU(zU.bind(null,M,ee,h),[h]),M.flags|=2048,Fb(9,{destroy:void 0},OU.bind(null,M,ee,k,v),null),k},useId:function(){var h=ho(),v=da.identifierPrefix;if(Cr){var k=jd,M=Ad;k=(M&~(1<<32-We(M)-1)).toString(32)+k,v="_"+v+"R_"+k,k=R_++,0<\/script>",ee=ee.removeChild(ee.firstChild);break;case"select":ee=typeof M.is=="string"?we.createElement("select",{is:M.is}):we.createElement("select"),M.multiple?ee.multiple=!0:M.size&&(ee.size=M.size);break;default:ee=typeof M.is=="string"?we.createElement(V,{is:M.is}):we.createElement(V)}}ee[kt]=v,ee[Nt]=M;e:for(we=v.child;we!==null;){if(we.tag===5||we.tag===6)ee.appendChild(we.stateNode);else if(we.tag!==4&&we.tag!==27&&we.child!==null){we.child.return=we,we=we.child;continue}if(we===v)break e;for(;we.sibling===null;){if(we.return===null||we.return===v)break e;we=we.return}we.sibling.return=we.return,we=we.sibling}v.stateNode=ee;e:switch(Ns(ee,V,M),V){case"button":case"input":case"select":case"textarea":M=!!M.autoFocus;break e;case"img":M=!0;break e;default:M=!1}M&&zu(v)}}return Ca(v),iM(v,v.type,h===null?null:h.memoizedProps,v.pendingProps,k),null;case 6:if(h&&v.stateNode!=null)h.memoizedProps!==M&&zu(v);else{if(typeof M!="string"&&v.stateNode===null)throw Error(a(166));if(h=$.current,Nb(v)){if(h=v.stateNode,k=v.memoizedProps,M=null,V=Ss,V!==null)switch(V.tag){case 27:case 5:M=V.memoizedProps}h[kt]=v,h=!!(h.nodeValue===k||M!==null&&M.suppressHydrationWarning===!0||L8(h.nodeValue,k)),h||xp(v,!0)}else h=lk(h).createTextNode(M),h[kt]=v,v.stateNode=h}return Ca(v),null;case 31:if(k=v.memoizedState,h===null||h.memoizedState!==null){if(M=Nb(v),k!==null){if(h===null){if(!M)throw Error(a(318));if(h=v.memoizedState,h=h!==null?h.dehydrated:null,!h)throw Error(a(557));h[kt]=v}else wf(),(v.flags&128)===0&&(v.memoizedState=null),v.flags|=4;Ca(v),h=!1}else k=fj(),h!==null&&h.memoizedState!==null&&(h.memoizedState.hydrationErrors=k),h=!0;if(!h)return v.flags&256?(ol(v),v):(ol(v),null);if((v.flags&128)!==0)throw Error(a(558))}return Ca(v),null;case 13:if(M=v.memoizedState,h===null||h.memoizedState!==null&&h.memoizedState.dehydrated!==null){if(V=Nb(v),M!==null&&M.dehydrated!==null){if(h===null){if(!V)throw Error(a(318));if(V=v.memoizedState,V=V!==null?V.dehydrated:null,!V)throw Error(a(317));V[kt]=v}else wf(),(v.flags&128)===0&&(v.memoizedState=null),v.flags|=4;Ca(v),V=!1}else V=fj(),h!==null&&h.memoizedState!==null&&(h.memoizedState.hydrationErrors=V),V=!0;if(!V)return v.flags&256?(ol(v),v):(ol(v),null)}return ol(v),(v.flags&128)!==0?(v.lanes=k,v):(k=M!==null,h=h!==null&&h.memoizedState!==null,k&&(M=v.child,V=null,M.alternate!==null&&M.alternate.memoizedState!==null&&M.alternate.memoizedState.cachePool!==null&&(V=M.alternate.memoizedState.cachePool.pool),ee=null,M.memoizedState!==null&&M.memoizedState.cachePool!==null&&(ee=M.memoizedState.cachePool.pool),ee!==V&&(M.flags|=2048)),k!==h&&k&&(v.child.flags|=8192),W_(v,v.updateQueue),Ca(v),null);case 4:return j(),h===null&&PM(v.stateNode.containerInfo),Ca(v),null;case 10:return Lu(v.type),Ca(v),null;case 19:if(ie(oi),M=v.memoizedState,M===null)return Ca(v),null;if(V=(v.flags&128)!==0,ee=M.rendering,ee===null)if(V)Mv(M,!1);else{if(Ya!==0||h!==null&&(h.flags&128)!==0)for(h=v.child;h!==null;){if(ee=F_(h),ee!==null){for(v.flags|=128,Mv(M,!1),h=ee.updateQueue,v.updateQueue=h,W_(v,h),v.subtreeFlags=0,h=k,k=v.child;k!==null;)pU(k,h),k=k.sibling;return ue(oi,oi.current&1|2),Cr&&Du(v,M.treeForkCount),v.child}h=h.sibling}M.tail!==null&&L()>Z_&&(v.flags|=128,V=!0,Mv(M,!1),v.lanes=4194304)}else{if(!V)if(h=F_(ee),h!==null){if(v.flags|=128,V=!0,h=h.updateQueue,v.updateQueue=h,W_(v,h),Mv(M,!0),M.tail===null&&M.tailMode==="hidden"&&!ee.alternate&&!Cr)return Ca(v),null}else 2*L()-M.renderingStartTime>Z_&&k!==536870912&&(v.flags|=128,V=!0,Mv(M,!1),v.lanes=4194304);M.isBackwards?(ee.sibling=v.child,v.child=ee):(h=M.last,h!==null?h.sibling=ee:v.child=ee,M.last=ee)}return M.tail!==null?(h=M.tail,M.rendering=h,M.tail=h.sibling,M.renderingStartTime=L(),h.sibling=null,k=oi.current,ue(oi,V?k&1|2:k&1),Cr&&Du(v,M.treeForkCount),h):(Ca(v),null);case 22:case 23:return ol(v),Tj(),M=v.memoizedState!==null,h!==null?h.memoizedState!==null!==M&&(v.flags|=8192):M&&(v.flags|=8192),M?(k&536870912)!==0&&(v.flags&128)===0&&(Ca(v),v.subtreeFlags&6&&(v.flags|=8192)):Ca(v),k=v.updateQueue,k!==null&&W_(v,k.retryQueue),k=null,h!==null&&h.memoizedState!==null&&h.memoizedState.cachePool!==null&&(k=h.memoizedState.cachePool.pool),M=null,v.memoizedState!==null&&v.memoizedState.cachePool!==null&&(M=v.memoizedState.cachePool.pool),M!==k&&(v.flags|=2048),h!==null&&ie(kf),null;case 24:return k=null,h!==null&&(k=h.memoizedState.cache),v.memoizedState.cache!==k&&(v.flags|=2048),Lu(fi),Ca(v),null;case 25:return null;case 30:return null}throw Error(a(156,v.tag))}function Dde(h,v){switch(pj(v),v.tag){case 1:return h=v.flags,h&65536?(v.flags=h&-65537|128,v):null;case 3:return Lu(fi),j(),h=v.flags,(h&65536)!==0&&(h&128)===0?(v.flags=h&-65537|128,v):null;case 26:case 27:case 5:return X(v),null;case 31:if(v.memoizedState!==null){if(ol(v),v.alternate===null)throw Error(a(340));wf()}return h=v.flags,h&65536?(v.flags=h&-65537|128,v):null;case 13:if(ol(v),h=v.memoizedState,h!==null&&h.dehydrated!==null){if(v.alternate===null)throw Error(a(340));wf()}return h=v.flags,h&65536?(v.flags=h&-65537|128,v):null;case 19:return ie(oi),null;case 4:return j(),null;case 10:return Lu(v.type),null;case 22:case 23:return ol(v),Tj(),h!==null&&ie(kf),h=v.flags,h&65536?(v.flags=h&-65537|128,v):null;case 24:return Lu(fi),null;case 25:return null;default:return null}}function UB(h,v){switch(pj(v),v.tag){case 3:Lu(fi),j();break;case 26:case 27:case 5:X(v);break;case 4:j();break;case 31:v.memoizedState!==null&&ol(v);break;case 13:ol(v);break;case 19:ie(oi);break;case 10:Lu(v.type);break;case 22:case 23:ol(v),Tj(),h!==null&&ie(kf);break;case 24:Lu(fi)}}function Ev(h,v){try{var k=v.updateQueue,M=k!==null?k.lastEffect:null;if(M!==null){var V=M.next;k=V;do{if((k.tag&h)===h){M=void 0;var ee=k.create,we=k.inst;M=ee(),we.destroy=M}k=k.next}while(k!==V)}}catch(qe){Gr(v,v.return,qe)}}function Np(h,v,k){try{var M=v.updateQueue,V=M!==null?M.lastEffect:null;if(V!==null){var ee=V.next;M=ee;do{if((M.tag&h)===h){var we=M.inst,qe=we.destroy;if(qe!==void 0){we.destroy=void 0,V=v;var ht=k,jt=qe;try{jt()}catch(Bt){Gr(V,ht,Bt)}}}M=M.next}while(M!==ee)}}catch(Bt){Gr(v,v.return,Bt)}}function BB(h){var v=h.updateQueue;if(v!==null){var k=h.stateNode;try{MU(v,k)}catch(M){Gr(h,h.return,M)}}}function HB(h,v,k){k.props=Af(h.type,h.memoizedProps),k.state=h.memoizedState;try{k.componentWillUnmount()}catch(M){Gr(h,v,M)}}function Dv(h,v){try{var k=h.ref;if(k!==null){switch(h.tag){case 26:case 27:case 5:var M=h.stateNode;break;case 30:M=h.stateNode;break;default:M=h.stateNode}typeof k=="function"?h.refCleanup=k(M):k.current=M}}catch(V){Gr(h,v,V)}}function Md(h,v){var k=h.ref,M=h.refCleanup;if(k!==null)if(typeof M=="function")try{M()}catch(V){Gr(h,v,V)}finally{h.refCleanup=null,h=h.alternate,h!=null&&(h.refCleanup=null)}else if(typeof k=="function")try{k(null)}catch(V){Gr(h,v,V)}else k.current=null}function qB(h){var v=h.type,k=h.memoizedProps,M=h.stateNode;try{e:switch(v){case"button":case"input":case"select":case"textarea":k.autoFocus&&M.focus();break e;case"img":k.src?M.src=k.src:k.srcSet&&(M.srcset=k.srcSet)}}catch(V){Gr(h,h.return,V)}}function sM(h,v,k){try{var M=h.stateNode;tue(M,h.type,k,v),M[Nt]=v}catch(V){Gr(h,h.return,V)}}function $B(h){return h.tag===5||h.tag===3||h.tag===26||h.tag===27&&Ep(h.type)||h.tag===4}function oM(h){e:for(;;){for(;h.sibling===null;){if(h.return===null||$B(h.return))return null;h=h.return}for(h.sibling.return=h.return,h=h.sibling;h.tag!==5&&h.tag!==6&&h.tag!==18;){if(h.tag===27&&Ep(h.type)||h.flags&2||h.child===null||h.tag===4)continue e;h.child.return=h,h=h.child}if(!(h.flags&2))return h.stateNode}}function lM(h,v,k){var M=h.tag;if(M===5||M===6)h=h.stateNode,v?(k.nodeType===9?k.body:k.nodeName==="HTML"?k.ownerDocument.body:k).insertBefore(h,v):(v=k.nodeType===9?k.body:k.nodeName==="HTML"?k.ownerDocument.body:k,v.appendChild(h),k=k._reactRootContainer,k!=null||v.onclick!==null||(v.onclick=Wt));else if(M!==4&&(M===27&&Ep(h.type)&&(k=h.stateNode,v=null),h=h.child,h!==null))for(lM(h,v,k),h=h.sibling;h!==null;)lM(h,v,k),h=h.sibling}function K_(h,v,k){var M=h.tag;if(M===5||M===6)h=h.stateNode,v?k.insertBefore(h,v):k.appendChild(h);else if(M!==4&&(M===27&&Ep(h.type)&&(k=h.stateNode),h=h.child,h!==null))for(K_(h,v,k),h=h.sibling;h!==null;)K_(h,v,k),h=h.sibling}function VB(h){var v=h.stateNode,k=h.memoizedProps;try{for(var M=h.type,V=v.attributes;V.length;)v.removeAttributeNode(V[0]);Ns(v,M,k),v[kt]=h,v[Nt]=k}catch(ee){Gr(h,h.return,ee)}}var Uu=!1,xi=!1,cM=!1,GB=typeof WeakSet=="function"?WeakSet:Set,Zi=null;function Fde(h,v){if(h=h.containerInfo,jM=fk,h=ws(h),mr(h)){if("selectionStart"in h)var k={start:h.selectionStart,end:h.selectionEnd};else e:{k=(k=h.ownerDocument)&&k.defaultView||window;var M=k.getSelection&&k.getSelection();if(M&&M.rangeCount!==0){k=M.anchorNode;var V=M.anchorOffset,ee=M.focusNode;M=M.focusOffset;try{k.nodeType,ee.nodeType}catch{k=null;break e}var we=0,qe=-1,ht=-1,jt=0,Bt=0,Vt=h,Et=null;t:for(;;){for(var It;Vt!==k||V!==0&&Vt.nodeType!==3||(qe=we+V),Vt!==ee||M!==0&&Vt.nodeType!==3||(ht=we+M),Vt.nodeType===3&&(we+=Vt.nodeValue.length),(It=Vt.firstChild)!==null;)Et=Vt,Vt=It;for(;;){if(Vt===h)break t;if(Et===k&&++jt===V&&(qe=we),Et===ee&&++Bt===M&&(ht=we),(It=Vt.nextSibling)!==null)break;Vt=Et,Et=Vt.parentNode}Vt=It}k=qe===-1||ht===-1?null:{start:qe,end:ht}}else k=null}k=k||{start:0,end:0}}else k=null;for(MM={focusedElem:h,selectionRange:k},fk=!1,Zi=v;Zi!==null;)if(v=Zi,h=v.child,(v.subtreeFlags&1028)!==0&&h!==null)h.return=v,Zi=h;else for(;Zi!==null;){switch(v=Zi,ee=v.alternate,h=v.flags,v.tag){case 0:if((h&4)!==0&&(h=v.updateQueue,h=h!==null?h.events:null,h!==null))for(k=0;k title"))),Ns(ee,M,k),ee[kt]=h,rt(ee),M=ee;break e;case"link":var we=Z8("link","href",V).get(M+(k.href||""));if(we){for(var qe=0;qeJr&&(we=Jr,Jr=Bn,Bn=we);var wt=Di(qe,Bn),yt=Di(qe,Jr);if(wt&&yt&&(It.rangeCount!==1||It.anchorNode!==wt.node||It.anchorOffset!==wt.offset||It.focusNode!==yt.node||It.focusOffset!==yt.offset)){var At=Vt.createRange();At.setStart(wt.node,wt.offset),It.removeAllRanges(),Bn>Jr?(It.addRange(At),It.extend(yt.node,yt.offset)):(At.setEnd(yt.node,yt.offset),It.addRange(At))}}}}for(Vt=[],It=qe;It=It.parentNode;)It.nodeType===1&&Vt.push({element:It,left:It.scrollLeft,top:It.scrollTop});for(typeof qe.focus=="function"&&qe.focus(),qe=0;qek?32:k,ne.T=null,k=gM,gM=null;var ee=Ap,we=Vu;if(Fi=0,zb=Ap=null,Vu=0,(zr&6)!==0)throw Error(a(331));var qe=zr;if(zr|=4,r8(ee.current),e8(ee,ee.current,we,k),zr=qe,zv(0,!1),Be&&typeof Be.onPostCommitFiberRoot=="function")try{Be.onPostCommitFiberRoot(Ie,ee)}catch{}return!0}finally{J.p=V,ne.T=M,w8(h,v)}}function _8(h,v,k){v=Ol(k,v),v=Qj(h.stateNode,v,2),h=Sp(h,v,2),h!==null&&(et(h,2),Ed(h))}function Gr(h,v,k){if(h.tag===3)_8(h,h,k);else for(;v!==null;){if(v.tag===3){_8(v,h,k);break}else if(v.tag===1){var M=v.stateNode;if(typeof v.type.getDerivedStateFromError=="function"||typeof M.componentDidCatch=="function"&&(Tp===null||!Tp.has(M))){h=Ol(k,h),k=kB(2),M=Sp(v,k,2),M!==null&&(NB(k,M,v,h),et(M,2),Ed(M));break}}v=v.return}}function vM(h,v,k){var M=h.pingCache;if(M===null){M=h.pingCache=new Ide;var V=new Set;M.set(v,V)}else V=M.get(v),V===void 0&&(V=new Set,M.set(v,V));V.has(k)||(mM=!0,V.add(k),h=Hde.bind(null,h,v,k),v.then(h,h))}function Hde(h,v,k){var M=h.pingCache;M!==null&&M.delete(v),h.pingedLanes|=h.suspendedLanes&k,h.warmLanes&=~k,da===h&&(wr&k)===k&&(Ya===4||Ya===3&&(wr&62914560)===wr&&300>L()-Y_?(zr&2)===0&&Ub(h,0):pM|=k,Ob===wr&&(Ob=0)),Ed(h)}function k8(h,v){v===0&&(v=ot()),h=yf(h,v),h!==null&&(et(h,v),Ed(h))}function qde(h){var v=h.memoizedState,k=0;v!==null&&(k=v.retryLane),k8(h,k)}function $de(h,v){var k=0;switch(h.tag){case 31:case 13:var M=h.stateNode,V=h.memoizedState;V!==null&&(k=V.retryLane);break;case 19:M=h.stateNode;break;case 22:M=h.stateNode._retryCache;break;default:throw Error(a(314))}M!==null&&M.delete(v),k8(h,k)}function Vde(h,v){return fe(h,v)}var ak=null,Hb=null,wM=!1,ik=!1,SM=!1,Mp=0;function Ed(h){h!==Hb&&h.next===null&&(Hb===null?ak=Hb=h:Hb=Hb.next=h),ik=!0,wM||(wM=!0,Wde())}function zv(h,v){if(!SM&&ik){SM=!0;do for(var k=!1,M=ak;M!==null;){if(h!==0){var V=M.pendingLanes;if(V===0)var ee=0;else{var we=M.suspendedLanes,qe=M.pingedLanes;ee=(1<<31-We(42|h)+1)-1,ee&=V&~(we&~qe),ee=ee&201326741?ee&201326741|1:ee?ee|2:0}ee!==0&&(k=!0,T8(M,ee))}else ee=wr,ee=_e(M,M===da?ee:0,M.cancelPendingCommit!==null||M.timeoutHandle!==-1),(ee&3)===0||Ee(M,ee)||(k=!0,T8(M,ee));M=M.next}while(k);SM=!1}}function Gde(){N8()}function N8(){ik=wM=!1;var h=0;Mp!==0&&rue()&&(h=Mp);for(var v=L(),k=null,M=ak;M!==null;){var V=M.next,ee=C8(M,v);ee===0?(M.next=null,k===null?ak=V:k.next=V,V===null&&(Hb=k)):(k=M,(h!==0||(ee&3)!==0)&&(ik=!0)),M=V}Fi!==0&&Fi!==5||zv(h),Mp!==0&&(Mp=0)}function C8(h,v){for(var k=h.suspendedLanes,M=h.pingedLanes,V=h.expirationTimes,ee=h.pendingLanes&-62914561;0qe)break;var Bt=ht.transferSize,Vt=ht.initiatorType;Bt&&R8(Vt)&&(ht=ht.responseEnd,we+=Bt*(ht"u"?null:document;function K8(h,v,k){var M=qb;if(M&&typeof v=="string"&&v){var V=Gn(v);V='link[rel="'+h+'"][href="'+V+'"]',typeof k=="string"&&(V+='[crossorigin="'+k+'"]'),W8.has(V)||(W8.add(V),h={rel:h,crossOrigin:k,href:v},M.querySelector(V)===null&&(v=M.createElement("link"),Ns(v,"link",h),rt(v),M.head.appendChild(v)))}}function mue(h){Gu.D(h),K8("dns-prefetch",h,null)}function pue(h,v){Gu.C(h,v),K8("preconnect",h,v)}function hue(h,v,k){Gu.L(h,v,k);var M=qb;if(M&&h&&v){var V='link[rel="preload"][as="'+Gn(v)+'"]';v==="image"&&k&&k.imageSrcSet?(V+='[imagesrcset="'+Gn(k.imageSrcSet)+'"]',typeof k.imageSizes=="string"&&(V+='[imagesizes="'+Gn(k.imageSizes)+'"]')):V+='[href="'+Gn(h)+'"]';var ee=V;switch(v){case"style":ee=$b(h);break;case"script":ee=Vb(h)}$l.has(ee)||(h=m({rel:"preload",href:v==="image"&&k&&k.imageSrcSet?void 0:h,as:v},k),$l.set(ee,h),M.querySelector(V)!==null||v==="style"&&M.querySelector(qv(ee))||v==="script"&&M.querySelector($v(ee))||(v=M.createElement("link"),Ns(v,"link",h),rt(v),M.head.appendChild(v)))}}function fue(h,v){Gu.m(h,v);var k=qb;if(k&&h){var M=v&&typeof v.as=="string"?v.as:"script",V='link[rel="modulepreload"][as="'+Gn(M)+'"][href="'+Gn(h)+'"]',ee=V;switch(M){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":ee=Vb(h)}if(!$l.has(ee)&&(h=m({rel:"modulepreload",href:h},v),$l.set(ee,h),k.querySelector(V)===null)){switch(M){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(k.querySelector($v(ee)))return}M=k.createElement("link"),Ns(M,"link",h),rt(M),k.head.appendChild(M)}}}function gue(h,v,k){Gu.S(h,v,k);var M=qb;if(M&&h){var V=nt(M).hoistableStyles,ee=$b(h);v=v||"default";var we=V.get(ee);if(!we){var qe={loading:0,preload:null};if(we=M.querySelector(qv(ee)))qe.loading=5;else{h=m({rel:"stylesheet",href:h,"data-precedence":v},k),(k=$l.get(ee))&&OM(h,k);var ht=we=M.createElement("link");rt(ht),Ns(ht,"link",h),ht._p=new Promise(function(jt,Bt){ht.onload=jt,ht.onerror=Bt}),ht.addEventListener("load",function(){qe.loading|=1}),ht.addEventListener("error",function(){qe.loading|=2}),qe.loading|=4,dk(we,v,M)}we={type:"stylesheet",instance:we,count:1,state:qe},V.set(ee,we)}}}function bue(h,v){Gu.X(h,v);var k=qb;if(k&&h){var M=nt(k).hoistableScripts,V=Vb(h),ee=M.get(V);ee||(ee=k.querySelector($v(V)),ee||(h=m({src:h,async:!0},v),(v=$l.get(V))&&zM(h,v),ee=k.createElement("script"),rt(ee),Ns(ee,"link",h),k.head.appendChild(ee)),ee={type:"script",instance:ee,count:1,state:null},M.set(V,ee))}}function xue(h,v){Gu.M(h,v);var k=qb;if(k&&h){var M=nt(k).hoistableScripts,V=Vb(h),ee=M.get(V);ee||(ee=k.querySelector($v(V)),ee||(h=m({src:h,async:!0,type:"module"},v),(v=$l.get(V))&&zM(h,v),ee=k.createElement("script"),rt(ee),Ns(ee,"link",h),k.head.appendChild(ee)),ee={type:"script",instance:ee,count:1,state:null},M.set(V,ee))}}function Q8(h,v,k,M){var V=(V=$.current)?ck(V):null;if(!V)throw Error(a(446));switch(h){case"meta":case"title":return null;case"style":return typeof k.precedence=="string"&&typeof k.href=="string"?(v=$b(k.href),k=nt(V).hoistableStyles,M=k.get(v),M||(M={type:"style",instance:null,count:0,state:null},k.set(v,M)),M):{type:"void",instance:null,count:0,state:null};case"link":if(k.rel==="stylesheet"&&typeof k.href=="string"&&typeof k.precedence=="string"){h=$b(k.href);var ee=nt(V).hoistableStyles,we=ee.get(h);if(we||(V=V.ownerDocument||V,we={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},ee.set(h,we),(ee=V.querySelector(qv(h)))&&!ee._p&&(we.instance=ee,we.state.loading=5),$l.has(h)||(k={rel:"preload",as:"style",href:k.href,crossOrigin:k.crossOrigin,integrity:k.integrity,media:k.media,hrefLang:k.hrefLang,referrerPolicy:k.referrerPolicy},$l.set(h,k),ee||yue(V,h,k,we.state))),v&&M===null)throw Error(a(528,""));return we}if(v&&M!==null)throw Error(a(529,""));return null;case"script":return v=k.async,k=k.src,typeof k=="string"&&v&&typeof v!="function"&&typeof v!="symbol"?(v=Vb(k),k=nt(V).hoistableScripts,M=k.get(v),M||(M={type:"script",instance:null,count:0,state:null},k.set(v,M)),M):{type:"void",instance:null,count:0,state:null};default:throw Error(a(444,h))}}function $b(h){return'href="'+Gn(h)+'"'}function qv(h){return'link[rel="stylesheet"]['+h+"]"}function X8(h){return m({},h,{"data-precedence":h.precedence,precedence:null})}function yue(h,v,k,M){h.querySelector('link[rel="preload"][as="style"]['+v+"]")?M.loading=1:(v=h.createElement("link"),M.preload=v,v.addEventListener("load",function(){return M.loading|=1}),v.addEventListener("error",function(){return M.loading|=2}),Ns(v,"link",k),rt(v),h.head.appendChild(v))}function Vb(h){return'[src="'+Gn(h)+'"]'}function $v(h){return"script[async]"+h}function Y8(h,v,k){if(v.count++,v.instance===null)switch(v.type){case"style":var M=h.querySelector('style[data-href~="'+Gn(k.href)+'"]');if(M)return v.instance=M,rt(M),M;var V=m({},k,{"data-href":k.href,"data-precedence":k.precedence,href:null,precedence:null});return M=(h.ownerDocument||h).createElement("style"),rt(M),Ns(M,"style",V),dk(M,k.precedence,h),v.instance=M;case"stylesheet":V=$b(k.href);var ee=h.querySelector(qv(V));if(ee)return v.state.loading|=4,v.instance=ee,rt(ee),ee;M=X8(k),(V=$l.get(V))&&OM(M,V),ee=(h.ownerDocument||h).createElement("link"),rt(ee);var we=ee;return we._p=new Promise(function(qe,ht){we.onload=qe,we.onerror=ht}),Ns(ee,"link",M),v.state.loading|=4,dk(ee,k.precedence,h),v.instance=ee;case"script":return ee=Vb(k.src),(V=h.querySelector($v(ee)))?(v.instance=V,rt(V),V):(M=k,(V=$l.get(ee))&&(M=m({},k),zM(M,V)),h=h.ownerDocument||h,V=h.createElement("script"),rt(V),Ns(V,"link",M),h.head.appendChild(V),v.instance=V);case"void":return null;default:throw Error(a(443,v.type))}else v.type==="stylesheet"&&(v.state.loading&4)===0&&(M=v.instance,v.state.loading|=4,dk(M,k.precedence,h));return v.instance}function dk(h,v,k){for(var M=k.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),V=M.length?M[M.length-1]:null,ee=V,we=0;we title"):null)}function vue(h,v,k){if(k===1||v.itemProp!=null)return!1;switch(h){case"meta":case"title":return!0;case"style":if(typeof v.precedence!="string"||typeof v.href!="string"||v.href==="")break;return!0;case"link":if(typeof v.rel!="string"||typeof v.href!="string"||v.href===""||v.onLoad||v.onError)break;return v.rel==="stylesheet"?(h=v.disabled,typeof v.precedence=="string"&&h==null):!0;case"script":if(v.async&&typeof v.async!="function"&&typeof v.async!="symbol"&&!v.onLoad&&!v.onError&&v.src&&typeof v.src=="string")return!0}return!1}function eH(h){return!(h.type==="stylesheet"&&(h.state.loading&3)===0)}function wue(h,v,k,M){if(k.type==="stylesheet"&&(typeof M.media!="string"||matchMedia(M.media).matches!==!1)&&(k.state.loading&4)===0){if(k.instance===null){var V=$b(M.href),ee=v.querySelector(qv(V));if(ee){v=ee._p,v!==null&&typeof v=="object"&&typeof v.then=="function"&&(h.count++,h=mk.bind(h),v.then(h,h)),k.state.loading|=4,k.instance=ee,rt(ee);return}ee=v.ownerDocument||v,M=X8(M),(V=$l.get(V))&&OM(M,V),ee=ee.createElement("link"),rt(ee);var we=ee;we._p=new Promise(function(qe,ht){we.onload=qe,we.onerror=ht}),Ns(ee,"link",M),k.instance=ee}h.stylesheets===null&&(h.stylesheets=new Map),h.stylesheets.set(k,v),(v=k.state.preload)&&(k.state.loading&3)===0&&(h.count++,k=mk.bind(h),v.addEventListener("load",k),v.addEventListener("error",k))}}var UM=0;function Sue(h,v){return h.stylesheets&&h.count===0&&hk(h,h.stylesheets),0UM?50:800)+v);return h.unsuspend=k,function(){h.unsuspend=null,clearTimeout(M),clearTimeout(V)}}:null}function mk(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)hk(this,this.stylesheets);else if(this.unsuspend){var h=this.unsuspend;this.unsuspend=null,h()}}}var pk=null;function hk(h,v){h.stylesheets=null,h.unsuspend!==null&&(h.count++,pk=new Map,v.forEach(_ue,h),pk=null,mk.call(h))}function _ue(h,v){if(!(v.state.loading&4)){var k=pk.get(h);if(k)var M=k.get(null);else{k=new Map,pk.set(h,k);for(var V=h.querySelectorAll("link[data-precedence],style[data-precedence]"),ee=0;ee"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(e){console.error(e)}}return t(),QM.exports=Uue(),QM.exports}var Hue=Bue();const qn=t=>typeof t=="string",Yv=()=>{let t,e;const n=new Promise((a,i)=>{t=a,e=i});return n.resolve=t,n.reject=e,n},kH=t=>t==null?"":""+t,que=(t,e,n)=>{t.forEach(a=>{e[a]&&(n[a]=e[a])})},$ue=/###/g,NH=t=>t&&t.indexOf("###")>-1?t.replace($ue,"."):t,CH=t=>!t||qn(t),K0=(t,e,n)=>{const a=qn(e)?e.split("."):e;let i=0;for(;i{const{obj:a,k:i}=K0(t,e,Object);if(a!==void 0||e.length===1){a[i]=n;return}let s=e[e.length-1],o=e.slice(0,e.length-1),l=K0(t,o,Object);for(;l.obj===void 0&&o.length;)s=`${o[o.length-1]}.${s}`,o=o.slice(0,o.length-1),l=K0(t,o,Object),l?.obj&&typeof l.obj[`${l.k}.${s}`]<"u"&&(l.obj=void 0);l.obj[`${l.k}.${s}`]=n},Vue=(t,e,n,a)=>{const{obj:i,k:s}=K0(t,e,Object);i[s]=i[s]||[],i[s].push(n)},VN=(t,e)=>{const{obj:n,k:a}=K0(t,e);if(n&&Object.prototype.hasOwnProperty.call(n,a))return n[a]},Gue=(t,e,n)=>{const a=VN(t,n);return a!==void 0?a:VN(e,n)},FY=(t,e,n)=>{for(const a in e)a!=="__proto__"&&a!=="constructor"&&(a in t?qn(t[a])||t[a]instanceof String||qn(e[a])||e[a]instanceof String?n&&(t[a]=e[a]):FY(t[a],e[a],n):t[a]=e[a]);return t},Wb=t=>t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");var Wue={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};const Kue=t=>qn(t)?t.replace(/[&<>"'\/]/g,e=>Wue[e]):t;class Que{constructor(e){this.capacity=e,this.regExpMap=new Map,this.regExpQueue=[]}getRegExp(e){const n=this.regExpMap.get(e);if(n!==void 0)return n;const a=new RegExp(e);return this.regExpQueue.length===this.capacity&&this.regExpMap.delete(this.regExpQueue.shift()),this.regExpMap.set(e,a),this.regExpQueue.push(e),a}}const Xue=[" ",",","?","!",";"],Yue=new Que(20),Zue=(t,e,n)=>{e=e||"",n=n||"";const a=Xue.filter(o=>e.indexOf(o)<0&&n.indexOf(o)<0);if(a.length===0)return!0;const i=Yue.getRegExp(`(${a.map(o=>o==="?"?"\\?":o).join("|")})`);let s=!i.test(t);if(!s){const o=t.indexOf(n);o>0&&!i.test(t.substring(0,o))&&(s=!0)}return s},CF=(t,e,n=".")=>{if(!t)return;if(t[e])return Object.prototype.hasOwnProperty.call(t,e)?t[e]:void 0;const a=e.split(n);let i=t;for(let s=0;s-1&&ct?.replace("_","-"),Jue={type:"logger",log(t){this.output("log",t)},warn(t){this.output("warn",t)},error(t){this.output("error",t)},output(t,e){console?.[t]?.apply?.(console,e)}};class GN{constructor(e,n={}){this.init(e,n)}init(e,n={}){this.prefix=n.prefix||"i18next:",this.logger=e||Jue,this.options=n,this.debug=n.debug}log(...e){return this.forward(e,"log","",!0)}warn(...e){return this.forward(e,"warn","",!0)}error(...e){return this.forward(e,"error","")}deprecate(...e){return this.forward(e,"warn","WARNING DEPRECATED: ",!0)}forward(e,n,a,i){return i&&!this.debug?null:(qn(e[0])&&(e[0]=`${a}${this.prefix} ${e[0]}`),this.logger[n](e))}create(e){return new GN(this.logger,{prefix:`${this.prefix}:${e}:`,...this.options})}clone(e){return e=e||this.options,e.prefix=e.prefix||this.prefix,new GN(this.logger,e)}}var Xd=new GN;let xT=class{constructor(){this.observers={}}on(e,n){return e.split(" ").forEach(a=>{this.observers[a]||(this.observers[a]=new Map);const i=this.observers[a].get(n)||0;this.observers[a].set(n,i+1)}),this}off(e,n){if(this.observers[e]){if(!n){delete this.observers[e];return}this.observers[e].delete(n)}}emit(e,...n){this.observers[e]&&Array.from(this.observers[e].entries()).forEach(([i,s])=>{for(let o=0;o{for(let o=0;o-1&&this.options.ns.splice(n,1)}getResource(e,n,a,i={}){const s=i.keySeparator!==void 0?i.keySeparator:this.options.keySeparator,o=i.ignoreJSONStructure!==void 0?i.ignoreJSONStructure:this.options.ignoreJSONStructure;let l;e.indexOf(".")>-1?l=e.split("."):(l=[e,n],a&&(Array.isArray(a)?l.push(...a):qn(a)&&s?l.push(...a.split(s)):l.push(a)));const c=VN(this.data,l);return!c&&!n&&!a&&e.indexOf(".")>-1&&(e=l[0],n=l[1],a=l.slice(2).join(".")),c||!o||!qn(a)?c:CF(this.data?.[e]?.[n],a,s)}addResource(e,n,a,i,s={silent:!1}){const o=s.keySeparator!==void 0?s.keySeparator:this.options.keySeparator;let l=[e,n];a&&(l=l.concat(o?a.split(o):a)),e.indexOf(".")>-1&&(l=e.split("."),i=n,n=l[1]),this.addNamespaces(n),PH(this.data,l,i),s.silent||this.emit("added",e,n,a,i)}addResources(e,n,a,i={silent:!1}){for(const s in a)(qn(a[s])||Array.isArray(a[s]))&&this.addResource(e,n,s,a[s],{silent:!0});i.silent||this.emit("added",e,n,a)}addResourceBundle(e,n,a,i,s,o={silent:!1,skipCopy:!1}){let l=[e,n];e.indexOf(".")>-1&&(l=e.split("."),i=a,a=n,n=l[1]),this.addNamespaces(n);let c=VN(this.data,l)||{};o.skipCopy||(a=JSON.parse(JSON.stringify(a))),i?FY(c,a,s):c={...c,...a},PH(this.data,l,c),o.silent||this.emit("added",e,n,a)}removeResourceBundle(e,n){this.hasResourceBundle(e,n)&&delete this.data[e][n],this.removeNamespaces(n),this.emit("removed",e,n)}hasResourceBundle(e,n){return this.getResource(e,n)!==void 0}getResourceBundle(e,n){return n||(n=this.options.defaultNS),this.getResource(e,n)}getDataByLanguage(e){return this.data[e]}hasLanguageSomeTranslations(e){const n=this.getDataByLanguage(e);return!!(n&&Object.keys(n)||[]).find(i=>n[i]&&Object.keys(n[i]).length>0)}toJSON(){return this.data}}var LY={processors:{},addPostProcessor(t){this.processors[t.name]=t},handle(t,e,n,a,i){return t.forEach(s=>{e=this.processors[s]?.process(e,n,a,i)??e}),e}};const RY=Symbol("i18next/PATH_KEY");function eme(){const t=[],e=Object.create(null);let n;return e.get=(a,i)=>(n?.revoke?.(),i===RY?t:(t.push(i),n=Proxy.revocable(a,e),n.proxy)),Proxy.revocable(Object.create(null),e).proxy}function PF(t,e){const{[RY]:n}=t(eme());return n.join(e?.keySeparator??".")}const AH={},JM=t=>!qn(t)&&typeof t!="boolean"&&typeof t!="number";class WN extends xT{constructor(e,n={}){super(),que(["resourceStore","languageUtils","pluralResolver","interpolator","backendConnector","i18nFormat","utils"],e,this),this.options=n,this.options.keySeparator===void 0&&(this.options.keySeparator="."),this.logger=Xd.create("translator")}changeLanguage(e){e&&(this.language=e)}exists(e,n={interpolation:{}}){const a={...n};if(e==null)return!1;const i=this.resolve(e,a);if(i?.res===void 0)return!1;const s=JM(i.res);return!(a.returnObjects===!1&&s)}extractFromKey(e,n){let a=n.nsSeparator!==void 0?n.nsSeparator:this.options.nsSeparator;a===void 0&&(a=":");const i=n.keySeparator!==void 0?n.keySeparator:this.options.keySeparator;let s=n.ns||this.options.defaultNS||[];const o=a&&e.indexOf(a)>-1,l=!this.options.userDefinedKeySeparator&&!n.keySeparator&&!this.options.userDefinedNsSeparator&&!n.nsSeparator&&!Zue(e,a,i);if(o&&!l){const c=e.match(this.interpolator.nestingRegexp);if(c&&c.length>0)return{key:e,namespaces:qn(s)?[s]:s};const d=e.split(a);(a!==i||a===i&&this.options.ns.indexOf(d[0])>-1)&&(s=d.shift()),e=d.join(i)}return{key:e,namespaces:qn(s)?[s]:s}}translate(e,n,a){let i=typeof n=="object"?{...n}:n;if(typeof i!="object"&&this.options.overloadTranslationOptionHandler&&(i=this.options.overloadTranslationOptionHandler(arguments)),typeof i=="object"&&(i={...i}),i||(i={}),e==null)return"";typeof e=="function"&&(e=PF(e,{...this.options,...i})),Array.isArray(e)||(e=[String(e)]);const s=i.returnDetails!==void 0?i.returnDetails:this.options.returnDetails,o=i.keySeparator!==void 0?i.keySeparator:this.options.keySeparator,{key:l,namespaces:c}=this.extractFromKey(e[e.length-1],i),d=c[c.length-1];let u=i.nsSeparator!==void 0?i.nsSeparator:this.options.nsSeparator;u===void 0&&(u=":");const m=i.lng||this.language,p=i.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if(m?.toLowerCase()==="cimode")return p?s?{res:`${d}${u}${l}`,usedKey:l,exactUsedKey:l,usedLng:m,usedNS:d,usedParams:this.getUsedParamsDetails(i)}:`${d}${u}${l}`:s?{res:l,usedKey:l,exactUsedKey:l,usedLng:m,usedNS:d,usedParams:this.getUsedParamsDetails(i)}:l;const f=this.resolve(e,i);let g=f?.res;const w=f?.usedKey||l,b=f?.exactUsedKey||l,x=["[object Number]","[object Function]","[object RegExp]"],S=i.joinArrays!==void 0?i.joinArrays:this.options.joinArrays,N=!this.i18nFormat||this.i18nFormat.handleAsObject,C=i.count!==void 0&&!qn(i.count),P=WN.hasDefaultValue(i),T=C?this.pluralResolver.getSuffix(m,i.count,i):"",A=i.ordinal&&C?this.pluralResolver.getSuffix(m,i.count,{ordinal:!1}):"",F=C&&!i.ordinal&&i.count===0,_=F&&i[`defaultValue${this.options.pluralSeparator}zero`]||i[`defaultValue${T}`]||i[`defaultValue${A}`]||i.defaultValue;let E=g;N&&!g&&P&&(E=_);const H=JM(E),I=Object.prototype.toString.apply(E);if(N&&E&&H&&x.indexOf(I)<0&&!(qn(S)&&Array.isArray(E))){if(!i.returnObjects&&!this.options.returnObjects){this.options.returnedObjectHandler||this.logger.warn("accessing an object - but returnObjects options is not enabled!");const U=this.options.returnedObjectHandler?this.options.returnedObjectHandler(w,E,{...i,ns:c}):`key '${l} (${this.language})' returned an object instead of string.`;return s?(f.res=U,f.usedParams=this.getUsedParamsDetails(i),f):U}if(o){const U=Array.isArray(E),R=U?[]:{},Y=U?b:w;for(const ne in E)if(Object.prototype.hasOwnProperty.call(E,ne)){const J=`${Y}${o}${ne}`;P&&!g?R[ne]=this.translate(J,{...i,defaultValue:JM(_)?_[ne]:void 0,joinArrays:!1,ns:c}):R[ne]=this.translate(J,{...i,joinArrays:!1,ns:c}),R[ne]===J&&(R[ne]=E[ne])}g=R}}else if(N&&qn(S)&&Array.isArray(g))g=g.join(S),g&&(g=this.extendTranslation(g,e,i,a));else{let U=!1,R=!1;!this.isValidLookup(g)&&P&&(U=!0,g=_),this.isValidLookup(g)||(R=!0,g=l);const ne=(i.missingKeyNoValueFallbackToKey||this.options.missingKeyNoValueFallbackToKey)&&R?void 0:g,J=P&&_!==g&&this.options.updateMissing;if(R||U||J){if(this.logger.log(J?"updateKey":"missingKey",m,d,l,J?_:g),o){const K=this.resolve(l,{...i,keySeparator:!1});K&&K.res&&this.logger.warn("Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.")}let le=[];const me=this.languageUtils.getFallbackCodes(this.options.fallbackLng,i.lng||this.language);if(this.options.saveMissingTo==="fallback"&&me&&me[0])for(let K=0;K{const he=P&&ue!==g?ue:ne;this.options.missingKeyHandler?this.options.missingKeyHandler(K,d,ie,he,J,i):this.backendConnector?.saveMissing&&this.backendConnector.saveMissing(K,d,ie,he,J,i),this.emit("missingKey",K,d,ie,g)};this.options.saveMissing&&(this.options.saveMissingPlurals&&C?le.forEach(K=>{const ie=this.pluralResolver.getSuffixes(K,i);F&&i[`defaultValue${this.options.pluralSeparator}zero`]&&ie.indexOf(`${this.options.pluralSeparator}zero`)<0&&ie.push(`${this.options.pluralSeparator}zero`),ie.forEach(ue=>{de([K],l+ue,i[`defaultValue${ue}`]||_)})}):de(le,l,_))}g=this.extendTranslation(g,e,i,f,a),R&&g===l&&this.options.appendNamespaceToMissingKey&&(g=`${d}${u}${l}`),(R||U)&&this.options.parseMissingKeyHandler&&(g=this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey?`${d}${u}${l}`:l,U?g:void 0,i))}return s?(f.res=g,f.usedParams=this.getUsedParamsDetails(i),f):g}extendTranslation(e,n,a,i,s){if(this.i18nFormat?.parse)e=this.i18nFormat.parse(e,{...this.options.interpolation.defaultVariables,...a},a.lng||this.language||i.usedLng,i.usedNS,i.usedKey,{resolved:i});else if(!a.skipInterpolation){a.interpolation&&this.interpolator.init({...a,interpolation:{...this.options.interpolation,...a.interpolation}});const c=qn(e)&&(a?.interpolation?.skipOnVariables!==void 0?a.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables);let d;if(c){const m=e.match(this.interpolator.nestingRegexp);d=m&&m.length}let u=a.replace&&!qn(a.replace)?a.replace:a;if(this.options.interpolation.defaultVariables&&(u={...this.options.interpolation.defaultVariables,...u}),e=this.interpolator.interpolate(e,u,a.lng||this.language||i.usedLng,a),c){const m=e.match(this.interpolator.nestingRegexp),p=m&&m.length;ds?.[0]===m[0]&&!a.context?(this.logger.warn(`It seems you are nesting recursively key: ${m[0]} in key: ${n[0]}`),null):this.translate(...m,n),a)),a.interpolation&&this.interpolator.reset()}const o=a.postProcess||this.options.postProcess,l=qn(o)?[o]:o;return e!=null&&l?.length&&a.applyPostProcessor!==!1&&(e=LY.handle(l,e,n,this.options&&this.options.postProcessPassResolved?{i18nResolved:{...i,usedParams:this.getUsedParamsDetails(a)},...a}:a,this)),e}resolve(e,n={}){let a,i,s,o,l;return qn(e)&&(e=[e]),e.forEach(c=>{if(this.isValidLookup(a))return;const d=this.extractFromKey(c,n),u=d.key;i=u;let m=d.namespaces;this.options.fallbackNS&&(m=m.concat(this.options.fallbackNS));const p=n.count!==void 0&&!qn(n.count),f=p&&!n.ordinal&&n.count===0,g=n.context!==void 0&&(qn(n.context)||typeof n.context=="number")&&n.context!=="",w=n.lngs?n.lngs:this.languageUtils.toResolveHierarchy(n.lng||this.language,n.fallbackLng);m.forEach(b=>{this.isValidLookup(a)||(l=b,!AH[`${w[0]}-${b}`]&&this.utils?.hasLoadedNamespace&&!this.utils?.hasLoadedNamespace(l)&&(AH[`${w[0]}-${b}`]=!0,this.logger.warn(`key "${i}" for languages "${w.join(", ")}" won't get resolved as namespace "${l}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!")),w.forEach(x=>{if(this.isValidLookup(a))return;o=x;const S=[u];if(this.i18nFormat?.addLookupKeys)this.i18nFormat.addLookupKeys(S,u,x,b,n);else{let C;p&&(C=this.pluralResolver.getSuffix(x,n.count,n));const P=`${this.options.pluralSeparator}zero`,T=`${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;if(p&&(n.ordinal&&C.indexOf(T)===0&&S.push(u+C.replace(T,this.options.pluralSeparator)),S.push(u+C),f&&S.push(u+P)),g){const A=`${u}${this.options.contextSeparator||"_"}${n.context}`;S.push(A),p&&(n.ordinal&&C.indexOf(T)===0&&S.push(A+C.replace(T,this.options.pluralSeparator)),S.push(A+C),f&&S.push(A+P))}}let N;for(;N=S.pop();)this.isValidLookup(a)||(s=N,a=this.getResource(x,b,N,n))}))})}),{res:a,usedKey:i,exactUsedKey:s,usedLng:o,usedNS:l}}isValidLookup(e){return e!==void 0&&!(!this.options.returnNull&&e===null)&&!(!this.options.returnEmptyString&&e==="")}getResource(e,n,a,i={}){return this.i18nFormat?.getResource?this.i18nFormat.getResource(e,n,a,i):this.resourceStore.getResource(e,n,a,i)}getUsedParamsDetails(e={}){const n=["defaultValue","ordinal","context","replace","lng","lngs","fallbackLng","ns","keySeparator","nsSeparator","returnObjects","returnDetails","joinArrays","postProcess","interpolation"],a=e.replace&&!qn(e.replace);let i=a?e.replace:e;if(a&&typeof e.count<"u"&&(i.count=e.count),this.options.interpolation.defaultVariables&&(i={...this.options.interpolation.defaultVariables,...i}),!a){i={...i};for(const s of n)delete i[s]}return i}static hasDefaultValue(e){const n="defaultValue";for(const a in e)if(Object.prototype.hasOwnProperty.call(e,a)&&n===a.substring(0,n.length)&&e[a]!==void 0)return!0;return!1}}class jH{constructor(e){this.options=e,this.supportedLngs=this.options.supportedLngs||!1,this.logger=Xd.create("languageUtils")}getScriptPartFromCode(e){if(e=Cw(e),!e||e.indexOf("-")<0)return null;const n=e.split("-");return n.length===2||(n.pop(),n[n.length-1].toLowerCase()==="x")?null:this.formatLanguageCode(n.join("-"))}getLanguagePartFromCode(e){if(e=Cw(e),!e||e.indexOf("-")<0)return e;const n=e.split("-");return this.formatLanguageCode(n[0])}formatLanguageCode(e){if(qn(e)&&e.indexOf("-")>-1){let n;try{n=Intl.getCanonicalLocales(e)[0]}catch{}return n&&this.options.lowerCaseLng&&(n=n.toLowerCase()),n||(this.options.lowerCaseLng?e.toLowerCase():e)}return this.options.cleanCode||this.options.lowerCaseLng?e.toLowerCase():e}isSupportedCode(e){return(this.options.load==="languageOnly"||this.options.nonExplicitSupportedLngs)&&(e=this.getLanguagePartFromCode(e)),!this.supportedLngs||!this.supportedLngs.length||this.supportedLngs.indexOf(e)>-1}getBestMatchFromCodes(e){if(!e)return null;let n;return e.forEach(a=>{if(n)return;const i=this.formatLanguageCode(a);(!this.options.supportedLngs||this.isSupportedCode(i))&&(n=i)}),!n&&this.options.supportedLngs&&e.forEach(a=>{if(n)return;const i=this.getScriptPartFromCode(a);if(this.isSupportedCode(i))return n=i;const s=this.getLanguagePartFromCode(a);if(this.isSupportedCode(s))return n=s;n=this.options.supportedLngs.find(o=>{if(o===s)return o;if(!(o.indexOf("-")<0&&s.indexOf("-")<0)&&(o.indexOf("-")>0&&s.indexOf("-")<0&&o.substring(0,o.indexOf("-"))===s||o.indexOf(s)===0&&s.length>1))return o})}),n||(n=this.getFallbackCodes(this.options.fallbackLng)[0]),n}getFallbackCodes(e,n){if(!e)return[];if(typeof e=="function"&&(e=e(n)),qn(e)&&(e=[e]),Array.isArray(e))return e;if(!n)return e.default||[];let a=e[n];return a||(a=e[this.getScriptPartFromCode(n)]),a||(a=e[this.formatLanguageCode(n)]),a||(a=e[this.getLanguagePartFromCode(n)]),a||(a=e.default),a||[]}toResolveHierarchy(e,n){const a=this.getFallbackCodes((n===!1?[]:n)||this.options.fallbackLng||[],e),i=[],s=o=>{o&&(this.isSupportedCode(o)?i.push(o):this.logger.warn(`rejecting language code not found in supportedLngs: ${o}`))};return qn(e)&&(e.indexOf("-")>-1||e.indexOf("_")>-1)?(this.options.load!=="languageOnly"&&s(this.formatLanguageCode(e)),this.options.load!=="languageOnly"&&this.options.load!=="currentOnly"&&s(this.getScriptPartFromCode(e)),this.options.load!=="currentOnly"&&s(this.getLanguagePartFromCode(e))):qn(e)&&s(this.formatLanguageCode(e)),a.forEach(o=>{i.indexOf(o)<0&&s(this.formatLanguageCode(o))}),i}}const MH={zero:0,one:1,two:2,few:3,many:4,other:5},EH={select:t=>t===1?"one":"other",resolvedOptions:()=>({pluralCategories:["one","other"]})};class tme{constructor(e,n={}){this.languageUtils=e,this.options=n,this.logger=Xd.create("pluralResolver"),this.pluralRulesCache={}}addRule(e,n){this.rules[e]=n}clearCache(){this.pluralRulesCache={}}getRule(e,n={}){const a=Cw(e==="dev"?"en":e),i=n.ordinal?"ordinal":"cardinal",s=JSON.stringify({cleanedCode:a,type:i});if(s in this.pluralRulesCache)return this.pluralRulesCache[s];let o;try{o=new Intl.PluralRules(a,{type:i})}catch{if(!Intl)return this.logger.error("No Intl support, please use an Intl polyfill!"),EH;if(!e.match(/-|_/))return EH;const c=this.languageUtils.getLanguagePartFromCode(e);o=this.getRule(c,n)}return this.pluralRulesCache[s]=o,o}needsPlural(e,n={}){let a=this.getRule(e,n);return a||(a=this.getRule("dev",n)),a?.resolvedOptions().pluralCategories.length>1}getPluralFormsOfKey(e,n,a={}){return this.getSuffixes(e,a).map(i=>`${n}${i}`)}getSuffixes(e,n={}){let a=this.getRule(e,n);return a||(a=this.getRule("dev",n)),a?a.resolvedOptions().pluralCategories.sort((i,s)=>MH[i]-MH[s]).map(i=>`${this.options.prepend}${n.ordinal?`ordinal${this.options.prepend}`:""}${i}`):[]}getSuffix(e,n,a={}){const i=this.getRule(e,a);return i?`${this.options.prepend}${a.ordinal?`ordinal${this.options.prepend}`:""}${i.select(n)}`:(this.logger.warn(`no plural rule found for: ${e}`),this.getSuffix("dev",n,a))}}const DH=(t,e,n,a=".",i=!0)=>{let s=Gue(t,e,n);return!s&&i&&qn(n)&&(s=CF(t,n,a),s===void 0&&(s=CF(e,n,a))),s},eE=t=>t.replace(/\$/g,"$$$$");class nme{constructor(e={}){this.logger=Xd.create("interpolator"),this.options=e,this.format=e?.interpolation?.format||(n=>n),this.init(e)}init(e={}){e.interpolation||(e.interpolation={escapeValue:!0});const{escape:n,escapeValue:a,useRawValueToEscape:i,prefix:s,prefixEscaped:o,suffix:l,suffixEscaped:c,formatSeparator:d,unescapeSuffix:u,unescapePrefix:m,nestingPrefix:p,nestingPrefixEscaped:f,nestingSuffix:g,nestingSuffixEscaped:w,nestingOptionsSeparator:b,maxReplaces:x,alwaysFormat:S}=e.interpolation;this.escape=n!==void 0?n:Kue,this.escapeValue=a!==void 0?a:!0,this.useRawValueToEscape=i!==void 0?i:!1,this.prefix=s?Wb(s):o||"{{",this.suffix=l?Wb(l):c||"}}",this.formatSeparator=d||",",this.unescapePrefix=u?"":m||"-",this.unescapeSuffix=this.unescapePrefix?"":u||"",this.nestingPrefix=p?Wb(p):f||Wb("$t("),this.nestingSuffix=g?Wb(g):w||Wb(")"),this.nestingOptionsSeparator=b||",",this.maxReplaces=x||1e3,this.alwaysFormat=S!==void 0?S:!1,this.resetRegExp()}reset(){this.options&&this.init(this.options)}resetRegExp(){const e=(n,a)=>n?.source===a?(n.lastIndex=0,n):new RegExp(a,"g");this.regexp=e(this.regexp,`${this.prefix}(.+?)${this.suffix}`),this.regexpUnescape=e(this.regexpUnescape,`${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`),this.nestingRegexp=e(this.nestingRegexp,`${this.nestingPrefix}((?:[^()"']+|"[^"]*"|'[^']*'|\\((?:[^()]|"[^"]*"|'[^']*')*\\))*?)${this.nestingSuffix}`)}interpolate(e,n,a,i){let s,o,l;const c=this.options&&this.options.interpolation&&this.options.interpolation.defaultVariables||{},d=f=>{if(f.indexOf(this.formatSeparator)<0){const x=DH(n,c,f,this.options.keySeparator,this.options.ignoreJSONStructure);return this.alwaysFormat?this.format(x,void 0,a,{...i,...n,interpolationkey:f}):x}const g=f.split(this.formatSeparator),w=g.shift().trim(),b=g.join(this.formatSeparator).trim();return this.format(DH(n,c,w,this.options.keySeparator,this.options.ignoreJSONStructure),b,a,{...i,...n,interpolationkey:w})};this.resetRegExp();const u=i?.missingInterpolationHandler||this.options.missingInterpolationHandler,m=i?.interpolation?.skipOnVariables!==void 0?i.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables;return[{regex:this.regexpUnescape,safeValue:f=>eE(f)},{regex:this.regexp,safeValue:f=>this.escapeValue?eE(this.escape(f)):eE(f)}].forEach(f=>{for(l=0;s=f.regex.exec(e);){const g=s[1].trim();if(o=d(g),o===void 0)if(typeof u=="function"){const b=u(e,s,i);o=qn(b)?b:""}else if(i&&Object.prototype.hasOwnProperty.call(i,g))o="";else if(m){o=s[0];continue}else this.logger.warn(`missed to pass in variable ${g} for interpolating ${e}`),o="";else!qn(o)&&!this.useRawValueToEscape&&(o=kH(o));const w=f.safeValue(o);if(e=e.replace(s[0],w),m?(f.regex.lastIndex+=o.length,f.regex.lastIndex-=s[0].length):f.regex.lastIndex=0,l++,l>=this.maxReplaces)break}}),e}nest(e,n,a={}){let i,s,o;const l=(c,d)=>{const u=this.nestingOptionsSeparator;if(c.indexOf(u)<0)return c;const m=c.split(new RegExp(`${u}[ ]*{`));let p=`{${m[1]}`;c=m[0],p=this.interpolate(p,o);const f=p.match(/'/g),g=p.match(/"/g);((f?.length??0)%2===0&&!g||g.length%2!==0)&&(p=p.replace(/'/g,'"'));try{o=JSON.parse(p),d&&(o={...d,...o})}catch(w){return this.logger.warn(`failed parsing options string in nesting for key ${c}`,w),`${c}${u}${p}`}return o.defaultValue&&o.defaultValue.indexOf(this.prefix)>-1&&delete o.defaultValue,c};for(;i=this.nestingRegexp.exec(e);){let c=[];o={...a},o=o.replace&&!qn(o.replace)?o.replace:o,o.applyPostProcessor=!1,delete o.defaultValue;const d=/{.*}/.test(i[1])?i[1].lastIndexOf("}")+1:i[1].indexOf(this.formatSeparator);if(d!==-1&&(c=i[1].slice(d).split(this.formatSeparator).map(u=>u.trim()).filter(Boolean),i[1]=i[1].slice(0,d)),s=n(l.call(this,i[1].trim(),o),o),s&&i[0]===e&&!qn(s))return s;qn(s)||(s=kH(s)),s||(this.logger.warn(`missed to resolve ${i[1]} for nesting ${e}`),s=""),c.length&&(s=c.reduce((u,m)=>this.format(u,m,a.lng,{...a,interpolationkey:i[1].trim()}),s.trim())),e=e.replace(i[0],s),this.regexp.lastIndex=0}return e}}const rme=t=>{let e=t.toLowerCase().trim();const n={};if(t.indexOf("(")>-1){const a=t.split("(");e=a[0].toLowerCase().trim();const i=a[1].substring(0,a[1].length-1);e==="currency"&&i.indexOf(":")<0?n.currency||(n.currency=i.trim()):e==="relativetime"&&i.indexOf(":")<0?n.range||(n.range=i.trim()):i.split(";").forEach(o=>{if(o){const[l,...c]=o.split(":"),d=c.join(":").trim().replace(/^'+|'+$/g,""),u=l.trim();n[u]||(n[u]=d),d==="false"&&(n[u]=!1),d==="true"&&(n[u]=!0),isNaN(d)||(n[u]=parseInt(d,10))}})}return{formatName:e,formatOptions:n}},FH=t=>{const e={};return(n,a,i)=>{let s=i;i&&i.interpolationkey&&i.formatParams&&i.formatParams[i.interpolationkey]&&i[i.interpolationkey]&&(s={...s,[i.interpolationkey]:void 0});const o=a+JSON.stringify(s);let l=e[o];return l||(l=t(Cw(a),i),e[o]=l),l(n)}},ame=t=>(e,n,a)=>t(Cw(n),a)(e);class ime{constructor(e={}){this.logger=Xd.create("formatter"),this.options=e,this.init(e)}init(e,n={interpolation:{}}){this.formatSeparator=n.interpolation.formatSeparator||",";const a=n.cacheInBuiltFormats?FH:ame;this.formats={number:a((i,s)=>{const o=new Intl.NumberFormat(i,{...s});return l=>o.format(l)}),currency:a((i,s)=>{const o=new Intl.NumberFormat(i,{...s,style:"currency"});return l=>o.format(l)}),datetime:a((i,s)=>{const o=new Intl.DateTimeFormat(i,{...s});return l=>o.format(l)}),relativetime:a((i,s)=>{const o=new Intl.RelativeTimeFormat(i,{...s});return l=>o.format(l,s.range||"day")}),list:a((i,s)=>{const o=new Intl.ListFormat(i,{...s});return l=>o.format(l)})}}add(e,n){this.formats[e.toLowerCase().trim()]=n}addCached(e,n){this.formats[e.toLowerCase().trim()]=FH(n)}format(e,n,a,i={}){const s=n.split(this.formatSeparator);if(s.length>1&&s[0].indexOf("(")>1&&s[0].indexOf(")")<0&&s.find(l=>l.indexOf(")")>-1)){const l=s.findIndex(c=>c.indexOf(")")>-1);s[0]=[s[0],...s.splice(1,l)].join(this.formatSeparator)}return s.reduce((l,c)=>{const{formatName:d,formatOptions:u}=rme(c);if(this.formats[d]){let m=l;try{const p=i?.formatParams?.[i.interpolationkey]||{},f=p.locale||p.lng||i.locale||i.lng||a;m=this.formats[d](l,f,{...u,...i,...p})}catch(p){this.logger.warn(p)}return m}else this.logger.warn(`there was no format function for ${d}`);return l},e)}}const sme=(t,e)=>{t.pending[e]!==void 0&&(delete t.pending[e],t.pendingCount--)};class ome extends xT{constructor(e,n,a,i={}){super(),this.backend=e,this.store=n,this.services=a,this.languageUtils=a.languageUtils,this.options=i,this.logger=Xd.create("backendConnector"),this.waitingReads=[],this.maxParallelReads=i.maxParallelReads||10,this.readingCalls=0,this.maxRetries=i.maxRetries>=0?i.maxRetries:5,this.retryTimeout=i.retryTimeout>=1?i.retryTimeout:350,this.state={},this.queue=[],this.backend?.init?.(a,i.backend,i)}queueLoad(e,n,a,i){const s={},o={},l={},c={};return e.forEach(d=>{let u=!0;n.forEach(m=>{const p=`${d}|${m}`;!a.reload&&this.store.hasResourceBundle(d,m)?this.state[p]=2:this.state[p]<0||(this.state[p]===1?o[p]===void 0&&(o[p]=!0):(this.state[p]=1,u=!1,o[p]===void 0&&(o[p]=!0),s[p]===void 0&&(s[p]=!0),c[m]===void 0&&(c[m]=!0)))}),u||(l[d]=!0)}),(Object.keys(s).length||Object.keys(o).length)&&this.queue.push({pending:o,pendingCount:Object.keys(o).length,loaded:{},errors:[],callback:i}),{toLoad:Object.keys(s),pending:Object.keys(o),toLoadLanguages:Object.keys(l),toLoadNamespaces:Object.keys(c)}}loaded(e,n,a){const i=e.split("|"),s=i[0],o=i[1];n&&this.emit("failedLoading",s,o,n),!n&&a&&this.store.addResourceBundle(s,o,a,void 0,void 0,{skipCopy:!0}),this.state[e]=n?-1:2,n&&a&&(this.state[e]=0);const l={};this.queue.forEach(c=>{Vue(c.loaded,[s],o),sme(c,e),n&&c.errors.push(n),c.pendingCount===0&&!c.done&&(Object.keys(c.loaded).forEach(d=>{l[d]||(l[d]={});const u=c.loaded[d];u.length&&u.forEach(m=>{l[d][m]===void 0&&(l[d][m]=!0)})}),c.done=!0,c.errors.length?c.callback(c.errors):c.callback())}),this.emit("loaded",l),this.queue=this.queue.filter(c=>!c.done)}read(e,n,a,i=0,s=this.retryTimeout,o){if(!e.length)return o(null,{});if(this.readingCalls>=this.maxParallelReads){this.waitingReads.push({lng:e,ns:n,fcName:a,tried:i,wait:s,callback:o});return}this.readingCalls++;const l=(d,u)=>{if(this.readingCalls--,this.waitingReads.length>0){const m=this.waitingReads.shift();this.read(m.lng,m.ns,m.fcName,m.tried,m.wait,m.callback)}if(d&&u&&i{this.read.call(this,e,n,a,i+1,s*2,o)},s);return}o(d,u)},c=this.backend[a].bind(this.backend);if(c.length===2){try{const d=c(e,n);d&&typeof d.then=="function"?d.then(u=>l(null,u)).catch(l):l(null,d)}catch(d){l(d)}return}return c(e,n,l)}prepareLoading(e,n,a={},i){if(!this.backend)return this.logger.warn("No backend was added via i18next.use. Will not load resources."),i&&i();qn(e)&&(e=this.languageUtils.toResolveHierarchy(e)),qn(n)&&(n=[n]);const s=this.queueLoad(e,n,a,i);if(!s.toLoad.length)return s.pending.length||i(),null;s.toLoad.forEach(o=>{this.loadOne(o)})}load(e,n,a){this.prepareLoading(e,n,{},a)}reload(e,n,a){this.prepareLoading(e,n,{reload:!0},a)}loadOne(e,n=""){const a=e.split("|"),i=a[0],s=a[1];this.read(i,s,"read",void 0,void 0,(o,l)=>{o&&this.logger.warn(`${n}loading namespace ${s} for language ${i} failed`,o),!o&&l&&this.logger.log(`${n}loaded namespace ${s} for language ${i}`,l),this.loaded(e,o,l)})}saveMissing(e,n,a,i,s,o={},l=()=>{}){if(this.services?.utils?.hasLoadedNamespace&&!this.services?.utils?.hasLoadedNamespace(n)){this.logger.warn(`did not save key "${a}" as the namespace "${n}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");return}if(!(a==null||a==="")){if(this.backend?.create){const c={...o,isUpdate:s},d=this.backend.create.bind(this.backend);if(d.length<6)try{let u;d.length===5?u=d(e,n,a,i,c):u=d(e,n,a,i),u&&typeof u.then=="function"?u.then(m=>l(null,m)).catch(l):l(null,u)}catch(u){l(u)}else d(e,n,a,i,l,c)}!e||!e[0]||this.store.addResource(e[0],n,a,i)}}}const LH=()=>({debug:!1,initAsync:!0,ns:["translation"],defaultNS:["translation"],fallbackLng:["dev"],fallbackNS:!1,supportedLngs:!1,nonExplicitSupportedLngs:!1,load:"all",preload:!1,simplifyPluralSuffix:!0,keySeparator:".",nsSeparator:":",pluralSeparator:"_",contextSeparator:"_",partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:"fallback",saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,postProcessPassResolved:!1,returnNull:!1,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:!1,parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:t=>{let e={};if(typeof t[1]=="object"&&(e=t[1]),qn(t[1])&&(e.defaultValue=t[1]),qn(t[2])&&(e.tDescription=t[2]),typeof t[2]=="object"||typeof t[3]=="object"){const n=t[3]||t[2];Object.keys(n).forEach(a=>{e[a]=n[a]})}return e},interpolation:{escapeValue:!0,format:t=>t,prefix:"{{",suffix:"}}",formatSeparator:",",unescapePrefix:"-",nestingPrefix:"$t(",nestingSuffix:")",nestingOptionsSeparator:",",maxReplaces:1e3,skipOnVariables:!0},cacheInBuiltFormats:!0}),RH=t=>(qn(t.ns)&&(t.ns=[t.ns]),qn(t.fallbackLng)&&(t.fallbackLng=[t.fallbackLng]),qn(t.fallbackNS)&&(t.fallbackNS=[t.fallbackNS]),t.supportedLngs?.indexOf?.("cimode")<0&&(t.supportedLngs=t.supportedLngs.concat(["cimode"])),typeof t.initImmediate=="boolean"&&(t.initAsync=t.initImmediate),t),_k=()=>{},lme=t=>{Object.getOwnPropertyNames(Object.getPrototypeOf(t)).forEach(n=>{typeof t[n]=="function"&&(t[n]=t[n].bind(t))})};class Q0 extends xT{constructor(e={},n){if(super(),this.options=RH(e),this.services={},this.logger=Xd,this.modules={external:[]},lme(this),n&&!this.isInitialized&&!e.isClone){if(!this.options.initAsync)return this.init(e,n),this;setTimeout(()=>{this.init(e,n)},0)}}init(e={},n){this.isInitializing=!0,typeof e=="function"&&(n=e,e={}),e.defaultNS==null&&e.ns&&(qn(e.ns)?e.defaultNS=e.ns:e.ns.indexOf("translation")<0&&(e.defaultNS=e.ns[0]));const a=LH();this.options={...a,...this.options,...RH(e)},this.options.interpolation={...a.interpolation,...this.options.interpolation},e.keySeparator!==void 0&&(this.options.userDefinedKeySeparator=e.keySeparator),e.nsSeparator!==void 0&&(this.options.userDefinedNsSeparator=e.nsSeparator);const i=d=>d?typeof d=="function"?new d:d:null;if(!this.options.isClone){this.modules.logger?Xd.init(i(this.modules.logger),this.options):Xd.init(null,this.options);let d;this.modules.formatter?d=this.modules.formatter:d=ime;const u=new jH(this.options);this.store=new TH(this.options.resources,this.options);const m=this.services;m.logger=Xd,m.resourceStore=this.store,m.languageUtils=u,m.pluralResolver=new tme(u,{prepend:this.options.pluralSeparator,simplifyPluralSuffix:this.options.simplifyPluralSuffix}),this.options.interpolation.format&&this.options.interpolation.format!==a.interpolation.format&&this.logger.deprecate("init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting"),d&&(!this.options.interpolation.format||this.options.interpolation.format===a.interpolation.format)&&(m.formatter=i(d),m.formatter.init&&m.formatter.init(m,this.options),this.options.interpolation.format=m.formatter.format.bind(m.formatter)),m.interpolator=new nme(this.options),m.utils={hasLoadedNamespace:this.hasLoadedNamespace.bind(this)},m.backendConnector=new ome(i(this.modules.backend),m.resourceStore,m,this.options),m.backendConnector.on("*",(f,...g)=>{this.emit(f,...g)}),this.modules.languageDetector&&(m.languageDetector=i(this.modules.languageDetector),m.languageDetector.init&&m.languageDetector.init(m,this.options.detection,this.options)),this.modules.i18nFormat&&(m.i18nFormat=i(this.modules.i18nFormat),m.i18nFormat.init&&m.i18nFormat.init(this)),this.translator=new WN(this.services,this.options),this.translator.on("*",(f,...g)=>{this.emit(f,...g)}),this.modules.external.forEach(f=>{f.init&&f.init(this)})}if(this.format=this.options.interpolation.format,n||(n=_k),this.options.fallbackLng&&!this.services.languageDetector&&!this.options.lng){const d=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);d.length>0&&d[0]!=="dev"&&(this.options.lng=d[0])}!this.services.languageDetector&&!this.options.lng&&this.logger.warn("init: no languageDetector is used and no lng is defined"),["getResource","hasResourceBundle","getResourceBundle","getDataByLanguage"].forEach(d=>{this[d]=(...u)=>this.store[d](...u)}),["addResource","addResources","addResourceBundle","removeResourceBundle"].forEach(d=>{this[d]=(...u)=>(this.store[d](...u),this)});const l=Yv(),c=()=>{const d=(u,m)=>{this.isInitializing=!1,this.isInitialized&&!this.initializedStoreOnce&&this.logger.warn("init: i18next is already initialized. You should call init just once!"),this.isInitialized=!0,this.options.isClone||this.logger.log("initialized",this.options),this.emit("initialized",this.options),l.resolve(m),n(u,m)};if(this.languages&&!this.isInitialized)return d(null,this.t.bind(this));this.changeLanguage(this.options.lng,d)};return this.options.resources||!this.options.initAsync?c():setTimeout(c,0),l}loadResources(e,n=_k){let a=n;const i=qn(e)?e:this.language;if(typeof e=="function"&&(a=e),!this.options.resources||this.options.partialBundledLanguages){if(i?.toLowerCase()==="cimode"&&(!this.options.preload||this.options.preload.length===0))return a();const s=[],o=l=>{if(!l||l==="cimode")return;this.services.languageUtils.toResolveHierarchy(l).forEach(d=>{d!=="cimode"&&s.indexOf(d)<0&&s.push(d)})};i?o(i):this.services.languageUtils.getFallbackCodes(this.options.fallbackLng).forEach(c=>o(c)),this.options.preload?.forEach?.(l=>o(l)),this.services.backendConnector.load(s,this.options.ns,l=>{!l&&!this.resolvedLanguage&&this.language&&this.setResolvedLanguage(this.language),a(l)})}else a(null)}reloadResources(e,n,a){const i=Yv();return typeof e=="function"&&(a=e,e=void 0),typeof n=="function"&&(a=n,n=void 0),e||(e=this.languages),n||(n=this.options.ns),a||(a=_k),this.services.backendConnector.reload(e,n,s=>{i.resolve(),a(s)}),i}use(e){if(!e)throw new Error("You are passing an undefined module! Please check the object you are passing to i18next.use()");if(!e.type)throw new Error("You are passing a wrong module! Please check the object you are passing to i18next.use()");return e.type==="backend"&&(this.modules.backend=e),(e.type==="logger"||e.log&&e.warn&&e.error)&&(this.modules.logger=e),e.type==="languageDetector"&&(this.modules.languageDetector=e),e.type==="i18nFormat"&&(this.modules.i18nFormat=e),e.type==="postProcessor"&&LY.addPostProcessor(e),e.type==="formatter"&&(this.modules.formatter=e),e.type==="3rdParty"&&this.modules.external.push(e),this}setResolvedLanguage(e){if(!(!e||!this.languages)&&!(["cimode","dev"].indexOf(e)>-1)){for(let n=0;n-1)&&this.store.hasLanguageSomeTranslations(a)){this.resolvedLanguage=a;break}}!this.resolvedLanguage&&this.languages.indexOf(e)<0&&this.store.hasLanguageSomeTranslations(e)&&(this.resolvedLanguage=e,this.languages.unshift(e))}}changeLanguage(e,n){this.isLanguageChangingTo=e;const a=Yv();this.emit("languageChanging",e);const i=l=>{this.language=l,this.languages=this.services.languageUtils.toResolveHierarchy(l),this.resolvedLanguage=void 0,this.setResolvedLanguage(l)},s=(l,c)=>{c?this.isLanguageChangingTo===e&&(i(c),this.translator.changeLanguage(c),this.isLanguageChangingTo=void 0,this.emit("languageChanged",c),this.logger.log("languageChanged",c)):this.isLanguageChangingTo=void 0,a.resolve((...d)=>this.t(...d)),n&&n(l,(...d)=>this.t(...d))},o=l=>{!e&&!l&&this.services.languageDetector&&(l=[]);const c=qn(l)?l:l&&l[0],d=this.store.hasLanguageSomeTranslations(c)?c:this.services.languageUtils.getBestMatchFromCodes(qn(l)?[l]:l);d&&(this.language||i(d),this.translator.language||this.translator.changeLanguage(d),this.services.languageDetector?.cacheUserLanguage?.(d)),this.loadResources(d,u=>{s(u,d)})};return!e&&this.services.languageDetector&&!this.services.languageDetector.async?o(this.services.languageDetector.detect()):!e&&this.services.languageDetector&&this.services.languageDetector.async?this.services.languageDetector.detect.length===0?this.services.languageDetector.detect().then(o):this.services.languageDetector.detect(o):o(e),a}getFixedT(e,n,a){const i=(s,o,...l)=>{let c;typeof o!="object"?c=this.options.overloadTranslationOptionHandler([s,o].concat(l)):c={...o},c.lng=c.lng||i.lng,c.lngs=c.lngs||i.lngs,c.ns=c.ns||i.ns,c.keyPrefix!==""&&(c.keyPrefix=c.keyPrefix||a||i.keyPrefix);const d=this.options.keySeparator||".";let u;return c.keyPrefix&&Array.isArray(s)?u=s.map(m=>(typeof m=="function"&&(m=PF(m,{...this.options,...o})),`${c.keyPrefix}${d}${m}`)):(typeof s=="function"&&(s=PF(s,{...this.options,...o})),u=c.keyPrefix?`${c.keyPrefix}${d}${s}`:s),this.t(u,c)};return qn(e)?i.lng=e:i.lngs=e,i.ns=n,i.keyPrefix=a,i}t(...e){return this.translator?.translate(...e)}exists(...e){return this.translator?.exists(...e)}setDefaultNamespace(e){this.options.defaultNS=e}hasLoadedNamespace(e,n={}){if(!this.isInitialized)return this.logger.warn("hasLoadedNamespace: i18next was not initialized",this.languages),!1;if(!this.languages||!this.languages.length)return this.logger.warn("hasLoadedNamespace: i18n.languages were undefined or empty",this.languages),!1;const a=n.lng||this.resolvedLanguage||this.languages[0],i=this.options?this.options.fallbackLng:!1,s=this.languages[this.languages.length-1];if(a.toLowerCase()==="cimode")return!0;const o=(l,c)=>{const d=this.services.backendConnector.state[`${l}|${c}`];return d===-1||d===0||d===2};if(n.precheck){const l=n.precheck(this,o);if(l!==void 0)return l}return!!(this.hasResourceBundle(a,e)||!this.services.backendConnector.backend||this.options.resources&&!this.options.partialBundledLanguages||o(a,e)&&(!i||o(s,e)))}loadNamespaces(e,n){const a=Yv();return this.options.ns?(qn(e)&&(e=[e]),e.forEach(i=>{this.options.ns.indexOf(i)<0&&this.options.ns.push(i)}),this.loadResources(i=>{a.resolve(),n&&n(i)}),a):(n&&n(),Promise.resolve())}loadLanguages(e,n){const a=Yv();qn(e)&&(e=[e]);const i=this.options.preload||[],s=e.filter(o=>i.indexOf(o)<0&&this.services.languageUtils.isSupportedCode(o));return s.length?(this.options.preload=i.concat(s),this.loadResources(o=>{a.resolve(),n&&n(o)}),a):(n&&n(),Promise.resolve())}dir(e){if(e||(e=this.resolvedLanguage||(this.languages?.length>0?this.languages[0]:this.language)),!e)return"rtl";try{const i=new Intl.Locale(e);if(i&&i.getTextInfo){const s=i.getTextInfo();if(s&&s.direction)return s.direction}}catch{}const n=["ar","shu","sqr","ssh","xaa","yhd","yud","aao","abh","abv","acm","acq","acw","acx","acy","adf","ads","aeb","aec","afb","ajp","apc","apd","arb","arq","ars","ary","arz","auz","avl","ayh","ayl","ayn","ayp","bbz","pga","he","iw","ps","pbt","pbu","pst","prp","prd","ug","ur","ydd","yds","yih","ji","yi","hbo","men","xmn","fa","jpr","peo","pes","prs","dv","sam","ckb"],a=this.services?.languageUtils||new jH(LH());return e.toLowerCase().indexOf("-latn")>1?"ltr":n.indexOf(a.getLanguagePartFromCode(e))>-1||e.toLowerCase().indexOf("-arab")>1?"rtl":"ltr"}static createInstance(e={},n){const a=new Q0(e,n);return a.createInstance=Q0.createInstance,a}cloneInstance(e={},n=_k){const a=e.forkResourceStore;a&&delete e.forkResourceStore;const i={...this.options,...e,isClone:!0},s=new Q0(i);if((e.debug!==void 0||e.prefix!==void 0)&&(s.logger=s.logger.clone(e)),["store","services","language"].forEach(l=>{s[l]=this[l]}),s.services={...this.services},s.services.utils={hasLoadedNamespace:s.hasLoadedNamespace.bind(s)},a){const l=Object.keys(this.store.data).reduce((c,d)=>(c[d]={...this.store.data[d]},c[d]=Object.keys(c[d]).reduce((u,m)=>(u[m]={...c[d][m]},u),c[d]),c),{});s.store=new TH(l,i),s.services.resourceStore=s.store}return s.translator=new WN(s.services,i),s.translator.on("*",(l,...c)=>{s.emit(l,...c)}),s.init(i,n),s.translator.options=i,s.translator.backendConnector.services.utils={hasLoadedNamespace:s.hasLoadedNamespace.bind(s)},s}toJSON(){return{options:this.options,store:this.store,language:this.language,languages:this.languages,resolvedLanguage:this.resolvedLanguage}}}const Mo=Q0.createInstance();Mo.createInstance;Mo.dir;Mo.init;Mo.loadResources;Mo.reloadResources;Mo.use;Mo.changeLanguage;Mo.getFixedT;Mo.t;Mo.exists;Mo.setDefaultNamespace;Mo.hasLoadedNamespace;Mo.loadNamespaces;Mo.loadLanguages;const cme=(t,e,n,a)=>{const i=[n,{code:e,...a||{}}];if(t?.services?.logger?.forward)return t.services.logger.forward(i,"warn","react-i18next::",!0);Pg(i[0])&&(i[0]=`react-i18next:: ${i[0]}`),t?.services?.logger?.warn?t.services.logger.warn(...i):console?.warn&&console.warn(...i)},IH={},IY=(t,e,n,a)=>{Pg(n)&&IH[n]||(Pg(n)&&(IH[n]=new Date),cme(t,e,n,a))},OY=(t,e)=>()=>{if(t.isInitialized)e();else{const n=()=>{setTimeout(()=>{t.off("initialized",n)},0),e()};t.on("initialized",n)}},TF=(t,e,n)=>{t.loadNamespaces(e,OY(t,n))},OH=(t,e,n,a)=>{if(Pg(n)&&(n=[n]),t.options.preload&&t.options.preload.indexOf(e)>-1)return TF(t,n,a);n.forEach(i=>{t.options.ns.indexOf(i)<0&&t.options.ns.push(i)}),t.loadLanguages(e,OY(t,a))},dme=(t,e,n={})=>!e.languages||!e.languages.length?(IY(e,"NO_LANGUAGES","i18n.languages were undefined or empty",{languages:e.languages}),!0):e.hasLoadedNamespace(t,{lng:n.lng,precheck:(a,i)=>{if(n.bindI18n&&n.bindI18n.indexOf("languageChanging")>-1&&a.services.backendConnector.backend&&a.isLanguageChangingTo&&!i(a.isLanguageChangingTo,t))return!1}}),Pg=t=>typeof t=="string",ume=t=>typeof t=="object"&&t!==null,mme=/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g,pme={"&":"&","&":"&","<":"<","<":"<",">":">",">":">","'":"'","'":"'",""":'"',""":'"'," ":" "," ":" ","©":"©","©":"©","®":"®","®":"®","…":"…","…":"…","/":"/","/":"/"},hme=t=>pme[t],fme=t=>t.replace(mme,hme);let AF={bindI18n:"languageChanged",bindI18nStore:"",transEmptyNodeValue:"",transSupportBasicHtmlNodes:!0,transWrapTextNodes:"",transKeepBasicHtmlNodesFor:["br","strong","i","p"],useSuspense:!0,unescape:fme,transDefaultProps:void 0};const gme=(t={})=>{AF={...AF,...t}},bme=()=>AF;let zY;const xme=t=>{zY=t},yme=()=>zY,vme={type:"3rdParty",init(t){gme(t.options.react),xme(t)}},wme=y.createContext();class Sme{constructor(){this.usedNamespaces={}}addUsedNamespaces(e){e.forEach(n=>{this.usedNamespaces[n]||(this.usedNamespaces[n]=!0)})}getUsedNamespaces(){return Object.keys(this.usedNamespaces)}}var tE={exports:{}},nE={};var zH;function _me(){if(zH)return nE;zH=1;var t=tb();function e(m,p){return m===p&&(m!==0||1/m===1/p)||m!==m&&p!==p}var n=typeof Object.is=="function"?Object.is:e,a=t.useState,i=t.useEffect,s=t.useLayoutEffect,o=t.useDebugValue;function l(m,p){var f=p(),g=a({inst:{value:f,getSnapshot:p}}),w=g[0].inst,b=g[1];return s(function(){w.value=f,w.getSnapshot=p,c(w)&&b({inst:w})},[m,f,p]),i(function(){return c(w)&&b({inst:w}),m(function(){c(w)&&b({inst:w})})},[m]),o(f),f}function c(m){var p=m.getSnapshot;m=m.value;try{var f=p();return!n(m,f)}catch{return!0}}function d(m,p){return p()}var u=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?d:l;return nE.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:u,nE}var UH;function UY(){return UH||(UH=1,tE.exports=_me()),tE.exports}var eO=UY();const kme=(t,e)=>Pg(e)?e:ume(e)&&Pg(e.defaultValue)?e.defaultValue:Array.isArray(t)?t[t.length-1]:t,Nme={t:kme,ready:!1},Cme=()=>()=>{},St=(t,e={})=>{const{i18n:n}=e,{i18n:a,defaultNS:i}=y.useContext(wme)||{},s=n||a||yme();s&&!s.reportNamespaces&&(s.reportNamespaces=new Sme),s||IY(s,"NO_I18NEXT_INSTANCE","useTranslation: You will need to pass in an i18next instance by using initReactI18next");const o=y.useMemo(()=>({...bme(),...s?.options?.react,...e}),[s,e]),{useSuspense:l,keyPrefix:c}=o,d=i||s?.options?.defaultNS,u=Pg(d)?[d]:d||["translation"],m=y.useMemo(()=>u,u);s?.reportNamespaces?.addUsedNamespaces?.(m);const p=y.useRef(0),f=y.useCallback(_=>{if(!s)return Cme;const{bindI18n:E,bindI18nStore:H}=o,I=()=>{p.current+=1,_()};return E&&s.on(E,I),H&&s.store.on(H,I),()=>{E&&E.split(" ").forEach(U=>s.off(U,I)),H&&H.split(" ").forEach(U=>s.store.off(U,I))}},[s,o]),g=y.useRef(),w=y.useCallback(()=>{if(!s)return Nme;const _=!!(s.isInitialized||s.initializedStoreOnce)&&m.every(Y=>dme(Y,s,o)),E=e.lng||s.language,H=p.current,I=g.current;if(I&&I.ready===_&&I.lng===E&&I.keyPrefix===c&&I.revision===H)return I;const R={t:s.getFixedT(E,o.nsMode==="fallback"?m:m[0],c),ready:_,lng:E,keyPrefix:c,revision:H};return g.current=R,R},[s,m,c,o,e.lng]),[b,x]=y.useState(0),{t:S,ready:N}=eO.useSyncExternalStore(f,w,w);y.useEffect(()=>{if(s&&!N&&!l){const _=()=>x(E=>E+1);e.lng?OH(s,e.lng,m,_):TF(s,m,_)}},[s,e.lng,m,N,l,b]);const C=s||{},P=y.useRef(null),T=y.useRef(),A=_=>{const E=Object.getOwnPropertyDescriptors(_);E.__original&&delete E.__original;const H=Object.create(Object.getPrototypeOf(_),E);if(!Object.prototype.hasOwnProperty.call(H,"__original"))try{Object.defineProperty(H,"__original",{value:_,writable:!1,enumerable:!1,configurable:!1})}catch{}return H},F=y.useMemo(()=>{const _=C,E=_?.language;let H=_;_&&(P.current&&P.current.__original===_?T.current!==E?(H=A(_),P.current=H,T.current=E):H=P.current:(H=A(_),P.current=H,T.current=E));const I=[S,H,N];return I.t=S,I.i18n=H,I.ready=N,I},[S,C,N,C.resolvedLanguage,C.language,C.languages]);if(s&&l&&!N)throw new Promise(_=>{const E=()=>_();e.lng?OH(s,e.lng,m,E):TF(s,m,E)});return F},{slice:Pme,forEach:Tme}=[];function Ame(t){return Tme.call(Pme.call(arguments,1),e=>{if(e)for(const n in e)t[n]===void 0&&(t[n]=e[n])}),t}function jme(t){return typeof t!="string"?!1:[/<\s*script.*?>/i,/<\s*\/\s*script\s*>/i,/<\s*img.*?on\w+\s*=/i,/<\s*\w+\s*on\w+\s*=.*?>/i,/javascript\s*:/i,/vbscript\s*:/i,/expression\s*\(/i,/eval\s*\(/i,/alert\s*\(/i,/document\.cookie/i,/document\.write\s*\(/i,/window\.location/i,/innerHTML/i].some(n=>n.test(t))}const BH=/^[\u0009\u0020-\u007e\u0080-\u00ff]+$/,Mme=function(t,e){const a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{path:"/"},i=encodeURIComponent(e);let s=`${t}=${i}`;if(a.maxAge>0){const o=a.maxAge-0;if(Number.isNaN(o))throw new Error("maxAge should be a Number");s+=`; Max-Age=${Math.floor(o)}`}if(a.domain){if(!BH.test(a.domain))throw new TypeError("option domain is invalid");s+=`; Domain=${a.domain}`}if(a.path){if(!BH.test(a.path))throw new TypeError("option path is invalid");s+=`; Path=${a.path}`}if(a.expires){if(typeof a.expires.toUTCString!="function")throw new TypeError("option expires is invalid");s+=`; Expires=${a.expires.toUTCString()}`}if(a.httpOnly&&(s+="; HttpOnly"),a.secure&&(s+="; Secure"),a.sameSite)switch(typeof a.sameSite=="string"?a.sameSite.toLowerCase():a.sameSite){case!0:s+="; SameSite=Strict";break;case"lax":s+="; SameSite=Lax";break;case"strict":s+="; SameSite=Strict";break;case"none":s+="; SameSite=None";break;default:throw new TypeError("option sameSite is invalid")}return a.partitioned&&(s+="; Partitioned"),s},HH={create(t,e,n,a){let i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:{path:"/",sameSite:"strict"};n&&(i.expires=new Date,i.expires.setTime(i.expires.getTime()+n*60*1e3)),a&&(i.domain=a),document.cookie=Mme(t,e,i)},read(t){const e=`${t}=`,n=document.cookie.split(";");for(let a=0;a-1&&(a=window.location.hash.substring(window.location.hash.indexOf("?")));const s=a.substring(1).split("&");for(let o=0;o0&&s[o].substring(0,l)===e&&(n=s[o].substring(l+1))}}return n}},Fme={name:"hash",lookup(t){let{lookupHash:e,lookupFromHashIndex:n}=t,a;if(typeof window<"u"){const{hash:i}=window.location;if(i&&i.length>2){const s=i.substring(1);if(e){const o=s.split("&");for(let l=0;l0&&o[l].substring(0,c)===e&&(a=o[l].substring(c+1))}}if(a)return a;if(!a&&n>-1){const o=i.match(/\/([a-zA-Z-]*)/g);return Array.isArray(o)?o[typeof n=="number"?n:0]?.replace("/",""):void 0}}}return a}};let Kb=null;const qH=()=>{if(Kb!==null)return Kb;try{if(Kb=typeof window<"u"&&window.localStorage!==null,!Kb)return!1;const t="i18next.translate.boo";window.localStorage.setItem(t,"foo"),window.localStorage.removeItem(t)}catch{Kb=!1}return Kb};var Lme={name:"localStorage",lookup(t){let{lookupLocalStorage:e}=t;if(e&&qH())return window.localStorage.getItem(e)||void 0},cacheUserLanguage(t,e){let{lookupLocalStorage:n}=e;n&&qH()&&window.localStorage.setItem(n,t)}};let Qb=null;const $H=()=>{if(Qb!==null)return Qb;try{if(Qb=typeof window<"u"&&window.sessionStorage!==null,!Qb)return!1;const t="i18next.translate.boo";window.sessionStorage.setItem(t,"foo"),window.sessionStorage.removeItem(t)}catch{Qb=!1}return Qb};var Rme={name:"sessionStorage",lookup(t){let{lookupSessionStorage:e}=t;if(e&&$H())return window.sessionStorage.getItem(e)||void 0},cacheUserLanguage(t,e){let{lookupSessionStorage:n}=e;n&&$H()&&window.sessionStorage.setItem(n,t)}},Ime={name:"navigator",lookup(t){const e=[];if(typeof navigator<"u"){const{languages:n,userLanguage:a,language:i}=navigator;if(n)for(let s=0;s0?e:void 0}},Ome={name:"htmlTag",lookup(t){let{htmlTag:e}=t,n;const a=e||(typeof document<"u"?document.documentElement:null);return a&&typeof a.getAttribute=="function"&&(n=a.getAttribute("lang")),n}},zme={name:"path",lookup(t){let{lookupFromPathIndex:e}=t;if(typeof window>"u")return;const n=window.location.pathname.match(/\/([a-zA-Z-]*)/g);return Array.isArray(n)?n[typeof e=="number"?e:0]?.replace("/",""):void 0}},Ume={name:"subdomain",lookup(t){let{lookupFromSubdomainIndex:e}=t;const n=typeof e=="number"?e+1:1,a=typeof window<"u"&&window.location?.hostname?.match(/^(\w{2,5})\.(([a-z0-9-]{1,63}\.[a-z]{2,6})|localhost)/i);if(a)return a[n]}};let BY=!1;try{document.cookie,BY=!0}catch{}const HY=["querystring","cookie","localStorage","sessionStorage","navigator","htmlTag"];BY||HY.splice(1,1);const Bme=()=>({order:HY,lookupQuerystring:"lng",lookupCookie:"i18next",lookupLocalStorage:"i18nextLng",lookupSessionStorage:"i18nextLng",caches:["localStorage"],excludeCacheFor:["cimode"],convertDetectedLanguage:t=>t});class qY{constructor(e){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};this.type="languageDetector",this.detectors={},this.init(e,n)}init(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{languageUtils:{}},n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};this.services=e,this.options=Ame(n,this.options||{},Bme()),typeof this.options.convertDetectedLanguage=="string"&&this.options.convertDetectedLanguage.indexOf("15897")>-1&&(this.options.convertDetectedLanguage=i=>i.replace("-","_")),this.options.lookupFromUrlIndex&&(this.options.lookupFromPathIndex=this.options.lookupFromUrlIndex),this.i18nOptions=a,this.addDetector(Eme),this.addDetector(Dme),this.addDetector(Lme),this.addDetector(Rme),this.addDetector(Ime),this.addDetector(Ome),this.addDetector(zme),this.addDetector(Ume),this.addDetector(Fme)}addDetector(e){return this.detectors[e.name]=e,this}detect(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:this.options.order,n=[];return e.forEach(a=>{if(this.detectors[a]){let i=this.detectors[a].lookup(this.options);i&&typeof i=="string"&&(i=[i]),i&&(n=n.concat(i))}}),n=n.filter(a=>a!=null&&!jme(a)).map(a=>this.options.convertDetectedLanguage(a)),this.services&&this.services.languageUtils&&this.services.languageUtils.getBestMatchFromCodes?n:n.length>0?n[0]:null}cacheUserLanguage(e){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.options.caches;n&&(this.options.excludeCacheFor&&this.options.excludeCacheFor.indexOf(e)>-1||n.forEach(a=>{this.detectors[a]&&this.detectors[a].cacheUserLanguage(e,this.options)}))}}qY.type="languageDetector";const Hme={nav:{printers:"Printers",archives:"Archives",queue:"Print Queue",stats:"Statistics",profiles:"Profiles",maintenance:"Maintenance",projects:"Projects",inventory:"Filament",files:"File Manager",makerworld:"MakerWorld",notifications:"Notifications",settings:"Settings",system:"System",collapseSidebar:"Collapse sidebar",expandSidebar:"Expand sidebar",update:"Update",updateAvailable:"Update available: v{{version}}",updateAvailableBanner:"Version {{version}} is available!",viewUpdate:"View update",viewOnGithub:"View on GitHub",keyboardShortcuts:"Keyboard shortcuts (?)",switchToLight:"Switch to light mode",switchToDark:"Switch to dark mode",smartSwitches:"Smart Switches",logout:"Logout"},common:{save:"Save",saving:"Saving...",cancel:"Cancel",delete:"Delete",edit:"Edit",add:"Add",close:"Close",confirm:"Confirm",loading:"Loading...",error:"Error",errorLoading:"Error loading data",retry:"Retry",success:"Success",warning:"Warning",enabled:"Enabled",disabled:"Disabled",yes:"Yes",no:"No",on:"On",off:"Off",all:"All",none:"None",search:"Search",filter:"Filter",sort:"Sort",refresh:"Refresh",download:"Download",upload:"Upload",uploading:"Uploading...",uploadFailed:"Upload failed",actions:"Actions",status:"Status",name:"Name",description:"Description",date:"Date",time:"Time",hours:"hours",minutes:"minutes",seconds:"seconds",days:"days",enable:"Enable",disable:"Disable",permissions:"Permissions",noPrinters:"No printers configured",noData:"No data available",linkNotFound:"Link not found",required:"Required",optional:"Optional",dismiss:"Dismiss",apply:"Apply",reset:"Reset",export:"Export",import:"Import",clear:"Clear",selectAll:"Select All",deselectAll:"Deselect All",noChange:"— No change —",unchanged:"Unchanged",unassigned:"Unassigned",unknown:"Unknown",unknownError:"Unknown error",today:"Today",tomorrow:"Tomorrow",asap:"ASAP",overdue:"Overdue",now:"Now",collapse:"Collapse",expand:"Expand",viewArchive:"View archive",viewInFileManager:"View in File Manager",addedBy:"Added by {{username}}",prints:"prints",more:"+{{count}} more",ascending:"Ascending",descending:"Descending",back:"Back",copy:"Copy",copied:"Copied!",printer:"Printer",remove:"Remove",type:"Type",print:"Print",rename:"Rename",move:"Move",create:"Create",duplicate:"Duplicate",left:"Left",right:"Right"},printers:{title:"Printers",addPrinter:"Add Printer",editPrinter:"Edit Printer",deletePrinter:"Delete Printer",printerName:"Printer Name",serialNumber:"Serial Number",ipAddress:"IP Address / Hostname",accessCode:"Access Code",model:"Model",nozzleCount:"Nozzle Count",autoArchive:"Auto Archive",status:{available:"Available",idle:"Idle",printing:"Printing",paused:"Paused",offline:"Offline",problem:"Problem",error:"Error",finished:"Finished",unknown:"Unknown"},temperatures:{nozzle:"Nozzle",bed:"Bed",chamber:"Chamber"},progress:"{{percent}}% complete",timeRemaining:"{{time}} remaining",deleteConfirm:'Are you sure you want to delete "{{name}}"?',maintenanceOk:"Maintenance OK",maintenanceWarning:"{{count}} warning",maintenanceWarning_plural:"{{count}} warnings",maintenanceDue:"{{count}} due",maintenanceDue_plural:"{{count}} due",sort:{name:"Name",status:"Status",model:"Model",location:"Location",ascending:"Sort ascending",descending:"Sort descending"},cardSize:{small:"Small cards",medium:"Medium cards",large:"Large cards",extraLarge:"Extra large cards"},hideOffline:"Hide offline",nextAvailable:"Next available",powerOn:"Power On",offlinePrintersWithPlugs:"Offline printers with smart plugs",noPrintersConfigured:"No printers configured yet",search:"Search printers...",noSearchResults:"No printers match your search or filters",filter:{allStatuses:"All statuses",allLocations:"All locations"},toolbar:{filters:"Filters",view:"View",actions:"Actions"},readyToPrint:"Ready to print",external:"External",extL:"Ext-L",extR:"Ext-R",deleteArchives:"Delete print archives",noLabel:"No label",printPreview:"Print preview",width:"Width",height:"Height",noObjectsFound:"No objects found",objectsLoadedOnPrintStart:"Objects are loaded when a print starts",willBeSkipped:"Will be skipped",name:"Name",serialCannotBeChanged:"Serial number cannot be changed",locationHelp:"Used to group printers and filter queue jobs",wifiSignal:{veryWeak:"Very weak",weak:"Weak",fair:"Fair",good:"Good",excellent:"Excellent"},maintenanceUpToDate:"All maintenance up to date - Click to view",chamberLightOn:"Turn on chamber light",chamberLightOff:"Turn off chamber light",files:"Files",browseFiles:"Browse printer files",autoOffAfterPrint:"Auto power-off after print",autoOffExecuted:"Auto-off was executed - turn printer on to reset",hmsErrors:"HMS Errors",viewHmsErrors:"View {{count}} HMS error(s)",resume:"Resume",pause:"Pause",stop:"Stop",camera:"Camera",skipObject:"Skip Object",reconnect:"Reconnect",forceRefresh:"Force Refresh",forceRefreshSuccess:"Refresh requested",mqttDebug:"MQTT Debug",printerInformation:"Printer Information",copyToClipboard:"Copy",copied:"Copied!",state:"State",wifiSignalLabel:"WiFi Signal",developerMode:"Developer Mode",enabled:"Enabled",disabled:"Disabled",addedOn:"Added",sdCard:"SD Card",inserted:"Inserted",notInserted:"Not inserted",totalPrintHours:"Print Hours",activeNozzle:"Active: {{nozzle}} nozzle",nozzleRack:"Nozzle Rack",nozzleDocked:"Docked",nozzleMounted:"Mounted",nozzleActive:"Active",nozzleIdle:"Idle",nozzleDiameter:"Diameter",nozzleType:"Type",nozzleStatus:"Status",nozzleFilament:"Filament",nozzleWear:"Wear",nozzleMaxTemp:"Max Temp",nozzleSerial:"Serial",nozzleHardenedSteel:"Hardened Steel",nozzleStainlessSteel:"Stainless Steel",nozzleTungstenCarbide:"Tungsten Carbide",nozzleFlow:"Flow",nozzleHighFlow:"High Flow",nozzleStandardFlow:"Standard",firmwareUpdate:"Firmware Update",firmwareInstructions:"On the printer's touchscreen, go to",firmwareNav:"Navigate to",settings:"Settings",firmware:"Firmware",discoverPrinters:"Discover Printers",searching:"Searching...",manualEntry:"Manual Entry",addFromCloud:"Add from Cloud",toast:{printerDeleted:"Printer deleted",missingSpoolAssignment:"Print started on {{printer}}. Missing spool assignment for: {{slots}}",printerAdded:"Printer added",printerUpdated:"Printer updated",failedToDelete:"Failed to delete printer",failedToAdd:"Failed to add printer",failedToUpdate:"Failed to update printer",commandSent:"Command sent",failedToSendCommand:"Failed to send command",turnedOn:"{{name}} turned on",failedToPowerOn:"Failed to power on {{name}}",scriptTriggered:"Script triggered",printStopped:"Print stopped",printPaused:"Print paused",printResumed:"Print resumed",referenceDeleted:"Reference deleted",detectionAreaSaved:"Detection area saved",failedToRunScript:"Failed to run script",failedToStopPrint:"Failed to stop print",failedToPausePrint:"Failed to pause print",failedToResumePrint:"Failed to resume print",failedToControlChamberLight:"Failed to control chamber light",failedToSetSpeed:"Failed to set print speed",failedToUpdateSetting:"Failed to update setting",failedToSkipObjects:"Failed to skip objects",failedToRereadRfid:"Failed to re-read RFID",failedToCheckPlate:"Failed to check plate",failedToUpdateLabel:"Failed to update label",failedToDeleteReference:"Failed to delete reference",failedToSaveDetectionArea:"Failed to save detection area",plateCheckEnabled:"Plate check enabled",plateCheckDisabled:"Plate check disabled",calibrationSaved:"Calibration saved!",calibrationFailed:"Calibration failed",rfidRereadInitiated:"RFID re-read initiated",loadInitiated:"Loading filament…",unloadInitiated:"Unloading filament…",failedToLoad:"Failed to load filament",failedToUnload:"Failed to unload filament"},connection:{connected:"Connected",offline:"Offline"},plateStatus:{markCleared:"Mark plate as cleared",cleared:"Plate Clear",notCleared:"Plate not Clear",inUse:"Plate in Use"},queue:{inQueue:"{{count}} print in queue",inQueue_plural:"{{count}} prints in queue"},controls:"Controls",rfid:{reread:"Re-read RFID"},ams:{load:"Load",unload:"Unload"},bedJog:{title:"Move build plate",bed:"Bed",step:"Step (mm)",up:"Move plate up",down:"Move plate down",disabledWhilePrinting:"Disabled while printing",notHomedTitle:"Printer is not homed",notHomedMessage:"The printer has not been homed since the last print. Run auto-home first for safe positioning (parks the toolhead, then homes X, Y, and Z), or move anyway — soft endstops will be bypassed.",homeZ:"Auto Home",moveAnyway:"Move anyway",homingStarted:"Auto-homing printer…"},permission:{noAdd:"You do not have permission to add printers",noEdit:"You do not have permission to edit printers",noDelete:"You do not have permission to delete printers",noControl:"You do not have permission to control printers",noFiles:"You do not have permission to access printer files",noAmsRfid:"You do not have permission to re-read AMS RFID",noSmartPlugControl:"You do not have permission to control smart plugs",noCamera:"You do not have permission to view cameras"},modal:{addTitle:"Add Printer",editTitle:"Edit Printer",myPrinter:"My Printer",selectModel:"Select model...",locationGroup:"Location / Group (optional)",locationPlaceholder:"e.g., Workshop, Office, Basement",autoArchiveLabel:"Auto-archive completed prints",fromPrinterSettings:"From printer settings",modelOptional:"Model (optional)",saveChanges:"Save Changes"},skipObjects:{tooltip:"Skip objects",onlyWhilePrinting:"Skip objects (only while printing)",requiresMultiple:"Skip objects (requires 2+ objects)",title:"Skip Objects",matchIdsInfo:"Match IDs with your printer display",printerShowsIds:"The printer screen shows object IDs on the build plate",skipSelected:"Skip Selected",skipping:"Skipping...",noObjectsSelected:"No objects selected",selectObjectsToSkip:"Select objects you want to skip from the current print",skipped:"skipped",objectsSkipped:"Objects skipped",activeCount:"{{count}} active",waitForLayer:"Wait for layer 2+ to skip objects (currently layer {{layer}})",skip:"Skip",confirmTitle:"Skip Object?",confirmMessage:'Are you sure you want to skip "{{name}}"? This cannot be undone.'},confirm:{deleteTitle:"Delete Printer",deleteMessage:'Are you sure you want to delete "{{name}}"? This will remove all connection settings.',deleteArchivesNote:"All print history for this printer will be permanently deleted.",keepArchivesNote:"Print history will be kept but no longer associated with this printer.",stopTitle:"Stop Print",stopMessage:'Are you sure you want to stop the current print on "{{name}}"? This will cancel the print job.',stopButton:"Stop Print",pauseTitle:"Pause Print",pauseMessage:'Are you sure you want to pause the current print on "{{name}}"?',pauseButton:"Pause Print",resumeTitle:"Resume Print",resumeMessage:'Are you sure you want to resume the print on "{{name}}"?',resumeButton:"Resume Print",powerOnTitle:"Power On Printer",powerOnMessage:'Are you sure you want to turn ON the power for "{{name}}"?',powerOnButton:"Power On",powerOffTitle:"Power Off Printer",powerOffMessage:'Are you sure you want to turn OFF the power for "{{name}}"?',powerOffWarning:'WARNING: "{{name}}" is currently printing! Are you sure you want to turn OFF the power? This will interrupt the print and may damage the printer.',powerOffButton:"Power Off",haToggleTitle:'Toggle "{{name}}"',haToggleMessage:"Toggle the Home Assistant entity {{entity}}? This may turn power off if it is currently on.",haToggleWarning:'WARNING: "{{name}}" is currently printing! Toggling {{entity}} may cut power and interrupt the print. Continue?',haToggleButton:"Toggle"},bulk:{select:"Select",selectAll:"Select All",selectByLocation:"Select by Location",selected:"{{count}} selected",actions:{stop:"Stop",pause:"Pause",resume:"Resume",clearPlate:"Clear Bed",clearHMS:"Clear Notifications"},confirm:{stopTitle:"Stop {{count}} Prints",stopMessage:"This will cancel active prints on {{count}} printer(s). This action cannot be undone.",stopButton:"Stop All",pauseTitle:"Pause {{count}} Prints",pauseMessage:"This will pause active prints on {{count}} printer(s).",pauseButton:"Pause All",clearPlateTitle:"Clear {{count}} Print Beds",clearPlateMessage:"This will clear the print bed on {{count}} printer(s) and may trigger queued jobs.",clearPlateButton:"Clear All"},success:"{{action}} completed on {{count}} printer(s)",partial:"{{succeeded}} succeeded, {{failed}} failed",noneApplicable:"No selected printers are in the right state for this action",selectByState:"Select by State"},discovery:{title:"Discover Printers",searching:"Searching...",scanning:"Scanning...",scanProgress:"Scanning... {{scanned}}/{{total}}",foundPrinters:"Found {{count}} printer(s)",noPrintersFound:"No printers found",noPrintersFoundSubnet:"No printers found in the specified subnet.",noPrintersFoundNetwork:"No printers found on the network.",allConfigured:"All discovered printers are already configured.",alreadyAdded:"Already added",select:"Select",manualEntry:"Manual Entry",addFromCloud:"Add from Cloud",subnetToScan:"Subnet to scan",dockerNote:"Docker detected. Enter your printer's subnet in CIDR notation. Requires network_mode: host in docker-compose.yml.",scanSubnet:"Scan Subnet for Printers",discoverNetwork:"Discover Printers on Network",scanningSubnet:"Scanning subnet for Bambu printers...",scanningNetwork:"Scanning network...",serialRequired:"Serial required",unknown:"Unknown",failedToStart:"Failed to start discovery"},drying:{start:"Start Drying",stop:"Stop Drying",temperature:"Temperature",duration:"Duration",hours:"hours",timeRemaining:"{{time}} left",active:"Drying",notSupported:"Drying not supported",powerRequired:"Connect AMS power adapter to enable drying",startingDrying:"Starting drying...",stoppingDrying:"Stopping drying...",rotateTray:"Rotate spool during drying"},filaments:"Filaments",openCameraOverlay:"Open camera overlay",openCameraWindow:"Open camera in new window",firmwareUpdateAvailable:"Firmware update available: {{current}} → {{latest}}",firmwareUpToDate:"Firmware {{version}} — Up to date",firmwareUpdateButton:"Update",plateDetection:{noPermission:"You do not have permission to update printers",enabledClick:"Plate check enabled - Click to disable",disabledClick:"Plate check disabled - Click to enable",manageCalibration:"Manage plate detection calibration",calibrationRequired:"Calibration Required",calibrationInstructions:"Please ensure the build plate is completely empty, then click Calibrate.",calibrationDescription:"Calibration captures a reference image of the empty plate. Future checks will compare against this reference to detect objects.",calibrationTip:"Tip: You can store up to 5 calibrations for different plates. The system automatically uses the best match when checking.",plateEmpty:"Plate appears empty",objectsDetected:"Objects detected on plate",confidence:"Confidence",difference:"Difference",analysisPreview:"Analysis preview:",analysisLegend:"Green box = detection area, Red overlay = differences from calibration",savedReferences:"Saved References ({{count}}/{{max}})",deleteReference:"Delete reference",labelPlaceholder:"Label...",clickToEdit:"{{label}} - Click to edit",clickToAddLabel:"Click to add label"},speed:{title:"Print Speed",silent:"Silent (50%)",standard:"Standard (100%)",sport:"Sport (124%)",ludicrous:"Ludicrous (166%)"},airduct:{title:"Airduct Mode",cooling:"Cooling",heating:"Heating"},noSdCard:"No SD",door:{open:"Open",closed:"Closed"},fans:{partCooling:"Part Cooling Fan",auxiliary:"Auxiliary Fan",chamber:"Chamber Fan"},clickToViewHmsErrors:"Click to view HMS errors",estimatedCompletion:"Estimated completion time",plateNumber:"Plate {{number}}",slotOptions:"Slot options",amsPopup:{friendlyName:"AMS Name",friendlyNamePlaceholder:"e.g. AMS Friendly Name",serialNumber:"Serial Number",firmwareVersion:"Firmware",save:"Save",clear:"Clear",noEditPermission:"You do not have permission to rename AMS units"},firmwareModal:{title:"Firmware Update",titleUpToDate:"Firmware Info",currentVersion:"Current:",latestVersion:"Latest:",releaseNotes:"Release Notes",checkingPrereqs:"Checking prerequisites...",sdCardReady:"SD card ready. Click below to upload firmware.",uploadedSuccess:"Firmware uploaded to SD card!",applyInstructions:"To apply the update on your printer:",step1:"On the printer's touchscreen, go to Settings",step2:"Navigate to Firmware",step3:"Select Update from SD card",step4:"The update will take 10-20 minutes",done:"Done",starting:"Starting...",uploadFirmware:"Upload Firmware",uploadFailed:"Failed to start upload: {{error}}",uploadedToast:"Firmware uploaded! Trigger update from printer screen.",availableVersions:"Available versions",usable:"Usable",unavailable:"Unavailable",installed:"Installed",newerBadge:"newer",olderBadge:"older",currentBadge:"current"},accessCodePlaceholder:"Leave empty to keep current",roi:{title:"Detection Area (ROI)",xStart:"X Start",yStart:"Y Start",width:"Width",height:"Height",instruction:"Adjust the detection area to focus on the build plate. The green box in the preview shows the current area."},developerModeWarning:"Developer LAN mode is not enabled on: {{names}}. Some features may not work.",howToEnable:"How to enable",incompatibleFile:"This file was sliced for {{slicedFor}}, but this printer is a {{printerModel}}",dropNotPrintable:"Only .gcode and .gcode.3mf files can be printed",dropToPrint:"Drop to print",cannotPrint:"Printer busy"},archives:{title:"Print Archives",searchPlaceholder:"Search archives...",filterByPrinter:"Filter by printer",filterByStatus:"Filter by status",sortBy:"Sort by",sortNewest:"Newest first",sortOldest:"Oldest first",sortName:"Name",sortDuration:"Duration",sortLargest:"Largest first",sortSmallest:"Smallest first",sortSize:"Size",noArchives:"No archives found",noArchivesSearch:"No archives match your search",originalPrintNotVisible:"Original print not visible - try clearing filters",noArchivesYet:"No archives yet",prints:"prints",pagination:{showing:"Showing",to:"to",of:"of",show:"Show",page:"Page",all:"All"},loadingArchives:"Loading archives...",releaseToUpload:"Release to upload",showAll:"Show all",showFavoritesOnly:"Show favorites only",gridView:"Grid view",listView:"List view",calendarView:"Calendar view",logView:"Print Log",manageTags:"Manage Tags",showFailedPrints:"Show failed prints",hideFailedPrints:"Hide failed prints",hideDuplicates:"Hide Duplicates",viewOriginalPrint:"Click to view original print (#{{id}})",printTime:"Print Time",filamentUsed:"Filament Used",cost:"Cost",reprint:"Reprint",preview:"Preview",deleteArchive:"Delete Archive",deleteConfirm:"Are you sure you want to delete this archive?",favorite:"Favorite",unfavorite:"Remove from favorites",viewDetails:"View Details",status:{completed:"Completed",failed:"Failed",stopped:"Stopped"},toast:{source3mfAttached:"Source 3MF attached: {{filename}}",failedUploadSource3mf:"Failed to upload source 3MF",source3mfRemoved:"Source 3MF removed",failedRemoveSource3mf:"Failed to remove source 3MF",f3dAttached:"F3D attached: {{filename}}",failedUploadF3d:"Failed to upload F3D",f3dRemoved:"F3D removed",failedRemoveF3d:"Failed to remove F3D",timelapseAttached:"Timelapse attached: {{filename}}",timelapseAlreadyAttached:"Timelapse already attached",noMatchingTimelapse:"No matching timelapse found",failedScanTimelapse:"Failed to scan for timelapse",failedAttachTimelapse:"Failed to attach timelapse",timelapseRemoved:"Timelapse removed",failedRemoveTimelapse:"Failed to remove timelapse",timelapseUploaded:"Timelapse uploaded: {{filename}}",failedUploadTimelapse:"Failed to upload timelapse",archiveDeleted:"Archive deleted",failedDeleteArchive:"Failed to delete archive",addedToFavorites:"Added to favorites",removedFromFavorites:"Removed from favorites",projectUpdated:"Project updated",failedUpdateProject:"Failed to update project",linkCopied:"Link copied to clipboard",failedCopyLink:"Failed to copy link",photoDeleted:"Photo deleted",failedDeletePhoto:"Failed to delete photo",failedDeleteArchives:"Failed to delete archives",failedUpdateFavorites:"Failed to update favorites",exportDownloaded:"Export downloaded",exportFailed:"Export failed"},menu:{print:"Print",schedule:"Schedule",openInBambuStudio:"Open in Slicer",slice:"Slice",externalLink:"External Link",viewOnMakerWorld:"View on MakerWorld",preview3d:"3D Preview",viewTimelapse:"View Timelapse",scanForTimelapse:"Scan for Timelapse",uploadTimelapse:"Upload Timelapse",removeTimelapse:"Remove Timelapse",downloadSource3mf:"Download Source 3MF",uploadSource3mf:"Upload Source 3MF",replaceSource3mf:"Replace Source 3MF",removeSource3mf:"Remove Source 3MF",uploadF3d:"Upload F3D",replaceF3d:"Replace F3D",downloadF3d:"Download F3D",removeF3d:"Remove F3D",download:"Download",copyDownloadLink:"Copy Download Link",qrCode:"QR Code",viewPhotos:"View Photos",viewPhotosCount:"View Photos ({{count}})",projectPage:"Project Page",addToFavorites:"Add to Favorites",removeFromFavorites:"Remove from Favorites",edit:"Edit",printLog:"Print Log",goToProject:"Go to Project: {{name}}",addToProject:"Add to Project",removeFromProject:"Remove from Project",loading:"Loading...",noProjectsAvailable:"No projects available",searchProjects:"Search projects…",select:"Select",deselect:"Deselect",delete:"Delete"},permission:{noReprint:"You do not have permission to reprint this archive",noAddToQueue:"You do not have permission to add to queue",noUpdateArchives:"You do not have permission to update archives",noUploadFiles:"You do not have permission to upload files",noDownload:"You do not have permission to download archives",noCopyLink:"You do not have permission to copy download links",noDelete:"You do not have permission to delete this archive",noCreate:"You do not have permission to create archives"},platePicker:{title:"Select plate to preview",hint:"This archive has multiple plates. Pick one to open in the GCode viewer.",plateLabel:"Plate {{index}}",objectCount:"{{count}} object",objectCount_plural:"{{count}} objects",noGcode:"This archive has no sliced G-code to preview. Open it in Bambu Studio to slice first."},card:{previousPlate:"Previous plate",nextPlate:"Next plate",plateNumber:"Plate {{index}}",moreOptions:"Right-click for more options",addToFavorites:"Add to favorites",removeFromFavorites:"Remove from favorites",cancelled:"cancelled",failed:"failed",duplicate:"duplicate",duplicateTitle:"This model has been printed before",openSource3mf:"Open source 3MF in Bambu Studio (right-click for more options)",downloadF3d:"Download Fusion 360 design file",viewTimelapse:"View timelapse",viewPhoto:"View 1 photo",viewPhotos:"View {{count}} photos",openFolder:"Open folder: {{name}}",slicedFile:"Sliced file - ready to print",sourceFile:"Source file only - no AMS mapping available",gcode:"GCODE",source:"SOURCE",project:"Project: {{name}}",runsBadge:"{{count}} prints",runsBadgeTitle:"{{count}} prints total — {{successful}} successful, {{failed}} failed. Click to see the full print log.",estimated:"Estimated: {{time}}",actual:"Actual: {{time}}",accuracy:"Accuracy: {{percent}}%",filament:"{{weight}}g",layer:"{{count}} layer",layers:"{{count}} layers",object:"{{count}} object",objects:"{{count}} objects",slicedFor:"Sliced for {{model}}",uploadedBy:"Uploaded By",noPermissionReprint:"You do not have permission to reprint",noFileForReprint:"No 3MF file available — the file could not be downloaded from the printer when the print was recorded",noPermissionEdit:"You do not have permission to edit archives",noPermissionDelete:"You do not have permission to delete archives",reprint:"Reprint",schedulePrint:"Schedule Print",schedule:"Schedule",openInBambuStudio:"Open in Slicer",openInBambuStudioToSlice:"Open in Slicer to slice",slice:"Slice",externalLink:"External Link",makerWorld:"MakerWorld: {{designer}}",viewProject:"View project",noExternalLink:"No external link",preview3d:"3D Preview",download:"Download",edit:"Edit",delete:"Delete"},runLog:{title:"Print Log",modalTitle:"Print Log — {{name}}",modalTitleFallback:"this archive",empty:"No print events recorded for this archive yet.",col:{date:"Date",status:"Status",duration:"Duration",filament:"Filament",cost:"Cost"},status:{completed:"Completed",failed:"Failed",cancelled:"Cancelled",stopped:"Stopped",skipped:"Skipped",printing:"Printing"}},modal:{deleteArchive:"Delete Archive",deleteConfirm:'Are you sure you want to delete "{{name}}"? This action cannot be undone.',deleteButton:"Delete",deletePurgeStats:"Also remove this print from Quick Stats (filament, time, cost, energy)",removeSource3mf:"Remove Source 3MF",removeSource3mfConfirm:'Are you sure you want to remove the source 3MF file from "{{name}}"? This will delete the original slicer project file.',removeButton:"Remove",removeF3d:"Remove F3D",removeF3dConfirm:'Are you sure you want to remove the Fusion 360 design file from "{{name}}"?',removeTimelapse:"Remove Timelapse",removeTimelapseConfirm:'Are you sure you want to remove the timelapse video from "{{name}}"?',timelapse:"{{name}} - Timelapse",selectTimelapse:"Select Timelapse",selectTimelapseDesc:"No auto-match found. Select the timelapse for this print:",deleteArchives:"Delete Archives",deleteArchivesConfirm:"Are you sure you want to delete {{count}} archive(s)? This action cannot be undone.",deleteCount:"Delete {{count}}"},page:{title:"Archives",printsCount:"{{filtered}} of {{total}} prints",dropFilesHere:"Drop .3mf files here",releaseToUpload:"Release to upload",only3mfSupported:"Only .3mf files are supported",close:"Close",selected:"{{count}} selected",selectAll:"Select All",tags:"Tags",project:"Project",favorite:"Favorite",delete:"Delete",toggledFavorites:"Toggled favorites for {{count}} archive(s)",failedUpdateFavorites:"Failed to update favorites",archivesDeleted:"{{count}} archive(s) deleted",failedDeleteArchives:"Failed to delete archives",photoDeleted:"Photo deleted",failedDeletePhoto:"Failed to delete photo"},list:{name:"Name",printer:"Printer",date:"Date",size:"Size",actions:"Actions",hasTimelapse:"Has timelapse"},log:{date:"Date",printName:"Print Name",printer:"Printer",user:"User",status:"Status",duration:"Duration",filament:"Filament",allPrinters:"All Printers",allUsers:"All Users",allStatuses:"All Statuses",cancelled:"Cancelled",skipped:"Skipped",dateFrom:"From",dateTo:"To",noEntries:"No print log entries found",showing:"Showing {{count}} of {{total}} entries",rowsPerPage:"Rows",page:"Page",prev:"Prev",next:"Next",clearLog:"Clear Log",clearLogTitle:"Clear Print Log",clearLogConfirm:"All print log entries will be permanently deleted. Archives and queue items are not affected. This action cannot be undone. Are you sure?",clearLogButton:"Clear All",cleared:"{{count}} log entries cleared",clearFailed:"Failed to clear print log"}},queue:{title:"Print Queue",subtitle:"Schedule and manage your print jobs",addToQueue:"Add to Queue",print:"Print",reprint:"Re-print",schedulePrint:"Schedule Print",editQueueItem:"Edit Queue Item",printToPrinters:"Print to {{count}} Printers",queueToPrinters:"Queue to {{count}} Printers",queueSelectedPlates:"Queue {{count}} Plates",selectAllPlates:"Select All {{count}} Plates",deselectAll:"Deselect All",printQueued:"Print queued",itemsQueued:"{{count}} items queued",sending:"Sending...",sendingProgress:"Sending {{current}}/{{total}}...",adding:"Adding...",addingProgress:"Adding {{current}}/{{total}}...",savingProgress:"Saving {{current}}/{{total}}...",clearQueue:"Clear Queue",clearHistory:"Clear History",emptyQueue:"Queue is empty",position:"Position",scheduledTime:"Scheduled Time",moveUp:"Move Up",moveDown:"Move Down",startNow:"Start Now",printingInProgress:"Printing in progress...",viewArchive:"View archive",viewInFileManager:"View in File Manager",itemCount:"{{count}} item",itemCount_plural:"{{count}} items",dragToReorder:"Drag to reorder (ASAP only)",reorderHint:"Position only affects ASAP items. Scheduled items run at their set time.",sjf:{label:"SJF",tooltip:"Shortest Job First — scheduler prioritizes shorter prints"},addedBy:"Added by {{name}}",nextInQueue:"Next in queue",clearPlateSuccess:"Plate cleared — ready for next print",plateNumber:"Plate {{index}}",quantity:"Quantity",quantityHint:"Creates {{count}} queue items",activeBatches:"Active Batches",batchProgress:"{{completed}} of {{total}} completed",cancelBatch:"Cancel Remaining",batchCancelled:"Remaining batch items cancelled",cancelBatchConfirmTitle:"Cancel Batch",cancelBatchConfirmMessage:"Cancel all remaining pending items in this batch?",batch:"Batch",sections:{currentlyPrinting:"Currently Printing",queued:"Queued",history:"History"},status:{pending:"Pending",waiting:"Waiting",printing:"Printing",paused:"Paused",completed:"Completed",failed:"Failed",skipped:"Skipped",cancelled:"Cancelled"},summary:{printing:"Printing",queued:"Queued",totalTime:"Total Queue Time",totalWeight:"Total Queue Weight",history:"History"},filter:{allPrinters:"All Printers",unassigned:"Unassigned",allStatus:"All Status",allLocations:"All Locations",any:"Any"},sort:{byPosition:"Sort by Position",byName:"Sort by Name",byPrinter:"Sort by Printer",bySchedule:"Sort by Schedule",byDate:"Sort by Date",ascendingOldest:"Ascending (oldest first)",descendingNewest:"Descending (newest first)"},badges:{staged:"Staged",requiresPrevious:"Requires previous success",autoPowerOff:"Auto power off",gcodeInjection:"G-code"},empty:{title:"No prints scheduled",description:'Schedule a print from the Archives page using the "Schedule" option in the context menu, or drag and drop files to get started.'},time:{asap:"ASAP",overdue:"Overdue",now:"Now",lessThanMinute:"In less than a minute",inMinutes:"In {{count}} min",inHours:"In {{count}} hours"},actions:{stopPrint:"Stop Print",startPrint:"Start Print",requeue:"Re-queue"},bulkEdit:{title:"Edit {{count}} Item",title_plural:"Edit {{count}} Items",description:"Only changed settings will be applied to selected items.",printer:"Printer",noChange:"— No change —",queueOptions:"Queue Options",staged:"Staged (manual start)",autoPowerOff:"Auto power off after print",requirePrevious:"Require previous success",printOptions:"Print Options",bedLevelling:"Bed levelling",flowCalibration:"Flow calibration",vibrationCalibration:"Vibration calibration",layerInspection:"First layer inspection",timelapse:"Timelapse",useAms:"Use AMS",applyChanges:"Apply Changes",selectAll:"Select All",deselectAll:"Deselect All",selected:"{{count}} selected",editSelected:"Edit Selected",cancelSelected:"Cancel Selected"},confirm:{cancelTitle:"Cancel Scheduled Print",cancelMessage:'Are you sure you want to cancel "{{name}}"?',stopTitle:"Stop Print",stopMessage:'Are you sure you want to stop the current print "{{name}}"? This will cancel the print job on the printer.',removeTitle:"Remove from History",removeMessage:'Are you sure you want to remove "{{name}}" from the queue history?',clearHistoryTitle:"Clear History",clearHistoryMessage:"Are you sure you want to remove all {{count}} item(s) from the history?",cancelButton:"Cancel Print",stopButton:"Stop Print",thisPrint:"this print",thisItem:"this item"},toast:{cancelled:"Queue item cancelled",cancelFailed:"Failed to cancel item",removed:"Queue item removed",removeFailed:"Failed to remove item",stopped:"Print stopped",stopFailed:"Failed to stop print",released:"Print released to queue",startFailed:"Failed to start print",reorderFailed:"Failed to reorder queue",historyCleared:"Cleared {{count}} history item(s)",clearHistoryFailed:"Failed to clear history",updateFailed:"Failed to update items",bulkCancelled:"Cancelled {{count}} item(s)",bulkCancelFailed:"Failed to cancel items"},timeline:{listView:"List",timelineView:"Timeline",unassigned:"Unassigned",noData:"No scheduled prints for this day",allDoneBy:"All prints estimated done by {{time}}",staged:"Staged",filterAll:"Show All",filterPrinting:"Printing",filterQueued:"Queued",time:{anyMoment:"any moment",minutesLeft:"{{minutes}}m left",hoursLeft:"{{hours}}h left",hoursMinutesLeft:"{{hours}}h {{minutes}}m left"},day:{previous:"Previous day",next:"Next day",today:"Today"}},permissions:{noStopPrint:"You do not have permission to stop prints",noStartPrint:"You do not have permission to start prints",noEdit:"You do not have permission to edit this queue item",noCancel:"You do not have permission to cancel this queue item",noRequeue:"You do not have permission to re-queue items",noRemove:"You do not have permission to remove this queue item",noClearHistory:"You do not have permission to clear all history",noEditItems:"You do not have permission to edit queue items",noCancelItems:"You do not have permission to cancel queue items"}},backgroundDispatch:{unknownFile:"Unknown file",unknownPrinter:"Unknown printer",startingPrints:"Starting prints",progressSummary:"{{complete}}/{{total}} complete • Dispatched: {{dispatched}} • Processing: {{processing}}",expandDetails:"Expand dispatch details",collapseDetails:"Collapse dispatch details",dismissToast:"Dismiss dispatch toast",cancelDispatchJob:"Cancel dispatch job",cancel:"Cancel",cancelling:"Cancelling…",awaitingPrinter:"Awaiting printer…",status:{dispatched:"Dispatched",processing:"Processing",completed:"Completed",failed:"Failed",cancelled:"Cancelled"},toast:{cancellingUpload:"Cancelling upload...",cancelled:"Dispatch cancelled",cancelFailed:"Failed to cancel dispatch",completeWithFailures:"Background dispatch complete: {{completed}} succeeded, {{failed}} failed",completeSuccess:"Background dispatch complete: {{completed}} succeeded",printStartedRemaining:"{{completed}} print(s) started, {{remaining}} more sending..."}},stats:{title:"Statistics",subtitle:"Drag widgets to rearrange. Click the eye icon to hide.",overview:"Overview",totalPrints:"Total Prints",successRate:"Success Rate",totalPrintTime:"Total Print Time",printTime:"Print Time",totalFilament:"Total Filament Used",filamentUsed:"Filament Used",filamentCost:"Filament Cost",totalCost:"Total Cost",energyUsed:"Energy Used",energyCost:"Energy Cost",energyWarmingUpTooltip:"Energy tracking is still collecting hourly snapshots. Date-range totals will become accurate once at least one snapshot exists before the selected range. Early values may undercount.",averagePrintTime:"Average Print Time",printsPerDay:"Prints per Day",byPrinter:"By Printer",printsByPrinter:"Prints by Printer",byMaterial:"By Material",byMonth:"By Month",last7Days:"Last 7 Days",last30Days:"Last 30 Days",last90Days:"Last 90 Days",allTime:"All Time",quickStats:"Quick Stats",printActivity:"Print Activity",filamentTypes:"Filament Types",filamentTrends:"Filament Trends",failureAnalysis:"Failure Analysis",timeAccuracy:"Time Accuracy",successful:"Successful:",failed:"Failed:",perfectEstimate:"100% = perfect estimate",noTimeAccuracyData:"No time accuracy data yet",noFilamentData:"No filament data available",noPrinterData:"No printer data available",noPrintData:"No print data available",noPrintDataLast30Days:"No print data in the last 30 days",failureReasons:"Failure Reasons",topFailureReasons:"Top Failure Reasons",failedPrintsCount:"{{failed}} / {{total}} prints failed",lastWeekRate:"Last week: {{rate}}%",resetLayout:"Reset Layout",recalculateCosts:"Recalculate Costs",recalculateCostsHint:"Recalculate all archive costs using current filament prices",exportStats:"Export Stats",exportAsCsv:"Export as CSV",exportAsExcel:"Export as Excel",hiddenCount:"{{count}} Hidden",exportDownloaded:"Export downloaded",exportFailed:"Export failed",layoutReset:"Layout reset",recalculatedCosts:"Recalculated costs for {{count}} archives",recalculateFailed:"Failed to recalculate costs",loadingStats:"Loading statistics...",noPermissionResetLayout:"You do not have permission to reset layout",noPermissionRecalculate:"You do not have permission to recalculate costs",noPrintDataInRange:"No print data in selected range",periodFilament:"Period Filament",periodCost:"Period Cost",avgPerPrint:"Avg per Print",usageOverTime:"Usage Over Time",filamentByWeight:"Weight",printDuration:"Print Duration",printerUtilization:"Printer Utilization",filamentSuccess:"Success by Material",printHabits:"Print Habits",printTimeOfDay:"Print Time of Day",colorDistribution:"Color Distribution",noColorData:"No color data available",records:"Records",longestPrint:"Longest Print",heaviestPrint:"Heaviest Print",mostExpensivePrint:"Most Expensive",busiestDay:"Busiest Day",successStreak:"Success Streak",streakPrint:"consecutive print",streakPrints:"{{count}} consecutive prints",printerStats:"Printer Stats",hours:"hours",avgPrints:"Avg. prints",noArchiveData:"No print data available",filamentByTime:"Time",avgWeight:"Avg. weight",avgTime:"Avg. time",filamentByPrints:"Prints",timeframe:{today:"Today","this-week":"This Week","this-month":"This Month","last-7":"Last 7 Days","last-30":"Last 30 Days","last-90":"Last 90 Days","this-year":"This Year","all-time":"All Time",custom:"Custom Range",from:"From",to:"To"},allUsers:"All Users",noUser:"No User (System)",filterByUser:"Filter by User"},maintenance:{title:"Maintenance",overview:"Overview",allOk:"All maintenance up to date",dueCount:"{{count}} item due",dueCount_plural:"{{count}} items due",warningCount:"{{count}} warning",warningCount_plural:"{{count}} warnings",totalPrintTime:"Total Print Time",nextMaintenance:"Next Maintenance",nothingDue:"Nothing due",tasks:"Tasks",lastPerformed:"Last performed",interval:"Interval",hoursRemaining:"{{hours}}h remaining",hoursOverdue:"{{hours}}h overdue",markDone:"Mark as Done",performMaintenance:"Perform Maintenance",history:"History",noHistory:"No maintenance history",editPrintHours:"Edit Print Hours",currentHours:"Current Hours",statusTab:"Status",settingsTab:"Settings",overdueCount:"{{count}} overdue",dueSoonCount:"{{count}} due soon",dueSoon:"Due soon",allGood:"All good",overdueBy:"Overdue by {{duration}}",dueIn:"Due in {{duration}}",timeLeft:"{{duration}} left",day:"1 day",days:"{{count}} days",week:"1 week",weeks:"{{count}} weeks",month:"1 month",months:"{{count}} months",year:"1 year",maintenanceTypes:"Maintenance Types",maintenanceTypesDescription:"System types and your custom maintenance tasks",addCustomType:"Add Custom Type",restoreDefaults:"Restore Default Tasks",intervalType:"Interval Type",intervalValue:"Interval ({{type}})",icon:"Icon",documentationLink:"Documentation Link (optional)",assignToPrinters:"Assign to Printers",selectAtLeastOnePrinter:"Select at least one printer",addType:"Add Type",custom:"Custom",printHours:"Print Hours",calendarDays:"Calendar Days",exampleName:"e.g., Replace HEPA Filter",viewDocumentation:"View documentation",timeBasedInterval:"Time-based interval",intervalOverrides:"Interval Overrides",intervalOverridesDescription:"Customize intervals for specific printers",assignedToPrinters:"Assigned to printers:",noPrintersAssigned:"No printers assigned",addPrinterShort:"Add:",printersAssignedClick:"{{count}} printer(s) assigned - click to manage",removeFromPrinter:"Remove from this printer",types:{lubricateCarbonRods:"Lubricate Carbon Rods",lubricateRails:"Lubricate Linear Rails",cleanNozzle:"Clean Nozzle/Hotend",checkBelts:"Check Belt Tension",cleanBuildPlate:"Clean Build Plate",checkExtruder:"Check Extruder Gears",checkCooling:"Check Cooling Fans",generalInspection:"General Inspection",cleanCarbonRods:"Clean Carbon Rods",lubricateSteelRods:"Lubricate Steel Rods",cleanSteelRods:"Clean Steel Rods",cleanLinearRails:"Clean Linear Rails",checkPtfeTube:"Check PTFE Tube",replaceHepaFilter:"Replace HEPA Filter",replaceCarbonFilter:"Replace Carbon Filter",lubricateLeftNozzleRail:"Lubricate Left Nozzle Rail"},maintenanceComplete:"Maintenance marked as complete",typeUpdated:"Maintenance type updated",typeDeleted:"Maintenance type deleted",defaultsRestored:"Restored {{count}} default task(s)",printHoursUpdated:"Print hours updated",printerAssigned:"Printer assigned",printerRemoved:"Printer removed",deleteTypeConfirm:'Delete "{{name}}"?',deleteSystemTypeTitle:"Delete default maintenance task?",deleteSystemTypeMessage:'Are you sure you want to delete the default maintenance task "{{name}}"?',noPermissionUpdate:"You do not have permission to update maintenance items",noPermissionPerform:"You do not have permission to perform maintenance",noPermissionEditTypes:"You do not have permission to edit maintenance types",noPermissionDeleteTypes:"You do not have permission to delete maintenance types",noPermissionEditHours:"You do not have permission to edit print hours",noPermissionRemovePrinter:"You do not have permission to remove printer assignments",noPermissionAssignPrinter:"You do not have permission to assign printers",noPermissionEditIntervals:"You do not have permission to edit intervals",configureSettings:"Configure maintenance types and intervals"},settings:{title:"Settings",general:"General",tabs:{general:"General",smartPlugs:"Smart Plugs",notifications:"Notifications",queue:"Workflow",filament:"Filament",network:"Network",apiKeys:"API Keys",virtualPrinter:"Virtual Printer",spoolbuddy:"SpoolBuddy",failureDetection:"Failure Detection",users:"Authentication",backup:"Backup",emailAuth:"Email Authentication",ldap:"LDAP",twoFa:"Two-Factor Auth",oidc:"SSO / OIDC",security:"Security"},spoolbuddy:{infoTitle:"SpoolBuddy devices",infoBody:"SpoolBuddy kiosks register themselves automatically via heartbeat. Unregister a device here if it is no longer in use or if a stale duplicate was left behind by a daemon crash.",duplicatesTitle:"{{count}} devices registered",duplicatesBody:"Only the first registered device is used by the kiosk UI. If one of these is a stale duplicate from a crash, unregister it — an online device will re-register itself on its next heartbeat.",empty:"No SpoolBuddy devices registered yet.",online:"Online",offline:"Offline",unregister:"Unregister",unregisterSuccess:"Device unregistered",unregisterError:"Failed to unregister device",confirmTitle:"Unregister SpoolBuddy device?",confirmBody:'This will remove "{{hostname}}" ({{deviceId}}) from the database. If the device is online, it will re-register itself on its next heartbeat.',ipAddress:"IP address",firmware:"Firmware",lastSeen:"Last seen",daemonUptime:"Daemon uptime",systemUptime:"System uptime",never:"never",nfc:"NFC",scale:"Scale",cpuTemp:"CPU temp",memory:"Memory",disk:"Disk",update:"Update",updateConfirmTitle:"Update Spoolbuddy daemon?",updateConfirmBody:'Trigger a software update on "{{hostname}}"? The daemon will restart once the update is applied.',restartBrowser:"Restart Browser",restartBrowserConfirmTitle:"Restart kiosk browser?",restartBrowserConfirmBody:'Restart the kiosk browser on "{{hostname}}"? The display will blank briefly.',restartDaemon:"Restart Daemon",restartDaemonConfirmTitle:"Restart Spoolbuddy daemon?",restartDaemonConfirmBody:'Restart the Spoolbuddy daemon on "{{hostname}}"? The device will go offline for a few seconds.',reboot:"Reboot",rebootConfirmTitle:"Reboot device?",rebootConfirmBody:'Reboot "{{hostname}}"? The device will be offline for around a minute.',shutdown:"Shutdown",shutdownConfirmTitle:"Shutdown device?",shutdownConfirmBody:'Shutdown "{{hostname}}"? You will need physical access to power it back on.',commandConfirm:"Confirm",commandQueued:"Command queued",commandError:"Failed to send command"},ldap:{title:"LDAP Authentication",enabledDesc:"LDAP authentication is enabled",disabledDesc:"LDAP authentication is disabled",disabledHint:"Configure and save LDAP settings below, then enable.",enabled:"LDAP authentication enabled",disabled:"LDAP authentication disabled",feature1:"Users can login with LDAP credentials",feature2:"Local admin account remains as fallback",feature3:"LDAP groups are mapped to BamBuddy groups on login",serverConfig:"LDAP Server Configuration",serverUrl:"Server URL",serverUrlHint:"Use ldaps:// for SSL or ldap:// with StartTLS",security:"Security",securityHint:"StartTLS upgrades a plain connection to TLS. LDAPS uses TLS from the start.",bindDn:"Bind DN (Service Account)",bindPassword:"Bind Password",searchBase:"Search Base DN",userFilter:"User Search Filter",userFilterHint:"{username} is replaced with the login username. Use (uid={username}) for OpenLDAP.",advanced:"Advanced",autoProvision:"Auto-provision users",autoProvisionHint:"Automatically create a BamBuddy account on first LDAP login",defaultGroup:"Default group",defaultGroupNone:"— None (no fallback) —",defaultGroupHint:"Fallback group assigned when an LDAP user authenticates but is not listed in any mapped LDAP group. Leave empty to leave unmapped users without permissions.",groupMapping:"Group Mapping (JSON)",groupMappingHint:"Map LDAP group DNs to BamBuddy groups. Available groups: ",testConnection:"Test Connection",settingsSaved:"LDAP settings saved",errors:{serverRequired:"LDAP server URL is required",searchBaseRequired:"Search base DN is required",enableAuthFirst:"Enable authentication first",configureLdapFirst:"Save LDAP settings first"}},email:{smtpSettings:"SMTP Configuration",smtpHost:"SMTP Server",smtpPort:"SMTP Port",security:"Security",authentication:"Authentication",username:"Username",password:"Password",fromEmail:"From Email",fromName:"From Name",testConnection:"Test SMTP Connection",testRecipient:"Test Recipient Email",sendTest:"Send Test Email",sending:"Sending...",save:"Save Settings",saving:"Saving...",advancedAuth:"Advanced Authentication",advancedAuthEnabled:"Advanced Authentication is enabled",advancedAuthEnabledDesc:"Email-based user management features are active. New users will receive auto-generated passwords via email, and users can reset their passwords through the forgot password feature.",advancedAuthDisabled:"Advanced Authentication is disabled",advancedAuthDisabledDesc:"Enable advanced authentication to activate email-based features for user management.",enable:"Enable",disable:"Disable",feature1:"Passwords are auto-generated and emailed to new users",feature2:"Users can login with username or email",feature3:"Forgot password feature is available",feature4:"Admins can reset user passwords via email",errors:{requiredFields:"Please fill in all required fields",usernameRequired:"Username is required when authentication is enabled",enterTestEmail:"Please enter a test email address",smtpServerAndEmail:"Please fill in SMTP Server and From Email before testing",usernamePasswordRequired:"Username and Password are required when authentication is enabled",configureSmtpFirst:"Please configure and test SMTP settings first",enableAuthFirst:"Please enable authentication first to use email-based features."},success:{settingsSaved:"SMTP settings saved successfully"},securityOptions:{starttls:"STARTTLS (Port 587)",ssl:"SSL/TLS (Port 465)",none:"None (Port 25)"},authOptions:{enabled:"Enabled",disabled:"Disabled"}},appearance:"Appearance",notifications:"Notifications",smartPlugs:"Smart Plugs",spoolman:"Spoolman",updates:"Updates",language:"Language",languageDescription:"Select your preferred language",theme:"Theme",themeLight:"Light",themeDark:"Dark",themeSystem:"System",defaultView:"Default View",defaultViewDescription:"Page to show when opening the app",checkForUpdates:"Check for Updates",autoUpdate:"Auto Update",currentVersion:"Current Version",latestVersion:"Latest Version",upToDate:"You are up to date",updateAvailable:"Update available",notificationLanguage:"Notification Language",notificationLanguageDescription:"Language for push notifications",bedCooledThreshold:"Bed Cooled Threshold",bedCooledThresholdDescription:"Temperature below which the bed is considered cooled after a print",userNotificationsEnabled:"User Notifications",userNotificationsEnabledDescription:"Enable the user notifications menu and email notifications for print job events. Requires Advanced Authentication.",userNotificationsDisabledHint:"Enable Advanced Authentication to use user notifications.",notificationProviders:"Notification Providers",addProvider:"Add Provider",editProvider:"Edit Provider",providerType:"Provider Type",testNotification:"Test Notification",testSuccess:"Test notification sent successfully",testFailed:"Failed to send test notification",quietHours:"Quiet Hours",quietHoursDescription:"Do not disturb during these hours",quietHoursStart:"Start",quietHoursEnd:"End",events:{title:"Notification Events",printStart:"Print Started",printComplete:"Print Completed",printFailed:"Print Failed",printStopped:"Print Stopped",printProgress:"Progress Milestones",printProgressDescription:"Notify at 25%, 50%, 75%",printerOffline:"Printer Offline",printerError:"Printer Error",filamentLow:"Low Filament",maintenanceDue:"Maintenance Due",maintenanceDueDescription:"Notify when maintenance is needed"},smartPlug:{title:"Smart Plugs",add:"Add Smart Plug",edit:"Edit Smart Plug",name:"Name",ipAddress:"IP Address",linkedPrinter:"Linked Printer",autoOn:"Auto Power On",autoOnDescription:"Turn on when print starts",autoOff:"Auto Power Off",autoOffDescription:"Turn off after print completes",offDelay:"Off Delay",offDelayMinutes:"Minutes after print",offDelayTemp:"When nozzle below temperature",currentState:"Current State",turnOn:"Turn On",turnOff:"Turn Off"},filamentTracking:"Filament Tracking",filamentTrackingDesc:"Choose how to track your filament spools. You can use the built-in inventory or connect an external Spoolman server.",filamentChecks:"Filament checks",disableFilamentWarnings:"Disable filament warnings",disableFilamentWarningsDesc:"Don't show warnings about insufficient filament when printing or queueing",preferLowestFilament:"Prefer lowest remaining filament",preferLowestFilamentDesc:"When multiple spools match, use the one with the least filament remaining",trackingModeBuiltIn:"Built-in Inventory",trackingModeBuiltInDesc:"RFID auto-matching and usage tracking included",trackingModeSpoolmanDesc:"External filament management server",builtInFeatureRfid:"Automatically detects Bambu Lab RFID spools in AMS",builtInFeatureUsage:"Tracks filament consumption per print",builtInFeatureCatalog:"Manage spools, colors, and K-factor profiles",builtInFeatureThirdParty:"Third-party spools can be assigned to inventory spools",amsSyncButton:"Sync Weights from AMS",amsSyncTitle:"Sync Spool Weights from AMS",amsSyncMessage:"This will overwrite all inventory spool weights with the current AMS remain% values from connected printers. Use this to recover from corrupted weight data. Printers must be online.",amsSyncing:"Syncing...",amsSyncSuccess:"{{synced}} spool(s) synced, {{skipped}} skipped",amsSyncError:"Failed to sync weights from AMS",spoolmanAmsSyncButton:"Sync Spoolman Weights from AMS",spoolmanAmsSyncTitle:"Sync Spoolman Spool Weights from AMS",spoolmanAmsSyncMessage:"This will update all Spoolman spool weights based on the current AMS remain% values from connected printers. Printers must be online.",spoolmanAmsSyncing:"Syncing...",spoolmanAmsSyncSuccess:"{{synced}} spool(s) synced, {{skipped}} skipped",spoolmanAmsSyncError:"Failed to sync Spoolman weights from AMS",spoolmanAmsSyncErrorUnreachable:"Failed to sync Spoolman weights (Spoolman unreachable)",spoolmanAmsSyncErrorNotConfigured:"Failed to sync Spoolman weights (Spoolman not configured)",spoolmanNotConfigured:"Spoolman not configured",spoolmanFilamentCatalogTitle:"Spoolman Filament Catalog",spoolmanFilamentCatalogDesc:"Filament names and tare weights from your Spoolman instance. Name and spool weight are editable here; all other properties are managed directly in Spoolman.",spoolmanUrl:"Spoolman URL",spoolmanUrlHint:"URL of your Spoolman server (e.g., http://localhost:7912)",spoolmanConnected:"Connected",spoolmanDisconnected:"Disconnected",status:"Status",connect:"Connect",disconnect:"Disconnect",howSyncWorks:"How Sync Works",syncInfoRfidOnly:"Only official Bambu Lab spools with RFID are synced",syncInfoAutoCreate:"New spools are auto-created in Spoolman on first sync",syncInfoThirdPartySkipped:"Non-Bambu Lab spools (third-party, refilled) are skipped",linkingExistingSpools:"Linking Existing Spools",linkingExistingSpoolsDesc:'To link existing Spoolman spools to your AMS, hover over an AMS slot and click "Link to Spoolman".',syncMode:"Sync Mode",syncModeAuto:"Automatic",syncModeManual:"Manual Only",syncModeAutoDesc:"AMS data syncs automatically when changes are detected",syncModeManualDesc:"Only sync when manually triggered",syncAmsData:"Sync AMS Data",syncAmsDataDesc:"Manually sync printer AMS data to Spoolman",allPrinters:"All Printers",noDefaultPrinter:"No default (ask each time)",sidebarOrder:"Sidebar order",saveThumbnails:"Save thumbnails",captureFinishPhoto:"Capture finish photo",noPrintersConfigured:"No printers configured",archiveMode:{always:"Always create archive entry",never:"Never create archive entry",ask:"Ask each time"},checkForUpdatesLabel:"Check for updates",checkPrinterFirmware:"Check printer firmware",includeBetaUpdates:"Include beta versions",includeBetaUpdatesDesc:"Notify about beta and prerelease versions when checking for updates",enableRetry:"Enable retry",homeAssistantDescription:"Control smart plugs via Home Assistant",environmentManagedLabel:"(Environment Managed)",autoEnabledViaEnv:"Automatically enabled via environment variables",urlFromEnvReadOnly:"Value set by HA_URL environment variable (read-only)",tokenFromEnvReadOnly:"Value set by HA_TOKEN environment variable (read-only)",mqttConnectedTo:"Connected to",prometheusDescription:"Expose printer data in Prometheus format",noSmartPlugsTitle:"No smart plugs configured",noSmartPlugsDescription:"Add a Tasmota-based smart plug to track energy usage and automate power control.",noProvidersTitle:"No providers configured",noProvidersDescription:"Add a provider to receive alerts.",noTemplatesAvailable:"No templates available. Restart the backend to seed default templates.",apiPermissionView:"View printer status and queue",apiPermissionEdit:"Add and remove items from print queue",apiKeysEmptyTitle:"No API keys",apiKeysEmptyDescription:"Create an API key to integrate with external services.",noUsersFound:"No users found",noGroupsFound:"No groups found",noGroupsAvailable:"No groups available",passwordsDoNotMatch:"Passwords do not match",systemGroupWarning:"System group names cannot be changed",authDisabledTitle:"Authentication is Disabled",authDisabledFeature1:"Require login to access the system",authDisabledFeature2:"Create multiple users with group-based permissions",authDisabledFeature3:"Control access with 50+ granular permissions",userHasCreated:"This user has created:",userItemsQuestion:"What would you like to do with these items?",deleteUserConfirm:"Are you sure you want to delete this user?",actionCannotBeUndone:"This action cannot be undone.",addFirstSmartPlug:"Add Your First Smart Plug",providers:"Providers",log:"Log",testAll:"Test All",testResults:"Test Results",testPassedCount:"{{count}} passed",testFailedCount:"{{count}} failed",messageTemplates:"Message Templates",messageTemplatesDescription:"Customize notification messages for each event.",apiKeys:"API Keys",apiKeysDescription:"Create API keys for external integrations and webhooks.",createKey:"Create Key",apiKeyCreated:"API Key Created Successfully",apiKeyCopyWarning:"Copy this key now - it won't be shown again!",useInApiBrowser:"Use in API Browser",createNewApiKey:"Create New API Key",keyName:"Key Name",keyNamePlaceholder:"e.g., Home Assistant, OctoPrint",readStatus:"Read Status",readStatusDescription:"View printer status and queue",manageQueue:"Manage Queue",manageQueueDescription:"Add and remove items from print queue",controlPrinter:"Control Printer",controlPrinterDescription:"Pause, resume, and stop prints",cloudAccess:"Allow cloud access",cloudAccessDescription:"Read Bambu Cloud presets and filaments on your behalf. Requires you to be signed into Bambu Cloud.",cloudBadge:"Cloud",updateEnergyCost:"Update electricity price",updateEnergyCostDescription:"Allow this key to POST a new per-kWh electricity price to /settings/electricity-price. Useful for Home Assistant dynamic-tariff automations (Tibber, Octopus, etc.). This is the only settings field writable via API key.",energyCostBadge:"Energy",legacyKey:"Legacy",legacyKeyTooltip:"Created before per-user ownership; recreate to use cloud access",unnamedKey:"Unnamed Key",lastUsed:"Last used",read:"Read",control:"Control",createFirstKey:"Create Your First Key",webhookEndpoints:"Webhook Endpoints",webhookApiKeyHint:"Use your API key in the X-API-Key header.",webhook:{getAllStatus:"Get all printer status",getSpecificStatus:"Get specific printer status",addToQueue:"Add to print queue",pausePrint:"Pause print",resumePrint:"Resume print",stopPrint:"Stop print"},apiBrowser:"API Browser",apiBrowserDescription:"Explore and test all available API endpoints.",apiKeyForTesting:"API Key for Testing",apiKeyPlaceholder:"Paste your API key here to test authenticated endpoints...",apiKeyHint:"This key will be sent as X-API-Key header with requests.",deleteApiKeyTitle:"Delete API Key",deleteApiKeyMessage:"Are you sure you want to delete this API key? Any integrations using this key will stop working.",deleteKey:"Delete Key",amsDisplayThresholds:"AMS Display Thresholds",amsThresholdsDescription:"Configure color thresholds for AMS humidity and temperature indicators.",humidity:"Humidity",goodGreen:"Good (green)",fairOrange:"Fair (orange)",aboveFairBad:"Above fair threshold shows as red (bad)",fairAlsoDryingThreshold:"This threshold is also used to trigger auto-drying when enabled",temperature:"Temperature",goodBlue:"Good (blue)",aboveFairHot:"Above fair threshold shows as red (hot)",historyRetention:"History Retention",keepSensorHistory:"Keep sensor history for",historyRetentionDescription:"Older humidity and temperature data will be automatically deleted",defaultPrintOptions:"Default Print Options",defaultPrintOptionsDescription:"Set default values for print options when starting new prints. These can be overridden per print in the print dialog.",defaultBedLevelling:"Bed Levelling",defaultBedLevellingDesc:"Auto-level bed before print",defaultFlowCali:"Flow Calibration",defaultFlowCaliDesc:"Calibrate extrusion flow",defaultVibrationCali:"Vibration Calibration",defaultVibrationCaliDesc:"Reduce ringing artifacts",defaultLayerInspect:"First Layer Inspection",defaultLayerInspectDesc:"AI inspection of first layer",defaultTimelapse:"Timelapse",defaultTimelapseDesc:"Record timelapse video",staggeredStart:"Staggered Start",staggeredStartDescription:"Default group size and interval when staggering multi-printer batch starts. Can be overridden per batch in the print modal.",plateClear:"Plate-Clear Confirmation",requirePlateClear:"Require plate-clear confirmation",requirePlateClearDescription:'When enabled, the scheduler waits for per-printer plate-clear confirmation before starting queued prints on printers with finished jobs. Disabling this also hides the plate status badge and the "Mark plate as cleared" button on printer cards.',gcodeInjection:"G-code Injection",gcodeInjectionDescription:'Configure custom G-code to inject at the start and/or end of prints for auto-print systems like Farmloop, SwapMod, AutoClear, and Printflow 3D. Snippets are configured per printer model and applied when "Inject G-code" is enabled on a queue item.',gcodeInjectionNoPrinters:"No printers found. Add printers to configure G-code snippets.",gcodeStartLabel:"Start G-code",gcodeEndLabel:"End G-code",gcodeStartPlaceholder:"G-code prepended before the print starts...",gcodeEndPlaceholder:"G-code appended after the print ends...",staggerGroupSize:"Group size",staggerGroupSizeHelp:"Printers to start simultaneously per group",staggerInterval:"Interval (minutes)",staggerIntervalHelp:"Delay between each group starting",queueDrying:"Queue Auto-Drying",queueDryingDescription:"Automatically dry AMS filament when printer is idle between queued prints. Uses humidity threshold above to trigger drying.",queueDryingEnabled:"Enable auto-drying",queueDryingEnabledDescription:"Start AMS drying automatically when printer is idle and humidity is above threshold",queueDryingBlock:"Wait for drying to complete",queueDryingBlockDescription:"Block the print queue until drying finishes. When off, prints take priority over drying.",ambientDryingEnabled:"Ambient drying",ambientDryingEnabledDescription:"Automatically dry filament on idle printers when humidity exceeds threshold, even without queued prints.",dryingPresets:"Drying Presets",dryingPresetsDescription:"Temperature and duration per filament type. AMS 2 Pro uses lower temps, AMS-HT supports higher temps.",dryingFilament:"Filament",printModal:"Print Modal",expandCustomMapping:"Expand custom mapping by default",expandCustomMappingDescription:"When printing to multiple printers, show per-printer AMS mapping expanded",authentication:"Authentication",authEnabledDescription:"Your instance is secured with user authentication",authDisabledDescription:"Enable to require login and manage user access",authDisabledMessage:"Enable authentication to create user accounts, manage permissions, and secure your Bambuddy instance.",enableAuthentication:"Enable Authentication",currentUser:"Current User",changePassword:"Change Password",admin:"Admin",users:"Users",addUser:"Add User",groups:"Groups",addGroup:"Add Group",system:"System",noDescription:"No description",userCount:"{{count}} users",permissionCount:"{{count}} permissions",createUser:"Create User",username:"Username",enterUsername:"Enter username",password:"Password",enterPassword:"Enter password",passwordRequirements:"At least 8 characters, with one uppercase, one lowercase, one digit, and one special character.",confirmPassword:"Confirm Password",confirmPasswordPlaceholder:"Confirm password",viewReleaseOnGitHub:"View release on GitHub",turnAllPlugsOn:"Turn all plugs on",turnAllPlugsOff:"Turn all plugs off",clearNotificationLogs:"Clear Notification Logs",clearLogsMessage:"This will permanently delete all notification logs older than 30 days. This action cannot be undone.",clearLogs:"Clear Logs",resetUiPreferences:"Reset UI Preferences",resetUiPreferencesMessage:"This will reset all UI preferences to defaults: sidebar order, theme, dashboard layout, view modes, and sorting preferences. Your printers, archives, and server settings will NOT be affected. The page will reload after clearing.",resetPreferences:"Reset Preferences",deleteGroupTitle:"Delete Group",deleteGroupMessage:"Are you sure you want to delete this group? Users in this group will lose these permissions.",deleteGroup:"Delete Group",disableAuthenticationTitle:"Disable Authentication",disableAuthenticationMessage:"Are you sure you want to disable authentication? This will make your Bambuddy instance accessible without login. All users will remain in the database but authentication will be disabled.",disableAuthentication:"Disable Authentication",configureBambuddy:"Configure Bambuddy",systemDefault:"System Default",archiveSettings:"Archive Settings",newWindow:"New Window",embeddedOverlay:"Embedded Overlay",preferredSlicer:"Preferred Slicer",preferredSlicerDescription:"Choose which slicer application to open files with",orcaslicerKnownIssuesWarning:"OrcaSlicer 2.3.2 / 2.4.0-dev have known CLI bugs that block slicing many Bambu-authored 3MFs — see upstream issues #12426 (segfault on painted multi-extruder files) and #13386 (parameter-range strict-validation reject). Bambu Studio is recommended until the upstream fixes land.",useSlicerApi:"Use Slicer API",useSlicerApiDescription:'When on, "Slice" actions open the in-app slicer modal and call the slicer-API sidecar. When off (default), they hand off to the desktop slicer via URI scheme.',slicerCard:"Slicer",orcaslicerApiUrl:"OrcaSlicer sidecar URL",bambuStudioApiUrl:"Bambu Studio sidecar URL",slicerApiUrlDescription:"URL of the slicer-API sidecar container. Leave blank to use the SLICER_API_URL / BAMBU_STUDIO_API_URL env var defaults.",slicerBundles:{title:"Slicer Bundles",description:'Import a Printer Preset Bundle (.bbscfg) exported from BambuStudio (File → Export → Export Preset Bundle → "Printer preset bundle"). Once imported, slice requests can pick presets from the bundle by name without re-uploading the JSON profile triplet.',uploadButton:"Upload bundle",uploading:"Uploading…",loading:"Loading bundles…",empty:"No bundles imported yet.",summary:"{{processCount}} process · {{filamentCount}} filament presets",delete:"Delete",uploadSuccess:"Imported {{name}}",uploadError:"Bundle upload failed: {{message}}",deleteSuccess:"Bundle removed",deleteError:"Bundle delete failed: {{message}}",confirmDeleteTitle:"Remove this bundle?",confirmDeleteMessage:'Slice requests that reference "{{name}}" will fail until the bundle is re-imported.'},externalCameras:"External Cameras",costTracking:"Cost Tracking",printsOnly:"Prints Only",totalConsumption:"Total Consumption",dataManagement:"Data Management",storageUsage:"Storage Usage",storageUsageDescription:"Breakdown of data usage by category",storageUsageTotal:"Total",storageUsageErrors:"Errors",storageUsageOtherBreakdown:"Other (includes static assets, scripts, and configuration files)",storageUsageSystem:"System",storageUsageData:"Data",storageUsageUnavailable:"Storage usage information unavailable",clearNotificationLogsDescription:"Delete notification logs older than 30 days",resetUiPreferencesDescription:"Reset sidebar order, theme, view modes, and layout preferences. Printers, archives, and settings are not affected.",enableHomeAssistant:"Enable Home Assistant",enableMqtt:"Enable MQTT",useTls:"Use TLS",enableMetricsEndpoint:"Enable Metrics Endpoint",availableMetrics:"Available Metrics",editUser:"Edit User",deleteUserTitle:"Delete User",groupName:"Group Name",leaveEmptyForAnonymous:"Leave empty for anonymous",leaveEmptyForNoAuth:"Leave empty for no authentication",enterNewPassword:"Enter new password",confirmNewPassword:"Confirm new password",enterGroupName:"Enter group name",enterDescriptionOptional:"Enter description (optional)",enterCurrentPassword:"Enter current password",enterNewPasswordMin6:"Enter new password (min 6 characters)",toast:{keyCopied:"Key copied to clipboard",copyFailed:"Failed to copy key",keyAddedToBrowser:"Key added to API Browser",clearLogsFailed:"Failed to clear logs",uiPreferencesReset:"UI preferences reset. Refreshing...",authDisabled:"Authentication disabled successfully",authDisableFailed:"Failed to disable authentication",apiKeyCreated:"API key created",apiKeyDeleted:"API key deleted",userCreated:"User created successfully",userUpdated:"User updated successfully",userDeleted:"User deleted successfully",groupCreated:"Group created successfully",groupUpdated:"Group updated successfully",groupDeleted:"Group deleted successfully",fillRequiredFields:"Please fill in all required fields",passwordsDoNotMatch:"Passwords do not match",passwordTooShort:"Password must be at least 8 characters",passwordNeedsUppercase:"Password must contain at least one uppercase letter",passwordNeedsLowercase:"Password must contain at least one lowercase letter",passwordNeedsDigit:"Password must contain at least one digit",passwordNeedsSpecial:"Password must contain at least one special character",enterGroupName:"Please enter a group name",settingsSaved:"Settings saved",noPermissionUpdate:"You do not have permission to change settings",cameraSettingsSaved:"Camera settings saved",enterCameraUrl:"Please enter a camera URL",passwordChanged:"Password changed successfully",connectionFailed:"Connection failed",testFailed:"Test failed",cameraConnected:"Camera connected{{resolution}}"},testConnection:"Test Connection",catalog:{spoolCatalog:"Spool Catalog",spoolCatalogDescription:"Empty spool weights by brand/type. Used for automatic weight lookup when adding spools.",searchCatalog:"Search catalog...",addNewEntry:"Add New Entry",namePlaceholder:"Name (e.g., Bambu Lab - Plastic)",weight:"Weight",type:"Type",default:"Default",custom:"Custom",noMatch:"No entries match your search",empty:"No entries in catalog",deleteEntry:"Delete Entry",deleteConfirm:'Are you sure you want to delete "{{name}}"?',resetCatalog:"Reset Catalog",resetConfirm:"Reset catalog to defaults? This will remove all custom entries.",loadFailed:"Failed to load spool catalog",nameWeightRequired:"Name and weight are required",entryAdded:"Entry added",addFailed:"Failed to add entry",entryUpdated:"Entry updated",updateFailed:"Failed to update entry",entryDeleted:"Entry deleted",deleteFailed:"Failed to delete entry",resetSuccess:"Catalog reset to defaults",resetFailed:"Failed to reset catalog",exported:"Exported {{count}} entries",imported:"Imported {{added}} entries ({{skipped}} skipped)",importFailed:"Failed to import: invalid JSON format",exportTooltip:"Export catalog to JSON",importTooltip:"Import catalog from JSON",resetTooltip:"Reset to defaults",selectedCount:"{{count}} selected",deleteSelected:"Delete Selected",bulkDeleteConfirm:"Are you sure you want to delete {{count}} entries?",bulkDeleted:"Deleted {{count}} entries",bulkDeleteFailed:"Failed to delete entries",material:"Material",spoolWeight:"Spool Weight",color:"Color",updateSpoolWeight:"Update Spool Weight",filamentUpdated:"Filament updated",filamentUpdateFailed:"Failed to update filament",filamentUpdateInvalid:"Invalid filament data",keepExistingSpoolWeight:"Keep old weight for existing spools",keepExistingSpoolWeightDesc:"Spools already created with this filament type retain the old tare weight. New spools use the updated value.",applyToAllSpools:"Apply to all spools",applyToAllSpoolsDesc:"All weight calculations for this filament type immediately use the new tare weight."},colorCatalog:{title:"Color Catalog",description:"Filament colors by manufacturer/material. Used for automatic color lookup when adding spools.",searchColors:"Search colors...",allManufacturers:"All manufacturers",addNewColor:"Add New Color",manufacturer:"Manufacturer",colorName:"Color Name",hex:"Hex",materialOptional:"Material (optional)",showing:"Showing {{filtered}} of {{total}} colors",noMatch:"No colors match your search",empty:"No colors in catalog",deleteColor:"Delete Color",deleteConfirm:'Are you sure you want to delete "{{name}}"?',resetCatalog:"Reset Color Catalog",resetConfirm:"Reset catalog to defaults? This will remove all custom colors.",sync:"Sync",starting:"Starting...",syncTooltip:"Sync from FilamentColors.xyz (2000+ colors, may take a minute)",loadFailed:"Failed to load color catalog",fieldsRequired:"Manufacturer, color name, and hex color are required",colorAdded:"Color added",addFailed:"Failed to add color",colorUpdated:"Color updated",updateFailed:"Failed to update color",colorDeleted:"Color deleted",deleteFailed:"Failed to delete color",resetSuccess:"Color catalog reset to defaults",resetFailed:"Failed to reset catalog",syncUpToDate:"Already up to date ({{count}} colors checked)",syncComplete:"Added {{added}} new colors ({{skipped}} already existed)",syncError:"Sync error",syncFailed:"Failed to sync from FilamentColors.xyz",exported:"Exported {{count}} colors",imported:"Imported {{added}} colors ({{skipped}} skipped)",importFailed:"Failed to import: invalid JSON format",selectedCount:"{{count}} selected",deleteSelected:"Delete Selected",bulkDeleteConfirm:"Are you sure you want to delete {{count}} colors?",bulkDeleted:"Deleted {{count}} colors",bulkDeleteFailed:"Failed to delete colors"},dateFormat:"Date Format",dateFormatUs:"US (MM/DD/YYYY)",dateFormatEu:"EU (DD/MM/YYYY)",dateFormatIso:"ISO (YYYY-MM-DD)",timeFormat:"Time Format",timeFormat12:"12-hour (3:30 PM)",timeFormat24:"24-hour (15:30)",defaultPrinter:"Default Printer",defaultPrinterDescription:"Pre-select this printer for uploads, reprints, and other operations.",slicerBambuStudio:"Bambu Studio",slicerOrcaSlicer:"OrcaSlicer",sidebarOrderDescription:"Drag items in the sidebar to reorder. Reset to default order here.",setDefault:"Set Default",sidebarOrderSetDefaultHint:"Set default applies the current menu order to users who haven't customized theirs.",sidebarDefaultSet:"Default menu order has been set.",sidebarDefaultCleared:"Default menu order cleared.",sidebarDefaultFailed:"Failed to set default menu order.",reset:"Reset",darkMode:"Dark Mode",lightMode:"Light Mode",active:"(active)",background:"Background",accent:"Accent",style:"Style",bgNeutral:"Neutral",bgWarm:"Warm",bgCool:"Cool",bgOled:"OLED Black",bgSlate:"Slate Blue",bgForest:"Forest Green",accentGreen:"Green",accentTeal:"Teal",accentBlue:"Blue",accentOrange:"Orange",accentPurple:"Purple",accentRed:"Red",styleClassic:"Classic",styleGlow:"Glow",styleVibrant:"Vibrant",themeToggleHint:"Toggle between dark and light mode using the sun/moon icon in the sidebar.",autoArchivePrints:"Auto-archive prints",autoArchiveDescription:"Automatically save 3MF files when prints complete",saveThumbnailsDescription:"Extract and save preview images from 3MF files",captureFinishPhotoDescription:"Take a photo from printer camera when print completes",ffmpegNotInstalled:"ffmpeg not installed",ffmpegRequired:"Camera capture requires ffmpeg. Install it via brew install ffmpeg (macOS) or apt install ffmpeg (Linux).",camera:"Camera",cameraViewMode:"Camera View Mode",cameraOverlayDescription:"Camera opens in a resizable overlay on the main screen",cameraWindowDescription:"Camera opens in a separate browser window",externalCamerasDescription:"Configure external cameras to replace the built-in printer camera. Supports MJPEG streams, RTSP, HTTP snapshots, and USB cameras (V4L2). When enabled, the external camera is used for live view and finish photos.",cameraPlaceholderUsb:"Device path (/dev/video0)",cameraPlaceholderUrl:"Camera URL (rtsp://... or http://...)",cameraTypeMjpeg:"MJPEG Stream",cameraTypeRtsp:"RTSP Stream",cameraTypeSnapshot:"HTTP Snapshot",cameraTypeUsb:"USB Camera (V4L2)",cameraSnapshotUrl:"Snapshot URL (optional)",cameraSnapshotUrlPlaceholder:"http://192.168.1.61:1984/api/frame.jpeg?src=printer",cameraSnapshotUrlHelp:"Single-frame URL used for notification thumbnails, finish photos, layer-timelapse frames, and plate detection. Timelapse and plate detection each require their own per-printer toggle — this URL is just the image source they pull from when active. Leave blank to capture from the live stream above. Useful for go2rtc (/api/frame.jpeg) and IP cameras with a dedicated snapshot endpoint.",cameraRotation:"Rotation",test:"Test",connected:"Connected",disconnected:"Disconnected",currency:"Currency",defaultFilamentCost:"Default filament cost (per kg)",electricityCost:"Electricity cost per kWh",energyDisplayMode:"Energy display mode",energyModePrintDescription:"Dashboard shows sum of energy used during prints",energyModeTotalDescription:"Dashboard shows lifetime energy from smart plugs",fileManager:"File Manager",createArchiveEntry:"Create Archive Entry When Printing",createArchiveEntryDescription:"When printing from File Manager, optionally create an archive entry",lowDiskSpaceWarning:"Low Disk Space Warning",lowDiskSpaceDescription:"Show warning when free disk space falls below this threshold",printerFirmware:"Printer Firmware",checkFirmwareDescription:"Check for printer firmware updates from Bambu Lab",bambuddySoftware:"Bambuddy Software",autoCheckDescription:"Automatically check for new versions on startup",checkNow:"Check now",updateAvailableVersion:"Update available: v{{version}}",releaseNotes:"Release Notes",updateViaDocker:"Update via Docker Compose:",updateViaHomeAssistant:"Updates are managed by the Home Assistant Supervisor. Open Settings → Add-ons → Bambuddy in Home Assistant to install the new version.",installUpdate:"Install Update",latestVersionRunning:"You're running the latest version",failedToCheckUpdates:"Failed to check for updates: {{error}}",backupRestore:"Backup & Restore",backupRestoreDescription:"Export/import settings and configure GitHub backup",goToBackup:"Go to Backup",externalUrl:"External URL",externalUrlDescription:"The external URL where Bambuddy is accessible. Used for notification images and external integrations.",bambuddyUrl:"Bambuddy URL",externalUrlHint:"Include protocol and port (e.g., http://192.168.1.100:8000)",ftpRetry:"FTP Retry",ftpRetryDescription:"Retry FTP operations when printer WiFi is unreliable. Applies to 3MF downloads, print uploads, timelapse downloads, and firmware updates.",autoRetryDescription:"Automatically retry failed FTP operations",retryAttempts:"Retry attempts",retryDelay:"Retry delay",connectionTimeout:"Connection timeout",time_one:"{{count}} time",time_other:"{{count}} times",second_one:"{{count}} second",second_other:"{{count}} seconds",nSeconds:"{{count}} seconds",increaseForWeakWifi:"Increase for printers with weak WiFi",homeAssistant:"Home Assistant",homeAssistantFullDescription:"Connect to Home Assistant to control smart plugs via HA's REST API. Supports switch, light, input_boolean, and script entities.",homeAssistantUrl:"Home Assistant URL",longLivedAccessToken:"Long-Lived Access Token",haTokenHint:"Create a token in HA: Profile → Long-Lived Access Tokens → Create Token",connectionSuccessful:"Connection Successful",connectionFailed:"Connection Failed",haConnectionSuccess:"Successfully connected to Home Assistant.",haConnectionFailed:"Failed to connect to Home Assistant.",mqttPublishing:"MQTT Publishing",mqttDescription:"Publish BamBuddy events to an external MQTT broker for integration with Node-RED, Home Assistant, and other automation systems.",mqttEnableDescription:"Publish events to external MQTT broker",brokerHostname:"Broker hostname",port:"Port",usernameOptional:"Username (optional)",passwordOptional:"Password (optional)",topicPrefix:"Topic prefix",topicPrefixHint:"Topics will be: {{prefix}}/printers//status, etc.",prometheusMetrics:"Prometheus Metrics",prometheusEndpointDescription:"Expose printer metrics at /api/v1/metrics for Prometheus/Grafana monitoring.",bearerTokenOptional:"Bearer Token (optional)",bearerTokenHint:"If set, requests must include Authorization: Bearer ",metricsConnectionStatus:"Connection status",metricsPrinterState:"Printer state (idle/printing/etc)",metricsPrintProgress:"Print progress 0-100%",metricsBedTemp:"Bed temperature",metricsNozzleTemp:"Nozzle temperature",metricsPrintsTotal:"Total prints by result",metricsMore:"...and more (layers, fans, queue, filament usage)",smartPlugsDescription:"Connect smart plugs (Tasmota or Home Assistant) to automate power control and track energy usage for your printers.",allOn:"All On",allOff:"All Off",addSmartPlug:"Add Smart Plug",energySummary:"Energy Summary",currentPower:"Current Power",plugsOnline:"{{reachable}}/{{total}} plugs online",today:"Today",yesterday:"Yesterday",total:"Total",enablePlugsForSummary:"Enable plugs to see energy summary",addNotificationProvider:"Add",systemBadge:"(System)",creating:"Creating...",changing:"Changing...",deleteUserAndItems:"Delete user AND their items",deleteUserKeepItems:"Delete user, keep items (become ownerless)",ok:"OK",twoFa:{totpTitle:"Authenticator App (TOTP)",totpDesc:"Use an authenticator app like Google Authenticator, Aegis or Authy.",emailOtpTitle:"Email OTP",emailOtpDesc:"Send a one-time code to {{email}} when you log in.",emailOtpNoEmail:"Add an email address to your account to enable this method.",addEmailFirst:"Your account has no email address. Ask an admin to add one before enabling Email OTP.",setupTotp:"Set up Authenticator App",setupAuthApp:"Set up Authenticator App",setupInstructions:"Scan the QR code below with your authenticator app, then confirm with a code.",manualEntry:"Can't scan? Enter this secret manually:",scannedContinue:"I've scanned the code — continue",enterCodeToConfirm:"Enter the 6-digit code from your authenticator app to confirm setup.",activate:"Activate",disableTotp:"Disable Authenticator",disableConfirmHint:"Enter a valid TOTP code or a backup code to disable the authenticator.",totpDisabled:"Authenticator app disabled.",emailOtpEnabled:"Email OTP enabled.",emailOtpDisabled:"Email OTP disabled.",smtpRequired:"Please configure and test SMTP settings first.",invalidCode:"Invalid code. Please try again.",enableEmailOtp:"Enable Email OTP",disableEmailOtp:"Disable Email OTP",emailSetupEnterCode:"A verification code has been sent to your email address. Enter it below to confirm you own this inbox.",verifyAndEnable:"Verify & Enable",emailDisablePasswordHint:"Enter your account password to confirm disabling email OTP.",passwordPlaceholder:"Enter your password",backupCodesTitle:"Save your backup codes",backupCodesWarning:"Save these codes somewhere safe. Each code can only be used once and they will not be shown again.",backupCodesRemaining:"{{count}} backup codes remaining",savedCodes:"I've saved my codes",regenBackup:"Regenerate Backup Codes",regenBackupHint:"Enter your current TOTP code to generate 10 new backup codes. All existing backup codes will be invalidated.",newBackupCodes:"New backup codes",linkedAccounts:"Linked SSO Accounts",linkedAccountsDesc:"These external identity providers are linked to your account.",oidcUnlinked:"Account unlinked."},oidc:{title:"SSO / OIDC Providers",desc:"Configure OpenID Connect providers to allow single sign-on via external identity providers.",addProvider:"Add Provider",newProvider:"New Provider",empty:"No OIDC providers configured yet.",created:"Provider created.",updated:"Provider updated.",deleted:"Provider deleted.",refreshIcon:"Refresh icon",removeIcon:"Remove icon",iconRefreshed:"Icon refreshed.",iconRemoved:"Icon removed.",iconFetchFailed:"Icon could not be fetched from the provider URL.",deleteTitle:"Delete Provider",deleteMessage:'Delete "{{name}}"? All linked user accounts will be disconnected.',form:{name:"Display Name",issuerUrl:"Issuer URL",clientId:"Client ID",clientSecret:"Client Secret",scopes:"Scopes",iconUrl:"Icon URL (optional)",enabled:"Enabled",autoCreate:"Auto-create users",autoCreateDesc:"Automatically create a local account on first login.",autoLink:"Auto-link existing accounts",autoLinkDesc:"Link existing local accounts by matching email on first login.",secretHint:"leave blank to keep current",secretPlaceholder:"new secret",emailClaim:"Email Claim",emailClaimDesc:"JWT claim used as email identity. Use 'preferred_username' or 'upn' for Azure Entra ID (which does not send email_verified). Only use trusted claim names.",emailClaimPlaceholder:"email",emailClaimCustomClaimAutoLinkWarning:"Custom claims are safe for auto-link only when the value is tenant-administered (e.g. Azure Entra ID upn / preferred_username). Do not enable auto-link if your IdP allows users to self-assert this claim.",requireEmailVerified:"Require email verified",requireEmailVerifiedDesc:"Only accept the email claim when the provider marks it as verified.",requireEmailVerifiedWarning:"Warning: email will be accepted even without verification. Use only with trusted providers.",requireEmailVerifiedAutoLink:"Disable auto-link first to change this setting.",defaultGroup:"Default Group",defaultGroupDesc:"Group assigned to auto-created users. Falls back to Viewers if not set.",defaultGroupViewersFallback:"Viewers (default)"}},encryption:{title:"MFA Encryption Status",enabledFromEnv:"At-rest encryption enabled (key from MFA_ENCRYPTION_KEY environment variable)",enabledFromFile:"At-rest encryption enabled (key loaded from data directory)",enabledGenerated:"At-rest encryption enabled with auto-generated key",notConfigured:"At-rest encryption not configured",notConfiguredDesc:"TOTP secrets and OIDC client_secrets are stored in plaintext. Set MFA_ENCRYPTION_KEY or restart Bambuddy with a writable data directory to auto-generate one.",allEncrypted:"All MFA secrets are encrypted at rest.",legacyRowsLabel:"Legacy plaintext rows",encryptedRowsLabel:"Encrypted rows",legacyRowsWarning:"{{count}} legacy plaintext row(s) detected. Re-save the OIDC provider or re-enroll the user’s authenticator app to migrate to encrypted storage.",backupHint:"The auto-generated key is stored at DATA_DIR/.mfa_encryption_key and is included in local backup ZIPs. Keep your backups secure or set MFA_ENCRYPTION_KEY explicitly.",decryptionBrokenTitle:"Encryption key missing",decryptionBrokenError:"{{count}} encrypted record(s) cannot be decrypted because the encryption key is no longer available. Restore the previous MFA_ENCRYPTION_KEY or DATA_DIR/.mfa_encryption_key to recover.",migrationErrorWarning:"{{count}} legacy row(s) failed to re-encrypt at startup. Check server logs and restart Bambuddy to retry."}},notification:{printStarted:{title:"Print Started",body:"{{printer}}: {{filename}} has started printing"},printCompleted:{title:"Print Completed",body:"{{printer}}: {{filename}} completed successfully"},printFailed:{title:"Print Failed",body:"{{printer}}: {{filename}} has failed"},printStopped:{title:"Print Stopped",body:"{{printer}}: {{filename}} was stopped"},printProgress:{title:"Print Progress",body:"{{printer}}: {{filename}} is {{percent}}% complete"},printerOffline:{title:"Printer Offline",body:"{{printer}} is offline"},printerError:{title:"Printer Error",body:"{{printer}}: {{error}}"},filamentLow:{title:"Low Filament",body:"{{printer}}: Filament is running low"},maintenanceDue:{title:"Maintenance Due",body:"{{printer}}: {{items}} need attention"}},errors:{generic:"Something went wrong",networkError:"Network error. Please check your connection.",notFound:"Not found",unauthorized:"Unauthorized",serverError:"Server error",validationError:"Please check your input",printerConnectionFailed:"Failed to connect to printer",saveFailed:"Failed to save changes",deleteFailed:"Failed to delete",loadFailed:"Failed to load data"},hmsErrors:{title:"Errors - {{name}}",noErrors:"No errors",viewOnWiki:"View on Bambu Lab Wiki",clearInstructions:"Clear errors on the printer to dismiss them here.",clearErrors:"Clear Errors",clearSuccess:"HMS errors cleared",clearFailed:"Failed to clear HMS errors"},mqttDebug:{title:"MQTT Debug Log",searchPlaceholder:"Search topic or payload...",noMessages:"No messages logged yet",startLoggingHint:'Click "Start Logging" to begin capturing MQTT messages',noMessagesMatch:"No messages match your filter",adjustFilterHint:"Try adjusting your search or filter criteria",incoming:"Incoming",outgoing:"Outgoing",loggingStopped:"Logging stopped",loggingActive:"Logging active - messages will auto-refresh",startLogging:"Start Logging",stopLogging:"Stop Logging",clearLog:"Clear Log",topic:"Topic",timestamp:"Timestamp",direction:"Direction",all:"All"},printerFiles:{title:"File Manager",storageUsed:"Used:",storageFree:"Free:",filterPlaceholder:"Filter files...",deleteButton:"Delete",deleteFiles:"Delete {{count}} Files",deleteFileConfirm:'Delete "{{name}}"? This cannot be undone.',deleteFilesConfirm:"Delete {{count}} selected files? This cannot be undone.",noFiles:"No files on printer",loadingFiles:"Loading files...",failedToLoad:"Failed to load files",toast:{filesDeleted:"Deleted {{count}} file(s)",deleteFailed:"Delete failed: {{error}}"}},confirm:{delete:"Are you sure you want to delete this?",unsavedChanges:"You have unsaved changes. Are you sure you want to leave?",clearQueue:"Are you sure you want to clear the queue?"},login:{title:"Bambuddy Login",subtitle:"Sign in to your account",username:"Username",usernamePlaceholder:"Enter your username",usernameOrEmail:"Username or Email",usernameOrEmailPlaceholder:"Username or @ Email",password:"Password",passwordPlaceholder:"Enter your password",signIn:"Sign in",signingIn:"Logging in...",rememberMe:"Remember Me",forgotPassword:"Forgot your password?",loginSuccess:"Logged in successfully",loginFailed:"Login failed",enterCredentials:"Please enter username and password",enterEmail:"Please enter your email address",oidcLoginFailed:"OIDC login failed",oidcErrors:{providerError:"The identity provider returned an error",missingParameters:"OIDC callback is missing required parameters",invalidState:"OIDC state is invalid or has already been used",stateExpired:"OIDC login session expired — please try again",providerNotFound:"OIDC provider not found",discoveryFailed:"Failed to fetch OIDC discovery document",invalidDiscovery:"OIDC discovery document is invalid",networkError:"Network error during OIDC token exchange",badResponse:"Unexpected response during OIDC token exchange",noIdToken:"OIDC provider did not return an ID token",validationFailed:"OIDC token validation failed",nonceMismatch:"OIDC nonce mismatch — possible replay attack",missingSubClaim:"OIDC token is missing the sub claim",noLinkedAccount:"No local account is linked to this OIDC identity",accountInactive:"Your account is inactive",userResolutionFailed:"Failed to resolve your account",internalError:"An internal error occurred during OIDC login",tokenExchangeFailed:"OIDC token exchange failed"},forgotPasswordTitle:"Forgot Password",forgotPasswordMessage:"If you've forgotten your password, please contact your system administrator to reset it.",forgotPasswordEmailMessage:"Enter your email address and we'll send you a new password.",emailAddress:"Email Address",emailPlaceholder:"your.email@example.com",cancel:"Cancel",sending:"Sending...",sendResetEmail:"Send Reset Email",howToReset:"How to reset your password:",resetStep1:"Contact your Bambuddy administrator",resetStep2:"Ask them to reset your password in User Management",resetStep3:"They can set a new temporary password for you",resetStep4:"Log in with the new password and change it in Settings",gotIt:"Got it",resetPassword:{title:"Set New Password",subtitle:"Enter and confirm your new password below.",newPassword:"New Password",newPasswordPlaceholder:"At least 8 characters",confirmPassword:"Confirm Password",confirmPasswordPlaceholder:"Repeat new password",saving:"Saving…",submit:"Set New Password",backToLogin:"Back to login",passwordsDoNotMatch:"Passwords do not match",passwordTooShort:"Password must be at least 8 characters",resetFailed:"Password reset failed. The link may have expired."},twoFA:{title:"Two-Factor Authentication",subtitle:"Your account is protected with 2FA. Enter the verification code below.",methodAuthenticator:"Authenticator App",methodEmail:"Email Code",methodBackup:"Backup Code",instructionsTotp:"Open your authenticator app and enter the 6-digit code for Bambuddy.",instructionsEmail:"A 6-digit code has been sent to your email address. It expires in 10 minutes.",instructionsEmailNotSent:"Click the button below to receive a verification code via email.",instructionsBackup:"Enter one of your 8-character backup recovery codes. Each code can only be used once.",sendCodeButton:"Send Code via Email",sendingCode:"Sending...",resendCode:"Resend code",codeLabel:"Verification Code",backupCodeLabel:"Backup Code",codePlaceholder:"000000",backupCodePlaceholder:"XXXXXXXX",verifyButton:"Verify",verifyingButton:"Verifying...",backToLogin:"← Back to login",orContinueWith:"or continue with",signInWith:"Sign in with {{provider}}",enterCode:"Please enter the verification code",sendCodeFailed:"Failed to send verification code",invalidCode:"Invalid code. Please try again."}},setup:{title:"Bambuddy Setup",subtitle:"Configure authentication for your Bambuddy instance",enableAuth:"Enable Authentication",adminAccount:"Admin Account",adminAccountDesc:"If admin users already exist, authentication will be enabled using the existing admin accounts. Leave the fields below empty to use existing admins, or enter new credentials to create a new admin user.",adminUsername:"Admin Username",adminPassword:"Admin Password",optionalIfAdminExists:"(optional if admin users exist)",adminUsernamePlaceholder:"Enter admin username (optional)",adminPasswordPlaceholder:"Enter admin password (optional)",confirmPassword:"Confirm Password",confirmPasswordPlaceholder:"Confirm admin password",settingUp:"Setting up...",completeSetup:"Complete Setup",toast:{authEnabledAdminCreated:"Authentication enabled and admin user created",authEnabledExistingAdmins:"Authentication enabled using existing admin users",setupCompleted:"Setup completed",enterBothCredentials:"Please enter both admin username and password, or leave both empty to use existing admin users",passwordsDoNotMatch:"Passwords do not match",passwordTooShort:"Password must be at least 6 characters"}},changePassword:{title:"Change Password",currentPassword:"Current Password",currentPasswordPlaceholder:"Enter current password",newPassword:"New Password",newPasswordPlaceholder:"Enter new password (min 6 characters)",confirmPassword:"Confirm New Password",confirmPasswordPlaceholder:"Confirm new password",passwordsDoNotMatch:"Passwords do not match",passwordTooShort:"Password must be at least 6 characters",changing:"Changing...",success:"Password changed successfully",failed:"Failed to change password"},plateAlert:{title:"Print Paused!",message:"Objects detected on build plate. The print has been automatically paused. Please clear the plate and resume the print.",understand:"I Understand"},camera:{title:"Camera View",invalidPrinterId:"Invalid printer ID",live:"Live",snapshot:"Snapshot",restartStream:"Restart stream",refreshSnapshot:"Refresh snapshot",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",connectingToCamera:"Connecting to camera...",capturingSnapshot:"Capturing snapshot...",connectionLost:"Connection lost",connectionFailed:"Camera connection failed",reconnecting:"Reconnecting in {{countdown}}s... (attempt {{attempt}}/{{max}})",reconnectNow:"Reconnect now",cameraUnavailable:"Camera unavailable",cameraUnavailableDesc:"Make sure the printer is powered on and connected.",noCamera:"No camera available",retry:"Retry",cameraStream:"Camera stream",zoomOut:"Zoom out",zoomIn:"Zoom in",resetZoom:"Reset zoom",recording:"Recording",startRecording:"Start Recording",stopRecording:"Stop Recording",chamberLight:"Toggle chamber light"},groups:{title:"Group Management",subtitle:"Manage permission groups for access control",backToSettings:"Back to Settings",createGroup:"Create Group",noPermission:"You do not have permission to access this page.",system:"System",noDescription:"No description",usersCount:"{{count}} users",permissionsCount:"{{count}} permissions",edit:"Edit",delete:"Delete",toast:{created:"Group created successfully",updated:"Group updated successfully",deleted:"Group deleted successfully",enterGroupName:"Please enter a group name"},modal:{editGroup:"Edit Group",createGroup:"Create Group",cancel:"Cancel",saving:"Saving...",creating:"Creating...",saveChanges:"Save Changes"},form:{groupName:"Group Name",groupNamePlaceholder:"Enter group name",systemGroupWarning:"System group names cannot be changed",description:"Description",descriptionPlaceholder:"Enter description (optional)",permissions:"Permissions ({{count}} selected)"},deleteModal:{title:"Delete Group",message:"Are you sure you want to delete this group? Users in this group will lose these permissions.",confirm:"Delete Group"},editor:{title:"Edit Group",createTitle:"Create Group",search:"Search permissions...",selectAll:"Select All",clearAll:"Clear All",permissionsSelected:"{{count}} selected",noResults:"No permissions match your search"}},users:{title:"User Management",subtitle:"Manage users and their access to your Bambuddy instance",backToSettings:"Back to Settings",createUser:"Create User",noPermission:"You do not have permission to access this page.",admin:"Admin",noGroups:"No groups",active:"Active",inactive:"Inactive",edit:"Edit",delete:"Delete",system:"System",noGroupsAvailable:"No groups available",table:{username:"Username",groups:"Groups",status:"Status",actions:"Actions"},toast:{created:"User created successfully",updated:"User updated successfully",deleted:"User deleted successfully",fillRequired:"Please fill in all required fields",passwordsDoNotMatch:"Passwords do not match",passwordTooShort:"Password must be at least 6 characters",ldapProvisioned:'Provisioned LDAP user "{{username}}"'},modal:{createUser:"Create User",editUser:"Edit User",cancel:"Cancel",creating:"Creating...",saving:"Saving...",saveChanges:"Save Changes",advancedAuthSubtitle:"with Advanced Authentication",tabsAriaLabel:"User source",localTab:"Local",ldapTab:"LDAP",ldapSearchLabel:"Search directory",ldapSearchPlaceholder:"Type a username, name, or email...",ldapMinChars:"Type at least 2 characters to search",ldapTypeToSearch:"Start typing to search the LDAP directory",ldapSearching:"Searching directory...",ldapNoResults:"No matching users in the directory",ldapSearchError:"Directory search failed. Check the LDAP server status.",ldapAlreadyProvisioned:"Already provisioned",ldapSelectedLabel:"Selected",ldapProvision:"Provision user",ldapProvisioning:"Provisioning...",ldapErrorProvision:"Provisioning failed. Check the LDAP server status and try again."},form:{username:"Username",usernamePlaceholder:"Enter username",email:"Email",emailPlaceholder:"user@example.com",password:"Password",passwordPlaceholder:"Enter password",confirmPassword:"Confirm Password",confirmPasswordPlaceholder:"Confirm password",newPasswordPlaceholder:"Enter new password",confirmNewPasswordPlaceholder:"Confirm new password",leaveBlankToKeep:"leave blank to keep current",groups:"Groups",optional:"optional",autoGeneratedPassword:"A secure password will be automatically generated and emailed to the user.",passwordManagedByAdvancedAuth:'Password is managed by Advanced Authentication. Use "Reset Password" to send a new password to the user via email.',resetPassword:"Reset Password",resettingPassword:"Resetting Password..."},deleteModal:{title:"Delete User",message:"Are you sure you want to delete this user? This action cannot be undone.",confirm:"Delete User"}},streamOverlay:{title:"Stream Overlay",invalidPrinterId:"Invalid printer ID",cameraStream:"Camera stream",progress:"Progress",eta:"ETA",printerIdle:"Printer is idle",printerOffline:"Printer offline",status:{printing:"Printing",paused:"Paused",finished:"Finished",failed:"Failed",idle:"Idle",unknown:"Unknown"}},profiles:{title:"Profiles",subtitle:"Manage your slicer presets and pressure advance calibrations",tabs:{cloud:"Cloud Profiles",local:"Local Profiles",kprofiles:"K-Profiles"},localProfiles:{title:"Local Profiles",subtitle:"Import and manage slicer presets from OrcaSlicer",import:"Import Profiles",importDesc:"Drop .bbscfg, .bbsflmt, .orca_filament, .zip, or .json files here",importing:"Importing...",search:"Search local presets...",noPresets:"No local presets yet",badge:"Local",edit:"Edit",delete:"Delete",cancel:"Cancel",deleteConfirmTitle:"Delete Preset",deleteConfirm:"Are you sure you want to delete this preset? This cannot be undone.",source:"Source",inheritsFrom:"Inherits",filamentType:"Type",vendor:"Vendor",compatiblePrinters:"Printers",nozzleTemp:"Nozzle Temp",cost:"Cost",density:"Density",pressureAdvance:"Pressure Advance",filament:"Filament",process:"Process",printer:"Printer",toast:{importSuccess:"{{count}} preset(s) imported",importSkipped:"{{count}} preset(s) skipped (duplicates)",importError:"{{count}} error(s) during import",deleted:"Preset deleted",updated:"Preset updated"}},connectedAs:"Connected as",logout:"Logout",noLogoutPermission:"You do not have permission to logout",failedToLoad:"Failed to load profiles",retry:"Retry",time:{justNow:"Just now",minsAgo:"{{count}}m ago",hoursAgo:"{{count}}h ago",daysAgo:"{{count}}d ago"},toast:{loggedOut:"Logged out"},login:{title:"Connect to Bambu Cloud",subtitle:"Sync your slicer presets across devices",email:"Email",password:"Password",region:"Region",regionGlobal:"Global",regionChina:"China",verificationCode:"Verification Code",totpCode:"Authenticator Code",checkEmail:"Check your email ({{email}}) for a 6-digit code",enterTotpHint:"Enter the 6-digit code from your authenticator app",accessToken:"Access Token",accessTokenHint:"Paste your Bambu Cloud access token. China-region accounts must use this path (phone-bound — email login unavailable). See the wiki for how to retrieve the token from MakerWorld cookies.",back:"Back",loginButton:"Login",verifyButton:"Verify",setTokenButton:"Set Token",useToken:"Use access token instead",useEmail:"Login with email instead",toast:{loggedIn:"Logged in successfully",codeSent:"Verification code sent to your email",enterTotp:"Enter code from your authenticator app",tokenSet:"Token set successfully"}},presets:{myPreset:"My preset (editable)",duplicate:"Duplicate",editable:"Editable",failedToLoadDetails:"Failed to load preset details",deleteConfirm:"Delete this preset?",deleteWarning:'This will permanently delete "{{name}}" from Bambu Cloud. This cannot be undone.',noDuplicatePermission:"You do not have permission to duplicate presets",noEditPermission:"You do not have permission to edit presets",noDeletePermission:"You do not have permission to delete presets",types:{filament:"Filament preset",printer:"Printer preset",process:"Process preset"},toast:{deleted:"Preset deleted",created:"Preset created",updated:"Preset updated",duplicated:"Preset duplicated",fieldAdded:'Field "{{key}}" added',exported:"Preset exported"},baseLabel:"Base: {{name}}",currentLabel:"Current: {{name}}",newPreset:"New Preset",editPreset:"Edit Preset",duplicatePreset:"Duplicate Preset",createNewPreset:"Create New Preset",customizeSettings:"Customize settings for your new preset",compareWithBase:"Compare with base preset",compare:"Compare",basePreset:"Base Preset",selectBasePreset:"Select base preset...",presetName:"Preset Name",myCustomPreset:"My custom preset",inheritsFrom:"Inherits from",dropJsonToImport:"Drop JSON to import",tabs:{common:"Common",allFields:"All Fields"},availableFields:"Available Fields",searchFieldsPlaceholder:"Search fields...",noMatchingFields:"No matching fields",allFieldsAdded:"All fields added",addCustomField:"Add custom field",yourOverrides:"Your Overrides",noOverridesYet:"No overrides yet",clickFieldsToAdd:"Click fields on the left to add them",saveAsTemplate:"Save as template",jsonTip:"Tip: Drag & drop a .json file anywhere on this modal to import settings"},cloudView:{searchPlaceholder:"Search presets...",templates:"Templates",refresh:"Refresh",newPreset:"New Preset",clearFilters:"Clear filters",compareMode:"Compare Mode",selectAnotherPreset:"Select another {{type}} preset",clickTwoPresets:"Click two presets of the same type to compare",selectFirst:"1. Select first",selectSecond:"2. Select second",compareNow:"Compare Now",lastSynced:"Last synced:",showingCount:"Showing {{showing}} of {{total}} presets",noPresetsFound:"No presets found",columns:{filament:"Filament",process:"Process",printer:"Printer"},noFilamentPresets:"No filament presets",noProcessPresets:"No process presets",noPrinterPresets:"No printer presets",filters:{type:"Type",owner:"Owner",printer:"Printer",nozzle:"Nozzle",filament:"Filament",layer:"Layer",all:"All",myPresets:"My Presets",builtIn:"Built-in",process:"Process"},noTemplatesPermission:"You do not have permission to manage templates",noRefreshPermission:"You do not have permission to refresh profiles",noCreatePermission:"You do not have permission to create presets"},templates:{title:"Quick Templates",noTemplates:"No templates yet",createFirst:"Create templates from the preset editor",typeFilter:"Type:",deleteTitle:"Delete Template",deleteWarning:"This action cannot be undone",deleteConfirm:'Are you sure you want to delete "{{name}}"?',namePlaceholder:"Template name",descriptionPlaceholder:"Description",settingsJson:"Settings (JSON)",fieldsCount:"{{count}} fields",shownInModals:"Shown in modals",hiddenInModals:"Hidden in modals",apply:"Apply",toast:{deleted:"Template deleted",updated:"Template updated",created:"Template created",applied:"Template applied"}}},support:{debugLoggingActive:"Debug logging is active",manageLogs:"Manage",collectItem7:"Printer connectivity and firmware versions",collectItem8:"Integration status (Spoolman, MQTT, HA)",collectItem9:"Network interfaces (subnets only)",collectItem10:"Python package versions",collectItem11:"Database health checks",collectItem12:"Docker environment details"},fileManager:{title:"File Manager",subtitle:"Organize and manage your print files",uploadFiles:"Upload Files",newFolder:"New Folder",folderName:"Folder Name",folderNamePlaceholder:"e.g., Functional Parts",renameFile:"Rename File",renameFolder:"Rename Folder",moveFiles:"Move {{count}} File(s)",rootNoFolder:"Root (No Folder)",current:"current",linkFolder:"Link Folder",linkFolderDescription:'Link "{{name}}" to a project or archive for quick access.',project:"Project",archive:"Archive",noProjectsFound:"No projects found",noArchivesFound:"No archives found",unlink:"Unlink",link:"Link",dragDropFiles:"Drag & drop files here",dropFilesHere:"Drop files here",orClickToBrowse:"or click to browse",allFileTypesSupported:"All file types supported. ZIP files will be extracted.",zipFilesDetected:"ZIP files detected",zipExtractOptions:"ZIP files will be extracted. Choose how to handle folder structure:",preserveZipStructure:"Preserve folder structure from ZIP",createFolderFromZip:"Create folder from ZIP filename",stlThumbnailGeneration:"STL thumbnail generation",zipMayContainStl:"ZIP files may contain STL files. Thumbnails can be generated during extraction.",thumbnailsCanBeGenerated:"Thumbnails can be generated for STL files. Large models may take longer to process.",generateThumbnailsForStl:"Generate thumbnails for STL files",threemfDetected:"3MF files detected",threemfExtractionInfo:"Printer model, material, color, and print settings will be automatically extracted from 3MF files.",willBeExtracted:"Will be extracted",filesExtracted:"{{count}} files extracted",uploadComplete:"Upload complete: {{succeeded}} succeeded",uploadFailed:"Upload failed",zipFilesFailed:"{{count}} files failed",uploading:"Uploading...",changeLink:"Change Link...",linkTo:"Link to...",linkToProjectOrArchive:"Link to project or archive",addToQueue:"Add to Queue",schedulePrint:"Schedule",generateThumbnail:"Generate Thumbnail",generateThumbnails:"Generate Thumbnails",generateThumbnailsForMissing:"Generate thumbnails for STL files missing them",gridView:"Grid view",listView:"List view",lowDiskSpaceWarning:"Low disk space warning",lowDiskSpaceDetails:"Only {{free}} free of {{total}} total. Threshold is set to {{threshold}} GB in settings.",files:"Files",folders:"Folders",size:"Size",free:"Free",allFiles:"All Files",wrap:"Wrap",enableTextWrapping:"Enable text wrapping",disableTextWrapping:"Disable text wrapping",collapse:"Collapse",collapseFoldersByDefault:"Collapse folders by default",expandFoldersByDefault:"Expand folders by default",dragToResizeTooltip:"Drag to resize, double-click to reset",searchFiles:"Search files...",allTypes:"All types",prints:"Prints",ascending:"Ascending",descending:"Descending",resultsCount:"{{showing}} of {{total}} files",selectAll:"Select All",deselectAll:"Deselect All",selected:"{{count}} selected",adding:"Adding...",loadingFiles:"Loading files...",folderIsEmpty:"Folder is empty",noFilesYet:"No files yet",folderEmptyDescription:"Upload files or move files into this folder to get started.",noFilesDescription:"Upload files to start organizing your print-related files.",noMatchingFiles:"No matching files",noMatchingFilesDescription:"No files match your current search or filter criteria.",clearFilters:"Clear filters",printedCount:"Printed {{count}}x",uploadedBy:"Uploaded By",deleteFolder:"Delete Folder",deleteFile:"Delete File",deleteFilesCount:"Delete {{count}} Files",deleteFolderConfirm:"Are you sure you want to delete this folder? All files inside will also be deleted.",deleteFileConfirm:"Are you sure you want to delete this file?",deleteFilesConfirm:"Are you sure you want to delete {{count}} selected files? This action cannot be undone.",deleting:"Deleting...",noPermissionRenameFolder:"You do not have permission to rename folders",noPermissionLinkFolder:"You do not have permission to link folders",noPermissionDeleteFolder:"You do not have permission to delete folders",noPermissionPrint:"You do not have permission to print",noPermissionAddToQueue:"You do not have permission to add to queue",noPermissionSlice:"You do not have permission to slice files",noPermissionDownload:"You do not have permission to download files",noPermissionRenameFile:"You do not have permission to rename this file",noPermissionGenerateThumbnail:"You do not have permission to generate thumbnails",noPermissionDeleteFile:"You do not have permission to delete this file",noPermissionCreateFolder:"You do not have permission to create folders",noPermissionUpload:"You do not have permission to upload files",noPermissionMoveFiles:"You do not have permission to move files",noPermissionDeleteFiles:"You do not have permission to delete files",linkExternal:"Link External",linkExternalFolder:"Link External Folder",linkExternalFolderDescription:"Mount a host directory (NAS, USB, network share) into the File Manager. Files are not copied — they are accessed directly from the original path.",externalFolderNamePlaceholder:"e.g., NAS Prints",externalPath:"Host Path",externalPathHelp:"Absolute path to the directory on the Docker host. Must be bind-mounted into the container.",readOnly:"Read Only",readOnlyHelp:"prevents uploads and deletions",showHiddenFiles:"Show hidden files (dotfiles)",externalFolder:"External Folder",scanFolder:"Scan",toast:{folderCreated:"Folder created",folderDeleted:"Folder deleted",fileDeleted:"File deleted",filesDeleted:"Deleted {{count}} files",filesMoved:"Files moved",folderLinked:"Folder linked",folderUnlinked:"Folder unlinked",externalFolderLinked:"External folder linked and scanned",folderScanned:"Scan complete: {{added}} added, {{removed}} removed",addedToQueue:"Added {{count}} file(s) to queue",addedToQueuePartial:"Added {{added}} file(s), {{failed}} failed",failedToAddToQueue:"Failed to add files: {{error}}",fileRenamed:"File renamed",folderRenamed:"Folder renamed",thumbnailsGenerated:"Generated {{count}} thumbnail(s)",thumbnailsGeneratedPartial:"Generated {{succeeded}} thumbnail(s), {{failed}} failed",noStlMissingThumbnails:"No STL files missing thumbnails",failedToGenerateThumbnails:"Failed to generate thumbnails: {{error}}",thumbnailGenerated:"Thumbnail generated",failedToGenerateThumbnail:"Failed to generate thumbnail: {{error}}"}},projects:{title:"Projects",subtitle:"Organize and track your 3D printing projects",newProject:"New Project",editProject:"Edit Project",deleteProject:"Delete Project",projectName:"Project Name",description:"Description",noProjects:"No projects yet",noProjectsFiltered:"No {{status}} projects",noProjectsFilteredHelp:"You don't have any {{status}} projects. Projects will appear here when their status changes.",createFirst:"Create your first project to start organizing related prints, tracking progress, and managing your builds.",createFirstButton:"Create Your First Project",create:"Create",files:"Files",prints:"Prints",plates:"plates",parts:"parts",lastModified:"Last Modified",deleteConfirm:"Are you sure you want to delete this project? Archives and queue items will be unlinked but not deleted.",addFiles:"Add Files",removeFile:"Remove File",viewDetails:"View Details",namePlaceholder:"e.g., Voron 2.4 Build",descriptionPlaceholder:"Optional description...",urlLabel:"URL",urlPlaceholder:"https://makerworld.com/...",urlInvalid:"URL must start with http:// or https://",openExternalUrl:"Open project URL",coverImageLabel:"Cover photo",coverImageAlt:"Project cover photo",coverImageUpload:"Upload",coverImageReplace:"Replace",coverImageRemove:"Remove",color:"Color",targetPlates:"Target Plates",targetPlatesPlaceholder:"e.g., 25",targetPlatesHelp:"Number of print jobs",targetParts:"Target Parts",targetPartsPlaceholder:"e.g., 150",targetPartsHelp:"Total objects needed",tagsLabel:"Tags (comma-separated)",tagsPlaceholder:"e.g., voron, functional, gift",dueDate:"Due Date",priority:"Priority",priorityLow:"Low",priorityNormal:"Normal",priorityHigh:"High",priorityUrgent:"Urgent",statusActive:"Active",statusCompleted:"Completed",statusArchived:"Archived",done:"Done",completed:"completed",failed:"failed",inQueue:"in queue",noPrintsYet:"No prints yet",printJobs:"Print jobs (plates)",partsPrinted:"Parts printed",failedParts:"Failed parts",import:"Import",export:"Export",importProject:"Import project",exportAll:"Export all projects",loading:"Loading projects...",noEditPermission:"You do not have permission to edit projects",noDeletePermission:"You do not have permission to delete projects",noCreatePermission:"You do not have permission to create projects",noImportPermission:"You do not have permission to import projects",noExportPermission:"You do not have permission to export projects",toast:{created:"Project created",updated:"Project updated",deleted:"Project deleted",imported:"Project imported",multipleImported:"{{count}} projects imported",importFailed:"Import failed",exported:"Projects exported (metadata only)"}},projectDetail:{notFound:"Project not found",backToProjects:"Back to Projects",export:"Export",exportProject:"Export project",noExportPermission:"You do not have permission to export projects",noEditPermission:"You do not have permission to edit projects",partOf:"Part of:",priorityLabel:"Priority:",noPrints:"No prints in this project yet",status:{active:"Active",completed:"Completed",archived:"Archived"},priority:{low:"Low",normal:"Normal",high:"High",urgent:"Urgent"},dueDate:{overdue:"Overdue",today:"Due today",daysLeft:"{{count}} days left"},progress:{platesProgress:"Plates Progress",partsProgress:"Parts Progress",printJobs:"print jobs",parts:"parts",percentComplete:"{{percent}}% complete",remaining:"{{count}} remaining"},stats:{printJobs:"Print Jobs",total:"total",failed:"{{count}} failed",partsPrinted:"{{count}} parts printed",printTime:"Print Time",filamentUsed:"Filament Used"},cost:{title:"Cost Tracking",filamentCost:"Filament Cost",energy:"Energy",totalCost:"Total Cost",total:"Total",includesBom:"incl. BOM",budget:"Budget",remaining:"Remaining"},subProjects:{title:"Sub-projects ({{count}})"},notes:{title:"Notes",noEditPermission:"You do not have permission to edit notes",placeholder:"Add notes about this project...",empty:"No notes yet. Click Edit to add notes."},files:{title:"Files",linkFolders:"Link folders from the File Manager",forQuickAccess:"to this project for quick access.",fileCount:"{{count}} file(s)",empty:"No folders linked. Go to File Manager and link a folder to this project.",noFiles:"No files in this folder.",print:"Print Now",addToQueue:"Add to Queue"},bom:{title:"Bill of Materials",acquired:"{{completed}}/{{total}} acquired",showAll:"Show all",hideDone:"Hide done",addPart:"Add Part",noAddPermission:"You do not have permission to add parts",partNamePlaceholder:"Part name (e.g., M3x8 screws)",partName:"Part name",qty:"Qty",price:"Price ({{currency}})",sourcingUrlPlaceholder:"Sourcing URL (optional)",remarksPlaceholder:"Remarks (optional)",deletePart:"Delete Part",deleteConfirm:'Are you sure you want to delete "{{name}}"?',noUpdatePermission:"You do not have permission to update parts",noEditPermission:"You do not have permission to edit parts",noDeletePermission:"You do not have permission to delete parts",totalCost:"Total cost:",empty:"No parts in the bill of materials. Add hardware, electronics, or other components to track what needs to be sourced."},timeline:{title:"Activity Timeline",empty:"No activity yet."},template:{saveAsTemplate:"Save as Template",noCreatePermission:"You do not have permission to create templates"},queue:{title:"Queue",viewAll:"View all",printing:"{{count}} printing",queued:"{{count}} queued"},prints:{title:"Prints ({{count}})"},toast:{projectUpdated:"Project updated",partAdded:"Part added",partRemoved:"Part removed",exportFailed:"Export failed",projectExported:"Project exported",templateCreated:"Template created"}},system:{title:"System Information",version:"Version",uptime:"Uptime",cpuUsage:"CPU Usage",memoryUsage:"Memory Usage",diskUsage:"Disk Usage",networkInfo:"Network Info",logs:"Logs",debugMode:"Debug Mode",enableDebug:"Enable Debug Logging",disableDebug:"Disable Debug Logging",downloadLogs:"Download Logs",clearLogs:"Clear Logs",dockerInfo:"Docker Info",containerName:"Container Name",imageName:"Image Name",platform:"Platform",architecture:"Architecture"},library:{title:"Filament Library",addFilament:"Add Filament",editFilament:"Edit Filament",deleteFilament:"Delete Filament",vendor:"Vendor",material:"Material",color:"Color",kFactor:"K Factor",temperature:"Temperature",noFilaments:"No filaments in library",deleteConfirm:"Are you sure you want to delete this filament?",importFromPrinter:"Import from Printer",exportToFile:"Export to File"},slice:{title:"Slice model",action:"Slice",slicing:"Slicing…",printer:"Printer profile",process:"Process profile",filament:"Filament profile",filamentSlot:"Filament {{index}} ({{type}})",selectPreset:"— Select a preset —",loadingPresets:"Loading presets…",analyzingPlateFilaments:"Analyzing plate filaments…",analyzingPlateFilamentsHint:"Running a preview slice to discover which AMS slots this plate uses. Cached after — re-opening is instant.",previewToast:"Analyzing {{name}} — {{elapsed}}",previewWithProgress:"Analyzing {{name}} — {{stage}} ({{percent}}%) — {{elapsed}}",notUsedByPlate:"— not used by this plate",printerMismatch:"This 3MF was sliced for {{source}}, but you picked {{target}}. The slicer CLI cannot re-slice a 3MF for a different printer — open the source in Bambu Studio, change the printer, and re-export.",noPresetsForSlot:"No presets available",presetsLoadFailed:"Failed to load presets. Open Settings → Profiles to import them first.",allPresetsRequired:"All presets must be selected",enqueuing:"Submitting slice job…",queued:"Queued…",failed:"Slicing failed. Check the slicer sidecar logs.",startedToast:"Slicing {{name}} in the background…",queuedToast:"Queued: {{name}} — {{elapsed}}",runningToast:"Slicing {{name}} — {{elapsed}}",runningWithProgress:"{{name}} — {{stage}} ({{percent}}%) — {{elapsed}}",completedToast:"Sliced {{name}}",failedToast:"Slicing {{name}} failed: {{detail}}",tier:{local:"Imported",cloud:"Cloud",standard:"Standard"},cloud:{notAuthenticated:"Sign in to Bambu Cloud (Settings → Profiles → Cloud) to see your cloud presets.",expired:"Bambu Cloud session expired — sign in again to refresh your cloud presets.",unreachable:"Bambu Cloud is unreachable right now. Local and standard presets still work."},bedType:{label:"Build plate",auto:"Auto (use process preset)",coolPlate:"Cool Plate",coolPlateSuperTack:"Cool Plate SuperTack",engineering:"Engineering Plate",highTemp:"High Temp Plate",texturedPEI:"Textured PEI Plate",smoothPEI:"Smooth PEI Plate"}},spoolman:{title:"Spoolman Integration",enabled:"Spoolman Enabled",url:"Spoolman URL",connected:"Connected",disconnected:"Not Connected",testConnection:"Test Connection",sync:"Sync",syncing:"Syncing...",lastSync:"Last Sync",linkToSpoolman:"Link to Spoolman",openInSpoolman:"Open in Spoolman",unlinkSpool:"Unlink Spool",unlinkConfirmTitle:"Unassign Spool?",unlinkConfirmMessage:"This will remove the spool from this slot. The spool data itself will remain unchanged.",selectSpool:"Select Spool",noUnlinkedSpools:"No unassigned spools available",linkSuccess:"Spool assigned successfully",linkFailed:"Failed to assign spool",unlinkSuccess:"Spool unassigned successfully",unlinkFailed:"Failed to unassign spool",linkedSpool:"Assigned spool",spoolId:"Spool ID",fillSourceLabel:"(Spoolman)",weight:"Weight",remaining:"Remaining",disableWeightSync:"Disable AMS Estimated Weight Sync",disableWeightSyncDesc:"Don't update remaining capacity from AMS estimates. Use this if you prefer Spoolman's usage tracking over AMS percentage-based estimates. New spools will still use the AMS estimate as their initial weight.",reportPartialUsage:"Report Partial Usage for Failed Prints",reportPartialUsageDesc:"When a print fails or is cancelled, report the estimated filament used up to that point based on layer progress."},inventory:{title:"Spool Inventory",subtitle:"Manage your spools",spoolmanMixedContentTitle:"Spoolman can't load over HTTPS — mixed-content blocked by your browser",spoolmanMixedContentBody:"Bambuddy is served over HTTPS (via your reverse proxy), but your Spoolman URL is still plain HTTP. Browsers block mixed content for security, so the embedded Spoolman UI can't render. Spoolman needs to be reachable over HTTPS for this to work.",spoolmanMixedContentFixReverseProxy:"Put Spoolman behind the same reverse proxy as Bambuddy (Traefik / Nginx / Caddy) with HTTPS, then update the Spoolman URL in Settings to the new HTTPS address.",spoolmanMixedContentFixOpenNewTab:"As a workaround, open Spoolman in a new browser tab over HTTP — mixed-content rules only apply to embedded frames, so a standalone tab still works.",spoolmanOpenInNewTab:"Open Spoolman in a new tab",labels:{title:"Print spool labels",selectedCount:"{{count}} selected",pickSpools:"Pick which spools to print labels for:",searchPlaceholder:"Search name, brand, or #ID",filterByMaterial:"Material:",allMaterials:"All",selectVisible:"Select all visible ({{count}})",deselectVisible:"Deselect visible",clearAll:"Clear all",noSpoolsToShow:"No spools to show. Adjust your filter and try again.",noMatches:"No spools match the current search or filter.",printOne:"Print label for this spool",printLabels:"Print labels…",bulkTitle:"Pick spools to print labels for from the {{count}} currently shown",noSpoolsTitle:"No spools to label",error:"Could not generate labels: {{msg}}",templates:{ams:{label:"AMS holder (30 × 15 mm)",hint:"Single label per page; fits the popular AMS filament label holder."},box40x30:{label:"Box label (40 × 30 mm)",hint:"Single label per page; common DK/Brother roll size, good for filament-bag and storage-bin labels."},box:{label:"Box label (62 × 29 mm)",hint:"Single label per page; sized for Brother PT/QL and Dymo small labels."},averyL7160:{label:"Avery L7160 — A4 sheet (38.1 × 63.5 mm × 21)",hint:"EU sheet stock; 21 labels per A4 page."},avery5160:{label:"Avery 5160 — US Letter sheet (25.4 × 66.7 mm × 30)",hint:"US sheet stock; 30 labels per Letter page."}}},addSpool:"Add Spool",editSpool:"Edit Spool",copySpool:"Copy Spool",material:"Material",selectMaterial:"Select material...",subtype:"Subtype",brand:"Brand",searchBrand:"Search brand...",useCustomBrand:'Use "{{brand}}"',useCustomMaterial:"Use custom material: {{material}}",colorName:"Color Name",colorNamePlaceholder:"Jade White, Fire Red...",color:"Color",hexColor:"Hex Color",pickColor:"Pick custom color",labelWeight:"Label Weight",coreWeight:"Empty Spool Weight",searchSpoolWeight:"Search spool weight...",weightUsed:"Used",currentWeight:"Remaining Weight",measuredWeight:"Measured Weight",spoolName:"Spool",costPerKg:"Cost per kg",storageLocation:"Storage Location",storageLocationPlaceholder:"e.g. Shelf A, Drawer 1",openInInventory:"Open in Inventory",measuredWeightError:"Measured weight must be between {{min}}g and {{max}}g.",slicerFilament:"Slicer Filament",slicerFilamentName:"Slicer Preset Name",slicerPreset:"Slicer Preset",searchPresets:"Search filament presets...",selectedPreset:"Selected",noPresetsFound:"No presets found",tempOverrides:"Temperature Overrides",note:"Note",notePlaceholder:"Any additional notes about this spool...",category:"Category",categoryPlaceholder:"e.g. Production, Prototype, Client A",categoryNone:"Uncategorized",storageLocationNone:"No location set",lowStockThresholdOverride:"Low-stock threshold (this spool)",lowStockThresholdOverrideHelp:"Leave blank to use the global threshold ({{global}}%).",clearRfid:"Clear RFID Tag",rfidCleared:"RFID tag cleared",archive:"Archive",restore:"Restore",noSpools:"No spools yet. Add your first spool to get started.",noAvailableSpools:"No spools available. Add a spool to your inventory or unassign one from another slot first.",kProfiles:"K-Profiles",addKProfile:"Add K-Profile",assignSpool:"Assign Spool",unassignSpool:"Unassign",assignSuccess:"Spool assigned and AMS slot configured",assignFailed:"Failed to assign spool",selectSpool:"Select a spool to assign to this slot",assigned:"Assigned",assigning:"Assigning...",searchSpools:"Search spools...",showAllSpools:"Show all spools",spoolmanSpools:"Spoolman Spools",allMaterials:"All Materials",filterByBrand:"Filter by brand...",showArchived:"Show archived",quickAdd:"Quick Add (Stock)",quantity:"Quantity",stock:"Stock",configured:"Configured",spoolsCreated:"{{count}} spools created",spoolsPartiallyCreated:"{{created}} of {{total}} spools created (some failed)",spoolCreated:"Spool created",spoolUpdated:"Spool updated",spoolDeleted:"Spool deleted",deepLinkSpoolNotFound:"Spool not found",deepLinkFetchFailed:"Could not load spool — try again",spoolArchived:"Spool archived",spoolRestored:"Spool restored",kProfileSaveFailed:"K-profile settings could not be saved",syncWeightSpoolNotFound:"Spool not found — it may have been deleted",syncWeightSpoolmanUnreachable:"Spoolman is unreachable — try again later",syncWeightFailed:"Failed to sync weight",spoolmanUnreachable:"Spoolman is not reachable — please try again later",deleteSpoolNotFound:"Spool not found — it may have already been deleted",deleteFailed:"Failed to delete spool",archiveSpoolNotFound:"Spool not found — it may have already been deleted",archiveFailed:"Failed to archive spool",restoreSpoolNotFound:"Spool not found — it may have already been deleted",restoreFailed:"Failed to restore spool",saveFailed:"Failed to save changes",tagClearFailed:"Failed to clear tag",deleteConfirm:"Are you sure you want to delete this spool? This cannot be undone.",archiveConfirm:"Are you sure you want to archive this spool?",advancedSettings:"Advanced Settings",filamentInfoTab:"Filament Info",paProfileTab:"PA Profile",filamentInfo:"Filament",additional:"Additional",loadingPresets:"Loading cloud presets...",cloudConnected:"Cloud connected",cloudNotConnected:"Cloud not connected (using defaults)",recentColors:"Recent",searchColors:"Search colors...",searchResults:"Search results",allColors:"All colors",commonColors:"Common colors",showLess:"Show less",showAll:"Show all",noColorsFound:"No colors match your search",noResults:"No matches found",extraColorsLabel:"Extra colors",extraColorsPlaceholder:"EC984C,#6CD4BC,A66EB9,D87694",extraColorsHint:"Paste 2 to 8 hex stops, separated by commas. Renders as a gradient.",extraColorsInvalid:"Ignored invalid hex: {{tokens}}",colorEffectLabel:"Effect",colorEffect:{none:"None",sparkle:"Sparkle",wood:"Wood",marble:"Marble",glow:"Glow",matte:"Matte",silk:"Silk",galaxy:"Galaxy",rainbow:"Rainbow",metal:"Metal",translucent:"Translucent",gradient:"Gradient",dualColor:"Dual Color",triColor:"Tri Color",multicolor:"Multicolor"},selectMaterialFirst:"Please select a material first in the Filament Info tab.",noPrintersConfigured:"No printers configured. Add printers to use PA profiles.",matchingFilter:"Matching",anyBrand:"Any brand",anyVariant:"Any variant",autoSelect:"Auto-select",matches:"matches",match:"match",noMatches:"No matches",connected:"Connected",offline:"Offline",printerOffline:"Printer is offline. Connect to view calibration profiles.",noKProfilesMatch:"No K-profiles match the selected filament.",leftNozzle:"Left Nozzle",rightNozzle:"Right Nozzle",profilesSelected:"calibration profile(s) selected",totalInventory:"Total Inventory",totalConsumed:"Total Consumed",byMaterial:"By Material",inPrinter:"In Printer",lowStock:"Low Stock",sinceTracking:"Since tracking started",loadedInAms:"Loaded in AMS/Ext",remaining:"Remaining",weightCheck:"Weight Check",lastWeighed:"Last weighed",neverWeighed:"Never weighed",search:"Search spools...",showing:"Showing",to:"to",of:"of",show:"Show",spools:"spools",spool:"spool",page:"Page",noSpoolsMatch:"No results found",noSpoolsMatchDesc:"Try adjusting your search or filters to find what you're looking for.",active:"Active",archived:"Archived",all:"All",used:"Used",new:"New",clearFilters:"Clear filters",table:"Table",cards:"Cards",net:"Net",groupSimilar:"Group",groupedSpools:"{{count}} identical spools",groupedRows:"rows",columns:"Columns",configureColumns:"Configure Columns",configureColumnsDesc:"Drag to reorder columns or use arrows. Toggle visibility with the eye icon.",visible:"visible",reset:"Reset",cancel:"Cancel",applyChanges:"Apply Changes",moveUp:"Move up",moveDown:"Move down",hideColumn:"Hide column",showColumn:"Show column",linkToSpool:"Link to Spool",tagLinked:"Tag linked to spool",tagLinkFailed:"Failed to link tag",tagAlreadyLinked:"Tag already linked to another spool",unknownTag:"Unknown RFID tag detected",usageHistory:"Usage History",noUsageHistory:"No usage recorded yet",printName:"Print Name",weightConsumed:"Weight Consumed",clearHistory:"Clear",historyCleared:"Usage history cleared",fillSourceLabel:"(Inv)",lowStockThresholdError:"Threshold must be between 0.1 and 99.9",assignMismatchTitle:"Material mismatch",assignMismatchMessage:'The selected spool material "{{spoolMaterial}}" does not match the tray material "{{trayMaterial}}" for {{location}}. Assign anyway?',assignMismatchConfirm:"Assign Anyway",assignPartialMismatchMessage:'The spool material "{{spoolMaterial}}" is similar to but not exactly matching "{{trayMaterial}}" in {{location}}. Do you want to proceed?',assignProfileMismatchMessage:'The spool profile "{{spoolProfile}}" does not match the tray profile "{{trayProfile}}" in {{location}}. Do you want to proceed?',spoolmanFilamentCatalog:"Spoolman Filament Catalog",pickFromSpoolmanCatalog:"Pick from Spoolman catalog…",spoolmanFilamentSelected:"Filament selected from Spoolman catalog",spoolmanFilamentUnlinked:"Filament catalog link cleared",noSpoolmanFilaments:"No filaments found in Spoolman catalog",spoolmanFilamentColorSwatch:"Filament color",spoolWeightManagedBySpoolman:"Empty spool weight is managed per filament type in Spoolman",spoolmanCatalogLoadFailed:"Failed to load Spoolman filament catalog"},timelapse:{title:"Timelapse",create:"Create Timelapse",download:"Download",delete:"Delete",preview:"Preview",frameRate:"Frame Rate",quality:"Quality",processing:"Processing...",noTimelapses:"No timelapses available"},ams:{title:"AMS",slot:"Slot",empty:"Empty",emptySlot:"Empty slot",unknown:"Unknown",humidity:"Humidity",temperature:"Temperature",filamentType:"Filament Type",filamentColor:"Color",remaining:"Remaining",history:"AMS History",noHistory:"No history available",configureSlot:"Configure Slot",externalSpool:"External Spool",profile:"Profile",kFactor:"K Factor",fill:"Fill",configure:"Configure",used:"used",remainingUnit:"remaining"},printModal:{title:"Start Print",selectPrinter:"Select Printer",selectPlate:"Select Plate",filamentMapping:"Filament Mapping",totalCost:"Total cost:",slotRemainingShort:" - {{grams}}g left",printSettings:"Print Settings",bedLeveling:"Bed Leveling",flowCalibration:"Flow Calibration",vibrationCalibration:"Vibration Calibration",layerInspection:"First Layer Inspection",timelapse:"Timelapse",startPrint:"Start Print",addToQueue:"Add to Queue",cancel:"Cancel",noPrintersAvailable:"No printers available",printerBusy:"Printer is busy",printerOffline:"Printer is offline",sameTypeDifferentColor:"Same type, different color",filamentTypeNotLoaded:"Filament type not loaded",openCalendar:"Open calendar",leftNozzle:"L",rightNozzle:"R",leftNozzleTooltip:"Left nozzle",rightNozzleTooltip:"Right nozzle",filamentOverride:"Filament Override",filamentOverrideHint:"Optionally override filaments for model-based assignment. The scheduler will match against your selected filaments instead of the original 3MF values.",originalFilament:"Original",overrideWith:"Override with",resetToOriginal:"Reset to original",insufficientFilamentTitle:"Not enough filament",insufficientFilamentMessage:"Some assigned spools have less filament remaining than this print needs:",insufficientFilamentLine:"{{printer}} - {{slot}}: needs {{required}}g, remaining {{remaining}}g",printAnyway:"Print anyway",forceColorMatch:"Force color match",staggerPrinterStarts:"Stagger printer starts",staggerGroupSize:"Group size",staggerInterval:"Interval (min)",staggerPreview:"{{printers}} printers → {{groups}} groups of {{size}}, starting every {{interval}} min",staggerLastGroup:"last group: {{count}}",staggerTotal:"total: {{minutes}} min",staggerToPrinters:"Stagger to {{count}} printers",gcodeInjection:"Inject auto-print G-code"},backup:{includesEncryptionKey:"Local backups include the MFA encryption key file (DATA_DIR/.mfa_encryption_key) so a backup ZIP is self-contained. Treat the ZIP as sensitive — anyone with the file can decrypt the OIDC client secrets and TOTP secrets stored inside.",title:"Backup & Restore",createBackup:"Create Backup",restoreBackup:"Restore Backup",restoreDescription:"Replace all data from a backup file",downloadBackup:"Download Backup",uploadBackup:"Upload Backup",lastBackup:"Last Backup",autoBackup:"Auto Backup",backupNow:"Backup Now",restoreWarning:"Warning: Restoring a backup will overwrite all current data.",includeArchives:"Include Archives",includeSettings:"Include Settings",includeProfiles:"Include Profiles",backupSuccess:"Backup created successfully",restoreSuccess:"Backup restored successfully",backupFailed:"Backup failed",restoreFailed:"Restore failed",restoreNote:"Virtual Printer will be stopped during restore",githubBackup:"Git Backup",enabled:"Enabled",cloudLoginRequired:"Bambu Cloud login required. Sign in under Profiles → Cloud Profiles to enable GitHub backup.",cloudLoginRequiredShort:"Cloud login required",githubDescription:"Automatically sync your profiles to a private GitHub repository for backup and version history.",repositoryUrl:"Repository URL",repoUrlPlaceholderGitHub:"https://github.com/username/repo-name",repoUrlPlaceholderGitea:"https://gitea.example.com/username/repo-name",repoUrlPlaceholderForgejo:"https://forgejo.example.com/username/repo-name",repoUrlPlaceholderGitLab:"https://gitlab.com/username/repo-name",allowInsecureHttp:"Allow insecure HTTP",allowInsecureHttpHint:"Enable for self-hosted instances on private networks without TLS",personalAccessToken:"Personal Access Token",tokenSaved:"(saved)",enterNewToken:"Enter new token to update",tokenHint:"Fine-grained token with Contents read/write permission",branch:"Branch",provider:"Git Provider",providerGitHub:"GitHub",providerGitLab:"GitLab",providerGitea:"Gitea",providerForgejo:"Forgejo",manualOnly:"Manual only",hourly:"Hourly",daily:"Daily",weekly:"Weekly",includeInBackup:"Include in backup",kProfiles:"K-Profiles",kProfilesDescription:"Pressure advance calibration from connected printers",noPrintersConnected:"No printers connected",printersConnected:"{{connected}}/{{total}} connected",cloudProfiles:"Cloud Profiles",cloudProfilesDescription:"Filament, printer, and process presets from Bambu Cloud",appSettings:"App Settings",appSettingsDescription:"Bambuddy configuration (complete database)",spoolInventory:"Spool Inventory",spoolInventoryDescription:"Filament spools, usage history, and cost tracking",printArchives:"Print Archives",printArchivesDescription:"Print history metadata (no gcode/3MF files)",lastBackupAt:"Last backup:",noBackupsYet:"No backups yet",next:"Next:",startingBackup:"Starting backup...",test:"Test",enableBackup:"Enable Backup",testConnection:"Test Connection",enterRepoUrl:"Enter repository URL",enterRepoAndToken:"Enter repository URL and access token",repoRequired:"Repository URL is required",tokenRequired:"Access token is required",githubBackupEnabled:"GitHub backup enabled",tokenUpdated:"Token updated",settingsSaved:"Settings saved",failedToSave:"Failed to save: {{message}}",backupCompleteFiles:"Backup complete - {{count}} files updated",backupSkippedNoChanges:"Backup skipped - no changes",backupFailed2:"Backup failed: {{message}}",clearedLogs:"Cleared {{count}} logs",failedToClearLogs:"Failed to clear logs: {{message}}",history:"History",clear:"Clear",date:"Date",status:"Status",commit:"Commit",localBackup:"Local Backup",localBackupDescription:"Create a complete backup of your Bambuddy data including the database, archives, uploads, and all files.",downloadBackupLabel:"Download Backup",completeBackupZip:"Complete backup: database + all files (ZIP)",download:"Download",preparingBackup:"Preparing backup...",creatingArchive:"Creating backup archive... This may take a while for large archives.",downloadingFile:"Downloading backup file...",backupDownloaded:"Backup downloaded successfully",failedToCreateBackup:"Failed to create backup: {{message}}",restore:"Restore",restoreReplacesAll:"Restore replaces all data.",restoreReplacesAllDetail:"Your current database and files will be completely replaced. A restart is required after restore.",restoreConfirmTitle:"Restore Backup",restoreConfirmMessage:'Are you sure you want to restore from "{{filename}}"? This will completely replace your current database and all files. The application will need to be restarted after restore.',restoreConfirmButton:"Restore Backup",uploadingFile:"Uploading backup file...",backupRestoredRestart:"Backup restored. Please restart Bambuddy.",failedToRestore:"Failed to restore backup. Please check the file format.",reloadNow:"Reload Now",creatingBackup:"Creating Backup",restoringBackup:"Restoring Backup",preparing:"Preparing...",processing:"Processing...",doNotClosePage:"Please do not close this page or navigate away. This operation may take several minutes for large backups.",restoring:"Restoring...",restoreComplete:"Restore Complete",restoreFailed2:"Restore Failed",importSettings:"Import settings from a backup file",pleaseWaitRestoring:"Please wait while your data is being restored",selectBackupFile:"Click to select backup file (.json or .zip)",duplicateHandling:"How duplicate handling works:",matchPrinters:"Printers",matchPrintersBy:"matched by serial number",matchSmartPlugs:"Smart Plugs",matchSmartPlugsBy:"matched by IP address",matchNotificationProviders:"Notification Providers",matchNotificationProvidersBy:"matched by name",matchFilaments:"Filaments",matchFilamentsBy:"matched by name + type + brand",matchArchives:"Archives",matchArchivesBy:"matched by content hash (always skipped)",matchPendingUploads:"Pending Uploads",matchPendingUploadsBy:"matched by filename",matchSettingsTemplates:"Settings & Templates",matchSettingsTemplatesBy:"always overwritten",replaceExisting:"Replace existing data",keepExisting:"Keep existing data",overwriteDescription:"Overwrite items that already exist with backup data",keepDescription:"Only restore items that don't already exist",overwriteCaution:"Caution:",overwriteWarning:"Overwriting will replace your current configurations with data from the backup. Printer access codes are never overwritten for security.",cancel:"Cancel",processingBackup:"Processing backup file...",itemsRestored:"Items Restored",itemsSkipped:"Items Skipped",restored:"Restored",skippedAlreadyExist:"Skipped (already exist)",filesCategory:"Files (3MF, thumbnails, etc.)",andMore:"...and {{count}} more",newApiKeysGenerated:"New API Keys Generated",keysShownOnce:"These keys are only shown once. Copy them now!",copy:"Copy",noDataFound:"No data was found to restore in the backup file.",close:"Close",scheduledBackup:"Scheduled Backups",scheduledBackupDescription:"Automatically create backup snapshots on a schedule. Output directory can be mounted to a NAS or external storage.",frequency:"Frequency",backupTime:"Time",retention:"Retention",retentionDescription:"Number of backups to keep",outputPath:"Output Path",outputPathPlaceholder:"Default: {{path}}",outputPathDescription:"Leave empty for default location",runNow:"Run Now",backupFiles:"Backup Files",noScheduledBackups:"No backups yet",deleteBackup:"Delete",deleteBackupConfirm:"Delete this backup file?",backupRunning:"Backup in progress...",scheduledBackupComplete:"Backup completed successfully",scheduledBackupFailed:"Backup failed",nextBackup:"Next backup",backupSize:"Size",utc:"UTC",defaultPathLabel:"Default:",categories:{settings:"Settings",notification_providers:"Notification Providers",notification_templates:"Notification Templates",smart_plugs:"Smart Plugs",printers:"Printers",filaments:"Filaments",maintenance_types:"Maintenance Types",archives:"Archives",projects:"Projects",pending_uploads:"Pending Uploads",external_links:"External Links",api_keys:"API Keys"}},tags:{title:"Tags",addTag:"Add Tag",editTag:"Edit Tag",deleteTag:"Delete Tag",tagName:"Tag Name",tagColor:"Tag Color",noTags:"No tags",deleteConfirm:"Are you sure you want to delete this tag?",manageTags:"Manage Tags"},uploadModal:{title:"Upload 3MF Files",dragDrop:"Drag & drop .3mf files here",or:"or",browseFiles:"Browse Files",extractionInfo:"The printer model will be automatically extracted from the 3MF file metadata.",uploaded:"uploaded",failed:"failed",uploading:"Uploading...",upload:"Upload",uploadFailed:"Upload failed"},editArchive:{title:"Edit Archive",name:"Name",namePlaceholder:"Print name",printer:"Printer",noPrinter:"No printer",project:"Project",noProject:"No project",itemsPrinted:"Items Printed",itemsPrintedHelp:"Number of items produced in this print job",notes:"Notes",notesPlaceholder:"Add notes about this print...",externalLink:"External Link",externalLinkPlaceholder:"https://printables.com/model/...",externalLinkHelp:"Link to Printables, Thingiverse, or other source",tags:"Tags",tagsPlaceholder:"Add tags...",addMoreTags:"Add more tags...",matchingTags:'Matching "{{query}}"',existingTags:"Existing tags",clickToAdd:"(click to add)",status:"Status",failureReason:"Failure Reason",selectReason:"Select reason...",photos:"Photos of Printed Result",photosHelp:"Click + to add photos of your printed result",printResult:"Print result",saving:"Saving...",failureReasons:{adhesionFailure:"Adhesion failure",spaghettiDetached:"Spaghetti / Detached",layerShift:"Layer shift",cloggedNozzle:"Clogged nozzle",filamentRunout:"Filament runout",warping:"Warping",stringing:"Stringing",underExtrusion:"Under-extrusion",powerFailure:"Power failure",userCancelled:"User cancelled",other:"Other"},statuses:{completed:"Completed",failed:"Failed",aborted:"Cancelled",printing:"Printing"}},kProfiles:{title:"K-Profiles",noPrintersConfigured:"No Printers Configured",addPrinterInSettings:"Add a printer in Settings to manage K-profiles",noActivePrinters:"No Active Printers",enablePrinterConnection:"Enable a printer connection to view its K-profiles",loadingProfiles:"Loading K-Profiles...",printerOffline:"Printer Offline",printerOfflineDesc:"The selected printer is not connected. Power it on to view K-profiles.",noMatchingProfiles:"No Matching Profiles",noMatchingProfilesDesc:"No profiles match your search criteria",noKProfiles:"No K-Profiles",noKProfilesDesc:"No pressure advance profiles found for {{diameter}}mm nozzle",createFirstProfile:"Create First Profile",printer:"Printer",nozzle:"Nozzle",refresh:"Refresh",addProfile:"Add Profile",export:"Export",import:"Import",select:"Select",selectAll:"Select All",delete:"Delete",searchPlaceholder:"Search by name or filament...",allExtruders:"All Extruders",leftOnly:"Left Only",rightOnly:"Right Only",allFlow:"All Flow",hfOnly:"HF Only",sOnly:"S Only",sortName:"Sort: Name",sortKValue:"Sort: K-Value",sortFilament:"Sort: Filament",leftExtruder:"Left Extruder",rightExtruder:"Right Extruder",modal:{addTitle:"Add K-Profile",editTitle:"Edit K-Profile",profileName:"Profile Name",profileNamePlaceholder:"My PLA Profile",kValue:"K-Value",kValuePlaceholder:"0.020",kValueHelp:"Typical range: 0.01 - 0.06 for PLA, 0.02 - 0.10 for PETG",filament:"Filament",selectFilament:"Select filament...",noFilamentsHelp:"No filaments found. Create a K-profile in Bambu Studio first.",flowType:"Flow Type",highFlow:"High Flow",standard:"Standard",nozzleSize:"Nozzle Size",extruder:"Extruder",extruders:"Extruders",left:"Left",right:"Right",notes:"Notes (stored locally)",notesPlaceholder:"Add notes about this profile...",notesHelp:"Notes are saved in Bambuddy, not on the printer",syncing:"Syncing with printer...",savingExtruder:"Saving to extruder {{current}}/{{total}}...",pleaseWait:"Please wait"},deleteConfirm:{title:"Delete Profile",cannotUndo:"This cannot be undone",message:'Are you sure you want to delete "{{name}}" from the printer?'},bulkDelete:{title:"Delete Profiles",cannotUndo:"This cannot be undone",message:"Are you sure you want to delete {{count}} selected profiles from the printer?"},toast:{profileSaved:"K-profile saved",profilesSaved:"K-profile saved to {{count}} extruders",selectAtLeastOneExtruder:"Please select at least one extruder",profileDeleted:"K-profile deleted",profilesDeleted:"Deleted {{count}} profiles",exportedProfiles:"Exported {{count}} profiles",importedProfiles:"Imported {{count}} of {{total}} profiles",noProfilesToExport:"No profiles to export",invalidFileFormat:"Invalid file format",failedToParseImport:"Failed to parse import file",failedToSaveBatch:"Failed to save K-profiles",noteSaved:"Note saved",failedToSaveNote:"Failed to save note"},permission:{noRead:"You do not have permission to refresh profiles",noCreate:"You do not have permission to add profiles",noUpdate:"You do not have permission to update K-profiles",noDelete:"You do not have permission to delete K-profiles",noExport:"You do not have permission to export profiles",noImport:"You do not have permission to import profiles"}},virtualPrinter:{title:"Virtual Printer",running:"Running",stopped:"Stopped",description:{default:"Enable a virtual printer that appears in Bambu Studio and OrcaSlicer. Files sent to this printer will be archived directly without printing.",proxy:"Enable a proxy that relays slicer traffic to a real printer, allowing remote printing over any network."},enable:{title:"Enable Virtual Printer",visibleInSlicer:'Visible as "Bambuddy" in slicer discovery',proxyingTo:"Proxying to {{name}}",notActive:"Not active"},model:{title:"Printer Model",description:"Select which printer model to emulate.",restartWarning:"Changing the model will restart the virtual printer"},accessCode:{title:"Access Code",isSet:"Access code is set",notSet:"No access code set - required to enable",placeholder:"Enter 8-char code",placeholderChange:"Enter new code to change",hint:"Must be exactly 8 characters. Used by slicers to authenticate.",charCount:"({{count}}/8)"},targetPrinter:{title:"Target Printer",configured:"Proxy target configured",notConfigured:"No target printer selected - required for proxy mode",placeholder:"Select a printer...",hint:"Select the printer to proxy slicer traffic to. The printer must be in LAN mode.",noPrinters:"No printers configured. Add a printer first to use proxy mode."},remoteInterface:{title:"Network Interface Override",configured:"Interface override active",optional:"Optional - use if auto-detected IP is wrong (e.g. multiple NICs, Docker, VPN)",placeholder:"Auto-detect (default)...",hint:"Override the IP address advertised via SSDP and used in the TLS certificate. Useful when Bambuddy has multiple network interfaces."},mode:{title:"Mode",archive:"Archive",archiveDesc:"Archive files immediately",review:"Review",reviewDesc:"Review before archiving",queue:"Queue",queueDesc:"Archive and add to queue",proxy:"Proxy",proxyDesc:"Relay to real printer"},autoDispatch:{title:"Auto-dispatch",description:"Automatically start prints when added to queue. When off, prints wait for manual dispatch."},queueForceColorMatch:{title:"Force color match",description:"Refuse to dispatch onto a printer that does not have the exact filament type and color loaded. Off by default — without this, the queue uses model-only matching and may pick a printer with the wrong color loaded."},tailscaleDisabled:{title:"Tailscale integration",description:"Enable to mark this VP as exposed over Tailscale. Shows the host's Tailscale address so you know which IP to paste into the slicer. The CA-import step is unchanged — this toggle has no effect on certificates."},setupRequired:{title:"Setup Required",description:"The virtual printer feature requires additional system configuration before it will work. This includes port forwarding, firewall rules, and platform-specific settings.",readGuide:"Read the setup guide before enabling"},archiveNameSource:{title:"Archive name source",description:'Choose how new archives are named when files arrive via the virtual printer. "Metadata" uses the slicer-embedded title from the 3MF (default). "Filename" uses the filename Bambu Studio sent over FTP — handy if you renamed the job in the "send to printer" dialog.',metadata:"Metadata",filename:"Filename"},howItWorks:{title:"How it works",step1:"On the same LAN, virtual printers appear in your slicer (Bambu Studio / OrcaSlicer) automatically via discovery. From other networks, add them manually by IP address and access code.",step2:'In Archive, Review, and Queue modes, use the "Send" button in your slicer to upload 3MF files to Bambuddy. The slicer will show "Print success" — the file is stored, not printed.',step3:"In Proxy mode, the virtual printer relays all traffic to a real printer — prints start immediately as if connected directly."},status:{title:"Status Details",printerName:"Printer Name",model:"Model",serialNumber:"Serial Number",mode:"Mode",pendingFiles:"Pending Files",targetPrinter:"Target Printer",ftpPort:"FTP Port",mqttPort:"MQTT Port",ftpConnections:"FTP Connections",mqttConnections:"MQTT Connections"},toast:{updated:"Virtual printer settings updated",failedToUpdate:"Failed to update settings",copyFailed:"Failed to copy — try selecting the text manually",accessCodeRequired:"Please set an access code first",targetPrinterRequired:"Please select a target printer first",bindIpRequired:"Please set a bind IP first",accessCodeEmpty:"Access code cannot be empty",accessCodeLength:"Access code must be exactly 8 characters",created:"Virtual printer created",failedToCreate:"Failed to create virtual printer",deleted:"Virtual printer deleted",failedToDelete:"Failed to delete virtual printer"},list:{title:"Virtual Printers",add:"Add",addFirst:"Add Virtual Printer",empty:"No virtual printers configured. Add one to get started."},bindIp:{title:"Bind Interface",placeholder:"Select interface...",hint:"Network interface for this virtual printer to bind to. Must be unique per printer."},proxy:{accessCodeHint:"In proxy mode, use your target printer's access code in the slicer. The connection is forwarded transparently to the real printer."},addDialog:{title:"Add Virtual Printer",name:"Name",hint:"You can configure access code, target printer, and other settings after creating.",create:"Create"},deleteConfirm:{title:"Delete Virtual Printer",message:'Are you sure you want to delete "{{name}}"? This will stop all services for this printer.'}},modelViewer:{openInSlicer:"Open in Slicer",tabs:{model:"3D Model",gcode:"G-code Preview"},notAvailable:"not available",notSliced:"not sliced",plates:"Plates",allPlates:"All Plates",plateNumber:"Plate {{number}}",plateCount:"{{count}} plate",plateCount_other:"{{count}} plates",objectCount:"{{count}} object",objectCount_other:"{{count}} objects",filamentCount:"{{count}} filament",filamentCount_other:"{{count}} filaments",eta:"ETA {{minutes}} min",noPreview:"No preview available for this file",pagination:{pageOf:"Page {{current}} of {{total}}",prev:"Prev",next:"Next"},errors:{failedToLoad:"Failed to load file",noMeshes:"No meshes found in 3MF file",unsupportedFormat:"Unsupported file format"}},maintenanceDescriptions:{lubricateCarbonRods:"Apply lubricant to carbon rods for smooth motion",lubricateRails:"Apply lubricant to linear rails for smooth motion",cleanNozzle:"Clean hotend and nozzle to prevent clogs",checkBelts:"Verify belt tension for accurate prints",cleanBuildPlate:"Clean build plate for better adhesion",checkExtruder:"Inspect extruder gears for wear",checkCooling:"Ensure cooling fans are working properly",generalInspection:"General printer inspection",cleanCarbonRods:"Clean carbon rods to reduce friction",lubricateSteelRods:"Apply lubricant to steel rods for smooth motion",cleanSteelRods:"Clean steel rods to reduce friction",cleanLinearRails:"Wipe linear rails to remove dust and debris",checkPtfeTube:"Inspect PTFE tube for wear or damage",replaceHepaFilter:"Replace HEPA filter for air quality",replaceCarbonFilter:"Replace activated carbon filter",lubricateLeftNozzleRail:"Lubricate left nozzle rail (H2 series)"},smartPlugs:{offline:"Offline",admin:"Admin",openPlugAdminPage:"Open plug admin page",deleteSmartPlug:"Delete Smart Plug",turnOnSmartPlug:"Turn On Smart Plug",turnOffSmartPlug:"Turn Off Smart Plug",turnOn:"Turn On",turnOff:"Turn Off",addSmartPlug:{scanningNetwork:"Scanning network...",chooseEntity:"Choose an entity...",connectionFailed:"Connection failed",searchEntities:"Search entities...",searchPowerSensors:"Search power sensors...",searchEnergySensors:"Search energy sensors...",placeholders:{plugName:"Living Room Plug",mqttStateOnValue:"ON, true, 1",mqttSameAsPower:"Same as power topic, or different"}},linkedTo:"Linked to:",monitorOnly:"Monitor Only",alerts:"Alerts",scheduleOn:"On {{time}}",scheduleOff:"Off {{time}}",on:"On",off:"Off",power:"Power",kwhToday:"kWh Today",settings:"Settings",automationSettings:"Automation Settings",showInSwitchbar:"Show in Switchbar",quickAccessSidebar:"Quick access from sidebar",enabled:"Enabled",enableAutomation:"Enable automation for this plug",autoOn:"Auto On",autoOnDescription:"Turn on when print starts",autoOff:"Auto Off",autoOffDescription:"Turn off when print completes (one-shot)",autoOffPersistent:"Keep Enabled",autoOffPersistentDescription:"Stay enabled between prints instead of one-shot",autoOffAfterDrying:"Auto Off After Drying",autoOffAfterDryingDescription:"Turn off when AMS drying completes",delayAfterDryingMinutes:"Drying delay (minutes)",turnOffDelayMode:"Turn Off Delay Mode",time:"Time",temp:"Temp",delayMinutes:"Delay (minutes)",tempThreshold:"Temperature threshold (°C)",tempThresholdDescription:"Turns off when nozzle cools below this temperature",edit:"Edit",deleteConfirm:'Are you sure you want to delete "{{name}}"? This cannot be undone.',turnOnConfirm:'Are you sure you want to turn on "{{name}}"?',turnOffConfirm:'Are you sure you want to turn off "{{name}}"? This will cut power to the connected device.',failedToTurn:'Failed to turn {{action}} "{{name}}"',unknown:"Unknown",addTitle:"Add Smart Plug",editTitle:"Edit Smart Plug",stopScanning:"Stop Scanning",discoverTasmota:"Discover Tasmota Devices",foundDevices:"Found {{count}} device(s) - click to select:",noDevicesFound:"No Tasmota devices found on your network",haNotConfigured:"Home Assistant is not configured. Set it up in",haSettingsPath:"Settings → Network → Home Assistant",selectEntity:"Select Entity *",ipAddress:"IP Address *",nameLabel:"Name *",username:"Username",password:"Password",authHint:"Leave empty if your Tasmota device doesn't require authentication",linkToPrinter:"Link to Printer",noPrinter:"No printer (manual control only)",linkingDescription:"Linking enables automatic on/off when prints start/complete",powerAlerts:"Power Alerts",alertAbove:"Alert if above (W)",alertBelow:"Alert if below (W)",alertDescription:"Get notified when power consumption crosses these thresholds. Leave empty to disable that direction.",dailySchedule:"Daily Schedule",turnOnAt:"Turn On at",turnOffAt:"Turn Off at",scheduleDescription:"Automatically turn the plug on/off at these times daily. Leave empty to skip that action.",showOnPrinterCard:"Show on Printer Card",displayOnPrinterCard:"Display button on printer card",connectedResult:"Connected!",deviceLabel:"Device: {{name}} - ",stateLabel:"State: {{state}}",test:"Test",delete:"Delete",save:"Save",add:"Add",cancel:"Cancel",failedToStartScan:"Failed to start scan",nameRequired:"Name is required",entityRequired:"Entity is required for Home Assistant plugs",mqttTopicRequired:"At least one MQTT topic must be configured for power, energy, or state monitoring",loadingEntities:"Loading entities...",loading:"Loading...",failedToLoadEntities:"Failed to load entities: {{error}}",noEntitiesMatching:'No entities found matching "{{search}}"',noEntitiesAvailable:"No entities available",searchingEntities:"Searching all entities ({{count}} found)",showingEntities:"Showing switch, light, input_boolean ({{count}} available)",energyMonitoringOptional:"Energy Monitoring (Optional)",energyMonitoringHint:"Search and select sensors that provide power/energy data.",powerSensorW:"Power Sensor (W)",energyTodayKwh:"Energy Today (kWh)",totalEnergyKwh:"Total Energy (kWh)",noMatchingSensors:"No matching sensors",none:"None",mqttNotConfigured:"MQTT broker not configured. Set broker address in",mqttSettingsPath:"Settings → Network → MQTT Publishing",mqttNotConfiguredSuffix:"(you don't need to enable publishing, just fill in the broker details).",mqttMonitorOnlyDescription:"MQTT plugs receive power/energy data via MQTT subscription. On/off control is not available - use your MQTT broker or home automation system.",powerMonitoring:"Power Monitoring",energyMonitoring:"Energy Monitoring",stateMonitoring:"State Monitoring",optional:"optional",topic:"Topic",jsonPath:"JSON Path",multiplier:"Multiplier",onValue:"ON Value",mqttPowerHint:`JSON path extracts value from JSON payload (e.g., "power_l1"). Leave empty if topic publishes raw numeric values. Use multiplier 0.001 for mW→W, 1000 for kW→W.`,mqttEnergyHint:`JSON path extracts value from JSON payload. Leave empty for raw values. Use multiplier 0.001 for Wh→kWh, 1000 for MWh→kWh.`,mqttStateHint:`JSON path extracts value from JSON payload. Leave empty for raw values. ON value: the exact string that means "ON". Leave empty for auto-detect (ON, true, 1).`,restControl:"Control",restOnUrl:"Turn ON URL",restOffUrl:"Turn OFF URL",restOnBody:"ON Request Body",restOffBody:"OFF Request Body",restMethod:"HTTP Method",restHeaders:"Custom Headers (JSON)",restStatusUrl:"Status URL",restStatusPath:"State JSON Path",restStatusOnValue:"ON Value",restPowerUrl:"Power URL",restPowerPath:"Power JSON Path",restPowerMultiplier:"Power Multiplier",restEnergyUrl:"Energy URL",restEnergyPath:"Energy JSON Path",restEnergyMultiplier:"Energy Multiplier",restUrlRequired:"At least one URL (ON or OFF) is required for REST plugs",restHeadersHint:'e.g. {"Authorization": "Bearer your-token"}',restBodyHint:'e.g. ON, {"state": "on"}',restStatusHint:"URL to poll for current state",restPathHint:"e.g. state or data.power.status",restPowerUrlHint:"Separate URL for power data (uses Status URL if empty)",restEnergyUrlHint:"Separate URL for energy data (uses Status URL if empty)",restEnergyHint:"Each value can use its own URL or fall back to the Status URL. Use multipliers for unit conversion (e.g. 0.001 to convert Wh to kWh).",testConnection:"Test Connection",connectionSuccess:"Connection successful",noSwitchesInSwitchbar:"No switches in switchbar",enableSwitchbarHint:'Enable "Show in Switchbar" in Settings > Smart Plugs'},notifications:{providerTypes:{callmebot:"CallMeBot/WhatsApp",ntfy:"ntfy",pushover:"Pushover",telegram:"Telegram",email:"Email",discord:"Discord",webhook:"Webhook",homeassistant:"Home Assistant"},providerDescriptions:{email:"SMTP email notifications",telegram:"Notifications via Telegram bot",discord:"Send to Discord channel via webhook",ntfy:"Free, self-hostable push notifications",pushover:"Simple, reliable push notifications",callmebot:"Free WhatsApp notifications via CallMeBot",webhook:"Generic HTTP POST to any URL",homeassistant:"Persistent notifications in Home Assistant dashboard"},lastSuccess:"Last: {{date}}",error:"Error",printer:"Printer:",allPrinters:"All printers",sendTestNotification:"Send Test Notification",eventSettings:"Event Settings",enabled:"Enabled",sendFromProvider:"Send notifications from this provider",printEvents:"Print Events",printerStatus:"Printer Status",amsAlarms:"AMS Alarms",amsHtAlarms:"AMS-HT Alarms",printQueue:"Print Queue",start:"Start",plateCheck:"Plate Check",complete:"Complete",failed:"Failed",stopped:"Stopped",progress:"Progress",offline:"Offline",lowFilament:"Low Filament",maintenance:"Maintenance",amsHumidity:"AMS Humidity",amsTemp:"AMS Temp",amsHtHumidity:"AMS-HT Humidity",amsHtTemp:"AMS-HT Temp",bedCooled:"Bed Cooled",firstLayer:"First Layer",quiet:"Quiet",digest:"Digest {{time}}",printStarted:"Print Started",plateNotEmpty:"Plate Not Empty",plateNotEmptyDescription:"Objects detected before print",printCompleted:"Print Completed",bedCooledLabel:"Bed Cooled",bedCooledDescription:"Bed cooled below threshold after print",firstLayerCompleteLabel:"First Layer Complete",firstLayerCompleteDescription:"Notify with snapshot when first layer finishes",missingSpoolAssignmentLabel:"Missing Spool Assignment",missingSpoolAssignmentDescription:"Notify when print starts and required trays have no assigned spool",printFailed:"Print Failed",printStopped:"Print Stopped",progressMilestones:"Progress Milestones",progressMilestonesDescription:"Notify at 25%, 50%, 75%",printerOffline:"Printer Offline",printerError:"Printer Error",lowFilamentLabel:"Low Filament",maintenanceDue:"Maintenance Due",maintenanceDueDescription:"Notify when maintenance is needed",amsHumidityHigh:"AMS Humidity High",amsHumidityHighDescription:"Regular AMS humidity exceeds threshold",amsTemperatureHigh:"AMS Temperature High",amsTemperatureHighDescription:"Regular AMS temperature exceeds threshold",amsHtHumidityHigh:"AMS-HT Humidity High",amsHtHumidityHighDescription:"AMS-HT humidity exceeds threshold",amsHtTemperatureHigh:"AMS-HT Temperature High",amsHtTemperatureHighDescription:"AMS-HT temperature exceeds threshold",inventoryAlerts:"Inventory Alerts",stockReorderAlert:"Reorder Alert",stockReorderAlertDescription:"SKU has reached its reorder point",stockBreakAlert:"Stock Break Alert",stockBreakAlertDescription:"Stock will run out before replenishment arrives",jobAdded:"Job Added",jobAddedDescription:"Job added to queue",jobAssigned:"Job Assigned",jobAssignedDescription:"Model-based job assigned to printer",jobStarted:"Job Started",jobStartedDescription:"Queue job started printing",jobWaiting:"Job Waiting",jobWaitingDescription:"Job waiting for filament or printer",jobSkipped:"Job Skipped",jobSkippedDescription:"Job skipped (previous failed)",jobFailed:"Job Failed",jobFailedDescription:"Job failed to start",queueComplete:"Queue Complete",queueCompleteDescription:"All queue jobs finished",quietHours:"Quiet Hours",noNotificationsDuring:"No notifications during these hours",editProviderToChangeQuietHours:"Edit provider to change quiet hours",dailyDigest:"Daily Digest",batchNotifications:"Batch notifications into a single daily summary",sendAt:"Send at {{time}}",editProviderToChangeDigestTime:"Edit provider to change digest time",edit:"Edit",deleteProvider:"Delete Notification Provider",deleteConfirm:'Are you sure you want to delete "{{name}}"? This cannot be undone.',delete:"Delete",addTitle:"Add Notification Provider",editTitle:"Edit Notification Provider",nameLabel:"Name *",namePlaceholder:"My Notifications",providerTypeLabel:"Provider Type *",configuration:"Configuration",testConfiguration:"Test Configuration",printerFilter:"Printer Filter",onlyFromPrinter:"Only send notifications for events from this printer",quietHoursDnd:"Quiet Hours (Do Not Disturb)",quietStart:"Start",quietEnd:"End",dailyDigestLabel:"Daily Digest",sendDigestAt:"Send digest at",digestCollected:"Events will be collected and sent as a single summary at this time",notificationEvents:"Notification Events",progressPercent:"(25%, 50%, 75%)",bedCooledAfterPrint:"(after print completes)",eventPriority:{sectionTitle:"ntfy Priority",helpNtfy:"Pick a priority for each enabled event. ntfy uses these to escalate alerts (sound, visibility, push behavior). Levels not set here use the ntfy server default.",min:"Min",low:"Low",default:"Default",high:"High",urgent:"Urgent"},cancel:"Cancel",save:"Save",add:"Add",nameRequired:"Name is required",fieldRequired:"{{field}} is required",phoneNumber:"Phone Number",apiKey:"API Key",serverUrl:"Server URL",topic:"Topic",authToken:"Auth Token",userKey:"User Key",appToken:"App Token",priority:"Priority",botToken:"Bot Token",chatId:"Chat ID",smtpServer:"SMTP Server",smtpPort:"SMTP Port",security:"Security",authentication:"Authentication",username:"Username",password:"Password",fromEmail:"From Email",toEmail:"To Email",webhookUrl:"Webhook URL",payloadFormat:"Payload Format",authorization:"Authorization",titleFieldName:"Title Field Name",messageFieldName:"Message Field Name",editTemplate:"Edit Template: {{name}}",titleLabel:"Title",bodyLabel:"Body",titlePlaceholder:"Notification title...",bodyPlaceholder:"Notification body...",availableVariables:"Available Variables",clickToInsert:"Click to insert at cursor position in body",livePreview:"Live Preview",hide:"Hide",show:"Show",loadingPreview:"Loading preview...",enterTemplateContent:"Enter template content to see preview",titlePreview:"Title:",bodyPreview:"Body:",resetToDefault:"Reset to Default",titleRequired:"Title is required",bodyRequired:"Body is required",notificationLog:"Notification Log",showFailedOnly:"Failed only",last24Hours:"Last 24 hours",last7Days:"Last 7 days",last30Days:"Last 30 days",last90Days:"Last 90 days",justNow:"Just now",noFailedNotifications:"No failed notifications",noNotificationsLogged:"No notifications logged",unknownProvider:"Unknown Provider",logTitle:"Title",logMessage:"Message",logError:"Error",logProvider:"Provider: {{type}}",logTime:"Time: {{time}}",refresh:"Refresh",clearOld:"Clear Old",statsSummary:"Last {{days}} days:",statsNotifications:"notifications",statsSent:"{{count}} sent",statsFailed:"{{count}} failed",eventTypes:{print_start:"Print Started",print_complete:"Print Complete",print_failed:"Print Failed",print_stopped:"Print Stopped",print_progress:"Progress",printer_offline:"Printer Offline",printer_error:"Printer Error",filament_low:"Low Filament",maintenance_due:"Maintenance Due",test:"Test"},userEmail:{title:"Notifications",emailNotifications:"Email Notifications",emailNotificationsDesc:"Receive email notifications for your own print jobs. Emails are sent using the system SMTP settings configured in Advanced Authentication.",sendingTo:"Notifications will be sent to",noEmailWarning:"Your account does not have an email address. Contact an administrator to add one.",printJobNotifications:"Print Job Notifications",printJobNotificationsDesc:"Choose which events trigger email notifications for print jobs you submit.",printJobStarts:"Print Job Starts",printJobStartsDesc:"Get notified when your print job begins.",printJobFinishes:"Print Job Finishes",printJobFinishesDesc:"Get notified when your print job completes successfully.",printErrors:"Print Errors",printErrorsDesc:"Get notified when your print job fails or encounters an error.",printJobStops:"Print Job Stops",printJobStopsDesc:"Get notified when your print job is cancelled or stopped.",saveSuccess:"Notification preferences saved.",saveError:"Failed to save notification preferences."}},richTextEditor:{bold:"Bold",italic:"Italic",underline:"Underline",bulletList:"Bullet List",numberedList:"Numbered List",alignLeft:"Align Left",alignCenter:"Align Center",alignRight:"Align Right",addLink:"Add Link",removeLink:"Remove Link"},externalLinks:{noLinksConfigured:"No external links configured",deleteLink:"Delete Link",removeCustomIcon:"Remove custom icon",openInNewTab:"Open in new tab",placeholders:{linkName:"My Link"}},keyboardShortcuts:{title:"Keyboard Shortcuts",navigation:"Navigation",archivesSection:"Archives",kProfilesSection:"K-Profiles",generalSection:"General",shortcuts:{goToPrinters:"Go to Printers",goToArchives:"Go to Archives",goToQueue:"Go to Queue",goToStats:"Go to Statistics",goToProfiles:"Go to Cloud Profiles",goToSettings:"Go to Settings",focusSearch:"Focus search",openUploadModal:"Open upload modal",clearSelection:"Clear selection / blur input",contextMenu:"Context menu on cards",refreshProfiles:"Refresh profiles",newProfile:"New profile",exitSelectionMode:"Exit selection mode",showHelp:"Show this help"},footer:"Press Esc or click outside to close"},notificationLog:{title:"Notification Log",events:{printStarted:"Print Started",printComplete:"Print Complete",printFailed:"Print Failed",printStopped:"Print Stopped",progress:"Progress",printerOffline:"Printer Offline",printerError:"Printer Error",lowFilament:"Low Filament",maintenanceDue:"Maintenance Due",test:"Test"},timeAgo:{justNow:"Just now",minutesAgo:"{{minutes}}m ago",hoursAgo:"{{hours}}h ago"}},restoreBackup:{title:"Restore Backup",restoring:"Restoring...",restoreComplete:"Restore Complete",restoreFailed:"Restore Failed",importSettings:"Import settings from a backup file",pleaseWait:"Please wait while your data is being restored",clickToSelect:"Click to select backup file (.json or .zip)",howDuplicateHandling:"How duplicate handling works:",categories:{printers:"Printers",smartPlugs:"Smart Plugs",notificationProviders:"Notification Providers",filaments:"Filaments",archives:"Archives",pendingUploads:"Pending Uploads",settingsTemplates:"Settings & Templates"},matchingInfo:{printers:"matched by serial number",smartPlugs:"matched by IP address",notificationProviders:"matched by name",filaments:"matched by name + type + brand",archives:"matched by content hash",pendingUploads:"matched by filename",settingsTemplates:"always overwritten"},replaceExisting:"Replace existing data",keepExisting:"Keep existing data",replaceDescription:"Overwrite items that already exist with backup data",keepDescription:"Only restore items that don't already exist",caution:"Caution:",cautionText:"Overwriting will replace your current configurations with backup data. Printer access codes are never overwritten for security.",itemsRestored:"Items Restored",itemsSkipped:"Items Skipped",restored:"Restored",skipped:"Skipped (already exist)",filesLabel:"Files (3MF, thumbnails, etc.)",newApiKeysGenerated:"New API Keys Generated",newApiKeysWarning:"These keys are only shown once. Copy them now!",processingBackup:"Processing backup file...",noDataFound:"No data was found to restore in the backup file.",failedToRestore:"Failed to restore backup. Please check the file format."},backupExport:{title:"Export Backup",selectData:"Select data to include",selectAll:"Select All",selectNone:"Select None",categoryDescriptions:{settings:"Language, theme, update preferences",notifications:"ntfy, Pushover, Discord, etc.",templates:"Custom message templates",smartPlugs:"Tasmota plug configurations",externalLinks:"Sidebar links to external services",printers:"Printer info (access codes excluded)",plateDetection:"Empty plate reference images",filaments:"Filament types and costs",maintenance:"Custom maintenance schedules",archives:"All print data + files (3MF, thumbnails, photos)",projects:"Projects, BOM items, and attachments",pendingUploads:"Virtual printer uploads awaiting review",apiKeys:"Webhook API keys (new keys generated on import)"},requiresPrinters:"Requires Printers to be selected",zipFileWarning:"ZIP file will be created.",zipFileDescription:"Includes all 3MF files, thumbnails, timelapses, and photos. This may take a while and result in a large file.",includeAccessCodes:"Include Access Codes",includeAccessCodesDescription:"For transferring to another machine",includeAccessCodesWarning:"Access codes will be included in plain text. Keep this backup file secure!",categoriesSelected:"{{selectedCount}} categories selected"},pendingUploads:{placeholders:{notes:"Add notes about this print..."},discardUpload:"Discard Upload",archiveAllUploads:"Archive All Uploads",discardAllUploads:"Discard All Uploads",archive:"Archive",timeAgo:{justNow:"Just now",minutesAgo:"{{minutes}}m ago",hoursAgo:"{{hours}}h ago",daysAgo:"{{days}}d ago"}},apiBrowser:{placeholders:{requestBody:"JSON request body...",searchEndpoints:"Search endpoints..."}},configureAmsSlot:{title:"Configure AMS Slot",slotConfigured:"Slot Configured!",configuringSlot:"Configuring slot:",slotLabel:"{{ams}} Slot {{slot}}",searchPresets:"Search presets...",colorPlaceholder:"Color name or hex (e.g., brown, FF8800)",clearCustomColor:"Clear custom color",noCloudPresets:"No cloud presets. Login to Bambu Cloud to sync.",noPresetsAvailable:"No presets available. Login to Bambu Cloud or import local profiles.",noMatchingPresets:"No matching presets found.",custom:"Custom",builtin:"Built-in",settingsSentToPrinter:"Settings sent to printer",filamentProfile:"Filament Profile",kProfileLabel:"K Profile (Pressure Advance)",filteringFor:"Filtering for: {{material}}",noKProfile:"No K profile (use default 0.020)",noMatchingKProfiles:"No matching K profiles found. Default K=0.020 will be used.",selectFilamentFirst:"Select a filament profile first",kFromCalibration:"K={{value}} from printer calibration",customColorLabel:"Custom Color (optional)",presetColors:"{{name}} colors:",showLessColors:"Show less colors",showMoreColors:"Show more colors",clear:"Clear",hexLabel:"Hex: #{{hex}}",resetting:"Resetting...",resetSlot:"Reset Slot",cancel:"Cancel",configuring:"Configuring...",configureSlot:"Configure Slot"},githubBackup:{title:"Git Backup",history:"History",downloadBackup:"Download Backup",restoreBackup:"Restore Backup",noBackupsYet:"No backups yet"},emailSettings:{placeholders:{fromName:"BamBuddy"}},tagManagement:{searchTags:"Search tags...",renameTag:"Rename tag",deleteTag:"Delete tag"},notificationTemplates:{placeholders:{title:"Notification title...",body:"Notification body..."}},batchTag:{placeholders:{newTag:"Enter new tag..."}},photoGallery:{deletePhoto:"Delete Photo"},filamentHoverCard:{copySpoolUuid:"Copy spool UUID"},kProfilesView:{hasNote:"Has note",copyProfile:"Copy profile"},layout:{openMenu:"Open menu",noPermissionSystemInfo:"You do not have permission to view system information"},dashboard:{dragToReorder:"Drag to reorder",hideWidget:"Hide widget"},notificationProviderCard:{deleteNotificationProvider:"Delete Notification Provider"},fileManagerModal:{closeFileManager:"Close file manager",sortFiles:"Sort files",goToParentFolder:"Go to parent folder",threeView:"3D View"},embeddedCameraViewer:{refreshStream:"Refresh stream",close:"Close",zoomOut:"Zoom out",resetZoom:"Reset zoom",zoomIn:"Zoom in",dragToResize:"Drag to resize"},timelapseViewer:{skipBack5s:"Skip back 5s",skipForward5s:"Skip forward 5s"},notificationProviders:{descriptions:{email:"SMTP email notifications",telegram:"Notifications via Telegram bot",discord:"Send to Discord channel via webhook",ntfy:"Free, self-hostable push notifications",pushover:"Simple, reliable push notifications",callmebot:"Free WhatsApp notifications via CallMeBot",webhook:"Generic HTTP POST to any URL"}},logViewer:{searchPlaceholder:"Search message or logger name...",noLogEntries:"No log entries found"},switchbarPopover:{noSwitchesInSwitchbar:"No switches in switchbar"},projectPageModal:{placeholders:{title:"Title",designer:"Designer",license:"License",description:"Enter description...",profileTitle:"Profile Title",profileDescription:"Profile description..."}},spoolmanSettings:{},time:{unknown:"-",waiting:"Waiting",justNow:"Just now",now:"Now",minsAgo:"{{count}}m ago",inMins:"in {{count}}m",hoursAgo:"{{count}}h ago",inHours:"in {{count}}h",daysAgo:"{{count}}d ago",inDays:"in {{count}}d"},spoolbuddy:{nav:{dashboard:"Dashboard",ams:"AMS",inventory:"Inventory",writeTag:"Write",settings:"Settings"},status:{nfcReady:"NFC Ready",nfcOff:"NFC Off",offline:"Offline",online:"Online",noPrinters:"No printers",deviceOffline:"Device Offline",waitingConnection:"Waiting for device connection...",systemReady:"System Ready",status:"Status"},dashboard:{readyToScan:"Ready to scan",idleMessage:"Place a spool on the scale to identify it",nfcHint:"NFC tag will be read automatically",device:"Device",syncWeight:"Sync Weight",weightSynced:"Synced!",unknownTag:"Unknown Tag",newTag:"New Tag Detected",onScale:"on scale",linkSpool:"Link to Spool",linkTagTitle:"Link Tag to Spool",linkTag:"Link Tag",selectSpool:"Select a spool to link this tag to:",noUntagged:"No spools without tags found",tagDetected:"Tag detected",noTag:"No tag",tagId:"Tag",grossWeight:"Gross weight",spoolSize:"Spool size",close:"Close",currentSpool:"Current Spool",plateReady:"Plate ready: {{name}}",plateReadyLabel:"Plates ready to clear",plateClearAction:"Clear",plateClearedToast:"Plate marked as cleared",plateClearFailed:"Could not mark plate as cleared"},modal:{spoolDetected:"Spool Detected",assignToAms:"Assign to AMS",syncWeight:"Sync Weight",weightSynced:"Synced!",syncing:"Syncing...",newTagDetected:"New Tag Detected",addToInventory:"Add to Inventory",assignToAmsTitle:"Assign to AMS",selectSlot:"Select a slot",assign:"Assign",assigning:"Assigning...",assignSuccess:"Assigned!",assignPendingInsert:"Assigned. Slot will configure when you insert the spool.",assignError:"Failed to assign spool. Please try again.",noPrinterSelected:"Select a printer...",noAmsDetected:"No AMS detected on this printer",slot:"Slot"},weight:{noReading:"No reading",stable:"Stable",measuring:"Measuring...",tare:"Tare",calibrate:"Calibrate"},spool:{remaining:"Remaining",material:"Material",brand:"Brand",color:"Color",coreWeight:"Core",labelWeight:"Label",scaleWeight:"Scale",netWeight:"Net",lastUsed:"Last used"},ams:{noData:"No AMS detected",connectAms:"Connect an AMS to see filament slots",noPrinter:"No printer selected",selectPrinter:"Select a printer from the top bar",printerDisconnected:"Printer disconnected",humidity:"Humidity",level:"Level",active:"Active",slot:"Slot",empty:"Empty"},inventory:{search:"Search spools...",empty:"No spools in inventory",noResults:"No matching spools",spools:"spools",addSpool:"Add Spool"},settings:{tabDevice:"Device",tabDisplay:"Display",tabScale:"Scale",tabUpdates:"Updates",nfcReader:"NFC Reader",type:"Type",connection:"Connection",notConnected:"N/A",deviceInfo:"Device Info",hostname:"Host",uptime:"Uptime",systemConfig:"Backend & Auth",backendUrl:"Bambuddy Backend URL",apiToken:"API Token",apiTokenPlaceholder:"Enter API token",saveConfig:"Save Config",systemQueued:"Config queued.",nfcDiagnostic:"NFC Diagnostic",scaleDiagnostic:"Scale Diagnostic",readTagDiagnostic:"Read Tag Diagnostic",testNfc:"Test reader",testScale:"Test accuracy",testReadTag:"Read tag",systemFieldsRequired:"Backend URL is required.",brightness:"Brightness",saved:"Saved",noBacklight:"No DSI backlight detected. Brightness control requires a DSI display.",screenBlank:"Screen Blank Timeout",screenBlankDesc:"Screen turns off after inactivity. Touch to wake.",displayNote:"Brightness is applied as a software filter.",scaleCalibration:"Scale Calibration",currentWeight:"Current weight",tareOffset:"Tare",calFactor:"Factor",knownWeight:"Known weight",calStep1:"Remove all items from the scale and press Set Zero.",calStep2:"Place known weight on scale.",setZero:"Set Zero",calibrateNow:"Calibrate",calibrated:"Calibrated",tareSet:"Tare command sent. Waiting for device...",tareFailed:"Failed to send tare command",zeroSet:"Zero point set. Place known weight on scale.",calibrationDone:"Calibration complete!",calibrationFailed:"Calibration failed",lastCalibrated:"Last calibrated",stable:"Stable",settling:"Settling...",firmware:"Firmware",scale:"Scale",noDevice:"No SpoolBuddy device found",daemonVersion:"Daemon Version",currentVersion:"Current",versionPending:"Waiting for daemon...",checking:"Checking...",checkUpdates:"Check for Updates",updateAvailable:"Update available",updateInstructions:"Update via SSH: run the SpoolBuddy install script to upgrade.",upToDate:"Up to date",includeBeta:"Include beta versions"},writeTag:{tabExisting:"Existing Spool",tabNew:"New Spool",tabReplace:"Replace Tag",searchPlaceholder:"Search by material, color, brand...",noUntaggedSpools:"No spools without tags",noTaggedSpools:"No spools with tags",selectSpool:"Select a spool, then place a blank NTAG on the reader",placeTag:"Place an NTAG on the reader",tagReady:"Tag detected — ready to write",writeTag:"Write Tag",replaceTag:"Replace Tag",writing:"Writing tag...",waiting:"Waiting for SpoolBuddy...",writeSuccess:"Tag written successfully!",writeFailed:"Write failed",queueFailed:"Failed to queue write command",tryAgain:"Try Again",cancel:"Cancel",replaceWarning:"Old tag will be unlinked. New tag will replace it.",deviceOffline:"SpoolBuddy is offline",material:"Material",colorName:"Color Name",color:"Color",brand:"Brand",weight:"Weight (g)",createSpool:"Create Spool",creating:"Creating...",spoolCreated:"Spool created! Ready to write.",createFailed:"Failed to create spool",incompleteDataWarning:"Tag written with incomplete Spoolman data"},quickMenu:{printerPower:"Printer Power",systemControls:"System",restartDaemon:"Restart Daemon",restartBrowser:"Restart Browser",reboot:"Reboot",shutdown:"Shutdown",swipeToClose:"Swipe down to close",confirmTitle:"Confirm",confirmShutdown:"Are you sure you want to shut down the SpoolBuddy? You will need physical access to turn it back on.",confirmReboot:"Are you sure you want to reboot the SpoolBuddy?",confirmRestartDaemon:"Restart the SpoolBuddy daemon? NFC and scale will be temporarily unavailable.",confirmRestartBrowser:"Restart the kiosk browser? The display will briefly go blank.",confirm:"Confirm",confirmPlugOn:"Turn on {{name}}?",confirmPlugOff:"Turn off {{name}}?",turnOn:"Turn On",turnOff:"Turn Off"}},bugReport:{title:"Report a Bug",description:"Description",descriptionPlaceholder:"What went wrong? Please describe the issue...",email:"Email (optional)",emailPlaceholder:"your@email.com",emailPrivacy:"If provided, your email will be included in a collapsed section of the GitHub issue so the maintainer can follow up.",screenshot:"Screenshot",uploadOrPaste:"Upload, paste, or drag an image",dataCollectedSummary:"What data is included in the report?",dataIncluded:"Included:",dataIncludedList:"App version, OS, architecture, Python version, database stats (counts only), printer models, nozzle counts, firmware versions, connectivity status, integration status (Spoolman, MQTT, HA), non-sensitive settings, network interface count, Docker details, dependency versions.",dataNeverIncluded:"Never included:",dataNeverIncludedList:"Printer names, serial numbers, access codes, passwords, IP addresses, email addresses, API keys, tokens, webhook URLs, hostnames, or usernames.",submit:"Submit",startLogging:"Start Debug Logging",stepEnableLogging:"Debug logging enabled",stepReproduce:"Reproduce the issue now",stepStopLogging:"Stop & submit report",stopAndSubmit:"Stop & Submit",maxDuration:"Auto-stops after {{minutes}} min",stoppingLogs:"Collecting logs & submitting...",submitting:"Submitting bug report...",submitSuccess:"Bug report submitted successfully!",submitFailed:"Failed to submit bug report",thankYou:"Thank you!",submitted:"Your bug report has been submitted.",viewIssue:"View Issue",unexpectedError:"An unexpected error occurred"},failureDetection:{title:"AI Failure Detection",description:"Monitor prints with a self-hosted Obico ML API and act on detected failures automatically.",mlUrl:"Obico ML API URL",mlUrlHint:"Base URL of your self-hosted Obico ml_api container (e.g. http://192.168.1.10:3333).",test:"Test",testSuccess:"ML API reachable and healthy.",testFailed:"Could not reach the ML API.",sensitivity:"Sensitivity",sensitivityLow:"Low (fewer false positives)",sensitivityMedium:"Medium (balanced)",sensitivityHigh:"High (detect early, more false positives)",sensitivityHint:"Adjusts the confidence thresholds that trigger warnings and failures.",action:"Action on detected failure",actionNotify:"Notify only",actionPause:"Pause print",actionPauseOff:"Pause and cut power",pollInterval:"Poll interval (seconds)",pollIntervalHint:"How often to check each printer while it is printing. Minimum 5s, maximum 120s.",externalUrlMissing:"External URL is not set.",externalUrlHint:"The ML API fetches the camera snapshot by URL. Set the External URL in General settings so the ML API container can reach Bambuddy.",perPrinterTitle:"Monitored Printers",perPrinterHint:"Choose which printers the detection service watches.",monitorAll:"Monitor all connected printers",statusTitle:"Status",serviceRunning:"Service running",thresholds:"Low / High thresholds",activePrinters:"Active prints",noActivePrints:"No prints currently running.",historyTitle:"Recent Detections",noHistory:"No detections yet."},makerworld:{title:"MakerWorld",description:"Paste a MakerWorld model URL to import and print it directly from Bambuddy — without leaving for the Bambu Handy app.",pasteUrlHeader:"Import from MakerWorld",pasteUrlPlaceholder:"https://makerworld.com/en/models/… or paste any MakerWorld link",resolveButton:"Resolve",signInRequiredTitle:"Bambu Cloud sign-in required to download",signInRequiredBody:"You can browse model details anonymously, but MakerWorld requires a Bambu Cloud account to download 3MF files.",openCloudSettings:"Open Cloud settings",untitledModel:"Untitled model",byCreator:"by {{name}}",downloadsCount:"{{count}} downloads",licensePrefix:"License",alreadyImported:"Already in library",openOnMakerworld:"Open on MakerWorld",alreadyInLibrary:"This model is already in your library — find it in File Manager → MakerWorld",importSuccess:"Imported {{filename}} — saved to File Manager → MakerWorld",platesHeader:"Plates ({{count}})",plateDefaultName:"Plate {{n}}",materialCount:"{{count}} filaments",amsRequired:"AMS required",slicedFor:"Sliced for {{printer}}",alsoCompatible:"Also marked compatible: {{printers}}",importToLibrary:"Save",sliceIn:"Save & Slice in {{slicer}}",disclaimer:"MakerWorld integration uses community-documented API endpoints. Bambuddy is not affiliated with or endorsed by MakerWorld or Bambu Lab.",lastImportSuccess:"Imported to your library",lastImportAlreadyInLibrary:"Already in your library",viewInLibrary:"View in File Manager",openInBambuStudio:"Open in Bambu Studio",openInOrcaSlicer:"Open in OrcaSlicer",importTo:"Import to file manager",recentImportsHeader:"Recent imports",phaseResolving:"Resolving",phaseDownloading:"Downloading",folderAuto:"MakerWorld (default)",importAll:"Import all",importAllProgress:"Importing {{current}}/{{total}}",openGallery:"Open image gallery",galleryPrev:"Previous image",galleryNext:"Next image",deleteImport:"Remove from library",importDeleting:"Removing…",importDeleted:"Removed from library",confirmDelete:"Remove {{filename}} from the library? This deletes the local file but the plate can be re-imported from MakerWorld.",errors:{resolveFailed:"Could not resolve that MakerWorld URL.",downloadFailed:"Download failed. Please try again.",deleteFailed:"Could not remove the file from the library."}},gcodeViewer:{back:"Back",backToArchives:"Back to Print Archives",backToFiles:"Back to File Manager"},libraryTrash:{title:"Trash",headerButton:"Trash",headerTooltip:"View files moved to the trash",backToFiles:"Back to File Manager",subtitleAdmin:"Deleted files stay here for {{days}} days, then auto-delete. This view shows trashed files for all users.",subtitleUser:"Deleted files stay here for {{days}} days, then auto-delete.",loading:"Loading trash…",loadError:"Could not load the trash.",empty:"The trash is empty.",summary:"{{count}} files · {{size}}",emptyTrash:"Empty trash",restore:"Restore",purgeNow:"Delete now",autoPurgeIn:"Auto-deletes in {{when}}",days:"days",retentionLabel:"Auto-delete after",selectAll:"Select all",selectOne:"Select {{filename}}",selectionCount:"{{count}} selected",bulkRestore:"Restore selected",bulkPurge:"Delete selected",col:{filename:"File",folder:"Folder",size:"Size",deleted:"Moved to trash",autoPurge:"Auto-deletes",owner:"Owner",actions:"Actions"},confirm:{purgeTitle:"Delete permanently?",purgeBody:"{{filename}} will be deleted from disk and cannot be restored.",emptyTitle:"Empty the trash?",emptyBody:"All {{count}} files will be deleted from disk. This cannot be undone.",bulkPurgeTitle:"Delete selected files permanently?",bulkPurgeBody:"The {{count}} selected files will be deleted from disk and cannot be restored.",cta:"Delete permanently"},toast:{restored:"File restored.",restoreFailed:"Could not restore the file.",purged:"File deleted permanently.",purgeFailed:"Could not delete the file.",emptied:"Deleted {{count}} file(s) from trash.",emptyFailed:"Could not empty the trash.",retentionSaved:"Auto-delete set to {{days}} days.",retentionFailed:"Could not save retention setting.",bulkRestored:"Restored {{count}} file(s).",bulkPurged:"Deleted {{count}} file(s)."}},libraryPurge:{title:"Purge old files",headerButton:"Purge old",headerTooltip:"Bulk-move old files to trash",description:"Sweep old files out of your library in one shot. Files with a print history are aged by their last-printed date; files that were never printed are aged by their upload date.",ageLabel:"Move files older than",days:"days",includeNeverPrinted:"Include files that have never been printed",effectsTitle:"What happens when you click Purge",effect1:"Matching files are moved to Trash — they are not deleted from disk yet.",effect2:"You can restore them from Trash at any time until the retention window expires.",effect3:"After retention, the trash sweeper permanently removes them from disk.",effect4:"Files in external (linked) folders are skipped — Bambuddy never deletes bytes it does not own.",previewLoading:"Checking how many files match…",previewFailed:"Could not preview the purge.",previewSummary:"{{count}} files · {{size}} would move to trash",andMore:"…and {{count}} more",warning:"Trashed files still count against storage until the retention window expires. Empty the Trash afterwards to free disk immediately.",confirmCta:"Move {{count}} to trash",purging:"Moving to trash…",toast:{success:"Moved {{count}} file(s) to trash.",failed:"Could not purge files."}},libraryAutoPurge:{enableLabel:"Auto-purge old files",enableDescription:"Runs the admin purge once per day. Files go to Trash first — they are not deleted immediately.",ageLabel:"Auto-purge files older than",ageDescription:"Minimum 7 days, maximum 10 years. Uses the same age rule as the manual Purge button.",days:"days",includeNeverPrinted:"Include files that have never been printed",saveFailed:"Could not save auto-purge settings."},archivePurge:{headerButton:"Purge old",headerTooltip:"Bulk-delete old archives",title:"Purge old archives",description:"Clear out old print history. Each archive is aged by its most recent print completion — reprinting an archive refreshes its age, so active work is never purged.",ageLabel:"Delete archives not printed in the last",days:"days",effectsTitle:"What happens when you click Purge",effect1:"Each matching archive is hidden from the listings and its files are removed from disk (3MF, thumbnail, timelapse, source 3MF, F3D design file, photos).",effect2:"The archive row stays in the database so Quick Stats keeps the filament, time, cost, and energy contribution — same as the single-archive delete default.",effect3:'Tick "Also remove from statistics" below to drop the Quick Stats contribution too (matches the single-archive delete option). That path is irreversible.',effect4:"Reprinting an archive refreshes its age clock, so archives you still use are safe.",purgeStatsLabel:"Also remove from statistics",purgeStatsHint:"Drops the matching archives from Quick Stats (filament, time, cost, energy). Without this, Quick Stats keeps every contribution and only the files leave disk.",previewLoading:"Checking how many archives match…",previewFailed:"Could not preview the purge.",previewSummary:"{{count}} archives · {{size}} would be removed",andMore:"…and {{count}} more",warning:"Files are removed from disk and cannot be restored. Download or favourite anything you want to keep before continuing.",confirmCta:"Remove {{count}} archive(s)",purging:"Removing…",toast:{success:"Removed {{count}} archive(s).",failed:"Could not purge archives."}},archiveAutoPurge:{enableLabel:"Auto-purge old archives",enableDescription:"Once per day, hides archives from the listings and removes their files from disk when they have not been printed within the threshold. Reprinting an archive resets the clock.",ageLabel:"Auto-delete archives not printed in the last",ageDescription:"Minimum 7 days, maximum 10 years. Based on the most recent print completion — reprinting an archive refreshes its age. Removes the 3MF, thumbnail, timelapse, source 3MF, F3D, and photos.",days:"days",purgeStatsLabel:"Also remove from statistics",purgeStatsDescription:"When enabled, the daily sweeper also drops each purged archive from Quick Stats (filament, time, cost, energy). Default off — Quick Stats keeps the contribution, only the files leave disk.",runNow:"Purge archives now",saveFailed:"Could not save auto-purge settings."},cameraTokens:{title:"Camera API Tokens",navTitle:"Camera API tokens",description:"Long-lived tokens for embedding the camera stream into Home Assistant, Frigate, kiosks, or any other tool that needs a stable URL. Each token is camera-stream-only and can be revoked at any time.",loading:"Loading…",confirmRevoke:{title:"Revoke this token?",body:'Any device using "{{name}}" will lose access immediately. This cannot be undone.',cancel:"Cancel",confirm:"Revoke"},create:{title:"Create new token",nameLabel:"Token name",namePlaceholder:"e.g. Home Assistant",daysLabel:"Days until expiry",submit:"Create",hint:"Maximum lifetime is 365 days. The token value is shown only once on creation — copy it now."},created:{title:"Token created — copy it now",warning:"This is the only time this token will be visible. After you close this dialog you can never view it again.",copy:"Copy",dismiss:"I've saved it"},list:{myTitle:"My tokens",allTitle:"All users (admin view)",empty:"No tokens yet.",name:"Name",owner:"Owner",prefix:"Prefix",created:"Created",expires:"Expires",lastUsed:"Last used",revoke:"Revoke",expired:"Expired"},toast:{created:"Token created",createFailed:"Failed to create token",revoked:"Token revoked",revokeFailed:"Failed to revoke token",loadFailed:"Failed to load tokens",copied:"Copied to clipboard",copyFailed:"Copy failed — select and copy manually"}},forecast:{title:"Forecast",noSpools:"No active spools found. Add spools to your inventory to see forecast data.",noUsageData:"No usage data available — cannot project stock timeline.",sku:"SKU",material:"Material",stock:"Stock",dailyRate:"Rate",daysLeft:"Days Left",emptyBy:"Empty By",reorderBy:"Reorder By",actions:"Actions",trend:"Trend",estimated:"Est.",noData:"No data",timeframe:"Timeframe",chartTitle:"Projected Stock — Top 5 Materials",dashedLinesROP:"Dashed lines = reorder points",stockLevel:"Stock Level",reorderPoint:"Reorder Point",safetyMargin:"Safety Margin",trendLegend:"Trend (history-based, 95% service level)",estimatedLegend:"Estimated (weight delta)",noDataLegend:"No data",ropLabel:"ROP",ssLabel:"SS",safetyStockLegend:"Safety stock",stockArrivalLegend:"Stock arrival",stockoutLegend:"Stockout",alertCount_one:"{{count}} alert",alertCount_other:"{{count}} alerts",order:"Order",save:"Save",cancel:"Cancel",settingsSaved:"Settings saved",failedSaveSettings:"Failed to save settings",globalLeadTimeSaved:"Global lead time saved",globalLeadTime:"Global lead time",globalLeadTimeHint:"Global lead time floor — used in reorder point calculation for all SKUs",skuLeadTimeOverride:"SKU Lead Time Override",skuLeadTimeHint:"0 = use global lead time. Set >0 to override for this SKU.",safetyMarginLabel:"Safety Margin",effectiveLeadTime:"Effective Lead Time",effectiveLeadTimeHint:"max(global {{global}}d, SKU {{sku}}d)",reorderPointHint:"d̄ × LT + safety margin — order when stock hits this level",safetyMarginHint:"Statistical safety stock (z=1.65 × σ × √LT) + user-defined buffer",safetyMarginHintDays:"Buffer added on top of statistical safety stock.{{approx}}",safetyMarginHintDaysApprox:" ≈ {{g}}g at current rate.",safetyMarginHintG:"Fixed weight buffer added on top of statistical safety stock.{{approx}}",safetyMarginHintGApprox:" ≈ {{days}}d at current rate.",individualSpools:"Individual spools",labelWeight:"Label",spoolCount_one:"{{count}} spool",spoolCount_other:"{{count}} spools",stockBreakRisk:"Stock break risk",stockBreakDetail:"{{days}}d remaining, lead time {{lt}}d.",stockBreakBefore:"Stock break before replenishment",reorderNow:"Reorder now",reorderTriggerPassed:"Trigger date {{date}} has passed.",shoppingList:"Shopping List",shoppingListItems_one:"({{count}} item)",shoppingListItems_other:"({{count}} items)",shoppingListEmpty:"Shopping list is empty. Click the cart icon on any row to add items.",addToCart:"Add to shopping list",alertsSnoozed:"Mute alerts for this SKU",alertsEnabled:"Unmute alerts for this SKU",addedToCart:"Added to shopping list",failedAddItem:"Failed to add item",listView:"List",logisticsView:"Logistics",qty:"Qty",weight:"Weight",leadTime:"Lead Time",expectedRestock:"Expected Restock",status:"Status",note:"Note",pending:"Pending",purchased:"Purchased",received:"Received",markPurchased:"Mark as purchased",markReceived:"Mark as received — adds spools to Stock inventory",resetToPending:"Reset to pending",remove:"Remove",clearAll:"Clear all",downloadCsv:"CSV",addToCartTitle:"Add to Shopping List",byQuantity:"By Quantity",byDuration:"By Duration",numberOfSpools:"Number of spools",lastHowManyDays:"Should last how many days?",noUsageQty:"No usage data — quantity set to 1.",noteOptional:"Note (optional)",notePlaceholder:"e.g. for project X, urgent…",addNSpools_one:"Add {{count}} spool",addNSpools_other:"Add {{count}} spools",onArrival:"On Arrival",stockBreakIn:"Stock break in {{days}}d.",stockRunsOutBefore:"Stock runs out before the {{lt}}d lead time elapses.",atRate:"At {{rate}}g/day you need",moreSpools_one:"{{count}} more spool",moreSpools_other:"{{count}} more spools",bridgeGap:"to bridge the gap.",noReadAccess:"You do not have permission to view inventory forecasts.",noWriteAccess:"You do not have permission to modify forecast settings."}},qme={nav:{printers:"Drucker",archives:"Archiv",queue:"Druckwarteschlange",stats:"Statistiken",profiles:"Profile",maintenance:"Wartung",projects:"Projekte",inventory:"Filament",files:"Dateimanager",makerworld:"MakerWorld",notifications:"Benachrichtigungen",settings:"Einstellungen",system:"System",collapseSidebar:"Seitenleiste einklappen",expandSidebar:"Seitenleiste ausklappen",update:"Aktualisieren",updateAvailable:"Update verfügbar: v{{version}}",updateAvailableBanner:"Version {{version}} ist verfügbar!",viewUpdate:"Update anzeigen",viewOnGithub:"Auf GitHub ansehen",keyboardShortcuts:"Tastaturkürzel (?)",switchToLight:"Zum hellen Modus wechseln",switchToDark:"Zum dunklen Modus wechseln",smartSwitches:"Smart Switches",logout:"Abmelden"},common:{save:"Speichern",saving:"Speichern...",cancel:"Abbrechen",delete:"Löschen",edit:"Bearbeiten",add:"Hinzufügen",close:"Schließen",confirm:"Bestätigen",loading:"Lädt...",error:"Fehler",errorLoading:"Fehler beim Laden",retry:"Erneut versuchen",success:"Erfolg",warning:"Warnung",enabled:"Aktiviert",disabled:"Deaktiviert",yes:"Ja",no:"Nein",on:"An",off:"Aus",all:"Alle",none:"Keine",search:"Suchen",filter:"Filtern",sort:"Sortieren",refresh:"Aktualisieren",download:"Herunterladen",upload:"Hochladen",uploading:"Hochladen...",uploadFailed:"Hochladen fehlgeschlagen",actions:"Aktionen",status:"Status",name:"Name",description:"Beschreibung",date:"Datum",time:"Zeit",hours:"Stunden",minutes:"Minuten",seconds:"Sekunden",days:"Tage",enable:"Aktivieren",disable:"Deaktivieren",permissions:"Berechtigungen",noPrinters:"Keine Drucker konfiguriert",noData:"Keine Daten verfügbar",linkNotFound:"Link nicht gefunden",required:"Erforderlich",optional:"Optional",dismiss:"Schließen",apply:"Anwenden",reset:"Zurücksetzen",export:"Exportieren",import:"Importieren",clear:"Leeren",selectAll:"Alle auswählen",deselectAll:"Auswahl aufheben",noChange:"— Keine Änderung —",unchanged:"Unverändert",unassigned:"Nicht zugewiesen",unknown:"Unbekannt",unknownError:"Unbekannter Fehler",today:"Heute",tomorrow:"Morgen",asap:"Sofort",overdue:"Überfällig",now:"Jetzt",collapse:"Einklappen",expand:"Ausklappen",viewArchive:"Archiv anzeigen",viewInFileManager:"Im Dateimanager anzeigen",addedBy:"Hinzugefügt von {{username}}",prints:"Drucke",more:"+{{count}} weitere",ascending:"Aufsteigend",descending:"Absteigend",back:"Zurück",copy:"Kopieren",copied:"Kopiert!",printer:"Drucker",remove:"Entfernen",type:"Typ",print:"Drucken",rename:"Umbenennen",move:"Verschieben",create:"Erstellen",duplicate:"Duplizieren",left:"Links",right:"Rechts"},printers:{title:"Drucker",addPrinter:"Drucker hinzufügen",editPrinter:"Drucker bearbeiten",deletePrinter:"Drucker löschen",printerName:"Druckername",serialNumber:"Seriennummer",ipAddress:"IP-Adresse / Hostname",accessCode:"Zugangscode",model:"Modell",nozzleCount:"Düsenanzahl",autoArchive:"Automatische Archivierung",status:{available:"Verfügbar",idle:"Bereit",printing:"Druckt",paused:"Pausiert",offline:"Offline",problem:"Problem",error:"Fehler",finished:"Fertig",unknown:"Unbekannt"},temperatures:{nozzle:"Düse",bed:"Druckbett",chamber:"Kammer"},progress:"{{percent}}% abgeschlossen",timeRemaining:"Noch {{time}}",deleteConfirm:'Möchten Sie "{{name}}" wirklich löschen?',maintenanceOk:"Wartung OK",maintenanceWarning:"{{count}} Warnung",maintenanceWarning_plural:"{{count}} Warnungen",maintenanceDue:"{{count}} fällig",maintenanceDue_plural:"{{count}} fällig",sort:{name:"Name",status:"Status",model:"Modell",location:"Standort",ascending:"Aufsteigend sortieren",descending:"Absteigend sortieren"},cardSize:{small:"Kleine Karten",medium:"Mittlere Karten",large:"Große Karten",extraLarge:"Extra große Karten"},hideOffline:"Offline ausblenden",nextAvailable:"Nächster verfügbar",powerOn:"Einschalten",offlinePrintersWithPlugs:"Offline-Drucker mit Smart-Plugs",noPrintersConfigured:"Noch keine Drucker konfiguriert",search:"Drucker suchen...",noSearchResults:"Keine Drucker entsprechen deiner Suche oder deinen Filtern",filter:{allStatuses:"Alle Status",allLocations:"Alle Standorte"},toolbar:{filters:"Filter",view:"Ansicht",actions:"Aktionen"},readyToPrint:"Druckbereit",external:"Extern",extL:"Ext-L",extR:"Ext-R",deleteArchives:"Druckarchive löschen",noLabel:"Keine Bezeichnung",printPreview:"Druckvorschau",width:"Breite",height:"Höhe",noObjectsFound:"Keine Objekte gefunden",objectsLoadedOnPrintStart:"Objekte werden beim Druckstart geladen",willBeSkipped:"Wird übersprungen",name:"Name",serialCannotBeChanged:"Seriennummer kann nicht geändert werden",locationHelp:"Dient zur Gruppierung von Druckern und zum Filtern von Warteschlangenaufträgen",wifiSignal:{veryWeak:"Sehr schwach",weak:"Schwach",fair:"Ausreichend",good:"Gut",excellent:"Ausgezeichnet"},maintenanceUpToDate:"Alle Wartungen aktuell - Klicken zum Anzeigen",chamberLightOn:"Kammerbeleuchtung einschalten",chamberLightOff:"Kammerbeleuchtung ausschalten",files:"Dateien",browseFiles:"Druckerdateien durchsuchen",autoOffAfterPrint:"Automatisches Ausschalten nach Druck",autoOffExecuted:"Auto-off wurde ausgeführt - Drucker einschalten zum Zurücksetzen",hmsErrors:"HMS-Fehler",viewHmsErrors:"{{count}} HMS-Fehler anzeigen",resume:"Fortsetzen",pause:"Pausieren",stop:"Stoppen",camera:"Kamera",skipObject:"Objekt überspringen",reconnect:"Neu verbinden",forceRefresh:"Aktualisierung erzwingen",forceRefreshSuccess:"Aktualisierung angefordert",mqttDebug:"MQTT-Debug",printerInformation:"Druckerinformationen",copyToClipboard:"Kopieren",copied:"Kopiert!",state:"Zustand",wifiSignalLabel:"WLAN-Signal",developerMode:"Entwicklermodus",enabled:"Aktiviert",disabled:"Deaktiviert",addedOn:"Hinzugefügt",sdCard:"SD-Karte",inserted:"Eingelegt",notInserted:"Nicht eingelegt",totalPrintHours:"Druckstunden",activeNozzle:"Aktiv: {{nozzle}} Düse",nozzleRack:"Düsenhalter",nozzleDocked:"Angedockt",nozzleMounted:"Montiert",nozzleActive:"Aktiv",nozzleIdle:"Inaktiv",nozzleDiameter:"Durchmesser",nozzleType:"Typ",nozzleStatus:"Status",nozzleFilament:"Filament",nozzleWear:"Verschleiß",nozzleMaxTemp:"Max. Temp",nozzleSerial:"Seriennr.",nozzleHardenedSteel:"Gehärteter Stahl",nozzleStainlessSteel:"Edelstahl",nozzleTungstenCarbide:"Wolframkarbid",nozzleFlow:"Durchfluss",nozzleHighFlow:"Hoher Durchfluss",nozzleStandardFlow:"Standard",firmwareUpdate:"Firmware-Update",firmwareInstructions:"Gehen Sie auf dem Touchscreen des Druckers zu",firmwareNav:"Navigieren Sie zu",settings:"Einstellungen",firmware:"Firmware",discoverPrinters:"Drucker entdecken",searching:"Suche...",manualEntry:"Manuelle Eingabe",addFromCloud:"Aus Cloud hinzufügen",toast:{printerDeleted:"Drucker gelöscht",missingSpoolAssignment:"Druck gestartet auf {{printer}}. Fehlende Spulenzuordnung für: {{slots}}",printerAdded:"Drucker hinzugefügt",printerUpdated:"Drucker aktualisiert",failedToDelete:"Drucker konnte nicht gelöscht werden",failedToAdd:"Drucker konnte nicht hinzugefügt werden",failedToUpdate:"Drucker konnte nicht aktualisiert werden",commandSent:"Befehl gesendet",failedToSendCommand:"Befehl konnte nicht gesendet werden",turnedOn:"{{name}} eingeschaltet",failedToPowerOn:"{{name}} konnte nicht eingeschaltet werden",scriptTriggered:"Skript ausgelöst",printStopped:"Druck gestoppt",printPaused:"Druck pausiert",printResumed:"Druck fortgesetzt",referenceDeleted:"Referenz gelöscht",detectionAreaSaved:"Erkennungsbereich gespeichert",failedToRunScript:"Skript konnte nicht ausgeführt werden",failedToStopPrint:"Druck konnte nicht gestoppt werden",failedToPausePrint:"Druck konnte nicht pausiert werden",failedToResumePrint:"Druck konnte nicht fortgesetzt werden",failedToControlChamberLight:"Kammerbeleuchtung konnte nicht gesteuert werden",failedToSetSpeed:"Druckgeschwindigkeit konnte nicht eingestellt werden",failedToUpdateSetting:"Einstellung konnte nicht aktualisiert werden",failedToSkipObjects:"Objekte konnten nicht übersprungen werden",failedToRereadRfid:"RFID konnte nicht erneut gelesen werden",failedToCheckPlate:"Platte konnte nicht überprüft werden",failedToUpdateLabel:"Bezeichnung konnte nicht aktualisiert werden",failedToDeleteReference:"Referenz konnte nicht gelöscht werden",failedToSaveDetectionArea:"Erkennungsbereich konnte nicht gespeichert werden",plateCheckEnabled:"Plattenprüfung aktiviert",plateCheckDisabled:"Plattenprüfung deaktiviert",calibrationSaved:"Kalibrierung gespeichert!",calibrationFailed:"Kalibrierung fehlgeschlagen",rfidRereadInitiated:"RFID-Neueinlesen gestartet",loadInitiated:"Filament wird geladen…",unloadInitiated:"Filament wird entladen…",failedToLoad:"Filament konnte nicht geladen werden",failedToUnload:"Filament konnte nicht entladen werden"},connection:{connected:"Verbunden",offline:"Offline"},plateStatus:{markCleared:"Platte als freigegeben markieren",cleared:"Platte freigegeben",notCleared:"Platte nicht freigegeben",inUse:"Platte in Benutzung"},queue:{inQueue:"{{count}} Druck in Warteschlange",inQueue_plural:"{{count}} Drucke in Warteschlange"},controls:"Steuerung",rfid:{reread:"RFID neu lesen"},ams:{load:"Laden",unload:"Entladen"},bedJog:{title:"Druckbett bewegen",bed:"Bett",step:"Schritt (mm)",up:"Platte hoch",down:"Platte runter",disabledWhilePrinting:"Während des Drucks deaktiviert",notHomedTitle:"Drucker ist nicht referenziert",notHomedMessage:"Der Drucker wurde seit dem letzten Druck nicht referenziert. Führen Sie zuerst die automatische Referenzfahrt aus (parkt den Werkzeugkopf und referenziert dann X, Y und Z) oder bewegen Sie trotzdem — die Software-Endschalter werden dabei umgangen.",homeZ:"Automatische Referenzfahrt",moveAnyway:"Trotzdem bewegen",homingStarted:"Drucker wird automatisch referenziert…"},permission:{noAdd:"Sie haben keine Berechtigung, Drucker hinzuzufügen",noEdit:"Sie haben keine Berechtigung, Drucker zu bearbeiten",noDelete:"Sie haben keine Berechtigung, Drucker zu löschen",noControl:"Sie haben keine Berechtigung, Drucker zu steuern",noFiles:"Sie haben keine Berechtigung, auf Druckerdateien zuzugreifen",noAmsRfid:"Sie haben keine Berechtigung, AMS-RFID erneut zu lesen",noSmartPlugControl:"Sie haben keine Berechtigung, Smart Plugs zu steuern",noCamera:"Sie haben keine Berechtigung, Kameras anzuzeigen"},modal:{addTitle:"Drucker hinzufügen",editTitle:"Drucker bearbeiten",myPrinter:"Mein Drucker",selectModel:"Modell auswählen...",locationGroup:"Standort / Gruppe (optional)",locationPlaceholder:"z.B. Werkstatt, Büro, Keller",autoArchiveLabel:"Abgeschlossene Drucke automatisch archivieren",fromPrinterSettings:"Aus Druckereinstellungen",modelOptional:"Modell (optional)",saveChanges:"Änderungen speichern"},skipObjects:{tooltip:"Objekte überspringen",onlyWhilePrinting:"Objekte überspringen (nur während des Drucks)",requiresMultiple:"Objekte überspringen (erfordert 2+ Objekte)",title:"Objekte überspringen",matchIdsInfo:"IDs mit Drucker-Display abgleichen",printerShowsIds:"Der Druckerbildschirm zeigt Objekt-IDs auf der Bauplatte",skipSelected:"Ausgewählte überspringen",skipping:"Überspringe...",noObjectsSelected:"Keine Objekte ausgewählt",selectObjectsToSkip:"Wählen Sie Objekte aus, die Sie vom aktuellen Druck überspringen möchten",skipped:"übersprungen",objectsSkipped:"Objekte übersprungen",activeCount:"{{count}} aktiv",waitForLayer:"Warten Sie auf Schicht 2+ zum Überspringen von Objekten (aktuell Schicht {{layer}})",skip:"Überspringen",confirmTitle:"Objekt überspringen?",confirmMessage:'Möchten Sie "{{name}}" wirklich überspringen? Dies kann nicht rückgängig gemacht werden.'},confirm:{deleteTitle:"Drucker löschen",deleteMessage:'Möchten Sie "{{name}}" wirklich löschen? Alle Verbindungseinstellungen werden entfernt.',deleteArchivesNote:"Der gesamte Druckverlauf für diesen Drucker wird dauerhaft gelöscht.",keepArchivesNote:"Der Druckverlauf wird beibehalten, aber nicht mehr mit diesem Drucker verknüpft.",stopTitle:"Druck stoppen",stopMessage:'Möchten Sie den aktuellen Druck auf "{{name}}" wirklich stoppen? Der Druckauftrag wird abgebrochen.',stopButton:"Druck stoppen",pauseTitle:"Druck pausieren",pauseMessage:'Möchten Sie den aktuellen Druck auf "{{name}}" wirklich pausieren?',pauseButton:"Druck pausieren",resumeTitle:"Druck fortsetzen",resumeMessage:'Möchten Sie den Druck auf "{{name}}" fortsetzen?',resumeButton:"Druck fortsetzen",powerOnTitle:"Drucker einschalten",powerOnMessage:'Möchten Sie die Stromversorgung für "{{name}}" wirklich EINSCHALTEN?',powerOnButton:"Einschalten",powerOffTitle:"Drucker ausschalten",powerOffMessage:'Möchten Sie die Stromversorgung für "{{name}}" wirklich AUSSCHALTEN?',powerOffWarning:'WARNUNG: "{{name}}" druckt gerade! Möchten Sie die Stromversorgung wirklich AUSSCHALTEN? Dies unterbricht den Druck und kann den Drucker beschädigen.',powerOffButton:"Ausschalten",haToggleTitle:'"{{name}}" umschalten',haToggleMessage:"Home-Assistant-Entität {{entity}} umschalten? Das kann die Stromversorgung ausschalten, falls sie gerade an ist.",haToggleWarning:'WARNUNG: "{{name}}" druckt gerade! Umschalten von {{entity}} kann die Stromversorgung trennen und den Druck abbrechen. Fortfahren?',haToggleButton:"Umschalten"},bulk:{select:"Auswählen",selectAll:"Alle auswählen",selectByLocation:"Nach Standort auswählen",selected:"{{count}} ausgewählt",actions:{stop:"Stoppen",pause:"Pausieren",resume:"Fortsetzen",clearPlate:"Druckbett leeren",clearHMS:"Benachrichtigungen löschen"},confirm:{stopTitle:"{{count}} Drucke stoppen",stopMessage:"Dies wird aktive Drucke auf {{count}} Drucker(n) abbrechen. Diese Aktion kann nicht rückgängig gemacht werden.",stopButton:"Alle stoppen",pauseTitle:"{{count}} Drucke pausieren",pauseMessage:"Dies wird aktive Drucke auf {{count}} Drucker(n) pausieren.",pauseButton:"Alle pausieren",clearPlateTitle:"{{count}} Druckbetten leeren",clearPlateMessage:"Dies wird das Druckbett auf {{count}} Drucker(n) leeren und kann wartende Aufträge starten.",clearPlateButton:"Alle leeren"},success:"{{action}} auf {{count}} Drucker(n) abgeschlossen",partial:"{{succeeded}} erfolgreich, {{failed}} fehlgeschlagen",noneApplicable:"Keine ausgewählten Drucker sind im richtigen Zustand für diese Aktion",selectByState:"Nach Status auswählen"},discovery:{title:"Drucker entdecken",searching:"Suche...",scanning:"Scanne...",scanProgress:"Scanne... {{scanned}}/{{total}}",foundPrinters:"{{count}} Drucker gefunden",noPrintersFound:"Keine Drucker gefunden",noPrintersFoundSubnet:"Keine Drucker im angegebenen Subnetz gefunden.",noPrintersFoundNetwork:"Keine Drucker im Netzwerk gefunden.",allConfigured:"Alle erkannten Drucker sind bereits konfiguriert.",alreadyAdded:"Bereits hinzugefügt",select:"Auswählen",manualEntry:"Manuelle Eingabe",addFromCloud:"Aus Cloud hinzufügen",subnetToScan:"Zu scannendes Subnetz",dockerNote:"Docker erkannt. Geben Sie das Subnetz Ihres Druckers in CIDR-Notation ein. Erfordert network_mode: host in docker-compose.yml.",scanSubnet:"Subnetz nach Druckern scannen",discoverNetwork:"Drucker im Netzwerk suchen",scanningSubnet:"Subnetz wird nach Bambu-Druckern gescannt...",scanningNetwork:"Netzwerk wird gescannt...",serialRequired:"Seriennummer erforderlich",unknown:"Unbekannt",failedToStart:"Erkennung konnte nicht gestartet werden"},drying:{start:"Trocknung starten",stop:"Trocknung stoppen",temperature:"Temperatur",duration:"Dauer",hours:"Stunden",timeRemaining:"{{time}} verbleibend",active:"Trocknung",notSupported:"Trocknung nicht unterstützt",powerRequired:"AMS-Netzteil anschließen, um Trocknung zu aktivieren",startingDrying:"Trocknung wird gestartet...",stoppingDrying:"Trocknung wird gestoppt...",rotateTray:"Spule während der Trocknung drehen"},filaments:"Filamente",openCameraOverlay:"Kamera-Overlay öffnen",openCameraWindow:"Kamera in neuem Fenster öffnen",firmwareUpdateAvailable:"Firmware-Update verfügbar: {{current}} → {{latest}}",firmwareUpToDate:"Firmware {{version}} — Aktuell",firmwareUpdateButton:"Aktualisieren",plateDetection:{noPermission:"Sie haben keine Berechtigung, Drucker zu aktualisieren",enabledClick:"Plattenprüfung aktiviert - Klicken zum Deaktivieren",disabledClick:"Plattenprüfung deaktiviert - Klicken zum Aktivieren",manageCalibration:"Platten-Erkennungskalibrierung verwalten",calibrationRequired:"Kalibrierung erforderlich",calibrationInstructions:"Bitte stellen Sie sicher, dass die Druckplatte vollständig leer ist, und klicken Sie dann auf Kalibrieren.",calibrationDescription:"Die Kalibrierung erfasst ein Referenzbild der leeren Platte. Zukünftige Prüfungen vergleichen mit dieser Referenz, um Objekte zu erkennen.",calibrationTip:"Tipp: Sie können bis zu 5 Kalibrierungen für verschiedene Platten speichern. Das System verwendet automatisch die beste Übereinstimmung bei der Prüfung.",plateEmpty:"Platte erscheint leer",objectsDetected:"Objekte auf Platte erkannt",confidence:"Konfidenz",difference:"Differenz",analysisPreview:"Analysevorschau:",analysisLegend:"Grüner Rahmen = Erkennungsbereich, Rote Überlagerung = Unterschiede zur Kalibrierung",savedReferences:"Gespeicherte Referenzen ({{count}}/{{max}})",deleteReference:"Referenz löschen",labelPlaceholder:"Bezeichnung...",clickToEdit:"{{label}} - Zum Bearbeiten klicken",clickToAddLabel:"Zum Hinzufügen einer Bezeichnung klicken"},speed:{title:"Druckgeschwindigkeit",silent:"Leise (50%)",standard:"Standard (100%)",sport:"Sport (124%)",ludicrous:"Ludicrous (166%)"},airduct:{title:"Luftkanal-Modus",cooling:"Kühlen",heating:"Heizen"},noSdCard:"Keine SD",door:{open:"Offen",closed:"Zu"},fans:{partCooling:"Bauteilkühlung",auxiliary:"Hilfsventilator",chamber:"Kammerventilator"},clickToViewHmsErrors:"Klicken, um HMS-Fehler anzuzeigen",estimatedCompletion:"Geschätzte Fertigstellungszeit",plateNumber:"Platte {{number}}",slotOptions:"Slot-Optionen",amsPopup:{friendlyName:"AMS-Name",friendlyNamePlaceholder:"z. B. AMS-Anzeigename",serialNumber:"Seriennummer",firmwareVersion:"Firmware",save:"Speichern",clear:"Löschen",noEditPermission:"Sie haben keine Berechtigung, AMS-Einheiten umzubenennen"},firmwareModal:{title:"Firmware-Update",titleUpToDate:"Firmware-Info",currentVersion:"Aktuell:",latestVersion:"Neueste:",releaseNotes:"Versionshinweise",checkingPrereqs:"Prüfe Voraussetzungen...",sdCardReady:"SD-Karte bereit. Klicken Sie unten, um die Firmware hochzuladen.",uploadedSuccess:"Firmware auf SD-Karte hochgeladen!",applyInstructions:"So wenden Sie das Update auf Ihrem Drucker an:",step1:"Gehen Sie auf dem Touchscreen des Druckers zu Einstellungen",step2:"Navigieren Sie zu Firmware",step3:"Wählen Sie Update von SD-Karte",step4:"Das Update dauert 10-20 Minuten",done:"Fertig",starting:"Starte...",uploadFirmware:"Firmware hochladen",uploadFailed:"Upload fehlgeschlagen: {{error}}",uploadedToast:"Firmware hochgeladen! Starten Sie das Update vom Druckerbildschirm.",availableVersions:"Verfügbare Versionen",usable:"Installierbar",unavailable:"Nicht verfügbar",installed:"Installiert",newerBadge:"neuer",olderBadge:"älter",currentBadge:"aktuell"},accessCodePlaceholder:"Leer lassen, um den aktuellen zu behalten",roi:{title:"Erkennungsbereich (ROI)",xStart:"X-Start",yStart:"Y-Start",width:"Breite",height:"Höhe",instruction:"Passen Sie den Erkennungsbereich an, um sich auf die Druckplatte zu konzentrieren. Der grüne Rahmen in der Vorschau zeigt den aktuellen Bereich."},developerModeWarning:"Der Entwickler-LAN-Modus ist nicht aktiviert auf: {{names}}. Einige Funktionen funktionieren möglicherweise nicht.",howToEnable:"Aktivieren",incompatibleFile:"Diese Datei wurde für {{slicedFor}} geslicet, aber dieser Drucker ist ein {{printerModel}}",dropNotPrintable:"Nur .gcode- und .gcode.3mf-Dateien können gedruckt werden",dropToPrint:"Zum Drucken ablegen",cannotPrint:"Drucker beschäftigt"},archives:{title:"Druckarchiv",searchPlaceholder:"Archiv durchsuchen...",filterByPrinter:"Nach Drucker filtern",filterByStatus:"Nach Status filtern",sortBy:"Sortieren nach",sortNewest:"Neueste zuerst",sortOldest:"Älteste zuerst",sortName:"Name",sortDuration:"Dauer",sortLargest:"Größte zuerst",sortSmallest:"Kleinste zuerst",sortSize:"Größe",noArchives:"Keine Archive gefunden",noArchivesSearch:"Keine Archive entsprechen Ihrer Suche",originalPrintNotVisible:"Ursprünglicher Druck nicht sichtbar - versuchen Sie, die Filter zu löschen",noArchivesYet:"Noch keine Archive",prints:"Drucke",pagination:{showing:"Zeige",to:"bis",of:"von",show:"Zeige",page:"Seite",all:"Alle"},loadingArchives:"Lade Archive...",releaseToUpload:"Loslassen zum Hochladen",showAll:"Alle anzeigen",showFavoritesOnly:"Nur Favoriten anzeigen",gridView:"Rasteransicht",listView:"Listenansicht",calendarView:"Kalenderansicht",logView:"Druckprotokoll",manageTags:"Tags verwalten",showFailedPrints:"Fehlgeschlagene Drucke anzeigen",hideFailedPrints:"Fehlgeschlagene Drucke ausblenden",hideDuplicates:"Duplikate ausblenden",viewOriginalPrint:"Klicken, um den ursprünglichen Druck anzuzeigen (#{{id}})",printTime:"Druckzeit",filamentUsed:"Verbrauchtes Filament",cost:"Kosten",reprint:"Drucken",preview:"Vorschau",deleteArchive:"Archiv löschen",deleteConfirm:"Möchten Sie dieses Archiv wirklich löschen?",favorite:"Favorit",unfavorite:"Aus Favoriten entfernen",viewDetails:"Details anzeigen",status:{completed:"Abgeschlossen",failed:"Fehlgeschlagen",stopped:"Gestoppt"},toast:{source3mfAttached:"Quell-3MF angehängt: {{filename}}",failedUploadSource3mf:"Fehler beim Hochladen der Quell-3MF",source3mfRemoved:"Quell-3MF entfernt",failedRemoveSource3mf:"Fehler beim Entfernen der Quell-3MF",f3dAttached:"F3D angehängt: {{filename}}",failedUploadF3d:"Fehler beim Hochladen der F3D",f3dRemoved:"F3D entfernt",failedRemoveF3d:"Fehler beim Entfernen der F3D",timelapseAttached:"Zeitraffer angehängt: {{filename}}",timelapseAlreadyAttached:"Zeitraffer bereits angehängt",noMatchingTimelapse:"Kein passender Zeitraffer gefunden",failedScanTimelapse:"Fehler beim Suchen nach Zeitraffer",failedAttachTimelapse:"Fehler beim Anhängen des Zeitraffers",timelapseRemoved:"Zeitraffer entfernt",failedRemoveTimelapse:"Fehler beim Entfernen des Zeitraffers",timelapseUploaded:"Zeitraffer hochgeladen: {{filename}}",failedUploadTimelapse:"Fehler beim Hochladen des Zeitraffers",archiveDeleted:"Archiv gelöscht",failedDeleteArchive:"Fehler beim Löschen des Archivs",addedToFavorites:"Zu Favoriten hinzugefügt",removedFromFavorites:"Aus Favoriten entfernt",projectUpdated:"Projekt aktualisiert",failedUpdateProject:"Fehler beim Aktualisieren des Projekts",linkCopied:"Link in die Zwischenablage kopiert",failedCopyLink:"Fehler beim Kopieren des Links",photoDeleted:"Foto gelöscht",failedDeletePhoto:"Fehler beim Löschen des Fotos",failedDeleteArchives:"Fehler beim Löschen der Archive",failedUpdateFavorites:"Fehler beim Aktualisieren der Favoriten",exportDownloaded:"Export heruntergeladen",exportFailed:"Export fehlgeschlagen"},menu:{print:"Drucken",schedule:"Planen",openInBambuStudio:"Im Slicer öffnen",slice:"Slicen",externalLink:"Externer Link",viewOnMakerWorld:"Auf MakerWorld ansehen",preview3d:"3D-Vorschau",viewTimelapse:"Zeitraffer ansehen",scanForTimelapse:"Nach Zeitraffer suchen",uploadTimelapse:"Zeitraffer hochladen",removeTimelapse:"Zeitraffer entfernen",downloadSource3mf:"Quell-3MF herunterladen",uploadSource3mf:"Quell-3MF hochladen",replaceSource3mf:"Quell-3MF ersetzen",removeSource3mf:"Quell-3MF entfernen",uploadF3d:"F3D hochladen",replaceF3d:"F3D ersetzen",downloadF3d:"F3D herunterladen",removeF3d:"F3D entfernen",download:"Herunterladen",copyDownloadLink:"Download-Link kopieren",qrCode:"QR-Code",viewPhotos:"Fotos ansehen",viewPhotosCount:"Fotos ansehen ({{count}})",projectPage:"Projektseite",addToFavorites:"Zu Favoriten hinzufügen",removeFromFavorites:"Aus Favoriten entfernen",edit:"Bearbeiten",printLog:"Druckprotokoll",goToProject:"Zum Projekt: {{name}}",addToProject:"Zu Projekt hinzufügen",removeFromProject:"Aus Projekt entfernen",loading:"Laden...",noProjectsAvailable:"Keine Projekte verfügbar",searchProjects:"Projekte suchen…",select:"Auswählen",deselect:"Abwählen",delete:"Löschen"},permission:{noReprint:"Sie haben keine Berechtigung, dieses Archiv erneut zu drucken",noAddToQueue:"Sie haben keine Berechtigung, zur Warteschlange hinzuzufügen",noUpdateArchives:"Sie haben keine Berechtigung, Archive zu aktualisieren",noUploadFiles:"Sie haben keine Berechtigung, Dateien hochzuladen",noDownload:"Sie haben keine Berechtigung, Archive herunterzuladen",noCopyLink:"Sie haben keine Berechtigung, Download-Links zu kopieren",noDelete:"Sie haben keine Berechtigung, dieses Archiv zu löschen",noCreate:"Sie haben keine Berechtigung, Archive zu erstellen"},platePicker:{title:"Platte zur Vorschau auswählen",hint:"Dieses Archiv enthält mehrere Platten. Wähle eine, um sie im GCode-Viewer zu öffnen.",plateLabel:"Platte {{index}}",objectCount:"{{count}} Objekt",objectCount_plural:"{{count}} Objekte",noGcode:"Dieses Archiv enthält keinen geschnittenen G-Code zur Vorschau. Öffne es zuerst in Bambu Studio zum Slicen."},card:{previousPlate:"Vorherige Platte",nextPlate:"Nächste Platte",plateNumber:"Platte {{index}}",moreOptions:"Rechtsklick für mehr Optionen",addToFavorites:"Zu Favoriten hinzufügen",removeFromFavorites:"Aus Favoriten entfernen",cancelled:"abgebrochen",failed:"fehlgeschlagen",duplicate:"Duplikat",duplicateTitle:"Dieses Modell wurde bereits zuvor gedruckt",openSource3mf:"Quell-3MF in Bambu Studio öffnen (Rechtsklick für mehr Optionen)",downloadF3d:"Fusion 360 Designdatei herunterladen",viewTimelapse:"Zeitraffer ansehen",viewPhoto:"1 Foto ansehen",viewPhotos:"{{count}} Fotos ansehen",openFolder:"Ordner öffnen: {{name}}",slicedFile:"Geslicte Datei - druckbereit",sourceFile:"Nur Quelldatei - keine AMS-Zuordnung verfügbar",gcode:"GCODE",source:"QUELLE",project:"Projekt: {{name}}",runsBadge:"{{count}} Drucke",runsBadgeTitle:"Insgesamt {{count}} Drucke — {{successful}} erfolgreich, {{failed}} fehlgeschlagen. Klicken, um das vollständige Druckprotokoll zu öffnen.",estimated:"Geschätzt: {{time}}",actual:"Tatsächlich: {{time}}",accuracy:"Genauigkeit: {{percent}}%",filament:"{{weight}} g",layer:"{{count}} Schicht",layers:"{{count}} Schichten",object:"{{count}} Objekt",objects:"{{count}} Objekte",slicedFor:"Geslict für {{model}}",uploadedBy:"Hochgeladen von",noPermissionReprint:"Sie haben keine Berechtigung, erneut zu drucken",noFileForReprint:"Keine 3MF-Datei verfügbar — die Datei konnte beim Aufzeichnen des Drucks nicht vom Drucker heruntergeladen werden",noPermissionEdit:"Sie haben keine Berechtigung, Archive zu bearbeiten",noPermissionDelete:"Sie haben keine Berechtigung, Archive zu löschen",reprint:"Drucken",schedulePrint:"Druck planen",schedule:"Planen",openInBambuStudio:"Im Slicer öffnen",openInBambuStudioToSlice:"Im Slicer öffnen zum Slicen",slice:"Slicen",externalLink:"Externer Link",makerWorld:"MakerWorld – {{designer}}",viewProject:"Projekt ansehen",noExternalLink:"Kein externer Link",preview3d:"3D-Vorschau",download:"Herunterladen",edit:"Bearbeiten",delete:"Löschen"},runLog:{title:"Druckprotokoll",modalTitle:"Druckprotokoll — {{name}}",modalTitleFallback:"dieses Archiv",empty:"Für dieses Archiv wurden noch keine Druckereignisse aufgezeichnet.",col:{date:"Datum",status:"Status",duration:"Dauer",filament:"Filament",cost:"Kosten"},status:{completed:"Abgeschlossen",failed:"Fehlgeschlagen",cancelled:"Abgebrochen",stopped:"Gestoppt",skipped:"Übersprungen",printing:"Druckt"}},modal:{deleteArchive:"Archiv löschen",deleteConfirm:'Möchten Sie "{{name}}" wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.',deleteButton:"Löschen",deletePurgeStats:"Diesen Druck auch aus den Quick Stats entfernen (Filament, Zeit, Kosten, Energie)",removeSource3mf:"Quell-3MF entfernen",removeSource3mfConfirm:'Möchten Sie die Quell-3MF-Datei wirklich von "{{name}}" entfernen? Die ursprüngliche Slicer-Projektdatei wird gelöscht.',removeButton:"Entfernen",removeF3d:"F3D entfernen",removeF3dConfirm:'Möchten Sie die Fusion 360 Designdatei wirklich von "{{name}}" entfernen?',removeTimelapse:"Zeitraffer entfernen",removeTimelapseConfirm:'Möchten Sie das Zeitraffervideo wirklich von "{{name}}" entfernen?',timelapse:"{{name}} - Zeitraffer",selectTimelapse:"Zeitraffer auswählen",selectTimelapseDesc:"Keine automatische Übereinstimmung gefunden. Wählen Sie den Zeitraffer für diesen Druck:",deleteArchives:"Archive löschen",deleteArchivesConfirm:"Möchten Sie wirklich {{count}} Archiv(e) löschen? Diese Aktion kann nicht rückgängig gemacht werden.",deleteCount:"{{count}} löschen"},page:{title:"Archive",printsCount:"{{filtered}} von {{total}} Drucken",dropFilesHere:".3mf-Dateien hier ablegen",releaseToUpload:"Loslassen zum Hochladen",only3mfSupported:"Nur .3mf-Dateien werden unterstützt",close:"Schließen",selected:"{{count}} ausgewählt",selectAll:"Alle auswählen",tags:"Tags",project:"Projekt",favorite:"Favorit",delete:"Löschen",toggledFavorites:"Favoriten für {{count}} Archiv(e) umgeschaltet",failedUpdateFavorites:"Fehler beim Aktualisieren der Favoriten",archivesDeleted:"{{count}} Archiv(e) gelöscht",failedDeleteArchives:"Fehler beim Löschen der Archive",photoDeleted:"Foto gelöscht",failedDeletePhoto:"Fehler beim Löschen des Fotos"},list:{name:"Name",printer:"Drucker",date:"Datum",size:"Größe",actions:"Aktionen",hasTimelapse:"Hat Zeitraffer"},log:{date:"Datum",printName:"Druckname",printer:"Drucker",user:"Benutzer",status:"Status",duration:"Dauer",filament:"Filament",allPrinters:"Alle Drucker",allUsers:"Alle Benutzer",allStatuses:"Alle Status",cancelled:"Abgebrochen",skipped:"Übersprungen",dateFrom:"Von",dateTo:"Bis",noEntries:"Keine Druckprotokolleinträge gefunden",showing:"{{count}} von {{total}} Einträgen",rowsPerPage:"Zeilen",page:"Seite",prev:"Zurück",next:"Weiter",clearLog:"Protokoll löschen",clearLogTitle:"Druckprotokoll löschen",clearLogConfirm:"Alle Druckprotokolleinträge werden dauerhaft gelöscht. Archive und Warteschlangeneinträge sind nicht betroffen. Diese Aktion kann nicht rückgängig gemacht werden. Sind Sie sicher?",clearLogButton:"Alle löschen",cleared:"{{count}} Protokolleinträge gelöscht",clearFailed:"Druckprotokoll konnte nicht gelöscht werden"}},queue:{title:"Druckwarteschlange",subtitle:"Planen und verwalten Sie Ihre Druckaufträge",addToQueue:"Zur Warteschlange hinzufügen",print:"Drucken",reprint:"Erneut drucken",schedulePrint:"Druck planen",editQueueItem:"Warteschlangeneintrag bearbeiten",printToPrinters:"Auf {{count}} Druckern drucken",queueToPrinters:"Zu {{count}} Druckern hinzufügen",queueSelectedPlates:"{{count}} Platten in die Warteschlange",selectAllPlates:"Alle {{count}} Platten auswählen",deselectAll:"Alle abwählen",printQueued:"Druck in Warteschlange",itemsQueued:"{{count}} Einträge in Warteschlange",sending:"Wird gesendet...",sendingProgress:"Sende {{current}}/{{total}}...",adding:"Wird hinzugefügt...",addingProgress:"Füge hinzu {{current}}/{{total}}...",savingProgress:"Speichere {{current}}/{{total}}...",clearQueue:"Warteschlange leeren",clearHistory:"Verlauf löschen",emptyQueue:"Warteschlange ist leer",position:"Position",scheduledTime:"Geplante Zeit",moveUp:"Nach oben",moveDown:"Nach unten",startNow:"Jetzt starten",printingInProgress:"Druck läuft...",viewArchive:"Archiv anzeigen",viewInFileManager:"Im Dateimanager anzeigen",itemCount:"{{count}} Element",itemCount_plural:"{{count}} Elemente",dragToReorder:"Ziehen zum Neuordnen (nur Sofort)",reorderHint:"Position betrifft nur Sofort-Elemente. Geplante Elemente werden zur festgelegten Zeit ausgeführt.",sjf:{label:"SJF",tooltip:"Kürzester Auftrag zuerst — Scheduler bevorzugt kürzere Drucke"},addedBy:"Hinzugefügt von {{name}}",nextInQueue:"Nächster in der Warteschlange",clearPlateSuccess:"Druckplatte freigegeben — bereit für nächsten Druck",plateNumber:"Platte {{index}}",quantity:"Menge",quantityHint:"Erstellt {{count}} Warteschlangeneinträge",activeBatches:"Aktive Stapel",batchProgress:"{{completed}} von {{total}} abgeschlossen",cancelBatch:"Verbleibende abbrechen",batchCancelled:"Verbleibende Stapeleinträge abgebrochen",cancelBatchConfirmTitle:"Stapel abbrechen",cancelBatchConfirmMessage:"Alle verbleibenden ausstehenden Einträge in diesem Stapel abbrechen?",batch:"Stapel",sections:{currentlyPrinting:"Aktuell druckend",queued:"In Warteschlange",history:"Verlauf"},status:{pending:"Ausstehend",waiting:"Wartend",printing:"Druckt",paused:"Pausiert",completed:"Abgeschlossen",failed:"Fehlgeschlagen",skipped:"Übersprungen",cancelled:"Abgebrochen"},summary:{printing:"Druckt",queued:"In Warteschlange",totalTime:"Gesamte Wartezeit",totalWeight:"Gesamtgewicht der Warteschlange",history:"Verlauf"},filter:{allPrinters:"Alle Drucker",unassigned:"Nicht zugewiesen",allStatus:"Alle Status",allLocations:"Alle Standorte",any:"Beliebig"},sort:{byPosition:"Nach Position sortieren",byName:"Nach Name sortieren",byPrinter:"Nach Drucker sortieren",bySchedule:"Nach Zeitplan sortieren",byDate:"Nach Datum sortieren",ascendingOldest:"Aufsteigend (älteste zuerst)",descendingNewest:"Absteigend (neueste zuerst)"},badges:{staged:"Bereitgestellt",requiresPrevious:"Erfordert vorherigen Erfolg",autoPowerOff:"Automatisch ausschalten",gcodeInjection:"G-Code"},empty:{title:"Keine Drucke geplant",description:'Planen Sie einen Druck von der Archivseite über die Option "Planen" im Kontextmenü oder ziehen Sie Dateien hierher.'},time:{asap:"Sofort",overdue:"Überfällig",now:"Jetzt",lessThanMinute:"In weniger als einer Minute",inMinutes:"In {{count}} Min",inHours:"In {{count}} Stunden"},actions:{stopPrint:"Druck stoppen",startPrint:"Druck starten",requeue:"Erneut einreihen"},bulkEdit:{title:"{{count}} Element bearbeiten",title_plural:"{{count}} Elemente bearbeiten",description:"Nur geänderte Einstellungen werden auf ausgewählte Elemente angewendet.",printer:"Drucker",noChange:"— Keine Änderung —",queueOptions:"Warteschlangenoptionen",staged:"Bereitgestellt (manueller Start)",autoPowerOff:"Nach Druck automatisch ausschalten",requirePrevious:"Vorherigen Erfolg erfordern",printOptions:"Druckoptionen",bedLevelling:"Bett-Nivellierung",flowCalibration:"Fluss-Kalibrierung",vibrationCalibration:"Vibrations-Kalibrierung",layerInspection:"Erste-Schicht-Prüfung",timelapse:"Zeitraffer",useAms:"AMS verwenden",applyChanges:"Änderungen übernehmen",selectAll:"Alle auswählen",deselectAll:"Auswahl aufheben",selected:"{{count}} ausgewählt",editSelected:"Ausgewählte bearbeiten",cancelSelected:"Ausgewählte abbrechen"},confirm:{cancelTitle:"Geplanten Druck abbrechen",cancelMessage:'Möchten Sie "{{name}}" wirklich abbrechen?',stopTitle:"Druck stoppen",stopMessage:'Möchten Sie den aktuellen Druck "{{name}}" wirklich stoppen? Der Druckauftrag wird am Drucker abgebrochen.',removeTitle:"Aus Verlauf entfernen",removeMessage:'Möchten Sie "{{name}}" wirklich aus dem Warteschlangenverlauf entfernen?',clearHistoryTitle:"Verlauf löschen",clearHistoryMessage:"Möchten Sie alle {{count}} Element(e) aus dem Verlauf entfernen?",cancelButton:"Druck abbrechen",stopButton:"Druck stoppen",thisPrint:"diesen Druck",thisItem:"dieses Element"},toast:{cancelled:"Warteschlangenelement abgebrochen",cancelFailed:"Element konnte nicht abgebrochen werden",removed:"Warteschlangenelement entfernt",removeFailed:"Element konnte nicht entfernt werden",stopped:"Druck gestoppt",stopFailed:"Druck konnte nicht gestoppt werden",released:"Druck in Warteschlange freigegeben",startFailed:"Druck konnte nicht gestartet werden",reorderFailed:"Warteschlange konnte nicht neu geordnet werden",historyCleared:"{{count}} Verlaufselement(e) gelöscht",clearHistoryFailed:"Verlauf konnte nicht gelöscht werden",updateFailed:"Elemente konnten nicht aktualisiert werden",bulkCancelled:"{{count}} Element(e) abgebrochen",bulkCancelFailed:"Elemente konnten nicht abgebrochen werden"},timeline:{listView:"Liste",timelineView:"Zeitstrahl",unassigned:"Nicht zugewiesen",noData:"Keine geplanten Drucke für diesen Tag",allDoneBy:"Alle Drucke voraussichtlich fertig um {{time}}",staged:"Bereitgestellt",filterAll:"Alle anzeigen",filterPrinting:"Druckend",filterQueued:"Warteschlange",time:{anyMoment:"jeden Moment",minutesLeft:"{{minutes}}m übrig",hoursLeft:"{{hours}}h übrig",hoursMinutesLeft:"{{hours}}h {{minutes}}m übrig"},day:{previous:"Vorheriger Tag",next:"Nächster Tag",today:"Heute"}},permissions:{noStopPrint:"Sie haben keine Berechtigung, Drucke zu stoppen",noStartPrint:"Sie haben keine Berechtigung, Drucke zu starten",noEdit:"Sie haben keine Berechtigung, dieses Warteschlangenelement zu bearbeiten",noCancel:"Sie haben keine Berechtigung, dieses Warteschlangenelement abzubrechen",noRequeue:"Sie haben keine Berechtigung, Elemente erneut einzureihen",noRemove:"Sie haben keine Berechtigung, dieses Warteschlangenelement zu entfernen",noClearHistory:"Sie haben keine Berechtigung, den gesamten Verlauf zu löschen",noEditItems:"Sie haben keine Berechtigung, Warteschlangenelemente zu bearbeiten",noCancelItems:"Sie haben keine Berechtigung, Warteschlangenelemente abzubrechen"}},backgroundDispatch:{unknownFile:"Unbekannte Datei",unknownPrinter:"Unbekannter Drucker",startingPrints:"Starte Drucke",progressSummary:"{{complete}}/{{total}} abgeschlossen • Geplant: {{dispatched}} • In Bearbeitung: {{processing}}",expandDetails:"Dispatch-Details ausklappen",collapseDetails:"Dispatch-Details einklappen",dismissToast:"Dispatch-Hinweis schließen",cancelDispatchJob:"Dispatch-Job abbrechen",cancel:"Abbrechen",cancelling:"Wird abgebrochen…",awaitingPrinter:"Warte auf Drucker…",status:{dispatched:"Geplant",processing:"In Bearbeitung",completed:"Abgeschlossen",failed:"Fehlgeschlagen",cancelled:"Abgebrochen"},toast:{cancellingUpload:"Upload wird abgebrochen...",cancelled:"Dispatch abgebrochen",cancelFailed:"Dispatch konnte nicht abgebrochen werden",completeWithFailures:"Background Dispatch abgeschlossen: {{completed}} erfolgreich, {{failed}} fehlgeschlagen",completeSuccess:"Background Dispatch abgeschlossen: {{completed}} erfolgreich",printStartedRemaining:"{{completed}} Druck(e) gestartet, {{remaining}} weitere werden gesendet..."}},stats:{title:"Statistiken",subtitle:"Widgets zum Neuanordnen ziehen. Auf das Augensymbol klicken zum Ausblenden.",overview:"Übersicht",totalPrints:"Gesamtdrucke",successRate:"Erfolgsrate",totalPrintTime:"Gesamtdruckzeit",printTime:"Druckzeit",totalFilament:"Gesamtverbrauch Filament",filamentUsed:"Filamentverbrauch",filamentCost:"Filamentkosten",totalCost:"Gesamtkosten",energyUsed:"Energieverbrauch",energyCost:"Energiekosten",energyWarmingUpTooltip:"Die Energieerfassung sammelt noch stündliche Snapshots. Zeitraumwerte werden genau, sobald vor dem gewählten Bereich mindestens ein Snapshot vorliegt. Frühe Werte können zu niedrig sein.",averagePrintTime:"Durchschnittliche Druckzeit",printsPerDay:"Drucke pro Tag",byPrinter:"Nach Drucker",printsByPrinter:"Drucke nach Drucker",byMaterial:"Nach Material",byMonth:"Nach Monat",last7Days:"Letzte 7 Tage",last30Days:"Letzte 30 Tage",last90Days:"Letzte 90 Tage",allTime:"Gesamt",quickStats:"Schnellstatistiken",printActivity:"Druckaktivität",filamentTypes:"Filamenttypen",filamentTrends:"Filamenttrends",failureAnalysis:"Fehleranalyse",timeAccuracy:"Zeitgenauigkeit",successful:"Erfolgreich:",failed:"Fehlgeschlagen:",perfectEstimate:"100% = perfekte Schätzung",noTimeAccuracyData:"Noch keine Zeitgenauigkeitsdaten",noFilamentData:"Keine Filamentdaten verfügbar",noPrinterData:"Keine Druckerdaten verfügbar",noPrintData:"Keine Druckdaten verfügbar",noPrintDataLast30Days:"Keine Druckdaten in den letzten 30 Tagen",failureReasons:"Fehlerursachen",topFailureReasons:"Häufigste Fehlerursachen",failedPrintsCount:"{{failed}} / {{total}} Drucke fehlgeschlagen",lastWeekRate:"Letzte Woche: {{rate}}%",resetLayout:"Layout zurücksetzen",recalculateCosts:"Kosten neu berechnen",recalculateCostsHint:"Alle Archivkosten mit aktuellen Filamentpreisen neu berechnen",exportStats:"Statistiken exportieren",exportAsCsv:"Als CSV exportieren",exportAsExcel:"Als Excel exportieren",hiddenCount:"{{count}} ausgeblendet",exportDownloaded:"Export heruntergeladen",exportFailed:"Export fehlgeschlagen",layoutReset:"Layout zurückgesetzt",recalculatedCosts:"Kosten für {{count}} Archive neu berechnet",recalculateFailed:"Kosten konnten nicht neu berechnet werden",loadingStats:"Statistiken werden geladen...",noPermissionResetLayout:"Sie haben keine Berechtigung, das Layout zurückzusetzen",noPermissionRecalculate:"Sie haben keine Berechtigung, Kosten neu zu berechnen",noPrintDataInRange:"Keine Druckdaten im ausgewählten Zeitraum",periodFilament:"Filamentverbrauch",periodCost:"Kosten",avgPerPrint:"Durchschnitt pro Druck",usageOverTime:"Verbrauch im Zeitverlauf",filamentByWeight:"Gewicht",printDuration:"Druckdauer",printerUtilization:"Druckerauslastung",filamentSuccess:"Erfolg nach Material",printHabits:"Druckgewohnheiten",printTimeOfDay:"Druck-Tageszeit",colorDistribution:"Farbverteilung",noColorData:"Keine Farbdaten verfügbar",records:"Rekorde",longestPrint:"Längster Druck",heaviestPrint:"Schwerster Druck",mostExpensivePrint:"Teuerster Druck",busiestDay:"Aktivster Tag",successStreak:"Erfolgsserie",streakPrint:"aufeinanderfolgender Druck",streakPrints:"{{count}} aufeinanderfolgende Drucke",printerStats:"Druckerstatistiken",hours:"Stunden",avgPrints:"Ø Drucke",noArchiveData:"Keine Druckdaten verfügbar",filamentByTime:"Zeitverlauf",avgWeight:"Ø Gewicht",avgTime:"Ø Zeit",filamentByPrints:"Drucke",timeframe:{today:"Heute","this-week":"Diese Woche","this-month":"Dieser Monat","last-7":"Letzte 7 Tage","last-30":"Letzte 30 Tage","last-90":"Letzte 90 Tage","this-year":"Dieses Jahr","all-time":"Gesamt",custom:"Benutzerdefiniert",from:"Von",to:"Bis"},allUsers:"Alle Benutzer",noUser:"Kein Benutzer (System)",filterByUser:"Nach Benutzer filtern"},maintenance:{title:"Wartung",overview:"Übersicht",allOk:"Alle Wartungen aktuell",dueCount:"{{count}} Aufgabe fällig",dueCount_plural:"{{count}} Aufgaben fällig",warningCount:"{{count}} Warnung",warningCount_plural:"{{count}} Warnungen",totalPrintTime:"Gesamtdruckzeit",nextMaintenance:"Nächste Wartung",nothingDue:"Nichts fällig",tasks:"Aufgaben",lastPerformed:"Zuletzt durchgeführt",interval:"Intervall",hoursRemaining:"{{hours}}h verbleibend",hoursOverdue:"{{hours}}h überfällig",markDone:"Als erledigt markieren",performMaintenance:"Wartung durchführen",history:"Verlauf",noHistory:"Kein Wartungsverlauf",editPrintHours:"Druckstunden bearbeiten",currentHours:"Aktuelle Stunden",statusTab:"Status",settingsTab:"Einstellungen",overdueCount:"{{count}} überfällig",dueSoonCount:"{{count}} bald fällig",dueSoon:"Bald fällig",allGood:"Alles in Ordnung",overdueBy:"Überfällig um {{duration}}",dueIn:"Fällig in {{duration}}",timeLeft:"{{duration}} verbleibend",day:"1 Tag",days:"{{count}} Tage",week:"1 Woche",weeks:"{{count}} Wochen",month:"1 Monat",months:"{{count}} Monate",year:"1 Jahr",maintenanceTypes:"Wartungstypen",maintenanceTypesDescription:"Systemtypen und Ihre benutzerdefinierten Wartungsaufgaben",addCustomType:"Benutzerdefinierten Typ hinzufügen",restoreDefaults:"Standardaufgaben wiederherstellen",intervalType:"Intervalltyp",intervalValue:"Intervall ({{type}})",icon:"Symbol",documentationLink:"Dokumentationslink (optional)",assignToPrinters:"Druckern zuweisen",selectAtLeastOnePrinter:"Wählen Sie mindestens einen Drucker",addType:"Typ hinzufügen",custom:"Benutzerdefiniert",printHours:"Druckstunden",calendarDays:"Kalendertage",exampleName:"z.B. HEPA-Filter ersetzen",viewDocumentation:"Dokumentation anzeigen",timeBasedInterval:"Zeitbasiertes Intervall",intervalOverrides:"Intervall-Überschreibungen",intervalOverridesDescription:"Intervalle für bestimmte Drucker anpassen",assignedToPrinters:"Druckern zugewiesen:",noPrintersAssigned:"Keine Drucker zugewiesen",addPrinterShort:"Hinzufügen:",printersAssignedClick:"{{count}} Drucker zugewiesen - klicken zum Verwalten",removeFromPrinter:"Von diesem Drucker entfernen",types:{lubricateCarbonRods:"Karbonstäbe schmieren",lubricateRails:"Linearschienen schmieren",cleanNozzle:"Düse/Hotend reinigen",checkBelts:"Riemenspannung prüfen",cleanBuildPlate:"Druckbett reinigen",checkExtruder:"Extruderzahnräder prüfen",checkCooling:"Kühlungslüfter prüfen",generalInspection:"Allgemeine Inspektion",cleanCarbonRods:"Kohlenstoffstangen reinigen",lubricateSteelRods:"Stahlstangen schmieren",cleanSteelRods:"Stahlstangen reinigen",cleanLinearRails:"Linearschienen reinigen",checkPtfeTube:"PTFE-Schlauch prüfen",replaceHepaFilter:"HEPA-Filter ersetzen",replaceCarbonFilter:"Aktivkohlefilter ersetzen",lubricateLeftNozzleRail:"Linke Düsenschiene schmieren"},maintenanceComplete:"Wartung als abgeschlossen markiert",typeUpdated:"Wartungstyp aktualisiert",typeDeleted:"Wartungstyp gelöscht",defaultsRestored:"{{count}} Standardaufgabe(n) wiederhergestellt",printHoursUpdated:"Druckstunden aktualisiert",printerAssigned:"Drucker zugewiesen",printerRemoved:"Drucker entfernt",deleteTypeConfirm:'"{{name}}" löschen?',deleteSystemTypeTitle:"Standard-Wartungsaufgabe löschen?",deleteSystemTypeMessage:'Möchten Sie die Standard-Wartungsaufgabe "{{name}}" wirklich löschen?',noPermissionUpdate:"Sie haben keine Berechtigung, Wartungselemente zu aktualisieren",noPermissionPerform:"Sie haben keine Berechtigung, Wartungen durchzuführen",noPermissionEditTypes:"Sie haben keine Berechtigung, Wartungstypen zu bearbeiten",noPermissionDeleteTypes:"Sie haben keine Berechtigung, Wartungstypen zu löschen",noPermissionEditHours:"Sie haben keine Berechtigung, Druckstunden zu bearbeiten",noPermissionRemovePrinter:"Sie haben keine Berechtigung, Druckerzuweisungen zu entfernen",noPermissionAssignPrinter:"Sie haben keine Berechtigung, Drucker zuzuweisen",noPermissionEditIntervals:"Sie haben keine Berechtigung, Intervalle zu bearbeiten",configureSettings:"Wartungstypen und Intervalle konfigurieren"},settings:{title:"Einstellungen",general:"Allgemein",tabs:{general:"Allgemein",smartPlugs:"Smart Plugs",notifications:"Benachrichtigungen",queue:"Workflow",filament:"Filament",network:"Netzwerk",apiKeys:"API-Schlüssel",virtualPrinter:"Virtueller Drucker",spoolbuddy:"SpoolBuddy",failureDetection:"Fehlererkennung",users:"Authentifizierung",backup:"Sicherung",emailAuth:"E-Mail-Authentifizierung",ldap:"LDAP",twoFa:"Zwei-Faktor-Auth",oidc:"SSO / OIDC",security:"Sicherheit"},spoolbuddy:{infoTitle:"SpoolBuddy-Geräte",infoBody:"SpoolBuddy-Kioske registrieren sich automatisch per Heartbeat. Ein Gerät hier abmelden, wenn es nicht mehr verwendet wird oder wenn ein veralteter Eintrag nach einem Daemon-Absturz übrig geblieben ist.",duplicatesTitle:"{{count}} Geräte registriert",duplicatesBody:"Die Kiosk-Oberfläche verwendet nur das zuerst registrierte Gerät. Falls eines davon ein veralteter Doppeleintrag nach einem Absturz ist, kann es hier entfernt werden — ein laufendes Gerät registriert sich beim nächsten Heartbeat automatisch neu.",empty:"Noch keine SpoolBuddy-Geräte registriert.",online:"Online",offline:"Offline",unregister:"Abmelden",unregisterSuccess:"Gerät abgemeldet",unregisterError:"Gerät konnte nicht abgemeldet werden",confirmTitle:"SpoolBuddy-Gerät abmelden?",confirmBody:'Dies entfernt „{{hostname}}" ({{deviceId}}) aus der Datenbank. Ein laufendes Gerät registriert sich beim nächsten Heartbeat automatisch neu.',ipAddress:"IP-Adresse",firmware:"Firmware",lastSeen:"Zuletzt gesehen",daemonUptime:"Daemon-Laufzeit",systemUptime:"System-Laufzeit",never:"nie",nfc:"NFC",scale:"Waage",cpuTemp:"CPU-Temp.",memory:"Speicher",disk:"Festplatte",update:"Aktualisieren",updateConfirmTitle:"Spoolbuddy-Daemon aktualisieren?",updateConfirmBody:'Software-Update auf „{{hostname}}" auslösen? Der Daemon startet nach dem Update neu.',restartBrowser:"Browser neu starten",restartBrowserConfirmTitle:"Kiosk-Browser neu starten?",restartBrowserConfirmBody:'Kiosk-Browser auf „{{hostname}}" neu starten? Die Anzeige wird kurz schwarz.',restartDaemon:"Daemon neu starten",restartDaemonConfirmTitle:"Spoolbuddy-Daemon neu starten?",restartDaemonConfirmBody:'Spoolbuddy-Daemon auf „{{hostname}}" neu starten? Das Gerät ist für einige Sekunden offline.',reboot:"Neustart",rebootConfirmTitle:"Gerät neu starten?",rebootConfirmBody:'„{{hostname}}" neu starten? Das Gerät ist für etwa eine Minute offline.',shutdown:"Herunterfahren",shutdownConfirmTitle:"Gerät herunterfahren?",shutdownConfirmBody:'„{{hostname}}" herunterfahren? Physischer Zugriff ist nötig, um es wieder einzuschalten.',commandConfirm:"Bestätigen",commandQueued:"Befehl eingereiht",commandError:"Befehl konnte nicht gesendet werden"},ldap:{title:"LDAP-Authentifizierung",enabledDesc:"LDAP-Authentifizierung ist aktiviert",disabledDesc:"LDAP-Authentifizierung ist deaktiviert",disabledHint:"LDAP-Einstellungen unten konfigurieren und speichern, dann aktivieren.",enabled:"LDAP-Authentifizierung aktiviert",disabled:"LDAP-Authentifizierung deaktiviert",feature1:"Benutzer können sich mit LDAP-Anmeldedaten anmelden",feature2:"Lokales Admin-Konto bleibt als Fallback erhalten",feature3:"LDAP-Gruppen werden bei der Anmeldung BamBuddy-Gruppen zugeordnet",serverConfig:"LDAP-Server-Konfiguration",serverUrl:"Server-URL",serverUrlHint:"Verwenden Sie ldap:// für Standard oder ldaps:// für SSL-Verbindungen",security:"Sicherheit",securityHint:"StartTLS aktualisiert eine einfache Verbindung auf TLS. LDAPS verwendet TLS von Anfang an.",bindDn:"Bind-DN (Dienstkonto)",bindPassword:"Bind-Passwort",searchBase:"Such-Basis-DN",userFilter:"Benutzer-Suchfilter",userFilterHint:"{username} wird durch den Anmeldenamen ersetzt. Verwenden Sie (uid={username}) für OpenLDAP.",advanced:"Erweitert",autoProvision:"Benutzer automatisch anlegen",autoProvisionHint:"Automatisch ein BamBuddy-Konto bei der ersten LDAP-Anmeldung erstellen",defaultGroup:"Standardgruppe",defaultGroupNone:"— Keine (kein Fallback) —",defaultGroupHint:"Fallback-Gruppe, die zugewiesen wird, wenn sich ein LDAP-Benutzer authentifiziert, aber in keiner zugeordneten LDAP-Gruppe enthalten ist. Leer lassen, um nicht zugeordnete Benutzer ohne Berechtigungen zu belassen.",groupMapping:"Gruppenzuordnung (JSON)",groupMappingHint:"LDAP-Gruppen-DNs BamBuddy-Gruppen zuordnen. Verfügbare Gruppen: ",testConnection:"Verbindung testen",settingsSaved:"LDAP-Einstellungen gespeichert",errors:{serverRequired:"LDAP-Server-URL ist erforderlich",searchBaseRequired:"Such-Basis-DN ist erforderlich",enableAuthFirst:"Authentifizierung zuerst aktivieren",configureLdapFirst:"LDAP-Einstellungen zuerst speichern"}},email:{smtpSettings:"SMTP-Konfiguration",smtpHost:"SMTP-Server",smtpPort:"SMTP-Port",security:"Sicherheit",authentication:"Authentifizierung",username:"Benutzername",password:"Passwort",fromEmail:"Absender-E-Mail",fromName:"Absendername",testConnection:"SMTP-Verbindung testen",testRecipient:"Test-Empfänger-E-Mail",sendTest:"Test-E-Mail senden",sending:"Wird gesendet...",save:"Einstellungen speichern",saving:"Wird gespeichert...",advancedAuth:"Erweiterte Authentifizierung",advancedAuthEnabled:"Erweiterte Authentifizierung ist aktiviert",advancedAuthEnabledDesc:"E-Mail-basierte Benutzerverwaltungsfunktionen sind aktiv. Neue Benutzer erhalten automatisch generierte Passwörter per E-Mail und können ihr Passwort über die Passwort vergessen Funktion zurücksetzen.",advancedAuthDisabled:"Erweiterte Authentifizierung ist deaktiviert",advancedAuthDisabledDesc:"Aktivieren Sie die erweiterte Authentifizierung, um E-Mail-basierte Funktionen für die Benutzerverwaltung zu aktivieren.",enable:"Aktivieren",disable:"Deaktivieren",feature1:"Passwörter werden automatisch generiert und an neue Benutzer gesendet",feature2:"Benutzer können sich mit Benutzername oder E-Mail anmelden",feature3:"Passwort vergessen Funktion ist verfügbar",feature4:"Administratoren können Benutzerpasswörter per E-Mail zurücksetzen",errors:{requiredFields:"Bitte füllen Sie alle Pflichtfelder aus",usernameRequired:"Benutzername ist erforderlich, wenn Authentifizierung aktiviert ist",enterTestEmail:"Bitte geben Sie eine Test-E-Mail-Adresse ein",smtpServerAndEmail:"Bitte füllen Sie SMTP-Server und Absender-E-Mail aus, bevor Sie testen",usernamePasswordRequired:"Benutzername und Passwort sind erforderlich, wenn Authentifizierung aktiviert ist",configureSmtpFirst:"Bitte konfigurieren und testen Sie zuerst die SMTP-Einstellungen",enableAuthFirst:"Bitte aktivieren Sie zuerst die Authentifizierung, um E-Mail-basierte Funktionen nutzen zu können."},success:{settingsSaved:"SMTP-Einstellungen erfolgreich gespeichert"},securityOptions:{starttls:"STARTTLS (Port 587)",ssl:"SSL/TLS (Port 465)",none:"Keine (Port 25)"},authOptions:{enabled:"Aktiviert",disabled:"Deaktiviert"}},appearance:"Erscheinungsbild",notifications:"Benachrichtigungen",smartPlugs:"Smart Plugs",spoolman:"Spoolman",updates:"Aktualisierungen",language:"Sprache",languageDescription:"Wählen Sie Ihre bevorzugte Sprache",theme:"Design",themeLight:"Hell",themeDark:"Dunkel",themeSystem:"System",defaultView:"Standardansicht",defaultViewDescription:"Seite, die beim Öffnen der App angezeigt wird",checkForUpdates:"Nach Updates suchen",autoUpdate:"Automatische Updates",currentVersion:"Aktuelle Version",latestVersion:"Neueste Version",upToDate:"Sie sind auf dem neuesten Stand",updateAvailable:"Update verfügbar",notificationLanguage:"Benachrichtigungssprache",notificationLanguageDescription:"Sprache für Push-Benachrichtigungen",bedCooledThreshold:"Bett-Abkühlung Schwellenwert",bedCooledThresholdDescription:"Temperatur, unter der das Bett nach einem Druck als abgekühlt gilt",userNotificationsEnabled:"Benutzerbenachrichtigungen",userNotificationsEnabledDescription:"Aktiviert das Benutzerbenachrichtigungsmenü und E-Mail-Benachrichtigungen für Druckereignisse. Erfordert Erweiterte Authentifizierung.",userNotificationsDisabledHint:"Erweiterte Authentifizierung aktivieren, um Benutzerbenachrichtigungen zu verwenden.",notificationProviders:"Benachrichtigungsanbieter",addProvider:"Anbieter hinzufügen",editProvider:"Anbieter bearbeiten",providerType:"Anbietertyp",testNotification:"Testbenachrichtigung",testSuccess:"Testbenachrichtigung erfolgreich gesendet",testFailed:"Testbenachrichtigung konnte nicht gesendet werden",quietHours:"Ruhezeiten",quietHoursDescription:"Keine Störungen während dieser Zeiten",quietHoursStart:"Beginn",quietHoursEnd:"Ende",events:{title:"Benachrichtigungsereignisse",printStart:"Druck gestartet",printComplete:"Druck abgeschlossen",printFailed:"Druck fehlgeschlagen",printStopped:"Druck gestoppt",printProgress:"Fortschrittsmeldungen",printProgressDescription:"Bei 25%, 50%, 75% benachrichtigen",printerOffline:"Drucker offline",printerError:"Druckerfehler",filamentLow:"Filament niedrig",maintenanceDue:"Wartung fällig",maintenanceDueDescription:"Benachrichtigen, wenn Wartung erforderlich"},smartPlug:{title:"Smart Plugs",add:"Smart Plug hinzufügen",edit:"Smart Plug bearbeiten",name:"Name",ipAddress:"IP-Adresse",linkedPrinter:"Verknüpfter Drucker",autoOn:"Automatisch einschalten",autoOnDescription:"Einschalten beim Druckstart",autoOff:"Automatisch ausschalten",autoOffDescription:"Ausschalten nach Druckende",offDelay:"Ausschaltverzögerung",offDelayMinutes:"Minuten nach Druck",offDelayTemp:"Wenn Düse unter Temperatur",currentState:"Aktueller Status",turnOn:"Einschalten",turnOff:"Ausschalten"},filamentTracking:"Filament-Verfolgung",filamentTrackingDesc:"Wählen Sie, wie Sie Ihre Filamentspulen verfolgen möchten. Sie können das integrierte Inventar oder einen externen Spoolman-Server verwenden.",filamentChecks:"Filament-Prüfungen",disableFilamentWarnings:"Filament-Warnungen deaktivieren",disableFilamentWarningsDesc:"Keine Warnungen über unzureichendes Filament beim Drucken oder Einreihen anzeigen",preferLowestFilament:"Niedrigsten Filamentrest bevorzugen",preferLowestFilamentDesc:"Bei mehreren passenden Spulen die mit dem geringsten Restfilament verwenden",trackingModeBuiltIn:"Integriertes Inventar",trackingModeBuiltInDesc:"RFID-Erkennung und Verbrauchserfassung inklusive",trackingModeSpoolmanDesc:"Externer Filament-Management-Server",builtInFeatureRfid:"Erkennt automatisch Bambu Lab RFID-Spulen im AMS",builtInFeatureUsage:"Erfasst den Filamentverbrauch pro Druck",builtInFeatureCatalog:"Spulen, Farben und K-Faktor-Profile verwalten",builtInFeatureThirdParty:"Drittanbieter-Spulen können Inventarspulen zugewiesen werden",amsSyncButton:"Gewichte vom AMS synchronisieren",amsSyncTitle:"Spulengewichte vom AMS synchronisieren",amsSyncMessage:"Alle Inventar-Spulengewichte werden mit den aktuellen AMS-Restwerten der verbundenen Drucker überschrieben. Verwenden Sie dies zur Wiederherstellung beschädigter Gewichtsdaten. Drucker müssen online sein.",amsSyncing:"Synchronisiere...",amsSyncSuccess:"{{synced}} Spule(n) synchronisiert, {{skipped}} übersprungen",amsSyncError:"Synchronisierung der Gewichte vom AMS fehlgeschlagen",spoolmanAmsSyncButton:"Spoolman-Gewichte vom AMS synchronisieren",spoolmanAmsSyncTitle:"Spoolman-Spulengewichte vom AMS synchronisieren",spoolmanAmsSyncMessage:"Dabei werden alle Spoolman-Spulengewichte anhand der aktuellen AMS-Füllstandswerte der verbundenen Drucker aktualisiert. Die Drucker müssen online sein.",spoolmanAmsSyncing:"Synchronisiere...",spoolmanAmsSyncSuccess:"{{synced}} Spule(n) synchronisiert, {{skipped}} übersprungen",spoolmanAmsSyncError:"Synchronisierung der Spoolman-Gewichte vom AMS fehlgeschlagen",spoolmanAmsSyncErrorUnreachable:"Synchronisierung fehlgeschlagen (Spoolman nicht erreichbar)",spoolmanAmsSyncErrorNotConfigured:"Synchronisierung fehlgeschlagen (Spoolman nicht konfiguriert)",spoolmanNotConfigured:"Spoolman nicht konfiguriert",spoolmanFilamentCatalogTitle:"Spoolman-Filamentkatalog",spoolmanFilamentCatalogDesc:"Filamentnamen und Leergewichte aus deiner Spoolman-Instanz. Name und Spulengewicht sind hier editierbar; alle anderen Eigenschaften werden direkt in Spoolman verwaltet.",spoolmanUrl:"Spoolman URL",spoolmanUrlHint:"URL Ihres Spoolman-Servers (z.B. http://localhost:7912)",spoolmanConnected:"Verbunden",spoolmanDisconnected:"Nicht verbunden",status:"Status",connect:"Verbinden",disconnect:"Trennen",howSyncWorks:"So funktioniert die Synchronisierung",syncInfoRfidOnly:"Nur offizielle Bambu Lab Spulen mit RFID werden synchronisiert",syncInfoAutoCreate:"Neue Spulen werden bei der ersten Synchronisierung automatisch in Spoolman erstellt",syncInfoThirdPartySkipped:"Nicht-Bambu-Lab-Spulen (Drittanbieter, nachgefüllt) werden übersprungen",linkingExistingSpools:"Vorhandene Spulen verknüpfen",linkingExistingSpoolsDesc:'Um vorhandene Spoolman-Spulen mit Ihrem AMS zu verknüpfen, fahren Sie über einen AMS-Slot und klicken Sie auf "Mit Spoolman verknüpfen".',syncMode:"Synchronisierungsmodus",syncModeAuto:"Automatisch",syncModeManual:"Nur manuell",syncModeAutoDesc:"AMS-Daten werden automatisch synchronisiert, wenn Änderungen erkannt werden",syncModeManualDesc:"Nur bei manueller Auslösung synchronisieren",syncAmsData:"AMS-Daten synchronisieren",syncAmsDataDesc:"AMS-Daten des Druckers manuell mit Spoolman synchronisieren",allPrinters:"Alle Drucker",noDefaultPrinter:"Kein Standard (jedes Mal fragen)",sidebarOrder:"Seitenleisten-Reihenfolge",saveThumbnails:"Vorschaubilder speichern",captureFinishPhoto:"Abschlussfoto aufnehmen",noPrintersConfigured:"Keine Drucker konfiguriert",archiveMode:{always:"Immer Archiveintrag erstellen",never:"Nie Archiveintrag erstellen",ask:"Jedes Mal fragen"},checkForUpdatesLabel:"Nach Updates suchen",checkPrinterFirmware:"Drucker-Firmware prüfen",includeBetaUpdates:"Beta-Versionen einschließen",includeBetaUpdatesDesc:"Über Beta- und Vorabversionen bei der Updateprüfung benachrichtigen",enableRetry:"Wiederholung aktivieren",homeAssistantDescription:"Smart Plugs über Home Assistant steuern",environmentManagedLabel:"(Umgebungsvariable)",autoEnabledViaEnv:"Automatisch über Umgebungsvariablen aktiviert",urlFromEnvReadOnly:"Wert wird über HA_URL Umgebungsvariable gesetzt (schreibgeschützt)",tokenFromEnvReadOnly:"Wert wird über HA_TOKEN Umgebungsvariable gesetzt (schreibgeschützt)",mqttConnectedTo:"Verbunden mit",prometheusDescription:"Druckerdaten im Prometheus-Format bereitstellen",noSmartPlugsTitle:"Keine Smart Plugs konfiguriert",noSmartPlugsDescription:"Fügen Sie einen Tasmota-basierten Smart Plug hinzu, um den Energieverbrauch zu verfolgen und die Stromsteuerung zu automatisieren.",noProvidersTitle:"Keine Anbieter konfiguriert",noProvidersDescription:"Fügen Sie einen Anbieter hinzu, um Benachrichtigungen zu erhalten.",noTemplatesAvailable:"Keine Vorlagen verfügbar. Starten Sie das Backend neu, um Standardvorlagen zu laden.",apiPermissionView:"Druckerstatus und Warteschlange anzeigen",apiPermissionEdit:"Elemente zur Druckwarteschlange hinzufügen und entfernen",apiKeysEmptyTitle:"Keine API-Schlüssel",apiKeysEmptyDescription:"Erstellen Sie einen API-Schlüssel zur Integration mit externen Diensten.",noUsersFound:"Keine Benutzer gefunden",noGroupsFound:"Keine Gruppen gefunden",noGroupsAvailable:"Keine Gruppen verfügbar",passwordsDoNotMatch:"Passwörter stimmen nicht überein",systemGroupWarning:"System-Gruppennamen können nicht geändert werden",authDisabledTitle:"Authentifizierung ist deaktiviert",authDisabledFeature1:"Anmeldung zum Zugriff auf das System erforderlich",authDisabledFeature2:"Mehrere Benutzer mit gruppenbasierten Berechtigungen erstellen",authDisabledFeature3:"Zugriff mit über 50 granularen Berechtigungen steuern",userHasCreated:"Dieser Benutzer hat erstellt:",userItemsQuestion:"Was möchten Sie mit diesen Elementen tun?",deleteUserConfirm:"Möchten Sie diesen Benutzer wirklich löschen?",actionCannotBeUndone:"Diese Aktion kann nicht rückgängig gemacht werden.",addFirstSmartPlug:"Ersten Smart Plug hinzufügen",providers:"Anbieter",log:"Protokoll",testAll:"Alle testen",testResults:"Testergebnisse",testPassedCount:"{{count}} bestanden",testFailedCount:"{{count}} fehlgeschlagen",messageTemplates:"Nachrichtenvorlagen",messageTemplatesDescription:"Passen Sie Benachrichtigungen für jedes Ereignis an.",apiKeys:"API-Schlüssel",apiKeysDescription:"Erstellen Sie API-Schlüssel für externe Integrationen und Webhooks.",createKey:"Schlüssel erstellen",apiKeyCreated:"API-Schlüssel erfolgreich erstellt",apiKeyCopyWarning:"Kopieren Sie diesen Schlüssel jetzt - er wird nicht mehr angezeigt!",useInApiBrowser:"Im API-Browser verwenden",createNewApiKey:"Neuen API-Schlüssel erstellen",keyName:"Schlüsselname",keyNamePlaceholder:"z.B. Home Assistant, OctoPrint",readStatus:"Status lesen",readStatusDescription:"Druckerstatus und Warteschlange anzeigen",manageQueue:"Warteschlange verwalten",manageQueueDescription:"Elemente zur Druckwarteschlange hinzufügen und entfernen",controlPrinter:"Drucker steuern",controlPrinterDescription:"Drucke pausieren, fortsetzen und stoppen",cloudAccess:"Cloud-Zugriff erlauben",cloudAccessDescription:"Liest Bambu-Cloud-Presets und -Filamente in Ihrem Namen. Erfordert eine Anmeldung in Bambu Cloud.",cloudBadge:"Cloud",updateEnergyCost:"Strompreis aktualisieren",updateEnergyCostDescription:"Erlaubt diesem Schlüssel, einen neuen Strompreis pro kWh an /settings/electricity-price zu senden. Nützlich für Home-Assistant-Automatisierungen mit dynamischen Tarifen (Tibber, Octopus usw.). Dies ist das einzige Einstellungsfeld, das per API-Schlüssel schreibbar ist.",energyCostBadge:"Energie",legacyKey:"Alt",legacyKeyTooltip:"Wurde vor der nutzerbezogenen Eigentümerschaft erstellt; neu erstellen, um Cloud-Zugriff zu nutzen",unnamedKey:"Unbenannter Schlüssel",lastUsed:"Zuletzt verwendet",read:"Lesen",control:"Steuern",createFirstKey:"Ersten Schlüssel erstellen",webhookEndpoints:"Webhook-Endpunkte",webhookApiKeyHint:"Verwenden Sie Ihren API-Schlüssel im X-API-Key-Header.",webhook:{getAllStatus:"Alle Druckerstatus abrufen",getSpecificStatus:"Spezifischen Druckerstatus abrufen",addToQueue:"Zur Druckwarteschlange hinzufügen",pausePrint:"Druck pausieren",resumePrint:"Druck fortsetzen",stopPrint:"Druck stoppen"},apiBrowser:"API-Browser",apiBrowserDescription:"Erkunden und testen Sie alle verfügbaren API-Endpunkte.",apiKeyForTesting:"API-Schlüssel zum Testen",apiKeyPlaceholder:"Fügen Sie hier Ihren API-Schlüssel ein, um authentifizierte Endpunkte zu testen...",apiKeyHint:"Dieser Schlüssel wird als X-API-Key-Header mit Anfragen gesendet.",deleteApiKeyTitle:"API-Schlüssel löschen",deleteApiKeyMessage:"Möchten Sie diesen API-Schlüssel wirklich löschen? Alle Integrationen, die diesen Schlüssel verwenden, funktionieren nicht mehr.",deleteKey:"Schlüssel löschen",amsDisplayThresholds:"AMS-Anzeigeschwellenwerte",amsThresholdsDescription:"Konfigurieren Sie Farbschwellenwerte für AMS-Feuchtigkeits- und Temperaturanzeigen.",humidity:"Luftfeuchtigkeit",goodGreen:"Gut (grün)",fairOrange:"Mittel (orange)",aboveFairBad:"Über dem mittleren Schwellenwert wird rot angezeigt (schlecht)",fairAlsoDryingThreshold:"Dieser Schwellenwert wird auch für die automatische Trocknung verwendet",temperature:"Temperatur",goodBlue:"Gut (blau)",aboveFairHot:"Über dem mittleren Schwellenwert wird rot angezeigt (heiß)",historyRetention:"Verlaufsaufbewahrung",keepSensorHistory:"Sensorverlauf behalten für",historyRetentionDescription:"Ältere Feuchtigkeits- und Temperaturdaten werden automatisch gelöscht",defaultPrintOptions:"Standard-Druckoptionen",defaultPrintOptionsDescription:"Standardwerte für Druckoptionen bei neuen Drucken festlegen. Diese können im Druckdialog pro Druck überschrieben werden.",defaultBedLevelling:"Bett-Nivellierung",defaultBedLevellingDesc:"Bett vor dem Druck automatisch nivellieren",defaultFlowCali:"Fluss-Kalibrierung",defaultFlowCaliDesc:"Extrusionsfluss kalibrieren",defaultVibrationCali:"Vibrationskalibrierung",defaultVibrationCaliDesc:"Ringing-Artefakte reduzieren",defaultLayerInspect:"Erste-Schicht-Inspektion",defaultLayerInspectDesc:"KI-Inspektion der ersten Schicht",defaultTimelapse:"Zeitraffer",defaultTimelapseDesc:"Zeitraffervideo aufnehmen",staggeredStart:"Versetzter Start",staggeredStartDescription:"Standard-Gruppengröße und -Intervall beim Staffeln von Mehrdrucker-Batchstarts. Pro Batch im Druck-Dialog überschreibbar.",plateClear:"Druckplatte-Bestätigung",requirePlateClear:"Druckplatte-Bestätigung erforderlich",requirePlateClearDescription:'Wenn aktiviert, wartet der Scheduler auf eine Druckplatten-Bestätigung pro Drucker, bevor geplante Drucke auf Druckern mit abgeschlossenen Aufträgen gestartet werden. Wenn dies deaktiviert ist, werden auch das Druckplatten-Status-Badge und die Schaltfläche "Druckplatte als freigegeben markieren" auf den Druckerkarten ausgeblendet.',gcodeInjection:"G-Code-Injektion",gcodeInjectionDescription:'Konfigurieren Sie benutzerdefinierten G-code, der am Anfang und/oder Ende von Drucken für Auto-Print-Systeme wie Farmloop, SwapMod, AutoClear und Printflow 3D eingefügt wird. Snippets werden pro Druckermodell konfiguriert und angewendet, wenn "G-code einfügen" bei einem Warteschlangen-Element aktiviert ist.',gcodeInjectionNoPrinters:"Keine Drucker gefunden. Fügen Sie Drucker hinzu, um G-code-Snippets zu konfigurieren.",gcodeStartLabel:"Start-G-Code",gcodeEndLabel:"End-G-Code",gcodeStartPlaceholder:"G-code, der vor dem Druckstart eingefügt wird...",gcodeEndPlaceholder:"G-code, der nach dem Druckende angefügt wird...",staggerGroupSize:"Gruppengröße",staggerGroupSizeHelp:"Anzahl gleichzeitig zu startender Drucker pro Gruppe",staggerInterval:"Intervall (Minuten)",staggerIntervalHelp:"Verzögerung zwischen Gruppenstart",queueDrying:"Automatische Trocknung",queueDryingDescription:"AMS-Filament automatisch trocknen, wenn der Drucker zwischen Warteschlangen-Drucken im Leerlauf ist. Verwendet den Feuchtigkeitsschwellenwert oben.",queueDryingEnabled:"Automatische Trocknung aktivieren",queueDryingEnabledDescription:"AMS-Trocknung automatisch starten, wenn der Drucker im Leerlauf ist und die Feuchtigkeit über dem Schwellenwert liegt",queueDryingBlock:"Auf Trocknung warten",queueDryingBlockDescription:"Druckwarteschlange blockieren, bis die Trocknung abgeschlossen ist. Wenn aus, haben Drucke Vorrang.",ambientDryingEnabled:"Umgebungstrocknung",ambientDryingEnabledDescription:"Filament auf inaktiven Druckern automatisch trocknen, wenn die Luftfeuchtigkeit den Schwellenwert überschreitet — auch ohne Warteschlange.",dryingPresets:"Trocknungsvoreinstellungen",dryingPresetsDescription:"Temperatur und Dauer pro Filamenttyp. AMS 2 Pro verwendet niedrigere Temperaturen, AMS-HT unterstützt höhere.",dryingFilament:"Filament",printModal:"Druckdialog",expandCustomMapping:"Benutzerdefinierte Zuordnung standardmäßig erweitern",expandCustomMappingDescription:"Bei Druck auf mehrere Drucker die AMS-Zuordnung pro Drucker erweitert anzeigen",authentication:"Authentifizierung",authEnabledDescription:"Ihre Instanz ist mit Benutzerauthentifizierung gesichert",authDisabledDescription:"Aktivieren Sie die Anmeldepflicht und verwalten Sie den Benutzerzugriff",authDisabledMessage:"Aktivieren Sie die Authentifizierung, um Benutzerkonten zu erstellen, Berechtigungen zu verwalten und Ihre Bambuddy-Instanz zu sichern.",enableAuthentication:"Authentifizierung aktivieren",currentUser:"Aktueller Benutzer",changePassword:"Passwort ändern",admin:"Admin",users:"Benutzer",addUser:"Benutzer hinzufügen",groups:"Gruppen",addGroup:"Gruppe hinzufügen",system:"System",noDescription:"Keine Beschreibung",userCount:"{{count}} Benutzer",permissionCount:"{{count}} Berechtigungen",createUser:"Benutzer erstellen",username:"Benutzername",enterUsername:"Benutzername eingeben",password:"Passwort",enterPassword:"Passwort eingeben",passwordRequirements:"Mindestens 8 Zeichen, davon ein Großbuchstabe, ein Kleinbuchstabe, eine Ziffer und ein Sonderzeichen.",confirmPassword:"Passwort bestätigen",confirmPasswordPlaceholder:"Passwort bestätigen",viewReleaseOnGitHub:"Release auf GitHub anzeigen",turnAllPlugsOn:"Alle Stecker einschalten",turnAllPlugsOff:"Alle Stecker ausschalten",clearNotificationLogs:"Benachrichtigungsprotokolle löschen",clearLogsMessage:"Dadurch werden alle Benachrichtigungsprotokolle, die älter als 30 Tage sind, dauerhaft gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.",clearLogs:"Protokolle löschen",resetUiPreferences:"UI-Einstellungen zurücksetzen",resetUiPreferencesMessage:"Dadurch werden alle UI-Einstellungen auf Standardwerte zurückgesetzt: Seitenleisten-Reihenfolge, Theme, Dashboard-Layout, Ansichtsmodi und Sortiereinstellungen. Ihre Drucker, Archive und Servereinstellungen werden NICHT beeinträchtigt. Die Seite wird nach dem Löschen neu geladen.",resetPreferences:"Einstellungen zurücksetzen",deleteGroupTitle:"Gruppe löschen",deleteGroupMessage:"Möchten Sie diese Gruppe wirklich löschen? Benutzer in dieser Gruppe verlieren diese Berechtigungen.",deleteGroup:"Gruppe löschen",disableAuthenticationTitle:"Authentifizierung deaktivieren",disableAuthenticationMessage:"Möchten Sie die Authentifizierung wirklich deaktivieren? Dadurch wird Ihre Bambuddy-Instanz ohne Anmeldung zugänglich. Alle Benutzer bleiben in der Datenbank, aber die Authentifizierung wird deaktiviert.",disableAuthentication:"Authentifizierung deaktivieren",configureBambuddy:"Bambuddy konfigurieren",systemDefault:"Systemstandard",archiveSettings:"Archiv-Einstellungen",newWindow:"Neues Fenster",embeddedOverlay:"Eingebettetes Overlay",preferredSlicer:"Bevorzugter Slicer",preferredSlicerDescription:"Wähle die Slicer-Anwendung zum Öffnen von Dateien",orcaslicerKnownIssuesWarning:"OrcaSlicer 2.3.2 / 2.4.0-dev haben bekannte CLI-Bugs, die das Slicen vieler von BambuStudio erstellter 3MF-Dateien blockieren — siehe Upstream-Issues #12426 (Segfault bei bemalten Multi-Extruder-Dateien) und #13386 (zu strikte Parameter-Range-Validierung). Bis die Upstream-Fixes verfügbar sind, wird Bambu Studio empfohlen.",useSlicerApi:"Slicer-API verwenden",useSlicerApiDescription:'Wenn aktiv, öffnen "Slice"-Aktionen das in-App Slicer-Modal und rufen den Slicer-API-Sidecar. Aus (Standard): Übergabe an den Desktop-Slicer per URI-Schema.',slicerCard:"Slicer",orcaslicerApiUrl:"OrcaSlicer Sidecar-URL",bambuStudioApiUrl:"Bambu Studio Sidecar-URL",slicerApiUrlDescription:"URL des Slicer-API-Sidecar-Containers. Leer lassen, um die SLICER_API_URL- bzw. BAMBU_STUDIO_API_URL-Umgebungsvariablen zu nutzen.",slicerBundles:{title:"Slicer-Bundles",description:'Importiere ein Drucker-Voreinstellungspaket (.bbscfg), das aus BambuStudio exportiert wurde (Datei → Exportieren → Voreinstellungspaket exportieren → "Drucker-Voreinstellungspaket"). Nach dem Import können Slice-Anfragen Voreinstellungen aus dem Bundle per Name auswählen, ohne das JSON-Profil-Trio erneut hochzuladen.',uploadButton:"Bundle hochladen",uploading:"Hochladen…",loading:"Bundles werden geladen…",empty:"Noch keine Bundles importiert.",summary:"{{processCount}} Prozess · {{filamentCount}} Filament-Voreinstellungen",delete:"Löschen",uploadSuccess:"{{name}} importiert",uploadError:"Bundle-Upload fehlgeschlagen: {{message}}",deleteSuccess:"Bundle entfernt",deleteError:"Löschen des Bundles fehlgeschlagen: {{message}}",confirmDeleteTitle:"Dieses Bundle entfernen?",confirmDeleteMessage:'Slice-Anfragen, die "{{name}}" referenzieren, schlagen fehl, bis das Bundle erneut importiert wird.'},externalCameras:"Externe Kameras",costTracking:"Kostenverfolgung",printsOnly:"Nur Drucke",totalConsumption:"Gesamtverbrauch",dataManagement:"Datenverwaltung",storageUsage:"Speichernutzung",storageUsageDescription:"Aufschlüsselung der Datennutzung nach Kategorie",storageUsageTotal:"Gesamt",storageUsageErrors:"Fehler",storageUsageOtherBreakdown:"Sonstiges (enthält statische Assets, Skripte und Konfigurationsdateien)",storageUsageSystem:"System",storageUsageData:"Daten",storageUsageUnavailable:"Speichernutzungsinformationen nicht verfügbar",clearNotificationLogsDescription:"Benachrichtigungsprotokolle älter als 30 Tage löschen",resetUiPreferencesDescription:"Seitenleisten-Reihenfolge, Theme, Ansichtsmodi und Layout-Einstellungen zurücksetzen. Drucker, Archive und Einstellungen werden nicht beeinflusst.",enableHomeAssistant:"Home Assistant aktivieren",enableMqtt:"MQTT aktivieren",useTls:"TLS verwenden",enableMetricsEndpoint:"Metrik-Endpunkt aktivieren",availableMetrics:"Verfügbare Metriken",editUser:"Benutzer bearbeiten",deleteUserTitle:"Benutzer löschen",groupName:"Gruppenname",leaveEmptyForAnonymous:"Leer lassen für anonym",leaveEmptyForNoAuth:"Leer lassen für keine Authentifizierung",enterNewPassword:"Neues Passwort eingeben",confirmNewPassword:"Neues Passwort bestätigen",enterGroupName:"Gruppenname eingeben",enterDescriptionOptional:"Beschreibung eingeben (optional)",enterCurrentPassword:"Aktuelles Passwort eingeben",enterNewPasswordMin6:"Neues Passwort eingeben (min. 6 Zeichen)",toast:{keyCopied:"Schlüssel in Zwischenablage kopiert",copyFailed:"Schlüssel konnte nicht kopiert werden",keyAddedToBrowser:"Schlüssel zum API-Browser hinzugefügt",clearLogsFailed:"Protokolle konnten nicht gelöscht werden",uiPreferencesReset:"UI-Einstellungen zurückgesetzt. Wird neu geladen...",authDisabled:"Authentifizierung erfolgreich deaktiviert",authDisableFailed:"Authentifizierung konnte nicht deaktiviert werden",apiKeyCreated:"API-Schlüssel erstellt",apiKeyDeleted:"API-Schlüssel gelöscht",userCreated:"Benutzer erfolgreich erstellt",userUpdated:"Benutzer erfolgreich aktualisiert",userDeleted:"Benutzer erfolgreich gelöscht",groupCreated:"Gruppe erfolgreich erstellt",groupUpdated:"Gruppe erfolgreich aktualisiert",groupDeleted:"Gruppe erfolgreich gelöscht",fillRequiredFields:"Bitte füllen Sie alle erforderlichen Felder aus",passwordsDoNotMatch:"Passwörter stimmen nicht überein",passwordTooShort:"Passwort muss mindestens 8 Zeichen lang sein",passwordNeedsUppercase:"Passwort muss mindestens einen Großbuchstaben enthalten",passwordNeedsLowercase:"Passwort muss mindestens einen Kleinbuchstaben enthalten",passwordNeedsDigit:"Passwort muss mindestens eine Ziffer enthalten",passwordNeedsSpecial:"Passwort muss mindestens ein Sonderzeichen enthalten",enterGroupName:"Bitte geben Sie einen Gruppennamen ein",settingsSaved:"Einstellungen gespeichert",noPermissionUpdate:"Sie haben keine Berechtigung, Einstellungen zu ändern",cameraSettingsSaved:"Kamera-Einstellungen gespeichert",enterCameraUrl:"Bitte geben Sie eine Kamera-URL ein",passwordChanged:"Passwort erfolgreich geändert",connectionFailed:"Verbindung fehlgeschlagen",testFailed:"Test fehlgeschlagen",cameraConnected:"Kamera verbunden{{resolution}}"},testConnection:"Verbindung testen",catalog:{spoolCatalog:"Spulenkatalog",spoolCatalogDescription:"Leerspulengewichte nach Marke/Typ. Wird für die automatische Gewichtssuche beim Hinzufügen von Spulen verwendet.",searchCatalog:"Katalog durchsuchen...",addNewEntry:"Neuen Eintrag hinzufügen",namePlaceholder:"Name (z.B. Bambu Lab - Plastik)",weight:"Gewicht",type:"Typ",default:"Standard",custom:"Benutzerdefiniert",noMatch:"Keine Einträge entsprechen Ihrer Suche",empty:"Keine Einträge im Katalog",deleteEntry:"Eintrag löschen",deleteConfirm:'Möchten Sie "{{name}}" wirklich löschen?',resetCatalog:"Katalog zurücksetzen",resetConfirm:"Katalog auf Standardwerte zurücksetzen? Alle benutzerdefinierten Einträge werden entfernt.",loadFailed:"Spulenkatalog konnte nicht geladen werden",nameWeightRequired:"Name und Gewicht sind erforderlich",entryAdded:"Eintrag hinzugefügt",addFailed:"Eintrag konnte nicht hinzugefügt werden",entryUpdated:"Eintrag aktualisiert",updateFailed:"Eintrag konnte nicht aktualisiert werden",entryDeleted:"Eintrag gelöscht",deleteFailed:"Eintrag konnte nicht gelöscht werden",resetSuccess:"Katalog auf Standardwerte zurückgesetzt",resetFailed:"Katalog konnte nicht zurückgesetzt werden",exported:"{{count}} Einträge exportiert",imported:"{{added}} Einträge importiert ({{skipped}} übersprungen)",importFailed:"Import fehlgeschlagen: ungültiges JSON-Format",exportTooltip:"Katalog als JSON exportieren",importTooltip:"Katalog aus JSON importieren",resetTooltip:"Auf Standardwerte zurücksetzen",selectedCount:"{{count}} ausgewählt",deleteSelected:"Ausgewählte löschen",bulkDeleteConfirm:"Möchten Sie {{count}} Einträge wirklich löschen?",bulkDeleted:"{{count}} Einträge gelöscht",bulkDeleteFailed:"Fehler beim Löschen der Einträge",material:"Material",spoolWeight:"Spulengewicht",color:"Farbe",updateSpoolWeight:"Spulengewicht aktualisieren",filamentUpdated:"Filament aktualisiert",filamentUpdateFailed:"Filament konnte nicht aktualisiert werden",filamentUpdateInvalid:"Ungültige Filamentdaten",keepExistingSpoolWeight:"Altes Gewicht für bestehende Spulen behalten",keepExistingSpoolWeightDesc:"Bereits erstellte Spulen dieses Filamenttyps behalten das alte Leergewicht. Neue Spulen nutzen den neuen Wert.",applyToAllSpools:"Auf alle Spulen anwenden",applyToAllSpoolsDesc:"Alle Gewichtsberechnungen für diesen Filamenttyp nutzen sofort das neue Leergewicht."},colorCatalog:{title:"Farbkatalog",description:"Filamentfarben nach Hersteller/Material. Wird für die automatische Farbsuche beim Hinzufügen von Spulen verwendet.",searchColors:"Farben durchsuchen...",allManufacturers:"Alle Hersteller",addNewColor:"Neue Farbe hinzufügen",manufacturer:"Hersteller",colorName:"Farbname",hex:"Hex",materialOptional:"Material (optional)",showing:"{{filtered}} von {{total}} Farben angezeigt",noMatch:"Keine Farben entsprechen Ihrer Suche",empty:"Keine Farben im Katalog",deleteColor:"Farbe löschen",deleteConfirm:'Möchten Sie "{{name}}" wirklich löschen?',resetCatalog:"Farbkatalog zurücksetzen",resetConfirm:"Katalog auf Standardwerte zurücksetzen? Alle benutzerdefinierten Farben werden entfernt.",sync:"Synchron.",starting:"Starten...",syncTooltip:"Von FilamentColors.xyz synchronisieren (2000+ Farben)",loadFailed:"Farbkatalog konnte nicht geladen werden",fieldsRequired:"Hersteller, Farbname und Hex-Farbe sind erforderlich",colorAdded:"Farbe hinzugefügt",addFailed:"Farbe konnte nicht hinzugefügt werden",colorUpdated:"Farbe aktualisiert",updateFailed:"Farbe konnte nicht aktualisiert werden",colorDeleted:"Farbe gelöscht",deleteFailed:"Farbe konnte nicht gelöscht werden",resetSuccess:"Farbkatalog auf Standardwerte zurückgesetzt",resetFailed:"Katalog konnte nicht zurückgesetzt werden",syncUpToDate:"Bereits aktuell ({{count}} Farben geprüft)",syncComplete:"{{added}} neue Farben hinzugefügt ({{skipped}} bereits vorhanden)",syncError:"Sync-Fehler",syncFailed:"Synchronisierung von FilamentColors.xyz fehlgeschlagen",exported:"{{count}} Farben exportiert",imported:"{{added}} Farben importiert ({{skipped}} übersprungen)",importFailed:"Import fehlgeschlagen: ungültiges JSON-Format",selectedCount:"{{count}} ausgewählt",deleteSelected:"Ausgewählte löschen",bulkDeleteConfirm:"Möchten Sie {{count}} Farben wirklich löschen?",bulkDeleted:"{{count}} Farben gelöscht",bulkDeleteFailed:"Fehler beim Löschen der Farben"},dateFormat:"Datumsformat",dateFormatUs:"US (MM/TT/JJJJ)",dateFormatEu:"EU (TT/MM/JJJJ)",dateFormatIso:"ISO (JJJJ-MM-TT)",timeFormat:"Zeitformat",timeFormat12:"12-Stunden (3:30 PM)",timeFormat24:"24-Stunden (15:30)",defaultPrinter:"Standarddrucker",defaultPrinterDescription:"Diesen Drucker für Uploads, Nachdrucke und andere Vorgänge vorauswählen.",slicerBambuStudio:"Bambu Studio",slicerOrcaSlicer:"OrcaSlicer",sidebarOrderDescription:"Elemente in der Seitenleiste per Drag & Drop neu anordnen. Hier auf Standardreihenfolge zurücksetzen.",setDefault:"Standard setzen",sidebarOrderSetDefaultHint:"Standard setzen übernimmt die aktuelle Menüreihenfolge für Benutzer, die ihre noch nicht angepasst haben.",sidebarDefaultSet:"Standard-Menüreihenfolge wurde festgelegt.",sidebarDefaultCleared:"Standard-Menüreihenfolge gelöscht.",sidebarDefaultFailed:"Festlegen der Standard-Menüreihenfolge fehlgeschlagen.",reset:"Zurücksetzen",darkMode:"Dunkelmodus",lightMode:"Hellmodus",active:"(aktiv)",background:"Hintergrund",accent:"Akzent",style:"Stil",bgNeutral:"Neutral",bgWarm:"Warm",bgCool:"Kühl",bgOled:"OLED Schwarz",bgSlate:"Schieferblau",bgForest:"Waldgrün",accentGreen:"Grün",accentTeal:"Türkis",accentBlue:"Blau",accentOrange:"Orange",accentPurple:"Lila",accentRed:"Rot",styleClassic:"Klassisch",styleGlow:"Leuchtend",styleVibrant:"Lebendig",themeToggleHint:"Zwischen Hell- und Dunkelmodus mit dem Sonnen-/Mondsymbol in der Seitenleiste wechseln.",autoArchivePrints:"Drucke automatisch archivieren",autoArchiveDescription:"3MF-Dateien automatisch speichern, wenn Drucke abgeschlossen sind",saveThumbnailsDescription:"Vorschaubilder aus 3MF-Dateien extrahieren und speichern",captureFinishPhotoDescription:"Foto von der Druckerkamera aufnehmen, wenn der Druck abgeschlossen ist",ffmpegNotInstalled:"ffmpeg nicht installiert",ffmpegRequired:"Kameraaufnahme benötigt ffmpeg. Installieren über brew install ffmpeg (macOS) oder apt install ffmpeg (Linux).",camera:"Kamera",cameraViewMode:"Kamera-Ansichtsmodus",cameraOverlayDescription:"Kamera öffnet sich als größenveränderbares Overlay auf dem Hauptbildschirm",cameraWindowDescription:"Kamera öffnet sich in einem separaten Browserfenster",externalCamerasDescription:"Externe Kameras konfigurieren, um die eingebaute Druckerkamera zu ersetzen. Unterstützt MJPEG-Streams, RTSP, HTTP-Snapshots und USB-Kameras (V4L2). Wenn aktiviert, wird die externe Kamera für Live-Ansicht und Abschlussfotos verwendet.",cameraPlaceholderUsb:"Gerätepfad (/dev/video0)",cameraPlaceholderUrl:"Kamera-URL (rtsp://... oder http://...)",cameraTypeMjpeg:"MJPEG-Stream",cameraTypeRtsp:"RTSP-Stream",cameraTypeSnapshot:"HTTP-Snapshot",cameraTypeUsb:"USB-Kamera (V4L2)",cameraSnapshotUrl:"Snapshot-URL (optional)",cameraSnapshotUrlPlaceholder:"http://192.168.1.61:1984/api/frame.jpeg?src=printer",cameraSnapshotUrlHelp:"URL für Einzelbildaufnahmen — wird für Benachrichtigungs-Vorschaubilder, Abschlussfotos, Schicht-Zeitraffer und Plattenerkennung verwendet. Zeitraffer und Plattenerkennung benötigen jeweils eigene drucker-spezifische Schalter — diese URL ist nur die Bildquelle, die sie verwenden, wenn sie aktiv sind. Leer lassen, um Bilder aus dem oben konfigurierten Live-Stream zu verwenden. Nützlich für go2rtc (/api/frame.jpeg) und IP-Kameras mit dediziertem Snapshot-Endpunkt.",cameraRotation:"Drehung",test:"Testen",connected:"Verbunden",disconnected:"Getrennt",currency:"Währung",defaultFilamentCost:"Standard-Filamentkosten (pro kg)",electricityCost:"Stromkosten pro kWh",energyDisplayMode:"Energieanzeige-Modus",energyModePrintDescription:"Dashboard zeigt Summe der während Drucken verbrauchten Energie",energyModeTotalDescription:"Dashboard zeigt Gesamtenergie der Smart Plugs",fileManager:"Dateimanager",createArchiveEntry:"Archiveintrag beim Drucken erstellen",createArchiveEntryDescription:"Beim Drucken aus dem Dateimanager optional einen Archiveintrag erstellen",lowDiskSpaceWarning:"Warnung bei wenig Speicherplatz",lowDiskSpaceDescription:"Warnung anzeigen, wenn freier Speicherplatz unter diesen Schwellenwert fällt",printerFirmware:"Drucker-Firmware",checkFirmwareDescription:"Nach Firmware-Updates von Bambu Lab suchen",bambuddySoftware:"Bambuddy-Software",autoCheckDescription:"Automatisch beim Start nach neuen Versionen suchen",checkNow:"Jetzt prüfen",updateAvailableVersion:"Update verfügbar: v{{version}}",releaseNotes:"Versionshinweise",updateViaDocker:"Update über Docker Compose:",updateViaHomeAssistant:"Updates werden vom Home Assistant Supervisor verwaltet. Öffne Einstellungen → Add-ons → Bambuddy in Home Assistant, um die neue Version zu installieren.",installUpdate:"Update installieren",latestVersionRunning:"Sie verwenden die neueste Version",failedToCheckUpdates:"Update-Prüfung fehlgeschlagen: {{error}}",backupRestore:"Sicherung & Wiederherstellung",backupRestoreDescription:"Einstellungen exportieren/importieren und GitHub-Backup konfigurieren",goToBackup:"Zur Sicherung",externalUrl:"Externe URL",externalUrlDescription:"Die externe URL, unter der Bambuddy erreichbar ist. Wird für Benachrichtigungsbilder und externe Integrationen verwendet.",bambuddyUrl:"Bambuddy-URL",externalUrlHint:"Protokoll und Port angeben (z.B. http://192.168.1.100:8000)",ftpRetry:"FTP-Wiederholung",ftpRetryDescription:"FTP-Operationen bei unzuverlässigem Drucker-WLAN wiederholen. Gilt für 3MF-Downloads, Druck-Uploads, Zeitraffer-Downloads und Firmware-Updates.",autoRetryDescription:"Fehlgeschlagene FTP-Operationen automatisch wiederholen",retryAttempts:"Wiederholungsversuche",retryDelay:"Wiederholungsverzögerung",connectionTimeout:"Verbindungs-Timeout",time_one:"{{count}} Mal",time_other:"{{count}} Mal",second_one:"{{count}} Sekunde",second_other:"{{count}} Sekunden",nSeconds:"{{count}} Sekunden",increaseForWeakWifi:"Erhöhen für Drucker mit schwachem WLAN",homeAssistant:"Home Assistant",homeAssistantFullDescription:"Mit Home Assistant verbinden, um Smart Plugs über die HA REST-API zu steuern. Unterstützt Switch-, Light-, Input_Boolean- und Script-Entitäten.",homeAssistantUrl:"Home Assistant URL",longLivedAccessToken:"Langlebiges Zugriffstoken",haTokenHint:"Token in HA erstellen: Profil → Langlebige Zugriffstoken → Token erstellen",connectionSuccessful:"Verbindung erfolgreich",connectionFailed:"Verbindung fehlgeschlagen",haConnectionSuccess:"Erfolgreich mit Home Assistant verbunden.",haConnectionFailed:"Verbindung zu Home Assistant fehlgeschlagen.",mqttPublishing:"MQTT-Veröffentlichung",mqttDescription:"BamBuddy-Ereignisse an einen externen MQTT-Broker zur Integration mit Node-RED, Home Assistant und anderen Automatisierungssystemen veröffentlichen.",mqttEnableDescription:"Ereignisse an externen MQTT-Broker veröffentlichen",brokerHostname:"Broker-Hostname",port:"Port",usernameOptional:"Benutzername (optional)",passwordOptional:"Passwort (optional)",topicPrefix:"Topic-Präfix",topicPrefixHint:"Topics werden sein: {{prefix}}/printers//status, etc.",prometheusMetrics:"Prometheus-Metriken",prometheusEndpointDescription:"Druckermetriken unter /api/v1/metrics für Prometheus/Grafana-Überwachung bereitstellen.",bearerTokenOptional:"Bearer-Token (optional)",bearerTokenHint:"Wenn gesetzt, müssen Anfragen Authorization: Bearer enthalten",metricsConnectionStatus:"Verbindungsstatus",metricsPrinterState:"Druckerstatus (idle/printing/etc)",metricsPrintProgress:"Druckfortschritt 0-100%",metricsBedTemp:"Betttemperatur",metricsNozzleTemp:"Düsentemperatur",metricsPrintsTotal:"Gesamtdrucke nach Ergebnis",metricsMore:"...und mehr (Schichten, Lüfter, Warteschlange, Filamentverbrauch)",smartPlugsDescription:"Smart Plugs (Tasmota oder Home Assistant) verbinden, um Stromsteuerung zu automatisieren und Energieverbrauch für Ihre Drucker zu verfolgen.",allOn:"Alle Ein",allOff:"Alle Aus",addSmartPlug:"Smart Plug hinzufügen",energySummary:"Energieübersicht",currentPower:"Aktuelle Leistung",plugsOnline:"{{reachable}}/{{total}} Plugs online",today:"Heute",yesterday:"Gestern",total:"Gesamt",enablePlugsForSummary:"Plugs aktivieren, um Energieübersicht zu sehen",addNotificationProvider:"Hinzufügen",systemBadge:"(System)",creating:"Erstellen...",changing:"Ändern...",deleteUserAndItems:"Benutzer UND dessen Elemente löschen",deleteUserKeepItems:"Benutzer löschen, Elemente behalten (werden herrenlos)",ok:"OK",twoFa:{totpTitle:"Authenticator-App (TOTP)",totpDesc:"Verwende eine Authenticator-App wie Google Authenticator, Aegis oder Authy.",emailOtpTitle:"E-Mail OTP",emailOtpDesc:"Sende einen Einmalcode an {{email}} beim Einloggen.",emailOtpNoEmail:"Füge eine E-Mail-Adresse zu deinem Konto hinzu, um diese Methode zu aktivieren.",addEmailFirst:"Dein Konto hat keine E-Mail-Adresse. Bitte einen Administrator, eine hinzuzufügen.",setupTotp:"Authenticator-App einrichten",setupAuthApp:"Authenticator-App einrichten",setupInstructions:"Scanne den QR-Code mit deiner Authenticator-App und bestätige mit einem Code.",manualEntry:"Kein Scanner? Gib dieses Secret manuell ein:",scannedContinue:"Code gescannt — weiter",enterCodeToConfirm:"Gib den 6-stelligen Code aus deiner Authenticator-App ein, um die Einrichtung zu bestätigen.",activate:"Aktivieren",disableTotp:"Authenticator deaktivieren",disableConfirmHint:"Gib einen gültigen TOTP-Code oder einen Backup-Code ein, um den Authenticator zu deaktivieren.",totpDisabled:"Authenticator-App deaktiviert.",emailOtpEnabled:"E-Mail OTP aktiviert.",emailOtpDisabled:"E-Mail OTP deaktiviert.",smtpRequired:"Bitte konfigurieren und testen Sie zuerst die SMTP-Einstellungen.",invalidCode:"Ungültiger Code. Bitte erneut versuchen.",enableEmailOtp:"E-Mail OTP aktivieren",disableEmailOtp:"E-Mail OTP deaktivieren",emailSetupEnterCode:"Ein Bestätigungscode wurde an Ihre E-Mail-Adresse gesendet. Geben Sie ihn unten ein, um zu bestätigen, dass Ihnen dieses Postfach gehört.",verifyAndEnable:"Verifizieren & Aktivieren",emailDisablePasswordHint:"Geben Sie Ihr Kontopasswort ein, um die Deaktivierung des E-Mail OTP zu bestätigen.",passwordPlaceholder:"Passwort eingeben",backupCodesTitle:"Backup-Codes sichern",backupCodesWarning:"Speichere diese Codes sicher. Jeder Code kann nur einmal verwendet werden und wird nicht erneut angezeigt.",backupCodesRemaining:"{{count}} Backup-Codes verbleibend",savedCodes:"Codes gespeichert",regenBackup:"Backup-Codes neu generieren",regenBackupHint:"Gib deinen aktuellen TOTP-Code ein, um 10 neue Backup-Codes zu generieren. Alle bestehenden Codes werden ungültig.",newBackupCodes:"Neue Backup-Codes",linkedAccounts:"Verknüpfte SSO-Konten",linkedAccountsDesc:"Diese externen Identitätsanbieter sind mit deinem Konto verknüpft.",oidcUnlinked:"Konto getrennt."},oidc:{title:"SSO / OIDC-Anbieter",desc:"Konfiguriere OpenID Connect-Anbieter für Single Sign-On.",addProvider:"Anbieter hinzufügen",newProvider:"Neuer Anbieter",empty:"Noch keine OIDC-Anbieter konfiguriert.",created:"Anbieter erstellt.",updated:"Anbieter aktualisiert.",deleted:"Anbieter gelöscht.",refreshIcon:"Icon neu laden",removeIcon:"Icon entfernen",iconRefreshed:"Icon aktualisiert.",iconRemoved:"Icon entfernt.",iconFetchFailed:"Icon konnte von der Anbieter-URL nicht geladen werden.",deleteTitle:"Anbieter löschen",deleteMessage:'"{{name}}" löschen? Alle verknüpften Benutzerkonten werden getrennt.',form:{name:"Anzeigename",issuerUrl:"Aussteller-URL",clientId:"Client-ID",clientSecret:"Client-Secret",scopes:"Bereiche",iconUrl:"Symbol-URL (optional)",enabled:"Aktiviert",autoCreate:"Benutzer automatisch anlegen",autoCreateDesc:"Erstellt beim ersten Login automatisch ein lokales Konto.",autoLink:"Bestehende Konten automatisch verknüpfen",autoLinkDesc:"Verknüpft beim ersten Login vorhandene lokale Konten anhand der E-Mail-Adresse.",secretHint:"leer lassen zum Beibehalten",secretPlaceholder:"neues Secret",emailClaim:"E-Mail-Claim",emailClaimDesc:"JWT-Claim für die E-Mail-Identität. Für Azure Entra ID 'preferred_username' oder 'upn' verwenden (sendet kein email_verified). Nur vertrauenswürdige Claim-Namen verwenden.",emailClaimPlaceholder:"E-Mail",emailClaimCustomClaimAutoLinkWarning:"Benutzerdefinierte Claims sind für die Auto-Verknüpfung nur sicher, wenn der Wert vom Mandanten verwaltet wird (z. B. Azure Entra ID upn / preferred_username). Aktiviere Auto-Verknüpfung nicht, wenn dein IdP Benutzern erlaubt, diesen Claim selbst zu setzen.",requireEmailVerified:"E-Mail-Verifizierung erforderlich",requireEmailVerifiedDesc:"E-Mail-Claim nur akzeptieren, wenn der Provider ihn als verifiziert markiert.",requireEmailVerifiedWarning:"Warnung: E-Mail wird auch ohne Verifizierung akzeptiert. Nur bei vertrauenswürdigen Providern verwenden.",requireEmailVerifiedAutoLink:"Auto-Verknüpfung zuerst deaktivieren, um diese Einstellung zu ändern.",defaultGroup:"Standardgruppe",defaultGroupDesc:"Gruppe, der automatisch erstellte Benutzer zugewiesen werden. Fallback auf Viewers, wenn nicht gesetzt.",defaultGroupViewersFallback:"Viewers (Standard)"}},encryption:{title:"MFA-Verschlüsselungsstatus",enabledFromEnv:"At-Rest-Verschlüsselung aktiv (Schlüssel aus Umgebungsvariable MFA_ENCRYPTION_KEY)",enabledFromFile:"At-Rest-Verschlüsselung aktiv (Schlüssel aus dem Datenverzeichnis geladen)",enabledGenerated:"At-Rest-Verschlüsselung aktiv mit automatisch generiertem Schlüssel",notConfigured:"At-Rest-Verschlüsselung nicht konfiguriert",notConfiguredDesc:"TOTP-Geheimnisse und OIDC-Client-Secrets werden im Klartext gespeichert. Setze MFA_ENCRYPTION_KEY oder starte Bambuddy mit beschreibbarem Datenverzeichnis neu, damit ein Schlüssel automatisch erzeugt wird.",allEncrypted:"Alle MFA-Geheimnisse sind verschlüsselt gespeichert.",legacyRowsLabel:"Klartext-Zeilen (Altbestand)",encryptedRowsLabel:"Verschlüsselte Zeilen",legacyRowsWarning:"{{count}} Klartext-Zeile(n) erkannt. Den OIDC-Provider neu speichern oder den Authenticator des Benutzers neu einrichten, um die Daten verschlüsselt abzulegen.",backupHint:"Der automatisch erzeugte Schlüssel liegt unter DATA_DIR/.mfa_encryption_key und wird in lokalen Backup-ZIPs mitgesichert. Backups sicher aufbewahren oder MFA_ENCRYPTION_KEY explizit setzen.",decryptionBrokenTitle:"Verschlüsselungsschlüssel fehlt",decryptionBrokenError:"{{count}} verschlüsselte Datensätze können nicht entschlüsselt werden, weil der Schlüssel nicht mehr verfügbar ist. Den vorherigen MFA_ENCRYPTION_KEY oder DATA_DIR/.mfa_encryption_key wiederherstellen.",migrationErrorWarning:"{{count}} Legacy-Eintrag/Einträge konnten beim Start nicht verschlüsselt werden. Prüfen Sie die Server-Logs und starten Sie Bambuddy neu."}},notification:{printStarted:{title:"Druck gestartet",body:"{{printer}}: {{filename}} wird gedruckt"},printCompleted:{title:"Druck abgeschlossen",body:"{{printer}}: {{filename}} erfolgreich abgeschlossen"},printFailed:{title:"Druck fehlgeschlagen",body:"{{printer}}: {{filename}} ist fehlgeschlagen"},printStopped:{title:"Druck gestoppt",body:"{{printer}}: {{filename}} wurde gestoppt"},printProgress:{title:"Druckfortschritt",body:"{{printer}}: {{filename}} ist zu {{percent}}% abgeschlossen"},printerOffline:{title:"Drucker offline",body:"{{printer}} ist offline"},printerError:{title:"Druckerfehler",body:"{{printer}} – {{error}}"},filamentLow:{title:"Filament niedrig",body:"{{printer}}: Filament geht zur Neige"},maintenanceDue:{title:"Wartung fällig",body:"{{printer}}: {{items}} benötigen Aufmerksamkeit"}},errors:{generic:"Etwas ist schiefgelaufen",networkError:"Netzwerkfehler. Bitte überprüfen Sie Ihre Verbindung.",notFound:"Nicht gefunden",unauthorized:"Nicht autorisiert",serverError:"Serverfehler",validationError:"Bitte überprüfen Sie Ihre Eingabe",printerConnectionFailed:"Verbindung zum Drucker fehlgeschlagen",saveFailed:"Speichern fehlgeschlagen",deleteFailed:"Löschen fehlgeschlagen",loadFailed:"Laden der Daten fehlgeschlagen"},hmsErrors:{title:"Fehler - {{name}}",noErrors:"Keine Fehler",viewOnWiki:"Im Bambu Lab Wiki ansehen",clearInstructions:"Löschen Sie die Fehler am Drucker, um sie hier zu entfernen.",clearErrors:"Fehler löschen",clearSuccess:"HMS-Fehler gelöscht",clearFailed:"HMS-Fehler konnten nicht gelöscht werden"},mqttDebug:{title:"MQTT-Debug-Protokoll",searchPlaceholder:"Topic oder Payload suchen...",noMessages:"Noch keine Nachrichten protokolliert",startLoggingHint:'Klicken Sie auf "Protokollierung starten", um MQTT-Nachrichten aufzuzeichnen',noMessagesMatch:"Keine Nachrichten entsprechen Ihrem Filter",adjustFilterHint:"Versuchen Sie, Ihre Such- oder Filterkriterien anzupassen",incoming:"Eingehend",outgoing:"Ausgehend",loggingStopped:"Protokollierung gestoppt",loggingActive:"Protokollierung aktiv - Nachrichten werden automatisch aktualisiert",startLogging:"Protokollierung starten",stopLogging:"Protokollierung stoppen",clearLog:"Protokoll löschen",topic:"Thema",timestamp:"Zeitstempel",direction:"Richtung",all:"Alle"},printerFiles:{title:"Dateimanager",storageUsed:"Belegt:",storageFree:"Frei:",filterPlaceholder:"Dateien filtern...",deleteButton:"Löschen",deleteFiles:"{{count}} Dateien löschen",deleteFileConfirm:'"{{name}}" löschen? Dies kann nicht rückgängig gemacht werden.',deleteFilesConfirm:"{{count}} ausgewählte Dateien löschen? Dies kann nicht rückgängig gemacht werden.",noFiles:"Keine Dateien auf dem Drucker",loadingFiles:"Dateien werden geladen...",failedToLoad:"Dateien konnten nicht geladen werden",toast:{filesDeleted:"{{count}} Datei(en) gelöscht",deleteFailed:"Löschen fehlgeschlagen: {{error}}"}},confirm:{delete:"Möchten Sie dies wirklich löschen?",unsavedChanges:"Sie haben ungespeicherte Änderungen. Möchten Sie wirklich verlassen?",clearQueue:"Möchten Sie die Warteschlange wirklich leeren?"},login:{title:"Bambuddy Anmeldung",subtitle:"Melden Sie sich bei Ihrem Konto an",username:"Benutzername",usernamePlaceholder:"Benutzername eingeben",usernameOrEmail:"Benutzername oder E-Mail",usernameOrEmailPlaceholder:"Benutzername oder @ E-Mail",password:"Passwort",passwordPlaceholder:"Passwort eingeben",signIn:"Anmelden",signingIn:"Anmeldung läuft...",rememberMe:"Angemeldet bleiben",forgotPassword:"Passwort vergessen?",loginSuccess:"Erfolgreich angemeldet",loginFailed:"Anmeldung fehlgeschlagen",enterCredentials:"Bitte Benutzername und Passwort eingeben",enterEmail:"Bitte geben Sie Ihre E-Mail-Adresse ein",oidcLoginFailed:"OIDC-Anmeldung fehlgeschlagen",oidcErrors:{providerError:"Der Identity-Provider hat einen Fehler zurückgegeben",missingParameters:"Dem OIDC-Callback fehlen erforderliche Parameter",invalidState:"OIDC-State ist ungültig oder wurde bereits verwendet",stateExpired:"OIDC-Sitzung abgelaufen — bitte erneut versuchen",providerNotFound:"OIDC-Provider nicht gefunden",discoveryFailed:"OIDC-Discovery-Dokument konnte nicht abgerufen werden",invalidDiscovery:"OIDC-Discovery-Dokument ist ungültig",networkError:"Netzwerkfehler beim OIDC-Token-Austausch",badResponse:"Unerwartete Antwort beim OIDC-Token-Austausch",noIdToken:"OIDC-Provider hat kein ID-Token zurückgegeben",validationFailed:"OIDC-Token-Validierung fehlgeschlagen",nonceMismatch:"OIDC-Nonce stimmt nicht überein — möglicher Replay-Angriff",missingSubClaim:"OIDC-Token enthält keinen Sub-Claim",noLinkedAccount:"Kein lokales Konto mit dieser OIDC-Identität verknüpft",accountInactive:"Ihr Konto ist inaktiv",userResolutionFailed:"Ihr Konto konnte nicht aufgelöst werden",internalError:"Interner Fehler beim OIDC-Login",tokenExchangeFailed:"OIDC-Token-Austausch fehlgeschlagen"},forgotPasswordTitle:"Passwort vergessen",forgotPasswordMessage:"Wenn Sie Ihr Passwort vergessen haben, wenden Sie sich bitte an Ihren Systemadministrator.",forgotPasswordEmailMessage:"Geben Sie Ihre E-Mail-Adresse ein und wir senden Ihnen ein neues Passwort.",emailAddress:"E-Mail-Adresse",emailPlaceholder:"ihre.email@beispiel.de",cancel:"Abbrechen",sending:"Wird gesendet...",sendResetEmail:"Zurücksetzungs-E-Mail senden",howToReset:"So setzen Sie Ihr Passwort zurück:",resetStep1:"Kontaktieren Sie Ihren Bambuddy-Administrator",resetStep2:"Bitten Sie ihn, Ihr Passwort in der Benutzerverwaltung zurückzusetzen",resetStep3:"Er kann ein neues temporäres Passwort für Sie festlegen",resetStep4:"Melden Sie sich mit dem neuen Passwort an und ändern Sie es in den Einstellungen",gotIt:"Verstanden",resetPassword:{title:"Neues Passwort festlegen",subtitle:"Geben Sie unten Ihr neues Passwort ein und bestätigen Sie es.",newPassword:"Neues Passwort",newPasswordPlaceholder:"Mindestens 8 Zeichen",confirmPassword:"Passwort bestätigen",confirmPasswordPlaceholder:"Neues Passwort wiederholen",saving:"Wird gespeichert…",submit:"Neues Passwort festlegen",backToLogin:"Zurück zur Anmeldung",passwordsDoNotMatch:"Passwörter stimmen nicht überein",passwordTooShort:"Passwort muss mindestens 8 Zeichen lang sein",resetFailed:"Passwort zurücksetzen fehlgeschlagen. Der Link ist möglicherweise abgelaufen."},twoFA:{title:"Zwei-Faktor-Authentifizierung",subtitle:"Ihr Konto ist mit 2FA geschützt. Geben Sie unten den Bestätigungscode ein.",methodAuthenticator:"Authenticator-App",methodEmail:"E-Mail-Code",methodBackup:"Wiederherstellungscode",instructionsTotp:"Öffnen Sie Ihre Authenticator-App und geben Sie den 6-stelligen Code für Bambuddy ein.",instructionsEmail:"Ein 6-stelliger Code wurde an Ihre E-Mail-Adresse gesendet. Er ist 10 Minuten gültig.",instructionsEmailNotSent:"Klicken Sie unten, um einen Bestätigungscode per E-Mail zu erhalten.",instructionsBackup:"Geben Sie einen Ihrer 8-stelligen Wiederherstellungscodes ein. Jeder Code kann nur einmal verwendet werden.",sendCodeButton:"Code per E-Mail senden",sendingCode:"Wird gesendet...",resendCode:"Code erneut senden",codeLabel:"Bestätigungscode",backupCodeLabel:"Wiederherstellungscode",codePlaceholder:"000000",backupCodePlaceholder:"XXXXXXXX",verifyButton:"Bestätigen",verifyingButton:"Wird überprüft...",backToLogin:"← Zurück zur Anmeldung",orContinueWith:"oder anmelden mit",signInWith:"Anmelden mit {{provider}}",enterCode:"Bitte geben Sie den Bestätigungscode ein",sendCodeFailed:"Bestätigungscode konnte nicht gesendet werden",invalidCode:"Ungültiger Code. Bitte erneut versuchen."}},setup:{title:"Bambuddy Einrichtung",subtitle:"Konfigurieren Sie die Authentifizierung für Ihre Bambuddy-Instanz",enableAuth:"Authentifizierung aktivieren",adminAccount:"Admin-Konto",adminAccountDesc:"Wenn bereits Admin-Benutzer existieren, wird die Authentifizierung mit den vorhandenen Admin-Konten aktiviert. Lassen Sie die Felder unten leer, um vorhandene Admins zu verwenden, oder geben Sie neue Anmeldedaten ein, um einen neuen Admin-Benutzer zu erstellen.",adminUsername:"Admin-Benutzername",adminPassword:"Admin-Passwort",optionalIfAdminExists:"(optional, wenn Admin-Benutzer existieren)",adminUsernamePlaceholder:"Admin-Benutzernamen eingeben (optional)",adminPasswordPlaceholder:"Admin-Passwort eingeben (optional)",confirmPassword:"Passwort bestätigen",confirmPasswordPlaceholder:"Admin-Passwort bestätigen",settingUp:"Einrichtung läuft...",completeSetup:"Einrichtung abschließen",toast:{authEnabledAdminCreated:"Authentifizierung aktiviert und Admin-Benutzer erstellt",authEnabledExistingAdmins:"Authentifizierung mit vorhandenen Admin-Benutzern aktiviert",setupCompleted:"Einrichtung abgeschlossen",enterBothCredentials:"Bitte geben Sie sowohl Admin-Benutzernamen als auch Passwort ein, oder lassen Sie beide leer, um vorhandene Admin-Benutzer zu verwenden",passwordsDoNotMatch:"Passwörter stimmen nicht überein",passwordTooShort:"Passwort muss mindestens 6 Zeichen lang sein"}},changePassword:{title:"Passwort ändern",currentPassword:"Aktuelles Passwort",currentPasswordPlaceholder:"Aktuelles Passwort eingeben",newPassword:"Neues Passwort",newPasswordPlaceholder:"Neues Passwort eingeben (min. 6 Zeichen)",confirmPassword:"Neues Passwort bestätigen",confirmPasswordPlaceholder:"Neues Passwort bestätigen",passwordsDoNotMatch:"Passwörter stimmen nicht überein",passwordTooShort:"Passwort muss mindestens 6 Zeichen lang sein",changing:"Wird geändert...",success:"Passwort erfolgreich geändert",failed:"Passwortänderung fehlgeschlagen"},plateAlert:{title:"Druck pausiert!",message:"Objekte auf dem Druckbett erkannt. Der Druck wurde automatisch pausiert. Bitte räumen Sie das Druckbett und setzen Sie den Druck fort.",understand:"Verstanden"},camera:{title:"Kameraansicht",invalidPrinterId:"Ungültige Drucker-ID",live:"Live",snapshot:"Schnappschuss",restartStream:"Stream neu starten",refreshSnapshot:"Schnappschuss aktualisieren",fullscreen:"Vollbild",exitFullscreen:"Vollbild beenden",connectingToCamera:"Verbinde mit Kamera...",capturingSnapshot:"Schnappschuss wird aufgenommen...",connectionLost:"Verbindung verloren",connectionFailed:"Kameraverbindung fehlgeschlagen",reconnecting:"Neuverbindung in {{countdown}}s... (Versuch {{attempt}}/{{max}})",reconnectNow:"Jetzt verbinden",cameraUnavailable:"Kamera nicht verfügbar",cameraUnavailableDesc:"Stellen Sie sicher, dass der Drucker eingeschaltet und verbunden ist.",noCamera:"Keine Kamera verfügbar",retry:"Erneut versuchen",cameraStream:"Kamera-Stream",zoomOut:"Verkleinern",zoomIn:"Vergrößern",resetZoom:"Zoom zurücksetzen",recording:"Aufnahme",startRecording:"Aufnahme starten",stopRecording:"Aufnahme stoppen",chamberLight:"Kammerbeleuchtung umschalten"},groups:{title:"Gruppenverwaltung",subtitle:"Berechtigungsgruppen für Zugriffskontrolle verwalten",backToSettings:"Zurück zu Einstellungen",createGroup:"Gruppe erstellen",noPermission:"Sie haben keine Berechtigung, auf diese Seite zuzugreifen.",system:"System",noDescription:"Keine Beschreibung",usersCount:"{{count}} Benutzer",permissionsCount:"{{count}} Berechtigungen",edit:"Bearbeiten",delete:"Löschen",toast:{created:"Gruppe erfolgreich erstellt",updated:"Gruppe erfolgreich aktualisiert",deleted:"Gruppe erfolgreich gelöscht",enterGroupName:"Bitte geben Sie einen Gruppennamen ein"},modal:{editGroup:"Gruppe bearbeiten",createGroup:"Gruppe erstellen",cancel:"Abbrechen",saving:"Speichern...",creating:"Erstellen...",saveChanges:"Änderungen speichern"},form:{groupName:"Gruppenname",groupNamePlaceholder:"Gruppennamen eingeben",systemGroupWarning:"Systemgruppennamen können nicht geändert werden",description:"Beschreibung",descriptionPlaceholder:"Beschreibung eingeben (optional)",permissions:"Berechtigungen ({{count}} ausgewählt)"},deleteModal:{title:"Gruppe löschen",message:"Sind Sie sicher, dass Sie diese Gruppe löschen möchten? Benutzer in dieser Gruppe verlieren diese Berechtigungen.",confirm:"Gruppe löschen"},editor:{title:"Gruppe bearbeiten",createTitle:"Gruppe erstellen",search:"Berechtigungen suchen...",selectAll:"Alle auswählen",clearAll:"Alle abwählen",permissionsSelected:"{{count}} ausgewählt",noResults:"Keine Berechtigungen entsprechen Ihrer Suche"}},users:{title:"Benutzerverwaltung",subtitle:"Benutzer und deren Zugriff auf Ihre Bambuddy-Instanz verwalten",backToSettings:"Zurück zu Einstellungen",createUser:"Benutzer erstellen",noPermission:"Sie haben keine Berechtigung, auf diese Seite zuzugreifen.",admin:"Admin",noGroups:"Keine Gruppen",active:"Aktiv",inactive:"Inaktiv",edit:"Bearbeiten",delete:"Löschen",system:"System",noGroupsAvailable:"Keine Gruppen verfügbar",table:{username:"Benutzername",groups:"Gruppen",status:"Status",actions:"Aktionen"},toast:{created:"Benutzer erfolgreich erstellt",updated:"Benutzer erfolgreich aktualisiert",deleted:"Benutzer erfolgreich gelöscht",fillRequired:"Bitte füllen Sie alle Pflichtfelder aus",passwordsDoNotMatch:"Passwörter stimmen nicht überein",passwordTooShort:"Passwort muss mindestens 6 Zeichen lang sein",ldapProvisioned:'LDAP-Benutzer „{{username}}" bereitgestellt'},modal:{createUser:"Benutzer erstellen",editUser:"Benutzer bearbeiten",cancel:"Abbrechen",creating:"Erstellen...",saving:"Speichern...",saveChanges:"Änderungen speichern",advancedAuthSubtitle:"mit erweiterter Authentifizierung",tabsAriaLabel:"Benutzerquelle",localTab:"Lokal",ldapTab:"LDAP",ldapSearchLabel:"Verzeichnis durchsuchen",ldapSearchPlaceholder:"Benutzername, Name oder E-Mail eingeben...",ldapMinChars:"Mindestens 2 Zeichen für die Suche eingeben",ldapTypeToSearch:"Tippen, um das LDAP-Verzeichnis zu durchsuchen",ldapSearching:"Verzeichnis wird durchsucht...",ldapNoResults:"Keine passenden Benutzer im Verzeichnis",ldapSearchError:"Verzeichnissuche fehlgeschlagen. Bitte LDAP-Server-Status prüfen.",ldapAlreadyProvisioned:"Bereits bereitgestellt",ldapSelectedLabel:"Ausgewählt",ldapProvision:"Benutzer bereitstellen",ldapProvisioning:"Wird bereitgestellt...",ldapErrorProvision:"Bereitstellung fehlgeschlagen. Bitte LDAP-Server-Status prüfen und erneut versuchen."},form:{username:"Benutzername",usernamePlaceholder:"Benutzernamen eingeben",email:"E-Mail",emailPlaceholder:"benutzer@beispiel.de",password:"Passwort",passwordPlaceholder:"Passwort eingeben",confirmPassword:"Passwort bestätigen",confirmPasswordPlaceholder:"Passwort bestätigen",newPasswordPlaceholder:"Neues Passwort eingeben",confirmNewPasswordPlaceholder:"Neues Passwort bestätigen",leaveBlankToKeep:"leer lassen, um das aktuelle zu behalten",groups:"Gruppen",optional:"optional",autoGeneratedPassword:"Ein sicheres Passwort wird automatisch generiert und per E-Mail an den Benutzer gesendet.",passwordManagedByAdvancedAuth:'Das Passwort wird durch erweiterte Authentifizierung verwaltet. Verwenden Sie "Passwort zurücksetzen", um ein neues Passwort per E-Mail an den Benutzer zu senden.',resetPassword:"Passwort zurücksetzen",resettingPassword:"Passwort wird zurückgesetzt..."},deleteModal:{title:"Benutzer löschen",message:"Sind Sie sicher, dass Sie diesen Benutzer löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.",confirm:"Benutzer löschen"}},streamOverlay:{title:"Stream-Overlay",invalidPrinterId:"Ungültige Drucker-ID",cameraStream:"Kamera-Stream",progress:"Fortschritt",eta:"ETA",printerIdle:"Drucker ist inaktiv",printerOffline:"Drucker offline",status:{printing:"Druckt",paused:"Pausiert",finished:"Fertig",failed:"Fehlgeschlagen",idle:"Inaktiv",unknown:"Unbekannt"}},profiles:{title:"Profile",subtitle:"Verwalten Sie Ihre Slicer-Voreinstellungen und Druckvorschub-Kalibrierungen",tabs:{cloud:"Cloud-Profile",local:"Lokale Profile",kprofiles:"K-Profile"},localProfiles:{title:"Lokale Profile",subtitle:"Slicer-Voreinstellungen aus OrcaSlicer importieren und verwalten",import:"Profile importieren",importDesc:".bbscfg-, .bbsflmt-, .orca_filament-, .zip- oder .json-Dateien hier ablegen",importing:"Importiere...",search:"Lokale Voreinstellungen durchsuchen...",noPresets:"Noch keine lokalen Voreinstellungen",badge:"Lokal",edit:"Bearbeiten",delete:"Löschen",cancel:"Abbrechen",deleteConfirmTitle:"Voreinstellung löschen",deleteConfirm:"Möchten Sie diese Voreinstellung wirklich löschen? Dies kann nicht rückgängig gemacht werden.",source:"Quelle",inheritsFrom:"Erbt von",filamentType:"Typ",vendor:"Hersteller",compatiblePrinters:"Drucker",nozzleTemp:"Düsentemperatur",cost:"Kosten",density:"Dichte",pressureAdvance:"Druckvorschub",filament:"Filament",process:"Prozess",printer:"Drucker",toast:{importSuccess:"{{count}} Voreinstellung(en) importiert",importSkipped:"{{count}} Voreinstellung(en) übersprungen (Duplikate)",importError:"{{count}} Fehler beim Import",deleted:"Voreinstellung gelöscht",updated:"Voreinstellung aktualisiert"}},connectedAs:"Verbunden als",logout:"Abmelden",noLogoutPermission:"Sie haben keine Berechtigung zum Abmelden",failedToLoad:"Profile konnten nicht geladen werden",retry:"Erneut versuchen",time:{justNow:"Gerade eben",minsAgo:"vor {{count}}m",hoursAgo:"vor {{count}}h",daysAgo:"vor {{count}}d"},toast:{loggedOut:"Abgemeldet"},login:{title:"Mit Bambu Cloud verbinden",subtitle:"Synchronisieren Sie Ihre Slicer-Voreinstellungen geräteübergreifend",email:"E-Mail",password:"Passwort",region:"Region",regionGlobal:"Global",regionChina:"China",verificationCode:"Bestätigungscode",totpCode:"Authenticator-Code",checkEmail:"Prüfen Sie Ihre E-Mail ({{email}}) für einen 6-stelligen Code",enterTotpHint:"Geben Sie den 6-stelligen Code aus Ihrer Authenticator-App ein",accessToken:"Zugriffstoken",accessTokenHint:"Fügen Sie Ihr Bambu-Cloud-Zugriffstoken ein. Konten der Region China müssen diesen Weg nutzen (telefonnummerngebunden — kein E-Mail-Login). Im Wiki steht, wie Sie das Token aus den MakerWorld-Cookies auslesen.",back:"Zurück",loginButton:"Anmelden",verifyButton:"Bestätigen",setTokenButton:"Token setzen",useToken:"Stattdessen Zugriffstoken verwenden",useEmail:"Stattdessen mit E-Mail anmelden",toast:{loggedIn:"Erfolgreich angemeldet",codeSent:"Bestätigungscode an Ihre E-Mail gesendet",enterTotp:"Geben Sie den Code aus Ihrer Authenticator-App ein",tokenSet:"Token erfolgreich gesetzt"}},presets:{myPreset:"Mein Profil (bearbeitbar)",duplicate:"Duplizieren",editable:"Bearbeitbar",failedToLoadDetails:"Profil-Details konnten nicht geladen werden",deleteConfirm:"Dieses Profil löschen?",deleteWarning:'"{{name}}" wird dauerhaft aus Bambu Cloud gelöscht. Dies kann nicht rückgängig gemacht werden.',noDuplicatePermission:"Sie haben keine Berechtigung zum Duplizieren von Profilen",noEditPermission:"Sie haben keine Berechtigung zum Bearbeiten von Profilen",noDeletePermission:"Sie haben keine Berechtigung zum Löschen von Profilen",types:{filament:"Filament-Profil",printer:"Drucker-Profil",process:"Prozess-Profil"},toast:{deleted:"Profil gelöscht",created:"Profil erstellt",updated:"Profil aktualisiert",duplicated:"Profil dupliziert",fieldAdded:'Feld "{{key}}" hinzugefügt',exported:"Profil exportiert"},baseLabel:"Basis: {{name}}",currentLabel:"Aktuell: {{name}}",newPreset:"Neues Profil",editPreset:"Profil bearbeiten",duplicatePreset:"Profil duplizieren",createNewPreset:"Neues Profil erstellen",customizeSettings:"Passen Sie die Einstellungen für Ihr neues Profil an",compareWithBase:"Mit Basis-Profil vergleichen",compare:"Vergleichen",basePreset:"Basis-Profil",selectBasePreset:"Basis-Profil auswählen...",presetName:"Profilname",myCustomPreset:"Mein eigenes Profil",inheritsFrom:"Erbt von",dropJsonToImport:"JSON zum Importieren ablegen",tabs:{common:"Allgemein",allFields:"Alle Felder"},availableFields:"Verfügbare Felder",searchFieldsPlaceholder:"Felder suchen...",noMatchingFields:"Keine passenden Felder",allFieldsAdded:"Alle Felder hinzugefügt",addCustomField:"Eigenes Feld hinzufügen",yourOverrides:"Ihre Überschreibungen",noOverridesYet:"Noch keine Überschreibungen",clickFieldsToAdd:"Klicken Sie links auf Felder, um sie hinzuzufügen",saveAsTemplate:"Als Vorlage speichern",jsonTip:"Tipp: Ziehen Sie eine .json-Datei auf dieses Fenster, um Einstellungen zu importieren"},cloudView:{searchPlaceholder:"Profile suchen...",templates:"Vorlagen",refresh:"Aktualisieren",newPreset:"Neues Profil",clearFilters:"Filter zurücksetzen",compareMode:"Vergleichsmodus",selectAnotherPreset:"Wählen Sie ein weiteres {{type}}-Profil",clickTwoPresets:"Klicken Sie auf zwei Profile des gleichen Typs zum Vergleichen",selectFirst:"1. Erstes auswählen",selectSecond:"2. Zweites auswählen",compareNow:"Jetzt vergleichen",lastSynced:"Zuletzt synchronisiert:",showingCount:"{{showing}} von {{total}} Profilen",noPresetsFound:"Keine Profile gefunden",columns:{filament:"Filament",process:"Prozess",printer:"Drucker"},noFilamentPresets:"Keine Filament-Profile",noProcessPresets:"Keine Prozess-Profile",noPrinterPresets:"Keine Drucker-Profile",filters:{type:"Typ",owner:"Besitzer",printer:"Drucker",nozzle:"Düse",filament:"Filament",layer:"Schicht",all:"Alle",myPresets:"Meine Profile",builtIn:"Voreingestellt",process:"Prozess"},noTemplatesPermission:"Sie haben keine Berechtigung, Vorlagen zu verwalten",noRefreshPermission:"Sie haben keine Berechtigung, Profile zu aktualisieren",noCreatePermission:"Sie haben keine Berechtigung, Profile zu erstellen"},templates:{title:"Schnellvorlagen",noTemplates:"Noch keine Vorlagen",createFirst:"Erstellen Sie Vorlagen aus dem Preset-Editor",typeFilter:"Typ:",deleteTitle:"Vorlage löschen",deleteWarning:"Diese Aktion kann nicht rückgängig gemacht werden",deleteConfirm:'Möchten Sie "{{name}}" wirklich löschen?',namePlaceholder:"Vorlagenname",descriptionPlaceholder:"Beschreibung",settingsJson:"Einstellungen (JSON)",fieldsCount:"{{count}} Felder",shownInModals:"In Dialogen angezeigt",hiddenInModals:"In Dialogen ausgeblendet",apply:"Anwenden",toast:{deleted:"Vorlage gelöscht",updated:"Vorlage aktualisiert",created:"Vorlage erstellt",applied:"Vorlage angewendet"}}},support:{debugLoggingActive:"Debug-Protokollierung ist aktiv",manageLogs:"Verwalten",collectItem7:"Drucker-Verbindungsstatus und Firmware-Versionen",collectItem8:"Integrationsstatus (Spoolman, MQTT, HA)",collectItem9:"Netzwerkschnittstellen (nur Subnetze)",collectItem10:"Python-Paketversionen",collectItem11:"Datenbankzustandsprüfungen",collectItem12:"Docker-Umgebungsdetails"},fileManager:{title:"Dateimanager",subtitle:"Organisieren und verwalten Sie Ihre Druckdateien",uploadFiles:"Dateien hochladen",newFolder:"Neuer Ordner",folderName:"Ordnername",folderNamePlaceholder:"z.B. Funktionsteile",renameFile:"Datei umbenennen",renameFolder:"Ordner umbenennen",moveFiles:"{{count}} Datei(en) verschieben",rootNoFolder:"Stammverzeichnis (Kein Ordner)",current:"aktuell",linkFolder:"Ordner verknüpfen",linkFolderDescription:'"{{name}}" mit einem Projekt oder Archiv verknüpfen für schnellen Zugriff.',project:"Projekt",archive:"Archiv",noProjectsFound:"Keine Projekte gefunden",noArchivesFound:"Keine Archive gefunden",unlink:"Verknüpfung aufheben",link:"Verknüpfen",dragDropFiles:"Dateien hierher ziehen",dropFilesHere:"Dateien hier ablegen",orClickToBrowse:"oder klicken zum Durchsuchen",allFileTypesSupported:"Alle Dateitypen werden unterstützt. ZIP-Dateien werden extrahiert.",zipFilesDetected:"ZIP-Dateien erkannt",zipExtractOptions:"ZIP-Dateien werden extrahiert. Wählen Sie, wie die Ordnerstruktur behandelt werden soll:",preserveZipStructure:"Ordnerstruktur aus ZIP beibehalten",createFolderFromZip:"Ordner aus ZIP-Dateiname erstellen",stlThumbnailGeneration:"STL-Vorschaubildgenerierung",zipMayContainStl:"ZIP-Dateien können STL-Dateien enthalten. Vorschaubilder können während der Extraktion generiert werden.",thumbnailsCanBeGenerated:"Vorschaubilder können für STL-Dateien generiert werden. Große Modelle benötigen möglicherweise mehr Zeit.",generateThumbnailsForStl:"Vorschaubilder für STL-Dateien generieren",threemfDetected:"3MF-Dateien erkannt",threemfExtractionInfo:"Druckermodell, Material, Farbe und Druckeinstellungen werden automatisch aus 3MF-Dateien extrahiert.",willBeExtracted:"Wird extrahiert",filesExtracted:"{{count}} Dateien extrahiert",uploadComplete:"Upload abgeschlossen: {{succeeded}} erfolgreich",uploadFailed:"Hochladen fehlgeschlagen",zipFilesFailed:"{{count}} Dateien fehlgeschlagen",uploading:"Hochladen...",changeLink:"Verknüpfung ändern...",linkTo:"Verknüpfen mit...",linkToProjectOrArchive:"Mit Projekt oder Archiv verknüpfen",addToQueue:"Zur Warteschlange",schedulePrint:"Planen",generateThumbnail:"Vorschaubild generieren",generateThumbnails:"Vorschaubilder generieren",generateThumbnailsForMissing:"Vorschaubilder für STL-Dateien ohne Vorschau generieren",gridView:"Rasteransicht",listView:"Listenansicht",lowDiskSpaceWarning:"Warnung: Wenig Speicherplatz",lowDiskSpaceDetails:"Nur {{free}} frei von {{total}} gesamt. Schwellenwert ist auf {{threshold}} GB eingestellt.",files:"Dateien",folders:"Ordner",size:"Größe",free:"Frei",allFiles:"Alle Dateien",wrap:"Umbrechen",enableTextWrapping:"Textumbruch aktivieren",disableTextWrapping:"Textumbruch deaktivieren",collapse:"Einklappen",collapseFoldersByDefault:"Ordner standardmäßig einklappen",expandFoldersByDefault:"Ordner standardmäßig ausklappen",dragToResizeTooltip:"Ziehen zum Ändern der Größe, Doppelklick zum Zurücksetzen",searchFiles:"Dateien suchen...",allTypes:"Alle Typen",prints:"Drucke",ascending:"Aufsteigend",descending:"Absteigend",resultsCount:"{{showing}} von {{total}} Dateien",selectAll:"Alle auswählen",deselectAll:"Auswahl aufheben",selected:"{{count}} ausgewählt",adding:"Hinzufügen...",loadingFiles:"Dateien werden geladen...",folderIsEmpty:"Ordner ist leer",noFilesYet:"Noch keine Dateien",folderEmptyDescription:"Laden Sie Dateien hoch oder verschieben Sie Dateien in diesen Ordner.",noFilesDescription:"Laden Sie Dateien hoch, um Ihre Druckdateien zu organisieren.",noMatchingFiles:"Keine passenden Dateien",noMatchingFilesDescription:"Keine Dateien entsprechen Ihren aktuellen Such- oder Filterkriterien.",clearFilters:"Filter zurücksetzen",printedCount:"{{count}}x gedruckt",uploadedBy:"Hochgeladen von",deleteFolder:"Ordner löschen",deleteFile:"Datei löschen",deleteFilesCount:"{{count}} Dateien löschen",deleteFolderConfirm:"Möchten Sie diesen Ordner wirklich löschen? Alle Dateien darin werden ebenfalls gelöscht.",deleteFileConfirm:"Möchten Sie diese Datei wirklich löschen?",deleteFilesConfirm:"Möchten Sie {{count}} ausgewählte Dateien wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.",deleting:"Wird gelöscht...",noPermissionRenameFolder:"Sie haben keine Berechtigung, Ordner umzubenennen",noPermissionLinkFolder:"Sie haben keine Berechtigung, Ordner zu verknüpfen",noPermissionDeleteFolder:"Sie haben keine Berechtigung, Ordner zu löschen",noPermissionPrint:"Sie haben keine Berechtigung zum Drucken",noPermissionSlice:"Sie haben keine Berechtigung, Dateien zu slicen",noPermissionAddToQueue:"Sie haben keine Berechtigung, zur Warteschlange hinzuzufügen",noPermissionDownload:"Sie haben keine Berechtigung, Dateien herunterzuladen",noPermissionRenameFile:"Sie haben keine Berechtigung, diese Datei umzubenennen",noPermissionGenerateThumbnail:"Sie haben keine Berechtigung, Vorschaubilder zu generieren",noPermissionDeleteFile:"Sie haben keine Berechtigung, diese Datei zu löschen",noPermissionCreateFolder:"Sie haben keine Berechtigung, Ordner zu erstellen",noPermissionUpload:"Sie haben keine Berechtigung, Dateien hochzuladen",noPermissionMoveFiles:"Sie haben keine Berechtigung, Dateien zu verschieben",noPermissionDeleteFiles:"Sie haben keine Berechtigung, Dateien zu löschen",linkExternal:"Extern verknüpfen",linkExternalFolder:"Externen Ordner verknüpfen",linkExternalFolderDescription:"Ein Host-Verzeichnis (NAS, USB, Netzlaufwerk) in den Dateimanager einbinden. Dateien werden nicht kopiert — sie werden direkt vom Originalpfad gelesen.",externalFolderNamePlaceholder:"z.B. NAS-Drucke",externalPath:"Host-Pfad",externalPathHelp:"Absoluter Pfad zum Verzeichnis auf dem Docker-Host. Muss als Bind-Mount in den Container eingebunden sein.",readOnly:"Nur Lesen",readOnlyHelp:"verhindert Uploads und Löschungen",showHiddenFiles:"Versteckte Dateien anzeigen (Punkt-Dateien)",externalFolder:"Externer Ordner",scanFolder:"Scannen",toast:{folderCreated:"Ordner erstellt",folderDeleted:"Ordner gelöscht",fileDeleted:"Datei gelöscht",filesDeleted:"{{count}} Dateien gelöscht",filesMoved:"Dateien verschoben",folderLinked:"Ordner verknüpft",folderUnlinked:"Ordnerverknüpfung aufgehoben",externalFolderLinked:"Externer Ordner verknüpft und gescannt",folderScanned:"Scan abgeschlossen: {{added}} hinzugefügt, {{removed}} entfernt",addedToQueue:"{{count}} Datei(en) zur Warteschlange hinzugefügt",addedToQueuePartial:"{{added}} Datei(en) hinzugefügt, {{failed}} fehlgeschlagen",failedToAddToQueue:"Fehler beim Hinzufügen: {{error}}",fileRenamed:"Datei umbenannt",folderRenamed:"Ordner umbenannt",thumbnailsGenerated:"{{count}} Vorschaubild(er) generiert",thumbnailsGeneratedPartial:"{{succeeded}} Vorschaubild(er) generiert, {{failed}} fehlgeschlagen",noStlMissingThumbnails:"Keine STL-Dateien ohne Vorschaubild",failedToGenerateThumbnails:"Fehler beim Generieren der Vorschaubilder: {{error}}",thumbnailGenerated:"Vorschaubild generiert",failedToGenerateThumbnail:"Fehler beim Generieren des Vorschaubildes: {{error}}"}},projects:{title:"Projekte",subtitle:"Organisieren und verfolgen Sie Ihre 3D-Druckprojekte",newProject:"Neues Projekt",editProject:"Projekt bearbeiten",deleteProject:"Projekt löschen",projectName:"Projektname",description:"Beschreibung",noProjects:"Noch keine Projekte",noProjectsFiltered:"Keine {{status}} Projekte",noProjectsFilteredHelp:"Sie haben keine {{status}} Projekte. Projekte werden hier angezeigt, wenn sich ihr Status ändert.",createFirst:"Erstellen Sie Ihr erstes Projekt, um verwandte Drucke zu organisieren, den Fortschritt zu verfolgen und Ihre Builds zu verwalten.",createFirstButton:"Erstes Projekt erstellen",create:"Erstellen",files:"Dateien",prints:"Drucke",plates:"Platten",parts:"Teile",lastModified:"Zuletzt geändert",deleteConfirm:"Möchten Sie dieses Projekt wirklich löschen? Archive und Warteschlangenelemente werden getrennt, aber nicht gelöscht.",addFiles:"Dateien hinzufügen",removeFile:"Datei entfernen",viewDetails:"Details anzeigen",namePlaceholder:"z.B. Voron 2.4 Build",descriptionPlaceholder:"Optionale Beschreibung...",urlLabel:"URL",urlPlaceholder:"https://makerworld.com/...",urlInvalid:"URL muss mit http:// oder https:// beginnen",openExternalUrl:"Projekt-URL öffnen",coverImageLabel:"Titelbild",coverImageAlt:"Projekt-Titelbild",coverImageUpload:"Hochladen",coverImageReplace:"Ersetzen",coverImageRemove:"Entfernen",color:"Farbe",targetPlates:"Ziel-Platten",targetPlatesPlaceholder:"z.B. 25",targetPlatesHelp:"Anzahl der Druckaufträge",targetParts:"Ziel-Teile",targetPartsPlaceholder:"z.B. 150",targetPartsHelp:"Benötigte Objekte insgesamt",tagsLabel:"Tags (kommagetrennt)",tagsPlaceholder:"z.B. voron, funktional, geschenk",dueDate:"Fälligkeitsdatum",priority:"Priorität",priorityLow:"Niedrig",priorityNormal:"Normal",priorityHigh:"Hoch",priorityUrgent:"Dringend",statusActive:"Aktiv",statusCompleted:"Abgeschlossen",statusArchived:"Archiviert",done:"Fertig",completed:"abgeschlossen",failed:"fehlgeschlagen",inQueue:"in Warteschlange",noPrintsYet:"Noch keine Drucke",printJobs:"Druckaufträge (Platten)",partsPrinted:"Gedruckte Teile",failedParts:"Fehlgeschlagene Teile",import:"Importieren",export:"Exportieren",importProject:"Projekt importieren",exportAll:"Alle Projekte exportieren",loading:"Projekte werden geladen...",noEditPermission:"Sie haben keine Berechtigung, Projekte zu bearbeiten",noDeletePermission:"Sie haben keine Berechtigung, Projekte zu löschen",noCreatePermission:"Sie haben keine Berechtigung, Projekte zu erstellen",noImportPermission:"Sie haben keine Berechtigung, Projekte zu importieren",noExportPermission:"Sie haben keine Berechtigung, Projekte zu exportieren",toast:{created:"Projekt erstellt",updated:"Projekt aktualisiert",deleted:"Projekt gelöscht",imported:"Projekt importiert",multipleImported:"{{count}} Projekte importiert",importFailed:"Import fehlgeschlagen",exported:"Projekte exportiert (nur Metadaten)"}},projectDetail:{notFound:"Projekt nicht gefunden",backToProjects:"Zurück zu Projekten",export:"Exportieren",exportProject:"Projekt exportieren",noExportPermission:"Sie haben keine Berechtigung, Projekte zu exportieren",noEditPermission:"Sie haben keine Berechtigung, Projekte zu bearbeiten",partOf:"Teil von:",priorityLabel:"Priorität:",noPrints:"Noch keine Drucke in diesem Projekt",status:{active:"Aktiv",completed:"Abgeschlossen",archived:"Archiviert"},priority:{low:"Niedrig",normal:"Normal",high:"Hoch",urgent:"Dringend"},dueDate:{overdue:"Überfällig",today:"Heute fällig",daysLeft:"{{count}} Tage übrig"},progress:{platesProgress:"Platten-Fortschritt",partsProgress:"Teile-Fortschritt",printJobs:"Druckaufträge",parts:"Teile",percentComplete:"{{percent}}% abgeschlossen",remaining:"{{count}} verbleibend"},stats:{printJobs:"Druckaufträge",total:"gesamt",failed:"{{count}} fehlgeschlagen",partsPrinted:"{{count}} Teile gedruckt",printTime:"Druckzeit",filamentUsed:"Filament verbraucht"},cost:{title:"Kostenverfolgung",filamentCost:"Filamentkosten",energy:"Energie",totalCost:"Gesamtkosten",total:"Gesamt",includesBom:"inkl. Stückliste",budget:"Budget",remaining:"Verbleibend"},subProjects:{title:"Unterprojekte ({{count}})"},notes:{title:"Notizen",noEditPermission:"Sie haben keine Berechtigung, Notizen zu bearbeiten",placeholder:"Notizen zu diesem Projekt hinzufügen...",empty:"Noch keine Notizen. Klicken Sie auf Bearbeiten, um Notizen hinzuzufügen."},files:{title:"Dateien",linkFolders:"Ordner aus dem Dateimanager verknüpfen",forQuickAccess:"für schnellen Zugriff auf dieses Projekt.",fileCount:"{{count}} Datei(en)",empty:"Keine Ordner verknüpft. Gehen Sie zum Dateimanager und verknüpfen Sie einen Ordner mit diesem Projekt.",noFiles:"Keine Dateien in diesem Ordner.",print:"Jetzt drucken",addToQueue:"Zur Warteschlange"},bom:{title:"Stückliste",acquired:"{{completed}}/{{total}} beschafft",showAll:"Alle anzeigen",hideDone:"Erledigte ausblenden",addPart:"Teil hinzufügen",noAddPermission:"Sie haben keine Berechtigung, Teile hinzuzufügen",partNamePlaceholder:"Teilename (z.B. M3x8 Schrauben)",partName:"Teilename",qty:"Menge",price:"Preis ({{currency}})",sourcingUrlPlaceholder:"Bezugsquelle-URL (optional)",remarksPlaceholder:"Bemerkungen (optional)",deletePart:"Teil löschen",deleteConfirm:'Möchten Sie "{{name}}" wirklich löschen?',noUpdatePermission:"Sie haben keine Berechtigung, Teile zu aktualisieren",noEditPermission:"Sie haben keine Berechtigung, Teile zu bearbeiten",noDeletePermission:"Sie haben keine Berechtigung, Teile zu löschen",totalCost:"Gesamtkosten:",empty:"Keine Teile in der Stückliste. Fügen Sie Hardware, Elektronik oder andere Komponenten hinzu, um zu verfolgen, was beschafft werden muss."},timeline:{title:"Aktivitätsverlauf",empty:"Noch keine Aktivität."},template:{saveAsTemplate:"Als Vorlage speichern",noCreatePermission:"Sie haben keine Berechtigung, Vorlagen zu erstellen"},queue:{title:"Warteschlange",viewAll:"Alle anzeigen",printing:"{{count}} druckend",queued:"{{count}} in Warteschlange"},prints:{title:"Drucke ({{count}})"},toast:{projectUpdated:"Projekt aktualisiert",partAdded:"Teil hinzugefügt",partRemoved:"Teil entfernt",exportFailed:"Export fehlgeschlagen",projectExported:"Projekt exportiert",templateCreated:"Vorlage erstellt"}},system:{title:"Systeminformationen",version:"Version",uptime:"Laufzeit",cpuUsage:"CPU-Auslastung",memoryUsage:"Speicherauslastung",diskUsage:"Festplattenauslastung",networkInfo:"Netzwerkinformationen",logs:"Protokolle",debugMode:"Debug-Modus",enableDebug:"Debug-Protokollierung aktivieren",disableDebug:"Debug-Protokollierung deaktivieren",downloadLogs:"Protokolle herunterladen",clearLogs:"Protokolle löschen",dockerInfo:"Docker-Info",containerName:"Container-Name",imageName:"Image-Name",platform:"Plattform",architecture:"Architektur"},library:{title:"Filament-Bibliothek",addFilament:"Filament hinzufügen",editFilament:"Filament bearbeiten",deleteFilament:"Filament löschen",vendor:"Hersteller",material:"Material",color:"Farbe",kFactor:"K-Faktor",temperature:"Temperatur",noFilaments:"Keine Filamente in der Bibliothek",deleteConfirm:"Möchten Sie dieses Filament wirklich löschen?",importFromPrinter:"Vom Drucker importieren",exportToFile:"In Datei exportieren"},slice:{title:"Modell slicen",action:"Slicen",slicing:"Slicen…",printer:"Drucker-Profil",process:"Prozess-Profil",filament:"Filament-Profil",filamentSlot:"Filament {{index}} – {{type}}",selectPreset:"— Profil auswählen —",loadingPresets:"Profile werden geladen…",analyzingPlateFilaments:"Plattenfilamente werden analysiert…",analyzingPlateFilamentsHint:"Es wird ein Probeschnitt ausgeführt, um die belegten AMS-Slots dieser Platte zu ermitteln. Wird zwischengespeichert — erneutes Öffnen ist sofort.",previewToast:"{{name}} wird analysiert — {{elapsed}}",previewWithProgress:"{{name}} wird analysiert — {{stage}} ({{percent}}%) — {{elapsed}}",notUsedByPlate:"— wird von dieser Platte nicht verwendet",printerMismatch:"Dieses 3MF wurde für {{source}} gesliced, du hast aber {{target}} ausgewählt. Der Slicer-CLI kann ein 3MF nicht für einen anderen Drucker neu slicen — öffne die Quelle in Bambu Studio, ändere den Drucker und exportiere neu.",noPresetsForSlot:"Keine Profile verfügbar",presetsLoadFailed:"Profile konnten nicht geladen werden. Importiere sie zuerst unter Einstellungen → Profile.",allPresetsRequired:"Alle Profile müssen ausgewählt sein",enqueuing:"Slice-Auftrag wird übermittelt…",queued:"In Warteschlange…",failed:"Slicen fehlgeschlagen. Logs des Slicer-Sidecars prüfen.",startedToast:"{{name}} wird im Hintergrund gesliced…",queuedToast:"Warteschlange: {{name}} — {{elapsed}}",runningToast:"{{name}} wird gesliced — {{elapsed}}",runningWithProgress:"{{name}} – {{stage}} ({{percent}} %) – {{elapsed}}",completedToast:"{{name}} wurde gesliced",failedToast:"Slicen von {{name}} fehlgeschlagen: {{detail}}",tier:{local:"Importiert",cloud:"Cloud",standard:"Standard"},cloud:{notAuthenticated:"In Bambu Cloud anmelden (Einstellungen → Profile → Cloud), um deine Cloud-Profile zu sehen.",expired:"Bambu-Cloud-Sitzung abgelaufen — erneut anmelden, um die Cloud-Profile zu aktualisieren.",unreachable:"Bambu Cloud ist gerade nicht erreichbar. Lokale und Standard-Profile funktionieren weiterhin."},bedType:{label:"Druckbett",auto:"Auto (aus Prozess-Profil)",coolPlate:"Cool Plate",coolPlateSuperTack:"Cool Plate SuperTack",engineering:"Engineering Plate",highTemp:"High Temp Plate",texturedPEI:"Textured PEI Plate",smoothPEI:"Smooth PEI Plate"}},spoolman:{title:"Spoolman-Integration",enabled:"Spoolman aktiviert",url:"Spoolman URL",connected:"Verbunden",disconnected:"Nicht verbunden",testConnection:"Verbindung testen",sync:"Synchronisieren",syncing:"Synchronisiert...",lastSync:"Letzte Synchronisierung",linkToSpoolman:"Mit Spoolman verknüpfen",openInSpoolman:"In Spoolman öffnen",unlinkSpool:"Spule trennen",unlinkConfirmTitle:"Spule entfernen?",unlinkConfirmMessage:"Die Spule wird vom Slot entfernt. Die Spulendaten selbst bleiben unverändert.",selectSpool:"Spule auswählen",noUnlinkedSpools:"Keine nicht zugewiesenen Spulen verfügbar",linkSuccess:"Spule erfolgreich zugewiesen",linkFailed:"Spule konnte nicht zugewiesen werden",unlinkSuccess:"Spule erfolgreich entfernt",unlinkFailed:"Spule konnte nicht entfernt werden",linkedSpool:"Zugewiesene Spule",spoolId:"Spulen-ID",fillSourceLabel:"(Spoolman)",weight:"Gewicht",remaining:"Verbleibend",disableWeightSync:"AMS-Gewichtsschätzung deaktivieren",disableWeightSyncDesc:"Verbleibende Kapazität nicht aus AMS-Schätzungen aktualisieren. Verwenden Sie dies, wenn Sie die Verbrauchserfassung von Spoolman gegenüber den prozentualen AMS-Schätzungen bevorzugen. Neue Spulen verwenden weiterhin die AMS-Schätzung als Anfangsgewicht.",reportPartialUsage:"Teilverbrauch bei fehlgeschlagenen Drucken melden",reportPartialUsageDesc:"Wenn ein Druck fehlschlägt oder abgebrochen wird, den geschätzten Filamentverbrauch bis zu diesem Zeitpunkt basierend auf dem Schichtfortschritt melden."},inventory:{title:"Spulen-Inventar",subtitle:"Verwalten Sie Ihre Spulen",spoolmanMixedContentTitle:"Spoolman lässt sich nicht über HTTPS laden — Browser blockiert gemischte Inhalte",spoolmanMixedContentBody:"Bambuddy wird über HTTPS ausgeliefert (über deinen Reverse-Proxy), aber deine Spoolman-URL ist nach wie vor HTTP. Browser blockieren gemischte Inhalte aus Sicherheitsgründen, daher kann die eingebettete Spoolman-Oberfläche nicht geladen werden. Spoolman muss ebenfalls über HTTPS erreichbar sein.",spoolmanMixedContentFixReverseProxy:"Stelle Spoolman hinter denselben Reverse-Proxy wie Bambuddy (Traefik / Nginx / Caddy) mit HTTPS und aktualisiere die Spoolman-URL in den Einstellungen auf die neue HTTPS-Adresse.",spoolmanMixedContentFixOpenNewTab:"Als Workaround kannst du Spoolman in einem neuen Tab über HTTP öffnen — gemischte Inhalte werden nur innerhalb eingebetteter Frames blockiert, ein eigener Tab funktioniert weiterhin.",spoolmanOpenInNewTab:"Spoolman in neuem Tab öffnen",labels:{title:"Spulen-Etiketten drucken",selectedCount:"{{count}} ausgewählt",pickSpools:"Wählen Sie, für welche Spulen Etiketten gedruckt werden sollen:",searchPlaceholder:"Name, Marke oder #ID suchen",filterByMaterial:"Material:",allMaterials:"Alle",selectVisible:"Alle sichtbaren auswählen ({{count}})",deselectVisible:"Sichtbare abwählen",clearAll:"Alle entfernen",noSpoolsToShow:"Keine Spulen anzuzeigen. Filter anpassen und erneut versuchen.",noMatches:"Keine Spulen entsprechen der aktuellen Suche oder dem Filter.",printOne:"Etikett für diese Spule drucken",printLabels:"Etiketten drucken…",bulkTitle:"Spulen aus den aktuell angezeigten {{count}} zum Etikettieren auswählen",noSpoolsTitle:"Keine Spulen zum Etikettieren",error:"Etiketten konnten nicht erstellt werden: {{msg}}",templates:{ams:{label:"AMS holder (30 × 15 mm)",hint:"Ein Etikett pro Seite; passt in den beliebten AMS-Filament-Etikettenhalter."},box40x30:{label:"Boxetikett (40 × 30 mm)",hint:"Ein Etikett pro Seite; gängige DK/Brother-Rollengröße, ideal für Filament-Beutel und Lager-Etiketten."},box:{label:"Box label (62 × 29 mm)",hint:"Ein Etikett pro Seite; für Brother PT/QL und Dymo-Kleinetiketten dimensioniert."},averyL7160:{label:"Avery L7160 — A4 sheet (38.1 × 63.5 mm × 21)",hint:"EU-Bogenformat; 21 Etiketten pro A4-Seite."},avery5160:{label:"Avery 5160 — US Letter sheet (25.4 × 66.7 mm × 30)",hint:"US-Bogenformat; 30 Etiketten pro Letter-Seite."}}},addSpool:"Spule hinzufügen",copySpool:"Spule kopieren",editSpool:"Spule bearbeiten",material:"Material",selectMaterial:"Material auswählen...",subtype:"Untertyp",brand:"Marke",searchBrand:"Marke suchen...",useCustomBrand:'"{{brand}}" verwenden',useCustomMaterial:"Benutzerdefiniertes Material verwenden: {{material}}",colorName:"Farbname",colorNamePlaceholder:"Jadeweiß, Feuerrot...",color:"Farbe",hexColor:"Hex-Farbe",pickColor:"Benutzerdefinierte Farbe wählen",labelWeight:"Nenngewicht",coreWeight:"Leergewicht der Spule",searchSpoolWeight:"Spulengewicht suchen...",weightUsed:"Verbraucht",currentWeight:"Restgewicht",measuredWeight:"Gemessenes Gewicht",spoolName:"Spule",costPerKg:"Kosten pro kg",storageLocation:"Lagerstandort",storageLocationPlaceholder:"z.B. Regal A, Schublade 1",openInInventory:"Im Inventar öffnen",measuredWeightError:"Das gemessene Gewicht muss zwischen {{min}}g und {{max}}g liegen.",slicerFilament:"Slicer-Filament",slicerFilamentName:"Slicer-Preset-Name",slicerPreset:"Slicer-Preset",searchPresets:"Filament-Presets suchen...",selectedPreset:"Ausgewählt",noPresetsFound:"Keine Presets gefunden",tempOverrides:"Temperatur-Überschreibungen",note:"Notiz",notePlaceholder:"Zusätzliche Notizen zu dieser Spule...",category:"Kategorie",categoryPlaceholder:"z. B. Produktion, Prototyp, Kunde A",categoryNone:"Ohne Kategorie",storageLocationNone:"Kein Lagerort",lowStockThresholdOverride:"Niedrigbestandsschwelle (diese Spule)",lowStockThresholdOverrideHelp:"Leer lassen, um den globalen Schwellenwert ({{global}}%) zu verwenden.",clearRfid:"RFID-Tag löschen",rfidCleared:"RFID-Tag gelöscht",archive:"Archivieren",restore:"Wiederherstellen",noSpools:"Noch keine Spulen. Fügen Sie Ihre erste Spule hinzu.",noAvailableSpools:"Keine Spulen verfügbar. Fügen Sie eine Spule zum Inventar hinzu oder lösen Sie eine aus einem anderen Slot.",kProfiles:"K-Profile",addKProfile:"K-Profil hinzufügen",assignSpool:"Spule zuweisen",unassignSpool:"Zuweisung aufheben",assignSuccess:"Spule zugewiesen und AMS-Slot konfiguriert",assignFailed:"Spulenzuweisung fehlgeschlagen",selectSpool:"Wählen Sie eine Spule für diesen Slot",assigned:"Zugewiesen",assigning:"Wird zugewiesen...",searchSpools:"Spulen suchen...",showAllSpools:"Alle Spulen anzeigen",spoolmanSpools:"Spoolman-Spulen",allMaterials:"Alle Materialien",filterByBrand:"Nach Marke filtern...",showArchived:"Archivierte anzeigen",quickAdd:"Schnellerfassung (Lager)",quantity:"Menge",stock:"Lager",configured:"Konfiguriert",spoolsCreated:"{{count}} Spulen erstellt",spoolsPartiallyCreated:"{{created}} von {{total}} Spulen erstellt (einige fehlgeschlagen)",spoolCreated:"Spule erstellt",spoolUpdated:"Spule aktualisiert",spoolDeleted:"Spule gelöscht",deepLinkSpoolNotFound:"Spule nicht gefunden",deepLinkFetchFailed:"Spule konnte nicht geladen werden — bitte erneut versuchen",spoolArchived:"Spule archiviert",spoolRestored:"Spule wiederhergestellt",kProfileSaveFailed:"K-Profil-Einstellungen konnten nicht gespeichert werden",syncWeightSpoolNotFound:"Spule nicht gefunden — sie wurde möglicherweise gelöscht",syncWeightSpoolmanUnreachable:"Spoolman ist nicht erreichbar — bitte später erneut versuchen",syncWeightFailed:"Gewicht konnte nicht synchronisiert werden",spoolmanUnreachable:"Spoolman ist nicht erreichbar — bitte später erneut versuchen",deleteSpoolNotFound:"Spule nicht gefunden — sie wurde möglicherweise bereits gelöscht",deleteFailed:"Spule konnte nicht gelöscht werden",archiveSpoolNotFound:"Spule nicht gefunden — sie wurde möglicherweise bereits gelöscht",archiveFailed:"Spule konnte nicht archiviert werden",restoreSpoolNotFound:"Spule nicht gefunden — sie wurde möglicherweise bereits gelöscht",restoreFailed:"Spule konnte nicht wiederhergestellt werden",saveFailed:"Änderungen konnten nicht gespeichert werden",tagClearFailed:"Tag konnte nicht gelöscht werden",deleteConfirm:"Möchten Sie diese Spule wirklich löschen? Dies kann nicht rückgängig gemacht werden.",archiveConfirm:"Möchten Sie diese Spule wirklich archivieren?",advancedSettings:"Erweiterte Einstellungen",filamentInfoTab:"Filament-Info",paProfileTab:"PA-Profil",filamentInfo:"Filament",additional:"Zusätzlich",loadingPresets:"Cloud-Presets werden geladen...",cloudConnected:"Cloud verbunden",cloudNotConnected:"Cloud nicht verbunden (Standardwerte)",recentColors:"Zuletzt",searchColors:"Farben suchen...",searchResults:"Suchergebnisse",allColors:"Alle Farben",commonColors:"Häufige Farben",showLess:"Weniger",showAll:"Alle",noColorsFound:"Keine Farben gefunden",noResults:"Keine Ergebnisse",extraColorsLabel:"Zusätzliche Farben",extraColorsPlaceholder:"EC984C,#6CD4BC,A66EB9,D87694",extraColorsHint:"2 bis 8 Hex-Stops, durch Kommas getrennt. Wird als Verlauf dargestellt.",extraColorsInvalid:"Ungültige Hex-Werte ignoriert: {{tokens}}",colorEffectLabel:"Effekt",colorEffect:{none:"Keiner",sparkle:"Glitzer",wood:"Holz",marble:"Marmor",glow:"Leuchtend",matte:"Matt",silk:"Seide",galaxy:"Galaxie",rainbow:"Regenbogen",metal:"Metallic",translucent:"Lichtdurchlässig",gradient:"Verlauf",dualColor:"Zweifarbig",triColor:"Dreifarbig",multicolor:"Mehrfarbig"},selectMaterialFirst:"Bitte zuerst ein Material im Filament-Info Tab auswählen.",noPrintersConfigured:"Keine Drucker konfiguriert. Fügen Sie Drucker hinzu.",matchingFilter:"Filter",anyBrand:"Jede Marke",anyVariant:"Jede Variante",autoSelect:"Auto-Auswahl",matches:"Treffer",match:"Treffer",noMatches:"Keine Treffer",connected:"Verbunden",offline:"Offline",printerOffline:"Drucker ist offline. Verbinden Sie ihn, um Kalibrierungsprofile anzuzeigen.",noKProfilesMatch:"Keine K-Profile stimmen mit dem gewählten Filament überein.",leftNozzle:"Linke Düse",rightNozzle:"Rechte Düse",profilesSelected:"Kalibrierungsprofil(e) ausgewählt",totalInventory:"Gesamtbestand",totalConsumed:"Gesamtverbrauch",byMaterial:"Nach Material",inPrinter:"Im Drucker",lowStock:"Niedriger Bestand",sinceTracking:"Seit Beginn der Erfassung",loadedInAms:"Im AMS/Ext geladen",remaining:"Verbleibend",weightCheck:"Gewichtskontrolle",lastWeighed:"Zuletzt gewogen",neverWeighed:"Nie gewogen",search:"Spulen suchen...",showing:"Zeige",to:"bis",of:"von",show:"Zeige",spools:"Spulen",spool:"Spule",page:"Seite",noSpoolsMatch:"Keine Ergebnisse",noSpoolsMatchDesc:"Versuchen Sie, Ihre Suche oder Filter anzupassen.",active:"Aktiv",archived:"Archiviert",all:"Alle",used:"Verwendet",new:"Neu",clearFilters:"Filter löschen",table:"Tabelle",cards:"Karten",net:"Netto",groupSimilar:"Gruppieren",groupedSpools:"{{count}} identische Spulen",groupedRows:"Zeilen",columns:"Spalten",configureColumns:"Spalten konfigurieren",configureColumnsDesc:"Ziehen zum Neuordnen oder Pfeile verwenden. Sichtbarkeit mit dem Augensymbol umschalten.",visible:"sichtbar",reset:"Zurücksetzen",cancel:"Abbrechen",applyChanges:"Änderungen anwenden",moveUp:"Nach oben",moveDown:"Nach unten",hideColumn:"Spalte ausblenden",showColumn:"Spalte einblenden",linkToSpool:"Mit Spule verknüpfen",tagLinked:"Tag mit Spule verknüpft",tagLinkFailed:"Tag-Verknüpfung fehlgeschlagen",tagAlreadyLinked:"Tag bereits mit anderer Spule verknüpft",unknownTag:"Unbekannter RFID-Tag erkannt",usageHistory:"Verbrauchshistorie",noUsageHistory:"Noch kein Verbrauch erfasst",printName:"Druckname",weightConsumed:"Verbrauchtes Gewicht",clearHistory:"Löschen",historyCleared:"Verbrauchshistorie gelöscht",fillSourceLabel:"(Inv)",lowStockThresholdError:"Der Schwellenwert muss zwischen 0.1 und 99.9 liegen",assignMismatchTitle:"Material stimmt nicht überein",assignMismatchMessage:'Das ausgewählte Spulenmaterial "{{spoolMaterial}}" stimmt nicht mit dem Tray-Material "{{trayMaterial}}" für {{location}} überein. Trotzdem zuweisen?',assignMismatchConfirm:"Trotzdem zuweisen",assignPartialMismatchMessage:'Das Spulenmaterial "{{spoolMaterial}}" ist ähnlich, stimmt aber nicht genau mit "{{trayMaterial}}" in {{location}} überein. Möchten Sie fortfahren?',assignProfileMismatchMessage:'Das Spulenprofil "{{spoolProfile}}" stimmt nicht mit dem Fachprofil "{{trayProfile}}" in {{location}} überein. Möchten Sie fortfahren?',spoolmanFilamentCatalog:"Spoolman-Filamentkatalog",pickFromSpoolmanCatalog:"Aus Spoolman-Katalog wählen…",spoolmanFilamentSelected:"Filament aus Spoolman-Katalog ausgewählt",spoolmanFilamentUnlinked:"Verknüpfung mit Filamentkatalog aufgehoben",noSpoolmanFilaments:"Keine Filamente im Spoolman-Katalog gefunden",spoolmanFilamentColorSwatch:"Filamentfarbe",spoolWeightManagedBySpoolman:"Das Leerspulengewicht wird pro Filamenttyp in Spoolman verwaltet",spoolmanCatalogLoadFailed:"Spoolman-Filamentkatalog konnte nicht geladen werden"},timelapse:{title:"Zeitraffer",create:"Zeitraffer erstellen",download:"Herunterladen",delete:"Löschen",preview:"Vorschau",frameRate:"Bildrate",quality:"Qualität",processing:"Wird verarbeitet...",noTimelapses:"Keine Zeitraffer verfügbar"},ams:{title:"AMS",slot:"Slot",empty:"Leer",emptySlot:"Leerer Slot",unknown:"Unbekannt",humidity:"Luftfeuchtigkeit",temperature:"Temperatur",filamentType:"Filamenttyp",filamentColor:"Farbe",remaining:"Verbleibend",history:"AMS-Verlauf",noHistory:"Kein Verlauf verfügbar",configureSlot:"Slot konfigurieren",externalSpool:"Externe Spule",profile:"Profil",kFactor:"K-Faktor",fill:"Füllstand",configure:"Konfigurieren",used:"verwendet",remainingUnit:"verbleibend"},printModal:{title:"Druck starten",selectPrinter:"Drucker auswählen",selectPlate:"Platte auswählen",filamentMapping:"Filamentzuordnung",totalCost:"Gesamtkosten:",slotRemainingShort:" - {{grams}}g übrig",printSettings:"Druckeinstellungen",bedLeveling:"Bett-Nivellierung",flowCalibration:"Fluss-Kalibrierung",vibrationCalibration:"Vibrations-Kalibrierung",layerInspection:"Erste-Schicht-Prüfung",timelapse:"Zeitraffer",startPrint:"Druck starten",addToQueue:"Zur Warteschlange hinzufügen",cancel:"Abbrechen",noPrintersAvailable:"Keine Drucker verfügbar",printerBusy:"Drucker ist beschäftigt",printerOffline:"Drucker ist offline",sameTypeDifferentColor:"Gleicher Typ, andere Farbe",filamentTypeNotLoaded:"Filamenttyp nicht geladen",openCalendar:"Kalender öffnen",leftNozzle:"L",rightNozzle:"R",leftNozzleTooltip:"Linke Düse",rightNozzleTooltip:"Rechte Düse",filamentOverride:"Filament-Überschreibung",filamentOverrideHint:"Filamente für modellbasierte Zuweisung optional überschreiben. Der Planer wird gegen die ausgewählten Filamente statt der ursprünglichen 3MF-Werte abgleichen.",originalFilament:"Original",overrideWith:"Ersetzen mit",resetToOriginal:"Auf Original zurücksetzen",insufficientFilamentTitle:"Nicht genug Filament",insufficientFilamentMessage:"Einige zugewiesene Spulen haben weniger Filament als dieser Druck benötigt:",insufficientFilamentLine:"{{printer}} - {{slot}}: benötigt {{required}}g, verbleibend {{remaining}}g",printAnyway:"Trotzdem drucken",forceColorMatch:"Farbe erzwingen",staggerPrinterStarts:"Druckerstarts staffeln",staggerGroupSize:"Gruppengröße",staggerInterval:"Intervall (Min.)",staggerPreview:"{{printers}} Drucker → {{groups}} Gruppen à {{size}}, Start alle {{interval}} Min.",staggerLastGroup:"letzte Gruppe: {{count}}",staggerTotal:"insgesamt: {{minutes}} Min.",staggerToPrinters:"Gestaffelt an {{count}} Drucker senden",gcodeInjection:"Auto-Print G-code einfügen"},backup:{includesEncryptionKey:"Lokale Sicherungen enthalten die MFA-Schlüsseldatei (DATA_DIR/.mfa_encryption_key), damit ein Backup-ZIP selbstkonsistent ist. Behandle das ZIP als sensibel — wer Zugriff auf die Datei hat, kann die darin enthaltenen OIDC-Client-Secrets und TOTP-Geheimnisse entschlüsseln.",title:"Sichern & Wiederherstellen",createBackup:"Sicherung erstellen",restoreBackup:"Sicherung wiederherstellen",restoreDescription:"Alle Daten aus einer Sicherungsdatei ersetzen",downloadBackup:"Sicherung herunterladen",uploadBackup:"Sicherung hochladen",lastBackup:"Letzte Sicherung",autoBackup:"Automatische Sicherung",backupNow:"Jetzt sichern",restoreWarning:"Warnung: Das Wiederherstellen einer Sicherung überschreibt alle aktuellen Daten.",includeArchives:"Archive einschließen",includeSettings:"Einstellungen einschließen",includeProfiles:"Profile einschließen",backupSuccess:"Sicherung erfolgreich erstellt",restoreSuccess:"Sicherung erfolgreich wiederhergestellt",backupFailed:"Sicherung fehlgeschlagen",restoreFailed:"Wiederherstellung fehlgeschlagen",restoreNote:"Virtueller Drucker wird während der Wiederherstellung gestoppt",githubBackup:"Git-Backup",enabled:"Aktiviert",cloudLoginRequired:"Bambu Cloud Login erforderlich. Melden Sie sich unter Profile → Cloud-Profile an, um GitHub-Backup zu aktivieren.",cloudLoginRequiredShort:"Cloud-Login erforderlich",githubDescription:"Synchronisieren Sie Ihre Profile automatisch mit einem privaten GitHub-Repository für Backup und Versionsverlauf.",repositoryUrl:"Repository-URL",repoUrlPlaceholderGitHub:"https://github.com/username/repo-name",repoUrlPlaceholderGitea:"https://gitea.example.com/username/repo-name",repoUrlPlaceholderForgejo:"https://forgejo.example.com/username/repo-name",repoUrlPlaceholderGitLab:"https://gitlab.com/username/repo-name",allowInsecureHttp:"Unsicheres HTTP erlauben",allowInsecureHttpHint:"Für selbst gehostete Instanzen in privaten Netzwerken ohne TLS aktivieren",personalAccessToken:"Persönlicher Zugriffstoken",tokenSaved:"(gespeichert)",enterNewToken:"Neuen Token eingeben zum Aktualisieren",tokenHint:"Feingranularer Token mit Lese-/Schreibberechtigung für Inhalte",branch:"Branch",provider:"Git-Anbieter",providerGitHub:"GitHub",providerGitLab:"GitLab",providerGitea:"Gitea",providerForgejo:"Forgejo",manualOnly:"Nur manuell",hourly:"Stündlich",daily:"Täglich",weekly:"Wöchentlich",includeInBackup:"In Sicherung einschließen",kProfiles:"K-Profile",kProfilesDescription:"Druckvorschub-Kalibrierung von verbundenen Druckern",noPrintersConnected:"Keine Drucker verbunden",printersConnected:"{{connected}}/{{total}} verbunden",cloudProfiles:"Cloud-Profile",cloudProfilesDescription:"Filament-, Drucker- und Prozessprofile aus der Bambu Cloud",appSettings:"App-Einstellungen",appSettingsDescription:"Bambuddy-Konfiguration (komplette Datenbank)",spoolInventory:"Spulenbestand",spoolInventoryDescription:"Filamentspulen, Nutzungsverlauf und Kostenverfolgung",printArchives:"Druckarchive",printArchivesDescription:"Druckverlauf-Metadaten (keine GCode/3MF-Dateien)",lastBackupAt:"Letzte Sicherung:",noBackupsYet:"Noch keine Sicherungen",next:"Nächste:",startingBackup:"Sicherung wird gestartet...",test:"Test",enableBackup:"Sicherung aktivieren",testConnection:"Verbindung testen",enterRepoUrl:"Repository-URL eingeben",enterRepoAndToken:"Repository-URL und Zugriffstoken eingeben",repoRequired:"Repository-URL ist erforderlich",tokenRequired:"Zugriffstoken ist erforderlich",githubBackupEnabled:"GitHub-Backup aktiviert",tokenUpdated:"Token aktualisiert",settingsSaved:"Einstellungen gespeichert",failedToSave:"Speichern fehlgeschlagen: {{message}}",backupCompleteFiles:"Sicherung abgeschlossen - {{count}} Dateien aktualisiert",backupSkippedNoChanges:"Sicherung übersprungen - keine Änderungen",backupFailed2:"Sicherung fehlgeschlagen: {{message}}",clearedLogs:"{{count}} Protokolle gelöscht",failedToClearLogs:"Protokolle löschen fehlgeschlagen: {{message}}",history:"Verlauf",clear:"Löschen",date:"Datum",status:"Status",commit:"Commit",localBackup:"Lokale Sicherung",localBackupDescription:"Erstellen Sie eine vollständige Sicherung Ihrer Bambuddy-Daten einschließlich Datenbank, Archive, Uploads und aller Dateien.",downloadBackupLabel:"Sicherung herunterladen",completeBackupZip:"Vollständige Sicherung: Datenbank + alle Dateien (ZIP)",download:"Herunterladen",preparingBackup:"Sicherung wird vorbereitet...",creatingArchive:"Sicherungsarchiv wird erstellt... Dies kann bei großen Archiven eine Weile dauern.",downloadingFile:"Sicherungsdatei wird heruntergeladen...",backupDownloaded:"Sicherung erfolgreich heruntergeladen",failedToCreateBackup:"Sicherung erstellen fehlgeschlagen: {{message}}",restore:"Wiederherstellen",restoreReplacesAll:"Wiederherstellung ersetzt alle Daten.",restoreReplacesAllDetail:"Ihre aktuelle Datenbank und Dateien werden vollständig ersetzt. Nach der Wiederherstellung ist ein Neustart erforderlich.",restoreConfirmTitle:"Sicherung wiederherstellen",restoreConfirmMessage:'Sind Sie sicher, dass Sie von "{{filename}}" wiederherstellen möchten? Dies ersetzt Ihre aktuelle Datenbank und alle Dateien vollständig. Die Anwendung muss nach der Wiederherstellung neu gestartet werden.',restoreConfirmButton:"Sicherung wiederherstellen",uploadingFile:"Sicherungsdatei wird hochgeladen...",backupRestoredRestart:"Sicherung wiederhergestellt. Bitte starten Sie Bambuddy neu.",failedToRestore:"Sicherung wiederherstellen fehlgeschlagen. Bitte überprüfen Sie das Dateiformat.",reloadNow:"Jetzt neu laden",creatingBackup:"Sicherung erstellen",restoringBackup:"Sicherung wiederherstellen",preparing:"Vorbereiten...",processing:"Verarbeiten...",doNotClosePage:"Bitte schließen Sie diese Seite nicht und navigieren Sie nicht weg. Dieser Vorgang kann bei großen Sicherungen mehrere Minuten dauern.",restoring:"Wiederherstellen...",restoreComplete:"Wiederherstellung abgeschlossen",restoreFailed2:"Wiederherstellung fehlgeschlagen",importSettings:"Einstellungen aus einer Sicherungsdatei importieren",pleaseWaitRestoring:"Bitte warten Sie, während Ihre Daten wiederhergestellt werden",selectBackupFile:"Klicken Sie, um eine Sicherungsdatei auszuwählen (.json oder .zip)",duplicateHandling:"So funktioniert die Duplikatbehandlung:",matchPrinters:"Drucker",matchPrintersBy:"abgeglichen nach Seriennummer",matchSmartPlugs:"Smart Plugs",matchSmartPlugsBy:"abgeglichen nach IP-Adresse",matchNotificationProviders:"Benachrichtigungsanbieter",matchNotificationProvidersBy:"abgeglichen nach Name",matchFilaments:"Filamente",matchFilamentsBy:"abgeglichen nach Name + Typ + Marke",matchArchives:"Archive",matchArchivesBy:"abgeglichen nach Inhaltshash (immer übersprungen)",matchPendingUploads:"Ausstehende Uploads",matchPendingUploadsBy:"abgeglichen nach Dateiname",matchSettingsTemplates:"Einstellungen & Vorlagen",matchSettingsTemplatesBy:"immer überschrieben",replaceExisting:"Vorhandene Daten ersetzen",keepExisting:"Vorhandene Daten behalten",overwriteDescription:"Bereits vorhandene Elemente mit Sicherungsdaten überschreiben",keepDescription:"Nur Elemente wiederherstellen, die noch nicht vorhanden sind",overwriteCaution:"Achtung:",overwriteWarning:"Das Überschreiben ersetzt Ihre aktuellen Konfigurationen durch Daten aus der Sicherung. Drucker-Zugangscodes werden aus Sicherheitsgründen nie überschrieben.",cancel:"Abbrechen",processingBackup:"Sicherungsdatei wird verarbeitet...",itemsRestored:"Wiederhergestellt",itemsSkipped:"Übersprungen",restored:"Wiederhergestellt",skippedAlreadyExist:"Übersprungen (bereits vorhanden)",filesCategory:"Dateien (3MF, Thumbnails, etc.)",andMore:"...und {{count}} weitere",newApiKeysGenerated:"Neue API-Schlüssel generiert",keysShownOnce:"Diese Schlüssel werden nur einmal angezeigt. Kopieren Sie sie jetzt!",copy:"Kopieren",noDataFound:"In der Sicherungsdatei wurden keine Daten zur Wiederherstellung gefunden.",close:"Schließen",scheduledBackup:"Geplante Backups",scheduledBackupDescription:"Backup-Snapshots automatisch nach Zeitplan erstellen. Ausgabeverzeichnis kann auf einen NAS oder externen Speicher gemountet werden.",frequency:"Frequenz",backupTime:"Zeit",retention:"Aufbewahrung",retentionDescription:"Anzahl der zu behaltenden Backups",outputPath:"Ausgabepfad",outputPathPlaceholder:"Standard: {{path}}",outputPathDescription:"Leer lassen für den Standardort",runNow:"Jetzt ausführen",backupFiles:"Backup-Dateien",noScheduledBackups:"Noch keine Backups",deleteBackup:"Löschen",deleteBackupConfirm:"Diese Backup-Datei löschen?",backupRunning:"Backup läuft...",scheduledBackupComplete:"Backup erfolgreich abgeschlossen",scheduledBackupFailed:"Backup fehlgeschlagen",nextBackup:"Nächstes Backup",backupSize:"Größe",utc:"UTC",defaultPathLabel:"Standard:",categories:{settings:"Einstellungen",notification_providers:"Benachrichtigungsanbieter",notification_templates:"Benachrichtigungsvorlagen",smart_plugs:"Smart Plugs",printers:"Drucker",filaments:"Filamente",maintenance_types:"Wartungstypen",archives:"Archive",projects:"Projekte",pending_uploads:"Ausstehende Uploads",external_links:"Externe Links",api_keys:"API-Schlüssel"}},tags:{title:"Tags",addTag:"Tag hinzufügen",editTag:"Tag bearbeiten",deleteTag:"Tag löschen",tagName:"Tag-Name",tagColor:"Tag-Farbe",noTags:"Keine Tags",deleteConfirm:"Möchten Sie diesen Tag wirklich löschen?",manageTags:"Tags verwalten"},uploadModal:{title:"3MF-Dateien hochladen",dragDrop:"3MF-Dateien hierher ziehen",or:"oder",browseFiles:"Dateien durchsuchen",extractionInfo:"Das Druckermodell wird automatisch aus den 3MF-Datei-Metadaten extrahiert.",uploaded:"hochgeladen",failed:"fehlgeschlagen",uploading:"Wird hochgeladen...",upload:"Hochladen",uploadFailed:"Hochladen fehlgeschlagen"},editArchive:{title:"Archiv bearbeiten",name:"Name",namePlaceholder:"Druckname",printer:"Drucker",noPrinter:"Kein Drucker",project:"Projekt",noProject:"Kein Projekt",itemsPrinted:"Gedruckte Teile",itemsPrintedHelp:"Anzahl der in diesem Druckauftrag produzierten Teile",notes:"Notizen",notesPlaceholder:"Notizen zu diesem Druck hinzufügen...",externalLink:"Externer Link",externalLinkPlaceholder:"https://printables.com/model/...",externalLinkHelp:"Link zu Printables, Thingiverse oder anderer Quelle",tags:"Tags",tagsPlaceholder:"Tags hinzufügen...",addMoreTags:"Weitere Tags hinzufügen...",matchingTags:'Übereinstimmend mit "{{query}}"',existingTags:"Vorhandene Tags",clickToAdd:"(zum Hinzufügen klicken)",status:"Status",failureReason:"Fehlergrund",selectReason:"Grund auswählen...",photos:"Fotos des Druckergebnisses",photosHelp:"Klicken Sie auf + um Fotos Ihres Druckergebnisses hinzuzufügen",printResult:"Druckergebnis",saving:"Wird gespeichert...",failureReasons:{adhesionFailure:"Haftungsfehler",spaghettiDetached:"Spaghetti / Abgelöst",layerShift:"Schichtversatz",cloggedNozzle:"Verstopfte Düse",filamentRunout:"Filament aufgebraucht",warping:"Verformung",stringing:"Fadenziehen",underExtrusion:"Unterextrusion",powerFailure:"Stromausfall",userCancelled:"Vom Benutzer abgebrochen",other:"Sonstiges"},statuses:{completed:"Abgeschlossen",failed:"Fehlgeschlagen",aborted:"Abgebrochen",printing:"Druckt"}},kProfiles:{title:"K-Profile",noPrintersConfigured:"Keine Drucker konfiguriert",addPrinterInSettings:"Fügen Sie einen Drucker in den Einstellungen hinzu, um K-Profile zu verwalten",noActivePrinters:"Keine aktiven Drucker",enablePrinterConnection:"Aktivieren Sie eine Druckerverbindung, um K-Profile anzuzeigen",loadingProfiles:"Lade K-Profile...",printerOffline:"Drucker offline",printerOfflineDesc:"Der ausgewählte Drucker ist nicht verbunden. Schalten Sie ihn ein, um K-Profile anzuzeigen.",noMatchingProfiles:"Keine passenden Profile",noMatchingProfilesDesc:"Keine Profile entsprechen Ihren Suchkriterien",noKProfiles:"Keine K-Profile",noKProfilesDesc:"Keine Druckvorschub-Profile für {{diameter}}mm Düse gefunden",createFirstProfile:"Erstes Profil erstellen",printer:"Drucker",nozzle:"Düse",refresh:"Aktualisieren",addProfile:"Profil hinzufügen",export:"Exportieren",import:"Importieren",select:"Auswählen",selectAll:"Alle auswählen",delete:"Löschen",searchPlaceholder:"Nach Name oder Filament suchen...",allExtruders:"Alle Extruder",leftOnly:"Nur links",rightOnly:"Nur rechts",allFlow:"Alle Flusstypen",hfOnly:"Nur HF",sOnly:"Nur S",sortName:"Sortieren: Name",sortKValue:"Sortieren: K-Wert",sortFilament:"Sortieren: Filament",leftExtruder:"Linker Extruder",rightExtruder:"Rechter Extruder",modal:{addTitle:"K-Profil hinzufügen",editTitle:"K-Profil bearbeiten",profileName:"Profilname",profileNamePlaceholder:"Mein PLA-Profil",kValue:"K-Wert",kValuePlaceholder:"0,020",kValueHelp:"Typischer Bereich: 0,01 - 0,06 für PLA, 0,02 - 0,10 für PETG",filament:"Filament",selectFilament:"Filament auswählen...",noFilamentsHelp:"Keine Filamente gefunden. Erstellen Sie zuerst ein K-Profil in Bambu Studio.",flowType:"Flusstyp",highFlow:"Hoher Durchfluss",standard:"Standard",nozzleSize:"Düsengröße",extruder:"Extruder",extruders:"Extruder",left:"Links",right:"Rechts",notes:"Notizen (lokal gespeichert)",notesPlaceholder:"Notizen zu diesem Profil hinzufügen...",notesHelp:"Notizen werden in Bambuddy gespeichert, nicht auf dem Drucker",syncing:"Synchronisiert mit Drucker...",savingExtruder:"Speichern auf Extruder {{current}}/{{total}}...",pleaseWait:"Bitte warten"},deleteConfirm:{title:"Profil löschen",cannotUndo:"Dies kann nicht rückgängig gemacht werden",message:'Möchten Sie "{{name}}" wirklich vom Drucker löschen?'},bulkDelete:{title:"Profile löschen",cannotUndo:"Dies kann nicht rückgängig gemacht werden",message:"Möchten Sie wirklich {{count}} ausgewählte Profile vom Drucker löschen?"},toast:{profileSaved:"K-Profil gespeichert",profilesSaved:"K-Profil auf {{count}} Extrudern gespeichert",selectAtLeastOneExtruder:"Bitte wählen Sie mindestens einen Extruder aus",profileDeleted:"K-Profil gelöscht",profilesDeleted:"{{count}} Profile gelöscht",exportedProfiles:"{{count}} Profile exportiert",importedProfiles:"{{count}} von {{total}} Profilen importiert",noProfilesToExport:"Keine Profile zum Exportieren",invalidFileFormat:"Ungültiges Dateiformat",failedToParseImport:"Import-Datei konnte nicht gelesen werden",failedToSaveBatch:"K-Profile konnten nicht gespeichert werden",noteSaved:"Notiz gespeichert",failedToSaveNote:"Notiz konnte nicht gespeichert werden"},permission:{noRead:"Sie haben keine Berechtigung, Profile zu aktualisieren",noCreate:"Sie haben keine Berechtigung, Profile hinzuzufügen",noUpdate:"Sie haben keine Berechtigung, K-Profile zu aktualisieren",noDelete:"Sie haben keine Berechtigung, K-Profile zu löschen",noExport:"Sie haben keine Berechtigung, Profile zu exportieren",noImport:"Sie haben keine Berechtigung, Profile zu importieren"}},virtualPrinter:{title:"Virtueller Drucker",running:"Läuft",stopped:"Gestoppt",description:{default:"Aktiviere einen virtuellen Drucker, der in Bambu Studio und OrcaSlicer erscheint. Dateien, die an diesen Drucker gesendet werden, werden direkt archiviert ohne zu drucken.",proxy:"Aktiviere einen Proxy, der Slicer-Datenverkehr an einen echten Drucker weiterleitet, um Ferndruck über jedes Netzwerk zu ermöglichen."},enable:{title:"Virtuellen Drucker aktivieren",visibleInSlicer:'Sichtbar als "Bambuddy" in der Slicer-Erkennung',proxyingTo:"Proxy zu {{name}}",notActive:"Nicht aktiv"},model:{title:"Druckermodell",description:"Wähle welches Druckermodell emuliert werden soll.",restartWarning:"Das Ändern des Modells startet den virtuellen Drucker neu"},accessCode:{title:"Zugangscode",isSet:"Zugangscode ist gesetzt",notSet:"Kein Zugangscode gesetzt - erforderlich zum Aktivieren",placeholder:"8-Zeichen-Code eingeben",placeholderChange:"Neuen Code eingeben zum Ändern",hint:"Muss genau 8 Zeichen lang sein. Wird von Slicern zur Authentifizierung verwendet.",charCount:"({{count}}/8)"},targetPrinter:{title:"Zieldrucker",configured:"Proxy-Ziel konfiguriert",notConfigured:"Kein Zieldrucker ausgewählt - erforderlich für Proxy-Modus",placeholder:"Drucker auswählen...",hint:"Wähle den Drucker aus, an den der Slicer-Datenverkehr weitergeleitet werden soll. Der Drucker muss im LAN-Modus sein.",noPrinters:"Keine Drucker konfiguriert. Füge zuerst einen Drucker hinzu, um den Proxy-Modus zu verwenden."},remoteInterface:{title:"Netzwerkschnittstelle überschreiben",configured:"Schnittstellenüberschreibung aktiv",optional:"Optional - verwenden wenn die automatisch erkannte IP falsch ist (z.B. mehrere NICs, Docker, VPN)",placeholder:"Automatisch erkennen (Standard)...",hint:"Überschreibt die per SSDP beworbene und im TLS-Zertifikat verwendete IP-Adresse. Nützlich wenn Bambuddy mehrere Netzwerkschnittstellen hat."},mode:{title:"Modus",archive:"Archivieren",archiveDesc:"Dateien sofort archivieren",review:"Überprüfen",reviewDesc:"Vor dem Archivieren überprüfen",queue:"Warteschlange",queueDesc:"Archivieren und zur Warteschlange hinzufügen",proxy:"Proxy",proxyDesc:"An echten Drucker weiterleiten"},autoDispatch:{title:"Automatisch starten",description:"Drucke automatisch starten, wenn sie zur Warteschlange hinzugefügt werden. Wenn deaktiviert, warten Drucke auf manuellen Start."},queueForceColorMatch:{title:"Farbabgleich erzwingen",description:"Druckaufträge nur an Drucker senden, bei denen der genaue Filament-Typ und die genaue Farbe geladen sind. Standardmäßig deaktiviert — ohne diese Option verwendet die Warteschlange nur den Drucker-Modell-Abgleich und wählt möglicherweise einen Drucker mit der falschen Farbe."},tailscaleDisabled:{title:"Tailscale-Integration",description:"Aktivieren, um diesen VP als per Tailscale erreichbar zu markieren. Zeigt die Tailscale-Adresse des Hosts an, damit du weißt, welche IP du im Slicer eintragen musst. Der CA-Import bleibt unverändert — diese Option hat keinen Einfluss auf Zertifikate."},setupRequired:{title:"Einrichtung erforderlich",description:"Die virtuelle Druckerfunktion erfordert zusätzliche Systemkonfiguration, bevor sie funktioniert. Dies beinhaltet Portweiterleitung, Firewall-Regeln und plattformspezifische Einstellungen.",readGuide:"Lese die Einrichtungsanleitung vor dem Aktivieren"},archiveNameSource:{title:"Quelle des Archivnamens",description:'Lege fest, wie neue Archive benannt werden, wenn Dateien über den virtuellen Drucker eintreffen. "Metadaten" verwendet den im 3MF eingebetteten Titel des Slicers (Standard). "Dateiname" nutzt den Dateinamen, den Bambu Studio per FTP gesendet hat — praktisch, wenn der Job im Dialog "Zum Drucker senden" umbenannt wurde.',metadata:"Metadaten",filename:"Dateiname"},howItWorks:{title:"So funktioniert es",step1:"Im selben LAN erscheinen virtuelle Drucker automatisch in deinem Slicer (Bambu Studio / OrcaSlicer). Aus anderen Netzwerken füge sie manuell per IP-Adresse und Zugangscode hinzu.",step2:'Im Archiv-, Überprüfungs- und Warteschlangen-Modus verwende die "Senden"-Funktion im Slicer, um 3MF-Dateien an Bambuddy zu senden. Der Slicer zeigt "Druck erfolgreich" — die Datei wird gespeichert, nicht gedruckt.',step3:"Im Proxy-Modus leitet der virtuelle Drucker den gesamten Datenverkehr an einen echten Drucker weiter — Drucke starten sofort wie bei einer direkten Verbindung."},status:{title:"Status-Details",printerName:"Druckername",model:"Modell",serialNumber:"Seriennummer",mode:"Modus",pendingFiles:"Ausstehende Dateien",targetPrinter:"Zieldrucker",ftpPort:"FTP-Port",mqttPort:"MQTT-Port",ftpConnections:"FTP-Verbindungen",mqttConnections:"MQTT-Verbindungen"},toast:{updated:"Virtuelle Druckereinstellungen aktualisiert",failedToUpdate:"Einstellungen konnten nicht aktualisiert werden",copyFailed:"Kopieren fehlgeschlagen — bitte Text manuell markieren",accessCodeRequired:"Bitte zuerst einen Zugangscode setzen",targetPrinterRequired:"Bitte zuerst einen Zieldrucker auswählen",bindIpRequired:"Bitte zuerst eine Bind-IP setzen",accessCodeEmpty:"Zugangscode darf nicht leer sein",accessCodeLength:"Zugangscode muss genau 8 Zeichen lang sein",created:"Virtueller Drucker erstellt",failedToCreate:"Virtueller Drucker konnte nicht erstellt werden",deleted:"Virtueller Drucker gelöscht",failedToDelete:"Virtueller Drucker konnte nicht gelöscht werden"},list:{title:"Virtuelle Drucker",add:"Hinzufügen",addFirst:"Virtuellen Drucker hinzufügen",empty:"Keine virtuellen Drucker konfiguriert. Fügen Sie einen hinzu, um zu beginnen."},bindIp:{title:"Bind-Interface",placeholder:"Interface auswählen...",hint:"Netzwerkinterface, an das dieser virtuelle Drucker gebunden wird. Muss pro Drucker eindeutig sein."},proxy:{accessCodeHint:"Im Proxy-Modus den Zugangscode des Zieldruckers im Slicer verwenden. Die Verbindung wird transparent zum echten Drucker weitergeleitet."},addDialog:{title:"Virtuellen Drucker hinzufügen",name:"Name",hint:"Sie können Zugangscode, Zieldrucker und andere Einstellungen nach dem Erstellen konfigurieren.",create:"Erstellen"},deleteConfirm:{title:"Virtuellen Drucker löschen",message:'Möchten Sie "{{name}}" wirklich löschen? Dies stoppt alle Dienste für diesen Drucker.'}},modelViewer:{openInSlicer:"Im Slicer öffnen",tabs:{model:"3D-Modell",gcode:"G-Code Vorschau"},notAvailable:"nicht verfügbar",notSliced:"nicht geslicet",plates:"Platten",allPlates:"Alle Platten",plateNumber:"Platte {{number}}",plateCount:"{{count}} Platte",plateCount_other:"{{count}} Platten",objectCount:"{{count}} Objekt",objectCount_other:"{{count}} Objekte",filamentCount:"{{count}} Filament",filamentCount_other:"{{count}} Filamente",eta:"ETA {{minutes}} Min",noPreview:"Keine Vorschau für diese Datei verfügbar",pagination:{pageOf:"Seite {{current}} von {{total}}",prev:"Zurück",next:"Weiter"},errors:{failedToLoad:"Datei konnte nicht geladen werden",noMeshes:"Keine Meshes in 3MF-Datei gefunden",unsupportedFormat:"Nicht unterstütztes Dateiformat"}},maintenanceDescriptions:{lubricateCarbonRods:"Schmiermittel auf Karbonstäbe für sanfte Bewegung auftragen",lubricateRails:"Schmiermittel auf Linearschienen für sanfte Bewegung auftragen",cleanNozzle:"Hotend und Düse reinigen, um Verstopfungen zu verhindern",checkBelts:"Riemenspannung für präzise Drucke überprüfen",cleanBuildPlate:"Druckplatte für bessere Haftung reinigen",checkExtruder:"Extruderzahnräder auf Verschleiß prüfen",checkCooling:"Sicherstellen, dass Lüfter ordnungsgemäß funktionieren",generalInspection:"Allgemeine Druckerinspektion",cleanCarbonRods:"Karbonstäbe reinigen, um Reibung zu reduzieren",lubricateSteelRods:"Schmiermittel auf Stahlstangen für sanfte Bewegung auftragen",cleanSteelRods:"Stahlstangen reinigen, um Reibung zu reduzieren",cleanLinearRails:"Linearschienen abwischen, um Staub und Schmutz zu entfernen",checkPtfeTube:"PTFE-Schlauch auf Verschleiß oder Beschädigung prüfen",replaceHepaFilter:"HEPA-Filter für Luftqualität ersetzen",replaceCarbonFilter:"Aktivkohlefilter ersetzen",lubricateLeftNozzleRail:"Linke Düsenschiene schmieren (H2-Serie)"},smartPlugs:{offline:"Offline",admin:"Admin",openPlugAdminPage:"Plug-Admin-Seite öffnen",deleteSmartPlug:"Smart Plug löschen",turnOnSmartPlug:"Smart Plug einschalten",turnOffSmartPlug:"Smart Plug ausschalten",turnOn:"Einschalten",turnOff:"Ausschalten",addSmartPlug:{scanningNetwork:"Netzwerk wird durchsucht...",chooseEntity:"Entität auswählen...",connectionFailed:"Verbindung fehlgeschlagen",searchEntities:"Entitäten suchen...",searchPowerSensors:"Leistungssensoren suchen...",searchEnergySensors:"Energiesensoren suchen...",placeholders:{plugName:"Wohnzimmer Steckdose",mqttStateOnValue:"ON, true, 1",mqttSameAsPower:"Gleich wie Leistungs-Topic oder anders"}},linkedTo:"Verbunden mit:",monitorOnly:"Nur Überwachung",alerts:"Alarme",scheduleOn:"Ein {{time}}",scheduleOff:"Aus {{time}}",on:"Ein",off:"Aus",power:"Leistung",kwhToday:"kWh Heute",settings:"Einstellungen",automationSettings:"Automatisierungseinstellungen",showInSwitchbar:"In Schaltleiste anzeigen",quickAccessSidebar:"Schnellzugriff über Seitenleiste",enabled:"Aktiviert",enableAutomation:"Automatisierung für diesen Stecker aktivieren",autoOn:"Auto Ein",autoOnDescription:"Einschalten wenn Druck startet",autoOff:"Auto Aus",autoOffDescription:"Ausschalten wenn Druck abgeschlossen (einmalig)",autoOffPersistent:"Aktiviert lassen",autoOffPersistentDescription:"Zwischen Drucken aktiviert bleiben statt einmalig",autoOffAfterDrying:"Automatisch aus nach Trocknung",autoOffAfterDryingDescription:"Ausschalten, wenn AMS-Trocknung abgeschlossen ist",delayAfterDryingMinutes:"Verzögerung nach Trocknung (Minuten)",turnOffDelayMode:"Ausschaltverzögerungsmodus",time:"Zeit",temp:"Temp.",delayMinutes:"Verzögerung (Minuten)",tempThreshold:"Temperaturschwelle (°C)",tempThresholdDescription:"Schaltet aus wenn die Düse unter diese Temperatur abkühlt",edit:"Bearbeiten",deleteConfirm:'Möchten Sie "{{name}}" wirklich löschen? Dies kann nicht rückgängig gemacht werden.',turnOnConfirm:'Möchten Sie "{{name}}" wirklich einschalten?',turnOffConfirm:'Möchten Sie "{{name}}" wirklich ausschalten? Dies unterbricht die Stromversorgung des angeschlossenen Geräts.',failedToTurn:'{{name}}" konnte nicht {{action}} werden',unknown:"Unbekannt",addTitle:"Smart Plug hinzufügen",editTitle:"Smart Plug bearbeiten",stopScanning:"Suche beenden",discoverTasmota:"Tasmota Geräte suchen",foundDevices:"{{count}} Gerät(e) gefunden - zum Auswählen klicken:",noDevicesFound:"Keine Tasmota Geräte in Ihrem Netzwerk gefunden",haNotConfigured:"Home Assistant ist nicht konfiguriert. Einrichtung unter",haSettingsPath:"Einstellungen → Netzwerk → Home Assistant",selectEntity:"Entität auswählen *",ipAddress:"IP-Adresse *",nameLabel:"Name *",username:"Benutzername",password:"Passwort",authHint:"Leer lassen, wenn Ihr Tasmota-Gerät keine Authentifizierung benötigt",linkToPrinter:"Mit Drucker verbinden",noPrinter:"Kein Drucker (nur manuelle Steuerung)",linkingDescription:"Verknüpfung ermöglicht automatisches Ein-/Ausschalten bei Druckstart/-ende",powerAlerts:"Leistungsalarme",alertAbove:"Alarm wenn über (W)",alertBelow:"Alarm wenn unter (W)",alertDescription:"Benachrichtigung wenn der Stromverbrauch diese Schwellenwerte überschreitet. Leer lassen um diese Richtung zu deaktivieren.",dailySchedule:"Tagesplan",turnOnAt:"Einschalten um",turnOffAt:"Ausschalten um",scheduleDescription:"Den Stecker automatisch täglich zu diesen Zeiten ein-/ausschalten. Leer lassen um diese Aktion zu überspringen.",showOnPrinterCard:"Auf Druckerkarte anzeigen",displayOnPrinterCard:"Schaltfläche auf Druckerkarte anzeigen",connectedResult:"Verbunden!",deviceLabel:"Gerät: {{name}} - ",stateLabel:"Status: {{state}}",test:"Test",delete:"Löschen",save:"Speichern",add:"Hinzufügen",cancel:"Abbrechen",failedToStartScan:"Suche konnte nicht gestartet werden",nameRequired:"Name ist erforderlich",entityRequired:"Entität ist für Home Assistant Stecker erforderlich",mqttTopicRequired:"Mindestens ein MQTT-Topic muss für Leistung, Energie oder Statusüberwachung konfiguriert sein",loadingEntities:"Entitäten werden geladen...",loading:"Laden...",failedToLoadEntities:"Entitäten konnten nicht geladen werden: {{error}}",noEntitiesMatching:'Keine Entitäten gefunden die "{{search}}" entsprechen',noEntitiesAvailable:"Keine Entitäten verfügbar",searchingEntities:"Alle Entitäten durchsuchen ({{count}} gefunden)",showingEntities:"Zeige switch, light, input_boolean ({{count}} verfügbar)",energyMonitoringOptional:"Energieüberwachung (Optional)",energyMonitoringHint:"Sensoren suchen und auswählen, die Leistungs-/Energiedaten liefern.",powerSensorW:"Leistungssensor (W)",energyTodayKwh:"Energie Heute (kWh)",totalEnergyKwh:"Gesamtenergie (kWh)",noMatchingSensors:"Keine passenden Sensoren",none:"Keine",mqttNotConfigured:"MQTT-Broker nicht konfiguriert. Broker-Adresse einstellen unter",mqttSettingsPath:"Einstellungen → Netzwerk → MQTT-Veröffentlichung",mqttNotConfiguredSuffix:"(Sie müssen die Veröffentlichung nicht aktivieren, nur die Broker-Details ausfüllen).",mqttMonitorOnlyDescription:"MQTT-Stecker empfangen Leistungs-/Energiedaten über MQTT-Abonnement. Ein-/Ausschalten ist nicht verfügbar - verwenden Sie Ihren MQTT-Broker oder Ihr Home-Automation-System.",powerMonitoring:"Leistungsüberwachung",energyMonitoring:"Energieüberwachung",stateMonitoring:"Statusüberwachung",optional:"optional",topic:"Thema",jsonPath:"JSON-Pfad",multiplier:"Multiplikator",onValue:"EIN-Wert",mqttPowerHint:`JSON-Pfad extrahiert Wert aus JSON-Payload (z.B. "power_l1"). Leer lassen wenn Topic rohe numerische Werte sendet. @@ -30,13 +30,13 @@ Valor ON: a string exata que significa "ON". Deixe vazio para detecção automá ON值:表示"ON"的确切字符串。留空以自动检测(ON、true、1)。`,restControl:"控制",restOnUrl:"开启 URL",restOffUrl:"关闭 URL",restOnBody:"开启请求体",restOffBody:"关闭请求体",restMethod:"HTTP 方法",restHeaders:"Custom Headers (JSON)",restStatusUrl:"状态 URL",restStatusPath:"状态 JSON 路径",restStatusOnValue:"开启值",restPowerUrl:"功率URL",restPowerPath:"功率 JSON 路径",restPowerMultiplier:"功率乘数",restEnergyUrl:"能耗URL",restEnergyPath:"能耗 JSON 路径",restEnergyMultiplier:"能耗乘数",restUrlRequired:"REST 插座至少需要一个 URL(ON 或 OFF)",restHeadersHint:'例如 {"Authorization": "Bearer your-token"}',restBodyHint:'例如 ON, {"state": "on"}',restStatusHint:"轮询当前状态的 URL",restPathHint:"例如 state 或 data.power.status",restPowerUrlHint:"功率数据的独立URL(留空则使用状态URL)",restEnergyUrlHint:"能耗数据的独立URL(留空则使用状态URL)",restEnergyHint:"每个值可以使用独立的URL,或回退到状态URL。使用乘数进行单位转换(例如:0.001 将 Wh 转换为 kWh)。",testConnection:"测试连接",connectionSuccess:"连接成功",noSwitchesInSwitchbar:"开关栏中没有开关",enableSwitchbarHint:'在设置 > 智能插座中启用"在开关栏显示"'},notifications:{providerTypes:{callmebot:"CallMeBot/WhatsApp",ntfy:"ntfy",pushover:"Pushover",telegram:"Telegram",email:"电子邮件",discord:"Discord",webhook:"Webhook",homeassistant:"Home Assistant"},providerDescriptions:{email:"SMTP 电子邮件通知",telegram:"通过 Telegram 机器人发送通知",discord:"通过 Webhook 发送到 Discord 频道",ntfy:"免费、可自托管的推送通知",pushover:"简单、可靠的推送通知",callmebot:"通过 CallMeBot 免费发送 WhatsApp 通知",webhook:"通用 HTTP POST 到任意 URL",homeassistant:"Home Assistant 仪表板中的持久通知"},lastSuccess:"上次:{{date}}",error:"错误",printer:"打印机:",allPrinters:"所有打印机",sendTestNotification:"发送测试通知",eventSettings:"事件设置",enabled:"已启用",sendFromProvider:"从此提供商发送通知",printEvents:"打印事件",printerStatus:"打印机状态",amsAlarms:"AMS 警报",amsHtAlarms:"AMS-HT 警报",printQueue:"打印队列",start:"开始",plateCheck:"热床检测",complete:"完成",failed:"失败",stopped:"已停止",progress:"进度",offline:"离线",lowFilament:"耗材不足",maintenance:"维护",amsHumidity:"AMS 湿度",amsTemp:"AMS 温度",amsHtHumidity:"AMS-HT 湿度",amsHtTemp:"AMS-HT 温度",bedCooled:"热床已冷却",firstLayer:"首层完成",quiet:"免打扰",digest:"摘要 {{time}}",printStarted:"打印已开始",plateNotEmpty:"热床非空",plateNotEmptyDescription:"打印前检测到物体",printCompleted:"打印已完成",bedCooledLabel:"热床已冷却",bedCooledDescription:"打印后热床温度降至阈值以下",firstLayerCompleteLabel:"首层打印完成",firstLayerCompleteDescription:"首层完成时发送带照片的通知",missingSpoolAssignmentLabel:"缺少料卷分配",missingSpoolAssignmentDescription:"当打印开始且所需料盘没有分配料卷时发送通知",printFailed:"打印失败",printStopped:"打印已停止",progressMilestones:"进度里程碑",progressMilestonesDescription:"在 25%、50%、75% 时通知",printerOffline:"打印机离线",printerError:"打印机错误",lowFilamentLabel:"耗材不足",maintenanceDue:"需要维护",maintenanceDueDescription:"需要维护时通知",amsHumidityHigh:"AMS 湿度过高",amsHumidityHighDescription:"普通 AMS 湿度超过阈值",amsTemperatureHigh:"AMS 温度过高",amsTemperatureHighDescription:"普通 AMS 温度超过阈值",amsHtHumidityHigh:"AMS-HT 湿度过高",amsHtHumidityHighDescription:"AMS-HT 湿度超过阈值",amsHtTemperatureHigh:"AMS-HT 温度过高",amsHtTemperatureHighDescription:"AMS-HT 温度超过阈值",inventoryAlerts:"库存警报",stockReorderAlert:"补货警报",stockReorderAlertDescription:"SKU 已达到补货点",stockBreakAlert:"断货警报",stockBreakAlertDescription:"库存将在补货到达前耗尽",jobAdded:"任务已添加",jobAddedDescription:"任务已添加到队列",jobAssigned:"任务已分配",jobAssignedDescription:"基于模型的任务已分配给打印机",jobStarted:"任务已开始",jobStartedDescription:"队列任务已开始打印",jobWaiting:"任务等待中",jobWaitingDescription:"任务正在等待耗材或打印机",jobSkipped:"任务已跳过",jobSkippedDescription:"任务已跳过(上一个失败)",jobFailed:"任务失败",jobFailedDescription:"任务启动失败",queueComplete:"队列已完成",queueCompleteDescription:"所有队列任务已完成",quietHours:"免打扰时段",noNotificationsDuring:"在此时段内不发送通知",editProviderToChangeQuietHours:"编辑提供商以更改免打扰时段",dailyDigest:"每日摘要",batchNotifications:"将通知汇总为每日摘要",sendAt:"发送于 {{time}}",editProviderToChangeDigestTime:"编辑提供商以更改摘要时间",edit:"编辑",deleteProvider:"删除通知提供商",deleteConfirm:'确定要删除"{{name}}"吗?此操作无法撤销。',delete:"删除",addTitle:"添加通知提供商",editTitle:"编辑通知提供商",nameLabel:"名称 *",namePlaceholder:"我的通知",providerTypeLabel:"提供商类型 *",configuration:"配置",testConfiguration:"测试配置",printerFilter:"打印机筛选",onlyFromPrinter:"仅发送来自此打印机的事件通知",quietHoursDnd:"免打扰时段",quietStart:"开始",quietEnd:"结束",dailyDigestLabel:"每日摘要",sendDigestAt:"发送摘要于",digestCollected:"事件将被收集并在此时间作为单条摘要发送",notificationEvents:"通知事件",progressPercent:"(25%、50%、75%)",bedCooledAfterPrint:"(打印完成后)",eventPriority:{sectionTitle:"ntfy 优先级",helpNtfy:"为每个已启用的事件选择优先级。ntfy 使用它来升级提醒(声音、可见性、推送行为)。此处未设置的级别将使用 ntfy 服务器默认值。",min:"最低",low:"低",default:"默认",high:"高",urgent:"紧急"},cancel:"取消",save:"保存",add:"添加",nameRequired:"名称为必填项",fieldRequired:"{{field}}为必填项",phoneNumber:"电话号码",apiKey:"API 密钥",serverUrl:"服务器 URL",topic:"主题",authToken:"认证令牌",userKey:"用户密钥",appToken:"应用令牌",priority:"优先级",botToken:"机器人令牌",chatId:"聊天 ID",smtpServer:"SMTP 服务器",smtpPort:"SMTP 端口",security:"安全",authentication:"认证",username:"用户名",password:"密码",fromEmail:"发件人邮箱",toEmail:"收件人邮箱",webhookUrl:"Webhook URL",payloadFormat:"负载格式",authorization:"授权",titleFieldName:"标题字段名",messageFieldName:"消息字段名",editTemplate:"编辑模板:{{name}}",titleLabel:"标题",bodyLabel:"正文",titlePlaceholder:"通知标题...",bodyPlaceholder:"通知正文...",availableVariables:"可用变量",clickToInsert:"点击插入到正文光标位置",livePreview:"实时预览",hide:"隐藏",show:"显示",loadingPreview:"加载预览中...",enterTemplateContent:"输入模板内容以查看预览",titlePreview:"标题:",bodyPreview:"正文:",resetToDefault:"恢复默认",titleRequired:"标题为必填项",bodyRequired:"正文为必填项",notificationLog:"通知日志",showFailedOnly:"仅显示失败",last24Hours:"最近 24 小时",last7Days:"最近 7 天",last30Days:"最近 30 天",last90Days:"最近 90 天",justNow:"刚刚",noFailedNotifications:"没有失败的通知",noNotificationsLogged:"没有通知记录",unknownProvider:"未知提供商",logTitle:"标题",logMessage:"消息",logError:"错误",logProvider:"提供商:{{type}}",logTime:"时间:{{time}}",refresh:"刷新",clearOld:"清除旧记录",statsSummary:"最近 {{days}} 天:",statsNotifications:"条通知",statsSent:"{{count}} 条已发送",statsFailed:"{{count}} 条失败",eventTypes:{print_start:"打印已开始",print_complete:"打印完成",print_failed:"打印失败",print_stopped:"打印已停止",print_progress:"进度",printer_offline:"打印机离线",printer_error:"打印机错误",filament_low:"耗材不足",maintenance_due:"需要维护",test:"测试"},userEmail:{title:"通知",emailNotifications:"邮件通知",emailNotificationsDesc:"接收您自己打印任务的邮件通知。邮件将通过高级身份验证中配置的 SMTP 设置发送。",sendingTo:"通知将发送至",noEmailWarning:"您的账户没有邮件地址。请联系管理员添加。",printJobNotifications:"打印任务通知",printJobNotificationsDesc:"选择哪些事件会触发您提交的打印任务的邮件通知。",printJobStarts:"打印任务开始",printJobStartsDesc:"当您的打印任务开始时收到通知。",printJobFinishes:"打印任务完成",printJobFinishesDesc:"当您的打印任务成功完成时收到通知。",printErrors:"打印错误",printErrorsDesc:"当您的打印任务失败或遇到错误时收到通知。",printJobStops:"打印任务停止",printJobStopsDesc:"当您的打印任务被取消或停止时收到通知。",saveSuccess:"通知偏好设置已保存。",saveError:"保存通知偏好设置失败。"}},richTextEditor:{bold:"粗体",italic:"斜体",underline:"下划线",bulletList:"无序列表",numberedList:"有序列表",alignLeft:"左对齐",alignCenter:"居中对齐",alignRight:"右对齐",addLink:"添加链接",removeLink:"移除链接"},externalLinks:{noLinksConfigured:"未配置外部链接",deleteLink:"删除链接",removeCustomIcon:"移除自定义图标",openInNewTab:"在新标签页中打开",placeholders:{linkName:"我的链接"}},keyboardShortcuts:{title:"键盘快捷键",navigation:"导航",archivesSection:"归档",kProfilesSection:"K 值配置",generalSection:"通用",shortcuts:{goToPrinters:"前往打印机",goToArchives:"前往归档",goToQueue:"前往队列",goToStats:"前往统计",goToProfiles:"前往云端配置",goToSettings:"前往设置",focusSearch:"聚焦搜索",openUploadModal:"打开上传对话框",clearSelection:"清除选择 / 取消焦点",contextMenu:"卡片右键菜单",refreshProfiles:"刷新配置",newProfile:"新建配置",exitSelectionMode:"退出选择模式",showHelp:"显示此帮助"},footer:"按 Esc 或点击外部关闭"},notificationLog:{title:"通知日志",events:{printStarted:"打印开始",printComplete:"打印完成",printFailed:"打印失败",printStopped:"打印停止",progress:"进度",printerOffline:"打印机离线",printerError:"打印机错误",lowFilament:"耗材不足",maintenanceDue:"维护到期",test:"测试"},timeAgo:{justNow:"刚刚",minutesAgo:"{{minutes}} 分钟前",hoursAgo:"{{hours}} 小时前"}},restoreBackup:{title:"恢复备份",restoring:"恢复中...",restoreComplete:"恢复完成",restoreFailed:"恢复失败",importSettings:"从备份文件导入设置",pleaseWait:"请稍候,正在恢复您的数据",clickToSelect:"点击选择备份文件(.json 或 .zip)",howDuplicateHandling:"重复处理方式:",categories:{printers:"打印机",smartPlugs:"智能插座",notificationProviders:"通知提供商",filaments:"耗材",archives:"归档",pendingUploads:"待处理上传",settingsTemplates:"设置和模板"},matchingInfo:{printers:"按序列号匹配",smartPlugs:"按 IP 地址匹配",notificationProviders:"按名称匹配",filaments:"按名称 + 类型 + 品牌匹配",archives:"按内容哈希匹配",pendingUploads:"按文件名匹配",settingsTemplates:"始终覆盖"},replaceExisting:"替换现有数据",keepExisting:"保留现有数据",replaceDescription:"用备份数据覆盖已存在的项目",keepDescription:"仅恢复不存在的项目",caution:"注意:",cautionText:"覆盖将用备份数据替换您当前的配置。出于安全考虑,打印机访问码永远不会被覆盖。",itemsRestored:"已恢复项目",itemsSkipped:"已跳过项目",restored:"已恢复",skipped:"已跳过(已存在)",filesLabel:"文件(3MF、缩略图等)",newApiKeysGenerated:"已生成新 API 密钥",newApiKeysWarning:"这些密钥仅显示一次。请立即复制!",processingBackup:"处理备份文件中...",noDataFound:"备份文件中未找到可恢复的数据。",failedToRestore:"恢复备份失败。请检查文件格式。"},backupExport:{title:"导出备份",selectData:"选择要包含的数据",selectAll:"全选",selectNone:"全不选",categoryDescriptions:{settings:"语言、主题、更新偏好",notifications:"ntfy、Pushover、Discord 等",templates:"自定义消息模板",smartPlugs:"Tasmota 插座配置",externalLinks:"侧边栏外部服务链接",printers:"打印机信息(不含访问码)",plateDetection:"空打印板参考图像",filaments:"耗材类型和成本",maintenance:"自定义维护计划",archives:"所有打印数据 + 文件(3MF、缩略图、照片)",projects:"项目、材料清单和附件",pendingUploads:"虚拟打印机待审核的上传",apiKeys:"Webhook API 密钥(导入时生成新密钥)"},requiresPrinters:"需要选择打印机",zipFileWarning:"将创建 ZIP 文件。",zipFileDescription:"包括所有 3MF 文件、缩略图、延时摄影和照片。这可能需要一些时间并生成较大的文件。",includeAccessCodes:"包含访问码",includeAccessCodesDescription:"用于转移到另一台机器",includeAccessCodesWarning:"访问码将以明文形式包含。请妥善保管此备份文件!",categoriesSelected:"已选择 {{selectedCount}} 个类别"},pendingUploads:{placeholders:{notes:"添加关于此打印的备注..."},discardUpload:"丢弃上传",archiveAllUploads:"归档所有上传",discardAllUploads:"丢弃所有上传",archive:"归档",timeAgo:{justNow:"刚刚",minutesAgo:"{{minutes}} 分钟前",hoursAgo:"{{hours}} 小时前",daysAgo:"{{days}} 天前"}},apiBrowser:{placeholders:{requestBody:"JSON 请求体...",searchEndpoints:"搜索端点..."}},configureAmsSlot:{title:"配置 AMS 槽位",slotConfigured:"槽位已配置!",configuringSlot:"正在配置槽位:",slotLabel:"{{ams}} 槽位 {{slot}}",searchPresets:"搜索预设...",colorPlaceholder:"颜色名称或十六进制(例如:棕色、FF8800)",clearCustomColor:"清除自定义颜色",noCloudPresets:"无云端预设。登录拓竹云以同步。",noPresetsAvailable:"无可用预设。登录拓竹云或导入本地配置。",noMatchingPresets:"未找到匹配的预设。",custom:"自定义",builtin:"内置",settingsSentToPrinter:"设置已发送到打印机",filamentProfile:"耗材配置",kProfileLabel:"K 值配置(压力推进)",filteringFor:"筛选:{{material}}",noKProfile:"无 K 值配置(使用默认值 0.020)",noMatchingKProfiles:"未找到匹配的 K 值配置。将使用默认 K=0.020。",selectFilamentFirst:"请先选择耗材配置",kFromCalibration:"K={{value}}(来自打印机校准)",customColorLabel:"自定义颜色(可选)",presetColors:"{{name}} 颜色:",showLessColors:"显示更少颜色",showMoreColors:"显示更多颜色",clear:"清除",hexLabel:"十六进制:#{{hex}}",resetting:"重置中...",resetSlot:"重置槽位",cancel:"取消",configuring:"配置中...",configureSlot:"配置槽位"},githubBackup:{title:"Git 备份",history:"历史",downloadBackup:"下载备份",restoreBackup:"恢复备份",noBackupsYet:"暂无备份"},emailSettings:{placeholders:{fromName:"Bambuddy"}},tagManagement:{searchTags:"搜索标签...",renameTag:"重命名标签",deleteTag:"删除标签"},notificationTemplates:{placeholders:{title:"通知标题...",body:"通知正文..."}},batchTag:{placeholders:{newTag:"输入新标签..."}},photoGallery:{deletePhoto:"删除照片"},filamentHoverCard:{copySpoolUuid:"复制耗材 UUID"},kProfilesView:{hasNote:"有备注",copyProfile:"复制配置"},layout:{openMenu:"打开菜单",noPermissionSystemInfo:"您没有查看系统信息的权限"},dashboard:{dragToReorder:"拖动以重新排列",hideWidget:"隐藏小部件"},notificationProviderCard:{deleteNotificationProvider:"删除通知提供商"},fileManagerModal:{closeFileManager:"关闭文件管理器",sortFiles:"排序文件",goToParentFolder:"返回上级文件夹",threeView:"3D 视图"},embeddedCameraViewer:{refreshStream:"刷新流",close:"关闭",zoomOut:"缩小",resetZoom:"重置缩放",zoomIn:"放大",dragToResize:"拖动调整大小"},timelapseViewer:{skipBack5s:"后退 5 秒",skipForward5s:"前进 5 秒"},notificationProviders:{descriptions:{email:"SMTP 邮件通知",telegram:"通过 Telegram 机器人通知",discord:"通过 Webhook 发送到 Discord 频道",ntfy:"免费、可自托管的推送通知",pushover:"简单、可靠的推送通知",callmebot:"通过 CallMeBot 的免费 WhatsApp 通知",webhook:"通用 HTTP POST 到任意 URL"}},logViewer:{searchPlaceholder:"搜索消息或日志名称...",noLogEntries:"未找到日志条目"},switchbarPopover:{noSwitchesInSwitchbar:"切换栏中没有开关"},projectPageModal:{placeholders:{title:"标题",designer:"设计师",license:"许可证",description:"输入描述...",profileTitle:"配置标题",profileDescription:"配置描述..."}},spoolmanSettings:{},time:{unknown:"-",waiting:"等待中",justNow:"刚刚",now:"现在",minsAgo:"{{count}} 分钟前",inMins:"{{count}} 分钟后",hoursAgo:"{{count}} 小时前",inHours:"{{count}} 小时后",daysAgo:"{{count}} 天前",inDays:"{{count}} 天后"},spoolbuddy:{nav:{dashboard:"仪表板",ams:"AMS",inventory:"库存",writeTag:"写入",settings:"设置"},status:{nfcReady:"NFC 就绪",nfcOff:"NFC 关闭",offline:"离线",online:"在线",noPrinters:"无打印机",deviceOffline:"设备离线",waitingConnection:"等待设备连接...",systemReady:"系统就绪",status:"状态"},dashboard:{readyToScan:"准备扫描",idleMessage:"将耗材放在秤上以识别",nfcHint:"NFC 标签将自动读取",device:"设备",syncWeight:"同步重量",weightSynced:"已同步!",unknownTag:"未知标签",newTag:"检测到新标签",onScale:"在秤上",linkSpool:"链接到耗材",linkTagTitle:"将标签链接到耗材",linkTag:"链接标签",selectSpool:"选择要链接此标签的耗材:",noUntagged:"未找到没有标签的耗材",tagDetected:"检测到标签",noTag:"无标签",tagId:"标签",grossWeight:"毛重",spoolSize:"耗材盘尺寸",close:"关闭",currentSpool:"当前耗材",plateReady:"热床就绪: {{name}}",plateReadyLabel:"待清理的热床",plateClearAction:"清理",plateClearedToast:"已将热床标记为已清理",plateClearFailed:"无法将热床标记为已清理"},modal:{spoolDetected:"检测到耗材",assignToAms:"分配到 AMS",syncWeight:"同步重量",weightSynced:"已同步!",syncing:"同步中...",newTagDetected:"检测到新标签",addToInventory:"添加到库存",assignToAmsTitle:"分配到 AMS",selectSlot:"选择槽位",assign:"分配",assigning:"分配中...",assignSuccess:"已分配!",assignPendingInsert:"已分配。插入耗材后将配置槽位。",assignError:"分配耗材失败。请重试。",noPrinterSelected:"选择打印机...",noAmsDetected:"此打印机未检测到 AMS",slot:"槽位"},weight:{noReading:"无读数",stable:"稳定",measuring:"测量中...",tare:"去皮",calibrate:"校准"},spool:{remaining:"剩余",material:"材料",brand:"品牌",color:"颜色",coreWeight:"空盘",labelWeight:"标签",scaleWeight:"秤重",netWeight:"净重",lastUsed:"上次使用"},ams:{noData:"未检测到 AMS",connectAms:"连接 AMS 以查看耗材槽位",noPrinter:"未选择打印机",selectPrinter:"从顶部栏选择打印机",printerDisconnected:"打印机已断开",humidity:"湿度",level:"余量",active:"活跃",slot:"槽位",empty:"空"},inventory:{search:"搜索耗材...",empty:"库存中没有耗材",noResults:"没有匹配的耗材",spools:"个耗材",addSpool:"添加耗材"},settings:{tabDevice:"设备",tabDisplay:"显示",tabScale:"秤",tabUpdates:"更新",nfcReader:"NFC 读卡器",type:"类型",connection:"连接",notConnected:"不适用",deviceInfo:"设备信息",hostname:"主机",uptime:"运行时间",systemConfig:"后端与认证",backendUrl:"Bambuddy 后端 URL",apiToken:"API 令牌",apiTokenPlaceholder:"输入 API 令牌",saveConfig:"保存配置",systemQueued:"配置已加入队列。",nfcDiagnostic:"NFC 诊断",scaleDiagnostic:"秤诊断",readTagDiagnostic:"读取标签诊断",testNfc:"测试读卡器",testScale:"测试精度",testReadTag:"读取标签",systemFieldsRequired:"后端 URL 为必填项。",brightness:"亮度",saved:"已保存",noBacklight:"未检测到 DSI 背光。亮度控制需要 DSI 显示屏。",screenBlank:"屏幕熄灭超时",screenBlankDesc:"不活动后屏幕关闭。触摸唤醒。",displayNote:"亮度作为软件滤镜应用。",scaleCalibration:"秤校准",currentWeight:"当前重量",tareOffset:"去皮",calFactor:"系数",knownWeight:"已知重量",calStep1:"移除秤上所有物品并按设置零点。",calStep2:"将已知重量放在秤上。",setZero:"设置零点",calibrateNow:"校准",calibrated:"已校准",tareSet:"去皮命令已发送。等待设备响应...",tareFailed:"发送去皮命令失败",zeroSet:"零点已设置。将已知重量放在秤上。",calibrationDone:"校准完成!",calibrationFailed:"校准失败",lastCalibrated:"上次校准",stable:"稳定",settling:"稳定中...",firmware:"固件",scale:"秤",noDevice:"未找到 SpoolBuddy 设备",daemonVersion:"守护进程版本",currentVersion:"当前",versionPending:"等待守护进程...",checking:"检查中...",checkUpdates:"检查更新",updateAvailable:"有可用更新",updateInstructions:"通过 SSH 更新:运行 SpoolBuddy 安装脚本进行升级。",upToDate:"已是最新",includeBeta:"包含测试版本"},writeTag:{tabExisting:"现有耗材",tabNew:"新耗材",tabReplace:"替换标签",searchPlaceholder:"按材料、颜色、品牌搜索...",noUntaggedSpools:"没有无标签的耗材",noTaggedSpools:"没有有标签的耗材",selectSpool:"选择一个耗材,然后将空白 NTAG 放在读卡器上",placeTag:"将 NTAG 放在读卡器上",tagReady:"检测到标签 — 准备写入",writeTag:"写入标签",replaceTag:"替换标签",writing:"写入标签中...",waiting:"等待 SpoolBuddy...",writeSuccess:"标签写入成功!",writeFailed:"写入失败",queueFailed:"排队写入命令失败",tryAgain:"重试",cancel:"取消",replaceWarning:"旧标签将被取消链接。新标签将替换它。",deviceOffline:"SpoolBuddy 离线",material:"材料",colorName:"颜色名称",color:"颜色",brand:"品牌",weight:"重量 (g)",createSpool:"创建耗材",creating:"创建中...",spoolCreated:"耗材已创建!准备写入。",createFailed:"创建耗材失败",incompleteDataWarning:"已使用不完整的Spoolman数据写入标签"},quickMenu:{printerPower:"打印机电源",systemControls:"系统",restartDaemon:"重启守护进程",restartBrowser:"重启浏览器",reboot:"重启",shutdown:"关机",swipeToClose:"向下滑动关闭",confirmTitle:"确认",confirmShutdown:"确定要关闭SpoolBuddy吗?您需要物理访问才能重新开启。",confirmReboot:"确定要重启SpoolBuddy吗?",confirmRestartDaemon:"重启SpoolBuddy守护进程?NFC和秤将暂时不可用。",confirmRestartBrowser:"重启kiosk浏览器?屏幕将短暂变黑。",confirm:"确认",confirmPlugOn:"开启 {{name}}?",confirmPlugOff:"关闭 {{name}}?",turnOn:"开启",turnOff:"关闭"}},bugReport:{title:"报告错误",description:"描述",descriptionPlaceholder:"出了什么问题?请描述问题...",email:"邮箱(可选)",emailPlaceholder:"your@email.com",emailPrivacy:"如果提供,您的邮箱将包含在GitHub Issue的折叠部分中,以便维护者后续跟进。",screenshot:"截图",uploadOrPaste:"上传、粘贴或拖拽图片",dataCollectedSummary:"报告中包含哪些数据?",dataIncluded:"包含:",dataIncludedList:"应用版本、操作系统、架构、Python版本、数据库统计(仅计数)、打印机型号、喷嘴数量、固件版本、连接状态、集成状态(Spoolman、MQTT、HA)、非敏感设置、网络接口数量、Docker详情、依赖版本。",dataNeverIncluded:"绝不包含:",dataNeverIncludedList:"打印机名称、序列号、访问代码、密码、IP地址、邮箱地址、API密钥、令牌、Webhook URL、主机名或用户名。",submit:"提交",startLogging:"开始调试日志",stepEnableLogging:"调试日志已启用",stepReproduce:"请现在重现问题",stepStopLogging:"停止并提交报告",stopAndSubmit:"停止并提交",maxDuration:"{{minutes}}分钟后自动停止",stoppingLogs:"正在收集日志并提交...",submitting:"正在提交错误报告...",submitSuccess:"错误报告提交成功!",submitFailed:"提交错误报告失败",thankYou:"谢谢!",submitted:"您的错误报告已提交。",viewIssue:"查看Issue",unexpectedError:"发生了意外错误"},failureDetection:{title:"AI 故障检测",description:"通过自托管的 Obico ML API 监控打印,并对检测到的故障自动采取行动。",mlUrl:"Obico ML API 地址",mlUrlHint:"您自托管的 Obico ml_api 容器的基础 URL(例如 http://192.168.1.10:3333)。",test:"测试",testSuccess:"ML API 可访问且正常。",testFailed:"无法访问 ML API。",sensitivity:"灵敏度",sensitivityLow:"低(减少误报)",sensitivityMedium:"中(平衡)",sensitivityHigh:"高(更早检测,更多误报)",sensitivityHint:"调整触发警告和故障的置信度阈值。",action:"检测到故障时的操作",actionNotify:"仅通知",actionPause:"暂停打印",actionPauseOff:"暂停并切断电源",pollInterval:"检查间隔(秒)",pollIntervalHint:"打印过程中每台打印机的检查频率。最小 5 秒,最大 120 秒。",externalUrlMissing:"未设置外部 URL。",externalUrlHint:"ML API 通过 URL 获取摄像头快照。请在通用设置中设置外部 URL,以便 ML API 容器可以访问 Bambuddy。",perPrinterTitle:"监控的打印机",perPrinterHint:"选择检测服务要监视哪些打印机。",monitorAll:"监控所有已连接的打印机",statusTitle:"状态",serviceRunning:"服务运行中",thresholds:"低 / 高阈值",activePrinters:"活动打印",noActivePrints:"当前没有正在进行的打印。",historyTitle:"最近检测",noHistory:"暂无检测记录。"},makerworld:{title:"MakerWorld",description:"粘贴 MakerWorld 模型链接,即可直接在 Bambuddy 中导入并打印 —— 无需切换到 Bambu Handy 应用。",pasteUrlHeader:"从 MakerWorld 导入",pasteUrlPlaceholder:"https://makerworld.com/en/models/… 或粘贴任意 MakerWorld 链接",resolveButton:"解析",signInRequiredTitle:"下载需要登录 Bambu Cloud",signInRequiredBody:"您可以匿名浏览模型详情,但下载 3MF 文件需要 Bambu Cloud 账户。",openCloudSettings:"打开云设置",untitledModel:"无标题模型",byCreator:"作者: {{name}}",downloadsCount:"{{count}} 次下载",licensePrefix:"许可协议",alreadyImported:"已在资料库中",openOnMakerworld:"在 MakerWorld 中打开",alreadyInLibrary:"此模型已在您的资料库中 —— 可在文件管理器 → MakerWorld 中找到",importSuccess:"已导入 {{filename}} —— 已保存到文件管理器 → MakerWorld",platesHeader:"打印板 ({{count}})",plateDefaultName:"打印板 {{n}}",materialCount:"{{count}} 种耗材",amsRequired:"需要 AMS",slicedFor:"为 {{printer}} 切片",alsoCompatible:"还标记为兼容:{{printers}}",importToLibrary:"保存",sliceIn:"保存并在 {{slicer}} 中切片",disclaimer:"MakerWorld 集成使用由社区记录的 API 接口。Bambuddy 与 MakerWorld 或 Bambu Lab 没有从属或认可关系。",lastImportSuccess:"已导入到您的资料库",lastImportAlreadyInLibrary:"已存在于您的资料库中",viewInLibrary:"在文件管理器中查看",openInBambuStudio:"在 Bambu Studio 中打开",openInOrcaSlicer:"在 OrcaSlicer 中打开",importTo:"导入到文件管理器",recentImportsHeader:"最近导入",phaseResolving:"解析中",phaseDownloading:"下载中",folderAuto:"MakerWorld (默认)",importAll:"全部导入",importAllProgress:"正在导入 {{current}}/{{total}}",openGallery:"打开图片库",galleryPrev:"上一张",galleryNext:"下一张",deleteImport:"从资料库中移除",importDeleting:"正在移除…",importDeleted:"已从资料库中移除",confirmDelete:"从资料库中移除 {{filename}}?本地文件将被删除,但可以从 MakerWorld 重新导入。",errors:{resolveFailed:"无法解析该 MakerWorld 链接。",downloadFailed:"下载失败。请重试。",deleteFailed:"无法从资料库中移除文件。"}},gcodeViewer:{back:"返回",backToArchives:"返回打印归档",backToFiles:"返回文件管理器"},libraryTrash:{title:"回收站",headerButton:"回收站",headerTooltip:"查看已移至回收站的文件",backToFiles:"返回文件管理器",subtitleAdmin:"已删除的文件会在回收站保留 {{days}} 天,之后自动删除。此视图显示所有用户的回收站。",subtitleUser:"已删除的文件会在回收站保留 {{days}} 天,之后自动删除。",loading:"正在加载回收站…",loadError:"无法加载回收站。",empty:"回收站为空。",summary:"{{count}} 个文件 · {{size}}",emptyTrash:"清空回收站",restore:"还原",purgeNow:"立即删除",autoPurgeIn:"将于 {{when}} 自动删除",days:"天",retentionLabel:"自动删除时间",selectAll:"全选",selectOne:"选择 {{filename}}",selectionCount:"已选择 {{count}} 项",bulkRestore:"还原所选",bulkPurge:"删除所选",col:{filename:"文件",folder:"文件夹",size:"大小",deleted:"移入回收站",autoPurge:"自动删除",owner:"所有者",actions:"操作"},confirm:{purgeTitle:"永久删除?",purgeBody:"{{filename}} 将从磁盘中删除,无法恢复。",emptyTitle:"清空回收站?",emptyBody:"全部 {{count}} 个文件将从磁盘中删除。此操作无法撤消。",bulkPurgeTitle:"永久删除所选文件?",bulkPurgeBody:"所选的 {{count}} 个文件将从磁盘中删除,无法恢复。",cta:"永久删除"},toast:{restored:"文件已还原。",restoreFailed:"无法还原文件。",purged:"文件已永久删除。",purgeFailed:"无法删除文件。",emptied:"已从回收站删除 {{count}} 个文件。",emptyFailed:"无法清空回收站。",retentionSaved:"自动删除已设置为 {{days}} 天。",retentionFailed:"无法保存保留设置。",bulkRestored:"已还原 {{count}} 个文件。",bulkPurged:"已删除 {{count}} 个文件。"}},libraryPurge:{title:"清理旧文件",headerButton:"清理旧文件",headerTooltip:"批量将旧文件移至回收站",description:"早于所选阈值的文件将被移至回收站。外部文件夹会被跳过。在自动删除之前,您可以从回收站还原文件。",ageLabel:"移动早于以下天数的文件",days:"天",includeNeverPrinted:"包括从未打印过的文件",effectsTitle:"点击清除时会发生什么",effect1:"匹配的文件移至回收站 — 尚未从磁盘删除。",effect2:"在保留期到期之前,您可以随时从回收站恢复。",effect3:"保留期满后,回收站清理器将它们从磁盘永久删除。",effect4:"外部(链接)文件夹中的文件将被跳过 — Bambuddy 从不删除不属于自己的字节。",previewLoading:"正在检查匹配的文件数量…",previewFailed:"无法预览清理结果。",previewSummary:"{{count}} 个文件 · {{size}} 将被移至回收站",andMore:"…还有 {{count}} 个",warning:"文件将被软删除——在保留期结束前,您可以从回收站还原它们。",confirmCta:"将 {{count}} 个移至回收站",purging:"正在移至回收站…",toast:{success:"已将 {{count}} 个文件移至回收站。",failed:"无法清理文件。"}},libraryAutoPurge:{enableLabel:"自动清理旧文件",enableDescription:"每天执行一次管理员清理。文件会先进入回收站——不会立即删除。",ageLabel:"自动清理早于以下天数的文件",ageDescription:"最少 7 天,最多 10 年。使用与手动「清理旧文件」按钮相同的时间规则。",days:"天",includeNeverPrinted:"包括从未打印过的文件",saveFailed:"无法保存自动清理设置。"},archivePurge:{headerButton:"清除旧条目",headerTooltip:"批量删除旧归档",title:"清除旧归档",description:"清除旧的打印历史。每个归档按其最近一次打印完成时间老化 — 重新打印归档会刷新其年龄,因此活跃工作永远不会被清除。",ageLabel:"删除最近未打印的归档:",days:"天",effectsTitle:"点击清除时会发生什么",effect1:"每个匹配的归档将从列表中隐藏,其磁盘文件(3MF、缩略图、延时摄影、源 3MF、F3D、照片)也将被删除。",effect2:"数据库中的归档记录将被保留,因此 Quick Stats 仍可计入耗材、时间、成本和能耗的贡献 — 与单条删除的默认行为一致。",effect3:'勾选下方"同时从统计中移除"可一并清除 Quick Stats 中的贡献(与单条删除选项等同)。该操作不可撤销。',effect4:"重新打印归档会刷新其使用计时器,因此仍在使用的归档不会被清除。",purgeStatsLabel:"同时从统计中移除",purgeStatsHint:"从 Quick Stats(耗材、时间、成本、能耗)中移除匹配的归档。不勾选时,Quick Stats 保留所有贡献,仅文件从磁盘删除。",previewLoading:"检查匹配的归档数量…",previewFailed:"无法预览清除。",previewSummary:"将移除 {{count}} 个归档 · {{size}}",andMore:"…还有 {{count}} 个",warning:"文件将从磁盘删除且无法恢复。继续前请下载或收藏您想保留的内容。",confirmCta:"移除 {{count}} 个归档",purging:"移除中…",toast:{success:"已移除 {{count}} 个归档。",failed:"无法清除归档。"}},archiveAutoPurge:{enableLabel:"自动清除旧归档",enableDescription:"每天一次,将阈值内未打印的归档从列表中隐藏,并从磁盘中删除其文件。重新打印会重置计时器。",ageLabel:"自动删除最近未打印的归档:",ageDescription:"最少 7 天,最多 10 年。基于最近一次打印完成 — 重新打印会刷新年龄。删除 3MF、缩略图、延时摄影、源 3MF、F3D 和照片。",days:"天",purgeStatsLabel:"同时从统计中移除",purgeStatsDescription:"启用后,每日清理任务还会将每个被清除的归档从 Quick Stats(耗材、时间、成本、能耗)中移除。默认关闭 — Quick Stats 保留贡献,仅文件从磁盘删除。",runNow:"立即清除归档",saveFailed:"无法保存自动清除设置。"},cameraTokens:{title:"摄像头 API 令牌",navTitle:"摄像头 API 令牌",description:"长期令牌,用于将摄像头流嵌入 Home Assistant、Frigate、信息亭或其他需要稳定 URL 的工具。每个令牌仅限摄像头流,可随时撤销。",loading:"加载中…",confirmRevoke:{title:"撤销此令牌?",body:"使用「{{name}}」的任何设备将立即失去访问权限。此操作无法撤销。",cancel:"取消",confirm:"撤销"},create:{title:"创建新令牌",nameLabel:"令牌名称",namePlaceholder:"例如 Home Assistant",daysLabel:"过期天数",submit:"创建",hint:"最大有效期 365 天。令牌值仅在创建时显示一次 — 请立即复制。"},created:{title:"令牌已创建 — 立即复制",warning:"这是此令牌唯一一次可见。关闭此对话框后您将无法再次查看。",copy:"复制",dismiss:"我已保存"},list:{myTitle:"我的令牌",allTitle:"所有用户(管理员视图)",empty:"暂无令牌。",name:"名称",owner:"所有者",prefix:"前缀",created:"创建时间",expires:"过期时间",lastUsed:"最近使用",revoke:"撤销",expired:"已过期"},toast:{created:"令牌已创建",createFailed:"创建令牌失败",revoked:"令牌已撤销",revokeFailed:"撤销令牌失败",loadFailed:"加载令牌失败",copied:"已复制到剪贴板",copyFailed:"复制失败 — 手动选择并复制"}},forecast:{title:"库存预测",noSpools:"未找到活跃的料卷。请将料卷添加到库存中以查看预测数据。",noUsageData:"无可用使用数据 — 无法预测库存时间线。",sku:"SKU",material:"材料",stock:"库存",dailyRate:"消耗率",daysLeft:"剩余天数",emptyBy:"耗尽日期",reorderBy:"补货截止日",actions:"操作",trend:"趋势",estimated:"估算",noData:"无数据",timeframe:"时间范围",chartTitle:"库存预测 — 前5种材料",dashedLinesROP:"虚线 = 再订货点",stockLevel:"库存量",reorderPoint:"再订购点",safetyMargin:"安全余量",trendLegend:"趋势(基于历史,95%服务水平)",estimatedLegend:"估算(重量差值)",noDataLegend:"无数据",ropLabel:"再订货点",ssLabel:"安全库存",safetyStockLegend:"安全库存",stockArrivalLegend:"到货",stockoutLegend:"断货",alertCount_one:"{{count}}条警告",alertCount_other:"{{count}}条警告",order:"订购",globalLeadTime:"全局交货期",globalLeadTimeHint:"全局交货期下限 — 用于所有 SKU 的再订购点计算",save:"保存",cancel:"取消",settingsSaved:"设置已保存",failedSaveSettings:"保存设置失败",globalLeadTimeSaved:"全局提前期已保存",skuLeadTimeOverride:"SKU 交货期覆盖",skuLeadTimeHint:"0 = 使用全局交货期。设置 >0 以覆盖此 SKU。",safetyMarginLabel:"安全余量",effectiveLeadTime:"有效交货期",effectiveLeadTimeHint:"max(全局 {{global}}天, SKU {{sku}}天)",reorderPointHint:"d̄ × LT + safety margin — 当库存降至此水平时下单",safetyMarginHint:"统计安全库存 (z=1.65 × σ × √LT) + 用户自定义缓冲",safetyMarginHintDays:"在统计安全库存基础上额外增加的缓冲。{{approx}}",safetyMarginHintDaysApprox:" ≈ 按当前速率 {{g}}g。",safetyMarginHintG:"在统计安全库存基础上增加的固定重量缓冲。{{approx}}",safetyMarginHintGApprox:" ≈ 按当前速率 {{days}}天。",individualSpools:"单个料卷",labelWeight:"标注重量",spoolCount_one:"{{count}}个线轴",spoolCount_other:"{{count}}个线轴",stockBreakRisk:"断货风险",stockBreakBefore:"补货前库存断档",stockBreakDetail:"剩余 {{days}} 天,交货期 {{lt}} 天。",reorderNow:"立即补货",reorderTriggerPassed:"触发日期 {{date}} 已过。",shoppingList:"购物清单",shoppingListItems_one:"({{count}}项)",shoppingListItems_other:"({{count}}项)",shoppingListEmpty:"购物清单为空。点击任意行的购物车图标以添加商品。",addToCart:"添加到购物清单",alertsSnoozed:"静音此SKU的提醒",alertsEnabled:"启用此SKU的提醒",addedToCart:"已添加到购物清单",failedAddItem:"添加项目失败",listView:"列表",logisticsView:"物流",qty:"数量",weight:"重量",leadTime:"交货期",expectedRestock:"预计补货日期",status:"状态",note:"备注",pending:"待处理",purchased:"已购买",received:"已收货",markPurchased:"标记为已购买",markReceived:"标记为已收货 — 将料卷添加到库存",resetToPending:"重置为待处理",remove:"移除",clearAll:"清空",downloadCsv:"CSV",addToCartTitle:"添加到购物清单",byQuantity:"按数量",byDuration:"按时长",numberOfSpools:"线轴数量",lastHowManyDays:"需要持续多少天?",noUsageQty:"无使用数据 — 数量已设为1。",noteOptional:"备注(可选)",notePlaceholder:"例如:用于项目X,紧急…",addNSpools_one:"添加{{count}}个线轴",addNSpools_other:"添加{{count}}个线轴",onArrival:"到货时",stockBreakIn:"{{days}} 天后断货。",stockRunsOutBefore:"库存在 {{lt}} 天交货期结束前耗尽。",atRate:"按 {{rate}}g/天的速度,您需要",moreSpools_one:"再{{count}}个线轴",moreSpools_other:"再{{count}}个线轴",bridgeGap:"来弥补缺口。",noReadAccess:"您没有查看库存预测的权限。",noWriteAccess:"您没有修改预测设置的权限。"}},Qme={nav:{printers:"印表機",archives:"歸檔",queue:"列印佇列",stats:"統計",profiles:"設定檔案",maintenance:"維護",projects:"專案",inventory:"耗材",files:"檔案管理器",makerworld:"MakerWorld",notifications:"通知",settings:"設定",system:"系統",collapseSidebar:"收起側邊欄",expandSidebar:"展開側邊欄",update:"更新",updateAvailable:"有可用更新:v{{version}}",updateAvailableBanner:"版本 {{version}} 已發布!",viewUpdate:"檢視更新",viewOnGithub:"在 GitHub 上檢視",keyboardShortcuts:"鍵盤快捷鍵 (?)",switchToLight:"切換到淺色模式",switchToDark:"切換到深色模式",smartSwitches:"智慧開關",logout:"登出"},common:{save:"儲存",saving:"儲存中...",cancel:"取消",delete:"刪除",edit:"編輯",add:"新增",close:"關閉",confirm:"確認",loading:"載入中...",error:"錯誤",errorLoading:"載入錯誤",retry:"重試",success:"成功",warning:"警告",enabled:"已啟用",disabled:"已停用",yes:"是",no:"否",on:"開",off:"關",all:"全部",none:"無",search:"搜尋",filter:"篩選",sort:"排序",refresh:"重新整理",download:"下載",upload:"上傳",uploading:"上傳中...",uploadFailed:"上傳失敗",actions:"操作",status:"狀態",name:"名稱",description:"描述",date:"日期",time:"時間",hours:"小時",minutes:"分鐘",seconds:"秒",days:"天",enable:"啟用",disable:"停用",permissions:"權限",noPrinters:"未設定印表機",noData:"尚無資料",linkNotFound:"未找到連結",required:"必填",optional:"可選",dismiss:"關閉",apply:"套用",reset:"重設",export:"匯出",import:"匯入",clear:"清除",selectAll:"全選",deselectAll:"取消全選",noChange:"— 不更改 —",unchanged:"未更改",unassigned:"未分配",unknown:"未知",unknownError:"未知錯誤",today:"今天",tomorrow:"明天",asap:"儘快",overdue:"已逾期",now:"現在",collapse:"收起",expand:"展開",viewArchive:"檢視歸檔",viewInFileManager:"在檔案管理器中檢視",addedBy:"由 {{username}} 新增",prints:"次列印",more:"還有 {{count}} 個",ascending:"升序",descending:"降序",back:"返回",copy:"複製",copied:"已複製!",printer:"印表機",remove:"移除",type:"類型",print:"列印",rename:"重新命名",move:"移動",create:"建立",duplicate:"複製",left:"左",right:"右"},printers:{title:"印表機",addPrinter:"新增印表機",editPrinter:"編輯印表機",deletePrinter:"刪除印表機",printerName:"印表機名稱",serialNumber:"序列號",ipAddress:"IP 位址 / 主機名稱",accessCode:"存取碼",model:"型號",nozzleCount:"噴嘴數量",autoArchive:"自動歸檔",status:{available:"可用",idle:"空閒",printing:"列印中",paused:"已暫停",offline:"離線",problem:"故障",error:"錯誤",finished:"已完成",unknown:"未知"},temperatures:{nozzle:"噴嘴",bed:"熱床",chamber:"腔室"},progress:"{{percent}}% 完成",timeRemaining:"剩餘 {{time}}",deleteConfirm:'確定要刪除"{{name}}"嗎?',maintenanceOk:"維護正常",maintenanceWarning:"{{count}} 個警告",maintenanceWarning_plural:"{{count}} 個警告",maintenanceDue:"{{count}} 個到期",maintenanceDue_plural:"{{count}} 個到期",sort:{name:"名稱",status:"狀態",model:"型號",location:"位置",ascending:"升序排列",descending:"降序排列"},cardSize:{small:"小卡片",medium:"中卡片",large:"大卡片",extraLarge:"超大卡片"},hideOffline:"隱藏離線",nextAvailable:"下一個可用",powerOn:"開機",offlinePrintersWithPlugs:"帶智慧插座的離線印表機",noPrintersConfigured:"尚未設定印表機",search:"搜尋印表機...",noSearchResults:"沒有印表機符合您的搜尋或篩選條件",filter:{allStatuses:"所有狀態",allLocations:"所有位置"},toolbar:{filters:"篩選",view:"檢視",actions:"操作"},readyToPrint:"準備列印",external:"外部",extL:"外接左",extR:"外接右",deleteArchives:"刪除列印歸檔",noLabel:"無標籤",printPreview:"列印預覽",width:"寬度",height:"高度",noObjectsFound:"未找到物件",objectsLoadedOnPrintStart:"物件在列印開始時載入",willBeSkipped:"將被跳過",name:"名稱",serialCannotBeChanged:"序列號無法更改",locationHelp:"用於分組印表機和篩選佇列任務",wifiSignal:{veryWeak:"非常弱",weak:"弱",fair:"一般",good:"良好",excellent:"優秀"},maintenanceUpToDate:"所有維護均已完成 - 點選檢視",chamberLightOn:"開啟腔室燈",chamberLightOff:"關閉腔室燈",files:"檔案",browseFiles:"瀏覽印表機檔案",autoOffAfterPrint:"列印後自動關機",autoOffExecuted:"已執行自動關機 - 開啟印表機以重設",hmsErrors:"HMS 錯誤",viewHmsErrors:"檢視 {{count}} 個 HMS 錯誤",resume:"繼續",pause:"暫停",stop:"停止",camera:"攝影機",skipObject:"跳過物件",reconnect:"重新連線",forceRefresh:"強制重新整理",forceRefreshSuccess:"已請求重新整理",mqttDebug:"MQTT 偵錯",printerInformation:"印表機資訊",copyToClipboard:"複製",copied:"已複製!",state:"狀態",wifiSignalLabel:"Wi-Fi 訊號",developerMode:"開發者模式",enabled:"已啟用",disabled:"已停用",addedOn:"新增日期",sdCard:"SD 卡",inserted:"已插入",notInserted:"未插入",totalPrintHours:"列印時長",activeNozzle:"目前:{{nozzle}} 噴嘴",nozzleRack:"噴嘴架",nozzleDocked:"已停靠",nozzleMounted:"已安裝",nozzleActive:"使用中",nozzleIdle:"空閒",nozzleDiameter:"直徑",nozzleType:"類型",nozzleStatus:"狀態",nozzleFilament:"耗材",nozzleWear:"磨損",nozzleMaxTemp:"最高溫度",nozzleSerial:"序列號",nozzleHardenedSteel:"硬化鋼",nozzleStainlessSteel:"不鏽鋼",nozzleTungstenCarbide:"碳化鎢",nozzleFlow:"流量",nozzleHighFlow:"高流量",nozzleStandardFlow:"標準",firmwareUpdate:"韌體更新",firmwareInstructions:"在印表機觸控式螢幕上,前往",firmwareNav:"導航到",settings:"設定",firmware:"韌體",discoverPrinters:"發現印表機",searching:"搜尋中...",manualEntry:"手動輸入",addFromCloud:"從雲端新增",toast:{printerDeleted:"印表機已刪除",missingSpoolAssignment:"已在{{printer}}上開始列印。以下料槽未分配耗材: {{slots}}",printerAdded:"印表機已新增",printerUpdated:"印表機已更新",failedToDelete:"刪除印表機失敗",failedToAdd:"新增印表機失敗",failedToUpdate:"更新印表機失敗",commandSent:"命令已傳送",failedToSendCommand:"傳送命令失敗",turnedOn:"{{name}} 已開啟",failedToPowerOn:"開啟 {{name}} 失敗",scriptTriggered:"腳本已觸發",printStopped:"列印已停止",printPaused:"列印已暫停",printResumed:"列印已繼續",referenceDeleted:"參考已刪除",detectionAreaSaved:"檢測區域已儲存",failedToRunScript:"執行腳本失敗",failedToStopPrint:"停止列印失敗",failedToPausePrint:"暫停列印失敗",failedToResumePrint:"繼續列印失敗",failedToControlChamberLight:"控制腔室燈失敗",failedToSetSpeed:"設定列印速度失敗",failedToUpdateSetting:"更新設定失敗",failedToSkipObjects:"跳過物件失敗",failedToRereadRfid:"重新讀取 RFID 失敗",failedToCheckPlate:"檢查列印板失敗",failedToUpdateLabel:"更新標籤失敗",failedToDeleteReference:"刪除參考失敗",failedToSaveDetectionArea:"儲存檢測區域失敗",plateCheckEnabled:"列印板檢查已啟用",plateCheckDisabled:"列印板檢查已停用",calibrationSaved:"校準已儲存!",calibrationFailed:"校準失敗",rfidRereadInitiated:"已發起 RFID 重新讀取",loadInitiated:"載入耗材中…",unloadInitiated:"卸載耗材中…",failedToLoad:"載入耗材失敗",failedToUnload:"卸載耗材失敗"},connection:{connected:"已連線",offline:"離線"},plateStatus:{markCleared:"將列印板標記為已清理",cleared:"列印板已清理",notCleared:"列印板未清理",inUse:"列印板使用中"},queue:{inQueue:"佇列中有 {{count}} 個列印任務",inQueue_plural:"佇列中有 {{count}} 個列印任務"},controls:"控制",rfid:{reread:"重新讀取 RFID"},ams:{load:"載入",unload:"卸載"},bedJog:{title:"移動熱床",bed:"熱床",step:"步長 (mm)",up:"熱床上移",down:"熱床下移",disabledWhilePrinting:"列印中已停用",notHomedTitle:"印表機未歸零",notHomedMessage:"印表機自上次列印以來尚未歸零。請先執行自動歸零以確保安全定位(先停放噴頭,然後歸零 X、Y 和 Z),或者直接移動 — 軟限位將被繞過。",homeZ:"自動歸零",moveAnyway:"強制移動",homingStarted:"印表機自動歸零中…"},permission:{noAdd:"您沒有新增印表機的權限",noEdit:"您沒有編輯印表機的權限",noDelete:"您沒有刪除印表機的權限",noControl:"您沒有控制印表機的權限",noFiles:"您沒有存取印表機檔案的權限",noAmsRfid:"您沒有重新讀取 AMS RFID 的權限",noSmartPlugControl:"您沒有控制智慧插座的權限",noCamera:"您沒有檢視攝影機的權限"},modal:{addTitle:"新增印表機",editTitle:"編輯印表機",myPrinter:"我的印表機",selectModel:"選擇型號...",locationGroup:"位置 / 分組(可選)",locationPlaceholder:"例如:工作室、辦公室、地下室",autoArchiveLabel:"自動歸檔已完成的列印",fromPrinterSettings:"來自印表機設定",modelOptional:"型號(可選)",saveChanges:"儲存更改"},skipObjects:{tooltip:"跳過物件",onlyWhilePrinting:"跳過物件(僅在列印時)",requiresMultiple:"跳過物件(需要2個以上物件)",title:"跳過物件",matchIdsInfo:"將 ID 與印表機螢幕上的 ID 進行對照",printerShowsIds:"印表機螢幕上顯示列印板上物件的 ID",skipSelected:"跳過所選",skipping:"跳過中...",noObjectsSelected:"未選擇物件",selectObjectsToSkip:"選擇要從目前列印中跳過的物件",skipped:"已跳過",objectsSkipped:"物件已跳過",activeCount:"{{count}} 個活躍",waitForLayer:"等待第2層以上才能跳過物件(目前第 {{layer}} 層)",skip:"跳過",confirmTitle:"跳過物件?",confirmMessage:'確定要跳過"{{name}}"嗎?此操作無法復原。'},confirm:{deleteTitle:"刪除印表機",deleteMessage:'確定要刪除"{{name}}"嗎?這將移除所有連線設定。',deleteArchivesNote:"此印表機的所有列印歷史將被永久刪除。",keepArchivesNote:"列印歷史將保留,但不再與此印表機連結。",stopTitle:"停止列印",stopMessage:'確定要停止"{{name}}"上的目前列印嗎?這將取消列印任務。',stopButton:"停止列印",pauseTitle:"暫停列印",pauseMessage:'確定要暫停"{{name}}"上的目前列印嗎?',pauseButton:"暫停列印",resumeTitle:"繼續列印",resumeMessage:'確定要繼續"{{name}}"上的列印嗎?',resumeButton:"繼續列印",powerOnTitle:"開啟印表機",powerOnMessage:'確定要開啟"{{name}}"的電源嗎?',powerOnButton:"開機",powerOffTitle:"關閉印表機",powerOffMessage:'確定要關閉"{{name}}"的電源嗎?',powerOffWarning:'警告:"{{name}}"正在列印中!確定要關閉電源嗎?這將中斷列印並可能損壞印表機。',powerOffButton:"關機",haToggleTitle:'切換"{{name}}"',haToggleMessage:"切換 Home Assistant 實體 {{entity}}?如果目前為開啟狀態,可能會關閉電源。",haToggleWarning:'警告:"{{name}}"正在列印中!切換 {{entity}} 可能會切斷電源並中斷列印。是否繼續?',haToggleButton:"切換"},bulk:{select:"選擇",selectAll:"全選",selectByLocation:"按位置選擇",selected:"已選擇{{count}}臺",actions:{stop:"停止",pause:"暫停",resume:"繼續",clearPlate:"清除列印床",clearHMS:"清除通知"},confirm:{stopTitle:"停止{{count}}個列印任務",stopMessage:"這將取消{{count}}臺印表機上的活動列印任務。此操作無法復原。",stopButton:"全部停止",pauseTitle:"暫停{{count}}個列印任務",pauseMessage:"這將暫停{{count}}臺印表機上的活動列印任務。",pauseButton:"全部暫停",clearPlateTitle:"清除{{count}}個列印床",clearPlateMessage:"這將清除{{count}}臺印表機的列印床,可能會觸發佇列中的任務。",clearPlateButton:"全部清除"},success:"{{action}}已在{{count}}臺印表機上完成",partial:"{{succeeded}}成功,{{failed}}失敗",noneApplicable:"沒有選中的印表機處於適合此操作的狀態",selectByState:"按狀態選擇"},discovery:{title:"發現印表機",searching:"搜尋中...",scanning:"掃描中...",scanProgress:"掃描中... {{scanned}}/{{total}}",foundPrinters:"發現 {{count}} 臺印表機",noPrintersFound:"未找到印表機",noPrintersFoundSubnet:"在指定子網中未找到印表機。",noPrintersFoundNetwork:"在網路上未找到印表機。",allConfigured:"所有發現的印表機已設定完畢。",alreadyAdded:"已新增",select:"選擇",manualEntry:"手動輸入",addFromCloud:"從雲端新增",subnetToScan:"要掃描的子網",dockerNote:"偵測到 Docker 環境。請以 CIDR 格式輸入印表機所在子網。需要在 docker-compose.yml 中設定 network_mode: host。",scanSubnet:"掃描子網查詢印表機",discoverNetwork:"在網路上發現印表機",scanningSubnet:"正在掃描子網查詢拓竹印表機...",scanningNetwork:"正在掃描網路...",serialRequired:"需要序列號",unknown:"未知",failedToStart:"啟動發現失敗"},drying:{start:"開始乾燥",stop:"停止乾燥",temperature:"溫度",duration:"時長",hours:"小時",timeRemaining:"剩餘 {{time}}",active:"乾燥中",notSupported:"不支援乾燥",powerRequired:"連線AMS電源介面卡以啟用乾燥",startingDrying:"正在啟動乾燥...",stoppingDrying:"正在停止乾燥...",rotateTray:"乾燥時旋轉料盤"},filaments:"耗材",openCameraOverlay:"開啟攝影機疊加層",openCameraWindow:"在新視窗中開啟攝影機",firmwareUpdateAvailable:"韌體更新可用:{{current}} → {{latest}}",firmwareUpToDate:"韌體 {{version}} — 已是最新",firmwareUpdateButton:"更新",plateDetection:{noPermission:"您沒有更新印表機的權限",enabledClick:"列印板檢查已啟用 - 點選停用",disabledClick:"列印板檢查已停用 - 點選啟用",manageCalibration:"管理列印板檢測校準",calibrationRequired:"需要校準",calibrationInstructions:"請確保列印板完全空置,然後點選校準。",calibrationDescription:"校準會拍攝空置列印板的參考影像。後續檢查將與此參考進行比較以檢測物體。",calibrationTip:"提示:您最多可以為不同的列印板儲存5個校準。系統會在檢查時自動使用最佳匹配。",plateEmpty:"列印板似乎是空的",objectsDetected:"在列印板上偵測到物體",confidence:"置信度",difference:"差異",analysisPreview:"分析預覽:",analysisLegend:"綠色框 = 檢測區域,紅色覆蓋 = 與校準的差異",savedReferences:"已儲存的參考 ({{count}}/{{max}})",deleteReference:"刪除參考",labelPlaceholder:"標籤...",clickToEdit:"{{label}} - 點選編輯",clickToAddLabel:"點選新增標籤"},speed:{title:"列印速度",silent:"靜音 (50%)",standard:"標準 (100%)",sport:"運動 (124%)",ludicrous:"瘋狂 (166%)"},airduct:{title:"風道模式",cooling:"製冷",heating:"加熱"},noSdCard:"無SD",door:{open:"開",closed:"關"},fans:{partCooling:"零件冷卻風扇",auxiliary:"輔助風扇",chamber:"腔室風扇"},clickToViewHmsErrors:"點選檢視 HMS 錯誤",estimatedCompletion:"預計完成時間",plateNumber:"板 {{number}}",slotOptions:"槽位選項",amsPopup:{friendlyName:"AMS 名稱",friendlyNamePlaceholder:"例如 AMS 友好名稱",serialNumber:"序列號",firmwareVersion:"韌體",save:"儲存",clear:"清除",noEditPermission:"您沒有重新命名 AMS 單元的權限"},firmwareModal:{title:"韌體更新",titleUpToDate:"韌體資訊",currentVersion:"目前版本:",latestVersion:"最新版本:",releaseNotes:"發布說明",checkingPrereqs:"正在檢查前提條件...",sdCardReady:"SD 卡已就緒。點選下方上傳韌體。",uploadedSuccess:"韌體已上傳到 SD 卡!",applyInstructions:"在印表機上套用更新:",step1:"在印表機觸控式螢幕上,前往設定",step2:"導航到韌體",step3:"選擇從 SD 卡更新",step4:"更新將需要 10-20 分鐘",done:"完成",starting:"啟動中...",uploadFirmware:"上傳韌體",uploadFailed:"上傳啟動失敗:{{error}}",uploadedToast:"韌體已上傳!請在印表機螢幕上觸發更新。",availableVersions:"可用版本",usable:"可用",unavailable:"不可用",installed:"已安裝",newerBadge:"較新",olderBadge:"較舊",currentBadge:"目前"},accessCodePlaceholder:"留空以保持目前值",roi:{title:"檢測區域 (ROI)",xStart:"X 起點",yStart:"Y 起點",width:"寬度",height:"高度",instruction:"調整檢測區域以聚焦到列印板。預覽中的綠色框顯示目前區域。"},developerModeWarning:"以下印表機未啟用開發者區域網路模式:{{names}}。某些功能可能無法使用。",howToEnable:"如何啟用",incompatibleFile:"此檔案是為 {{slicedFor}} 切片的,但該印表機是 {{printerModel}}",dropNotPrintable:"只能列印 .gcode 和 .gcode.3mf 檔案",dropToPrint:"拖放以列印",cannotPrint:"印表機忙碌"},archives:{title:"列印歸檔",searchPlaceholder:"搜尋歸檔...",filterByPrinter:"按印表機篩選",filterByStatus:"按狀態篩選",sortBy:"排序方式",sortNewest:"最新優先",sortOldest:"最舊優先",sortName:"名稱",sortDuration:"時長",sortLargest:"最大優先",sortSmallest:"最小優先",sortSize:"大小",noArchives:"未找到歸檔",noArchivesSearch:"沒有匹配搜尋的歸檔",originalPrintNotVisible:"原始列印不可見 - 請嘗試清除篩選條件",noArchivesYet:"尚無歸檔",prints:"條列印",pagination:{showing:"顯示",to:"至",of:"共",show:"每頁",page:"頁",all:"全部"},loadingArchives:"載入歸檔中...",releaseToUpload:"放開以上傳",showAll:"顯示全部",showFavoritesOnly:"僅顯示收藏",gridView:"網格檢視",listView:"列表檢視",calendarView:"日曆檢視",logView:"列印日誌",manageTags:"管理標籤",showFailedPrints:"顯示失敗的列印",hideFailedPrints:"隱藏失敗的列印",hideDuplicates:"隱藏重複項",viewOriginalPrint:"點選檢視原始列印 (#{{id}})",printTime:"列印時間",filamentUsed:"耗材用量",cost:"成本",reprint:"重新列印",preview:"預覽",deleteArchive:"刪除歸檔",deleteConfirm:"確定要刪除此歸檔嗎?",favorite:"收藏",unfavorite:"取消收藏",viewDetails:"檢視詳情",status:{completed:"已完成",failed:"失敗",stopped:"已停止"},toast:{source3mfAttached:"源 3MF 已附加:{{filename}}",failedUploadSource3mf:"上傳源 3MF 失敗",source3mfRemoved:"源 3MF 已移除",failedRemoveSource3mf:"移除源 3MF 失敗",f3dAttached:"F3D 已附加:{{filename}}",failedUploadF3d:"上傳 F3D 失敗",f3dRemoved:"F3D 已移除",failedRemoveF3d:"移除 F3D 失敗",timelapseAttached:"縮時攝影已附加:{{filename}}",timelapseAlreadyAttached:"縮時攝影已附加",noMatchingTimelapse:"未找到匹配的縮時攝影",failedScanTimelapse:"掃描縮時攝影失敗",failedAttachTimelapse:"附加縮時攝影失敗",timelapseRemoved:"縮時攝影已移除",failedRemoveTimelapse:"移除縮時攝影失敗",timelapseUploaded:"縮時攝影已上傳:{{filename}}",failedUploadTimelapse:"上傳縮時攝影失敗",archiveDeleted:"歸檔已刪除",failedDeleteArchive:"刪除歸檔失敗",addedToFavorites:"已新增到收藏",removedFromFavorites:"已從收藏中移除",projectUpdated:"專案已更新",failedUpdateProject:"更新項目失敗",linkCopied:"連結已複製到剪貼簿",failedCopyLink:"複製連結失敗",photoDeleted:"照片已刪除",failedDeletePhoto:"刪除照片失敗",failedDeleteArchives:"刪除歸檔失敗",failedUpdateFavorites:"更新收藏失敗",exportDownloaded:"匯出已下載",exportFailed:"匯出失敗"},menu:{print:"列印",schedule:"排程",openInBambuStudio:"在切片軟體中開啟",slice:"切片",externalLink:"外部連結",viewOnMakerWorld:"在 MakerWorld 上檢視",preview3d:"3D 預覽",viewTimelapse:"檢視縮時攝影",scanForTimelapse:"掃描縮時攝影",uploadTimelapse:"上傳縮時攝影",removeTimelapse:"移除縮時攝影",downloadSource3mf:"下載源 3MF",uploadSource3mf:"上傳源 3MF",replaceSource3mf:"替換源 3MF",removeSource3mf:"移除源 3MF",uploadF3d:"上傳 F3D",replaceF3d:"替換 F3D",downloadF3d:"下載 F3D",removeF3d:"移除 F3D",download:"下載",copyDownloadLink:"複製下載連結",qrCode:"QR 碼",viewPhotos:"檢視照片",viewPhotosCount:"檢視照片 ({{count}})",projectPage:"專案頁面",addToFavorites:"新增到收藏",removeFromFavorites:"從收藏中移除",edit:"編輯",printLog:"列印記錄",goToProject:"前往專案:{{name}}",addToProject:"新增到專案",removeFromProject:"從專案中移除",loading:"載入中...",noProjectsAvailable:"無可用專案",searchProjects:"搜尋專案…",select:"選擇",deselect:"取消選擇",delete:"刪除"},permission:{noReprint:"您沒有重新列印此歸檔的權限",noAddToQueue:"您沒有新增到佇列的權限",noUpdateArchives:"您沒有更新歸檔的權限",noUploadFiles:"您沒有上傳檔案的權限",noDownload:"您沒有下載歸檔的權限",noCopyLink:"您沒有複製下載連結的權限",noDelete:"您沒有刪除此歸檔的權限",noCreate:"您沒有建立歸檔的權限"},platePicker:{title:"選擇要預覽的列印板",hint:"此存檔包含多個列印板。選擇一個在 GCode 檢視器中開啟。",plateLabel:"列印板 {{index}}",objectCount:"{{count}} 個物件",objectCount_plural:"{{count}} 個物件",noGcode:"此存檔沒有可預覽的已切片 G 代碼。請先在 Bambu Studio 中開啟並切片。"},card:{previousPlate:"上一個板",nextPlate:"下一個板",plateNumber:"板 {{index}}",moreOptions:"右鍵檢視更多選項",addToFavorites:"新增到收藏",removeFromFavorites:"從收藏中移除",cancelled:"已取消",failed:"失敗",duplicate:"重複",duplicateTitle:"此模型之前已列印過",openSource3mf:"在 Bambu Studio 中開啟源 3MF(右鍵檢視更多選項)",downloadF3d:"下載 Fusion 360 設計檔案",viewTimelapse:"檢視縮時攝影",viewPhoto:"檢視 1 張照片",viewPhotos:"檢視 {{count}} 張照片",openFolder:"開啟資料夾:{{name}}",slicedFile:"已切片檔案 - 可以列印",sourceFile:"僅原始檔 - 無 AMS 對應可用",gcode:"GCODE",source:"原始檔",project:"專案:{{name}}",runsBadge:"{{count}} 次列印",runsBadgeTitle:"共 {{count}} 次列印 — 成功 {{successful}} 次,失敗 {{failed}} 次。點擊查看完整列印記錄。",estimated:"預計:{{time}}",actual:"實際:{{time}}",accuracy:"準確度:{{percent}}%",filament:"{{weight}} 克",layer:"{{count}} 層",layers:"{{count}} 層",object:"{{count}} 個物件",objects:"{{count}} 個物件",slicedFor:"為 {{model}} 切片",uploadedBy:"上傳者",noPermissionReprint:"您沒有重新列印的權限",noFileForReprint:"無可用的 3MF 檔案 — 列印紀錄時無法從印表機下載該檔案",noPermissionEdit:"您沒有編輯歸檔的權限",noPermissionDelete:"您沒有刪除歸檔的權限",reprint:"重新列印",schedulePrint:"排程列印",schedule:"排程",openInBambuStudio:"在切片軟體中開啟",openInBambuStudioToSlice:"在切片軟體中開啟進行切片",slice:"切片",externalLink:"外部連結",makerWorld:"MakerWorld:{{designer}}",viewProject:"檢視專案",noExternalLink:"無外部連結",preview3d:"3D 預覽",download:"下載",edit:"編輯",delete:"刪除"},runLog:{title:"列印記錄",modalTitle:"列印記錄 — {{name}}",modalTitleFallback:"此歸檔",empty:"此歸檔尚未記錄任何列印事件。",col:{date:"日期",status:"狀態",duration:"時長",filament:"耗材",cost:"成本"},status:{completed:"已完成",failed:"失敗",cancelled:"已取消",stopped:"已停止",skipped:"已略過",printing:"列印中"}},modal:{deleteArchive:"刪除歸檔",deleteConfirm:'確定要刪除"{{name}}"嗎?此操作無法復原。',deleteButton:"刪除",deletePurgeStats:"同時從快速統計中刪除此列印(耗材、時間、成本、能耗)",removeSource3mf:"移除源 3MF",removeSource3mfConfirm:'確定要從"{{name}}"中移除源 3MF 檔案嗎?這將刪除原始切片專案檔案。',removeButton:"移除",removeF3d:"移除 F3D",removeF3dConfirm:'確定要從"{{name}}"中移除 Fusion 360 設計檔案嗎?',removeTimelapse:"移除縮時攝影",removeTimelapseConfirm:'確定要從"{{name}}"中移除縮時攝影影片嗎?',timelapse:"{{name}} - 縮時攝影",selectTimelapse:"選擇縮時攝影",selectTimelapseDesc:"未找到自動匹配。請選擇此列印的縮時攝影:",deleteArchives:"刪除歸檔",deleteArchivesConfirm:"確定要刪除 {{count}} 個歸檔嗎?此操作無法復原。",deleteCount:"刪除 {{count}} 個"},page:{title:"歸檔",printsCount:"{{filtered}} / {{total}} 次列印",dropFilesHere:"將 .3mf 檔案拖放到此處",releaseToUpload:"放開以上傳",only3mfSupported:"僅支援 .3mf 檔案",close:"關閉",selected:"已選擇 {{count}} 個",selectAll:"全選",tags:"標籤",project:"專案",favorite:"收藏",delete:"刪除",toggledFavorites:"已切換 {{count}} 個歸檔的收藏狀態",failedUpdateFavorites:"更新收藏失敗",archivesDeleted:"已刪除 {{count}} 個歸檔",failedDeleteArchives:"刪除歸檔失敗",photoDeleted:"照片已刪除",failedDeletePhoto:"刪除照片失敗"},list:{name:"名稱",printer:"印表機",date:"日期",size:"大小",actions:"操作",hasTimelapse:"有縮時攝影"},log:{date:"日期",printName:"列印名稱",printer:"印表機",user:"使用者",status:"狀態",duration:"時長",filament:"耗材",allPrinters:"所有印表機",allUsers:"所有使用者",allStatuses:"所有狀態",cancelled:"已取消",skipped:"已跳過",dateFrom:"從",dateTo:"到",noEntries:"未找到列印日誌條目",showing:"顯示 {{count}} / {{total}} 條",rowsPerPage:"行數",page:"頁",prev:"上一頁",next:"下一頁",clearLog:"清除日誌",clearLogTitle:"清除列印日誌",clearLogConfirm:"所有列印日誌條目將被永久刪除。歸檔和佇列項目不受影響。此操作無法復原。確定要繼續嗎?",clearLogButton:"全部清除",cleared:"已清除 {{count}} 條日誌",clearFailed:"清除列印日誌失敗"}},queue:{title:"列印佇列",subtitle:"排程和管理您的列印任務",addToQueue:"新增到佇列",print:"列印",reprint:"重新列印",schedulePrint:"排程列印",editQueueItem:"編輯佇列項目",printToPrinters:"列印到 {{count}} 臺印表機",queueToPrinters:"佇列到 {{count}} 臺印表機",queueSelectedPlates:"將 {{count}} 個熱床加入佇列",selectAllPlates:"選擇全部 {{count}} 個熱床",deselectAll:"取消全選",printQueued:"已加入列印佇列",itemsQueued:"{{count}} 個任務已加入佇列",sending:"傳送中...",sendingProgress:"傳送中 {{current}}/{{total}}...",adding:"新增中...",addingProgress:"新增中 {{current}}/{{total}}...",savingProgress:"儲存中 {{current}}/{{total}}...",clearQueue:"清空佇列",clearHistory:"清除歷史",emptyQueue:"佇列為空",position:"位置",scheduledTime:"排程時間",moveUp:"上移",moveDown:"下移",startNow:"立即開始",printingInProgress:"列印進行中...",viewArchive:"檢視歸檔",viewInFileManager:"在檔案管理器中檢視",itemCount:"{{count}} 個項目",itemCount_plural:"{{count}} 個項目",dragToReorder:"拖曳以重新排序(僅限盡快)",reorderHint:'位置僅影響"儘快"項目。排程項目按設定時間執行。',sjf:{label:"SJF",tooltip:"最短任務優先 — 排程器優先處理較短的列印任務"},addedBy:"由 {{name}} 新增",nextInQueue:"佇列中的下一個",clearPlateSuccess:"列印板已清理 — 準備進行下一個列印",plateNumber:"板 {{index}}",quantity:"數量",quantityHint:"建立 {{count}} 個佇列項目",activeBatches:"活躍批次",batchProgress:"已完成 {{completed}}/{{total}}",cancelBatch:"取消剩餘",batchCancelled:"已取消剩餘批次項目",cancelBatchConfirmTitle:"取消批次",cancelBatchConfirmMessage:"取消此批次中所有剩餘的待處理項目?",batch:"批次",sections:{currentlyPrinting:"正在列印",queued:"佇列中",history:"歷史"},status:{pending:"等待中",waiting:"等待中",printing:"列印中",paused:"已暫停",completed:"已完成",failed:"失敗",skipped:"已跳過",cancelled:"已取消"},summary:{printing:"列印中",queued:"佇列中",totalTime:"總佇列時間",totalWeight:"總佇列重量",history:"歷史"},filter:{allPrinters:"所有印表機",unassigned:"未分配",allStatus:"所有狀態",allLocations:"所有位置",any:"任意"},sort:{byPosition:"按位置排序",byName:"按名稱排序",byPrinter:"按印表機排序",bySchedule:"按排程排序",byDate:"按日期排序",ascendingOldest:"升序(最舊優先)",descendingNewest:"降序(最新優先)"},badges:{staged:"已暫存",requiresPrevious:"需要前一個成功",autoPowerOff:"自動關機",gcodeInjection:"G-code"},empty:{title:"沒有排程的列印",description:'從歸檔頁面使用右鍵選單中的"排程"選項來排程列印,或拖放檔案開始。'},time:{asap:"儘快",overdue:"已逾期",now:"現在",lessThanMinute:"不到一分鐘",inMinutes:"{{count}} 分鐘後",inHours:"{{count}} 小時後"},actions:{stopPrint:"停止列印",startPrint:"開始列印",requeue:"重新佇列"},bulkEdit:{title:"編輯 {{count}} 個項目",title_plural:"編輯 {{count}} 個項目",description:"僅更改的設定將套用於所選項目。",printer:"印表機",noChange:"— 不更改 —",queueOptions:"佇列選項",staged:"暫存(手動開始)",autoPowerOff:"列印後自動關機",requirePrevious:"要求前一個成功",printOptions:"列印選項",bedLevelling:"熱床調平",flowCalibration:"流量校準",vibrationCalibration:"振動校準",layerInspection:"首層檢查",timelapse:"縮時攝影",useAms:"使用 AMS",applyChanges:"套用更改",selectAll:"全選",deselectAll:"取消全選",selected:"已選擇 {{count}} 個",editSelected:"編輯所選",cancelSelected:"取消所選"},confirm:{cancelTitle:"取消排程列印",cancelMessage:'確定要取消"{{name}}"嗎?',stopTitle:"停止列印",stopMessage:'確定要停止目前列印"{{name}}"嗎?這將取消印表機上的列印任務。',removeTitle:"從歷史中移除",removeMessage:'確定要從佇列歷史中移除"{{name}}"嗎?',clearHistoryTitle:"清除歷史",clearHistoryMessage:"確定要從歷史中移除所有 {{count}} 個項目嗎?",cancelButton:"取消列印",stopButton:"停止列印",thisPrint:"此列印",thisItem:"此項目"},toast:{cancelled:"佇列項目已取消",cancelFailed:"取消項目失敗",removed:"佇列項目已移除",removeFailed:"移除項目失敗",stopped:"列印已停止",stopFailed:"停止列印失敗",released:"列印已加入佇列",startFailed:"開始列印失敗",reorderFailed:"重新排序佇列失敗",historyCleared:"已清除 {{count}} 條歷史紀錄",clearHistoryFailed:"清除歷史失敗",updateFailed:"更新項目失敗",bulkCancelled:"已取消 {{count}} 個項目",bulkCancelFailed:"批次取消項目失敗"},timeline:{listView:"列表",timelineView:"時間線",unassigned:"未分配",noData:"當天沒有計畫的列印任務",allDoneBy:"所有列印預計在 {{time}} 前完成",staged:"暫存",filterAll:"全部顯示",filterPrinting:"列印中",filterQueued:"佇列中",time:{anyMoment:"即將完成",minutesLeft:"剩餘{{minutes}} 分鐘",hoursLeft:"剩餘{{hours}}小時",hoursMinutesLeft:"剩餘{{hours}}小時{{minutes}} 分鐘"},day:{previous:"前一天",next:"後一天",today:"今天"}},permissions:{noStopPrint:"您沒有停止列印的權限",noStartPrint:"您沒有開始列印的權限",noEdit:"您沒有編輯此佇列項目的權限",noCancel:"您沒有取消此佇列項目的權限",noRequeue:"您沒有重新佇列的權限",noRemove:"您沒有移除此佇列項目的權限",noClearHistory:"您沒有清除所有歷史的權限",noEditItems:"您沒有編輯佇列項目的權限",noCancelItems:"您沒有取消佇列項目的權限"}},backgroundDispatch:{unknownFile:"未知檔案",unknownPrinter:"未知印表機",startingPrints:"正在開始列印",progressSummary:"{{complete}}/{{total}} 完成 • 已分發:{{dispatched}} • 處理中:{{processing}}",expandDetails:"展開分發詳情",collapseDetails:"收起分發詳情",dismissToast:"關閉分發通知",cancelDispatchJob:"取消分發任務",cancel:"取消",cancelling:"取消中…",awaitingPrinter:"等待印表機…",status:{dispatched:"已分發",processing:"處理中",completed:"已完成",failed:"失敗",cancelled:"已取消"},toast:{cancellingUpload:"取消上傳中...",cancelled:"分發已取消",cancelFailed:"取消分發失敗",completeWithFailures:"後台分發完成:{{completed}} 成功,{{failed}} 失敗",completeSuccess:"後台分發完成:{{completed}} 成功",printStartedRemaining:"{{completed}} 個列印已開始,{{remaining}} 個正在傳送..."}},stats:{title:"統計",subtitle:"拖曳小工具以重新排列。點選眼睛圖示隱藏。",overview:"概覽",totalPrints:"總列印次數",successRate:"成功率",totalPrintTime:"總列印時間",printTime:"列印時間",totalFilament:"總耗材用量",filamentUsed:"耗材用量",filamentCost:"耗材成本",totalCost:"總成本",energyUsed:"能耗",energyCost:"能源成本",energyWarmingUpTooltip:"能耗追蹤正在收集每小時快照。當所選範圍之前至少存在一個快照時,時間段合計將變得準確。早期數值可能偏低。",averagePrintTime:"平均列印時間",printsPerDay:"每日列印次數",byPrinter:"按印表機",printsByPrinter:"各印表機列印次數",byMaterial:"按材料",byMonth:"按月份",last7Days:"最近 7 天",last30Days:"最近 30 天",last90Days:"最近 90 天",allTime:"全部時間",quickStats:"快速統計",printActivity:"列印活動",filamentTypes:"耗材類型",filamentTrends:"耗材趨勢",failureAnalysis:"失敗分析",timeAccuracy:"時間準確度",successful:"成功:",failed:"失敗:",perfectEstimate:"100% = 完美估計",noTimeAccuracyData:"尚無時間準確度資料",noFilamentData:"尚無耗材資料",noPrinterData:"尚無印表機資料",noPrintData:"尚無列印資料",noPrintDataLast30Days:"最近 30 天無列印資料",failureReasons:"失敗原因",topFailureReasons:"主要失敗原因",failedPrintsCount:"{{failed}} / {{total}} 次列印失敗",lastWeekRate:"上週:{{rate}}%",resetLayout:"重設佈局",recalculateCosts:"重新計算成本",recalculateCostsHint:"使用目前耗材價格重新計算所有歸檔成本",exportStats:"匯出統計",exportAsCsv:"匯出為 CSV",exportAsExcel:"匯出為 Excel",hiddenCount:"{{count}} 個已隱藏",exportDownloaded:"匯出已下載",exportFailed:"匯出失敗",layoutReset:"佈局已重設",recalculatedCosts:"已為 {{count}} 個歸檔重新計算成本",recalculateFailed:"重新計算成本失敗",loadingStats:"載入統計資料中...",noPermissionResetLayout:"您沒有重設佈局的權限",noPermissionRecalculate:"您沒有重新計算成本的權限",noPrintDataInRange:"所選範圍內無列印資料",periodFilament:"期間耗材",periodCost:"期間成本",avgPerPrint:"每次列印平均",usageOverTime:"隨時間的使用量",filamentByWeight:"重量",printDuration:"列印時長",printerUtilization:"印表機利用率",filamentSuccess:"按材料成功率",printHabits:"列印習慣",printTimeOfDay:"列印時段",colorDistribution:"顏色分佈",noColorData:"尚無顏色資料",records:"紀錄",longestPrint:"最長列印",heaviestPrint:"最重列印",mostExpensivePrint:"最貴列印",busiestDay:"最忙碌的一天",successStreak:"連續成功",streakPrint:"連續列印",streakPrints:"{{count}} 次連續列印",printerStats:"印表機統計",hours:"小時",avgPrints:"平均列印",noArchiveData:"尚無列印資料",filamentByTime:"時間",avgWeight:"平均重量",avgTime:"平均時間",filamentByPrints:"列印次數",timeframe:{today:"今天","this-week":"本週","this-month":"本月","last-7":"最近 7 天","last-30":"最近 30 天","last-90":"最近 90 天","this-year":"今年","all-time":"全部時間",custom:"自訂範圍",from:"從",to:"到"},allUsers:"所有使用者",noUser:"無使用者(系統)",filterByUser:"按使用者篩選"},maintenance:{title:"維護",overview:"概覽",allOk:"所有維護均已完成",dueCount:"{{count}} 項到期",dueCount_plural:"{{count}} 項到期",warningCount:"{{count}} 個警告",warningCount_plural:"{{count}} 個警告",totalPrintTime:"總列印時間",nextMaintenance:"下次維護",nothingDue:"無到期項目",tasks:"任務",lastPerformed:"上次執行",interval:"間隔",hoursRemaining:"剩餘 {{hours}} 小時",hoursOverdue:"逾期 {{hours}} 小時",markDone:"標記為完成",performMaintenance:"執行維護",history:"歷史",noHistory:"無維護歷史",editPrintHours:"編輯列印時間",currentHours:"目前小時數",statusTab:"狀態",settingsTab:"設定",overdueCount:"{{count}} 個逾期",dueSoonCount:"{{count}} 個即將到期",dueSoon:"即將到期",allGood:"一切正常",overdueBy:"逾期 {{duration}}",dueIn:"{{duration}} 後到期",timeLeft:"剩餘 {{duration}}",day:"1 天",days:"{{count}} 天",week:"1 週",weeks:"{{count}} 週",month:"1 個月",months:"{{count}} 個月",year:"1 年",maintenanceTypes:"維護類型",maintenanceTypesDescription:"系統類型和您的自訂維護任務",addCustomType:"新增自訂類型",restoreDefaults:"恢復預設任務",intervalType:"間隔類型",intervalValue:"間隔 ({{type}})",icon:"圖示",documentationLink:"說明文件連結(可選)",assignToPrinters:"分配給印表機",selectAtLeastOnePrinter:"至少選擇一臺印表機",addType:"新增類型",custom:"自訂",printHours:"列印小時數",calendarDays:"日曆天數",exampleName:"例如:更換 HEPA 過濾器",viewDocumentation:"檢視說明文件",timeBasedInterval:"基於時間的間隔",intervalOverrides:"間隔覆蓋",intervalOverridesDescription:"為特定印表機自訂間隔",assignedToPrinters:"已分配給印表機:",noPrintersAssigned:"未分配印表機",addPrinterShort:"新增:",printersAssignedClick:"已分配 {{count}} 臺印表機 - 點選管理",removeFromPrinter:"從此印表機移除",types:{lubricateCarbonRods:"潤滑碳纖維杆",lubricateRails:"潤滑線性導軌",cleanNozzle:"清潔噴嘴/熱端",checkBelts:"檢查皮帶張力",cleanBuildPlate:"清潔列印板",checkExtruder:"檢查擠出機齒輪",checkCooling:"檢查冷卻風扇",generalInspection:"綜合檢查",cleanCarbonRods:"清潔碳纖維杆",lubricateSteelRods:"潤滑鋼杆",cleanSteelRods:"清潔鋼杆",cleanLinearRails:"清潔線性導軌",checkPtfeTube:"檢查 PTFE 管",replaceHepaFilter:"更換 HEPA 過濾器",replaceCarbonFilter:"更換活性炭過濾器",lubricateLeftNozzleRail:"潤滑左噴嘴導軌"},maintenanceComplete:"維護已標記為完成",typeUpdated:"維護類型已更新",typeDeleted:"維護類型已刪除",defaultsRestored:"已恢復 {{count}} 個預設任務",printHoursUpdated:"列印小時數已更新",printerAssigned:"印表機已分配",printerRemoved:"印表機已移除",deleteTypeConfirm:'刪除"{{name}}"?',deleteSystemTypeTitle:"刪除預設維護任務?",deleteSystemTypeMessage:'確定要刪除預設維護任務"{{name}}"嗎?',noPermissionUpdate:"您沒有更新維護項目的權限",noPermissionPerform:"您沒有執行維護的權限",noPermissionEditTypes:"您沒有編輯維護類型的權限",noPermissionDeleteTypes:"您沒有刪除維護類型的權限",noPermissionEditHours:"您沒有編輯列印時間的權限",noPermissionRemovePrinter:"您沒有移除印表機分配的權限",noPermissionAssignPrinter:"您沒有分配印表機的權限",noPermissionEditIntervals:"您沒有編輯間隔的權限",configureSettings:"設定維護類型和間隔"},settings:{title:"設定",general:"通用",tabs:{general:"通用",smartPlugs:"智慧插座",notifications:"通知",queue:"工作流程",filament:"耗材",network:"網路",apiKeys:"API 金鑰",virtualPrinter:"虛擬印表機",spoolbuddy:"SpoolBuddy",failureDetection:"故障檢測",users:"身份驗證",backup:"備份",emailAuth:"信箱認證",ldap:"LDAP",twoFa:"雙因素認證",oidc:"SSO / OIDC",security:"安全"},spoolbuddy:{infoTitle:"SpoolBuddy 裝置",infoBody:"SpoolBuddy kiosk 透過心跳自動註冊。如果裝置不再使用,或守護程式當機遺留了過時的重複項,可在此取消註冊。",duplicatesTitle:"已註冊 {{count}} 台裝置",duplicatesBody:"kiosk 介面只使用最先註冊的裝置。如果其中有因當機遺留的過時重複項,請取消註冊它——線上裝置會在下次心跳時重新註冊自己。",empty:"尚未註冊任何 SpoolBuddy 裝置。",online:"線上",offline:"離線",unregister:"取消註冊",unregisterSuccess:"裝置已取消註冊",unregisterError:"取消註冊裝置失敗",confirmTitle:"取消註冊 SpoolBuddy 裝置?",confirmBody:'將從資料庫中移除 "{{hostname}}" ({{deviceId}})。如果裝置線上,會在下次心跳時重新註冊自己。',ipAddress:"IP 位址",firmware:"韌體",lastSeen:"上次線上",daemonUptime:"守護程式執行時間",systemUptime:"系統執行時間",never:"從未",nfc:"NFC",scale:"磅秤",cpuTemp:"CPU 溫度",memory:"記憶體",disk:"磁碟",update:"更新",updateConfirmTitle:"更新 SpoolBuddy 守護程式?",updateConfirmBody:'對 "{{hostname}}" 觸發軟體更新?更新完成後守護程式將重新啟動。',restartBrowser:"重新啟動瀏覽器",restartBrowserConfirmTitle:"重新啟動 kiosk 瀏覽器?",restartBrowserConfirmBody:'在 "{{hostname}}" 上重新啟動 kiosk 瀏覽器?顯示將短暫黑屏。',restartDaemon:"重新啟動守護程式",restartDaemonConfirmTitle:"重新啟動 SpoolBuddy 守護程式?",restartDaemonConfirmBody:'在 "{{hostname}}" 上重新啟動 SpoolBuddy 守護程式?裝置將離線幾秒鐘。',reboot:"重新開機",rebootConfirmTitle:"重新開機?",rebootConfirmBody:'重新開機 "{{hostname}}"?裝置將離線約一分鐘。',shutdown:"關機",shutdownConfirmTitle:"關閉裝置?",shutdownConfirmBody:'關閉 "{{hostname}}"?您需要實體存取才能重新開機。',commandConfirm:"確認",commandQueued:"命令已加入佇列",commandError:"傳送命令失敗"},ldap:{title:"LDAP 認證",enabledDesc:"LDAP 認證已啟用",disabledDesc:"LDAP 認證已停用",disabledHint:"在下方設定並儲存 LDAP 設定,然後啟用。",enabled:"LDAP 認證已啟用",disabled:"LDAP 認證已停用",feature1:"使用者可以使用 LDAP 憑據登入",feature2:"本機管理員帳戶作為後備保留",feature3:"登入時 LDAP 群組對應到 BamBuddy 群組",serverConfig:"LDAP 伺服器設定",serverUrl:"伺服器 URL",serverUrlHint:"使用 ldap:// 進行標準連線或 ldaps:// 進行 SSL 連線",security:"安全",securityHint:"StartTLS 將普通連線升級為 TLS。LDAPS 從一開始就使用 TLS。",bindDn:"繫結 DN(服務帳戶)",bindPassword:"繫結密碼",searchBase:"搜尋基礎 DN",userFilter:"使用者搜尋過濾器",userFilterHint:"{username} 替換為登入使用者名稱。OpenLDAP 使用 (uid={username})。",advanced:"進階",autoProvision:"自動建立使用者",autoProvisionHint:"首次 LDAP 登入時自動建立 BamBuddy 帳戶",defaultGroup:"預設群組",defaultGroupNone:"— 無(無復原)—",defaultGroupHint:"當 LDAP 使用者透過身份驗證但不在任何已對應的 LDAP 群組中時分配的備援群組。留空以使未對應的使用者沒有權限。",groupMapping:"群組對應(JSON)",groupMappingHint:"將 LDAP 群組 DN 對應到 BamBuddy 群組。可用群組:",testConnection:"測試連線",settingsSaved:"LDAP 設定已儲存",errors:{serverRequired:"LDAP 伺服器 URL 為必填項",searchBaseRequired:"搜尋基礎 DN 為必填項",enableAuthFirst:"請先啟用認證",configureLdapFirst:"請先儲存 LDAP 設定"}},email:{smtpSettings:"SMTP 設定",smtpHost:"SMTP 伺服器",smtpPort:"SMTP 連接埠",security:"安全",authentication:"認證",username:"使用者名稱",password:"密碼",fromEmail:"寄件信箱",fromName:"寄件人名稱",testConnection:"測試 SMTP 連線",testRecipient:"測試收件信箱",sendTest:"傳送測試郵件",sending:"傳送中...",save:"儲存設定",saving:"儲存中...",advancedAuth:"進階認證",advancedAuthEnabled:"進階認證已啟用",advancedAuthEnabledDesc:"基於信箱的使用者管理功能已啟用。新使用者將透過郵件收到自動產生的密碼,使用者可以透過忘記密碼功能重設密碼。",advancedAuthDisabled:"進階認證已停用",advancedAuthDisabledDesc:"啟用進階認證以啟用基於信箱的使用者管理功能。",enable:"啟用",disable:"停用",feature1:"密碼自動產生並透過郵件傳送給新使用者",feature2:"使用者可以使用使用者名稱或信箱登入",feature3:"忘記密碼功能可用",feature4:"管理員可以透過郵件重設使用者密碼",errors:{requiredFields:"請填寫所有必填欄位",usernameRequired:"啟用認證時需要使用者名稱",enterTestEmail:"請輸入測試信箱地址",smtpServerAndEmail:"測試前請填寫 SMTP 伺服器和寄件信箱",usernamePasswordRequired:"啟用認證時需要使用者名稱和密碼",configureSmtpFirst:"請先設定並測試 SMTP 設定",enableAuthFirst:"請先啟用身份驗證才能使用基於電子郵件的功能。"},success:{settingsSaved:"SMTP 設定儲存成功"},securityOptions:{starttls:"STARTTLS(連接埠 587)",ssl:"SSL/TLS(連接埠 465)",none:"無(連接埠 25)"},authOptions:{enabled:"已啟用",disabled:"已停用"}},appearance:"外觀",notifications:"通知",smartPlugs:"智慧插座",spoolman:"Spoolman",updates:"更新",language:"語言",languageDescription:"選擇您的首選語言",theme:"主題",themeLight:"淺色",themeDark:"深色",themeSystem:"跟隨系統",defaultView:"預設檢視",defaultViewDescription:"開啟應用程式時顯示的頁面",checkForUpdates:"檢查更新",autoUpdate:"自動更新",currentVersion:"目前版本",latestVersion:"最新版本",upToDate:"已是最新版本",updateAvailable:"有可用更新",notificationLanguage:"通知語言",notificationLanguageDescription:"推送通知的語言",bedCooledThreshold:"熱床冷卻閾值",bedCooledThresholdDescription:"列印後熱床被視為已冷卻的溫度",userNotificationsEnabled:"使用者通知",userNotificationsEnabledDescription:"啟用使用者通知選單和列印任務事件的郵件通知。需要進階身份驗證。",userNotificationsDisabledHint:"請啟用進階身份驗證以使用使用者通知。",notificationProviders:"通知提供者",addProvider:"新增提供者",editProvider:"編輯提供者",providerType:"提供者類型",testNotification:"測試通知",testSuccess:"測試通知傳送成功",testFailed:"傳送測試通知失敗",quietHours:"免打擾時間",quietHoursDescription:"在此時間段內不傳送通知",quietHoursStart:"開始",quietHoursEnd:"結束",events:{title:"通知事件",printStart:"列印開始",printComplete:"列印完成",printFailed:"列印失敗",printStopped:"列印停止",printProgress:"進度里程碑",printProgressDescription:"在 25%、50%、75% 時通知",printerOffline:"印表機離線",printerError:"印表機錯誤",filamentLow:"耗材不足",maintenanceDue:"維護到期",maintenanceDueDescription:"需要維護時通知"},smartPlug:{title:"智慧插座",add:"新增智慧插座",edit:"編輯智慧插座",name:"名稱",ipAddress:"IP 位址",linkedPrinter:"連結印表機",autoOn:"自動開啟",autoOnDescription:"列印開始時開啟",autoOff:"自動關閉",autoOffDescription:"列印完成後關閉",offDelay:"關閉延遲",offDelayMinutes:"列印後分鐘數",offDelayTemp:"當噴嘴溫度低於",currentState:"目前狀態",turnOn:"開啟",turnOff:"關閉"},filamentTracking:"耗材追蹤",filamentTrackingDesc:"選擇如何追蹤您的耗材。您可以使用內建庫存或連線外部 Spoolman 伺服器。",filamentChecks:"耗材檢查",disableFilamentWarnings:"停用耗材警告",disableFilamentWarningsDesc:"在列印或加入佇列時不顯示耗材不足警告",preferLowestFilament:"優先使用剩餘最少的耗材",preferLowestFilamentDesc:"當多個料盤匹配時,使用剩餘耗材最少的那個",trackingModeBuiltIn:"內建庫存",trackingModeBuiltInDesc:"包含 RFID 自動匹配和用量追蹤",trackingModeSpoolmanDesc:"外部耗材管理伺服器",builtInFeatureRfid:"自動檢測 AMS 中的拓竹 RFID 耗材",builtInFeatureUsage:"追蹤每次列印的耗材消耗",builtInFeatureCatalog:"管理耗材、顏色和 K 值設定檔案",builtInFeatureThirdParty:"第三方耗材可分配到庫存耗材",amsSyncButton:"從 AMS 同步重量",amsSyncTitle:"從 AMS 同步耗材重量",amsSyncMessage:"這將使用已連線印表機的目前 AMS 剩餘百分比值覆蓋所有庫存耗材重量。用於從損壞的重量資料中恢復。印表機必須線上。",amsSyncing:"同步中...",amsSyncSuccess:"已同步 {{synced}} 個耗材,跳過 {{skipped}} 個",amsSyncError:"從 AMS 同步重量失敗",spoolmanAmsSyncButton:"從 AMS 同步 Spoolman 重量",spoolmanAmsSyncTitle:"從 AMS 同步 Spoolman 耗材重量",spoolmanAmsSyncMessage:"這將根據已連線印表機的目前 AMS 剩餘百分比值更新所有 Spoolman 耗材重量。印表機必須線上。",spoolmanAmsSyncing:"同步中...",spoolmanAmsSyncSuccess:"已同步 {{synced}} 個 Spoolman 耗材,跳過 {{skipped}} 個",spoolmanAmsSyncError:"從 AMS 同步 Spoolman 重量失敗",spoolmanAmsSyncErrorUnreachable:"同步失敗(Spoolman 無法存取)",spoolmanAmsSyncErrorNotConfigured:"同步失敗(Spoolman 未設定)",spoolmanNotConfigured:"Spoolman 未設定",spoolmanFilamentCatalogTitle:"Spoolman 耗材目錄",spoolmanFilamentCatalogDesc:"來自 Spoolman 的耗材名稱和皮重。名稱和線軸重量可在此處編輯;其他屬性請直接在 Spoolman 中管理。",spoolmanUrl:"Spoolman URL",spoolmanUrlHint:"Spoolman 伺服器的 URL(例如 http://localhost:7912)",spoolmanConnected:"已連線",spoolmanDisconnected:"未連線",status:"狀態",connect:"連線",disconnect:"斷開",howSyncWorks:"同步工作原理",syncInfoRfidOnly:"僅同步帶有 RFID 的官方拓竹耗材",syncInfoAutoCreate:"首次同步時自動在 Spoolman 中建立新耗材",syncInfoThirdPartySkipped:"非拓竹耗材(第三方、重新填充的)將被跳過",linkingExistingSpools:"連結現有耗材",linkingExistingSpoolsDesc:'要將現有的 Spoolman 耗材連結到您的 AMS,請將滑鼠懸停在 AMS 槽位上並點選"連結到 Spoolman"。',syncMode:"同步模式",syncModeAuto:"自動",syncModeManual:"僅手動",syncModeAutoDesc:"偵測到更改時自動同步 AMS 資料",syncModeManualDesc:"僅在手動觸發時同步",syncAmsData:"同步 AMS 資料",syncAmsDataDesc:"手動將印表機 AMS 資料同步到 Spoolman",allPrinters:"所有印表機",noDefaultPrinter:"無預設(每次詢問)",sidebarOrder:"側邊欄順序",saveThumbnails:"儲存縮圖",captureFinishPhoto:"拍攝完成照片",noPrintersConfigured:"未設定印表機",archiveMode:{always:"始終建立歸檔條目",never:"從不建立歸檔條目",ask:"每次詢問"},checkForUpdatesLabel:"檢查更新",checkPrinterFirmware:"檢查印表機韌體",includeBetaUpdates:"包含測試版本",includeBetaUpdatesDesc:"檢查更新時通知測試版和預發布版本",enableRetry:"啟用重試",homeAssistantDescription:"透過 Home Assistant 控制智慧插座",environmentManagedLabel:"(環境變數管理)",autoEnabledViaEnv:"透過環境變數自動啟用",urlFromEnvReadOnly:"值由 HA_URL 環境變數設定(只讀)",tokenFromEnvReadOnly:"值由 HA_TOKEN 環境變數設定(只讀)",mqttConnectedTo:"已連線到",prometheusDescription:"以 Prometheus 格式暴露印表機資料",noSmartPlugsTitle:"未設定智慧插座",noSmartPlugsDescription:"新增基於 Tasmota 的智慧插座以追蹤能耗並自動化電源控制。",noProvidersTitle:"未設定提供者",noProvidersDescription:"新增提供者以接收警報。",noTemplatesAvailable:"無可用範本。重新啟動後端以載入預設範本。",apiPermissionView:"檢視印表機狀態和佇列",apiPermissionEdit:"新增和移除列印佇列中的項目",apiKeysEmptyTitle:"無 API 金鑰",apiKeysEmptyDescription:"建立 API 金鑰以與外部服務整合。",noUsersFound:"未找到使用者",noGroupsFound:"未找到群組",noGroupsAvailable:"無可用群組",passwordsDoNotMatch:"密碼不符",systemGroupWarning:"系統群組名稱不可更改",authDisabledTitle:"身份驗證已停用",authDisabledFeature1:"需要登入才能存取系統",authDisabledFeature2:"建立多個使用者並基於群組的權限管理",authDisabledFeature3:"使用 50+ 個細粒度權限控制存取",userHasCreated:"此使用者已建立:",userItemsQuestion:"您想如何處理這些項目?",deleteUserConfirm:"確定要刪除此使用者嗎?",actionCannotBeUndone:"此操作無法復原。",addFirstSmartPlug:"新增您的第一個智慧插座",providers:"提供者",log:"日誌",testAll:"全部測試",testResults:"測試結果",testPassedCount:"{{count}} 個透過",testFailedCount:"{{count}} 個失敗",messageTemplates:"訊息範本",messageTemplatesDescription:"自訂每個事件的通知訊息。",apiKeys:"API 金鑰",apiKeysDescription:"建立 API 金鑰用於外部整合和 Webhook。",createKey:"建立金鑰",apiKeyCreated:"API 金鑰建立成功",apiKeyCopyWarning:"請立即複製此金鑰 - 它不會再次顯示!",useInApiBrowser:"在 API 瀏覽器中使用",createNewApiKey:"建立新 API 金鑰",keyName:"金鑰名稱",keyNamePlaceholder:"例如:Home Assistant、OctoPrint",readStatus:"讀取狀態",readStatusDescription:"檢視印表機狀態和佇列",manageQueue:"管理佇列",manageQueueDescription:"新增和移除列印佇列中的項目",controlPrinter:"控制印表機",controlPrinterDescription:"暫停、繼續和停止列印",cloudAccess:"允許雲端存取",cloudAccessDescription:"代表您讀取 Bambu Cloud 預設和耗材。需要登入 Bambu Cloud。",cloudBadge:"雲端",updateEnergyCost:"更新電價",updateEnergyCostDescription:"允許此金鑰向 /settings/electricity-price POST 新的每千瓦時電價。適用於 Home Assistant 動態電價自動化(Tibber、Octopus 等)。這是唯一可透過 API 金鑰寫入的設定欄位。",energyCostBadge:"能耗",legacyKey:"舊版",legacyKeyTooltip:"在按使用者所有權之前建立;需重建以使用雲端存取",unnamedKey:"未命名金鑰",lastUsed:"上次使用",read:"讀取",control:"控制",createFirstKey:"建立您的第一個金鑰",webhookEndpoints:"Webhook 端點",webhookApiKeyHint:"在 X-API-Key 請求頭中使用您的 API 金鑰。",webhook:{getAllStatus:"獲取所有印表機狀態",getSpecificStatus:"獲取特定印表機狀態",addToQueue:"新增到列印佇列",pausePrint:"暫停列印",resumePrint:"繼續列印",stopPrint:"停止列印"},apiBrowser:"API 瀏覽器",apiBrowserDescription:"瀏覽和測試所有可用的 API 端點。",apiKeyForTesting:"測試用 API 金鑰",apiKeyPlaceholder:"在此貼上您的 API 金鑰以測試需要認證的端點...",apiKeyHint:"此金鑰將作為 X-API-Key 請求頭隨請求傳送。",deleteApiKeyTitle:"刪除 API 金鑰",deleteApiKeyMessage:"確定要刪除此 API 金鑰嗎?使用此金鑰的所有整合將停止工作。",deleteKey:"刪除金鑰",amsDisplayThresholds:"AMS 顯示閾值",amsThresholdsDescription:"設定 AMS 濕度和溫度指示器的顏色閾值。",humidity:"濕度",goodGreen:"良好(綠色)",fairOrange:"一般(橙色)",aboveFairBad:"超過一般閾值顯示為紅色(差)",fairAlsoDryingThreshold:"此閾值也用於觸發自動乾燥",temperature:"溫度",goodBlue:"良好(藍色)",aboveFairHot:"超過一般閾值顯示為紅色(熱)",historyRetention:"歷史保留",keepSensorHistory:"保留感測器歷史",historyRetentionDescription:"較舊的濕度和溫度資料將被自動刪除",defaultPrintOptions:"預設列印選項",defaultPrintOptionsDescription:"設定新列印的預設選項值。可在列印對話方塊中逐次覆蓋。",defaultBedLevelling:"熱床調平",defaultBedLevellingDesc:"列印前自動調平熱床",defaultFlowCali:"流量校準",defaultFlowCaliDesc:"校準擠出流量",defaultVibrationCali:"振動校準",defaultVibrationCaliDesc:"減少振紋偽影",defaultLayerInspect:"首層檢測",defaultLayerInspectDesc:"AI首層檢測",defaultTimelapse:"縮時攝影",defaultTimelapseDesc:"錄製縮時攝影影片",staggeredStart:"錯開啟動",staggeredStartDescription:"多台印表機批次啟動時的預設群組大小與間隔。可在列印對話框中逐批覆寫。",plateClear:"熱床清空確認",requirePlateClear:"需要熱床清空確認",requirePlateClearDescription:"啟用後,排程器會在已完成列印的印表機上啟動佇列列印之前,等待每臺印表機的熱床清空確認。停用後,也會隱藏印表機卡片上的列印板狀態標記和「將列印板標記為已清理」按鈕。",gcodeInjection:"G-code注入",gcodeInjectionDescription:'為Farmloop、SwapMod、AutoClear和Printflow 3D等自動列印系統設定自訂G-code,在列印開始和/或結束時注入。程式碼片段按印表機型號設定,在佇列項目上啟用"注入G-code"時套用。',gcodeInjectionNoPrinters:"未找到印表機。新增印表機以設定G-code程式碼片段。",gcodeStartLabel:"開始G-code",gcodeEndLabel:"結束G-code",gcodeStartPlaceholder:"在列印開始前插入的G-code...",gcodeEndPlaceholder:"在列印結束後追加的G-code...",staggerGroupSize:"群組大小",staggerGroupSizeHelp:"每個群組要同時啟動的印表機數量",staggerInterval:"間隔(分鐘)",staggerIntervalHelp:"每個群組啟動之間的延遲",queueDrying:"自動乾燥",queueDryingDescription:"在佇列列印之間,印表機空閒時自動乾燥AMS耗材。使用上方的濕度閾值觸發乾燥。",queueDryingEnabled:"啟用自動乾燥",queueDryingEnabledDescription:"當印表機空閒且濕度超過閾值時,自動啟動AMS乾燥",queueDryingBlock:"等待乾燥完成",queueDryingBlockDescription:"阻止列印佇列直到乾燥完成。關閉時,列印優先於乾燥。",ambientDryingEnabled:"環境乾燥",ambientDryingEnabledDescription:"當空閒印表機的濕度超過閾值時自動乾燥耗材,無需佇列列印。",dryingPresets:"乾燥預設",dryingPresetsDescription:"每種耗材類型的溫度和時長。AMS 2 Pro使用較低溫度,AMS-HT支援較高溫度。",dryingFilament:"耗材",printModal:"列印對話方塊",expandCustomMapping:"預設展開自訂對應",expandCustomMappingDescription:"列印到多臺印表機時,預設展開顯示每臺印表機的 AMS 對應",authentication:"身份驗證",authEnabledDescription:"您的實例已透過使用者身份驗證保護",authDisabledDescription:"啟用以要求登入並管理使用者存取",authDisabledMessage:"啟用身份驗證以建立使用者帳戶、管理權限並保護您的 Bambuddy 實例。",enableAuthentication:"啟用身份驗證",currentUser:"目前使用者",changePassword:"修改密碼",admin:"管理員",users:"使用者",addUser:"新增使用者",groups:"群組",addGroup:"新增群組",system:"系統",noDescription:"無描述",userCount:"{{count}} 個使用者",permissionCount:"{{count}} 個權限",createUser:"建立使用者",username:"使用者名稱",enterUsername:"輸入使用者名稱",password:"密碼",enterPassword:"輸入密碼",passwordRequirements:"至少 8 個字元,包含一個大寫、一個小寫、一個數字和一個特殊字元。",confirmPassword:"確認密碼",confirmPasswordPlaceholder:"確認密碼",viewReleaseOnGitHub:"在 GitHub 上檢視發布",turnAllPlugsOn:"開啟所有插座",turnAllPlugsOff:"關閉所有插座",clearNotificationLogs:"清除通知日誌",clearLogsMessage:"這將永久刪除所有 30 天前的通知日誌。此操作無法復原。",clearLogs:"清除日誌",resetUiPreferences:"重設 UI 偏好",resetUiPreferencesMessage:"這將重設所有 UI 偏好為預設值:側邊欄順序、主題、儀表板佈局、檢視模式和排序偏好。您的印表機、歸檔和伺服器設定不會受到影響。清除後頁面將重新載入。",resetPreferences:"重設偏好",deleteGroupTitle:"刪除群組",deleteGroupMessage:"確定要刪除此群組嗎?此群組中的使用者將失去這些權限。",deleteGroup:"刪除群組",disableAuthenticationTitle:"停用身份驗證",disableAuthenticationMessage:"確定要停用身份驗證嗎?這將使您的 Bambuddy 實例無需登入即可存取。所有使用者將保留在資料庫中但身份驗證將被停用。",disableAuthentication:"停用身份驗證",configureBambuddy:"設定 Bambuddy",systemDefault:"系統預設",archiveSettings:"歸檔設定",newWindow:"新視窗",embeddedOverlay:"嵌入式疊加層",preferredSlicer:"首選切片軟體",preferredSlicerDescription:"選擇要用於開啟檔案的切片軟體",orcaslicerKnownIssuesWarning:"OrcaSlicer 2.3.2 / 2.4.0-dev 存在已知 CLI 錯誤,無法切片許多 Bambu 建立的 3MF — 見上游 issue #12426(繪製的多擠出機檔案 segfault)和 #13386(參數範圍嚴格驗證拒絕)。在上游修復發布之前,推薦使用 Bambu Studio。",useSlicerApi:"使用切片器 API",useSlicerApiDescription:"開啟時,「切片」操作開啟應用程式內切片器對話框並呼叫 slicer-API sidecar。關閉時(預設),透過 URI 方案交給桌面切片器。",slicerCard:"切片器",orcaslicerApiUrl:"OrcaSlicer sidecar URL",bambuStudioApiUrl:"Bambu Studio sidecar URL",slicerApiUrlDescription:"slicer-API sidecar 容器的 URL。留空以使用 SLICER_API_URL / BAMBU_STUDIO_API_URL 環境變數預設值。",slicerBundles:{title:"切片器捆綁包",description:'匯入從 BambuStudio 匯出的 Printer Preset Bundle (.bbscfg)(檔案 → 匯出 → 匯出預設捆綁包 → "Printer preset bundle")。匯入後,切片請求可以按名稱從捆綁包中選擇預設,無需重新上傳 JSON 設定三元組。',uploadButton:"上傳捆綁包",uploading:"上傳中…",loading:"載入捆綁包中…",empty:"尚未匯入捆綁包。",summary:"{{processCount}} 個製程 · {{filamentCount}} 個耗材預設",delete:"刪除",uploadSuccess:"已匯入 {{name}}",uploadError:"上傳捆綁包失敗:{{message}}",deleteSuccess:"捆綁包已移除",deleteError:"刪除捆綁包失敗:{{message}}",confirmDeleteTitle:"移除此捆綁包?",confirmDeleteMessage:"引用「{{name}}」的切片請求將失敗,直到捆綁包重新匯入。"},externalCameras:"外部攝影機",costTracking:"成本追蹤",printsOnly:"僅列印",totalConsumption:"總消耗",dataManagement:"資料管理",storageUsage:"儲存使用情況",storageUsageDescription:"按類別的資料使用情況明細",storageUsageTotal:"總計",storageUsageErrors:"錯誤",storageUsageOtherBreakdown:"其他(包括靜態資源、腳本和設定檔案)",storageUsageSystem:"系統",storageUsageData:"資料",storageUsageUnavailable:"儲存使用資訊不可用",clearNotificationLogsDescription:"刪除 30 天前的通知日誌",resetUiPreferencesDescription:"重設側邊欄順序、主題、檢視模式和佈局偏好。印表機、歸檔和設定不受影響。",enableHomeAssistant:"啟用 Home Assistant",enableMqtt:"啟用 MQTT",useTls:"使用 TLS",enableMetricsEndpoint:"啟用指標端點",availableMetrics:"可用指標",editUser:"編輯使用者",deleteUserTitle:"刪除使用者",groupName:"群組名稱",leaveEmptyForAnonymous:"留空為匿名",leaveEmptyForNoAuth:"留空為無認證",enterNewPassword:"輸入新密碼",confirmNewPassword:"確認新密碼",enterGroupName:"輸入群組名稱",enterDescriptionOptional:"輸入描述(可選)",enterCurrentPassword:"輸入目前密碼",enterNewPasswordMin6:"輸入新密碼(至少 6 個字元)",toast:{keyCopied:"金鑰已複製到剪貼簿",copyFailed:"複製金鑰失敗",keyAddedToBrowser:"金鑰已新增到 API 瀏覽器",clearLogsFailed:"清除日誌失敗",uiPreferencesReset:"UI 偏好已重設。重新整理中...",authDisabled:"身份驗證已成功停用",authDisableFailed:"停用身份驗證失敗",apiKeyCreated:"API 金鑰已建立",apiKeyDeleted:"API 金鑰已刪除",userCreated:"使用者建立成功",userUpdated:"使用者更新成功",userDeleted:"使用者刪除成功",groupCreated:"群組建立成功",groupUpdated:"群組更新成功",groupDeleted:"群組刪除成功",fillRequiredFields:"請填寫所有必填欄位",passwordsDoNotMatch:"密碼不符",passwordTooShort:"密碼至少需要 8 個字元",passwordNeedsUppercase:"密碼必須至少包含一個大寫字母",passwordNeedsLowercase:"密碼必須至少包含一個小寫字母",passwordNeedsDigit:"密碼必須至少包含一個數字",passwordNeedsSpecial:"密碼必須至少包含一個特殊字元",enterGroupName:"請輸入群組名稱",settingsSaved:"設定已儲存",noPermissionUpdate:"您沒有權限變更設定",cameraSettingsSaved:"攝影機設定已儲存",enterCameraUrl:"請輸入攝影機 URL",passwordChanged:"密碼修改成功",connectionFailed:"連線失敗",testFailed:"測試失敗",cameraConnected:"攝影機已連線{{resolution}}"},testConnection:"測試連線",catalog:{spoolCatalog:"耗材目錄",spoolCatalogDescription:"按品牌/類型的空耗材重量。用於新增耗材時的自動重量查詢。",searchCatalog:"搜尋目錄...",addNewEntry:"新增新條目",namePlaceholder:"名稱(例如:Bambu Lab - 塑膠)",weight:"重量",type:"類型",default:"預設",custom:"自訂",noMatch:"沒有條目匹配您的搜尋",empty:"目錄中沒有條目",deleteEntry:"刪除條目",deleteConfirm:'確定要刪除"{{name}}"嗎?',resetCatalog:"重設目錄",resetConfirm:"重設目錄為預設值?這將移除所有自訂條目。",loadFailed:"載入耗材目錄失敗",nameWeightRequired:"名稱和重量為必填項",entryAdded:"條目已新增",addFailed:"新增條目失敗",entryUpdated:"條目已更新",updateFailed:"更新條目失敗",entryDeleted:"條目已刪除",deleteFailed:"刪除條目失敗",resetSuccess:"目錄已重設為預設值",resetFailed:"重設目錄失敗",exported:"已匯出 {{count}} 條",imported:"已匯入 {{added}} 條(跳過 {{skipped}} 條)",importFailed:"匯入失敗:無效的 JSON 格式",exportTooltip:"匯出目錄為 JSON",importTooltip:"從 JSON 匯入目錄",resetTooltip:"重設為預設值",selectedCount:"已選擇 {{count}} 項",deleteSelected:"刪除所選",bulkDeleteConfirm:"確定要刪除 {{count}} 個條目嗎?",bulkDeleted:"已刪除 {{count}} 個條目",bulkDeleteFailed:"刪除條目失敗",material:"材料",spoolWeight:"線軸重量",color:"顏色",updateSpoolWeight:"更新線軸重量",filamentUpdated:"耗材已更新",filamentUpdateFailed:"更新耗材失敗",filamentUpdateInvalid:"耗材資料無效",keepExistingSpoolWeight:"保留現有線軸的舊重量",keepExistingSpoolWeightDesc:"已使用此耗材類型建立的線軸保留舊的皮重。新線軸使用更新後的值。",applyToAllSpools:"套用至所有線軸",applyToAllSpoolsDesc:"此耗材類型的所有重量計算立即使用新的皮重。"},colorCatalog:{title:"顏色目錄",description:"按製造商/材料的耗材顏色。用於新增耗材時的自動顏色查詢。",searchColors:"搜尋顏色...",allManufacturers:"所有製造商",addNewColor:"新增新顏色",manufacturer:"製造商",colorName:"顏色名稱",hex:"十六進位",materialOptional:"材料(可選)",showing:"顯示 {{filtered}} / {{total}} 種顏色",noMatch:"沒有顏色匹配您的搜尋",empty:"目錄中沒有顏色",deleteColor:"刪除顏色",deleteConfirm:'確定要刪除"{{name}}"嗎?',resetCatalog:"重設顏色目錄",resetConfirm:"重設目錄為預設值?這將移除所有自訂顏色。",sync:"同步",starting:"啟動中...",syncTooltip:"從 FilamentColors.xyz 同步(2000+ 種顏色,可能需要一分鐘)",loadFailed:"載入顏色目錄失敗",fieldsRequired:"製造商、顏色名稱和十六進位顏色為必填項",colorAdded:"顏色已新增",addFailed:"新增顏色失敗",colorUpdated:"顏色已更新",updateFailed:"更新顏色失敗",colorDeleted:"顏色已刪除",deleteFailed:"刪除顏色失敗",resetSuccess:"顏色目錄已重設為預設值",resetFailed:"重設目錄失敗",syncUpToDate:"已是最新(檢查了 {{count}} 種顏色)",syncComplete:"新增了 {{added}} 種新顏色({{skipped}} 種已存在)",syncError:"同步錯誤",syncFailed:"從 FilamentColors.xyz 同步失敗",exported:"已匯出 {{count}} 種顏色",imported:"已匯入 {{added}} 種顏色(跳過 {{skipped}} 種)",importFailed:"匯入失敗:無效的 JSON 格式",selectedCount:"已選擇 {{count}} 項",deleteSelected:"刪除所選",bulkDeleteConfirm:"確定要刪除 {{count}} 種顏色嗎?",bulkDeleted:"已刪除 {{count}} 種顏色",bulkDeleteFailed:"刪除顏色失敗"},dateFormat:"日期格式",dateFormatUs:"美式 (MM/DD/YYYY)",dateFormatEu:"歐式 (DD/MM/YYYY)",dateFormatIso:"ISO (YYYY-MM-DD)",timeFormat:"時間格式",timeFormat12:"12小時制 (3:30 PM)",timeFormat24:"24小時制 (15:30)",defaultPrinter:"預設印表機",defaultPrinterDescription:"為上傳、重印和其他操作預選此印表機。",slicerBambuStudio:"Bambu Studio",slicerOrcaSlicer:"OrcaSlicer",sidebarOrderDescription:"拖曳側邊欄項目以重新排序。在此處重設為預設順序。",setDefault:"設為預設",sidebarOrderSetDefaultHint:"設為預設將目前選單順序套用於尚未自訂的使用者。",sidebarDefaultSet:"已設定預設選單順序。",sidebarDefaultCleared:"已清除預設選單順序。",sidebarDefaultFailed:"設定預設選單順序失敗。",reset:"重設",darkMode:"深色模式",lightMode:"淺色模式",active:"(目前)",background:"背景",accent:"強調色",style:"樣式",bgNeutral:"中性",bgWarm:"暖色",bgCool:"冷色",bgOled:"OLED 純黑",bgSlate:"石板藍",bgForest:"森林綠",accentGreen:"綠色",accentTeal:"青色",accentBlue:"藍色",accentOrange:"橙色",accentPurple:"紫色",accentRed:"紅色",styleClassic:"經典",styleGlow:"發光",styleVibrant:"鮮豔",themeToggleHint:"使用側邊欄中的太陽/月亮圖示在深色和淺色模式之間切換。",autoArchivePrints:"自動歸檔列印",autoArchiveDescription:"列印完成時自動儲存3MF檔案",saveThumbnailsDescription:"從3MF檔案中提取並儲存預覽影像",captureFinishPhotoDescription:"列印完成時從印表機攝影機拍照",ffmpegNotInstalled:"未安裝ffmpeg",ffmpegRequired:"攝影機捕獲需要ffmpeg。透過 brew install ffmpeg(macOS)或 apt install ffmpeg(Linux)安裝。",camera:"攝影機",cameraViewMode:"攝影機檢視模式",cameraOverlayDescription:"攝影機在主螢幕上以可調大小的覆蓋層開啟",cameraWindowDescription:"攝影機在單獨的瀏覽器視窗中開啟",externalCamerasDescription:"設定外部攝影機以替換內建印表機攝影機。支援MJPEG流、RTSP、HTTP快照和USB攝影機(V4L2)。啟用後,外部攝影機將用於即時檢視和完成照片。",cameraPlaceholderUsb:"裝置路徑 (/dev/video0)",cameraPlaceholderUrl:"攝影機URL (rtsp://... 或 http://...)",cameraTypeMjpeg:"MJPEG 流",cameraTypeRtsp:"RTSP 流",cameraTypeSnapshot:"HTTP 快照",cameraTypeUsb:"USB 攝影機 (V4L2)",cameraSnapshotUrl:"快照 URL(選用)",cameraSnapshotUrlPlaceholder:"http://192.168.1.61:1984/api/frame.jpeg?src=printer",cameraSnapshotUrlHelp:"用於通知縮圖、完成照片、層縮時攝影影格和列印板偵測的單一影格 URL。縮時攝影和列印板偵測各自需要自己的每印表機切換 — 此 URL 只是它們啟用時拉取的影像來源。留空以從上方即時串流擷取。適用於 go2rtc(/api/frame.jpeg)和具有專用快照端點的 IP 攝影機。",cameraRotation:"旋轉",test:"測試",connected:"已連線",disconnected:"未連線",currency:"貨幣",defaultFilamentCost:"預設耗材成本(每公斤)",electricityCost:"每千瓦時電費",energyDisplayMode:"能源顯示模式",energyModePrintDescription:"儀表板顯示列印期間使用的能源總和",energyModeTotalDescription:"儀表板顯示智慧插座的累計能源",fileManager:"檔案管理器",createArchiveEntry:"列印時建立歸檔條目",createArchiveEntryDescription:"從檔案管理器列印時,可選擇建立歸檔條目",lowDiskSpaceWarning:"磁碟空間不足警告",lowDiskSpaceDescription:"當可用磁碟空間低於此閾值時顯示警告",printerFirmware:"印表機韌體",checkFirmwareDescription:"檢查Bambu Lab的印表機韌體更新",bambuddySoftware:"Bambuddy 軟體",autoCheckDescription:"啟動時自動檢查新版本",checkNow:"立即檢查",updateAvailableVersion:"可用更新:v{{version}}",releaseNotes:"發布說明",updateViaDocker:"透過 Docker Compose 更新:",updateViaHomeAssistant:"更新由 Home Assistant Supervisor 管理。請在 Home Assistant 中開啟 設定 → 附加元件 → Bambuddy 以安裝新版本。",installUpdate:"安裝更新",latestVersionRunning:"您正在執行最新版本",failedToCheckUpdates:"檢查更新失敗:{{error}}",backupRestore:"備份與恢復",backupRestoreDescription:"匯出/匯入設定並設定GitHub 備份",goToBackup:"前往備份",externalUrl:"外部URL",externalUrlDescription:"Bambuddy可存取的外部URL。用於通知影像和外部整合。",bambuddyUrl:"Bambuddy URL",externalUrlHint:"包含協定和連接埠(例如:http://192.168.1.100:8000)",ftpRetry:"FTP重試",ftpRetryDescription:"當印表機Wi-Fi 不穩定時重試FTP操作。適用於3MF下載、列印上傳、縮時攝影下載和韌體更新。",autoRetryDescription:"自動重試失敗的FTP操作",retryAttempts:"重試次數",retryDelay:"重試延遲",connectionTimeout:"連線超時",time_one:"{{count}} 次",time_other:"{{count}} 次",second_one:"{{count}} 秒",second_other:"{{count}} 秒",nSeconds:"{{count}} 秒",increaseForWeakWifi:"對Wi-Fi 訊號弱的印表機增加此值",homeAssistant:"Home Assistant",homeAssistantFullDescription:"連線到Home Assistant,透過HA REST API控制智慧插座。支援switch、light、input_boolean和script實體。",homeAssistantUrl:"Home Assistant URL",longLivedAccessToken:"長期存取權杖",haTokenHint:"在HA中建立權杖:個人資料 → 長期存取權杖 → 建立權杖",connectionSuccessful:"連線成功",connectionFailed:"連線失敗",haConnectionSuccess:"已成功連線到Home Assistant。",haConnectionFailed:"連線Home Assistant失敗。",mqttPublishing:"MQTT發布",mqttDescription:"將BamBuddy事件發布到外部MQTT代理,用於與Node-RED、Home Assistant和其他自動化系統整合。",mqttEnableDescription:"向外部MQTT代理發布事件",brokerHostname:"代理主機名稱",port:"連接埠",usernameOptional:"使用者名稱(可選)",passwordOptional:"密碼(可選)",topicPrefix:"主題前綴",topicPrefixHint:"主題格式:{{prefix}}/printers//status 等",prometheusMetrics:"Prometheus 指標",prometheusEndpointDescription:"在 /api/v1/metrics 公開印表機指標,用於Prometheus/Grafana監控。",bearerTokenOptional:"Bearer權杖(可選)",bearerTokenHint:"設定後,請求必須包含 Authorization: Bearer ",metricsConnectionStatus:"連線狀態",metricsPrinterState:"印表機狀態(空閒/列印中等)",metricsPrintProgress:"列印進度 0-100%",metricsBedTemp:"熱床溫度",metricsNozzleTemp:"噴嘴溫度",metricsPrintsTotal:"按結果分類的總列印數",metricsMore:"...以及更多(層數、風扇、佇列、耗材用量)",smartPlugsDescription:"連線智慧插座(Tasmota或Home Assistant)以自動化電源控制並追蹤印表機的能源使用情況。",allOn:"全部開啟",allOff:"全部關閉",addSmartPlug:"新增智慧插座",energySummary:"能源概要",currentPower:"目前功率",plugsOnline:"{{reachable}}/{{total}} 個插座線上",today:"今天",yesterday:"昨天",total:"總計",enablePlugsForSummary:"啟用插座以檢視能源概要",addNotificationProvider:"新增",systemBadge:"(系統)",creating:"建立中...",changing:"修改中...",deleteUserAndItems:"刪除使用者及其所有項目",deleteUserKeepItems:"刪除使用者,保留項目(將變為無主項目)",ok:"確定",twoFa:{totpTitle:"身份驗證器 App (TOTP)",totpDesc:"使用 Google Authenticator、Aegis 或 Authy 等 App。",emailOtpTitle:"郵件 OTP",emailOtpDesc:"登入時向 {{email}} 傳送一次性驗證碼。",emailOtpNoEmail:"請先為帳戶新增信箱地址以啟用此方式。",addEmailFirst:"您的帳戶沒有信箱地址,請聯絡管理員新增。",setupTotp:"設定身份驗證器 App",setupAuthApp:"設定身份驗證器 App",setupInstructions:"使用身份驗證器 App 掃描QR Code,然後輸入驗證碼確認。",manualEntry:"無法掃描?請手動輸入此金鑰:",scannedContinue:"已掃描 — 繼續",enterCodeToConfirm:"請輸入身份驗證器 App 中的6位驗證碼以確認設定。",activate:"啟用",disableTotp:"停用身份驗證器",disableConfirmHint:"請輸入有效的 TOTP 碼或備用碼來停用身份驗證器。",totpDisabled:"身份驗證器 App 已停用。",emailOtpEnabled:"郵件 OTP 已啟用。",emailOtpDisabled:"郵件 OTP 已停用。",smtpRequired:"請先設定並測試SMTP設定。",invalidCode:"無效驗證碼,請重試。",enableEmailOtp:"啟用郵件 OTP",disableEmailOtp:"停用郵件 OTP",emailSetupEnterCode:"驗證碼已傳送至您的信箱地址。請在下方輸入以確認您擁有此信箱。",verifyAndEnable:"驗證並啟用",emailDisablePasswordHint:"請輸入您的帳戶密碼以確認停用郵件 OTP。",passwordPlaceholder:"輸入您的密碼",backupCodesTitle:"儲存備用碼",backupCodesWarning:"請將這些碼儲存在安全的地方。每個碼只能使用一次,且不會再次顯示。",backupCodesRemaining:"剩餘 {{count}} 個備用碼",savedCodes:"已儲存",regenBackup:"重新產生備用碼",regenBackupHint:"輸入目前 TOTP 碼以產生 10 個新備用碼,所有現有備用碼將失效。",newBackupCodes:"新備用碼",linkedAccounts:"已連結的 SSO 帳戶",linkedAccountsDesc:"以下外部身份提供者已與您的帳戶連結。",oidcUnlinked:"帳戶已解除連結。"},oidc:{title:"SSO / OIDC 提供者",desc:"設定 OpenID Connect 提供者以實現單點登入。",addProvider:"新增提供者",newProvider:"新提供者",empty:"尚未設定 OIDC 提供者。",created:"提供者已建立。",updated:"提供者已更新。",deleted:"提供者已刪除。",refreshIcon:"重新整理圖示",removeIcon:"移除圖示",iconRefreshed:"圖示已重新整理。",iconRemoved:"圖示已移除。",iconFetchFailed:"無法從提供者 URL 取得圖示。",deleteTitle:"刪除提供者",deleteMessage:'刪除"{{name}}"?所有連結帳戶將斷開連線。',form:{name:"顯示名稱",issuerUrl:"頒發者 URL",clientId:"客戶端 ID",clientSecret:"客戶端金鑰",scopes:"作用域",iconUrl:"圖示 URL(可選)",enabled:"已啟用",autoCreate:"自動建立使用者",autoCreateDesc:"首次登入時自動建立本機帳戶。",autoLink:"自動連結已有帳戶",autoLinkDesc:"首次登入時透過信箱匹配現有本機帳戶並自動連結。",emailClaim:"電子郵件聲明",emailClaimDesc:"用作電子郵件身份的 JWT 聲明。Azure Entra ID 請使用 'preferred_username' 或 'upn'(不發送 email_verified)。僅使用可信的聲明名稱。",emailClaimPlaceholder:"電子郵件",emailClaimCustomClaimAutoLinkWarning:"自訂宣告僅在值由租用戶管理時(例如 Azure Entra ID 的 upn / preferred_username)對自動關聯安全。如果您的 IdP 允許使用者自我宣告此宣告,請勿啟用自動關聯。",requireEmailVerified:"要求電子郵件已驗證",requireEmailVerifiedDesc:"僅在提供商將電子郵件聲明標記為已驗證時才接受。",requireEmailVerifiedWarning:"警告:將在未經驗證的情況下接受電子郵件。僅對受信任的提供商使用。",requireEmailVerifiedAutoLink:"請先停用自動連結以變更此設定。",secretHint:"留空以保留目前",secretPlaceholder:"新金鑰",defaultGroup:"預設群組",defaultGroupDesc:"自動建立使用者時分配的群組。未設定時回退到 Viewers。",defaultGroupViewersFallback:"Viewers(預設)"}},encryption:{title:"MFA 加密狀態",enabledFromEnv:"已啟用靜態加密(金鑰來自 MFA_ENCRYPTION_KEY 環境變數)",enabledFromFile:"已啟用靜態加密(金鑰從資料目錄載入)",enabledGenerated:"使用自動產生的金鑰啟用靜態加密",notConfigured:"未設定靜態加密",notConfiguredDesc:"TOTP 機密和 OIDC client_secrets 以明文儲存。請設定 MFA_ENCRYPTION_KEY 或使用可寫資料目錄重新啟動 Bambuddy 以自動產生。",allEncrypted:"所有 MFA 機密皆已靜態加密。",legacyRowsLabel:"舊版明文列",encryptedRowsLabel:"已加密列",legacyRowsWarning:"偵測到 {{count}} 個舊版明文列。請重新儲存 OIDC 供應商或重新註冊使用者的身份驗證器應用程式,以遷移到加密儲存。",backupHint:"自動產生的金鑰儲存在 DATA_DIR/.mfa_encryption_key 中,並包含在本機備份 ZIP 中。請保護備份安全或顯式設定 MFA_ENCRYPTION_KEY。",decryptionBrokenTitle:"加密金鑰遺失",decryptionBrokenError:"無法解密 {{count}} 條加密記錄,因為加密金鑰不再可用。請還原先前的 MFA_ENCRYPTION_KEY 或 DATA_DIR/.mfa_encryption_key 以恢復存取。",migrationErrorWarning:"{{count}} 行舊資料在啟動時未能重新加密。請檢查伺服器日誌並重新啟動 Bambuddy 以重試。"}},notification:{printStarted:{title:"列印已開始",body:"{{printer}}:{{filename}} 已開始列印"},printCompleted:{title:"列印已完成",body:"{{printer}}:{{filename}} 已成功完成"},printFailed:{title:"列印失敗",body:"{{printer}}:{{filename}} 列印失敗"},printStopped:{title:"列印已停止",body:"{{printer}}:{{filename}} 已停止"},printProgress:{title:"列印進度",body:"{{printer}}:{{filename}} 已完成 {{percent}}%"},printerOffline:{title:"印表機離線",body:"{{printer}} 已離線"},printerError:{title:"印表機錯誤",body:"{{printer}}:{{error}}"},filamentLow:{title:"耗材不足",body:"{{printer}}:耗材即將用完"},maintenanceDue:{title:"維護到期",body:"{{printer}}:{{items}} 需要關注"}},errors:{generic:"出了點問題",networkError:"網路錯誤。請檢查您的連線。",notFound:"未找到",unauthorized:"未授權",serverError:"伺服器錯誤",validationError:"請檢查您的輸入",printerConnectionFailed:"連線印表機失敗",saveFailed:"儲存更改失敗",deleteFailed:"刪除失敗",loadFailed:"載入資料失敗"},hmsErrors:{title:"錯誤 - {{name}}",noErrors:"無錯誤",viewOnWiki:"在拓竹 Wiki 上檢視",clearInstructions:"在印表機上清除錯誤以在此處消除它們。",clearErrors:"清除錯誤",clearSuccess:"HMS 錯誤已清除",clearFailed:"清除 HMS 錯誤失敗"},mqttDebug:{title:"MQTT 偵錯日誌",searchPlaceholder:"搜尋主題或負載...",noMessages:"尚未紀錄訊息",startLoggingHint:'點選"開始紀錄"以開始捕獲 MQTT 訊息',noMessagesMatch:"沒有訊息匹配您的篩選條件",adjustFilterHint:"嘗試調整您的搜尋或篩選條件",incoming:"傳入",outgoing:"傳出",loggingStopped:"紀錄已停止",loggingActive:"紀錄中 - 訊息將自動重新整理",startLogging:"開始紀錄",stopLogging:"停止紀錄",clearLog:"清除日誌",topic:"主題",timestamp:"時間戳",direction:"方向",all:"全部"},printerFiles:{title:"檔案管理器",storageUsed:"已用:",storageFree:"剩餘:",filterPlaceholder:"篩選檔案...",deleteButton:"刪除",deleteFiles:"刪除 {{count}} 個檔案",deleteFileConfirm:'刪除"{{name}}"?此操作無法復原。',deleteFilesConfirm:"刪除 {{count}} 個選中的檔案?此操作無法復原。",noFiles:"印表機上沒有檔案",loadingFiles:"載入檔案中...",failedToLoad:"載入檔案失敗",toast:{filesDeleted:"已刪除 {{count}} 個檔案",deleteFailed:"刪除失敗:{{error}}"}},confirm:{delete:"確定要刪除嗎?",unsavedChanges:"您有未儲存的更改。確定要離開嗎?",clearQueue:"確定要清空佇列嗎?"},login:{title:"Bambuddy 登入",subtitle:"登入您的帳戶",username:"使用者名稱",usernamePlaceholder:"輸入您的使用者名稱",usernameOrEmail:"使用者名稱或信箱",usernameOrEmailPlaceholder:"使用者名稱或 @ 信箱",password:"密碼",passwordPlaceholder:"輸入您的密碼",signIn:"登入",signingIn:"登入中...",rememberMe:"記住我",forgotPassword:"忘記密碼?",loginSuccess:"登入成功",loginFailed:"登入失敗",enterCredentials:"請輸入使用者名稱和密碼",enterEmail:"請輸入您的電子郵件地址",oidcLoginFailed:"OIDC 登入失敗",oidcErrors:{providerError:"身份提供者返回了一個錯誤",missingParameters:"OIDC 回呼缺少必要引數",invalidState:"OIDC 狀態無效或已被使用",stateExpired:"OIDC 登入會話已過期,請重試",providerNotFound:"未找到 OIDC 提供者",discoveryFailed:"無法獲取 OIDC 探索文件",invalidDiscovery:"OIDC 探索文件無效",networkError:"OIDC 權杖交換時出現網路錯誤",badResponse:"OIDC 權杖交換時收到意外回應",noIdToken:"OIDC 提供者未返回 ID 權杖",validationFailed:"OIDC 權杖驗證失敗",nonceMismatch:"OIDC nonce 不符,可能存在重放攻擊",missingSubClaim:"OIDC 權杖缺少 sub 宣告",noLinkedAccount:"沒有與此 OIDC 身份連結的本機帳戶",accountInactive:"您的帳戶已被停用",userResolutionFailed:"無法解析您的帳戶",internalError:"OIDC 登入過程中發生內部錯誤",tokenExchangeFailed:"OIDC 權杖交換失敗"},forgotPasswordTitle:"忘記密碼",forgotPasswordMessage:"如果您忘記了密碼,請聯絡系統管理員進行重設。",forgotPasswordEmailMessage:"輸入您的信箱地址,我們將向您傳送新密碼。",emailAddress:"信箱地址",emailPlaceholder:"your.email@example.com",cancel:"取消",sending:"傳送中...",sendResetEmail:"傳送重設郵件",howToReset:"如何重設密碼:",resetStep1:"聯絡您的 Bambuddy 管理員",resetStep2:"請他們在使用者管理中重設您的密碼",resetStep3:"他們可以為您設定一個臨時密碼",resetStep4:"使用新密碼登入並在設定中修改密碼",gotIt:"知道了",resetPassword:{title:"設定新密碼",subtitle:"請在下方輸入並確認您的新密碼。",newPassword:"新密碼",newPasswordPlaceholder:"至少 8 個字元",confirmPassword:"確認密碼",confirmPasswordPlaceholder:"重複輸入新密碼",saving:"儲存中…",submit:"設定新密碼",backToLogin:"回到登入",passwordsDoNotMatch:"密碼不符",passwordTooShort:"密碼至少需要 8 個字元",resetFailed:"密碼重設失敗。連結可能已過期。"},twoFA:{title:"兩步驗證",subtitle:"您的帳戶已啟用兩步驗證。請在下方輸入驗證碼。",methodAuthenticator:"身份驗證器 App",methodEmail:"信箱驗證碼",methodBackup:"備用恢復碼",instructionsTotp:"請開啟您的身份驗證器 App,輸入 Bambuddy 的 6 位驗證碼。",instructionsEmail:"6 位驗證碼已傳送至您的信箱,有效期為 10 分鐘。",instructionsEmailNotSent:"點選下方按鈕,透過郵件獲取驗證碼。",instructionsBackup:"請輸入您的一個 8 位備用恢復碼。每個恢復碼只能使用一次。",sendCodeButton:"傳送信箱驗證碼",sendingCode:"傳送中...",resendCode:"重新傳送驗證碼",codeLabel:"驗證碼",backupCodeLabel:"備用恢復碼",codePlaceholder:"000000",backupCodePlaceholder:"XXXXXXXX",verifyButton:"驗證",verifyingButton:"驗證中...",backToLogin:"← 回到登入頁面",orContinueWith:"或透過以下方式登入",signInWith:"使用 {{provider}} 登入",enterCode:"請輸入驗證碼",sendCodeFailed:"驗證碼傳送失敗",invalidCode:"無效驗證碼,請重試。"}},setup:{title:"Bambuddy 設定",subtitle:"為您的 Bambuddy 實例設定身份驗證",enableAuth:"啟用身份驗證",adminAccount:"管理員帳戶",adminAccountDesc:"如果管理員使用者已存在,將使用現有管理員帳戶啟用身份驗證。如需使用現有管理員,請將下方欄位留空,或輸入新憑據建立新管理員使用者。",adminUsername:"管理員使用者名稱",adminPassword:"管理員密碼",optionalIfAdminExists:"(如管理員使用者已存在則為可選)",adminUsernamePlaceholder:"輸入管理員使用者名稱(可選)",adminPasswordPlaceholder:"輸入管理員密碼(可選)",confirmPassword:"確認密碼",confirmPasswordPlaceholder:"確認管理員密碼",settingUp:"設定中...",completeSetup:"完成設定",toast:{authEnabledAdminCreated:"身份驗證已啟用並建立了管理員使用者",authEnabledExistingAdmins:"使用現有管理員使用者啟用了身份驗證",setupCompleted:"設定完成",enterBothCredentials:"請輸入管理員使用者名稱和密碼,或將兩者留空以使用現有管理員使用者",passwordsDoNotMatch:"密碼不符",passwordTooShort:"密碼至少需要 6 個字元"}},changePassword:{title:"修改密碼",currentPassword:"目前密碼",currentPasswordPlaceholder:"輸入目前密碼",newPassword:"新密碼",newPasswordPlaceholder:"輸入新密碼(至少 6 個字元)",confirmPassword:"確認新密碼",confirmPasswordPlaceholder:"確認新密碼",passwordsDoNotMatch:"密碼不符",passwordTooShort:"密碼至少需要 6 個字元",changing:"修改中...",success:"密碼修改成功",failed:"密碼修改失敗"},plateAlert:{title:"列印已暫停!",message:"在列印板上偵測到物體。列印已自動暫停。請清理列印板並繼續列印。",understand:"我知道了"},camera:{title:"攝影機檢視",invalidPrinterId:"無效的印表機 ID",live:"即時",snapshot:"快照",restartStream:"重新啟動流",refreshSnapshot:"重新整理快照",fullscreen:"全螢幕",exitFullscreen:"離開全螢幕",connectingToCamera:"連線攝影機中...",capturingSnapshot:"拍攝快照中...",connectionLost:"連線已斷開",connectionFailed:"攝影機連線失敗",reconnecting:"{{countdown}} 秒後重新連線...(第 {{attempt}}/{{max}} 次嘗試)",reconnectNow:"立即重新連線",cameraUnavailable:"攝影機不可用",cameraUnavailableDesc:"請確保印表機已通電並已連線。",noCamera:"無可用攝影機",retry:"重試",cameraStream:"攝影機流",zoomOut:"縮小",zoomIn:"放大",resetZoom:"重設縮放",recording:"錄製中",startRecording:"開始錄製",stopRecording:"停止錄製",chamberLight:"切換腔室燈"},groups:{title:"群組管理",subtitle:"管理存取控制的權限群組",backToSettings:"返回設定",createGroup:"建立群組",noPermission:"您沒有存取此頁面的權限。",system:"系統",noDescription:"無描述",usersCount:"{{count}} 個使用者",permissionsCount:"{{count}} 個權限",edit:"編輯",delete:"刪除",toast:{created:"群組建立成功",updated:"群組更新成功",deleted:"群組刪除成功",enterGroupName:"請輸入群組名稱"},modal:{editGroup:"編輯群組",createGroup:"建立群組",cancel:"取消",saving:"儲存中...",creating:"建立中...",saveChanges:"儲存更改"},form:{groupName:"群組名稱",groupNamePlaceholder:"輸入群組名稱",systemGroupWarning:"系統群組名稱不可更改",description:"描述",descriptionPlaceholder:"輸入描述(可選)",permissions:"權限(已選 {{count}} 個)"},deleteModal:{title:"刪除群組",message:"確定要刪除此群組嗎?此群組中的使用者將失去這些權限。",confirm:"刪除群組"},editor:{title:"編輯群組",createTitle:"建立群組",search:"搜尋權限...",selectAll:"全選",clearAll:"清除全部",permissionsSelected:"已選 {{count}} 個",noResults:"沒有權限匹配您的搜尋"}},users:{title:"使用者管理",subtitle:"管理使用者及其對 Bambuddy 實例的存取",backToSettings:"返回設定",createUser:"建立使用者",noPermission:"您沒有存取此頁面的權限。",admin:"管理員",noGroups:"無群組",active:"活躍",inactive:"非活躍",edit:"編輯",delete:"刪除",system:"系統",noGroupsAvailable:"無可用群組",table:{username:"使用者名稱",groups:"群組",status:"狀態",actions:"操作"},toast:{created:"使用者建立成功",updated:"使用者更新成功",deleted:"使用者刪除成功",fillRequired:"請填寫所有必填欄位",passwordsDoNotMatch:"密碼不符",passwordTooShort:"密碼至少需要 6 個字元",ldapProvisioned:"已建立 LDAP 使用者「{{username}}」"},modal:{createUser:"建立使用者",editUser:"編輯使用者",cancel:"取消",creating:"建立中...",saving:"儲存中...",saveChanges:"儲存更改",advancedAuthSubtitle:"使用進階認證",tabsAriaLabel:"使用者來源",localTab:"本機",ldapTab:"LDAP",ldapSearchLabel:"搜尋目錄",ldapSearchPlaceholder:"輸入使用者名稱、姓名或電子郵件...",ldapMinChars:"輸入至少 2 個字元以搜尋",ldapTypeToSearch:"開始輸入以搜尋 LDAP 目錄",ldapSearching:"搜尋目錄中...",ldapNoResults:"目錄中沒有符合的使用者",ldapSearchError:"目錄搜尋失敗。請檢查 LDAP 伺服器狀態。",ldapAlreadyProvisioned:"已建立",ldapSelectedLabel:"已選",ldapProvision:"建立使用者",ldapProvisioning:"建立中...",ldapErrorProvision:"建立失敗。請檢查 LDAP 伺服器狀態後重試。"},form:{username:"使用者名稱",usernamePlaceholder:"輸入使用者名稱",email:"信箱",emailPlaceholder:"user@example.com",password:"密碼",passwordPlaceholder:"輸入密碼",confirmPassword:"確認密碼",confirmPasswordPlaceholder:"確認密碼",newPasswordPlaceholder:"輸入新密碼",confirmNewPasswordPlaceholder:"確認新密碼",leaveBlankToKeep:"留空以保持目前值",groups:"群組",optional:"可選",autoGeneratedPassword:"將自動產生安全密碼並透過郵件傳送給使用者。",passwordManagedByAdvancedAuth:'密碼由進階認證管理。使用"重設密碼"透過郵件向使用者傳送新密碼。',resetPassword:"重設密碼",resettingPassword:"重設密碼中..."},deleteModal:{title:"刪除使用者",message:"確定要刪除此使用者嗎?此操作無法復原。",confirm:"刪除使用者"}},streamOverlay:{title:"流疊加層",invalidPrinterId:"無效的印表機 ID",cameraStream:"攝影機流",progress:"進度",eta:"預計完成時間",printerIdle:"印表機空閒",printerOffline:"印表機離線",status:{printing:"列印中",paused:"已暫停",finished:"已完成",failed:"失敗",idle:"空閒",unknown:"未知"}},profiles:{title:"設定檔案",subtitle:"管理您的切片預設和壓力推進校準",tabs:{cloud:"雲端設定檔案",local:"本機設定檔案",kprofiles:"K 值設定"},localProfiles:{title:"本機設定檔案",subtitle:"從 OrcaSlicer 匯入和管理切片預設",import:"匯入設定檔案",importDesc:"將 .bbscfg、.bbsflmt、.orca_filament、.zip 或 .json 檔案拖放到此處",importing:"匯入中...",search:"搜尋本機預設...",noPresets:"尚無本機預設",badge:"本機",edit:"編輯",delete:"刪除",cancel:"取消",deleteConfirmTitle:"刪除預設",deleteConfirm:"確定要刪除此預設嗎?此操作無法復原。",source:"來源",inheritsFrom:"繼承自",filamentType:"類型",vendor:"廠商",compatiblePrinters:"相容印表機",nozzleTemp:"噴嘴溫度",cost:"成本",density:"密度",pressureAdvance:"壓力推進",filament:"耗材",process:"工藝",printer:"印表機",toast:{importSuccess:"已匯入 {{count}} 個預設",importSkipped:"跳過 {{count}} 個預設(重複)",importError:"匯入時出現 {{count}} 個錯誤",deleted:"預設已刪除",updated:"預設已更新"}},connectedAs:"已連線為",logout:"登出",noLogoutPermission:"您沒有登出的權限",failedToLoad:"載入設定檔案失敗",retry:"重試",time:{justNow:"剛剛",minsAgo:"{{count}} 分鐘前",hoursAgo:"{{count}} 小時前",daysAgo:"{{count}} 天前"},toast:{loggedOut:"已登出"},login:{title:"連線到拓竹雲",subtitle:"跨裝置同步您的切片預設",email:"信箱",password:"密碼",region:"地區",regionGlobal:"全球",regionChina:"中國",verificationCode:"驗證碼",totpCode:"驗證器驗證碼",checkEmail:"檢查您的信箱 ({{email}}) 獲取 6 位驗證碼",enterTotpHint:"輸入驗證器 App 中的 6 位驗證碼",accessToken:"存取權杖",accessTokenHint:"貼上您的拓竹雲端存取權杖。中國大陸帳號(綁定手機號碼、無 Email 登入)僅能使用此方式登入。可從 MakerWorld 瀏覽器 Cookie 取得權杖,詳見 Wiki。",back:"返回",loginButton:"登入",verifyButton:"驗證",setTokenButton:"設定權杖",useToken:"改用存取權杖",useEmail:"改用信箱登入",toast:{loggedIn:"登入成功",codeSent:"驗證碼已傳送到您的信箱",enterTotp:"輸入驗證器 App 中的程式碼",tokenSet:"權杖設定成功"}},presets:{myPreset:"我的預設(可編輯)",duplicate:"複製",editable:"可編輯",failedToLoadDetails:"載入預設詳情失敗",deleteConfirm:"刪除此預設?",deleteWarning:'這將從拓竹雲中永久刪除"{{name}}"。此操作無法復原。',noDuplicatePermission:"您沒有複製預設的權限",noEditPermission:"您沒有編輯預設的權限",noDeletePermission:"您沒有刪除預設的權限",types:{filament:"耗材預設",printer:"印表機預設",process:"工藝預設"},toast:{deleted:"預設已刪除",created:"預設已建立",updated:"預設已更新",duplicated:"預設已複製",fieldAdded:'欄位"{{key}}"已新增',exported:"預設已匯出"},baseLabel:"基礎:{{name}}",currentLabel:"目前:{{name}}",newPreset:"新增預設",editPreset:"編輯預設",duplicatePreset:"複製預設",createNewPreset:"建立新預設",customizeSettings:"自訂新預設的設定",compareWithBase:"與基礎預設比較",compare:"比較",basePreset:"基礎預設",selectBasePreset:"選擇基礎預設...",presetName:"預設名稱",myCustomPreset:"我的自訂預設",inheritsFrom:"繼承自",dropJsonToImport:"拖放 JSON 以匯入",tabs:{common:"常用",allFields:"所有欄位"},availableFields:"可用欄位",searchFieldsPlaceholder:"搜尋欄位...",noMatchingFields:"沒有匹配的欄位",allFieldsAdded:"所有欄位已新增",addCustomField:"新增自訂欄位",yourOverrides:"您的覆蓋值",noOverridesYet:"尚無覆蓋值",clickFieldsToAdd:"點選左側的欄位進行新增",saveAsTemplate:"儲存為範本",jsonTip:"提示:將 .json 檔案拖放到此對話方塊的任意位置以匯入設定"},cloudView:{searchPlaceholder:"搜尋預設...",templates:"範本",refresh:"重新整理",newPreset:"新增預設",clearFilters:"清除篩選",compareMode:"比較模式",selectAnotherPreset:"選擇另一個 {{type}} 預設",clickTwoPresets:"點選兩個相同類型的預設進行比較",selectFirst:"1. 選擇第一個",selectSecond:"2. 選擇第二個",compareNow:"立即比較",lastSynced:"上次同步:",showingCount:"顯示 {{showing}} / {{total}} 個預設",noPresetsFound:"未找到預設",columns:{filament:"耗材",process:"工藝",printer:"印表機"},noFilamentPresets:"無耗材預設",noProcessPresets:"無工藝預設",noPrinterPresets:"無印表機預設",filters:{type:"類型",owner:"所有者",printer:"印表機",nozzle:"噴嘴",filament:"耗材",layer:"層",all:"全部",myPresets:"我的預設",builtIn:"內建",process:"工藝"},noTemplatesPermission:"您沒有管理範本的權限",noRefreshPermission:"您沒有重新整理設定檔案的權限",noCreatePermission:"您沒有建立預設的權限"},templates:{title:"快速範本",noTemplates:"尚無範本",createFirst:"從預設編輯器建立範本",typeFilter:"類型:",deleteTitle:"刪除範本",deleteWarning:"此操作無法復原",deleteConfirm:'確定要刪除"{{name}}"嗎?',namePlaceholder:"範本名稱",descriptionPlaceholder:"描述",settingsJson:"設定 (JSON)",fieldsCount:"{{count}} 個欄位",shownInModals:"在對話方塊中顯示",hiddenInModals:"在對話方塊中隱藏",apply:"套用",toast:{deleted:"範本已刪除",updated:"範本已更新",created:"範本已建立",applied:"範本已套用"}}},support:{debugLoggingActive:"偵錯日誌紀錄已啟用",manageLogs:"管理",collectItem7:"印表機連線和韌體版本",collectItem8:"整合狀態(Spoolman、MQTT、HA)",collectItem9:"網路介面(僅子網)",collectItem10:"Python 套件版本",collectItem11:"資料庫健康檢查",collectItem12:"Docker 環境詳情"},fileManager:{title:"檔案管理器",subtitle:"組織和管理您的列印檔案",uploadFiles:"上傳檔案",newFolder:"新增資料夾",folderName:"資料夾名稱",folderNamePlaceholder:"例如:功能零件",renameFile:"重新命名檔案",renameFolder:"重新命名資料夾",moveFiles:"移動 {{count}} 個檔案",rootNoFolder:"根目錄(無資料夾)",current:"目前",linkFolder:"連結資料夾",linkFolderDescription:'將"{{name}}"連結到專案或歸檔以便快速存取。',project:"專案",archive:"歸檔",noProjectsFound:"未找到專案",noArchivesFound:"未找到歸檔",unlink:"取消連結",link:"連結",dragDropFiles:"將檔案拖放到此處",dropFilesHere:"將檔案放在此處",orClickToBrowse:"或點選瀏覽",allFileTypesSupported:"支援所有檔案類型。ZIP 檔案將被解壓。",zipFilesDetected:"偵測到 ZIP 檔案",zipExtractOptions:"ZIP 檔案將被解壓。選擇如何處理資料夾結構:",preserveZipStructure:"保留 ZIP 中的資料夾結構",createFolderFromZip:"從 ZIP 檔名建立資料夾",stlThumbnailGeneration:"STL 縮圖產生",zipMayContainStl:"ZIP 檔案可能包含 STL 檔案。可以在解壓時產生縮圖。",thumbnailsCanBeGenerated:"可以為 STL 檔案產生縮圖。大型模型可能需要更長時間處理。",generateThumbnailsForStl:"為 STL 檔案產生縮圖",threemfDetected:"偵測到 3MF 檔案",threemfExtractionInfo:"將自動從 3MF 檔案中提取印表機型號、材料、顏色和列印設定。",willBeExtracted:"將被解壓",filesExtracted:"已解壓 {{count}} 個檔案",uploadComplete:"上傳完成:{{succeeded}} 個成功",uploadFailed:"上傳失敗",zipFilesFailed:"{{count}} 個檔案失敗",uploading:"上傳中...",changeLink:"更改連結...",linkTo:"連結到...",linkToProjectOrArchive:"連結到專案或歸檔",addToQueue:"新增到佇列",schedulePrint:"排程",generateThumbnail:"產生縮圖",generateThumbnails:"產生縮圖",generateThumbnailsForMissing:"為缺少縮圖的 STL 檔案產生縮圖",gridView:"網格檢視",listView:"列表檢視",lowDiskSpaceWarning:"磁碟空間不足警告",lowDiskSpaceDetails:"僅剩 {{free}}(總共 {{total}})。閾值設定為 {{threshold}} GB。",files:"檔案",folders:"資料夾",size:"大小",free:"剩餘",allFiles:"所有檔案",wrap:"換行",enableTextWrapping:"啟用文字換行",disableTextWrapping:"停用文字換行",collapse:"折疊",collapseFoldersByDefault:"預設折疊資料夾",expandFoldersByDefault:"預設展開資料夾",dragToResizeTooltip:"拖曳調整大小,雙擊重設",searchFiles:"搜尋檔案...",allTypes:"所有類型",prints:"列印",ascending:"升序",descending:"降序",resultsCount:"{{showing}} / {{total}} 個檔案",selectAll:"全選",deselectAll:"取消全選",selected:"已選擇 {{count}} 個",adding:"新增中...",loadingFiles:"載入檔案中...",folderIsEmpty:"資料夾為空",noFilesYet:"尚無檔案",folderEmptyDescription:"上傳檔案或將檔案移入此資料夾以開始使用。",noFilesDescription:"上傳檔案以開始組織您的列印相關檔案。",noMatchingFiles:"沒有匹配的檔案",noMatchingFilesDescription:"沒有檔案匹配您目前的搜尋或篩選條件。",clearFilters:"清除篩選",printedCount:"已列印 {{count}} 次",uploadedBy:"上傳者",deleteFolder:"刪除資料夾",deleteFile:"刪除檔案",deleteFilesCount:"刪除 {{count}} 個檔案",deleteFolderConfirm:"確定要刪除此資料夾嗎?其中的所有檔案也將被刪除。",deleteFileConfirm:"確定要刪除此檔案嗎?",deleteFilesConfirm:"確定要刪除 {{count}} 個選中的檔案嗎?此操作無法復原。",deleting:"刪除中...",noPermissionRenameFolder:"您沒有重新命名資料夾的權限",noPermissionLinkFolder:"您沒有連結資料夾的權限",noPermissionDeleteFolder:"您沒有刪除資料夾的權限",noPermissionPrint:"您沒有列印的權限",noPermissionSlice:"您沒有切片檔案的權限",noPermissionAddToQueue:"您沒有新增到佇列的權限",noPermissionDownload:"您沒有下載檔案的權限",noPermissionRenameFile:"您沒有重新命名此檔案的權限",noPermissionGenerateThumbnail:"您沒有產生縮圖的權限",noPermissionDeleteFile:"您沒有刪除此檔案的權限",noPermissionCreateFolder:"您沒有建立資料夾的權限",noPermissionUpload:"您沒有上傳檔案的權限",noPermissionMoveFiles:"您沒有移動檔案的權限",noPermissionDeleteFiles:"您沒有刪除檔案的權限",linkExternal:"連結外部",linkExternalFolder:"連結外部資料夾",linkExternalFolderDescription:"將主機目錄(NAS、USB、網路共享)掛載到檔案管理器中。檔案不會被複制——直接從原始路徑存取。",externalFolderNamePlaceholder:"例如:NAS列印檔案",externalPath:"主機路徑",externalPathHelp:"Docker主機上目錄的絕對路徑。必須以繫結掛載方式掛載到容器中。",readOnly:"只讀",readOnlyHelp:"防止上傳和刪除",showHiddenFiles:"顯示隱藏檔案(點檔案)",externalFolder:"外部資料夾",scanFolder:"掃描",toast:{folderCreated:"資料夾已建立",folderDeleted:"資料夾已刪除",fileDeleted:"檔案已刪除",filesDeleted:"已刪除 {{count}} 個檔案",filesMoved:"檔案已移動",folderLinked:"資料夾已連結",folderUnlinked:"資料夾已取消連結",externalFolderLinked:"外部資料夾已連結並掃描",folderScanned:"掃描完成:新增 {{added}} 個,移除 {{removed}} 個",addedToQueue:"已將 {{count}} 個檔案新增到佇列",addedToQueuePartial:"已新增 {{added}} 個檔案,{{failed}} 個失敗",failedToAddToQueue:"新增檔案失敗:{{error}}",fileRenamed:"檔案已重新命名",folderRenamed:"資料夾已重新命名",thumbnailsGenerated:"已產生 {{count}} 個縮圖",thumbnailsGeneratedPartial:"已產生 {{succeeded}} 個縮圖,{{failed}} 個失敗",noStlMissingThumbnails:"沒有缺少縮圖的 STL 檔案",failedToGenerateThumbnails:"產生縮圖失敗:{{error}}",thumbnailGenerated:"縮圖已產生",failedToGenerateThumbnail:"產生縮圖失敗:{{error}}"}},projects:{title:"專案",subtitle:"組織和追蹤您的 3D 列印專案",newProject:"新增專案",editProject:"編輯專案",deleteProject:"刪除專案",projectName:"專案名稱",description:"描述",noProjects:"尚無專案",noProjectsFiltered:"沒有{{status}}專案",noProjectsFilteredHelp:"您沒有任何{{status}}專案。當專案狀態更改時,它們將出現在這裡。",createFirst:"建立您的第一個項目以開始組織相關列印、追蹤進度和管理構建。",createFirstButton:"建立您的第一個項目",create:"建立",files:"檔案",prints:"列印",plates:"板",parts:"零件",lastModified:"最後修改",deleteConfirm:"確定要刪除此項目嗎?歸檔和佇列項目將被取消連結但不會被刪除。",addFiles:"新增檔案",removeFile:"移除檔案",viewDetails:"檢視詳情",namePlaceholder:"例如:Voron 2.4 構建",urlLabel:"網址",urlPlaceholder:"https://makerworld.com/...",urlInvalid:"網址必須以 http:// 或 https:// 開頭",openExternalUrl:"開啟專案網址",coverImageLabel:"封面圖片",coverImageAlt:"專案封面圖片",coverImageUpload:"上傳",coverImageReplace:"替換",coverImageRemove:"移除",descriptionPlaceholder:"可選描述...",color:"顏色",targetPlates:"目標板數",targetPlatesPlaceholder:"例如:25",targetPlatesHelp:"列印任務數量",targetParts:"目標零件數",targetPartsPlaceholder:"例如:150",targetPartsHelp:"所需零件總數",tagsLabel:"標籤(逗號分隔)",tagsPlaceholder:"例如:voron、功能件、禮物",dueDate:"截止日期",priority:"優先順序",priorityLow:"低",priorityNormal:"普通",priorityHigh:"高",priorityUrgent:"緊急",statusActive:"進行中",statusCompleted:"已完成",statusArchived:"已歸檔",done:"完成",completed:"已完成",failed:"失敗",inQueue:"佇列中",noPrintsYet:"尚無列印",printJobs:"列印任務(板)",partsPrinted:"已列印零件",failedParts:"失敗零件",import:"匯入",export:"匯出",importProject:"匯入專案",exportAll:"匯出所有專案",loading:"載入專案中...",noEditPermission:"您沒有編輯專案的權限",noDeletePermission:"您沒有刪除專案的權限",noCreatePermission:"您沒有建立專案的權限",noImportPermission:"您沒有匯入專案的權限",noExportPermission:"您沒有匯出專案的權限",toast:{created:"專案已建立",updated:"專案已更新",deleted:"專案已刪除",imported:"專案已匯入",multipleImported:"已匯入 {{count}} 個項目",importFailed:"匯入失敗",exported:"專案已匯出(僅中繼資料)"}},projectDetail:{notFound:"未找到專案",backToProjects:"返回專案",export:"匯出",exportProject:"匯出專案",noExportPermission:"您沒有匯出專案的權限",noEditPermission:"您沒有編輯專案的權限",partOf:"屬於:",priorityLabel:"優先順序:",noPrints:"此項目尚無列印",status:{active:"進行中",completed:"已完成",archived:"已歸檔"},priority:{low:"低",normal:"普通",high:"高",urgent:"緊急"},dueDate:{overdue:"已逾期",today:"今天到期",daysLeft:"還有 {{count}} 天"},progress:{platesProgress:"板進度",partsProgress:"零件進度",printJobs:"列印任務",parts:"零件",percentComplete:"{{percent}}% 完成",remaining:"剩餘 {{count}} 個"},stats:{printJobs:"列印任務",total:"總計",failed:"{{count}} 個失敗",partsPrinted:"已列印 {{count}} 個零件",printTime:"列印時間",filamentUsed:"耗材用量"},cost:{title:"成本追蹤",filamentCost:"耗材成本",energy:"能源",totalCost:"總成本",total:"總計",includesBom:"含物料清單",budget:"預算",remaining:"剩餘"},subProjects:{title:"子專案 ({{count}})"},notes:{title:"備註",noEditPermission:"您沒有編輯備註的權限",placeholder:"新增關於此項目的備註...",empty:"尚無備註。點選編輯新增備註。"},files:{title:"檔案",linkFolders:"從檔案管理器連結資料夾",forQuickAccess:"到此項目以便快速存取。",fileCount:"{{count}} 個檔案",empty:"未連結資料夾。前往檔案管理器將資料夾連結到此項目。",noFiles:"此資料夾中沒有檔案。",print:"立即列印",addToQueue:"加入佇列"},bom:{title:"材料清單",acquired:"已獲取 {{completed}}/{{total}}",showAll:"顯示全部",hideDone:"隱藏已完成",addPart:"新增零件",noAddPermission:"您沒有新增零件的權限",partNamePlaceholder:"零件名稱(例如:M3x8 螺絲)",partName:"零件名稱",qty:"數量",price:"價格 ({{currency}})",sourcingUrlPlaceholder:"採購連結(可選)",remarksPlaceholder:"備註(可選)",deletePart:"刪除零件",deleteConfirm:'確定要刪除"{{name}}"嗎?',noUpdatePermission:"您沒有更新零件的權限",noEditPermission:"您沒有編輯零件的權限",noDeletePermission:"您沒有刪除零件的權限",totalCost:"總成本:",empty:"材料清單中沒有零件。新增硬體、電子元件或其他元件以追蹤需要採購的物品。"},timeline:{title:"活動時間線",empty:"尚無活動。"},template:{saveAsTemplate:"儲存為範本",noCreatePermission:"您沒有建立範本的權限"},queue:{title:"佇列",viewAll:"檢視全部",printing:"{{count}} 個列印中",queued:"{{count}} 個佇列中"},prints:{title:"列印 ({{count}})"},toast:{projectUpdated:"專案已更新",partAdded:"零件已新增",partRemoved:"零件已移除",exportFailed:"匯出失敗",projectExported:"專案已匯出",templateCreated:"範本已建立"}},system:{title:"系統資訊",version:"版本",uptime:"執行時間",cpuUsage:"CPU 使用率",memoryUsage:"記憶體使用率",diskUsage:"磁碟使用率",networkInfo:"網路資訊",logs:"日誌",debugMode:"偵錯模式",enableDebug:"啟用偵錯日誌",disableDebug:"停用偵錯日誌",downloadLogs:"下載日誌",clearLogs:"清除日誌",dockerInfo:"Docker 資訊",containerName:"容器名稱",imageName:"映象名稱",platform:"平臺",architecture:"架構"},library:{title:"耗材庫",addFilament:"新增耗材",editFilament:"編輯耗材",deleteFilament:"刪除耗材",vendor:"廠商",material:"材料",color:"顏色",kFactor:"K 值",temperature:"溫度",noFilaments:"耗材庫中沒有耗材",deleteConfirm:"確定要刪除此耗材嗎?",importFromPrinter:"從印表機匯入",exportToFile:"匯出到檔案"},slice:{title:"切片模型",action:"切片",slicing:"切片中…",printer:"印表機設定檔",process:"製程設定檔",filament:"耗材設定檔",filamentSlot:"耗材 {{index}}({{type}})",selectPreset:"— 選擇預設 —",loadingPresets:"載入預設中…",analyzingPlateFilaments:"分析列印板耗材中…",analyzingPlateFilamentsHint:"正在執行預覽切片以發現此列印板使用的 AMS 插槽。之後會快取 — 重新開啟是即時的。",previewToast:"分析 {{name}} — {{elapsed}}",previewWithProgress:"分析 {{name}} — {{stage}} ({{percent}}%) — {{elapsed}}",notUsedByPlate:"— 此列印板未使用",printerMismatch:"此 3MF 是為 {{source}} 切片的,但您選擇了 {{target}}。切片器 CLI 無法為不同的印表機重新切片 3MF — 請在 Bambu Studio 中開啟原始檔案,變更印表機並重新匯出。",noPresetsForSlot:"無可用預設",presetsLoadFailed:"載入預設失敗。請先開啟設定 → 設定檔以匯入。",allPresetsRequired:"必須選擇所有預設",enqueuing:"提交切片任務中…",queued:"已排隊…",failed:"切片失敗。請檢查切片器 sidecar 日誌。",startedToast:"在背景切片 {{name}}…",queuedToast:"已排隊:{{name}} — {{elapsed}}",runningToast:"切片 {{name}} — {{elapsed}}",runningWithProgress:"{{name}} – {{stage}} ({{percent}}%) – {{elapsed}}",completedToast:"已切片 {{name}}",failedToast:"切片 {{name}} 失敗:{{detail}}",tier:{local:"已匯入",cloud:"雲端",standard:"標準"},cloud:{notAuthenticated:"登入 Bambu Cloud(設定 → 設定檔 → 雲端)以查看雲端預設。",expired:"Bambu Cloud 工作階段已過期 — 請重新登入以重新整理雲端預設。",unreachable:"目前無法存取 Bambu Cloud。本機和標準預設仍可使用。"},bedType:{label:"列印板",auto:"自動(使用製程預設)",coolPlate:"冷板",coolPlateSuperTack:"Cool Plate SuperTack",engineering:"Engineering Plate",highTemp:"High Temp Plate",texturedPEI:"Textured PEI Plate",smoothPEI:"Smooth PEI Plate"}},spoolman:{title:"Spoolman 整合",enabled:"Spoolman 已啟用",url:"Spoolman URL",connected:"已連線",disconnected:"未連線",testConnection:"測試連線",sync:"同步",syncing:"同步中...",lastSync:"上次同步",linkToSpoolman:"連結到 Spoolman",openInSpoolman:"在 Spoolman 中開啟",unlinkSpool:"取消連結耗材",unlinkConfirmTitle:"取消指派料盤?",unlinkConfirmMessage:"這將從此插槽中移除料盤。料盤本身的資料將保持不變。",selectSpool:"選擇耗材",noUnlinkedSpools:"無未指派的料盤",linkSuccess:"料盤指派成功",linkFailed:"料盤指派失敗",unlinkSuccess:"料盤取消指派成功",unlinkFailed:"料盤取消指派失敗",linkedSpool:"已指派料盤",spoolId:"耗材 ID",fillSourceLabel:"(Spoolman)",weight:"重量",remaining:"剩餘",disableWeightSync:"停用 AMS 估計重量同步",disableWeightSyncDesc:"不從 AMS 估計值更新剩餘容量。如果您更喜歡 Spoolman 的用量追蹤而非 AMS 百分比估計,請使用此選項。新耗材仍將使用 AMS 估計值作為初始重量。",reportPartialUsage:"報告失敗列印的部分用量",reportPartialUsageDesc:"當列印失敗或被取消時,根據層進度報告估計的耗材使用量。"},inventory:{title:"耗材庫存",subtitle:"管理您的料盤",spoolmanMixedContentTitle:"Spoolman 無法透過 HTTPS 載入 — 瀏覽器已封鎖混合內容",spoolmanMixedContentBody:"Bambuddy 透過您的反向代理以 HTTPS 提供服務,但您的 Spoolman 位址仍為 HTTP。基於安全考量,瀏覽器會封鎖混合內容,因此內嵌的 Spoolman 介面無法載入。Spoolman 也必須可透過 HTTPS 存取。",spoolmanMixedContentFixReverseProxy:"請將 Spoolman 置於與 Bambuddy 相同的反向代理(Traefik / Nginx / Caddy)之後並啟用 HTTPS,然後在設定中將 Spoolman URL 更新為新的 HTTPS 位址。",spoolmanMixedContentFixOpenNewTab:"作為替代方案,可在新分頁以 HTTP 開啟 Spoolman — 混合內容規則僅適用於內嵌框架,獨立分頁仍可正常運作。",spoolmanOpenInNewTab:"在新分頁開啟 Spoolman",labels:{title:"列印線材標籤",selectedCount:"已選 {{count}} 項",pickSpools:"選擇要列印標籤的線材:",searchPlaceholder:"按名稱、品牌或 #ID 搜尋",filterByMaterial:"材料:",allMaterials:"全部",selectVisible:"選擇所有可見 ({{count}})",deselectVisible:"取消選擇可見",clearAll:"全部清除",noSpoolsToShow:"沒有要顯示的線材。請調整篩選條件後重試。",noMatches:"沒有線材符合目前搜尋或篩選。",printOne:"列印此線材的標籤",printLabels:"列印標籤…",bulkTitle:"從目前顯示的 {{count}} 個線材中選擇要列印標籤的",noSpoolsTitle:"沒有要貼標籤的線材",error:"無法產生標籤:{{msg}}",templates:{ams:{label:"AMS holder (30 × 15 mm)",hint:"每頁一個標籤;適用於熱門的 AMS 耗材標籤托架。"},box40x30:{label:"盒標籤 (40 × 30 mm)",hint:"每頁一張;常見的 DK/Brother 捲尺寸,適合用於耗材袋與儲物盒標籤。"},box:{label:"Box label (62 × 29 mm)",hint:"每頁一個標籤;適配 Brother PT/QL 和 Dymo 小標籤。"},averyL7160:{label:"Avery L7160 — A4 sheet (38.1 × 63.5 mm × 21)",hint:"歐洲規格紙張;每張 A4 頁 21 個標籤。"},avery5160:{label:"Avery 5160 — US Letter sheet (25.4 × 66.7 mm × 30)",hint:"美國規格紙張;每張 Letter 頁 30 個標籤。"}}},addSpool:"新增耗材",editSpool:"編輯耗材",copySpool:"複製耗材",material:"材料",selectMaterial:"選擇材料...",subtype:"子類型",brand:"品牌",searchBrand:"搜尋品牌...",useCustomBrand:'使用"{{brand}}"',useCustomMaterial:"使用自訂材料:{{material}}",colorName:"顏色名稱",colorNamePlaceholder:"翡翠白、烈焰紅...",color:"顏色",hexColor:"十六進位顏色",pickColor:"選擇自訂顏色",labelWeight:"標籤重量",coreWeight:"空盤重量",searchSpoolWeight:"搜尋耗材重量...",weightUsed:"已使用",currentWeight:"剩餘重量",measuredWeight:"稱量重量",spoolName:"料盤",costPerKg:"每公斤成本",storageLocation:"存放位置",storageLocationPlaceholder:"例如:貨架A,抽屜1",openInInventory:"在庫存中查看",measuredWeightError:"稱量重量必須在 {{min}}g 到 {{max}}g 之間。",slicerFilament:"切片耗材",slicerFilamentName:"切片預設名稱",slicerPreset:"切片預設",searchPresets:"搜尋耗材預設...",selectedPreset:"已選擇",noPresetsFound:"未找到預設",tempOverrides:"溫度覆蓋",note:"備註",notePlaceholder:"關於此耗材的任何備註...",category:"類別",categoryPlaceholder:"例如:生產、原型、客戶A",categoryNone:"未分類",storageLocationNone:"未設定位置",lowStockThresholdOverride:"低庫存閾值(此料盤)",lowStockThresholdOverrideHelp:"留空以使用全域閾值({{global}}%)。",clearRfid:"清除 RFID 標籤",rfidCleared:"RFID 標籤已清除",archive:"歸檔",restore:"恢復",noSpools:"尚無耗材。新增您的第一個耗材開始使用。",noAvailableSpools:"沒有可用的耗材。請先向庫存中新增耗材,或從其他槽位取消指派一個耗材。",kProfiles:"K 值設定",addKProfile:"新增 K 值設定",assignSpool:"分配耗材",unassignSpool:"取消分配",assignSuccess:"耗材已分配,AMS 槽位已設定",assignFailed:"分配耗材失敗",assignMismatchTitle:"材料不符",assignMismatchMessage:'所選料盤材料 "{{spoolMaterial}}" 與 {{location}} 的料槽材料 "{{trayMaterial}}" 不符。仍要分配嗎?',assignMismatchConfirm:"仍然分配",assignPartialMismatchMessage:'料盤材料 "{{spoolMaterial}}" 與 {{location}} 的 "{{trayMaterial}}" 相近但不完全一致。是否繼續?',assignProfileMismatchMessage:'料盤設定 "{{spoolProfile}}" 與 {{location}} 的料槽設定 "{{trayProfile}}" 不一致。是否繼續?',selectSpool:"選擇要分配到此槽位的耗材",assigned:"已分配",assigning:"分配中...",searchSpools:"搜尋耗材...",showAllSpools:"顯示所有耗材",spoolmanSpools:"Spoolman 線軸",allMaterials:"所有材料",filterByBrand:"按品牌篩選...",showArchived:"顯示已歸檔",quickAdd:"快速新增(庫存)",quantity:"數量",stock:"庫存",configured:"已設定",spoolsCreated:"已建立 {{count}} 個耗材",spoolsPartiallyCreated:"已建立 {{created}} / {{total}} 個耗材(部分失敗)",spoolCreated:"耗材已建立",spoolUpdated:"耗材已更新",spoolDeleted:"耗材已刪除",deepLinkSpoolNotFound:"找不到耗材",deepLinkFetchFailed:"無法載入耗材 — 請重試",spoolArchived:"耗材已歸檔",spoolRestored:"耗材已恢復",kProfileSaveFailed:"K值設定檔設定無法儲存",syncWeightSpoolNotFound:"找不到耗材 — 可能已被刪除",syncWeightSpoolmanUnreachable:"Spoolman 無法存取 — 請稍後再試",syncWeightFailed:"重量同步失敗",spoolmanUnreachable:"Spoolman 無法存取 — 請稍後再試",deleteSpoolNotFound:"找不到耗材 — 可能已被刪除",deleteFailed:"刪除耗材失敗",archiveSpoolNotFound:"找不到耗材 — 可能已被刪除",archiveFailed:"歸檔耗材失敗",restoreSpoolNotFound:"找不到耗材 — 可能已被刪除",restoreFailed:"恢復耗材失敗",saveFailed:"儲存變更失敗",tagClearFailed:"清除標籤失敗",deleteConfirm:"確定要刪除此耗材嗎?此操作無法復原。",archiveConfirm:"確定要歸檔此耗材嗎?",advancedSettings:"進階設定",filamentInfoTab:"耗材資訊",paProfileTab:"PA 設定",filamentInfo:"耗材",additional:"附加",loadingPresets:"載入雲端預設中...",cloudConnected:"雲端已連線",cloudNotConnected:"雲端未連線(使用預設值)",recentColors:"最近",searchColors:"搜尋顏色...",searchResults:"搜尋結果",allColors:"所有顏色",commonColors:"常用顏色",showLess:"顯示更少",showAll:"顯示全部",noColorsFound:"沒有顏色匹配您的搜尋",noResults:"未找到匹配項",extraColorsLabel:"附加顏色",extraColorsPlaceholder:"EC984C,#6CD4BC,A66EB9,D87694",extraColorsHint:"貼上 2 至 8 個十六進位色值,以逗號分隔。將以漸層方式呈現。",extraColorsInvalid:"已略過無效的十六進位值:{{tokens}}",colorEffectLabel:"效果",colorEffect:{none:"無",sparkle:"閃光",wood:"木紋",marble:"大理石",glow:"夜光",matte:"霧面",silk:"絲光",galaxy:"星空",rainbow:"彩虹",metal:"金屬",translucent:"半透明",gradient:"漸層",dualColor:"雙色",triColor:"三色",multicolor:"多色"},selectMaterialFirst:"請先在耗材資訊分頁中選擇材料。",noPrintersConfigured:"未設定印表機。新增印表機以使用 PA 設定。",matchingFilter:"匹配",anyBrand:"任何品牌",anyVariant:"任何變體",autoSelect:"自動選擇",matches:"匹配",match:"匹配",noMatches:"無匹配",connected:"已連線",offline:"離線",printerOffline:"印表機離線。連線後檢視校準設定。",noKProfilesMatch:"沒有 K 值設定匹配所選耗材。",leftNozzle:"左噴嘴",rightNozzle:"右噴嘴",profilesSelected:"個校準設定已選擇",totalInventory:"總庫存",totalConsumed:"總消耗",byMaterial:"按材料",inPrinter:"在印表機中",lowStock:"庫存不足",sinceTracking:"自開始追蹤",loadedInAms:"已裝載到 AMS/外接",remaining:"剩餘",weightCheck:"重量檢查",lastWeighed:"上次稱量",neverWeighed:"從未稱量",search:"搜尋耗材...",showing:"顯示",to:"到",of:"共",show:"顯示",spools:"個耗材",spool:"個耗材",page:"頁",noSpoolsMatch:"未找到結果",noSpoolsMatchDesc:"嘗試調整您的搜尋或篩選條件。",active:"活躍",archived:"已歸檔",all:"全部",used:"已使用",new:"新的",clearFilters:"清除篩選",table:"表格",cards:"卡片",net:"淨重",groupSimilar:"分組",groupedSpools:"{{count}} 個相同耗材",groupedRows:"行",columns:"列",configureColumns:"設定列",configureColumnsDesc:"拖曳以重新排序列或使用箭頭。使用眼睛圖示切換可見性。",visible:"可見",reset:"重設",cancel:"取消",applyChanges:"套用更改",moveUp:"上移",moveDown:"下移",hideColumn:"隱藏列",showColumn:"顯示列",linkToSpool:"連結到耗材",tagLinked:"標籤已連結到耗材",tagLinkFailed:"連結標籤失敗",tagAlreadyLinked:"標籤已連結到其他耗材",unknownTag:"偵測到未知 RFID 標籤",usageHistory:"使用歷史",noUsageHistory:"尚無使用紀錄",printName:"列印名稱",weightConsumed:"消耗重量",clearHistory:"清除",historyCleared:"使用歷史已清除",fillSourceLabel:"(庫存)",lowStockThresholdError:"閾值必須在 0.1 到 99.9 之間",spoolmanFilamentCatalog:"Spoolman 耗材目錄",pickFromSpoolmanCatalog:"從 Spoolman 目錄選擇…",spoolmanFilamentSelected:"已從 Spoolman 目錄選擇耗材",spoolmanFilamentUnlinked:"已解除耗材目錄關聯",noSpoolmanFilaments:"Spoolman 目錄中未找到耗材",spoolmanFilamentColorSwatch:"耗材顏色",spoolWeightManagedBySpoolman:"空線軸重量在 Spoolman 中按耗材類型管理",spoolmanCatalogLoadFailed:"無法載入 Spoolman 耗材目錄"},timelapse:{title:"縮時攝影",create:"建立縮時攝影",download:"下載",delete:"刪除",preview:"預覽",frameRate:"幀率",quality:"品質",processing:"處理中...",noTimelapses:"無可用縮時攝影"},ams:{title:"AMS",slot:"槽位",empty:"空",emptySlot:"空槽位",unknown:"未知",humidity:"濕度",temperature:"溫度",filamentType:"耗材類型",filamentColor:"顏色",remaining:"剩餘",history:"AMS 歷史",noHistory:"無可用歷史",configureSlot:"設定槽位",externalSpool:"外接耗材",profile:"設定",kFactor:"K 值",fill:"填充",configure:"設定",used:"已使用",remainingUnit:"剩餘"},printModal:{title:"開始列印",selectPrinter:"選擇印表機",selectPlate:"選擇板",filamentMapping:"耗材對應",totalCost:"總成本:",slotRemainingShort:" - 剩餘 {{grams}}g",printSettings:"列印設定",bedLeveling:"熱床調平",flowCalibration:"流量校準",vibrationCalibration:"振動校準",layerInspection:"首層檢查",timelapse:"縮時攝影",startPrint:"開始列印",addToQueue:"新增到佇列",cancel:"取消",noPrintersAvailable:"無可用印表機",printerBusy:"印表機忙碌",printerOffline:"印表機離線",sameTypeDifferentColor:"相同類型,不同顏色",filamentTypeNotLoaded:"耗材類型未裝載",openCalendar:"開啟日曆",leftNozzle:"左",rightNozzle:"右",leftNozzleTooltip:"左噴嘴",rightNozzleTooltip:"右噴嘴",filamentOverride:"耗材覆蓋",filamentOverrideHint:"可選覆蓋用於基於模型的耗材分配。排程器將使用您選擇的耗材而不是原始 3MF 值進行匹配。",originalFilament:"原始",overrideWith:"覆蓋為",resetToOriginal:"恢復為原始",insufficientFilamentTitle:"耗材不足",insufficientFilamentMessage:"部分已分配料盤的剩餘耗材少於本次列印所需:",insufficientFilamentLine:"{{printer}} - {{slot}}:需要 {{required}}g,剩餘 {{remaining}}g",printAnyway:"仍然列印",forceColorMatch:"強制顏色匹配",staggerPrinterStarts:"錯開印表機啟動",staggerGroupSize:"群組大小",staggerInterval:"間隔(分鐘)",staggerPreview:"{{printers}} 台印表機 → 分成 {{groups}} 組,每組 {{size}} 台,每 {{interval}} 分鐘啟動一組",staggerLastGroup:"最後一組:{{count}}",staggerTotal:"總計:{{minutes}} 分鐘",staggerToPrinters:"分批傳送到 {{count}} 臺印表機",gcodeInjection:"注入自動列印G-code"},backup:{includesEncryptionKey:"本機備份包含 MFA 加密金鑰檔案(DATA_DIR/.mfa_encryption_key),因此備份 ZIP 是自包含的。請將 ZIP 視為敏感檔案 — 任何擁有該檔案的人都可以解密內部儲存的 OIDC 用戶端機密和 TOTP 機密。",title:"備份與恢復",createBackup:"建立備份",restoreBackup:"恢復備份",restoreDescription:"從備份檔案替換所有資料",downloadBackup:"下載備份",uploadBackup:"上傳備份",lastBackup:"上次備份",autoBackup:"自動備份",backupNow:"立即備份",restoreWarning:"警告:恢復備份將覆蓋所有目前資料。",includeArchives:"包含歸檔",includeSettings:"包含設定",includeProfiles:"包含設定檔案",backupSuccess:"備份建立成功",restoreSuccess:"備份恢復成功",backupFailed:"備份失敗",restoreFailed:"恢復失敗",restoreNote:"恢復期間虛擬印表機將停止",githubBackup:"GitHub 備份",enabled:"已啟用",cloudLoginRequired:"需要登入 Bambu Cloud。請在 設定檔案 → 雲設定檔案 中登入以啟用 GitHub 備份。",cloudLoginRequiredShort:"需要雲端登入",githubDescription:"自動將您的設定檔案同步到私有 GitHub 倉庫以進行備份和版本歷史紀錄。",repositoryUrl:"倉庫 URL",repoUrlPlaceholderGitHub:"https://github.com/username/repo-name",repoUrlPlaceholderGitea:"https://gitea.example.com/username/repo-name",repoUrlPlaceholderForgejo:"https://forgejo.example.com/username/repo-name",repoUrlPlaceholderGitLab:"https://gitlab.com/username/repo-name",allowInsecureHttp:"允許不安全的 HTTP",allowInsecureHttpHint:"為無 TLS 的私人網路自托管執行個體啟用",personalAccessToken:"個人存取權杖",tokenSaved:"(已儲存)",enterNewToken:"輸入新權杖以更新",tokenHint:"具有內容讀寫權限的細粒度權杖",branch:"分支",provider:"Git 供應商",providerGitHub:"GitHub",providerGitLab:"GitLab",providerGitea:"Gitea",providerForgejo:"Forgejo",manualOnly:"僅手動",hourly:"每小時",daily:"每天",weekly:"每週",includeInBackup:"包含在備份中",kProfiles:"K 設定檔案",kProfilesDescription:"來自已連線印表機的壓力推進校準",noPrintersConnected:"沒有印表機連線",printersConnected:"{{connected}}/{{total}} 已連線",cloudProfiles:"雲設定檔案",cloudProfilesDescription:"來自 Bambu Cloud 的耗材、印表機和工藝預設",appSettings:"應用程式設定",appSettingsDescription:"Bambuddy 設定(完整資料庫)",spoolInventory:"耗材庫存",spoolInventoryDescription:"耗材卷軸、使用紀錄和成本追蹤",printArchives:"列印檔案",printArchivesDescription:"列印歷史中繼資料(不含 gcode/3MF 檔案)",lastBackupAt:"上次備份:",noBackupsYet:"尚無備份",next:"下次:",startingBackup:"正在啟動備份...",test:"測試",enableBackup:"啟用備份",testConnection:"測試連線",enterRepoUrl:"請輸入倉庫 URL",enterRepoAndToken:"請輸入倉庫 URL 和存取權杖",repoRequired:"倉庫 URL 為必填項",tokenRequired:"存取權杖為必填項",githubBackupEnabled:"GitHub 備份已啟用",tokenUpdated:"權杖已更新",settingsSaved:"設定已儲存",failedToSave:"儲存失敗:{{message}}",backupCompleteFiles:"備份完成 - {{count}} 個檔案已更新",backupSkippedNoChanges:"備份已跳過 - 無更改",backupFailed2:"備份失敗:{{message}}",clearedLogs:"已清除 {{count}} 條日誌",failedToClearLogs:"清除日誌失敗:{{message}}",history:"歷史紀錄",clear:"清除",date:"日期",status:"狀態",commit:"提交",localBackup:"本機備份",localBackupDescription:"建立 Bambuddy 資料的完整備份,包括資料庫、檔案、上傳和所有檔案。",downloadBackupLabel:"下載備份",completeBackupZip:"完整備份:資料庫 + 所有檔案(ZIP)",download:"下載",preparingBackup:"正在準備備份...",creatingArchive:"正在建立備份歸檔...對於大型歸檔可能需要一些時間。",downloadingFile:"正在下載備份檔案...",backupDownloaded:"備份下載成功",failedToCreateBackup:"建立備份失敗:{{message}}",restore:"恢復",restoreReplacesAll:"恢復將替換所有資料。",restoreReplacesAllDetail:"您目前的資料庫和檔案將被完全替換。恢復後需要重新啟動。",restoreConfirmTitle:"恢復備份",restoreConfirmMessage:'您確定要從"{{filename}}"恢復嗎?這將完全替換您目前的資料庫和所有檔案。恢復後需要重新啟動應用程式。',restoreConfirmButton:"恢復備份",uploadingFile:"正在上傳備份檔案...",backupRestoredRestart:"備份已恢復。請重新啟動 Bambuddy。",failedToRestore:"恢復備份失敗。請檢查檔案格式。",reloadNow:"立即重新載入",creatingBackup:"正在建立備份",restoringBackup:"正在恢復備份",preparing:"準備中...",processing:"處理中...",doNotClosePage:"請不要關閉此頁面或離開頁面。對於大型備份,此操作可能需要幾分鐘。",restoring:"恢復中...",restoreComplete:"恢復完成",restoreFailed2:"恢復失敗",importSettings:"從備份檔案匯入設定",pleaseWaitRestoring:"請等待資料恢復中",selectBackupFile:"點選選擇備份檔案(.json 或 .zip)",duplicateHandling:"重複項處理方式:",matchPrinters:"印表機",matchPrintersBy:"按序列號匹配",matchSmartPlugs:"智慧插座",matchSmartPlugsBy:"按 IP 位址匹配",matchNotificationProviders:"通知提供者",matchNotificationProvidersBy:"按名稱匹配",matchFilaments:"耗材",matchFilamentsBy:"按名稱 + 類型 + 品牌匹配",matchArchives:"檔案",matchArchivesBy:"按內容雜湊匹配(始終跳過)",matchPendingUploads:"待上傳",matchPendingUploadsBy:"按檔名匹配",matchSettingsTemplates:"設定和範本",matchSettingsTemplatesBy:"始終覆蓋",replaceExisting:"替換現有資料",keepExisting:"保留現有資料",overwriteDescription:"用備份資料覆蓋已存在的項目",keepDescription:"僅恢復尚不存在的項目",overwriteCaution:"注意:",overwriteWarning:"覆蓋將用備份資料替換您目前的設定。出於安全考慮,印表機存取碼永遠不會被覆蓋。",cancel:"取消",processingBackup:"正在處理備份檔案...",itemsRestored:"已恢復項目",itemsSkipped:"已跳過項目",restored:"已恢復",skippedAlreadyExist:"已跳過(已存在)",filesCategory:"檔案(3MF、縮圖等)",andMore:"...還有 {{count}} 項",newApiKeysGenerated:"已產生新的 API 金鑰",keysShownOnce:"這些金鑰僅顯示一次。請立即複製!",copy:"複製",noDataFound:"在備份檔案中未找到可恢復的資料。",close:"關閉",scheduledBackup:"排程備份",scheduledBackupDescription:"依排程自動建立備份快照。輸出目錄可掛載到 NAS 或外部儲存。",frequency:"頻率",backupTime:"時間",retention:"保留",retentionDescription:"保留的備份數量",outputPath:"輸出路徑",outputPathPlaceholder:"預設:{{path}}",outputPathDescription:"留空以使用預設位置",runNow:"立即執行",backupFiles:"備份檔案",noScheduledBackups:"尚無備份",deleteBackup:"刪除",deleteBackupConfirm:"要刪除此備份檔案嗎?",backupRunning:"備份進行中…",scheduledBackupComplete:"備份已成功完成",scheduledBackupFailed:"備份失敗",nextBackup:"下次備份",backupSize:"大小",utc:"UTC",defaultPathLabel:"預設:",categories:{settings:"設定",notification_providers:"通知提供者",notification_templates:"通知範本",smart_plugs:"智慧插座",printers:"印表機",filaments:"耗材",maintenance_types:"維護類型",archives:"檔案",projects:"專案",pending_uploads:"待上傳",external_links:"外部連結",api_keys:"API 金鑰"}},tags:{title:"標籤",addTag:"新增標籤",editTag:"編輯標籤",deleteTag:"刪除標籤",tagName:"標籤名稱",tagColor:"標籤顏色",noTags:"無標籤",deleteConfirm:"確定要刪除此標籤嗎?",manageTags:"管理標籤"},uploadModal:{title:"上傳 3MF 檔案",dragDrop:"將 .3mf 檔案拖放到此處",or:"或",browseFiles:"瀏覽檔案",extractionInfo:"將從 3MF 檔案中繼資料中自動提取印表機型號。",uploaded:"已上傳",failed:"失敗",uploading:"上傳中...",upload:"上傳",uploadFailed:"上傳失敗"},editArchive:{title:"編輯歸檔",name:"名稱",namePlaceholder:"列印名稱",printer:"印表機",noPrinter:"無印表機",project:"專案",noProject:"無專案",itemsPrinted:"列印數量",itemsPrintedHelp:"此列印任務中生產的物品數量",notes:"備註",notesPlaceholder:"新增關於此列印的備註...",externalLink:"外部連結",externalLinkPlaceholder:"https://printables.com/model/...",externalLinkHelp:"連結到 Printables、Thingiverse 或其他來源",tags:"標籤",tagsPlaceholder:"新增標籤...",addMoreTags:"新增更多標籤...",matchingTags:'匹配"{{query}}"',existingTags:"現有標籤",clickToAdd:"(點選新增)",status:"狀態",failureReason:"失敗原因",selectReason:"選擇原因...",photos:"列印成品照片",photosHelp:"點選 + 新增列印成品照片",printResult:"列印成品",saving:"儲存中...",failureReasons:{adhesionFailure:"附著力失敗",spaghettiDetached:"拉絲 / 脫落",layerShift:"層偏移",cloggedNozzle:"噴嘴堵塞",filamentRunout:"耗材用完",warping:"翹曲",stringing:"拉絲",underExtrusion:"擠出不足",powerFailure:"斷電",userCancelled:"使用者取消",other:"其他"},statuses:{completed:"已完成",failed:"失敗",aborted:"已取消",printing:"列印中"}},kProfiles:{title:"K 值設定",noPrintersConfigured:"未設定印表機",addPrinterInSettings:"在設定中新增印表機以管理 K 值設定",noActivePrinters:"無活躍印表機",enablePrinterConnection:"啟用印表機連線以檢視其 K 值設定",loadingProfiles:"載入 K 值設定中...",printerOffline:"印表機離線",printerOfflineDesc:"所選印表機未連線。開啟電源以檢視 K 值設定。",noMatchingProfiles:"無匹配的設定",noMatchingProfilesDesc:"沒有設定匹配您的搜尋條件",noKProfiles:"無 K 值設定",noKProfilesDesc:"未找到 {{diameter}}mm 噴嘴的壓力推進設定",createFirstProfile:"建立第一個設定",printer:"印表機",nozzle:"噴嘴",refresh:"重新整理",addProfile:"新增設定",export:"匯出",import:"匯入",select:"選擇",selectAll:"全選",delete:"刪除",searchPlaceholder:"按名稱或耗材搜尋...",allExtruders:"所有擠出機",leftOnly:"僅左側",rightOnly:"僅右側",allFlow:"所有流量",hfOnly:"僅高流量",sOnly:"僅標準",sortName:"排序:名稱",sortKValue:"排序:K 值",sortFilament:"排序:耗材",leftExtruder:"左擠出機",rightExtruder:"右擠出機",modal:{addTitle:"新增 K 值設定",editTitle:"編輯 K 值設定",profileName:"設定名稱",profileNamePlaceholder:"我的 PLA 設定",kValue:"K 值",kValuePlaceholder:"0.020",kValueHelp:"典型範圍:PLA 0.01 - 0.06,PETG 0.02 - 0.10",filament:"耗材",selectFilament:"選擇耗材...",noFilamentsHelp:"未找到耗材。請先在 Bambu Studio 中建立 K 值設定。",flowType:"流量類型",highFlow:"高流量",standard:"標準",nozzleSize:"噴嘴尺寸",extruder:"擠出機",extruders:"擠出機",left:"左",right:"右",notes:"備註(本機儲存)",notesPlaceholder:"新增關於此設定的備註...",notesHelp:"備註儲存在 Bambuddy 中,不在印表機上",syncing:"與印表機同步中...",savingExtruder:"儲存到擠出機 {{current}}/{{total}}...",pleaseWait:"請稍候"},deleteConfirm:{title:"刪除設定",cannotUndo:"此操作無法復原",message:'確定要從印表機刪除"{{name}}"嗎?'},bulkDelete:{title:"刪除設定",cannotUndo:"此操作無法復原",message:"確定要從印表機刪除 {{count}} 個選中的設定嗎?"},toast:{profileSaved:"K 值設定已儲存",profilesSaved:"K 值設定已儲存到 {{count}} 個擠出機",selectAtLeastOneExtruder:"請至少選擇一個擠出機",profileDeleted:"K 值設定已刪除",profilesDeleted:"已刪除 {{count}} 個設定",exportedProfiles:"已匯出 {{count}} 個設定",importedProfiles:"已匯入 {{count}} / {{total}} 個設定",noProfilesToExport:"無可匯出的設定",invalidFileFormat:"無效的檔案格式",failedToParseImport:"解析匯入檔案失敗",failedToSaveBatch:"批次儲存 K 值設定失敗",noteSaved:"備註已儲存",failedToSaveNote:"儲存備註失敗"},permission:{noRead:"您沒有重新整理設定的權限",noCreate:"您沒有新增設定的權限",noUpdate:"您沒有更新 K 值設定的權限",noDelete:"您沒有刪除 K 值設定的權限",noExport:"您沒有匯出設定的權限",noImport:"您沒有匯入設定的權限"}},virtualPrinter:{title:"虛擬印表機",running:"執行中",stopped:"已停止",description:{default:"啟用虛擬印表機,使其在 Bambu Studio 和 OrcaSlicer 中可見。傳送到此印表機的檔案將直接歸檔而不列印。",proxy:"啟用代理,將切片軟體流量中繼到真實印表機,允許在任何網路上遠端列印。"},enable:{title:"啟用虛擬印表機",visibleInSlicer:'在切片軟體發現中顯示為"Bambuddy"',proxyingTo:"代理到 {{name}}",notActive:"未啟用"},model:{title:"印表機型號",description:"選擇要模擬的印表機型號。",restartWarning:"更改型號將重新啟動虛擬印表機"},accessCode:{title:"存取碼",isSet:"存取碼已設定",notSet:"未設定存取碼 - 需要設定才能啟用",placeholder:"輸入 8 位字元程式碼",placeholderChange:"輸入新程式碼以更改",hint:"必須恰好 8 個字元。切片軟體使用此程式碼進行認證。",charCount:"({{count}}/8)"},targetPrinter:{title:"目標印表機",configured:"代理目標已設定",notConfigured:"未選擇目標印表機 - 代理模式需要設定",placeholder:"選擇印表機...",hint:"選擇要將切片軟體流量代理到的印表機。印表機必須處於區域網路模式。",noPrinters:"未設定印表機。請先新增印表機以使用代理模式。"},remoteInterface:{title:"網路介面覆蓋",configured:"介面覆蓋已啟用",optional:"可選 - 當自動檢測的 IP 不正確時使用(例如多網路卡、Docker、VPN)",placeholder:"自動檢測(預設)...",hint:"覆蓋透過 SSDP 廣播並在 TLS 憑證中使用的 IP 位址。在 Bambuddy 有多個網路介面時很有用。"},mode:{title:"模式",archive:"歸檔",archiveDesc:"立即歸檔檔案",review:"審核",reviewDesc:"歸檔前審核",queue:"佇列",queueDesc:"歸檔並新增到佇列",proxy:"代理",proxyDesc:"中繼到真實印表機"},autoDispatch:{title:"自動派發",description:"新增到佇列時自動開始列印。關閉後,列印任務等待手動派發。"},queueForceColorMatch:{title:"強制顏色匹配",description:"拒絕派發到沒有完全相同耗材類型和顏色的印表機。預設關閉 — 不啟用時,佇列僅按型號匹配,可能選到顏色錯誤的印表機。"},tailscaleDisabled:{title:"Tailscale 整合",description:"啟用以將此 VP 標記為透過 Tailscale 公開。顯示主機的 Tailscale 位址,以便您知道要貼上到切片器中的 IP。CA 匯入步驟保持不變 — 此切換對憑證無影響。"},setupRequired:{title:"需要設定",description:"虛擬印表機功能需要額外的系統設定才能工作。包括埠轉發、防火牆規則和平臺特定設定。",readGuide:"啟用前請閱讀設定指南"},archiveNameSource:{title:"存檔名稱來源",description:'選擇透過虛擬印表機接收檔案時新存檔的命名方式。"元資料"使用 3MF 中嵌入的切片標題(預設)。"檔名"使用 Bambu Studio 透過 FTP 傳送的檔案名稱 — 當您在"傳送到印表機"對話方塊中重新命名工作時非常有用。',metadata:"元資料",filename:"檔名"},howItWorks:{title:"工作原理",step1:"在同一區域網路中,虛擬印表機會透過發現機制自動出現在您的切片軟體(Bambu Studio / OrcaSlicer)中。從其他網路,透過 IP 位址和存取碼手動新增。",step2:'在歸檔、審核和佇列模式下,使用切片軟體中的"傳送"按鈕將 3MF 檔案上傳到 Bambuddy。切片軟體會顯示"列印成功"— 檔案已儲存,未列印。',step3:"在代理模式下,虛擬印表機將所有流量中繼到真實印表機 — 列印會立即開始,就像直接連線一樣。"},status:{title:"狀態詳情",printerName:"印表機名稱",model:"型號",serialNumber:"序列號",mode:"模式",pendingFiles:"待處理檔案",targetPrinter:"目標印表機",ftpPort:"FTP 連接埠",mqttPort:"MQTT 連接埠",ftpConnections:"FTP 連線",mqttConnections:"MQTT 連線"},toast:{updated:"虛擬印表機設定已更新",failedToUpdate:"更新設定失敗",copyFailed:"複製失敗 — 請手動選取文字",accessCodeRequired:"請先設定存取碼",targetPrinterRequired:"請先選擇目標印表機",bindIpRequired:"請先設定繫結 IP",accessCodeEmpty:"存取碼不能為空",accessCodeLength:"存取碼必須恰好 8 個字元",created:"虛擬印表機已建立",failedToCreate:"建立虛擬印表機失敗",deleted:"虛擬印表機已刪除",failedToDelete:"刪除虛擬印表機失敗"},list:{title:"虛擬印表機",add:"新增",addFirst:"新增虛擬印表機",empty:"未設定虛擬印表機。新增一個以開始使用。"},bindIp:{title:"繫結介面",placeholder:"選擇介面...",hint:"此虛擬印表機繫結的網路介面。每臺印表機必須唯一。"},proxy:{accessCodeHint:"在代理模式下,在切片軟體中使用目標印表機的存取碼。連線會透明轉發到真實印表機。"},addDialog:{title:"新增虛擬印表機",name:"名稱",hint:"建立後可以設定存取碼、目標印表機和其他設定。",create:"建立"},deleteConfirm:{title:"刪除虛擬印表機",message:'確定要刪除"{{name}}"嗎?這將停止此印表機的所有服務。'}},modelViewer:{openInSlicer:"在切片軟體中開啟",tabs:{model:"3D 模型",gcode:"G-code 預覽"},notAvailable:"不可用",notSliced:"未切片",plates:"板",allPlates:"所有板",plateNumber:"板 {{number}}",plateCount:"{{count}} 個板",plateCount_other:"{{count}} 個板",objectCount:"{{count}} 個物件",objectCount_other:"{{count}} 個物件",filamentCount:"{{count}} 種耗材",filamentCount_other:"{{count}} 種耗材",eta:"預計 {{minutes}} 分鐘",noPreview:"此檔案無可用預覽",pagination:{pageOf:"第 {{current}} / {{total}} 頁",prev:"上一頁",next:"下一頁"},errors:{failedToLoad:"載入檔案失敗",noMeshes:"3MF 檔案中未找到網格",unsupportedFormat:"不支援的檔案格式"}},maintenanceDescriptions:{lubricateCarbonRods:"在碳纖維杆上塗抹潤滑劑以確保順暢運動",lubricateRails:"在線性導軌上塗抹潤滑劑以確保順暢運動",cleanNozzle:"清潔熱端和噴嘴以防止堵塞",checkBelts:"檢查皮帶張力以確保列印精度",cleanBuildPlate:"清潔列印板以獲得更好的附著力",checkExtruder:"檢查擠出機齒輪磨損情況",checkCooling:"確保冷卻風扇正常工作",generalInspection:"印表機綜合檢查",cleanCarbonRods:"清潔碳纖維杆以減少摩擦",lubricateSteelRods:"在鋼杆上塗抹潤滑劑以確保順暢運動",cleanSteelRods:"清潔鋼杆以減少摩擦",cleanLinearRails:"擦拭線性導軌以清除灰塵和碎屑",checkPtfeTube:"檢查 PTFE 管的磨損或損壞",replaceHepaFilter:"更換 HEPA 過濾器以保證空氣品質",replaceCarbonFilter:"更換活性炭過濾器",lubricateLeftNozzleRail:"潤滑左噴嘴導軌(H2 系列)"},smartPlugs:{offline:"離線",admin:"管理",openPlugAdminPage:"開啟插座管理頁面",deleteSmartPlug:"刪除智慧插座",turnOnSmartPlug:"開啟智慧插座",turnOffSmartPlug:"關閉智慧插座",turnOn:"開啟",turnOff:"關閉",addSmartPlug:{scanningNetwork:"掃描網路中...",chooseEntity:"選擇實體...",connectionFailed:"連線失敗",searchEntities:"搜尋實體...",searchPowerSensors:"搜尋功率感測器...",searchEnergySensors:"搜尋能量感測器...",placeholders:{plugName:"客廳插座",mqttStateOnValue:"ON、true、1",mqttSameAsPower:"與功率主題相同,或不同"}},linkedTo:"連結到:",monitorOnly:"僅監控",alerts:"警報",scheduleOn:"開啟 {{time}}",scheduleOff:"關閉 {{time}}",on:"開啟",off:"關閉",power:"功率",kwhToday:"今日kWh",settings:"設定",automationSettings:"自動化設定",showInSwitchbar:"在開關欄顯示",quickAccessSidebar:"從側邊欄快速存取",enabled:"已啟用",enableAutomation:"為此插座啟用自動化",autoOn:"自動開啟",autoOnDescription:"列印開始時開啟",autoOff:"自動關閉",autoOffDescription:"列印完成時關閉(一次性)",autoOffPersistent:"保持啟用",autoOffPersistentDescription:"在列印之間保持啟用而非一次性",autoOffAfterDrying:"乾燥完成後自動關閉",autoOffAfterDryingDescription:"AMS 乾燥完成後關閉",delayAfterDryingMinutes:"乾燥後延遲(分鐘)",turnOffDelayMode:"關閉延遲模式",time:"時間",temp:"溫度",delayMinutes:"延遲(分鐘)",tempThreshold:"溫度閾值(°C)",tempThresholdDescription:"當噴嘴冷卻到此溫度以下時關閉",edit:"編輯",deleteConfirm:'確定要刪除"{{name}}"嗎?此操作無法復原。',turnOnConfirm:'確定要開啟"{{name}}"嗎?',turnOffConfirm:'確定要關閉"{{name}}"嗎?這將切斷連線裝置的電源。',failedToTurn:'無法{{action}}"{{name}}"',unknown:"未知",addTitle:"新增智慧插座",editTitle:"編輯智慧插座",stopScanning:"停止掃描",discoverTasmota:"發現Tasmota裝置",foundDevices:"找到{{count}}個裝置 - 點選選擇:",noDevicesFound:"未在您的網路中找到Tasmota裝置",haNotConfigured:"Home Assistant未設定。請在以下位置設定",haSettingsPath:"設定 → 網路 → Home Assistant",selectEntity:"選擇實體 *",ipAddress:"IP 位址 *",nameLabel:"名稱 *",username:"使用者名稱",password:"密碼",authHint:"如果您的Tasmota裝置不需要認證,請留空",linkToPrinter:"連結印表機",noPrinter:"無印表機(僅手動控制)",linkingDescription:"連結後可在列印開始/完成時自動開關",powerAlerts:"功率警報",alertAbove:"高於時警報(W)",alertBelow:"低於時警報(W)",alertDescription:"當電力消耗超過這些閾值時收到通知。留空以停用該方向。",dailySchedule:"每日計畫",turnOnAt:"開啟時間",turnOffAt:"關閉時間",scheduleDescription:"每天在這些時間自動開關插座。留空以跳過該操作。",showOnPrinterCard:"在印表機卡片上顯示",displayOnPrinterCard:"在印表機卡片上顯示按鈕",connectedResult:"已連線!",deviceLabel:"裝置:{{name}} - ",stateLabel:"狀態:{{state}}",test:"測試",delete:"刪除",save:"儲存",add:"新增",cancel:"取消",failedToStartScan:"無法開始掃描",nameRequired:"名稱為必填項",entityRequired:"Home Assistant插座需要實體",mqttTopicRequired:"必須為功率、能源或狀態監控設定至少一個MQTT主題",loadingEntities:"正在載入實體...",loading:"載入中...",failedToLoadEntities:"載入實體失敗:{{error}}",noEntitiesMatching:'未找到匹配"{{search}}"的實體',noEntitiesAvailable:"無可用實體",searchingEntities:"搜尋所有實體(找到{{count}}個)",showingEntities:"顯示 switch、light、input_boolean({{count}}個可用)",energyMonitoringOptional:"能源監控(可選)",energyMonitoringHint:"搜尋並選擇提供功率/能源資料的感測器。",powerSensorW:"功率感測器(W)",energyTodayKwh:"今日能源(kWh)",totalEnergyKwh:"總能源(kWh)",noMatchingSensors:"無匹配的感測器",none:"無",mqttNotConfigured:"MQTT代理未設定。請在以下位置設定代理地址",mqttSettingsPath:"設定 → 網路 → MQTT發布",mqttNotConfiguredSuffix:"(您不需要啟用發布,只需填寫代理詳細資訊)。",mqttMonitorOnlyDescription:"MQTT插座透過MQTT訂閱接收功率/能源資料。開關控制不可用 - 請使用您的MQTT代理或家庭自動化系統。",powerMonitoring:"功率監控",energyMonitoring:"能源監控",stateMonitoring:"狀態監控",optional:"可選",topic:"主題",jsonPath:"JSON路徑",multiplier:"乘數",onValue:"ON值",mqttPowerHint:`JSON路徑從JSON負載中提取值(例如"power_l1")。如果主題發布原始數值,請留空。 乘數:mW→W使用0.001,kW→W使用1000。`,mqttEnergyHint:`JSON路徑從JSON負載中提取值。原始值請留空。 乘數:Wh→kWh使用0.001,MWh→kWh使用1000。`,mqttStateHint:`JSON路徑從JSON負載中提取值。原始值請留空。 -ON值:表示"ON"的確切字串。留空以自動檢測(ON、true、1)。`,restControl:"控制",restOnUrl:"開啟 URL",restOffUrl:"關閉 URL",restOnBody:"開啟請求內容",restOffBody:"關閉請求內容",restMethod:"HTTP 方法",restHeaders:"自訂標頭(JSON)",restStatusUrl:"狀態 URL",restStatusPath:"狀態 JSON 路徑",restStatusOnValue:"ON 值",restPowerUrl:"功率URL",restPowerPath:"功率 JSON 路徑",restPowerMultiplier:"功率乘數",restEnergyUrl:"能耗URL",restEnergyPath:"能耗 JSON 路徑",restEnergyMultiplier:"能耗乘數",restUrlRequired:"REST 插座至少需要一個 URL(ON 或 OFF)",restHeadersHint:'例如:{"Authorization": "Bearer your-token"}',restBodyHint:'例如:ON、{"state": "on"}',restStatusHint:"用於輪詢目前狀態的 URL",restPathHint:"例如:state 或 data.power.status",restPowerUrlHint:"功率資料的獨立URL(留空則使用狀態URL)",restEnergyUrlHint:"能耗資料的獨立URL(留空則使用狀態URL)",restEnergyHint:"每個值可以使用獨立的URL,或回退到狀態 URL。使用乘數進行單位轉換(例如:0.001 將 Wh 轉換為 kWh)。",testConnection:"測試連線",connectionSuccess:"連線成功",noSwitchesInSwitchbar:"開關欄中沒有開關",enableSwitchbarHint:'在設定 > 智慧插座中啟用"在開關欄顯示"'},notifications:{providerTypes:{callmebot:"CallMeBot/WhatsApp",ntfy:"ntfy",pushover:"Pushover",telegram:"Telegram",email:"電子郵件",discord:"Discord",webhook:"Webhook",homeassistant:"Home Assistant"},providerDescriptions:{email:"SMTP 電子郵件通知",telegram:"透過 Telegram 機器人傳送通知",discord:"透過 Webhook 傳送到 Discord 頻道",ntfy:"免費、可自託管的推送通知",pushover:"簡單、可靠的推送通知",callmebot:"透過 CallMeBot 免費傳送 WhatsApp 通知",webhook:"通用 HTTP POST 到任意 URL",homeassistant:"Home Assistant 儀表板中的持久通知"},lastSuccess:"上次:{{date}}",error:"錯誤",printer:"印表機:",allPrinters:"所有印表機",sendTestNotification:"傳送測試通知",eventSettings:"事件設定",enabled:"已啟用",sendFromProvider:"從此提供者傳送通知",printEvents:"列印事件",printerStatus:"印表機狀態",amsAlarms:"AMS 警報",amsHtAlarms:"AMS-HT 警報",printQueue:"列印佇列",start:"開始",plateCheck:"熱床檢測",complete:"完成",failed:"失敗",stopped:"已停止",progress:"進度",offline:"離線",lowFilament:"耗材不足",maintenance:"維護",amsHumidity:"AMS 濕度",amsTemp:"AMS 溫度",amsHtHumidity:"AMS-HT 濕度",amsHtTemp:"AMS-HT 溫度",bedCooled:"熱床已冷卻",firstLayer:"首層完成",quiet:"免打擾",digest:"摘要 {{time}}",printStarted:"列印已開始",plateNotEmpty:"熱床非空",plateNotEmptyDescription:"列印前偵測到物體",printCompleted:"列印已完成",bedCooledLabel:"熱床已冷卻",bedCooledDescription:"列印後熱床溫度降至閾值以下",firstLayerCompleteLabel:"首層列印完成",firstLayerCompleteDescription:"首層完成時傳送帶照片的通知",missingSpoolAssignmentLabel:"缺少料卷分配",missingSpoolAssignmentDescription:"當列印開始且所需料盤沒有分配料卷時傳送通知",printFailed:"列印失敗",printStopped:"列印已停止",progressMilestones:"進度里程碑",progressMilestonesDescription:"在 25%、50%、75% 時通知",printerOffline:"印表機離線",printerError:"印表機錯誤",lowFilamentLabel:"耗材不足",maintenanceDue:"需要維護",maintenanceDueDescription:"需要維護時通知",amsHumidityHigh:"AMS 濕度過高",amsHumidityHighDescription:"普通 AMS 濕度超過閾值",amsTemperatureHigh:"AMS 溫度過高",amsTemperatureHighDescription:"普通 AMS 溫度超過閾值",amsHtHumidityHigh:"AMS-HT 濕度過高",amsHtHumidityHighDescription:"AMS-HT 濕度超過閾值",amsHtTemperatureHigh:"AMS-HT 溫度過高",amsHtTemperatureHighDescription:"AMS-HT 溫度超過閾值",inventoryAlerts:"庫存警報",stockReorderAlert:"補貨警報",stockReorderAlertDescription:"SKU 已達到補貨點",stockBreakAlert:"斷貨警報",stockBreakAlertDescription:"庫存將在補貨到達前耗盡",jobAdded:"任務已新增",jobAddedDescription:"任務已新增到佇列",jobAssigned:"任務已分配",jobAssignedDescription:"基於模型的任務已分配給印表機",jobStarted:"任務已開始",jobStartedDescription:"佇列任務已開始列印",jobWaiting:"任務等待中",jobWaitingDescription:"任務正在等待耗材或印表機",jobSkipped:"任務已跳過",jobSkippedDescription:"任務已跳過(上一個失敗)",jobFailed:"任務失敗",jobFailedDescription:"任務啟動失敗",queueComplete:"佇列已完成",queueCompleteDescription:"所有佇列任務已完成",quietHours:"免打擾時段",noNotificationsDuring:"在此時段內不傳送通知",editProviderToChangeQuietHours:"編輯提供者以更改免打擾時段",dailyDigest:"每日摘要",batchNotifications:"將通知彙總為每日摘要",sendAt:"傳送於 {{time}}",editProviderToChangeDigestTime:"編輯提供者以更改摘要時間",edit:"編輯",deleteProvider:"刪除通知提供者",deleteConfirm:'確定要刪除"{{name}}"嗎?此操作無法復原。',delete:"刪除",addTitle:"新增通知提供者",editTitle:"編輯通知提供者",nameLabel:"名稱 *",namePlaceholder:"我的通知",providerTypeLabel:"提供者類型 *",configuration:"設定",testConfiguration:"測試設定",printerFilter:"印表機篩選",onlyFromPrinter:"僅傳送來自此印表機的事件通知",quietHoursDnd:"免打擾時段",quietStart:"開始",quietEnd:"結束",dailyDigestLabel:"每日摘要",sendDigestAt:"傳送摘要於",digestCollected:"事件將被收集並在此時間作為單條摘要傳送",notificationEvents:"通知事件",progressPercent:"(25%、50%、75%)",bedCooledAfterPrint:"(列印完成後)",eventPriority:{sectionTitle:"ntfy 優先級",helpNtfy:"為每個已啟用的事件選擇優先級。ntfy 使用它來升級提醒(聲音、可見性、推播行為)。此處未設定的級別將使用 ntfy 伺服器預設值。",min:"最低",low:"低",default:"預設",high:"高",urgent:"緊急"},cancel:"取消",save:"儲存",add:"新增",nameRequired:"名稱為必填項",fieldRequired:"{{field}}為必填項",phoneNumber:"電話號碼",apiKey:"API 金鑰",serverUrl:"伺服器 URL",topic:"主題",authToken:"認證權杖",userKey:"使用者金鑰",appToken:"應用程式權杖",priority:"優先順序",botToken:"機器人權杖",chatId:"聊天 ID",smtpServer:"SMTP 伺服器",smtpPort:"SMTP 連接埠",security:"安全",authentication:"認證",username:"使用者名稱",password:"密碼",fromEmail:"寄件人信箱",toEmail:"收件人信箱",webhookUrl:"Webhook URL",payloadFormat:"負載格式",authorization:"授權",titleFieldName:"標題欄位名",messageFieldName:"訊息欄位名",editTemplate:"編輯範本:{{name}}",titleLabel:"標題",bodyLabel:"正文",titlePlaceholder:"通知標題...",bodyPlaceholder:"通知正文...",availableVariables:"可用變數",clickToInsert:"點選插入到正文游標位置",livePreview:"即時預覽",hide:"隱藏",show:"顯示",loadingPreview:"載入預覽中...",enterTemplateContent:"輸入範本內容以檢視預覽",titlePreview:"標題:",bodyPreview:"正文:",resetToDefault:"恢復預設",titleRequired:"標題為必填項",bodyRequired:"正文為必填項",notificationLog:"通知日誌",showFailedOnly:"僅顯示失敗",last24Hours:"最近 24 小時",last7Days:"最近 7 天",last30Days:"最近 30 天",last90Days:"最近 90 天",justNow:"剛剛",noFailedNotifications:"沒有失敗的通知",noNotificationsLogged:"沒有通知紀錄",unknownProvider:"未知提供者",logTitle:"標題",logMessage:"訊息",logError:"錯誤",logProvider:"提供者:{{type}}",logTime:"時間:{{time}}",refresh:"重新整理",clearOld:"清除舊紀錄",statsSummary:"最近 {{days}} 天:",statsNotifications:"條通知",statsSent:"{{count}} 條已傳送",statsFailed:"{{count}} 條失敗",eventTypes:{print_start:"列印已開始",print_complete:"列印完成",print_failed:"列印失敗",print_stopped:"列印已停止",print_progress:"進度",printer_offline:"印表機離線",printer_error:"印表機錯誤",filament_low:"耗材不足",maintenance_due:"需要維護",test:"測試"},userEmail:{title:"通知",emailNotifications:"郵件通知",emailNotificationsDesc:"接收您自己列印任務的郵件通知。郵件將透過進階身份驗證中設定的 SMTP 設定傳送。",sendingTo:"通知將傳送至",noEmailWarning:"您的帳戶沒有郵件地址。請聯絡管理員新增。",printJobNotifications:"列印任務通知",printJobNotificationsDesc:"選擇哪些事件會觸發您提交的列印任務的郵件通知。",printJobStarts:"列印任務開始",printJobStartsDesc:"當您的列印任務開始時收到通知。",printJobFinishes:"列印任務完成",printJobFinishesDesc:"當您的列印任務成功完成時收到通知。",printErrors:"列印錯誤",printErrorsDesc:"當您的列印任務失敗或遇到錯誤時收到通知。",printJobStops:"列印任務停止",printJobStopsDesc:"當您的列印任務被取消或停止時收到通知。",saveSuccess:"通知偏好設定已儲存。",saveError:"儲存通知偏好設定失敗。"}},richTextEditor:{bold:"粗體",italic:"斜體",underline:"底線",bulletList:"無序列表",numberedList:"有序列表",alignLeft:"左對齊",alignCenter:"居中對齊",alignRight:"右對齊",addLink:"新增連結",removeLink:"移除連結"},externalLinks:{noLinksConfigured:"未設定外部連結",deleteLink:"刪除連結",removeCustomIcon:"移除自訂圖示",openInNewTab:"在新標籤頁中開啟",placeholders:{linkName:"我的連結"}},keyboardShortcuts:{title:"鍵盤快捷鍵",navigation:"導航",archivesSection:"歸檔",kProfilesSection:"K 值設定",generalSection:"通用",shortcuts:{goToPrinters:"前往印表機",goToArchives:"前往歸檔",goToQueue:"前往佇列",goToStats:"前往統計",goToProfiles:"前往雲端設定",goToSettings:"前往設定",focusSearch:"聚焦搜尋",openUploadModal:"開啟上傳對話方塊",clearSelection:"清除選擇 / 取消焦點",contextMenu:"卡片右鍵選單",refreshProfiles:"重新整理設定",newProfile:"新增設定",exitSelectionMode:"結束選擇模式",showHelp:"顯示此協助"},footer:"按 Esc 或點選外部關閉"},notificationLog:{title:"通知日誌",events:{printStarted:"列印開始",printComplete:"列印完成",printFailed:"列印失敗",printStopped:"列印停止",progress:"進度",printerOffline:"印表機離線",printerError:"印表機錯誤",lowFilament:"耗材不足",maintenanceDue:"維護到期",test:"測試"},timeAgo:{justNow:"剛剛",minutesAgo:"{{minutes}} 分鐘前",hoursAgo:"{{hours}} 小時前"}},restoreBackup:{title:"恢復備份",restoring:"恢復中...",restoreComplete:"恢復完成",restoreFailed:"恢復失敗",importSettings:"從備份檔案匯入設定",pleaseWait:"請稍候,正在恢復您的資料",clickToSelect:"點選選擇備份檔案(.json 或 .zip)",howDuplicateHandling:"重複處理方式:",categories:{printers:"印表機",smartPlugs:"智慧插座",notificationProviders:"通知提供者",filaments:"耗材",archives:"歸檔",pendingUploads:"待處理上傳",settingsTemplates:"設定和範本"},matchingInfo:{printers:"按序列號匹配",smartPlugs:"按 IP 位址匹配",notificationProviders:"按名稱匹配",filaments:"按名稱 + 類型 + 品牌匹配",archives:"按內容雜湊匹配",pendingUploads:"按檔名匹配",settingsTemplates:"始終覆蓋"},replaceExisting:"替換現有資料",keepExisting:"保留現有資料",replaceDescription:"用備份資料覆蓋已存在的項目",keepDescription:"僅恢復不存在的項目",caution:"注意:",cautionText:"覆蓋將用備份資料替換您目前的設定。出於安全考慮,印表機存取碼永遠不會被覆蓋。",itemsRestored:"已恢復項目",itemsSkipped:"已跳過項目",restored:"已恢復",skipped:"已跳過(已存在)",filesLabel:"檔案(3MF、縮圖等)",newApiKeysGenerated:"已產生新 API 金鑰",newApiKeysWarning:"這些金鑰僅顯示一次。請立即複製!",processingBackup:"處理備份檔案中...",noDataFound:"備份檔案中未找到可恢復的資料。",failedToRestore:"恢復備份失敗。請檢查檔案格式。"},backupExport:{title:"匯出備份",selectData:"選擇要包含的資料",selectAll:"全選",selectNone:"全不選",categoryDescriptions:{settings:"語言、主題、更新偏好",notifications:"ntfy、Pushover、Discord 等",templates:"自訂訊息範本",smartPlugs:"Tasmota 插座設定",externalLinks:"側邊欄外部服務連結",printers:"印表機資訊(不含存取碼)",plateDetection:"空列印板參考影像",filaments:"耗材類型和成本",maintenance:"自訂維護計畫",archives:"所有列印資料 + 檔案(3MF、縮圖、照片)",projects:"專案、材料清單和附件",pendingUploads:"虛擬印表機待審核的上傳",apiKeys:"Webhook API 金鑰(匯入時產生新金鑰)"},requiresPrinters:"需要選擇印表機",zipFileWarning:"將建立 ZIP 檔案。",zipFileDescription:"包括所有 3MF 檔案、縮圖、縮時攝影和照片。這可能需要一些時間並產生較大的檔案。",includeAccessCodes:"包含存取碼",includeAccessCodesDescription:"用於轉移到另一臺機器",includeAccessCodesWarning:"存取碼將以明文形式包含。請妥善保管此備份檔案!",categoriesSelected:"已選擇 {{selectedCount}} 個類別"},pendingUploads:{placeholders:{notes:"新增關於此列印的備註..."},discardUpload:"丟棄上傳",archiveAllUploads:"歸檔所有上傳",discardAllUploads:"丟棄所有上傳",archive:"歸檔",timeAgo:{justNow:"剛剛",minutesAgo:"{{minutes}} 分鐘前",hoursAgo:"{{hours}} 小時前",daysAgo:"{{days}} 天前"}},apiBrowser:{placeholders:{requestBody:"JSON 請求體...",searchEndpoints:"搜尋端點..."}},configureAmsSlot:{title:"設定 AMS 槽位",slotConfigured:"槽位已設定!",configuringSlot:"正在設定槽位:",slotLabel:"{{ams}} 槽位 {{slot}}",searchPresets:"搜尋預設...",colorPlaceholder:"顏色名稱或十六進位(例如:棕色、FF8800)",clearCustomColor:"清除自訂顏色",noCloudPresets:"無雲端預設。登入拓竹雲以同步。",noPresetsAvailable:"無可用預設。登入拓竹雲或匯入本機設定。",noMatchingPresets:"未找到匹配的預設。",custom:"自訂",builtin:"內建",settingsSentToPrinter:"設定已傳送到印表機",filamentProfile:"耗材設定",kProfileLabel:"K 值設定(壓力推進)",filteringFor:"篩選:{{material}}",noKProfile:"無 K 值設定(使用預設值 0.020)",noMatchingKProfiles:"未找到匹配的 K 值設定。將使用預設 K=0.020。",selectFilamentFirst:"請先選擇耗材設定",kFromCalibration:"K={{value}}(來自印表機校準)",customColorLabel:"自訂顏色(可選)",presetColors:"{{name}} 顏色:",showLessColors:"顯示更少顏色",showMoreColors:"顯示更多顏色",clear:"清除",hexLabel:"十六進位:#{{hex}}",resetting:"重設中...",resetSlot:"重設槽位",cancel:"取消",configuring:"設定中...",configureSlot:"設定槽位"},githubBackup:{title:"Git 備份",history:"歷史",downloadBackup:"下載備份",restoreBackup:"恢復備份",noBackupsYet:"尚無備份"},emailSettings:{placeholders:{fromName:"Bambuddy"}},tagManagement:{searchTags:"搜尋標籤...",renameTag:"重新命名標籤",deleteTag:"刪除標籤"},notificationTemplates:{placeholders:{title:"通知標題...",body:"通知正文..."}},batchTag:{placeholders:{newTag:"輸入新標籤..."}},photoGallery:{deletePhoto:"刪除照片"},filamentHoverCard:{copySpoolUuid:"複製耗材 UUID"},kProfilesView:{hasNote:"有備註",copyProfile:"複製設定"},layout:{openMenu:"開啟選單",noPermissionSystemInfo:"您沒有檢視系統資訊的權限"},dashboard:{dragToReorder:"拖曳以重新排列",hideWidget:"隱藏小工具"},notificationProviderCard:{deleteNotificationProvider:"刪除通知提供者"},fileManagerModal:{closeFileManager:"關閉檔案管理器",sortFiles:"排序檔案",goToParentFolder:"返回上級資料夾",threeView:"3D 檢視"},embeddedCameraViewer:{refreshStream:"重新整理流",close:"關閉",zoomOut:"縮小",resetZoom:"重設縮放",zoomIn:"放大",dragToResize:"拖曳調整大小"},timelapseViewer:{skipBack5s:"後退 5 秒",skipForward5s:"前進 5 秒"},notificationProviders:{descriptions:{email:"SMTP 郵件通知",telegram:"透過 Telegram 機器人通知",discord:"透過 Webhook 傳送到 Discord 頻道",ntfy:"免費、可自託管的推送通知",pushover:"簡單、可靠的推送通知",callmebot:"透過 CallMeBot 的免費 WhatsApp 通知",webhook:"通用 HTTP POST 到任意 URL"}},logViewer:{searchPlaceholder:"搜尋訊息或日誌名稱...",noLogEntries:"未找到日誌條目"},switchbarPopover:{noSwitchesInSwitchbar:"切換欄中沒有開關"},projectPageModal:{placeholders:{title:"標題",designer:"設計師",license:"許可證",description:"輸入描述...",profileTitle:"設定標題",profileDescription:"設定描述..."}},spoolmanSettings:{},time:{unknown:"-",waiting:"等待中",justNow:"剛剛",now:"現在",minsAgo:"{{count}} 分鐘前",inMins:"{{count}} 分鐘後",hoursAgo:"{{count}} 小時前",inHours:"{{count}} 小時後",daysAgo:"{{count}} 天前",inDays:"{{count}} 天後"},spoolbuddy:{nav:{dashboard:"儀表板",ams:"AMS",inventory:"庫存",writeTag:"寫入",settings:"設定"},status:{nfcReady:"NFC 就緒",nfcOff:"NFC 關閉",offline:"離線",online:"線上",noPrinters:"無印表機",deviceOffline:"裝置離線",waitingConnection:"等待裝置連線...",systemReady:"系統就緒",status:"狀態"},dashboard:{readyToScan:"準備掃描",idleMessage:"將耗材放在磅秤上以識別",nfcHint:"NFC 標籤將自動讀取",device:"裝置",syncWeight:"同步重量",weightSynced:"已同步!",unknownTag:"未知標籤",newTag:"偵測到新標籤",onScale:"在磅秤上",linkSpool:"連結到耗材",linkTagTitle:"將標籤連結到耗材",linkTag:"連結標籤",selectSpool:"選擇要連結此標籤的耗材:",noUntagged:"未找到沒有標籤的耗材",tagDetected:"偵測到標籤",noTag:"無標籤",tagId:"標籤",grossWeight:"毛重",spoolSize:"耗材盤尺寸",close:"關閉",currentSpool:"目前耗材",plateReady:"熱床就緒: {{name}}",plateReadyLabel:"待清理的熱床",plateClearAction:"清理",plateClearedToast:"已將熱床標記為已清理",plateClearFailed:"無法將熱床標記為已清理"},modal:{spoolDetected:"偵測到耗材",assignToAms:"分配到 AMS",syncWeight:"同步重量",weightSynced:"已同步!",syncing:"同步中...",newTagDetected:"偵測到新標籤",addToInventory:"新增到庫存",assignToAmsTitle:"分配到 AMS",selectSlot:"選擇槽位",assign:"分配",assigning:"分配中...",assignSuccess:"已分配!",assignPendingInsert:"已分配。插入耗材後將設定槽位。",assignError:"分配耗材失敗。請重試。",noPrinterSelected:"選擇印表機...",noAmsDetected:"此印表機未偵測到 AMS",slot:"槽位"},weight:{noReading:"無讀數",stable:"穩定",measuring:"測量中...",tare:"去皮",calibrate:"校準"},spool:{remaining:"剩餘",material:"材料",brand:"品牌",color:"顏色",coreWeight:"軸心重",labelWeight:"標籤重",scaleWeight:"磅秤重",netWeight:"淨重",lastUsed:"上次使用"},ams:{noData:"未偵測到 AMS",connectAms:"連線 AMS 以檢視耗材槽位",noPrinter:"未選擇印表機",selectPrinter:"從頂部欄選擇印表機",printerDisconnected:"印表機已斷開",humidity:"濕度",level:"餘量",active:"活躍",slot:"槽位",empty:"空"},inventory:{search:"搜尋耗材...",empty:"庫存中沒有耗材",noResults:"沒有匹配的耗材",spools:"個耗材",addSpool:"新增耗材"},settings:{tabDevice:"裝置",tabDisplay:"顯示",tabScale:"磅秤",tabUpdates:"更新",nfcReader:"NFC 讀卡器",type:"類型",connection:"連線",notConnected:"不適用",deviceInfo:"裝置資訊",hostname:"主機",uptime:"執行時間",systemConfig:"後端與認證",backendUrl:"Bambuddy 後端 URL",apiToken:"API 權杖",apiTokenPlaceholder:"輸入 API 權杖",saveConfig:"儲存設定",systemQueued:"設定已加入佇列。",nfcDiagnostic:"NFC 診斷",scaleDiagnostic:"磅秤診斷",readTagDiagnostic:"讀取標籤診斷",testNfc:"測試讀卡器",testScale:"測試精度",testReadTag:"讀取標籤",systemFieldsRequired:"後端 URL 為必填項。",brightness:"亮度",saved:"已儲存",noBacklight:"未偵測到 DSI 背光。亮度控制需要 DSI 螢幕。",screenBlank:"螢幕熄滅超時",screenBlankDesc:"不活動後螢幕關閉。觸控喚醒。",displayNote:"亮度作為軟體濾鏡套用。",scaleCalibration:"磅秤校準",currentWeight:"目前重量",tareOffset:"去皮",calFactor:"係數",knownWeight:"已知重量",calStep1:"移除磅秤上所有物品並按設定零點。",calStep2:"將已知重量放在磅秤上。",setZero:"設定零點",calibrateNow:"校準",calibrated:"已校準",tareSet:"去皮命令已傳送。等待裝置回應...",tareFailed:"傳送去皮命令失敗",zeroSet:"零點已設定。將已知重量放在磅秤上。",calibrationDone:"校準完成!",calibrationFailed:"校準失敗",lastCalibrated:"上次校準",stable:"穩定",settling:"穩定中...",firmware:"韌體",scale:"磅秤",noDevice:"未找到 SpoolBuddy 裝置",daemonVersion:"守護程式版本",currentVersion:"目前",versionPending:"等待守護程式...",checking:"檢查中...",checkUpdates:"檢查更新",updateAvailable:"有可用更新",updateInstructions:"透過 SSH 更新:執行 SpoolBuddy 安裝腳本進行升級。",upToDate:"已是最新",includeBeta:"包含測試版本"},writeTag:{tabExisting:"現有耗材",tabNew:"新耗材",tabReplace:"替換標籤",searchPlaceholder:"按材料、顏色、品牌搜尋...",noUntaggedSpools:"沒有無標籤的耗材",noTaggedSpools:"沒有有標籤的耗材",selectSpool:"選擇一個耗材,然後將空白 NTAG 放在讀卡器上",placeTag:"將 NTAG 放在讀卡器上",tagReady:"偵測到標籤 — 準備寫入",writeTag:"寫入標籤",replaceTag:"替換標籤",writing:"寫入標籤中...",waiting:"等待 SpoolBuddy...",writeSuccess:"標籤寫入成功!",writeFailed:"寫入失敗",queueFailed:"佇列寫入命令失敗",tryAgain:"重試",cancel:"取消",replaceWarning:"舊標籤將被取消連結。新標籤將替換它。",deviceOffline:"SpoolBuddy 離線",material:"材料",colorName:"顏色名稱",color:"顏色",brand:"品牌",weight:"重量 (g)",createSpool:"建立耗材",creating:"建立中...",spoolCreated:"耗材已建立!準備寫入。",createFailed:"建立耗材失敗",incompleteDataWarning:"已使用不完整的Spoolman資料寫入標籤"},quickMenu:{printerPower:"印表機電源",systemControls:"系統",restartDaemon:"重新啟動守護程式",restartBrowser:"重新啟動瀏覽器",reboot:"重新開機",shutdown:"關機",swipeToClose:"向下滑動關閉",confirmTitle:"確認",confirmShutdown:"確定要關閉 SpoolBuddy 嗎?您需要實體存取才能重新開啟。",confirmReboot:"確定要重新開機 SpoolBuddy 嗎?",confirmRestartDaemon:"重新啟動 SpoolBuddy 守護程式?NFC 和磅秤將暫時不可用。",confirmRestartBrowser:"重新啟動kiosk瀏覽器?螢幕將短暫變黑。",confirm:"確認",confirmPlugOn:"開啟 {{name}}?",confirmPlugOff:"關閉 {{name}}?",turnOn:"開啟",turnOff:"關閉"}},bugReport:{title:"報告錯誤",description:"描述",descriptionPlaceholder:"出了什麼問題?請描述問題...",email:"信箱(可選)",emailPlaceholder:"your@email.com",emailPrivacy:"如果提供,您的信箱將包含在GitHub Issue的摺疊部分中,以便維護者後續跟進。",screenshot:"截圖",uploadOrPaste:"上傳、貼上或拖曳圖片",dataCollectedSummary:"報告中包含哪些資料?",dataIncluded:"包含:",dataIncludedList:"應用程式版本、作業系統、架構、Python版本、資料庫統計(僅計數)、印表機型號、噴嘴數量、韌體版本、連線狀態、整合狀態(Spoolman、MQTT、HA)、非敏感設定、網路介面數量、Docker詳情、依賴版本。",dataNeverIncluded:"絕不包含:",dataNeverIncludedList:"印表機名稱、序列號、存取碼、密碼、IP 位址、信箱地址、API金鑰、權杖、Webhook URL、主機名稱或使用者名稱。",submit:"提交",startLogging:"開始偵錯日誌",stepEnableLogging:"偵錯日誌已啟用",stepReproduce:"請現在重現問題",stepStopLogging:"停止並提交報告",stopAndSubmit:"停止並提交",maxDuration:"{{minutes}} 分鐘後自動停止",stoppingLogs:"正在收集日誌並提交...",submitting:"正在提交錯誤報告...",submitSuccess:"錯誤報告提交成功!",submitFailed:"提交錯誤報告失敗",thankYou:"謝謝!",submitted:"您的錯誤報告已提交。",viewIssue:"檢視 Issue",unexpectedError:"發生了意外錯誤"},failureDetection:{title:"AI 故障檢測",description:"透過自託管的 Obico ML API 監控列印,並對偵測到的故障自動採取行動。",mlUrl:"Obico ML API 地址",mlUrlHint:"您自託管的 Obico ml_api 容器的基礎 URL(例如 http://192.168.1.10:3333)。",test:"測試",testSuccess:"ML API 可存取且正常。",testFailed:"無法存取 ML API。",sensitivity:"靈敏度",sensitivityLow:"低(減少誤報)",sensitivityMedium:"中(平衡)",sensitivityHigh:"高(更早檢測,更多誤報)",sensitivityHint:"調整觸發警告和故障的置信度閾值。",action:"偵測到故障時的操作",actionNotify:"僅通知",actionPause:"暫停列印",actionPauseOff:"暫停並切斷電源",pollInterval:"檢查間隔(秒)",pollIntervalHint:"列印過程中每臺印表機的檢查頻率。最小 5 秒,最大 120 秒。",externalUrlMissing:"尚未設定外部 URL。",externalUrlHint:"ML API 透過 URL 擷取攝影機快照。請在一般設定中設定外部 URL,讓 ML API 容器可以連線到 Bambuddy。",perPrinterTitle:"監控的印表機",perPrinterHint:"選擇檢測服務要監視哪些印表機。",monitorAll:"監控所有已連線的印表機",statusTitle:"狀態",serviceRunning:"服務執行中",thresholds:"低 / 高閾值",activePrinters:"活動列印",noActivePrints:"目前沒有正在進行的列印。",historyTitle:"最近檢測",noHistory:"尚無檢測紀錄。"},makerworld:{title:"MakerWorld",description:"貼上 MakerWorld 模型連結,即可直接在 Bambuddy 中匯入並列印 —— 無需切換至 Bambu Handy 應用程式。",pasteUrlHeader:"從 MakerWorld 匯入",pasteUrlPlaceholder:"https://makerworld.com/en/models/… 或貼上任意 MakerWorld 連結",resolveButton:"解析",signInRequiredTitle:"下載需要登入 Bambu Cloud",signInRequiredBody:"您可以匿名瀏覽模型詳情,但下載 3MF 檔案需要 Bambu Cloud 帳戶。",openCloudSettings:"開啟雲端設定",untitledModel:"無標題模型",byCreator:"作者: {{name}}",downloadsCount:"{{count}} 次下載",licensePrefix:"授權條款",alreadyImported:"已在資料庫中",openOnMakerworld:"在 MakerWorld 中開啟",alreadyInLibrary:"此模型已在您的資料庫中 —— 可在檔案管理員 → MakerWorld 中找到",importSuccess:"已匯入 {{filename}} —— 已儲存至檔案管理員 → MakerWorld",platesHeader:"列印板 ({{count}})",plateDefaultName:"列印板 {{n}}",materialCount:"{{count}} 種耗材",amsRequired:"需要 AMS",slicedFor:"為 {{printer}} 切片",alsoCompatible:"還標記為相容:{{printers}}",importToLibrary:"儲存",sliceIn:"儲存並在 {{slicer}} 中切片",disclaimer:"MakerWorld 整合使用由社群記錄的 API 介面。Bambuddy 與 MakerWorld 或 Bambu Lab 無從屬或認可關係。",lastImportSuccess:"已匯入您的資料庫",lastImportAlreadyInLibrary:"已存在於您的資料庫中",viewInLibrary:"在檔案管理員中查看",openInBambuStudio:"在 Bambu Studio 中開啟",openInOrcaSlicer:"在 OrcaSlicer 中開啟",importTo:"匯入至檔案管理員",recentImportsHeader:"最近匯入",phaseResolving:"解析中",phaseDownloading:"下載中",folderAuto:"MakerWorld (預設)",importAll:"全部匯入",importAllProgress:"正在匯入 {{current}}/{{total}}",openGallery:"開啟圖片庫",galleryPrev:"上一張",galleryNext:"下一張",deleteImport:"從資料庫中移除",importDeleting:"正在移除…",importDeleted:"已從資料庫中移除",confirmDelete:"從資料庫中移除 {{filename}}?本機檔案將被刪除,但可以從 MakerWorld 重新匯入。",errors:{resolveFailed:"無法解析該 MakerWorld 連結。",downloadFailed:"下載失敗。請重試。",deleteFailed:"無法從資料庫中移除檔案。"}},gcodeViewer:{back:"返回",backToArchives:"返回列印歸檔",backToFiles:"返回檔案管理器"},libraryTrash:{title:"資源回收筒",headerButton:"資源回收筒",headerTooltip:"檢視已移至資源回收筒的檔案",backToFiles:"返回檔案管理員",subtitleAdmin:"已刪除的檔案會在資源回收筒保留 {{days}} 天,之後自動刪除。此檢視顯示所有使用者的資源回收筒。",subtitleUser:"已刪除的檔案會在資源回收筒保留 {{days}} 天,之後自動刪除。",loading:"正在載入資源回收筒…",loadError:"無法載入資源回收筒。",empty:"資源回收筒是空的。",summary:"{{count}} 個檔案 · {{size}}",emptyTrash:"清空資源回收筒",restore:"還原",purgeNow:"立即刪除",autoPurgeIn:"將於 {{when}} 自動刪除",days:"天",retentionLabel:"自動刪除時間",selectAll:"全選",selectOne:"選擇 {{filename}}",selectionCount:"已選擇 {{count}} 項",bulkRestore:"還原所選",bulkPurge:"刪除所選",col:{filename:"檔案",folder:"資料夾",size:"大小",deleted:"移入資源回收筒",autoPurge:"自動刪除",owner:"擁有者",actions:"操作"},confirm:{purgeTitle:"永久刪除?",purgeBody:"{{filename}} 將從磁碟中刪除,無法還原。",emptyTitle:"清空資源回收筒?",emptyBody:"全部 {{count}} 個檔案將從磁碟中刪除。此操作無法復原。",bulkPurgeTitle:"永久刪除所選檔案?",bulkPurgeBody:"所選的 {{count}} 個檔案將從磁碟中刪除,無法還原。",cta:"永久刪除"},toast:{restored:"檔案已還原。",restoreFailed:"無法還原檔案。",purged:"檔案已永久刪除。",purgeFailed:"無法刪除檔案。",emptied:"已從資源回收筒刪除 {{count}} 個檔案。",emptyFailed:"無法清空資源回收筒。",retentionSaved:"自動刪除已設定為 {{days}} 天。",retentionFailed:"無法儲存保留設定。",bulkRestored:"已還原 {{count}} 個檔案。",bulkPurged:"已刪除 {{count}} 個檔案。"}},libraryPurge:{title:"清理舊檔案",headerButton:"清理舊檔案",headerTooltip:"批次將舊檔案移至資源回收筒",description:"早於所選時間的檔案將被移至資源回收筒。外部資料夾會被略過。在自動刪除之前,您可以從資源回收筒還原檔案。",ageLabel:"移動早於以下天數的檔案",days:"天",includeNeverPrinted:"包括從未列印過的檔案",effectsTitle:"點擊清除時會發生什麼",effect1:"符合的檔案移至回收筒 — 尚未從磁碟刪除。",effect2:"在保留期到期之前,您可以隨時從回收筒復原。",effect3:"保留期滿後,回收筒清理器將它們從磁碟永久刪除。",effect4:"外部(連結)資料夾中的檔案將被略過 — Bambuddy 從不刪除不屬於自己的位元組。",previewLoading:"正在檢查符合的檔案數量…",previewFailed:"無法預覽清理結果。",previewSummary:"{{count}} 個檔案 · {{size}} 將被移至資源回收筒",andMore:"…還有 {{count}} 個",warning:"檔案將被軟刪除——在保留期結束前,您可以從資源回收筒還原它們。",confirmCta:"將 {{count}} 個移至資源回收筒",purging:"正在移至資源回收筒…",toast:{success:"已將 {{count}} 個檔案移至資源回收筒。",failed:"無法清理檔案。"}},libraryAutoPurge:{enableLabel:"自動清理舊檔案",enableDescription:"每天執行一次管理員清理。檔案會先進入資源回收筒——不會立即刪除。",ageLabel:"自動清理早於以下天數的檔案",ageDescription:"最少 7 天,最多 10 年。使用與手動「清理舊檔案」按鈕相同的時間規則。",days:"天",includeNeverPrinted:"包括從未列印過的檔案",saveFailed:"無法儲存自動清理設定。"},archivePurge:{headerButton:"清除舊條目",headerTooltip:"批次刪除舊歸檔",title:"清除舊歸檔",description:"清除舊的列印歷史。每個歸檔按其最近一次列印完成時間老化 — 重新列印歸檔會重新整理其年齡,因此活躍工作永遠不會被清除。",ageLabel:"刪除最近未列印的歸檔:",days:"天",effectsTitle:"點擊清除時會發生什麼",effect1:"每個符合的歸檔將從清單中隱藏,其磁碟檔案(3MF、縮圖、縮時攝影、原始 3MF、F3D、照片)也會被刪除。",effect2:"資料庫中的歸檔記錄會保留,因此 Quick Stats 仍可計入耗材、時間、成本與能耗的貢獻 — 與單筆刪除的預設行為一致。",effect3:"勾選下方「同時從統計中移除」,可一併清除 Quick Stats 中的貢獻(等同單筆刪除選項)。此操作無法復原。",effect4:"重新列印歸檔會重新整理其使用計時器,因此仍在使用的歸檔不會被清除。",purgeStatsLabel:"同時從統計中移除",purgeStatsHint:"從 Quick Stats(耗材、時間、成本、能耗)中移除符合的歸檔。未勾選時,Quick Stats 會保留所有貢獻,僅檔案從磁碟刪除。",previewLoading:"檢查符合的歸檔數量…",previewFailed:"無法預覽清除。",previewSummary:"將移除 {{count}} 個歸檔 · {{size}}",andMore:"…還有 {{count}} 個",warning:"檔案會從磁碟刪除且無法復原。繼續前請下載或收藏您想保留的內容。",confirmCta:"移除 {{count}} 個歸檔",purging:"移除中…",toast:{success:"已移除 {{count}} 個歸檔。",failed:"無法清除歸檔。"}},archiveAutoPurge:{enableLabel:"自動清除舊歸檔",enableDescription:"每天一次,將閾值內未列印的歸檔從清單中隱藏,並從磁碟中刪除其檔案。重新列印會重設計時器。",ageLabel:"自動刪除最近未列印的歸檔:",ageDescription:"最少 7 天,最多 10 年。基於最近一次列印完成 — 重新列印會重新整理年齡。刪除 3MF、縮圖、縮時攝影、原始 3MF、F3D 與照片。",days:"天",purgeStatsLabel:"同時從統計中移除",purgeStatsDescription:"啟用後,每日清理任務還會將每個被清除的歸檔從 Quick Stats(耗材、時間、成本、能耗)中移除。預設關閉 — Quick Stats 會保留貢獻,僅檔案從磁碟刪除。",runNow:"立即清除歸檔",saveFailed:"無法儲存自動清除設定。"},cameraTokens:{title:"攝影機 API 權杖",navTitle:"攝影機 API 權杖",description:"長期權杖,用於將攝影機串流嵌入 Home Assistant、Frigate、資訊站或其他需要穩定 URL 的工具。每個權杖僅限攝影機串流,可隨時撤銷。",loading:"載入中…",confirmRevoke:{title:"撤銷此權杖?",body:"使用「{{name}}」的任何裝置將立即失去存取權限。此操作無法復原。",cancel:"取消",confirm:"撤銷"},create:{title:"建立新權杖",nameLabel:"權杖名稱",namePlaceholder:"例如 Home Assistant",daysLabel:"到期天數",submit:"建立",hint:"最大有效期 365 天。權杖值僅在建立時顯示一次 — 請立即複製。"},created:{title:"權杖已建立 — 立即複製",warning:"這是此權杖唯一一次可見。關閉此對話框後您將無法再次查看。",copy:"複製",dismiss:"我已儲存"},list:{myTitle:"我的權杖",allTitle:"所有使用者(管理員視圖)",empty:"尚無權杖。",name:"名稱",owner:"擁有者",prefix:"前綴",created:"建立時間",expires:"到期時間",lastUsed:"最近使用",revoke:"撤銷",expired:"已過期"},toast:{created:"權杖已建立",createFailed:"建立權杖失敗",revoked:"權杖已撤銷",revokeFailed:"撤銷權杖失敗",loadFailed:"載入權杖失敗",copied:"已複製到剪貼簿",copyFailed:"複製失敗 — 手動選擇並複製"}},forecast:{title:"庫存預測",noSpools:"未找到活躍的料卷。請將料卷新增至庫存以查看預測資料。",noUsageData:"無可用使用資料 — 無法預測庫存時間線。",sku:"SKU",material:"材料",stock:"庫存",dailyRate:"消耗率",daysLeft:"剩餘天數",emptyBy:"耗盡日期",reorderBy:"補貨截止日",actions:"操作",trend:"趨勢",estimated:"估算",noData:"無資料",timeframe:"時間範圍",chartTitle:"庫存預測 — 前5種材料",dashedLinesROP:"虛線 = 再訂貨點",stockLevel:"庫存量",reorderPoint:"再訂購點",safetyMargin:"安全餘量",trendLegend:"趨勢(基於歷史,95%服務水準)",estimatedLegend:"估算(重量差值)",noDataLegend:"無資料",ropLabel:"再訂貨點",ssLabel:"安全庫存",safetyStockLegend:"安全庫存",stockArrivalLegend:"到貨",stockoutLegend:"斷貨",alertCount_one:"{{count}}條警告",alertCount_other:"{{count}}條警告",order:"訂購",globalLeadTime:"全域交貨期",globalLeadTimeHint:"全域交貨期下限 — 用於所有 SKU 的再訂購點計算",save:"儲存",cancel:"取消",settingsSaved:"設定已儲存",failedSaveSettings:"儲存設定失敗",globalLeadTimeSaved:"全域提前期已儲存",skuLeadTimeOverride:"SKU 交貨期覆蓋",skuLeadTimeHint:"0 = 使用全域交貨期。設定 >0 以覆蓋此 SKU。",safetyMarginLabel:"安全餘量",effectiveLeadTime:"有效交貨期",effectiveLeadTimeHint:"max(全域 {{global}}天, SKU {{sku}}天)",reorderPointHint:"d̄ × LT + safety margin — 當庫存降至此水準時下單",safetyMarginHint:"統計安全庫存 (z=1.65 × σ × √LT) + 使用者自訂緩衝",safetyMarginHintDays:"在統計安全庫存基礎上額外增加的緩衝。{{approx}}",safetyMarginHintDaysApprox:" ≈ 按當前速率 {{g}}g。",safetyMarginHintG:"在統計安全庫存基礎上增加的固定重量緩衝。{{approx}}",safetyMarginHintGApprox:" ≈ 按當前速率 {{days}}天。",individualSpools:"單個料卷",labelWeight:"標示重量",spoolCount_one:"{{count}}個線軸",spoolCount_other:"{{count}}個線軸",stockBreakRisk:"斷貨風險",stockBreakBefore:"補貨前庫存斷檔",stockBreakDetail:"剩餘 {{days}} 天,交貨期 {{lt}} 天。",reorderNow:"立即補貨",reorderTriggerPassed:"觸發日期 {{date}} 已過。",shoppingList:"購物清單",shoppingListItems_one:"({{count}}項)",shoppingListItems_other:"({{count}}項)",shoppingListEmpty:"購物清單為空。點擊任意列的購物車圖示以新增商品。",addToCart:"新增至購物清單",alertsSnoozed:"靜音此SKU的提醒",alertsEnabled:"啟用此SKU的提醒",addedToCart:"已新增至購物清單",failedAddItem:"新增項目失敗",listView:"列表",logisticsView:"物流",qty:"數量",weight:"重量",leadTime:"交貨期",expectedRestock:"預計補貨日期",status:"狀態",note:"備註",pending:"待處理",purchased:"已購買",received:"已收貨",markPurchased:"標記為已購買",markReceived:"標記為已收貨 — 將料卷新增至庫存",resetToPending:"重置為待處理",remove:"移除",clearAll:"清空",downloadCsv:"CSV",addToCartTitle:"新增至購物清單",byQuantity:"依數量",byDuration:"依時長",numberOfSpools:"線軸數量",lastHowManyDays:"需要持續多少天?",noUsageQty:"無使用資料 — 數量已設為1。",noteOptional:"備註(選填)",notePlaceholder:"例如:用於專案X,緊急…",addNSpools_one:"新增{{count}}個線軸",addNSpools_other:"新增{{count}}個線軸",onArrival:"到貨時",stockBreakIn:"{{days}} 天後斷貨。",stockRunsOutBefore:"庫存在 {{lt}} 天交貨期結束前耗盡。",atRate:"按 {{rate}}g/天的速度,您需要",moreSpools_one:"再{{count}}個線軸",moreSpools_other:"再{{count}}個線軸",bridgeGap:"來彌補缺口。",noReadAccess:"您沒有查看庫存預測的權限。",noWriteAccess:"您沒有修改預測設定的權限。"}},Xme={en:{translation:Hme},de:{translation:qme},fr:{translation:$me},ja:{translation:Vme},it:{translation:Gme},"pt-BR":{translation:Wme},"zh-CN":{translation:Kme},"zh-TW":{translation:Qme}};Mo.use(qY).use(vme).init({resources:Xme,fallbackLng:"en",supportedLngs:["en","de","fr","ja","it","pt-BR","zh-CN","zh-TW"],detection:{order:["localStorage","navigator","htmlTag"],lookupLocalStorage:"bambutrack_language",caches:["localStorage"]},interpolation:{escapeValue:!1},react:{useSuspense:!1}});const VH=[{code:"en",name:"English",nativeName:"English"},{code:"de",name:"German",nativeName:"Deutsch"},{code:"fr",name:"French",nativeName:"Français"},{code:"ja",name:"Japanese",nativeName:"日本語"},{code:"it",name:"Italian",nativeName:"Italiano"},{code:"pt-BR",name:"Portuguese (Brazil)",nativeName:"Português (Brasil)"},{code:"zh-CN",name:"Chinese (Simplified)",nativeName:"简体中文"},{code:"zh-TW",name:"Chinese (Traditional)",nativeName:"繁體中文"}];var GH="popstate";function Yme(t={}){function e(a,i){let{pathname:s,search:o,hash:l}=a.location;return jF("",{pathname:s,search:o,hash:l},i.state&&i.state.usr||null,i.state&&i.state.key||"default")}function n(a,i){return typeof i=="string"?i:Pw(i)}return Jme(e,n,null,t)}function za(t,e){if(t===!1||t===null||typeof t>"u")throw new Error(e)}function vc(t,e){if(!t){typeof console<"u"&&console.warn(e);try{throw new Error(e)}catch{}}}function Zme(){return Math.random().toString(36).substring(2,10)}function WH(t,e){return{usr:t.state,key:t.key,idx:e}}function jF(t,e,n=null,a){return{pathname:typeof t=="string"?t:t.pathname,search:"",hash:"",...typeof e=="string"?qy(e):e,state:n,key:e&&e.key||a||Zme()}}function Pw({pathname:t="/",search:e="",hash:n=""}){return e&&e!=="?"&&(t+=e.charAt(0)==="?"?e:"?"+e),n&&n!=="#"&&(t+=n.charAt(0)==="#"?n:"#"+n),t}function qy(t){let e={};if(t){let n=t.indexOf("#");n>=0&&(e.hash=t.substring(n),t=t.substring(0,n));let a=t.indexOf("?");a>=0&&(e.search=t.substring(a),t=t.substring(0,a)),t&&(e.pathname=t)}return e}function Jme(t,e,n,a={}){let{window:i=document.defaultView,v5Compat:s=!1}=a,o=i.history,l="POP",c=null,d=u();d==null&&(d=0,o.replaceState({...o.state,idx:d},""));function u(){return(o.state||{idx:null}).idx}function m(){l="POP";let b=u(),x=b==null?null:b-d;d=b,c&&c({action:l,location:w.location,delta:x})}function p(b,x){l="PUSH";let S=jF(w.location,b,x);d=u()+1;let N=WH(S,d),C=w.createHref(S);try{o.pushState(N,"",C)}catch(P){if(P instanceof DOMException&&P.name==="DataCloneError")throw P;i.location.assign(C)}s&&c&&c({action:l,location:w.location,delta:1})}function f(b,x){l="REPLACE";let S=jF(w.location,b,x);d=u();let N=WH(S,d),C=w.createHref(S);o.replaceState(N,"",C),s&&c&&c({action:l,location:w.location,delta:0})}function g(b){return epe(b)}let w={get action(){return l},get location(){return t(i,o)},listen(b){if(c)throw new Error("A history only accepts one active listener");return i.addEventListener(GH,m),c=b,()=>{i.removeEventListener(GH,m),c=null}},createHref(b){return e(i,b)},createURL:g,encodeLocation(b){let x=g(b);return{pathname:x.pathname,search:x.search,hash:x.hash}},push:p,replace:f,go(b){return o.go(b)}};return w}function epe(t,e=!1){let n="http://localhost";typeof window<"u"&&(n=window.location.origin!=="null"?window.location.origin:window.location.href),za(n,"No window.location.(origin|href) available to create URL");let a=typeof t=="string"?t:Pw(t);return a=a.replace(/ $/,"%20"),!e&&a.startsWith("//")&&(a=n+a),new URL(a,n)}function $Y(t,e,n="/"){return tpe(t,e,n,!1)}function tpe(t,e,n,a){let i=typeof e=="string"?qy(e):e,s=Bm(i.pathname||"/",n);if(s==null)return null;let o=VY(t);npe(o);let l=null;for(let c=0;l==null&&c{let u={relativePath:d===void 0?o.path||"":d,caseSensitive:o.caseSensitive===!0,childrenIndex:l,route:o};if(u.relativePath.startsWith("/")){if(!u.relativePath.startsWith(a)&&c)return;za(u.relativePath.startsWith(a),`Absolute route path "${u.relativePath}" nested under path "${a}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),u.relativePath=u.relativePath.slice(a.length)}let m=Mm([a,u.relativePath]),p=n.concat(u);o.children&&o.children.length>0&&(za(o.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${m}".`),VY(o.children,e,p,m,c)),!(o.path==null&&!o.index)&&e.push({path:m,score:cpe(m,o.index),routesMeta:p})};return t.forEach((o,l)=>{if(o.path===""||!o.path?.includes("?"))s(o,l);else for(let c of GY(o.path))s(o,l,!0,c)}),e}function GY(t){let e=t.split("/");if(e.length===0)return[];let[n,...a]=e,i=n.endsWith("?"),s=n.replace(/\?$/,"");if(a.length===0)return i?[s,""]:[s];let o=GY(a.join("/")),l=[];return l.push(...o.map(c=>c===""?s:[s,c].join("/"))),i&&l.push(...o),l.map(c=>t.startsWith("/")&&c===""?"/":c)}function npe(t){t.sort((e,n)=>e.score!==n.score?n.score-e.score:dpe(e.routesMeta.map(a=>a.childrenIndex),n.routesMeta.map(a=>a.childrenIndex)))}var rpe=/^:[\w-]+$/,ape=3,ipe=2,spe=1,ope=10,lpe=-2,KH=t=>t==="*";function cpe(t,e){let n=t.split("/"),a=n.length;return n.some(KH)&&(a+=lpe),e&&(a+=ipe),n.filter(i=>!KH(i)).reduce((i,s)=>i+(rpe.test(s)?ape:s===""?spe:ope),a)}function dpe(t,e){return t.length===e.length&&t.slice(0,-1).every((a,i)=>a===e[i])?t[t.length-1]-e[e.length-1]:0}function upe(t,e,n=!1){let{routesMeta:a}=t,i={},s="/",o=[];for(let l=0;l{if(u==="*"){let g=l[p]||"";o=s.slice(0,s.length-g.length).replace(/(.)\/+$/,"$1")}const f=l[p];return m&&!f?d[u]=void 0:d[u]=(f||"").replace(/%2F/g,"/"),d},{}),pathname:s,pathnameBase:o,pattern:t}}function mpe(t,e=!1,n=!0){vc(t==="*"||!t.endsWith("*")||t.endsWith("/*"),`Route path "${t}" will be treated as if it were "${t.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${t.replace(/\*$/,"/*")}".`);let a=[],i="^"+t.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(o,l,c)=>(a.push({paramName:l,isOptional:c!=null}),c?"/?([^\\/]+)?":"/([^\\/]+)")).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return t.endsWith("*")?(a.push({paramName:"*"}),i+=t==="*"||t==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?i+="\\/*$":t!==""&&t!=="/"&&(i+="(?:(?=\\/|$))"),[new RegExp(i,e?void 0:"i"),a]}function ppe(t){try{return t.split("/").map(e=>decodeURIComponent(e).replace(/\//g,"%2F")).join("/")}catch(e){return vc(!1,`The URL path "${t}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${e}).`),t}}function Bm(t,e){if(e==="/")return t;if(!t.toLowerCase().startsWith(e.toLowerCase()))return null;let n=e.endsWith("/")?e.length-1:e.length,a=t.charAt(n);return a&&a!=="/"?null:t.slice(n)||"/"}var hpe=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function fpe(t,e="/"){let{pathname:n,search:a="",hash:i=""}=typeof t=="string"?qy(t):t,s;return n?(n=n.replace(/\/\/+/g,"/"),n.startsWith("/")?s=QH(n.substring(1),"/"):s=QH(n,e)):s=e,{pathname:s,search:xpe(a),hash:ype(i)}}function QH(t,e){let n=e.replace(/\/+$/,"").split("/");return t.split("/").forEach(i=>{i===".."?n.length>1&&n.pop():i!=="."&&n.push(i)}),n.length>1?n.join("/"):"/"}function rE(t,e,n,a){return`Cannot include a '${t}' character in a manually specified \`to.${e}\` field [${JSON.stringify(a)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function gpe(t){return t.filter((e,n)=>n===0||e.route.path&&e.route.path.length>0)}function tO(t){let e=gpe(t);return e.map((n,a)=>a===e.length-1?n.pathname:n.pathnameBase)}function nO(t,e,n,a=!1){let i;typeof t=="string"?i=qy(t):(i={...t},za(!i.pathname||!i.pathname.includes("?"),rE("?","pathname","search",i)),za(!i.pathname||!i.pathname.includes("#"),rE("#","pathname","hash",i)),za(!i.search||!i.search.includes("#"),rE("#","search","hash",i)));let s=t===""||i.pathname==="",o=s?"/":i.pathname,l;if(o==null)l=n;else{let m=e.length-1;if(!a&&o.startsWith("..")){let p=o.split("/");for(;p[0]==="..";)p.shift(),m-=1;i.pathname=p.join("/")}l=m>=0?e[m]:"/"}let c=fpe(i,l),d=o&&o!=="/"&&o.endsWith("/"),u=(s||o===".")&&n.endsWith("/");return!c.pathname.endsWith("/")&&(d||u)&&(c.pathname+="/"),c}var Mm=t=>t.join("/").replace(/\/\/+/g,"/"),bpe=t=>t.replace(/\/+$/,"").replace(/^\/*/,"/"),xpe=t=>!t||t==="?"?"":t.startsWith("?")?t:"?"+t,ype=t=>!t||t==="#"?"":t.startsWith("#")?t:"#"+t,vpe=class{constructor(t,e,n,a=!1){this.status=t,this.statusText=e||"",this.internal=a,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function wpe(t){return t!=null&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.internal=="boolean"&&"data"in t}function Spe(t){return t.map(e=>e.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var WY=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function KY(t,e){let n=t;if(typeof n!="string"||!hpe.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let a=n,i=!1;if(WY)try{let s=new URL(window.location.href),o=n.startsWith("//")?new URL(s.protocol+n):new URL(n),l=Bm(o.pathname,e);o.origin===s.origin&&l!=null?n=l+o.search+o.hash:i=!0}catch{vc(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:a,isExternal:i,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var QY=["POST","PUT","PATCH","DELETE"];new Set(QY);var _pe=["GET",...QY];new Set(_pe);var $y=y.createContext(null);$y.displayName="DataRouter";var yT=y.createContext(null);yT.displayName="DataRouterState";var kpe=y.createContext(!1),XY=y.createContext({isTransitioning:!1});XY.displayName="ViewTransition";var Npe=y.createContext(new Map);Npe.displayName="Fetchers";var Cpe=y.createContext(null);Cpe.displayName="Await";var jl=y.createContext(null);jl.displayName="Navigation";var _S=y.createContext(null);_S.displayName="Location";var Ac=y.createContext({outlet:null,matches:[],isDataRoute:!1});Ac.displayName="Route";var rO=y.createContext(null);rO.displayName="RouteError";var YY="REACT_ROUTER_ERROR",Ppe="REDIRECT",Tpe="ROUTE_ERROR_RESPONSE";function Ape(t){if(t.startsWith(`${YY}:${Ppe}:{`))try{let e=JSON.parse(t.slice(28));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.location=="string"&&typeof e.reloadDocument=="boolean"&&typeof e.replace=="boolean")return e}catch{}}function jpe(t){if(t.startsWith(`${YY}:${Tpe}:{`))try{let e=JSON.parse(t.slice(40));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string")return new vpe(e.status,e.statusText,e.data)}catch{}}function Mpe(t,{relative:e}={}){za(Vy(),"useHref() may be used only in the context of a component.");let{basename:n,navigator:a}=y.useContext(jl),{hash:i,pathname:s,search:o}=NS(t,{relative:e}),l=s;return n!=="/"&&(l=s==="/"?n:Mm([n,s])),a.createHref({pathname:l,search:o,hash:i})}function Vy(){return y.useContext(_S)!=null}function fd(){return za(Vy(),"useLocation() may be used only in the context of a component."),y.useContext(_S).location}var ZY="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function JY(t){y.useContext(jl).static||y.useLayoutEffect(t)}function Mi(){let{isDataRoute:t}=y.useContext(Ac);return t?Vpe():Epe()}function Epe(){za(Vy(),"useNavigate() may be used only in the context of a component.");let t=y.useContext($y),{basename:e,navigator:n}=y.useContext(jl),{matches:a}=y.useContext(Ac),{pathname:i}=fd(),s=JSON.stringify(tO(a)),o=y.useRef(!1);return JY(()=>{o.current=!0}),y.useCallback((c,d={})=>{if(vc(o.current,ZY),!o.current)return;if(typeof c=="number"){n.go(c);return}let u=nO(c,JSON.parse(s),i,d.relative==="path");t==null&&e!=="/"&&(u.pathname=u.pathname==="/"?e:Mm([e,u.pathname])),(d.replace?n.replace:n.push)(u,d.state,d)},[e,n,s,i,t])}var eZ=y.createContext(null);function Gy(){return y.useContext(eZ)}function Dpe(t){let e=y.useContext(Ac).outlet;return y.useMemo(()=>e&&y.createElement(eZ.Provider,{value:t},e),[e,t])}function kS(){let{matches:t}=y.useContext(Ac),e=t[t.length-1];return e?e.params:{}}function NS(t,{relative:e}={}){let{matches:n}=y.useContext(Ac),{pathname:a}=fd(),i=JSON.stringify(tO(n));return y.useMemo(()=>nO(t,JSON.parse(i),a,e==="path"),[t,i,a,e])}function Fpe(t,e){return tZ(t,e)}function tZ(t,e,n,a,i){za(Vy(),"useRoutes() may be used only in the context of a component.");let{navigator:s}=y.useContext(jl),{matches:o}=y.useContext(Ac),l=o[o.length-1],c=l?l.params:{},d=l?l.pathname:"/",u=l?l.pathnameBase:"/",m=l&&l.route;{let S=m&&m.path||"";rZ(d,!m||S.endsWith("*")||S.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${d}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. +ON值:表示"ON"的確切字串。留空以自動檢測(ON、true、1)。`,restControl:"控制",restOnUrl:"開啟 URL",restOffUrl:"關閉 URL",restOnBody:"開啟請求內容",restOffBody:"關閉請求內容",restMethod:"HTTP 方法",restHeaders:"自訂標頭(JSON)",restStatusUrl:"狀態 URL",restStatusPath:"狀態 JSON 路徑",restStatusOnValue:"ON 值",restPowerUrl:"功率URL",restPowerPath:"功率 JSON 路徑",restPowerMultiplier:"功率乘數",restEnergyUrl:"能耗URL",restEnergyPath:"能耗 JSON 路徑",restEnergyMultiplier:"能耗乘數",restUrlRequired:"REST 插座至少需要一個 URL(ON 或 OFF)",restHeadersHint:'例如:{"Authorization": "Bearer your-token"}',restBodyHint:'例如:ON、{"state": "on"}',restStatusHint:"用於輪詢目前狀態的 URL",restPathHint:"例如:state 或 data.power.status",restPowerUrlHint:"功率資料的獨立URL(留空則使用狀態URL)",restEnergyUrlHint:"能耗資料的獨立URL(留空則使用狀態URL)",restEnergyHint:"每個值可以使用獨立的URL,或回退到狀態 URL。使用乘數進行單位轉換(例如:0.001 將 Wh 轉換為 kWh)。",testConnection:"測試連線",connectionSuccess:"連線成功",noSwitchesInSwitchbar:"開關欄中沒有開關",enableSwitchbarHint:'在設定 > 智慧插座中啟用"在開關欄顯示"'},notifications:{providerTypes:{callmebot:"CallMeBot/WhatsApp",ntfy:"ntfy",pushover:"Pushover",telegram:"Telegram",email:"電子郵件",discord:"Discord",webhook:"Webhook",homeassistant:"Home Assistant"},providerDescriptions:{email:"SMTP 電子郵件通知",telegram:"透過 Telegram 機器人傳送通知",discord:"透過 Webhook 傳送到 Discord 頻道",ntfy:"免費、可自託管的推送通知",pushover:"簡單、可靠的推送通知",callmebot:"透過 CallMeBot 免費傳送 WhatsApp 通知",webhook:"通用 HTTP POST 到任意 URL",homeassistant:"Home Assistant 儀表板中的持久通知"},lastSuccess:"上次:{{date}}",error:"錯誤",printer:"印表機:",allPrinters:"所有印表機",sendTestNotification:"傳送測試通知",eventSettings:"事件設定",enabled:"已啟用",sendFromProvider:"從此提供者傳送通知",printEvents:"列印事件",printerStatus:"印表機狀態",amsAlarms:"AMS 警報",amsHtAlarms:"AMS-HT 警報",printQueue:"列印佇列",start:"開始",plateCheck:"熱床檢測",complete:"完成",failed:"失敗",stopped:"已停止",progress:"進度",offline:"離線",lowFilament:"耗材不足",maintenance:"維護",amsHumidity:"AMS 濕度",amsTemp:"AMS 溫度",amsHtHumidity:"AMS-HT 濕度",amsHtTemp:"AMS-HT 溫度",bedCooled:"熱床已冷卻",firstLayer:"首層完成",quiet:"免打擾",digest:"摘要 {{time}}",printStarted:"列印已開始",plateNotEmpty:"熱床非空",plateNotEmptyDescription:"列印前偵測到物體",printCompleted:"列印已完成",bedCooledLabel:"熱床已冷卻",bedCooledDescription:"列印後熱床溫度降至閾值以下",firstLayerCompleteLabel:"首層列印完成",firstLayerCompleteDescription:"首層完成時傳送帶照片的通知",missingSpoolAssignmentLabel:"缺少料卷分配",missingSpoolAssignmentDescription:"當列印開始且所需料盤沒有分配料卷時傳送通知",printFailed:"列印失敗",printStopped:"列印已停止",progressMilestones:"進度里程碑",progressMilestonesDescription:"在 25%、50%、75% 時通知",printerOffline:"印表機離線",printerError:"印表機錯誤",lowFilamentLabel:"耗材不足",maintenanceDue:"需要維護",maintenanceDueDescription:"需要維護時通知",amsHumidityHigh:"AMS 濕度過高",amsHumidityHighDescription:"普通 AMS 濕度超過閾值",amsTemperatureHigh:"AMS 溫度過高",amsTemperatureHighDescription:"普通 AMS 溫度超過閾值",amsHtHumidityHigh:"AMS-HT 濕度過高",amsHtHumidityHighDescription:"AMS-HT 濕度超過閾值",amsHtTemperatureHigh:"AMS-HT 溫度過高",amsHtTemperatureHighDescription:"AMS-HT 溫度超過閾值",inventoryAlerts:"庫存警報",stockReorderAlert:"補貨警報",stockReorderAlertDescription:"SKU 已達到補貨點",stockBreakAlert:"斷貨警報",stockBreakAlertDescription:"庫存將在補貨到達前耗盡",jobAdded:"任務已新增",jobAddedDescription:"任務已新增到佇列",jobAssigned:"任務已分配",jobAssignedDescription:"基於模型的任務已分配給印表機",jobStarted:"任務已開始",jobStartedDescription:"佇列任務已開始列印",jobWaiting:"任務等待中",jobWaitingDescription:"任務正在等待耗材或印表機",jobSkipped:"任務已跳過",jobSkippedDescription:"任務已跳過(上一個失敗)",jobFailed:"任務失敗",jobFailedDescription:"任務啟動失敗",queueComplete:"佇列已完成",queueCompleteDescription:"所有佇列任務已完成",quietHours:"免打擾時段",noNotificationsDuring:"在此時段內不傳送通知",editProviderToChangeQuietHours:"編輯提供者以更改免打擾時段",dailyDigest:"每日摘要",batchNotifications:"將通知彙總為每日摘要",sendAt:"傳送於 {{time}}",editProviderToChangeDigestTime:"編輯提供者以更改摘要時間",edit:"編輯",deleteProvider:"刪除通知提供者",deleteConfirm:'確定要刪除"{{name}}"嗎?此操作無法復原。',delete:"刪除",addTitle:"新增通知提供者",editTitle:"編輯通知提供者",nameLabel:"名稱 *",namePlaceholder:"我的通知",providerTypeLabel:"提供者類型 *",configuration:"設定",testConfiguration:"測試設定",printerFilter:"印表機篩選",onlyFromPrinter:"僅傳送來自此印表機的事件通知",quietHoursDnd:"免打擾時段",quietStart:"開始",quietEnd:"結束",dailyDigestLabel:"每日摘要",sendDigestAt:"傳送摘要於",digestCollected:"事件將被收集並在此時間作為單條摘要傳送",notificationEvents:"通知事件",progressPercent:"(25%、50%、75%)",bedCooledAfterPrint:"(列印完成後)",eventPriority:{sectionTitle:"ntfy 優先級",helpNtfy:"為每個已啟用的事件選擇優先級。ntfy 使用它來升級提醒(聲音、可見性、推播行為)。此處未設定的級別將使用 ntfy 伺服器預設值。",min:"最低",low:"低",default:"預設",high:"高",urgent:"緊急"},cancel:"取消",save:"儲存",add:"新增",nameRequired:"名稱為必填項",fieldRequired:"{{field}}為必填項",phoneNumber:"電話號碼",apiKey:"API 金鑰",serverUrl:"伺服器 URL",topic:"主題",authToken:"認證權杖",userKey:"使用者金鑰",appToken:"應用程式權杖",priority:"優先順序",botToken:"機器人權杖",chatId:"聊天 ID",smtpServer:"SMTP 伺服器",smtpPort:"SMTP 連接埠",security:"安全",authentication:"認證",username:"使用者名稱",password:"密碼",fromEmail:"寄件人信箱",toEmail:"收件人信箱",webhookUrl:"Webhook URL",payloadFormat:"負載格式",authorization:"授權",titleFieldName:"標題欄位名",messageFieldName:"訊息欄位名",editTemplate:"編輯範本:{{name}}",titleLabel:"標題",bodyLabel:"正文",titlePlaceholder:"通知標題...",bodyPlaceholder:"通知正文...",availableVariables:"可用變數",clickToInsert:"點選插入到正文游標位置",livePreview:"即時預覽",hide:"隱藏",show:"顯示",loadingPreview:"載入預覽中...",enterTemplateContent:"輸入範本內容以檢視預覽",titlePreview:"標題:",bodyPreview:"正文:",resetToDefault:"恢復預設",titleRequired:"標題為必填項",bodyRequired:"正文為必填項",notificationLog:"通知日誌",showFailedOnly:"僅顯示失敗",last24Hours:"最近 24 小時",last7Days:"最近 7 天",last30Days:"最近 30 天",last90Days:"最近 90 天",justNow:"剛剛",noFailedNotifications:"沒有失敗的通知",noNotificationsLogged:"沒有通知紀錄",unknownProvider:"未知提供者",logTitle:"標題",logMessage:"訊息",logError:"錯誤",logProvider:"提供者:{{type}}",logTime:"時間:{{time}}",refresh:"重新整理",clearOld:"清除舊紀錄",statsSummary:"最近 {{days}} 天:",statsNotifications:"條通知",statsSent:"{{count}} 條已傳送",statsFailed:"{{count}} 條失敗",eventTypes:{print_start:"列印已開始",print_complete:"列印完成",print_failed:"列印失敗",print_stopped:"列印已停止",print_progress:"進度",printer_offline:"印表機離線",printer_error:"印表機錯誤",filament_low:"耗材不足",maintenance_due:"需要維護",test:"測試"},userEmail:{title:"通知",emailNotifications:"郵件通知",emailNotificationsDesc:"接收您自己列印任務的郵件通知。郵件將透過進階身份驗證中設定的 SMTP 設定傳送。",sendingTo:"通知將傳送至",noEmailWarning:"您的帳戶沒有郵件地址。請聯絡管理員新增。",printJobNotifications:"列印任務通知",printJobNotificationsDesc:"選擇哪些事件會觸發您提交的列印任務的郵件通知。",printJobStarts:"列印任務開始",printJobStartsDesc:"當您的列印任務開始時收到通知。",printJobFinishes:"列印任務完成",printJobFinishesDesc:"當您的列印任務成功完成時收到通知。",printErrors:"列印錯誤",printErrorsDesc:"當您的列印任務失敗或遇到錯誤時收到通知。",printJobStops:"列印任務停止",printJobStopsDesc:"當您的列印任務被取消或停止時收到通知。",saveSuccess:"通知偏好設定已儲存。",saveError:"儲存通知偏好設定失敗。"}},richTextEditor:{bold:"粗體",italic:"斜體",underline:"底線",bulletList:"無序列表",numberedList:"有序列表",alignLeft:"左對齊",alignCenter:"居中對齊",alignRight:"右對齊",addLink:"新增連結",removeLink:"移除連結"},externalLinks:{noLinksConfigured:"未設定外部連結",deleteLink:"刪除連結",removeCustomIcon:"移除自訂圖示",openInNewTab:"在新標籤頁中開啟",placeholders:{linkName:"我的連結"}},keyboardShortcuts:{title:"鍵盤快捷鍵",navigation:"導航",archivesSection:"歸檔",kProfilesSection:"K 值設定",generalSection:"通用",shortcuts:{goToPrinters:"前往印表機",goToArchives:"前往歸檔",goToQueue:"前往佇列",goToStats:"前往統計",goToProfiles:"前往雲端設定",goToSettings:"前往設定",focusSearch:"聚焦搜尋",openUploadModal:"開啟上傳對話方塊",clearSelection:"清除選擇 / 取消焦點",contextMenu:"卡片右鍵選單",refreshProfiles:"重新整理設定",newProfile:"新增設定",exitSelectionMode:"結束選擇模式",showHelp:"顯示此協助"},footer:"按 Esc 或點選外部關閉"},notificationLog:{title:"通知日誌",events:{printStarted:"列印開始",printComplete:"列印完成",printFailed:"列印失敗",printStopped:"列印停止",progress:"進度",printerOffline:"印表機離線",printerError:"印表機錯誤",lowFilament:"耗材不足",maintenanceDue:"維護到期",test:"測試"},timeAgo:{justNow:"剛剛",minutesAgo:"{{minutes}} 分鐘前",hoursAgo:"{{hours}} 小時前"}},restoreBackup:{title:"恢復備份",restoring:"恢復中...",restoreComplete:"恢復完成",restoreFailed:"恢復失敗",importSettings:"從備份檔案匯入設定",pleaseWait:"請稍候,正在恢復您的資料",clickToSelect:"點選選擇備份檔案(.json 或 .zip)",howDuplicateHandling:"重複處理方式:",categories:{printers:"印表機",smartPlugs:"智慧插座",notificationProviders:"通知提供者",filaments:"耗材",archives:"歸檔",pendingUploads:"待處理上傳",settingsTemplates:"設定和範本"},matchingInfo:{printers:"按序列號匹配",smartPlugs:"按 IP 位址匹配",notificationProviders:"按名稱匹配",filaments:"按名稱 + 類型 + 品牌匹配",archives:"按內容雜湊匹配",pendingUploads:"按檔名匹配",settingsTemplates:"始終覆蓋"},replaceExisting:"替換現有資料",keepExisting:"保留現有資料",replaceDescription:"用備份資料覆蓋已存在的項目",keepDescription:"僅恢復不存在的項目",caution:"注意:",cautionText:"覆蓋將用備份資料替換您目前的設定。出於安全考慮,印表機存取碼永遠不會被覆蓋。",itemsRestored:"已恢復項目",itemsSkipped:"已跳過項目",restored:"已恢復",skipped:"已跳過(已存在)",filesLabel:"檔案(3MF、縮圖等)",newApiKeysGenerated:"已產生新 API 金鑰",newApiKeysWarning:"這些金鑰僅顯示一次。請立即複製!",processingBackup:"處理備份檔案中...",noDataFound:"備份檔案中未找到可恢復的資料。",failedToRestore:"恢復備份失敗。請檢查檔案格式。"},backupExport:{title:"匯出備份",selectData:"選擇要包含的資料",selectAll:"全選",selectNone:"全不選",categoryDescriptions:{settings:"語言、主題、更新偏好",notifications:"ntfy、Pushover、Discord 等",templates:"自訂訊息範本",smartPlugs:"Tasmota 插座設定",externalLinks:"側邊欄外部服務連結",printers:"印表機資訊(不含存取碼)",plateDetection:"空列印板參考影像",filaments:"耗材類型和成本",maintenance:"自訂維護計畫",archives:"所有列印資料 + 檔案(3MF、縮圖、照片)",projects:"專案、材料清單和附件",pendingUploads:"虛擬印表機待審核的上傳",apiKeys:"Webhook API 金鑰(匯入時產生新金鑰)"},requiresPrinters:"需要選擇印表機",zipFileWarning:"將建立 ZIP 檔案。",zipFileDescription:"包括所有 3MF 檔案、縮圖、縮時攝影和照片。這可能需要一些時間並產生較大的檔案。",includeAccessCodes:"包含存取碼",includeAccessCodesDescription:"用於轉移到另一臺機器",includeAccessCodesWarning:"存取碼將以明文形式包含。請妥善保管此備份檔案!",categoriesSelected:"已選擇 {{selectedCount}} 個類別"},pendingUploads:{placeholders:{notes:"新增關於此列印的備註..."},discardUpload:"丟棄上傳",archiveAllUploads:"歸檔所有上傳",discardAllUploads:"丟棄所有上傳",archive:"歸檔",timeAgo:{justNow:"剛剛",minutesAgo:"{{minutes}} 分鐘前",hoursAgo:"{{hours}} 小時前",daysAgo:"{{days}} 天前"}},apiBrowser:{placeholders:{requestBody:"JSON 請求體...",searchEndpoints:"搜尋端點..."}},configureAmsSlot:{title:"設定 AMS 槽位",slotConfigured:"槽位已設定!",configuringSlot:"正在設定槽位:",slotLabel:"{{ams}} 槽位 {{slot}}",searchPresets:"搜尋預設...",colorPlaceholder:"顏色名稱或十六進位(例如:棕色、FF8800)",clearCustomColor:"清除自訂顏色",noCloudPresets:"無雲端預設。登入拓竹雲以同步。",noPresetsAvailable:"無可用預設。登入拓竹雲或匯入本機設定。",noMatchingPresets:"未找到匹配的預設。",custom:"自訂",builtin:"內建",settingsSentToPrinter:"設定已傳送到印表機",filamentProfile:"耗材設定",kProfileLabel:"K 值設定(壓力推進)",filteringFor:"篩選:{{material}}",noKProfile:"無 K 值設定(使用預設值 0.020)",noMatchingKProfiles:"未找到匹配的 K 值設定。將使用預設 K=0.020。",selectFilamentFirst:"請先選擇耗材設定",kFromCalibration:"K={{value}}(來自印表機校準)",customColorLabel:"自訂顏色(可選)",presetColors:"{{name}} 顏色:",showLessColors:"顯示更少顏色",showMoreColors:"顯示更多顏色",clear:"清除",hexLabel:"十六進位:#{{hex}}",resetting:"重設中...",resetSlot:"重設槽位",cancel:"取消",configuring:"設定中...",configureSlot:"設定槽位"},githubBackup:{title:"Git 備份",history:"歷史",downloadBackup:"下載備份",restoreBackup:"恢復備份",noBackupsYet:"尚無備份"},emailSettings:{placeholders:{fromName:"Bambuddy"}},tagManagement:{searchTags:"搜尋標籤...",renameTag:"重新命名標籤",deleteTag:"刪除標籤"},notificationTemplates:{placeholders:{title:"通知標題...",body:"通知正文..."}},batchTag:{placeholders:{newTag:"輸入新標籤..."}},photoGallery:{deletePhoto:"刪除照片"},filamentHoverCard:{copySpoolUuid:"複製耗材 UUID"},kProfilesView:{hasNote:"有備註",copyProfile:"複製設定"},layout:{openMenu:"開啟選單",noPermissionSystemInfo:"您沒有檢視系統資訊的權限"},dashboard:{dragToReorder:"拖曳以重新排列",hideWidget:"隱藏小工具"},notificationProviderCard:{deleteNotificationProvider:"刪除通知提供者"},fileManagerModal:{closeFileManager:"關閉檔案管理器",sortFiles:"排序檔案",goToParentFolder:"返回上級資料夾",threeView:"3D 檢視"},embeddedCameraViewer:{refreshStream:"重新整理流",close:"關閉",zoomOut:"縮小",resetZoom:"重設縮放",zoomIn:"放大",dragToResize:"拖曳調整大小"},timelapseViewer:{skipBack5s:"後退 5 秒",skipForward5s:"前進 5 秒"},notificationProviders:{descriptions:{email:"SMTP 郵件通知",telegram:"透過 Telegram 機器人通知",discord:"透過 Webhook 傳送到 Discord 頻道",ntfy:"免費、可自託管的推送通知",pushover:"簡單、可靠的推送通知",callmebot:"透過 CallMeBot 的免費 WhatsApp 通知",webhook:"通用 HTTP POST 到任意 URL"}},logViewer:{searchPlaceholder:"搜尋訊息或日誌名稱...",noLogEntries:"未找到日誌條目"},switchbarPopover:{noSwitchesInSwitchbar:"切換欄中沒有開關"},projectPageModal:{placeholders:{title:"標題",designer:"設計師",license:"許可證",description:"輸入描述...",profileTitle:"設定標題",profileDescription:"設定描述..."}},spoolmanSettings:{},time:{unknown:"-",waiting:"等待中",justNow:"剛剛",now:"現在",minsAgo:"{{count}} 分鐘前",inMins:"{{count}} 分鐘後",hoursAgo:"{{count}} 小時前",inHours:"{{count}} 小時後",daysAgo:"{{count}} 天前",inDays:"{{count}} 天後"},spoolbuddy:{nav:{dashboard:"儀表板",ams:"AMS",inventory:"庫存",writeTag:"寫入",settings:"設定"},status:{nfcReady:"NFC 就緒",nfcOff:"NFC 關閉",offline:"離線",online:"線上",noPrinters:"無印表機",deviceOffline:"裝置離線",waitingConnection:"等待裝置連線...",systemReady:"系統就緒",status:"狀態"},dashboard:{readyToScan:"準備掃描",idleMessage:"將耗材放在磅秤上以識別",nfcHint:"NFC 標籤將自動讀取",device:"裝置",syncWeight:"同步重量",weightSynced:"已同步!",unknownTag:"未知標籤",newTag:"偵測到新標籤",onScale:"在磅秤上",linkSpool:"連結到耗材",linkTagTitle:"將標籤連結到耗材",linkTag:"連結標籤",selectSpool:"選擇要連結此標籤的耗材:",noUntagged:"未找到沒有標籤的耗材",tagDetected:"偵測到標籤",noTag:"無標籤",tagId:"標籤",grossWeight:"毛重",spoolSize:"耗材盤尺寸",close:"關閉",currentSpool:"目前耗材",plateReady:"熱床就緒: {{name}}",plateReadyLabel:"待清理的熱床",plateClearAction:"清理",plateClearedToast:"已將熱床標記為已清理",plateClearFailed:"無法將熱床標記為已清理"},modal:{spoolDetected:"偵測到耗材",assignToAms:"分配到 AMS",syncWeight:"同步重量",weightSynced:"已同步!",syncing:"同步中...",newTagDetected:"偵測到新標籤",addToInventory:"新增到庫存",assignToAmsTitle:"分配到 AMS",selectSlot:"選擇槽位",assign:"分配",assigning:"分配中...",assignSuccess:"已分配!",assignPendingInsert:"已分配。插入耗材後將設定槽位。",assignError:"分配耗材失敗。請重試。",noPrinterSelected:"選擇印表機...",noAmsDetected:"此印表機未偵測到 AMS",slot:"槽位"},weight:{noReading:"無讀數",stable:"穩定",measuring:"測量中...",tare:"去皮",calibrate:"校準"},spool:{remaining:"剩餘",material:"材料",brand:"品牌",color:"顏色",coreWeight:"軸心重",labelWeight:"標籤重",scaleWeight:"磅秤重",netWeight:"淨重",lastUsed:"上次使用"},ams:{noData:"未偵測到 AMS",connectAms:"連線 AMS 以檢視耗材槽位",noPrinter:"未選擇印表機",selectPrinter:"從頂部欄選擇印表機",printerDisconnected:"印表機已斷開",humidity:"濕度",level:"餘量",active:"活躍",slot:"槽位",empty:"空"},inventory:{search:"搜尋耗材...",empty:"庫存中沒有耗材",noResults:"沒有匹配的耗材",spools:"個耗材",addSpool:"新增耗材"},settings:{tabDevice:"裝置",tabDisplay:"顯示",tabScale:"磅秤",tabUpdates:"更新",nfcReader:"NFC 讀卡器",type:"類型",connection:"連線",notConnected:"不適用",deviceInfo:"裝置資訊",hostname:"主機",uptime:"執行時間",systemConfig:"後端與認證",backendUrl:"Bambuddy 後端 URL",apiToken:"API 權杖",apiTokenPlaceholder:"輸入 API 權杖",saveConfig:"儲存設定",systemQueued:"設定已加入佇列。",nfcDiagnostic:"NFC 診斷",scaleDiagnostic:"磅秤診斷",readTagDiagnostic:"讀取標籤診斷",testNfc:"測試讀卡器",testScale:"測試精度",testReadTag:"讀取標籤",systemFieldsRequired:"後端 URL 為必填項。",brightness:"亮度",saved:"已儲存",noBacklight:"未偵測到 DSI 背光。亮度控制需要 DSI 螢幕。",screenBlank:"螢幕熄滅超時",screenBlankDesc:"不活動後螢幕關閉。觸控喚醒。",displayNote:"亮度作為軟體濾鏡套用。",scaleCalibration:"磅秤校準",currentWeight:"目前重量",tareOffset:"去皮",calFactor:"係數",knownWeight:"已知重量",calStep1:"移除磅秤上所有物品並按設定零點。",calStep2:"將已知重量放在磅秤上。",setZero:"設定零點",calibrateNow:"校準",calibrated:"已校準",tareSet:"去皮命令已傳送。等待裝置回應...",tareFailed:"傳送去皮命令失敗",zeroSet:"零點已設定。將已知重量放在磅秤上。",calibrationDone:"校準完成!",calibrationFailed:"校準失敗",lastCalibrated:"上次校準",stable:"穩定",settling:"穩定中...",firmware:"韌體",scale:"磅秤",noDevice:"未找到 SpoolBuddy 裝置",daemonVersion:"守護程式版本",currentVersion:"目前",versionPending:"等待守護程式...",checking:"檢查中...",checkUpdates:"檢查更新",updateAvailable:"有可用更新",updateInstructions:"透過 SSH 更新:執行 SpoolBuddy 安裝腳本進行升級。",upToDate:"已是最新",includeBeta:"包含測試版本"},writeTag:{tabExisting:"現有耗材",tabNew:"新耗材",tabReplace:"替換標籤",searchPlaceholder:"按材料、顏色、品牌搜尋...",noUntaggedSpools:"沒有無標籤的耗材",noTaggedSpools:"沒有有標籤的耗材",selectSpool:"選擇一個耗材,然後將空白 NTAG 放在讀卡器上",placeTag:"將 NTAG 放在讀卡器上",tagReady:"偵測到標籤 — 準備寫入",writeTag:"寫入標籤",replaceTag:"替換標籤",writing:"寫入標籤中...",waiting:"等待 SpoolBuddy...",writeSuccess:"標籤寫入成功!",writeFailed:"寫入失敗",queueFailed:"佇列寫入命令失敗",tryAgain:"重試",cancel:"取消",replaceWarning:"舊標籤將被取消連結。新標籤將替換它。",deviceOffline:"SpoolBuddy 離線",material:"材料",colorName:"顏色名稱",color:"顏色",brand:"品牌",weight:"重量 (g)",createSpool:"建立耗材",creating:"建立中...",spoolCreated:"耗材已建立!準備寫入。",createFailed:"建立耗材失敗",incompleteDataWarning:"已使用不完整的Spoolman資料寫入標籤"},quickMenu:{printerPower:"印表機電源",systemControls:"系統",restartDaemon:"重新啟動守護程式",restartBrowser:"重新啟動瀏覽器",reboot:"重新開機",shutdown:"關機",swipeToClose:"向下滑動關閉",confirmTitle:"確認",confirmShutdown:"確定要關閉 SpoolBuddy 嗎?您需要實體存取才能重新開啟。",confirmReboot:"確定要重新開機 SpoolBuddy 嗎?",confirmRestartDaemon:"重新啟動 SpoolBuddy 守護程式?NFC 和磅秤將暫時不可用。",confirmRestartBrowser:"重新啟動kiosk瀏覽器?螢幕將短暫變黑。",confirm:"確認",confirmPlugOn:"開啟 {{name}}?",confirmPlugOff:"關閉 {{name}}?",turnOn:"開啟",turnOff:"關閉"}},bugReport:{title:"報告錯誤",description:"描述",descriptionPlaceholder:"出了什麼問題?請描述問題...",email:"信箱(可選)",emailPlaceholder:"your@email.com",emailPrivacy:"如果提供,您的信箱將包含在GitHub Issue的摺疊部分中,以便維護者後續跟進。",screenshot:"截圖",uploadOrPaste:"上傳、貼上或拖曳圖片",dataCollectedSummary:"報告中包含哪些資料?",dataIncluded:"包含:",dataIncludedList:"應用程式版本、作業系統、架構、Python版本、資料庫統計(僅計數)、印表機型號、噴嘴數量、韌體版本、連線狀態、整合狀態(Spoolman、MQTT、HA)、非敏感設定、網路介面數量、Docker詳情、依賴版本。",dataNeverIncluded:"絕不包含:",dataNeverIncludedList:"印表機名稱、序列號、存取碼、密碼、IP 位址、信箱地址、API金鑰、權杖、Webhook URL、主機名稱或使用者名稱。",submit:"提交",startLogging:"開始偵錯日誌",stepEnableLogging:"偵錯日誌已啟用",stepReproduce:"請現在重現問題",stepStopLogging:"停止並提交報告",stopAndSubmit:"停止並提交",maxDuration:"{{minutes}} 分鐘後自動停止",stoppingLogs:"正在收集日誌並提交...",submitting:"正在提交錯誤報告...",submitSuccess:"錯誤報告提交成功!",submitFailed:"提交錯誤報告失敗",thankYou:"謝謝!",submitted:"您的錯誤報告已提交。",viewIssue:"檢視 Issue",unexpectedError:"發生了意外錯誤"},failureDetection:{title:"AI 故障檢測",description:"透過自託管的 Obico ML API 監控列印,並對偵測到的故障自動採取行動。",mlUrl:"Obico ML API 地址",mlUrlHint:"您自託管的 Obico ml_api 容器的基礎 URL(例如 http://192.168.1.10:3333)。",test:"測試",testSuccess:"ML API 可存取且正常。",testFailed:"無法存取 ML API。",sensitivity:"靈敏度",sensitivityLow:"低(減少誤報)",sensitivityMedium:"中(平衡)",sensitivityHigh:"高(更早檢測,更多誤報)",sensitivityHint:"調整觸發警告和故障的置信度閾值。",action:"偵測到故障時的操作",actionNotify:"僅通知",actionPause:"暫停列印",actionPauseOff:"暫停並切斷電源",pollInterval:"檢查間隔(秒)",pollIntervalHint:"列印過程中每臺印表機的檢查頻率。最小 5 秒,最大 120 秒。",externalUrlMissing:"尚未設定外部 URL。",externalUrlHint:"ML API 透過 URL 擷取攝影機快照。請在一般設定中設定外部 URL,讓 ML API 容器可以連線到 Bambuddy。",perPrinterTitle:"監控的印表機",perPrinterHint:"選擇檢測服務要監視哪些印表機。",monitorAll:"監控所有已連線的印表機",statusTitle:"狀態",serviceRunning:"服務執行中",thresholds:"低 / 高閾值",activePrinters:"活動列印",noActivePrints:"目前沒有正在進行的列印。",historyTitle:"最近檢測",noHistory:"尚無檢測紀錄。"},makerworld:{title:"MakerWorld",description:"貼上 MakerWorld 模型連結,即可直接在 Bambuddy 中匯入並列印 —— 無需切換至 Bambu Handy 應用程式。",pasteUrlHeader:"從 MakerWorld 匯入",pasteUrlPlaceholder:"https://makerworld.com/en/models/… 或貼上任意 MakerWorld 連結",resolveButton:"解析",signInRequiredTitle:"下載需要登入 Bambu Cloud",signInRequiredBody:"您可以匿名瀏覽模型詳情,但下載 3MF 檔案需要 Bambu Cloud 帳戶。",openCloudSettings:"開啟雲端設定",untitledModel:"無標題模型",byCreator:"作者: {{name}}",downloadsCount:"{{count}} 次下載",licensePrefix:"授權條款",alreadyImported:"已在資料庫中",openOnMakerworld:"在 MakerWorld 中開啟",alreadyInLibrary:"此模型已在您的資料庫中 —— 可在檔案管理員 → MakerWorld 中找到",importSuccess:"已匯入 {{filename}} —— 已儲存至檔案管理員 → MakerWorld",platesHeader:"列印板 ({{count}})",plateDefaultName:"列印板 {{n}}",materialCount:"{{count}} 種耗材",amsRequired:"需要 AMS",slicedFor:"為 {{printer}} 切片",alsoCompatible:"還標記為相容:{{printers}}",importToLibrary:"儲存",sliceIn:"儲存並在 {{slicer}} 中切片",disclaimer:"MakerWorld 整合使用由社群記錄的 API 介面。Bambuddy 與 MakerWorld 或 Bambu Lab 無從屬或認可關係。",lastImportSuccess:"已匯入您的資料庫",lastImportAlreadyInLibrary:"已存在於您的資料庫中",viewInLibrary:"在檔案管理員中查看",openInBambuStudio:"在 Bambu Studio 中開啟",openInOrcaSlicer:"在 OrcaSlicer 中開啟",importTo:"匯入至檔案管理員",recentImportsHeader:"最近匯入",phaseResolving:"解析中",phaseDownloading:"下載中",folderAuto:"MakerWorld (預設)",importAll:"全部匯入",importAllProgress:"正在匯入 {{current}}/{{total}}",openGallery:"開啟圖片庫",galleryPrev:"上一張",galleryNext:"下一張",deleteImport:"從資料庫中移除",importDeleting:"正在移除…",importDeleted:"已從資料庫中移除",confirmDelete:"從資料庫中移除 {{filename}}?本機檔案將被刪除,但可以從 MakerWorld 重新匯入。",errors:{resolveFailed:"無法解析該 MakerWorld 連結。",downloadFailed:"下載失敗。請重試。",deleteFailed:"無法從資料庫中移除檔案。"}},gcodeViewer:{back:"返回",backToArchives:"返回列印歸檔",backToFiles:"返回檔案管理器"},libraryTrash:{title:"資源回收筒",headerButton:"資源回收筒",headerTooltip:"檢視已移至資源回收筒的檔案",backToFiles:"返回檔案管理員",subtitleAdmin:"已刪除的檔案會在資源回收筒保留 {{days}} 天,之後自動刪除。此檢視顯示所有使用者的資源回收筒。",subtitleUser:"已刪除的檔案會在資源回收筒保留 {{days}} 天,之後自動刪除。",loading:"正在載入資源回收筒…",loadError:"無法載入資源回收筒。",empty:"資源回收筒是空的。",summary:"{{count}} 個檔案 · {{size}}",emptyTrash:"清空資源回收筒",restore:"還原",purgeNow:"立即刪除",autoPurgeIn:"將於 {{when}} 自動刪除",days:"天",retentionLabel:"自動刪除時間",selectAll:"全選",selectOne:"選擇 {{filename}}",selectionCount:"已選擇 {{count}} 項",bulkRestore:"還原所選",bulkPurge:"刪除所選",col:{filename:"檔案",folder:"資料夾",size:"大小",deleted:"移入資源回收筒",autoPurge:"自動刪除",owner:"擁有者",actions:"操作"},confirm:{purgeTitle:"永久刪除?",purgeBody:"{{filename}} 將從磁碟中刪除,無法還原。",emptyTitle:"清空資源回收筒?",emptyBody:"全部 {{count}} 個檔案將從磁碟中刪除。此操作無法復原。",bulkPurgeTitle:"永久刪除所選檔案?",bulkPurgeBody:"所選的 {{count}} 個檔案將從磁碟中刪除,無法還原。",cta:"永久刪除"},toast:{restored:"檔案已還原。",restoreFailed:"無法還原檔案。",purged:"檔案已永久刪除。",purgeFailed:"無法刪除檔案。",emptied:"已從資源回收筒刪除 {{count}} 個檔案。",emptyFailed:"無法清空資源回收筒。",retentionSaved:"自動刪除已設定為 {{days}} 天。",retentionFailed:"無法儲存保留設定。",bulkRestored:"已還原 {{count}} 個檔案。",bulkPurged:"已刪除 {{count}} 個檔案。"}},libraryPurge:{title:"清理舊檔案",headerButton:"清理舊檔案",headerTooltip:"批次將舊檔案移至資源回收筒",description:"早於所選時間的檔案將被移至資源回收筒。外部資料夾會被略過。在自動刪除之前,您可以從資源回收筒還原檔案。",ageLabel:"移動早於以下天數的檔案",days:"天",includeNeverPrinted:"包括從未列印過的檔案",effectsTitle:"點擊清除時會發生什麼",effect1:"符合的檔案移至回收筒 — 尚未從磁碟刪除。",effect2:"在保留期到期之前,您可以隨時從回收筒復原。",effect3:"保留期滿後,回收筒清理器將它們從磁碟永久刪除。",effect4:"外部(連結)資料夾中的檔案將被略過 — Bambuddy 從不刪除不屬於自己的位元組。",previewLoading:"正在檢查符合的檔案數量…",previewFailed:"無法預覽清理結果。",previewSummary:"{{count}} 個檔案 · {{size}} 將被移至資源回收筒",andMore:"…還有 {{count}} 個",warning:"檔案將被軟刪除——在保留期結束前,您可以從資源回收筒還原它們。",confirmCta:"將 {{count}} 個移至資源回收筒",purging:"正在移至資源回收筒…",toast:{success:"已將 {{count}} 個檔案移至資源回收筒。",failed:"無法清理檔案。"}},libraryAutoPurge:{enableLabel:"自動清理舊檔案",enableDescription:"每天執行一次管理員清理。檔案會先進入資源回收筒——不會立即刪除。",ageLabel:"自動清理早於以下天數的檔案",ageDescription:"最少 7 天,最多 10 年。使用與手動「清理舊檔案」按鈕相同的時間規則。",days:"天",includeNeverPrinted:"包括從未列印過的檔案",saveFailed:"無法儲存自動清理設定。"},archivePurge:{headerButton:"清除舊條目",headerTooltip:"批次刪除舊歸檔",title:"清除舊歸檔",description:"清除舊的列印歷史。每個歸檔按其最近一次列印完成時間老化 — 重新列印歸檔會重新整理其年齡,因此活躍工作永遠不會被清除。",ageLabel:"刪除最近未列印的歸檔:",days:"天",effectsTitle:"點擊清除時會發生什麼",effect1:"每個符合的歸檔將從清單中隱藏,其磁碟檔案(3MF、縮圖、縮時攝影、原始 3MF、F3D、照片)也會被刪除。",effect2:"資料庫中的歸檔記錄會保留,因此 Quick Stats 仍可計入耗材、時間、成本與能耗的貢獻 — 與單筆刪除的預設行為一致。",effect3:"勾選下方「同時從統計中移除」,可一併清除 Quick Stats 中的貢獻(等同單筆刪除選項)。此操作無法復原。",effect4:"重新列印歸檔會重新整理其使用計時器,因此仍在使用的歸檔不會被清除。",purgeStatsLabel:"同時從統計中移除",purgeStatsHint:"從 Quick Stats(耗材、時間、成本、能耗)中移除符合的歸檔。未勾選時,Quick Stats 會保留所有貢獻,僅檔案從磁碟刪除。",previewLoading:"檢查符合的歸檔數量…",previewFailed:"無法預覽清除。",previewSummary:"將移除 {{count}} 個歸檔 · {{size}}",andMore:"…還有 {{count}} 個",warning:"檔案會從磁碟刪除且無法復原。繼續前請下載或收藏您想保留的內容。",confirmCta:"移除 {{count}} 個歸檔",purging:"移除中…",toast:{success:"已移除 {{count}} 個歸檔。",failed:"無法清除歸檔。"}},archiveAutoPurge:{enableLabel:"自動清除舊歸檔",enableDescription:"每天一次,將閾值內未列印的歸檔從清單中隱藏,並從磁碟中刪除其檔案。重新列印會重設計時器。",ageLabel:"自動刪除最近未列印的歸檔:",ageDescription:"最少 7 天,最多 10 年。基於最近一次列印完成 — 重新列印會重新整理年齡。刪除 3MF、縮圖、縮時攝影、原始 3MF、F3D 與照片。",days:"天",purgeStatsLabel:"同時從統計中移除",purgeStatsDescription:"啟用後,每日清理任務還會將每個被清除的歸檔從 Quick Stats(耗材、時間、成本、能耗)中移除。預設關閉 — Quick Stats 會保留貢獻,僅檔案從磁碟刪除。",runNow:"立即清除歸檔",saveFailed:"無法儲存自動清除設定。"},cameraTokens:{title:"攝影機 API 權杖",navTitle:"攝影機 API 權杖",description:"長期權杖,用於將攝影機串流嵌入 Home Assistant、Frigate、資訊站或其他需要穩定 URL 的工具。每個權杖僅限攝影機串流,可隨時撤銷。",loading:"載入中…",confirmRevoke:{title:"撤銷此權杖?",body:"使用「{{name}}」的任何裝置將立即失去存取權限。此操作無法復原。",cancel:"取消",confirm:"撤銷"},create:{title:"建立新權杖",nameLabel:"權杖名稱",namePlaceholder:"例如 Home Assistant",daysLabel:"到期天數",submit:"建立",hint:"最大有效期 365 天。權杖值僅在建立時顯示一次 — 請立即複製。"},created:{title:"權杖已建立 — 立即複製",warning:"這是此權杖唯一一次可見。關閉此對話框後您將無法再次查看。",copy:"複製",dismiss:"我已儲存"},list:{myTitle:"我的權杖",allTitle:"所有使用者(管理員視圖)",empty:"尚無權杖。",name:"名稱",owner:"擁有者",prefix:"前綴",created:"建立時間",expires:"到期時間",lastUsed:"最近使用",revoke:"撤銷",expired:"已過期"},toast:{created:"權杖已建立",createFailed:"建立權杖失敗",revoked:"權杖已撤銷",revokeFailed:"撤銷權杖失敗",loadFailed:"載入權杖失敗",copied:"已複製到剪貼簿",copyFailed:"複製失敗 — 手動選擇並複製"}},forecast:{title:"庫存預測",noSpools:"未找到活躍的料卷。請將料卷新增至庫存以查看預測資料。",noUsageData:"無可用使用資料 — 無法預測庫存時間線。",sku:"SKU",material:"材料",stock:"庫存",dailyRate:"消耗率",daysLeft:"剩餘天數",emptyBy:"耗盡日期",reorderBy:"補貨截止日",actions:"操作",trend:"趨勢",estimated:"估算",noData:"無資料",timeframe:"時間範圍",chartTitle:"庫存預測 — 前5種材料",dashedLinesROP:"虛線 = 再訂貨點",stockLevel:"庫存量",reorderPoint:"再訂購點",safetyMargin:"安全餘量",trendLegend:"趨勢(基於歷史,95%服務水準)",estimatedLegend:"估算(重量差值)",noDataLegend:"無資料",ropLabel:"再訂貨點",ssLabel:"安全庫存",safetyStockLegend:"安全庫存",stockArrivalLegend:"到貨",stockoutLegend:"斷貨",alertCount_one:"{{count}}條警告",alertCount_other:"{{count}}條警告",order:"訂購",globalLeadTime:"全域交貨期",globalLeadTimeHint:"全域交貨期下限 — 用於所有 SKU 的再訂購點計算",save:"儲存",cancel:"取消",settingsSaved:"設定已儲存",failedSaveSettings:"儲存設定失敗",globalLeadTimeSaved:"全域提前期已儲存",skuLeadTimeOverride:"SKU 交貨期覆蓋",skuLeadTimeHint:"0 = 使用全域交貨期。設定 >0 以覆蓋此 SKU。",safetyMarginLabel:"安全餘量",effectiveLeadTime:"有效交貨期",effectiveLeadTimeHint:"max(全域 {{global}}天, SKU {{sku}}天)",reorderPointHint:"d̄ × LT + safety margin — 當庫存降至此水準時下單",safetyMarginHint:"統計安全庫存 (z=1.65 × σ × √LT) + 使用者自訂緩衝",safetyMarginHintDays:"在統計安全庫存基礎上額外增加的緩衝。{{approx}}",safetyMarginHintDaysApprox:" ≈ 按當前速率 {{g}}g。",safetyMarginHintG:"在統計安全庫存基礎上增加的固定重量緩衝。{{approx}}",safetyMarginHintGApprox:" ≈ 按當前速率 {{days}}天。",individualSpools:"單個料卷",labelWeight:"標示重量",spoolCount_one:"{{count}}個線軸",spoolCount_other:"{{count}}個線軸",stockBreakRisk:"斷貨風險",stockBreakBefore:"補貨前庫存斷檔",stockBreakDetail:"剩餘 {{days}} 天,交貨期 {{lt}} 天。",reorderNow:"立即補貨",reorderTriggerPassed:"觸發日期 {{date}} 已過。",shoppingList:"購物清單",shoppingListItems_one:"({{count}}項)",shoppingListItems_other:"({{count}}項)",shoppingListEmpty:"購物清單為空。點擊任意列的購物車圖示以新增商品。",addToCart:"新增至購物清單",alertsSnoozed:"靜音此SKU的提醒",alertsEnabled:"啟用此SKU的提醒",addedToCart:"已新增至購物清單",failedAddItem:"新增項目失敗",listView:"列表",logisticsView:"物流",qty:"數量",weight:"重量",leadTime:"交貨期",expectedRestock:"預計補貨日期",status:"狀態",note:"備註",pending:"待處理",purchased:"已購買",received:"已收貨",markPurchased:"標記為已購買",markReceived:"標記為已收貨 — 將料卷新增至庫存",resetToPending:"重置為待處理",remove:"移除",clearAll:"清空",downloadCsv:"CSV",addToCartTitle:"新增至購物清單",byQuantity:"依數量",byDuration:"依時長",numberOfSpools:"線軸數量",lastHowManyDays:"需要持續多少天?",noUsageQty:"無使用資料 — 數量已設為1。",noteOptional:"備註(選填)",notePlaceholder:"例如:用於專案X,緊急…",addNSpools_one:"新增{{count}}個線軸",addNSpools_other:"新增{{count}}個線軸",onArrival:"到貨時",stockBreakIn:"{{days}} 天後斷貨。",stockRunsOutBefore:"庫存在 {{lt}} 天交貨期結束前耗盡。",atRate:"按 {{rate}}g/天的速度,您需要",moreSpools_one:"再{{count}}個線軸",moreSpools_other:"再{{count}}個線軸",bridgeGap:"來彌補缺口。",noReadAccess:"您沒有查看庫存預測的權限。",noWriteAccess:"您沒有修改預測設定的權限。"}},Xme={en:{translation:Hme},de:{translation:qme},fr:{translation:$me},ja:{translation:Vme},it:{translation:Gme},"pt-BR":{translation:Wme},"zh-CN":{translation:Kme},"zh-TW":{translation:Qme}};Mo.use(qY).use(vme).init({resources:Xme,fallbackLng:"en",supportedLngs:["en","de","fr","ja","it","pt-BR","zh-CN","zh-TW"],detection:{order:["localStorage","navigator","htmlTag"],lookupLocalStorage:"bambutrack_language",caches:["localStorage"]},interpolation:{escapeValue:!1},react:{useSuspense:!1}});const VH=[{code:"en",name:"English",nativeName:"English"},{code:"de",name:"German",nativeName:"Deutsch"},{code:"fr",name:"French",nativeName:"Français"},{code:"ja",name:"Japanese",nativeName:"日本語"},{code:"it",name:"Italian",nativeName:"Italiano"},{code:"pt-BR",name:"Portuguese (Brazil)",nativeName:"Português (Brasil)"},{code:"zh-CN",name:"Chinese (Simplified)",nativeName:"简体中文"},{code:"zh-TW",name:"Chinese (Traditional)",nativeName:"繁體中文"}];var GH="popstate";function Yme(t={}){function e(a,i){let{pathname:s,search:o,hash:l}=a.location;return jF("",{pathname:s,search:o,hash:l},i.state&&i.state.usr||null,i.state&&i.state.key||"default")}function n(a,i){return typeof i=="string"?i:Pw(i)}return Jme(e,n,null,t)}function za(t,e){if(t===!1||t===null||typeof t>"u")throw new Error(e)}function vc(t,e){if(!t){typeof console<"u"&&console.warn(e);try{throw new Error(e)}catch{}}}function Zme(){return Math.random().toString(36).substring(2,10)}function WH(t,e){return{usr:t.state,key:t.key,idx:e}}function jF(t,e,n=null,a){return{pathname:typeof t=="string"?t:t.pathname,search:"",hash:"",...typeof e=="string"?qy(e):e,state:n,key:e&&e.key||a||Zme()}}function Pw({pathname:t="/",search:e="",hash:n=""}){return e&&e!=="?"&&(t+=e.charAt(0)==="?"?e:"?"+e),n&&n!=="#"&&(t+=n.charAt(0)==="#"?n:"#"+n),t}function qy(t){let e={};if(t){let n=t.indexOf("#");n>=0&&(e.hash=t.substring(n),t=t.substring(0,n));let a=t.indexOf("?");a>=0&&(e.search=t.substring(a),t=t.substring(0,a)),t&&(e.pathname=t)}return e}function Jme(t,e,n,a={}){let{window:i=document.defaultView,v5Compat:s=!1}=a,o=i.history,l="POP",c=null,d=u();d==null&&(d=0,o.replaceState({...o.state,idx:d},""));function u(){return(o.state||{idx:null}).idx}function m(){l="POP";let b=u(),x=b==null?null:b-d;d=b,c&&c({action:l,location:w.location,delta:x})}function p(b,x){l="PUSH";let S=jF(w.location,b,x);d=u()+1;let N=WH(S,d),C=w.createHref(S);try{o.pushState(N,"",C)}catch(P){if(P instanceof DOMException&&P.name==="DataCloneError")throw P;i.location.assign(C)}s&&c&&c({action:l,location:w.location,delta:1})}function f(b,x){l="REPLACE";let S=jF(w.location,b,x);d=u();let N=WH(S,d),C=w.createHref(S);o.replaceState(N,"",C),s&&c&&c({action:l,location:w.location,delta:0})}function g(b){return epe(b)}let w={get action(){return l},get location(){return t(i,o)},listen(b){if(c)throw new Error("A history only accepts one active listener");return i.addEventListener(GH,m),c=b,()=>{i.removeEventListener(GH,m),c=null}},createHref(b){return e(i,b)},createURL:g,encodeLocation(b){let x=g(b);return{pathname:x.pathname,search:x.search,hash:x.hash}},push:p,replace:f,go(b){return o.go(b)}};return w}function epe(t,e=!1){let n="http://localhost";typeof window<"u"&&(n=window.location.origin!=="null"?window.location.origin:window.location.href),za(n,"No window.location.(origin|href) available to create URL");let a=typeof t=="string"?t:Pw(t);return a=a.replace(/ $/,"%20"),!e&&a.startsWith("//")&&(a=n+a),new URL(a,n)}function $Y(t,e,n="/"){return tpe(t,e,n,!1)}function tpe(t,e,n,a){let i=typeof e=="string"?qy(e):e,s=Bm(i.pathname||"/",n);if(s==null)return null;let o=VY(t);npe(o);let l=null;for(let c=0;l==null&&c{let u={relativePath:d===void 0?o.path||"":d,caseSensitive:o.caseSensitive===!0,childrenIndex:l,route:o};if(u.relativePath.startsWith("/")){if(!u.relativePath.startsWith(a)&&c)return;za(u.relativePath.startsWith(a),`Absolute route path "${u.relativePath}" nested under path "${a}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),u.relativePath=u.relativePath.slice(a.length)}let m=Mm([a,u.relativePath]),p=n.concat(u);o.children&&o.children.length>0&&(za(o.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${m}".`),VY(o.children,e,p,m,c)),!(o.path==null&&!o.index)&&e.push({path:m,score:cpe(m,o.index),routesMeta:p})};return t.forEach((o,l)=>{if(o.path===""||!o.path?.includes("?"))s(o,l);else for(let c of GY(o.path))s(o,l,!0,c)}),e}function GY(t){let e=t.split("/");if(e.length===0)return[];let[n,...a]=e,i=n.endsWith("?"),s=n.replace(/\?$/,"");if(a.length===0)return i?[s,""]:[s];let o=GY(a.join("/")),l=[];return l.push(...o.map(c=>c===""?s:[s,c].join("/"))),i&&l.push(...o),l.map(c=>t.startsWith("/")&&c===""?"/":c)}function npe(t){t.sort((e,n)=>e.score!==n.score?n.score-e.score:dpe(e.routesMeta.map(a=>a.childrenIndex),n.routesMeta.map(a=>a.childrenIndex)))}var rpe=/^:[\w-]+$/,ape=3,ipe=2,spe=1,ope=10,lpe=-2,KH=t=>t==="*";function cpe(t,e){let n=t.split("/"),a=n.length;return n.some(KH)&&(a+=lpe),e&&(a+=ipe),n.filter(i=>!KH(i)).reduce((i,s)=>i+(rpe.test(s)?ape:s===""?spe:ope),a)}function dpe(t,e){return t.length===e.length&&t.slice(0,-1).every((a,i)=>a===e[i])?t[t.length-1]-e[e.length-1]:0}function upe(t,e,n=!1){let{routesMeta:a}=t,i={},s="/",o=[];for(let l=0;l{if(u==="*"){let g=l[p]||"";o=s.slice(0,s.length-g.length).replace(/(.)\/+$/,"$1")}const f=l[p];return m&&!f?d[u]=void 0:d[u]=(f||"").replace(/%2F/g,"/"),d},{}),pathname:s,pathnameBase:o,pattern:t}}function mpe(t,e=!1,n=!0){vc(t==="*"||!t.endsWith("*")||t.endsWith("/*"),`Route path "${t}" will be treated as if it were "${t.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${t.replace(/\*$/,"/*")}".`);let a=[],i="^"+t.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(o,l,c)=>(a.push({paramName:l,isOptional:c!=null}),c?"/?([^\\/]+)?":"/([^\\/]+)")).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return t.endsWith("*")?(a.push({paramName:"*"}),i+=t==="*"||t==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?i+="\\/*$":t!==""&&t!=="/"&&(i+="(?:(?=\\/|$))"),[new RegExp(i,e?void 0:"i"),a]}function ppe(t){try{return t.split("/").map(e=>decodeURIComponent(e).replace(/\//g,"%2F")).join("/")}catch(e){return vc(!1,`The URL path "${t}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${e}).`),t}}function Bm(t,e){if(e==="/")return t;if(!t.toLowerCase().startsWith(e.toLowerCase()))return null;let n=e.endsWith("/")?e.length-1:e.length,a=t.charAt(n);return a&&a!=="/"?null:t.slice(n)||"/"}var hpe=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function fpe(t,e="/"){let{pathname:n,search:a="",hash:i=""}=typeof t=="string"?qy(t):t,s;return n?(n=n.replace(/\/\/+/g,"/"),n.startsWith("/")?s=QH(n.substring(1),"/"):s=QH(n,e)):s=e,{pathname:s,search:xpe(a),hash:ype(i)}}function QH(t,e){let n=e.replace(/\/+$/,"").split("/");return t.split("/").forEach(i=>{i===".."?n.length>1&&n.pop():i!=="."&&n.push(i)}),n.length>1?n.join("/"):"/"}function rE(t,e,n,a){return`Cannot include a '${t}' character in a manually specified \`to.${e}\` field [${JSON.stringify(a)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function gpe(t){return t.filter((e,n)=>n===0||e.route.path&&e.route.path.length>0)}function tO(t){let e=gpe(t);return e.map((n,a)=>a===e.length-1?n.pathname:n.pathnameBase)}function nO(t,e,n,a=!1){let i;typeof t=="string"?i=qy(t):(i={...t},za(!i.pathname||!i.pathname.includes("?"),rE("?","pathname","search",i)),za(!i.pathname||!i.pathname.includes("#"),rE("#","pathname","hash",i)),za(!i.search||!i.search.includes("#"),rE("#","search","hash",i)));let s=t===""||i.pathname==="",o=s?"/":i.pathname,l;if(o==null)l=n;else{let m=e.length-1;if(!a&&o.startsWith("..")){let p=o.split("/");for(;p[0]==="..";)p.shift(),m-=1;i.pathname=p.join("/")}l=m>=0?e[m]:"/"}let c=fpe(i,l),d=o&&o!=="/"&&o.endsWith("/"),u=(s||o===".")&&n.endsWith("/");return!c.pathname.endsWith("/")&&(d||u)&&(c.pathname+="/"),c}var Mm=t=>t.join("/").replace(/\/\/+/g,"/"),bpe=t=>t.replace(/\/+$/,"").replace(/^\/*/,"/"),xpe=t=>!t||t==="?"?"":t.startsWith("?")?t:"?"+t,ype=t=>!t||t==="#"?"":t.startsWith("#")?t:"#"+t,vpe=class{constructor(t,e,n,a=!1){this.status=t,this.statusText=e||"",this.internal=a,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function wpe(t){return t!=null&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.internal=="boolean"&&"data"in t}function Spe(t){return t.map(e=>e.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var WY=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function KY(t,e){let n=t;if(typeof n!="string"||!hpe.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let a=n,i=!1;if(WY)try{let s=new URL(window.location.href),o=n.startsWith("//")?new URL(s.protocol+n):new URL(n),l=Bm(o.pathname,e);o.origin===s.origin&&l!=null?n=l+o.search+o.hash:i=!0}catch{vc(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:a,isExternal:i,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var QY=["POST","PUT","PATCH","DELETE"];new Set(QY);var _pe=["GET",...QY];new Set(_pe);var $y=y.createContext(null);$y.displayName="DataRouter";var yT=y.createContext(null);yT.displayName="DataRouterState";var kpe=y.createContext(!1),XY=y.createContext({isTransitioning:!1});XY.displayName="ViewTransition";var Npe=y.createContext(new Map);Npe.displayName="Fetchers";var Cpe=y.createContext(null);Cpe.displayName="Await";var jl=y.createContext(null);jl.displayName="Navigation";var _S=y.createContext(null);_S.displayName="Location";var Ac=y.createContext({outlet:null,matches:[],isDataRoute:!1});Ac.displayName="Route";var rO=y.createContext(null);rO.displayName="RouteError";var YY="REACT_ROUTER_ERROR",Ppe="REDIRECT",Tpe="ROUTE_ERROR_RESPONSE";function Ape(t){if(t.startsWith(`${YY}:${Ppe}:{`))try{let e=JSON.parse(t.slice(28));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.location=="string"&&typeof e.reloadDocument=="boolean"&&typeof e.replace=="boolean")return e}catch{}}function jpe(t){if(t.startsWith(`${YY}:${Tpe}:{`))try{let e=JSON.parse(t.slice(40));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string")return new vpe(e.status,e.statusText,e.data)}catch{}}function Mpe(t,{relative:e}={}){za(Vy(),"useHref() may be used only in the context of a component.");let{basename:n,navigator:a}=y.useContext(jl),{hash:i,pathname:s,search:o}=NS(t,{relative:e}),l=s;return n!=="/"&&(l=s==="/"?n:Mm([n,s])),a.createHref({pathname:l,search:o,hash:i})}function Vy(){return y.useContext(_S)!=null}function fd(){return za(Vy(),"useLocation() may be used only in the context of a component."),y.useContext(_S).location}var ZY="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function JY(t){y.useContext(jl).static||y.useLayoutEffect(t)}function ji(){let{isDataRoute:t}=y.useContext(Ac);return t?Vpe():Epe()}function Epe(){za(Vy(),"useNavigate() may be used only in the context of a component.");let t=y.useContext($y),{basename:e,navigator:n}=y.useContext(jl),{matches:a}=y.useContext(Ac),{pathname:i}=fd(),s=JSON.stringify(tO(a)),o=y.useRef(!1);return JY(()=>{o.current=!0}),y.useCallback((c,d={})=>{if(vc(o.current,ZY),!o.current)return;if(typeof c=="number"){n.go(c);return}let u=nO(c,JSON.parse(s),i,d.relative==="path");t==null&&e!=="/"&&(u.pathname=u.pathname==="/"?e:Mm([e,u.pathname])),(d.replace?n.replace:n.push)(u,d.state,d)},[e,n,s,i,t])}var eZ=y.createContext(null);function Gy(){return y.useContext(eZ)}function Dpe(t){let e=y.useContext(Ac).outlet;return y.useMemo(()=>e&&y.createElement(eZ.Provider,{value:t},e),[e,t])}function kS(){let{matches:t}=y.useContext(Ac),e=t[t.length-1];return e?e.params:{}}function NS(t,{relative:e}={}){let{matches:n}=y.useContext(Ac),{pathname:a}=fd(),i=JSON.stringify(tO(n));return y.useMemo(()=>nO(t,JSON.parse(i),a,e==="path"),[t,i,a,e])}function Fpe(t,e){return tZ(t,e)}function tZ(t,e,n,a,i){za(Vy(),"useRoutes() may be used only in the context of a component.");let{navigator:s}=y.useContext(jl),{matches:o}=y.useContext(Ac),l=o[o.length-1],c=l?l.params:{},d=l?l.pathname:"/",u=l?l.pathnameBase:"/",m=l&&l.route;{let S=m&&m.path||"";rZ(d,!m||S.endsWith("*")||S.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${d}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. -Please change the parent to .`)}let p=fd(),f;if(e){let S=typeof e=="string"?qy(e):e;za(u==="/"||S.pathname?.startsWith(u),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${u}" but pathname "${S.pathname}" was given in the \`location\` prop.`),f=S}else f=p;let g=f.pathname||"/",w=g;if(u!=="/"){let S=u.replace(/^\//,"").split("/");w="/"+g.replace(/^\//,"").split("/").slice(S.length).join("/")}let b=$Y(t,{pathname:w});vc(m||b!=null,`No routes matched location "${f.pathname}${f.search}${f.hash}" `),vc(b==null||b[b.length-1].route.element!==void 0||b[b.length-1].route.Component!==void 0||b[b.length-1].route.lazy!==void 0,`Matched leaf route at location "${f.pathname}${f.search}${f.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let x=zpe(b&&b.map(S=>Object.assign({},S,{params:Object.assign({},c,S.params),pathname:Mm([u,s.encodeLocation?s.encodeLocation(S.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:S.pathname]),pathnameBase:S.pathnameBase==="/"?u:Mm([u,s.encodeLocation?s.encodeLocation(S.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:S.pathnameBase])})),o,n,a,i);return e&&x?y.createElement(_S.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",...f},navigationType:"POP"}},x):x}function Lpe(){let t=$pe(),e=wpe(t)?`${t.status} ${t.statusText}`:t instanceof Error?t.message:JSON.stringify(t),n=t instanceof Error?t.stack:null,a="rgba(200,200,200, 0.5)",i={padding:"0.5rem",backgroundColor:a},s={padding:"2px 4px",backgroundColor:a},o=null;return console.error("Error handled by React Router default ErrorBoundary:",t),o=y.createElement(y.Fragment,null,y.createElement("p",null,"💿 Hey developer 👋"),y.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",y.createElement("code",{style:s},"ErrorBoundary")," or"," ",y.createElement("code",{style:s},"errorElement")," prop on your route.")),y.createElement(y.Fragment,null,y.createElement("h2",null,"Unexpected Application Error!"),y.createElement("h3",{style:{fontStyle:"italic"}},e),n?y.createElement("pre",{style:i},n):null,o)}var Rpe=y.createElement(Lpe,null),nZ=class extends y.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,e){return e.location!==t.location||e.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:e.error,location:e.location,revalidation:t.revalidation||e.revalidation}}componentDidCatch(t,e){this.props.onError?this.props.onError(t,e):console.error("React Router caught the following error during render",t)}render(){let t=this.state.error;if(this.context&&typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){const n=jpe(t.digest);n&&(t=n)}let e=t!==void 0?y.createElement(Ac.Provider,{value:this.props.routeContext},y.createElement(rO.Provider,{value:t,children:this.props.component})):this.props.children;return this.context?y.createElement(Ipe,{error:t},e):e}};nZ.contextType=kpe;var aE=new WeakMap;function Ipe({children:t,error:e}){let{basename:n}=y.useContext(jl);if(typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){let a=Ape(e.digest);if(a){let i=aE.get(e);if(i)throw i;let s=KY(a.location,n);if(WY&&!aE.get(e))if(s.isExternal||a.reloadDocument)window.location.href=s.absoluteURL||s.to;else{const o=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(s.to,{replace:a.replace}));throw aE.set(e,o),o}return y.createElement("meta",{httpEquiv:"refresh",content:`0;url=${s.absoluteURL||s.to}`})}}return t}function Ope({routeContext:t,match:e,children:n}){let a=y.useContext($y);return a&&a.static&&a.staticContext&&(e.route.errorElement||e.route.ErrorBoundary)&&(a.staticContext._deepestRenderedBoundaryId=e.route.id),y.createElement(Ac.Provider,{value:t},n)}function zpe(t,e=[],n=null,a=null,i=null){if(t==null){if(!n)return null;if(n.errors)t=n.matches;else if(e.length===0&&!n.initialized&&n.matches.length>0)t=n.matches;else return null}let s=t,o=n?.errors;if(o!=null){let u=s.findIndex(m=>m.route.id&&o?.[m.route.id]!==void 0);za(u>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),s=s.slice(0,Math.min(s.length,u+1))}let l=!1,c=-1;if(n)for(let u=0;u=0?s=s.slice(0,c+1):s=[s[0]];break}}}let d=n&&a?(u,m)=>{a(u,{location:n.location,params:n.matches?.[0]?.params??{},unstable_pattern:Spe(n.matches),errorInfo:m})}:void 0;return s.reduceRight((u,m,p)=>{let f,g=!1,w=null,b=null;n&&(f=o&&m.route.id?o[m.route.id]:void 0,w=m.route.errorElement||Rpe,l&&(c<0&&p===0?(rZ("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),g=!0,b=null):c===p&&(g=!0,b=m.route.hydrateFallbackElement||null)));let x=e.concat(s.slice(0,p+1)),S=()=>{let N;return f?N=w:g?N=b:m.route.Component?N=y.createElement(m.route.Component,null):m.route.element?N=m.route.element:N=u,y.createElement(Ope,{match:m,routeContext:{outlet:u,matches:x,isDataRoute:n!=null},children:N})};return n&&(m.route.ErrorBoundary||m.route.errorElement||p===0)?y.createElement(nZ,{location:n.location,revalidation:n.revalidation,component:w,error:f,children:S(),routeContext:{outlet:null,matches:x,isDataRoute:!0},onError:d}):S()},null)}function aO(t){return`${t} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Upe(t){let e=y.useContext($y);return za(e,aO(t)),e}function Bpe(t){let e=y.useContext(yT);return za(e,aO(t)),e}function Hpe(t){let e=y.useContext(Ac);return za(e,aO(t)),e}function iO(t){let e=Hpe(t),n=e.matches[e.matches.length-1];return za(n.route.id,`${t} can only be used on routes that contain a unique "id"`),n.route.id}function qpe(){return iO("useRouteId")}function $pe(){let t=y.useContext(rO),e=Bpe("useRouteError"),n=iO("useRouteError");return t!==void 0?t:e.errors?.[n]}function Vpe(){let{router:t}=Upe("useNavigate"),e=iO("useNavigate"),n=y.useRef(!1);return JY(()=>{n.current=!0}),y.useCallback(async(i,s={})=>{vc(n.current,ZY),n.current&&(typeof i=="number"?await t.navigate(i):await t.navigate(i,{fromRouteId:e,...s}))},[t,e])}var XH={};function rZ(t,e,n){!e&&!XH[t]&&(XH[t]=!0,vc(!1,n))}y.memo(Gpe);function Gpe({routes:t,future:e,state:n,onError:a}){return tZ(t,void 0,n,a,e)}function hg({to:t,replace:e,state:n,relative:a}){za(Vy()," may be used only in the context of a component.");let{static:i}=y.useContext(jl);vc(!i," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:s}=y.useContext(Ac),{pathname:o}=fd(),l=Mi(),c=nO(t,tO(s),o,a==="path"),d=JSON.stringify(c);return y.useEffect(()=>{l(JSON.parse(d),{replace:e,state:n,relative:a})},[l,d,a,e,n]),null}function aZ(t){return Dpe(t.context)}function Tr(t){za(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function Wpe({basename:t="/",children:e=null,location:n,navigationType:a="POP",navigator:i,static:s=!1,unstable_useTransitions:o}){za(!Vy(),"You cannot render a inside another . You should never have more than one in your app.");let l=t.replace(/^\/*/,"/"),c=y.useMemo(()=>({basename:l,navigator:i,static:s,unstable_useTransitions:o,future:{}}),[l,i,s,o]);typeof n=="string"&&(n=qy(n));let{pathname:d="/",search:u="",hash:m="",state:p=null,key:f="default"}=n,g=y.useMemo(()=>{let w=Bm(d,l);return w==null?null:{location:{pathname:w,search:u,hash:m,state:p,key:f},navigationType:a}},[l,d,u,m,p,f,a]);return vc(g!=null,` is not able to match the URL "${d}${u}${m}" because it does not start with the basename, so the won't render anything.`),g==null?null:y.createElement(jl.Provider,{value:c},y.createElement(_S.Provider,{children:e,value:g}))}function Kpe({children:t,location:e}){return Fpe(MF(t),e)}function MF(t,e=[]){let n=[];return y.Children.forEach(t,(a,i)=>{if(!y.isValidElement(a))return;let s=[...e,i];if(a.type===y.Fragment){n.push.apply(n,MF(a.props.children,s));return}za(a.type===Tr,`[${typeof a.type=="string"?a.type:a.type.name}] is not a component. All component children of must be a or `),za(!a.props.index||!a.props.children,"An index route cannot have child routes.");let o={id:a.props.id||s.join("-"),caseSensitive:a.props.caseSensitive,element:a.props.element,Component:a.props.Component,index:a.props.index,path:a.props.path,middleware:a.props.middleware,loader:a.props.loader,action:a.props.action,hydrateFallbackElement:a.props.hydrateFallbackElement,HydrateFallback:a.props.HydrateFallback,errorElement:a.props.errorElement,ErrorBoundary:a.props.ErrorBoundary,hasErrorBoundary:a.props.hasErrorBoundary===!0||a.props.ErrorBoundary!=null||a.props.errorElement!=null,shouldRevalidate:a.props.shouldRevalidate,handle:a.props.handle,lazy:a.props.lazy};a.props.children&&(o.children=MF(a.props.children,s)),n.push(o)}),n}var gN="get",bN="application/x-www-form-urlencoded";function vT(t){return typeof HTMLElement<"u"&&t instanceof HTMLElement}function Qpe(t){return vT(t)&&t.tagName.toLowerCase()==="button"}function Xpe(t){return vT(t)&&t.tagName.toLowerCase()==="form"}function Ype(t){return vT(t)&&t.tagName.toLowerCase()==="input"}function Zpe(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)}function Jpe(t,e){return t.button===0&&(!e||e==="_self")&&!Zpe(t)}function EF(t=""){return new URLSearchParams(typeof t=="string"||Array.isArray(t)||t instanceof URLSearchParams?t:Object.keys(t).reduce((e,n)=>{let a=t[n];return e.concat(Array.isArray(a)?a.map(i=>[n,i]):[[n,a]])},[]))}function ehe(t,e){let n=EF(t);return e&&e.forEach((a,i)=>{n.has(i)||e.getAll(i).forEach(s=>{n.append(i,s)})}),n}var kk=null;function the(){if(kk===null)try{new FormData(document.createElement("form"),0),kk=!1}catch{kk=!0}return kk}var nhe=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function iE(t){return t!=null&&!nhe.has(t)?(vc(!1,`"${t}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${bN}"`),null):t}function rhe(t,e){let n,a,i,s,o;if(Xpe(t)){let l=t.getAttribute("action");a=l?Bm(l,e):null,n=t.getAttribute("method")||gN,i=iE(t.getAttribute("enctype"))||bN,s=new FormData(t)}else if(Qpe(t)||Ype(t)&&(t.type==="submit"||t.type==="image")){let l=t.form;if(l==null)throw new Error('Cannot submit a