mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-20 14:06:27 +00:00
ebc98f0a3f
* fix(plugins): unknown column * fix(mcp): reuse MCP sessions instead of creating one per tool call The /mcp CORS layer never set exposedHeaders, so Access-Control-Expose-Headers was absent and browser-context MCP clients (Claude Desktop connectors, Claude.ai, MCP Inspector) could not read Mcp-Session-Id off the initialize response. Unable to echo it back, every request looked like a fresh initialize: one McpServer and one session per tool call, until the per-user cap returned a 429 and the integration died until the container was restarted. The idle sweep was not at fault — it expires on lastActivity with a 1h default, so sessions born seconds apart are nowhere near expiry, hence 'cleaned 0'. - expose Mcp-Session-Id, MCP-Protocol-Version and WWW-Authenticate - evict a user's least-recently-active session at the cap rather than refusing the request, so a client that cannot persist its session id (or a proxy that strips the header) can never wedge the server - close the McpServer/transport orphaned by every session-less non-initialize POST, which was leaked: never mapped, never swept, never closed - return the cap error as JSON-RPC so clients surface the real reason - warn on session-less POSTs to make a header-stripping proxy diagnosable * chore(deps): declare @modelcontextprotocol/sdk ^1.29.0 Matches the version already resolved in the lockfile; no dependency-tree change. * docs(mcp): add the reverse proxy specs for MCP * fix(plugins): stop the row ⋯ menu being clipped by the sidebar The menu was an in-flow `absolute` div, and its ancestor (PageSidebar) is `overflow-hidden` — which clips absolutely-positioned descendants regardless of z-index. With enough plugins installed a row sits low enough that its menu runs past the sidebar's bottom edge and gets chopped, taking Delete with it, so the plugin could no longer be uninstalled from the UI. Portal the menu to <body> and position it `fixed` against the ⋯ button, flipping upward when the bottom is tight and re-anchoring on scroll/resize. A fixed child of <body> has no overflow ancestor, so nothing can clip it. Closes #1523 * feat(plugins): surface author-signature status and add a scoped re-trust override TREK has always verified an author's Ed25519 signature and TOFU-pinned the key on first install, but none of it was ever shown: a successfully-installed UNSIGNED plugin looked identical to a signed one, and a signature-refused update left the plugin quietly pinned at its old version with the reason dying in a toast. Give the four refusal conditions machine-readable codes (SIGNATURE_MISSING / _INCOMPLETE / _KEY_CHANGED / _INVALID), persist a refusal on the plugin row so the admin list keeps showing it, and badge Signed/Unsigned in the list and in Discover. Only SIGNATURE_KEY_CHANGED is overridable — an author can legitimately rotate a key; a signature that does not verify means the bytes are not what the author signed, and there is no story where waving that through is right. The override re-pins and updates in ONE call (POST :id/retrust): a re-pin that waited for a follow-up /update would leave the plugin pinned to a key no install had ever been verified against if that second call never came. The artifact must still verify under the new key, so a re-trust moves the pin from one verified key to another. assertRetrustable re-derives the condition server-side, so the UI hiding the button is a convenience, not the control, and it echoes back the full key the admin was shown so a re-key since the dialog rendered is refused. The rotation is written to the admin audit log with both fingerprints — after an incident, "which key did we move from, and to what?" is the question a single key cannot answer. * fix(plugins): let a plugin's frame reach the hosts an admin added for it The frame's connect-src was built from the manifest's http:outbound grants alone, but the child's egress guard is the UNION of those and the hosts an admin added after install for an operatorEgress plugin (a self-hosted Gotify, an ntfy — hosts the author cannot know in advance). So such a plugin WITH A UI could call the operator's host from its server and was CSP-blocked in its own iframe. Match the frame to the child. The admin consented to these hosts at install and the child already reaches them, so this widens no trust boundary that isn't already crossed. Both sources stay validated on the way in, and the interpolation filter is unchanged. * fix(plugins): report a rejected events.emit on the plugin's own log stream The host can reject an emit (an undeclared event name, a rate limit). The rejection must not escape — a detached rejection crashes the child and terminally disables the plugin over one bad emit — but swallowing it silently left an author with no way to discover that `emits` was missing from their manifest. Surface it as a warning instead. * feat(plugin-sdk): expose the raw request body for webhook signature checks A webhook author must run their HMAC over the exact bytes the sender signed. `body` is the PARSED value, and re-serializing it will not reproduce those bytes — key order, whitespace and unicode escaping all differ — so the signature never matches. Document `rawBodyBase64`, which the host already sets on auth:false routes. * fix(plugin-sdk): refuse to overwrite a released artifact, and keep the packed zip A released artifact is IMMUTABLE: the registry pins its sha256, so overwriting the bytes of a release already in the registry breaks the checksum for everyone who installed that version — they can no longer install or update it. The old code blanket-caught every `gh release create` failure (auth, network, a bad repo) and turned it into a --clobber upload. Probe for the release explicitly and refuse unless --force. Also stop deleting plugin.zip on the way out. It is the exact bytes the release and the entry's sha256 pin were computed from; a re-pack on another machine or SDK version can differ (CRLF, walk order), so anyone re-running `entry`/`sign` afterwards must hash THAT file, not a rebuild. * fix(plugin-sdk): don't fail submit when the fork already has an upstream remote `gh repo clone` of a fork may already have wired `upstream`, in which case a bare `remote add` exits non-zero and took the whole submit down. Set it either way. * fix(plugin-sdk): make the dev server behave like the host Three ways `dev` lied to an author about how their plugin would run in production: - ctx.db: one try/catch wrapped both the node:sqlite probe AND opening the database, so an mkdir/permission failure silently degraded to the in-memory stub — which swallows every write while reporting success. A db:own plugin "worked" in dev and persisted nothing. Probe separately: fail loudly on a real error, degrade only on old Node, and say plainly that the stub discards writes. - notificationChannel: the host fires it with no acting user and hands the recipient's decrypted settings in as a separate `config` argument — send(msg, config, ctx) / test(config, ctx). Firing it like an ordinary hook passed `ctx` where `config` belongs, so a channel plugin read its settings off ctx and was broken in production. - /preview pinned tripId 42 while the scaffold seeds trip 1, so the widget's first trek:invoke hit assertMember(42) and 500'd. Preview against a trip that exists. * fix(plugin-sdk): reject unknown flags, wire up create's new flags, and add --help `parse()` accepts any --x, so a flag a command does not read was silently dropped: `create --template notification-channel` cheerfully scaffolded a blank plugin. Silently ignoring an author's explicit instruction is worse than refusing it, so unknown flags are now an error, and create actually forwards --template/--egress/--required-addons. A bare --permissions used to split the string "true" into a permission literally named `true`; listFlag() now treats a valueless flag as absent. Since an unknown flag is now fatal, `--help` has to exist: it is intercepted before the flag check and prints usage on stdout with exit 0. * chore(plugins): drop three unused eslint-disable directives The no-console rule is not enabled for these files, so the directives were dead and eslint reports them as unused. * fix(plugin-sdk): bring preflight back in step with the registry's gates preflight exists to tell an author what TREK-Plugins' CI will say before they open the PR. The registry now verifies author signatures, and preflight didn't — so it drifted into the one failure mode it must never have: a false green. An author trusts a green. - Verify the signature against the artifact bytes. preflight already downloads them for the sha256 check, so this costs one call. Without it, signing with the wrong key (or re-packing after signing) sails through and is caught at review. - Check the signature SHAPE (checkSignatureShape): a key with no signed version, a signature with no key, a malformed key or signature. TREK refuses to install a half-signed entry, so such an entry is dead on arrival. - Default apiVersion to 1 before comparing. It is OPTIONAL in the manifest — install/ manifest.ts and `entry` both default it — so a manifest that legally omits it was failing preflight with "manifest apiVersion undefined != entry 1" while the registry passed it. A false RED, which teaches authors to ignore the tool. - Check requiredAddons/pluginDependencies parity, and operatorEgress without an http:outbound grant. The verifier is a port of the host's install/verify-signature.ts (the registry has its own port); sign.ts's verifyArtifact only understands the bare key/signature pair the SDK itself emits and cannot judge a minisign key. A test pins all three to the same verdicts. * feat(plugins): enforce compatibility range * chore: bump sdk version * test(e2e): repair the trip-creation specs create-trip and trip-planner have been failing for a while — long enough for three separate UI changes to drift past them, which nothing caught because CI runs vitest only and never invokes Playwright. Each failure was masking the next: - The release-notice modal greets a freshly seeded user and its backdrop swallowed the click on .add-trip-card. Added a shared dismissSystemNotices() helper (the X only shows on the notice's last page, so it has to page through first). - .modal-backdrop no longer exists — the class was namespaced to .trek-modal-backdrop so content blockers stop hiding it. - input[type=text].first() is no longer the Title field: the cover-image search inputs now sit above it, so the specs were typing the trip name into the photo search box and creating an untitled trip that never matched getByText(title). * fix(planner): gate drag & drop on pointer type, not viewport width (#1432) The 3.2.1 fix disabled drag on "mobile", but nothing in the client has ever detected touch — "mobile" was inferred from viewport width, at four independent breakpoints. A tablet is a coarse-pointer device at a *desktop* width, so an iPad (820-1366px) fell on the wrong side of all four, which is why iPhone was fixed and iPad was not: - useTripPlanner's isMobile (<768px) is what disarmed `draggable`, so on iPad rows stayed draggable and a scroll swipe became an HTML5 drag. - TripPlannerPage hardcoded isMobile={false} on the desktop PlacesSidebar, so its drop handlers and the drop-to-import overlay could never be disabled — that overlay is the reported symptom. - The arrow-button reorder fallback was revealed only below 767px, leaving iPad with no drag *and* no fallback. - touchDragPolyfill loaded drag-drop-touch at >=1024px, synthesising drags from touchmove — on a landscape iPad that re-armed the very gesture hijack 3.2.1 removed. Adds useIsTouch() ((pointer: coarse)) as a signal separate from isMobile: layout stays width-driven, so the iPad keeps the desktop two-pane planner, while every drag affordance is gated on isMobile || isTouch. The reorder arrows now show on coarse pointers, and the polyfill loads only on hybrid laptops ((pointer: fine) and (any-pointer: coarse)), which also removes the #1440 phantom-dblclick map zoom on tablets. Guarded by unit tests plus an e2e spec on real WebKit in an iPad Pro 11 context — the engine matters, since every browser on iPadOS is WebKit underneath, which is why the reporter hit this in all three they tried. * test(planner): guard the day-plan reorder arrows against phantom clicks The hover rule that reveals the reorder arrows had been dead since the TypeScript migration: it targeted `.place-row:hover .reorder-btns`, and neither class exists — the component renders `.reorder-buttons` inside an unclassed row. The buttons sat at opacity:0 on desktop with nothing to reveal them. That was not merely invisible. opacity:0 still hit-tests, so every itinerary row and day note carried an invisible, fully clickable target that silently reordered the trip: opacity: "0", visibility: "visible", pointerEvents: "auto" elementFromPoint(centre) -> BUTTON, inside .reorder-buttons The repair — pointer-events: none while hidden, plus a working .dp-row:hover/:focus-within reveal (focus-within so the buttons are also reachable by keyboard, which the file's JS-hover pattern cannot do) — lives in index.css and DayPlanSidebar.tsx. Both files also carry the #1432 drag gating, so they went with that commit rather than being split mid-file; this commit is the regression guard for them. E2E rather than unit, because jsdom does not evaluate :hover. Against the old CSS it fails on exactly the right assertion: "hidden arrows must not swallow clicks" — expected false, received true. * fix(pdf): keep the header gap on day-header overflow pages (#1531) The repeated <thead> day header (#1471) carried no gap before the first card on overflow pages: the 12px sat in .day-body's block-start padding, which a fragmented box only paints on its first fragment. Move it to the thead cell so it repeats with the header; the day's first page renders pixel-identically. * fix(budget): keep "no one paid yet" when editing an expense (#1533) The ExpenseModal payer initializer fell back to the current user whenever the edited item had no payer, so reopening an expense saved with "no one paid yet" silently reselected "You" — and re-saving then recorded the current user as the payer, corrupting the balances. An absent payer on an existing expense is a deliberate value, so only a brand-new expense defaults to me.
689 lines
69 KiB
TypeScript
689 lines
69 KiB
TypeScript
import type { TranslationStrings } from '../types';
|
||
|
||
const admin: TranslationStrings = {
|
||
'admin.notifications.title': 'Ειδοποιήσεις',
|
||
'admin.notifications.hint': 'Επιλέξτε ένα κανάλι ειδοποιήσεων. Μόνο ένα μπορεί να είναι ενεργό κάθε φορά.',
|
||
'admin.notifications.none': 'Απενεργοποιημένο',
|
||
'admin.notifications.email': 'Email (SMTP)',
|
||
'admin.notifications.webhook': 'Webhook',
|
||
'admin.notifications.ntfy': 'Ntfy',
|
||
'admin.ntfy.hint':
|
||
'Επιτρέψτε στους χρήστες να διαμορφώνουν τα δικά τους θέματα ntfy για push ειδοποιήσεις. Ορίστε τον προεπιλεγμένο server παρακάτω για να προ-συμπληρώνει τις ρυθμίσεις χρηστών.',
|
||
'admin.notifications.save': 'Αποθήκευση ρυθμίσεων ειδοποιήσεων',
|
||
'admin.notifications.saved': 'Οι ρυθμίσεις ειδοποιήσεων αποθηκεύτηκαν',
|
||
'admin.notifications.testWebhook': 'Αποστολή δοκιμαστικού webhook',
|
||
'admin.notifications.testWebhookSuccess': 'Η δοκιμή webhook στάλθηκε επιτυχώς',
|
||
'admin.notifications.testWebhookFailed': 'Η δοκιμή webhook απέτυχε',
|
||
'admin.notifications.testNtfy': 'Αποστολή δοκιμαστικού ntfy',
|
||
'admin.notifications.testNtfySuccess': 'Η δοκιμή ntfy στάλθηκε επιτυχώς',
|
||
'admin.notifications.testNtfyFailed': 'Η δοκιμή ntfy απέτυχε',
|
||
'admin.notifications.emailPanel.title': 'Email (SMTP)',
|
||
'admin.notifications.webhookPanel.title': 'Webhook',
|
||
'admin.notifications.inappPanel.title': 'Εντός εφαρμογής',
|
||
'admin.notifications.inappPanel.hint':
|
||
'Οι ειδοποιήσεις εντός εφαρμογής είναι πάντα ενεργές και δεν μπορούν να απενεργοποιηθούν καθολικά.',
|
||
'admin.notifications.adminWebhookPanel.title': 'Webhook Διαχειριστή',
|
||
'admin.notifications.adminWebhookPanel.hint':
|
||
'Αυτό το webhook χρησιμοποιείται αποκλειστικά για ειδοποιήσεις διαχειριστή (π.χ. ειδοποιήσεις έκδοσης). Είναι ξεχωριστό από τα webhooks των χρηστών και ενεργοποιείται πάντα όταν έχει οριστεί.',
|
||
'admin.notifications.adminWebhookPanel.saved': 'Το URL του webhook διαχειριστή αποθηκεύτηκε',
|
||
'admin.notifications.adminWebhookPanel.testSuccess': 'Η δοκιμή webhook στάλθηκε επιτυχώς',
|
||
'admin.notifications.adminWebhookPanel.testFailed': 'Η δοκιμή webhook απέτυχε',
|
||
'admin.notifications.adminWebhookPanel.alwaysOnHint':
|
||
'Το webhook διαχειριστή ενεργοποιείται πάντα όταν έχει διαμορφωθεί ένα URL',
|
||
'admin.notifications.adminNtfyPanel.title': 'Ntfy Διαχειριστή',
|
||
'admin.notifications.adminNtfyPanel.hint':
|
||
'Αυτό το θέμα ntfy χρησιμοποιείται αποκλειστικά για ειδοποιήσεις διαχειριστή (π.χ. ειδοποιήσεις έκδοσης). Είναι ξεχωριστό από τα θέματα των χρηστών και ενεργοποιείται πάντα όταν έχει διαμορφωθεί.',
|
||
'admin.notifications.adminNtfyPanel.serverLabel': 'URL Ntfy Server',
|
||
'admin.notifications.adminNtfyPanel.serverHint':
|
||
'Χρησιμοποιείται επίσης ως ο προεπιλεγμένος server για τις ντόπιες ntfy ειδοποιήσεις χρηστών. Αφήστε κενό για προεπιλογή ntfy.sh. Οι χρήστες μπορούν να το παρακάμψουν στις δικές τους ρυθμίσεις.',
|
||
'admin.notifications.adminNtfyPanel.serverPlaceholder': 'https://ntfy.sh',
|
||
'admin.notifications.adminNtfyPanel.topicLabel': 'Θέμα Διαχειριστή',
|
||
'admin.notifications.adminNtfyPanel.topicPlaceholder': 'trek-admin-alerts',
|
||
'admin.notifications.adminNtfyPanel.tokenLabel': 'Access Token (προαιρετικό)',
|
||
'admin.notifications.adminNtfyPanel.tokenCleared': 'Το access token διαχειριστή εκκαθαρίστηκε',
|
||
'admin.notifications.adminNtfyPanel.saved': 'Οι ρυθμίσεις ntfy διαχειριστή αποθηκεύτηκαν',
|
||
'admin.notifications.adminNtfyPanel.test': 'Αποστολή δοκιμαστικού ntfy',
|
||
'admin.notifications.adminNtfyPanel.testSuccess': 'Η δοκιμή ntfy στάλθηκε επιτυχώς',
|
||
'admin.notifications.adminNtfyPanel.testFailed': 'Η δοκιμή ntfy απέτυχε',
|
||
'admin.notifications.adminNtfyPanel.alwaysOnHint':
|
||
'Το ntfy διαχειριστή ενεργοποιείται πάντα όταν έχει διαμορφωθεί ένα θέμα',
|
||
'admin.notifications.adminNotificationsHint':
|
||
'Διαμορφώστε ποια κανάλια παραδίδουν ειδοποιήσεις μόνο για διαχειριστές (π.χ. ειδοποιήσεις έκδοσης).',
|
||
'admin.notifications.tripReminders.title': 'Υπενθυμίσεις Ταξιδιού',
|
||
'admin.notifications.tripReminders.hint':
|
||
'Αποστολή ειδοποίησης υπενθύμισης πριν την έναρξη ενός ταξιδιού (απαιτεί να έχουν οριστεί ημέρες υπενθύμισης στο ταξίδι).',
|
||
'admin.notifications.tripReminders.enabled': 'Οι υπενθυμίσεις ταξιδιού ενεργοποιήθηκαν',
|
||
'admin.notifications.tripReminders.disabled': 'Οι υπενθυμίσεις ταξιδιού απενεργοποιήθηκαν',
|
||
'admin.smtp.title': 'Email & Ειδοποιήσεις',
|
||
'admin.smtp.hint': 'Διαμόρφωση SMTP για αποστολή ειδοποιήσεων email.',
|
||
'admin.smtp.testButton': 'Αποστολή δοκιμαστικού email',
|
||
'admin.webhook.hint':
|
||
'Επιτρέψτε στους χρήστες να διαμορφώνουν τα δικά τους webhook URLs για ειδοποιήσεις (Discord, Slack, κ.λπ.).',
|
||
'admin.smtp.testSuccess': 'Το δοκιμαστικό email στάλθηκε επιτυχώς',
|
||
'admin.smtp.testFailed': 'Το δοκιμαστικό email απέτυχε',
|
||
'admin.title': 'Διαχείριση',
|
||
'admin.subtitle': 'Διαχείριση χρηστών και ρυθμίσεις συστήματος',
|
||
'admin.tabs.users': 'Χρήστες',
|
||
'admin.tabs.categories': 'Κατηγορίες',
|
||
'admin.tabs.backup': 'Αντίγραφο ασφαλείας',
|
||
'admin.tabs.notifications': 'Ειδοποιήσεις',
|
||
'admin.tabs.audit': 'Έλεγχος',
|
||
'admin.stats.users': 'Χρήστες',
|
||
'admin.stats.trips': 'Ταξίδια',
|
||
'admin.stats.places': 'Τόποι',
|
||
'admin.stats.photos': 'Φωτογραφίες',
|
||
'admin.stats.files': 'Αρχεία',
|
||
'admin.table.user': 'Χρήστης',
|
||
'admin.table.email': 'Email',
|
||
'admin.table.role': 'Ρόλος',
|
||
'admin.table.created': 'Δημιουργήθηκε',
|
||
'admin.table.lastLogin': 'Τελευταία Σύνδεση',
|
||
'admin.table.actions': 'Ενέργειες',
|
||
'admin.you': '(Εσείς)',
|
||
'admin.editUser': 'Επεξεργασία Χρήστη',
|
||
'admin.newPassword': 'Νέος Κωδικός',
|
||
'admin.newPasswordHint': 'Αφήστε κενό για να διατηρηθεί ο τρέχων κωδικός',
|
||
'admin.deleteUser': 'Διαγραφή χρήστη "{name}"; Όλα τα ταξίδια θα διαγραφούν μόνιμα.',
|
||
'admin.deleteUserTitle': 'Διαγραφή χρήστη',
|
||
'admin.newPasswordPlaceholder': 'Εισάγετε νέο κωδικό…',
|
||
'admin.toast.loadError': 'Αποτυχία φόρτωσης δεδομένων διαχείρισης',
|
||
'admin.toast.userUpdated': 'Ο χρήστης ενημερώθηκε',
|
||
'admin.toast.updateError': 'Αποτυχία ενημέρωσης',
|
||
'admin.toast.userDeleted': 'Ο χρήστης διαγράφηκε',
|
||
'admin.toast.deleteError': 'Αποτυχία διαγραφής',
|
||
'admin.toast.cannotDeleteSelf': 'Δεν μπορείτε να διαγράψετε τον δικό σας λογαριασμό',
|
||
'admin.toast.userCreated': 'Ο χρήστης δημιουργήθηκε',
|
||
'admin.toast.createError': 'Αποτυχία δημιουργίας χρήστη',
|
||
'admin.toast.fieldsRequired': 'Το όνομα χρήστη, το email και ο κωδικός είναι υποχρεωτικά',
|
||
'admin.createUser': 'Δημιουργία Χρήστη',
|
||
'admin.invite.title': 'Σύνδεσμοι Πρόσκλησης',
|
||
'admin.invite.subtitle': 'Δημιουργία συνδέσμων εγγραφής μίας χρήσης',
|
||
'admin.invite.create': 'Δημιουργία Συνδέσμου',
|
||
'admin.invite.createAndCopy': 'Δημιουργία & Αντιγραφή',
|
||
'admin.invite.empty': 'Δεν έχουν δημιουργηθεί σύνδεσμοι πρόσκλησης ακόμη',
|
||
'admin.invite.maxUses': 'Μέγ. Χρήσεις',
|
||
'admin.invite.expiry': 'Λήγει μετά από',
|
||
'admin.invite.uses': 'χρησιμοποιήθηκε',
|
||
'admin.invite.expiresAt': 'λήγει',
|
||
'admin.invite.createdBy': 'από',
|
||
'admin.invite.active': 'Ενεργός',
|
||
'admin.invite.expired': 'Έληξε',
|
||
'admin.invite.usedUp': 'Εξαντλήθηκε',
|
||
'admin.invite.copied': 'Ο σύνδεσμος πρόσκλησης αντιγράφηκε στο πρόχειρο',
|
||
'admin.invite.copyLink': 'Αντιγραφή συνδέσμου',
|
||
'admin.invite.deleted': 'Ο σύνδεσμος πρόσκλησης διαγράφηκε',
|
||
'admin.invite.createError': 'Αποτυχία δημιουργίας συνδέσμου πρόσκλησης',
|
||
'admin.invite.deleteError': 'Αποτυχία διαγραφής συνδέσμου πρόσκλησης',
|
||
'admin.tabs.settings': 'Ρυθμίσεις',
|
||
'admin.allowRegistration': 'Να επιτρέπονται οι εγγραφές',
|
||
'admin.allowRegistrationHint': 'Οι νέοι χρήστες μπορούν να εγγράφονται μόνοι τους',
|
||
'admin.authMethods': 'Μέθοδοι Ελέγχου Ταυτότητας',
|
||
'admin.passwordLogin': 'Σύνδεση με Κωδικό',
|
||
'admin.passwordLoginHint': 'Επιτρέψτε στους χρήστες να συνδέονται με email και κωδικό',
|
||
'admin.passwordRegistration': 'Εγγραφή με Κωδικό',
|
||
'admin.passwordRegistrationHint': 'Επιτρέψτε σε νέους χρήστες να εγγράφονται με email και κωδικό',
|
||
'admin.oidcLogin': 'Σύνδεση SSO',
|
||
'admin.oidcLoginHint': 'Επιτρέψτε στους χρήστες να συνδέονται με SSO',
|
||
'admin.oidcRegistration': 'Αυτόματη Δημιουργία SSO',
|
||
'admin.oidcRegistrationHint': 'Αυτόματη δημιουργία λογαριασμών για νέους χρήστες SSO',
|
||
'admin.envOverrideHint':
|
||
'Οι ρυθμίσεις σύνδεσης με κωδικό ελέγχονται από τη μεταβλητή περιβάλλοντος OIDC_ONLY και δεν μπορούν να αλλάξουν εδώ.',
|
||
'admin.lockoutWarning': 'Πρέπει να παραμείνει ενεργοποιημένη τουλάχιστον μία μέθοδος σύνδεσης',
|
||
'admin.requireMfa': 'Απαίτηση ελέγχου ταυτότητας δύο παραγόντων (2FA)',
|
||
'admin.requireMfaHint':
|
||
'Οι χρήστες χωρίς 2FA πρέπει να ολοκληρώσουν τη ρύθμιση στις Ρυθμίσεις πριν χρησιμοποιήσουν την εφαρμογή.',
|
||
'admin.apiKeys': 'Κλειδιά API',
|
||
'admin.apiKeysHint': 'Προαιρετικά. Ενεργοποιεί εκτεταμένα δεδομένα τόπων όπως φωτογραφίες και καιρό.',
|
||
'admin.mapsKey': 'Google Maps API Key',
|
||
'admin.mapsKeyHint': 'Απαιτείται για αναζήτηση τόπων. Λάβετε το από console.cloud.google.com',
|
||
'admin.mapsKeyHintLong':
|
||
'Χωρίς κλειδί API, χρησιμοποιείται το OpenStreetMap για αναζήτηση τόπων. Με κλειδί Google API, μπορούν επίσης να φορτωθούν φωτογραφίες, βαθμολογίες και ώρες λειτουργίας. Λάβετε ένα στο console.cloud.google.com.',
|
||
'admin.recommended': 'Συνιστάται',
|
||
'admin.weatherKey': 'OpenWeatherMap API Key',
|
||
'admin.weatherKeyHint': 'Για δεδομένα καιρού. Δωρεάν στο openweathermap.org',
|
||
'admin.unsplashKey': 'Κλειδί API Unsplash',
|
||
'admin.unsplashKeyHint': 'Για αναζήτηση εικόνων. Δωρεάν στο unsplash.com/developers',
|
||
'admin.validateKey': 'Δοκιμή',
|
||
'admin.keyValid': 'Συνδέθηκε',
|
||
'admin.keyInvalid': 'Μη έγκυρο',
|
||
'admin.keySaved': 'Τα κλειδιά API αποθηκεύτηκαν',
|
||
'admin.oidcTitle': 'Ενιαία Σύνδεση (OIDC)',
|
||
'admin.oidcSubtitle': 'Επιτρέψτε τη σύνδεση μέσω εξωτερικών παρόχων όπως Google, Apple, Authentik ή Keycloak.',
|
||
'admin.oidcDisplayName': 'Εμφανιζόμενο Όνομα',
|
||
'admin.oidcIssuer': 'Issuer URL',
|
||
'admin.oidcIssuerHint': 'Το OpenID Connect Issuer URL του παρόχου. π.χ. https://accounts.google.com',
|
||
'admin.oidcSaved': 'Η διαμόρφωση OIDC αποθηκεύτηκε',
|
||
'admin.oidcOnlyMode': 'Απενεργοποίηση ελέγχου ταυτότητας με κωδικό',
|
||
'admin.oidcOnlyModeHint':
|
||
'Όταν είναι ενεργοποιημένο, επιτρέπεται μόνο η σύνδεση SSO. Η σύνδεση και εγγραφή με κωδικό αποκλείονται.',
|
||
'admin.fileTypes': 'Επιτρεπόμενοι Τύποι Αρχείων',
|
||
'admin.fileTypesHint': 'Ρυθμίστε ποιους τύπους αρχείων μπορούν να μεταφορτώνουν οι χρήστες.',
|
||
'admin.fileTypesFormat':
|
||
'Επεκτάσεις χωρισμένες με κόμμα (π.χ. jpg,png,pdf,doc). Χρησιμοποιήστε * για να επιτρέπονται όλοι οι τύποι.',
|
||
'admin.fileTypesSaved': 'Οι ρυθμίσεις τύπων αρχείων αποθηκεύτηκαν',
|
||
'admin.placesPhotos.title': 'Φωτογραφίες Τόπων',
|
||
'admin.placesPhotos.subtitle':
|
||
'Λήψη φωτογραφιών από το Google Places API. Απενεργοποιήστε για εξοικονόμηση ποσοστώσης API. Οι φωτογραφίες Wikimedia δεν επηρεάζονται.',
|
||
'admin.placesAutocomplete.title': 'Αυτόματη Συμπλήρωση Τόπων',
|
||
'admin.placesAutocomplete.subtitle':
|
||
'Χρήση του Google Places API για προτάσεις αναζήτησης. Απενεργοποιήστε για εξοικονόμηση ποσοστώσης API.',
|
||
'admin.placesDetails.title': 'Λεπτομέρειες Τόπου',
|
||
'admin.placesDetails.subtitle':
|
||
'Λήψη λεπτομερών πληροφοριών τόπου (ώρες, βαθμολογία, ιστοσελίδα) από το Google Places API. Απενεργοποιήστε για εξοικονόμηση ποσοστώσης API.',
|
||
'admin.bagTracking.title': 'Παρακολούθηση Αποσκευών',
|
||
'admin.bagTracking.subtitle': 'Ενεργοποίηση βάρους και ανάθεσης τσάντας για αντικείμενα πακεταρίσματος',
|
||
'admin.collab.chat.title': 'Συνομιλία',
|
||
'admin.collab.chat.subtitle': 'Μηνύματα πραγματικού χρόνου για συνεργασία ταξιδιού',
|
||
'admin.collab.notes.title': 'Σημειώσεις',
|
||
'admin.collab.notes.subtitle': 'Κοινόχρηστες σημειώσεις και έγγραφα',
|
||
'admin.collab.polls.title': 'Δημοσκοπήσεις',
|
||
'admin.collab.polls.subtitle': 'Ομαδικές δημοσκοπήσεις και ψηφοφορίες',
|
||
'admin.collab.whatsnext.title': 'Τι Ακολουθεί',
|
||
'admin.collab.whatsnext.subtitle': 'Προτάσεις δραστηριοτήτων και επόμενα βήματα',
|
||
'admin.tabs.config': 'Εξατομίκευση',
|
||
'admin.tabs.defaults': 'Προεπιλογές Χρήστη',
|
||
'admin.defaultSettings.title': 'Προεπιλεγμένες Ρυθμίσεις Χρήστη',
|
||
'admin.defaultSettings.description':
|
||
'Ορίστε προεπιλογές για όλη την υπηρεσία. Οι χρήστες που δεν έχουν αλλάξει μια ρύθμιση θα βλέπουν αυτές τις τιμές. Οι δικές τους αλλαγές έχουν πάντα προτεραιότητα.',
|
||
'admin.defaultSettings.saved': 'Η προεπιλογή αποθηκεύτηκε',
|
||
'admin.defaultSettings.reset': 'Επαναφορά στην ενσωματωμένη προεπιλογή',
|
||
'admin.defaultSettings.resetToBuiltIn': 'επαναφορά',
|
||
'admin.tabs.templates': 'Πρότυπα Πακεταρίσματος',
|
||
'admin.packingTemplates.title': 'Πρότυπα Πακεταρίσματος',
|
||
'admin.packingTemplates.subtitle': 'Δημιουργήστε επαναχρησιμοποιήσιμες λίστες πακεταρίσματος για τα ταξίδια σας',
|
||
'admin.packingTemplates.create': 'Νέο Πρότυπο',
|
||
'admin.packingTemplates.namePlaceholder': 'Όνομα προτύπου (π.χ. Διακοπές στην Παραλία)',
|
||
'admin.packingTemplates.empty': 'Δεν έχουν δημιουργηθεί πρότυπα ακόμη',
|
||
'admin.packingTemplates.items': 'αντικείμενα',
|
||
'admin.packingTemplates.categories': 'κατηγορίες',
|
||
'admin.packingTemplates.itemName': 'Όνομα αντικειμένου',
|
||
'admin.packingTemplates.itemCategory': 'Κατηγορία',
|
||
'admin.packingTemplates.categoryName': 'Όνομα κατηγορίας (π.χ. Ρούχα)',
|
||
'admin.packingTemplates.addCategory': 'Προσθήκη κατηγορίας',
|
||
'admin.packingTemplates.created': 'Το πρότυπο δημιουργήθηκε',
|
||
'admin.packingTemplates.deleted': 'Το πρότυπο διαγράφηκε',
|
||
'admin.packingTemplates.loadError': 'Αποτυχία φόρτωσης προτύπων',
|
||
'admin.packingTemplates.createError': 'Αποτυχία δημιουργίας προτύπου',
|
||
'admin.packingTemplates.deleteError': 'Αποτυχία διαγραφής προτύπου',
|
||
'admin.packingTemplates.saveError': 'Αποτυχία αποθήκευσης',
|
||
'admin.tabs.addons': 'Πρόσθετα',
|
||
'admin.tabs.plugins': 'Plugins',
|
||
'admin.plugins.rescan': 'Επανασάρωση',
|
||
'admin.plugins.rescanned': 'Ο φάκελος plugins σαρώθηκε ξανά',
|
||
'admin.plugins.upload': 'Μεταφόρτωση plugin',
|
||
'admin.plugins.dropToUpload': 'Αποθέστε ένα .zip plugin για εγκατάσταση',
|
||
'admin.plugins.uploaded': 'Το plugin “{name}” μεταφορτώθηκε — ενεργοποιήστε το για εκτέλεση',
|
||
'admin.plugins.sideloaded': 'Φορτώθηκε χειροκίνητα',
|
||
'admin.plugins.devLinkBadge': 'Dev-Link',
|
||
'admin.plugins.devLinkHint':
|
||
'Φορτώνεται από τοπικό κατάλογο build και επαναφορτώνεται ζωντανά με πραγματικά δεδομένα — μόνο για ανάπτυξη',
|
||
'admin.plugins.devLinkTitle': 'Σύνδεση τοπικού πρόσθετου',
|
||
'admin.plugins.devLinkPathPlaceholder': '/absolute/path/to/your/plugin',
|
||
'admin.plugins.devLinkButton': 'Σύνδεση',
|
||
'admin.plugins.devLinkLinked': '{id} συνδέθηκε — ενεργοποιήστε το για εκτέλεση',
|
||
'admin.plugins.sideloadedHint': 'Μεταφορτώθηκε χειροκίνητα — όχι από το μητρώο, χωρίς υπογραφή και έλεγχο',
|
||
'admin.plugins.browse': 'Περιήγηση σε plugins',
|
||
'admin.plugins.installed': 'Εγκατεστημένο',
|
||
'admin.plugins.install': 'Εγκατάσταση',
|
||
'admin.plugins.registryEmpty': 'Δεν υπάρχουν ακόμη διαθέσιμα plugins στο μητρώο.',
|
||
'admin.plugins.actionError': 'Η ενέργεια απέτυχε',
|
||
'admin.plugins.activate': 'Ενεργοποίηση',
|
||
'admin.plugins.activated': 'Το plugin ενεργοποιήθηκε',
|
||
'admin.plugins.deactivate': 'Απενεργοποίηση',
|
||
'admin.plugins.deactivated': 'Το plugin απενεργοποιήθηκε',
|
||
'admin.plugins.viewErrors': 'Προβολή αρχείου σφαλμάτων',
|
||
'admin.plugins.errorLog': 'Αρχείο σφαλμάτων',
|
||
'admin.plugins.allowedHosts': 'Επιτρεπόμενοι κόμβοι',
|
||
'admin.plugins.allowedHosts.hint':
|
||
'Αυτό το πρόσθετο επικοινωνεί με μια υπηρεσία που μόνο εσείς μπορείτε να ονομάσετε (αυτο-φιλοξενούμενος διακομιστής). Προσθέστε τους κόμβους που μπορεί να προσεγγίσει — κανέναν άλλον.',
|
||
'admin.plugins.allowedHosts.none': 'Δεν έχουν προστεθεί κόμβοι ακόμη.',
|
||
'admin.plugins.allowedHosts.unsupported':
|
||
'Αυτό το πρόσθετο δεν χρησιμοποιεί κόμβους που ορίζει ο διαχειριστής. Οι επιτρεπόμενοι κόμβοι του είναι σταθεροί στο manifest.',
|
||
'admin.plugins.allowedHosts.restartNote': 'Η αποθήκευση επανεκκινεί το πρόσθετο ώστε να λάβει τη νέα λίστα.',
|
||
'admin.plugins.allowedHosts.add': 'Προσθήκη επιτρεπόμενου κόμβου',
|
||
'admin.plugins.allowedHosts.count': '{n} επιτρεπόμενοι κόμβοι',
|
||
'admin.plugins.operatorEgressPill': '+ κόμβοι που προσθέτετε',
|
||
'admin.plugins.operatorEgressHint':
|
||
'Αυτό το πρόσθετο επικοινωνεί με μια υπηρεσία που μόνο εσείς μπορείτε να ονομάσετε (αυτο-φιλοξενούμενος διακομιστής). Μετά την εγκατάσταση προσθέστε τους κόμβους στο ⋯ → Επιτρεπόμενοι κόμβοι. Κανέναν άλλον.',
|
||
'admin.plugins.noErrors': 'Δεν έχουν καταγραφεί σφάλματα.',
|
||
'admin.plugins.uninstalled': 'Το plugin απεγκαταστάθηκε',
|
||
'admin.plugins.uninstallTitle': 'Απεγκατάσταση plugin;',
|
||
'admin.plugins.uninstallBody':
|
||
'Αυτό σταματά το plugin, αφαιρεί τον κώδικά του και διαγράφει όλα τα δεδομένα του. Αυτή η ενέργεια δεν μπορεί να αναιρεθεί.',
|
||
'admin.plugins.status.starting': 'Εκκίνηση…',
|
||
'admin.plugins.type.widget': 'Widget',
|
||
'admin.plugins.type.page': 'Σελίδα',
|
||
'admin.plugins.type.integration': 'Ενσωμάτωση',
|
||
'admin.plugins.type.trip-page': 'Σελίδα ταξιδιού',
|
||
'admin.plugins.reviewed': 'Ελεγμένο',
|
||
'admin.plugins.unreviewed': 'Μη ελεγμένο',
|
||
'admin.plugins.updated': 'Το plugin ενημερώθηκε',
|
||
'admin.plugins.updateTo': 'Update → v{version}',
|
||
'admin.plugins.enabledToggle': 'Ενεργοποίηση plugin',
|
||
'plugins.notFound': 'Το plugin δεν βρέθηκε',
|
||
'admin.plugins.title': 'Plugins',
|
||
'admin.plugins.subtitle': 'Εγκαταστήστε και διαχειριστείτε plugins τρίτων στην εγκατάστασή σας.',
|
||
'admin.plugins.disabledTitle': 'Τα plugins είναι απενεργοποιημένα',
|
||
'admin.plugins.disabledBody':
|
||
'Το περιβάλλον εκτέλεσης plugins είναι απενεργοποιημένο (TREK_PLUGINS_ENABLED). Κανένα plugin δεν μπορεί να εκτελεστεί μέχρι ένας διαχειριστής να το ενεργοποιήσει στη διαμόρφωση του server.',
|
||
'admin.plugins.empty': 'Δεν έχουν εγκατασταθεί plugins ακόμη.',
|
||
'admin.plugins.loadError': 'Δεν ήταν δυνατή η φόρτωση των plugins.',
|
||
'admin.plugins.scaffoldNote':
|
||
'Η εγκατάσταση και ενεργοποίηση plugins έρχονται σε μελλοντική ενημέρωση. Αυτός ο πίνακας εμφανίζει προς το παρόν μόνο τα εγκατεστημένα plugins.',
|
||
'admin.plugins.status.active': 'Ενεργό',
|
||
'admin.plugins.status.inactive': 'Ανενεργό',
|
||
'admin.plugins.status.disabled': 'Απενεργοποιημένο',
|
||
'admin.plugins.status.error': 'Σφάλμα',
|
||
'admin.plugins.status.incompatible': 'Μη συμβατό',
|
||
'admin.plugins.details': 'Λεπτομέρειες',
|
||
'admin.plugins.detailError': 'Δεν ήταν δυνατή η φόρτωση των λεπτομερειών του plugin.',
|
||
'admin.plugins.permissionsTitle': 'Δικαιώματα',
|
||
'admin.plugins.noPermissions': 'Αυτό το plugin δεν ζητά ειδικά δικαιώματα.',
|
||
'admin.plugins.egressNote': 'Μπορεί να συνδεθεί σε: {hosts}',
|
||
'admin.plugins.setupTitle': 'Ρύθμιση',
|
||
'admin.plugins.noSetup': 'Λειτουργεί αμέσως — δεν χρειάζεται καμία διαμόρφωση.',
|
||
'admin.plugins.scope.instance': 'Σε επίπεδο instance',
|
||
'admin.plugins.scope.user': 'Ανά χρήστη',
|
||
'admin.plugins.fieldRequired': 'Υποχρεωτικό',
|
||
'admin.plugins.sourceRepo': 'Αποθετήριο πηγαίου κώδικα',
|
||
'admin.plugins.reportIssue': 'Αναφορά προβλήματος',
|
||
'admin.plugins.homepage': 'Αρχική σελίδα',
|
||
'admin.plugins.requiresTrek': 'Απαιτεί TREK {version}+',
|
||
'admin.plugins.reviewedOn': 'Ελέγχθηκε {date}',
|
||
'admin.plugins.perm.db:own': 'Αποθήκευση των δικών του δεδομένων σε απομονωμένη βάση δεδομένων',
|
||
'admin.plugins.perm.db:read:trips': 'Ανάγνωση ταξιδιών στα οποία έχει πρόσβαση ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:read:users': 'Ανάγνωση βασικών στοιχείων προφίλ (όνομα, avatar — ποτέ διαπιστευτήρια)',
|
||
'admin.plugins.perm.db:read:costs':
|
||
'Ανάγνωση εξόδων (στοιχεία προϋπολογισμού) στα οποία έχει πρόσβαση ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:read:packing': 'Ανάγνωση λιστών αποσκευών ταξιδιών στα οποία έχει πρόσβαση ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:write:packing':
|
||
'Δημιουργία, επεξεργασία και διαγραφή αντικειμένων λίστας αποσκευών σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης',
|
||
'admin.plugins.perm.weather:read':
|
||
'Ανάγνωση της προσωρινά αποθηκευμένης πρόγνωσης καιρού του κεντρικού υπολογιστή (ανά συντεταγμένες)',
|
||
'admin.plugins.perm.db:read:categories': 'Ανάγνωση της γενικής λίστας κατηγοριών τοποθεσιών',
|
||
'admin.plugins.perm.db:read:tags': 'Ανάγνωση των ετικετών του ενεργού χρήστη',
|
||
'admin.plugins.perm.db:write:tags': 'Δημιουργία, επεξεργασία και διαγραφή των ετικετών του ενεργού χρήστη',
|
||
'admin.plugins.perm.db:read:todos': 'Ανάγνωση των εργασιών ταξιδιών στα οποία έχει πρόσβαση ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:write:todos':
|
||
'Δημιουργία, επεξεργασία και διαγραφή εργασιών σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:write:atlas':
|
||
'Επισήμανση χωρών και περιοχών ως επισκεφθέντων και διαχείριση της λίστας επιθυμιών του ενεργού χρήστη (απαιτεί το πρόσθετο Atlas)',
|
||
'admin.plugins.perm.db:write:vacay':
|
||
'Εναλλαγή ημερών άδειας και εταιρικών αργιών στο ενεργό πλάνο του ενεργού χρήστη (απαιτεί το πρόσθετο Vacay)',
|
||
'admin.plugins.perm.db:write:journal':
|
||
'Δημιουργία, επεξεργασία και διαγραφή καταχωρήσεων σε ημερολόγια που μπορεί να επεξεργαστεί ο ενεργός χρήστης (απαιτεί το πρόσθετο Journey)',
|
||
'admin.plugins.perm.db:write:collections':
|
||
'Δημιουργία και επεξεργασία συλλογών και αποθήκευση τοποθεσιών σε αυτές, με τον ρόλο συλλογής του ενεργού χρήστη (απαιτεί το πρόσθετο Collections)',
|
||
'admin.plugins.perm.db:write:files':
|
||
'Επισύναψη αρχείων σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης (όριο 10 MB, αποκλεισμένες επεκτάσεις απορρίπτονται) και διαχείριση των συνδέσμων τους',
|
||
'admin.plugins.perm.db:write:collab':
|
||
'Δημοσίευση σημειώσεων, ψηφοφοριών και μηνυμάτων συνομιλίας σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης (απαιτεί το πρόσθετο Collab)',
|
||
'admin.plugins.perm.db:write:members':
|
||
'Προσθήκη χρηστών σε ταξίδια — παρέχει πρόσβαση στο ταξίδι· προστατεύεται από το δικαίωμα διαχείρισης μελών του ενεργού χρήστη',
|
||
'admin.plugins.perm.notify:send':
|
||
'Αποστολή ειδοποίησης (εισερχόμενα κουδουνιού + email/ntfy) στον ενεργό χρήστη ή σε ταξίδι στο οποίο ανήκει — ποτέ σε αυθαίρετο παραλήπτη',
|
||
'admin.plugins.perm.ai:invoke':
|
||
'Χρήση του παρόχου AI που ρύθμισε ο διαχειριστής (συμπλήρωση κειμένου + εξαγωγή εγγράφων) εκ μέρους του ενεργού χρήστη — το πρόσθετο δεν κρατά ποτέ κλειδί',
|
||
'admin.plugins.perm.oauth:client':
|
||
'Σύνδεση σε υπηρεσία τρίτου εκ μέρους σας μέσω OAuth με διαμεσολάβηση του κεντρικού υπολογιστή (ο κεντρικός υπολογιστής κρατά τα διακριτικά, το πρόσθετο δεν τα βλέπει ποτέ)',
|
||
'admin.plugins.perm.db:read:files': 'Ανάγνωση αρχείων ταξιδιών στα οποία έχει πρόσβαση ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:write:reservations':
|
||
'Δημιουργία, επεξεργασία και διαγραφή κρατήσεων σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:write:accommodations':
|
||
'Δημιουργία, επεξεργασία και διαγραφή καταλυμάτων σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:read:journal':
|
||
'Ανάγνωση των ημερολογίων ταξιδιού του ενεργού χρήστη (απαιτεί το πρόσθετο Journey)',
|
||
'admin.plugins.perm.db:read:atlas':
|
||
'Ανάγνωση των χωρών και περιοχών που έχει επισκεφθεί ο ενεργός χρήστης (απαιτεί το πρόσθετο Atlas)',
|
||
'admin.plugins.perm.db:read:vacay':
|
||
'Ανάγνωση του προγράμματος διακοπών του ενεργού χρήστη (απαιτεί το πρόσθετο Vacay)',
|
||
'admin.plugins.perm.db:read:daynotes':
|
||
'Ανάγνωση των σημειώσεων ημέρας ταξιδιών στα οποία έχει πρόσβαση ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:read:collections':
|
||
'Ανάγνωση των συλλογών αποθηκευμένων τοποθεσιών του ενεργού χρήστη (απαιτεί το πρόσθετο Collections)',
|
||
'admin.plugins.perm.db:write:daynotes':
|
||
'Δημιουργία, επεξεργασία και διαγραφή σημειώσεων ημέρας σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης',
|
||
'admin.plugins.perm.jobs:run':
|
||
'Εκτέλεση των δηλωμένων εργασιών παρασκηνίου βάσει προγράμματος (χωρίς περιβάλλον χρήστη — δεν μπορεί να διαβάσει δεδομένα χρήστη)',
|
||
'admin.plugins.perm.db:write:costs':
|
||
'Δημιουργία εξόδων (στοιχεία προϋπολογισμού) σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:write:places':
|
||
'Προσθήκη, επεξεργασία και αφαίρεση τοποθεσιών σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:write:days':
|
||
'Προσθήκη, επεξεργασία και αφαίρεση ημερών σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:write:itinerary':
|
||
'Ανάθεση και αφαίρεση τοποθεσιών σε ημέρες ταξιδιών που μπορεί να επεξεργαστεί ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:write:trips':
|
||
'Επεξεργασία στοιχείων ταξιδιού (τίτλος, ημερομηνίες, νόμισμα…) σε ταξίδια που μπορεί να επεξεργαστεί ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:meta':
|
||
'Επισύναψη των δικών του ιδιωτικών δεδομένων σε ταξίδια, τοποθεσίες και ημέρες στις οποίες έχει πρόσβαση ο ενεργός χρήστης',
|
||
'admin.plugins.perm.ws:broadcast:trip': 'Αποστολή ενημερώσεων σε πραγματικό χρόνο στα μέλη του ταξιδιού',
|
||
'admin.plugins.perm.ws:broadcast:user': 'Αποστολή ενημερώσεων σε πραγματικό χρόνο σε μεμονωμένους χρήστες',
|
||
'admin.plugins.perm.hook:photo-provider': 'Παροχή φωτογραφιών στις Αναμνήσεις',
|
||
'admin.plugins.perm.hook:calendar-source': 'Παροχή συμβάντων στο ημερολόγιο',
|
||
'admin.plugins.perm.hook:place-detail-provider':
|
||
'Συνεισφορά επιπλέον λεπτομερειών (κριτικές, βαθμολογίες, σύνδεσμοι) σε ένα μέρος',
|
||
'admin.plugins.perm.hook:trip-warning-provider':
|
||
'Εμφάνιση προειδοποιήσεων επικύρωσης σε ένα ταξίδι (εμφανίζονται στον σχεδιαστή)',
|
||
'admin.plugins.perm.hook:table-contributor':
|
||
'Προσθήκη στηλών και ενεργειών στις προβολές του ταξιδιού (κρατήσεις, τοποθεσίες, ημέρες)',
|
||
'admin.plugins.perm.hook:map-marker-provider':
|
||
'Προσθήκη δεικτών στον χάρτη του ταξιδιού (π.χ. εμφάνιση κρατήσεων ή POI)',
|
||
'admin.plugins.perm.hook:pdf-section-provider': 'Προσθήκη ενοτήτων κειμένου στην εξαγωγή PDF του ταξιδιού',
|
||
'admin.plugins.perm.hook:atlas-layer-provider':
|
||
'Επισήμανση χωρών στον παγκόσμιο χάρτη του Άτλαντα (π.χ. λίστες επιθυμιών ή ταξιδιωτικές οδηγίες)',
|
||
'admin.plugins.perm.hook:journal-entry-provider':
|
||
'Προσθήκη επιπλέον γραμμών (σύνδεσμοι, στατιστικά) στις καταχωρίσεις του ημερολογίου',
|
||
'admin.plugins.perm.hook:user-data':
|
||
'Διαγραφή ή εξαγωγή των δεδομένων που αποθηκεύει για έναν χρήστη (GDPR: διαγραφή λογαριασμού και αιτήματα δεδομένων)',
|
||
'admin.plugins.perm.hook:trip-card-provider':
|
||
'Προσθήκη μικρών σημάτων (κατάσταση, μετρήσεις) στις κάρτες ταξιδιού του πίνακα',
|
||
'admin.plugins.perm.hook:notification-channel': 'Παράδοση των ειδοποιήσεών σας μέσω πρόσθετου καναλιού',
|
||
'admin.plugins.perm.events:subscribe':
|
||
'Αντιδρά σε βασικά συμβάντα δραστηριότητας (όνομα συμβάντος + ταξίδι μόνο, ποτέ το περιεχόμενο)',
|
||
'admin.plugins.perm.http:outbound': 'Εκτέλεση εξερχόμενων αιτημάτων προς τους δηλωμένους hosts του',
|
||
'admin.plugins.perm.db:read:collab':
|
||
'Ανάγνωση σημειώσεων, ψηφοφοριών και μηνυμάτων συνομιλίας ταξιδιών στα οποία έχει πρόσβαση ο ενεργός χρήστης (απαιτεί το πρόσθετο Collab)',
|
||
'admin.plugins.perm.db:read:files:content':
|
||
'Ανάγνωση του περιεχομένου (bytes) των αρχείων ταξιδιών στα οποία έχει πρόσβαση ο ενεργός χρήστης',
|
||
'admin.plugins.perm.db:create:trips': 'Δημιουργία νέων ταξιδιών που ανήκουν στον ενεργό χρήστη',
|
||
'admin.plugins.perm.rates:read':
|
||
'Ανάγνωση των προσωρινά αποθηκευμένων συναλλαγματικών ισοτιμιών του κεντρικού υπολογιστή',
|
||
'admin.plugins.updateConsentTitle': 'Αυτή η ενημέρωση χρειάζεται νέα δικαιώματα',
|
||
'admin.plugins.updateConsentBody':
|
||
'Το {name} v{version} ζητά δικαιώματα που δεν έχετε ακόμη παραχωρήσει. Η νέα έκδοση έχει εγκατασταθεί αλλά παραμένει ανενεργή μέχρι να την εγκρίνετε.',
|
||
'admin.plugins.updateNewPermissions': 'Νέα δικαιώματα που ζητούνται',
|
||
'admin.plugins.updateNewEgress': 'Νέες εξερχόμενες συνδέσεις',
|
||
'admin.plugins.updateApprove': 'Έγκριση & ενεργοποίηση',
|
||
'admin.plugins.updateLater': 'Διατήρηση ανενεργού προς το παρόν',
|
||
'admin.plugins.updateKeptOff': 'Η ενημέρωση εγκαταστάθηκε — παραμένει ανενεργή μέχρι να εγκρίνετε τα νέα δικαιώματα',
|
||
'admin.plugins.reviewedMeaning':
|
||
'Το "Ελεγμένο" σημαίνει ότι ένας συντηρητής του TREK σάρωσε αυτό το plugin για κακόβουλο λογισμικό σε κάθε έκδοση — όχι για την ποιότητα ή για το αν λειτουργεί. Δεν αποτελεί εγγύηση ότι ένα plugin είναι ακίνδυνο.',
|
||
'admin.plugins.security.title': 'Πώς περιορίζονται τα plugins — και τα όρια',
|
||
'admin.plugins.security.isolationTitle': 'Κάθε plugin εκτελείται απομονωμένο',
|
||
'admin.plugins.security.isolationBody':
|
||
'Ένα plugin εκτελείται ως δική του κλειδωμένη διεργασία που μπορεί να διαβάσει μόνο τα δικά της αρχεία. Δεν μπορεί να διαβάσει τη βάση δεδομένων σας, το μυστικό σύνδεσής σας ή το κλειδί κρυπτογράφησής σας, δεν μπορεί να εκκινήσει άλλα προγράμματα και δεν μπορεί να γράψει αρχεία πουθενά. Η διεπαφή του εκτελείται σε ένα σφραγισμένο browser frame που δεν μπορεί να διαβάσει το cookie συνεδρίας σας ούτε να αγγίξει τη γύρω σελίδα του TREK.',
|
||
'admin.plugins.security.permsTitle': 'Τι σημαίνουν τα δικαιώματα',
|
||
'admin.plugins.security.permsBody':
|
||
'Τα δικαιώματα που εμφανίζονται πριν την εγκατάσταση αποτελούν ένα αυστηρό όριο που το TREK επιβάλλει όσο εκτελείται το plugin — κυριολεκτικά δεν μπορεί να κάνει τίποτα που δεν βρίσκεται στη λίστα. Όμως σας λένε τι μπορεί να κάνει ένα plugin, όχι τι κάνει στην πραγματικότητα. Ένα plugin που επιτρέπεται να διαβάζει τα ταξίδια σας και να συνδέεται σε έναν server μπορεί να στείλει τα ταξίδια σας σε αυτόν τον server, επομένως διαβάστε τα δικαιώματα και τους εξερχόμενους hosts, όχι μόνο την περιγραφή.',
|
||
'admin.plugins.security.limitsTitle': 'Τι δεν μπορούμε να υποσχεθούμε',
|
||
'admin.plugins.security.limitsBody':
|
||
'Η απομόνωση είναι ένα ισχυρό όριο λογισμικού, όχι απόλυτο. Ένα plugin λειτουργεί με ακριβώς τα δικαιώματα που εγκρίνετε, επομένως εντός αυτών των δικαιωμάτων μπορεί να συμπεριφέρεται διαφορετικά από ό,τι υποδηλώνει η περιγραφή του, και μπορεί να στείλει δεδομένα που κατέχει νόμιμα στους hosts που έχει δηλώσει. Το TREK δεν διαβάζει ούτε κρίνει τι κάνει στην πραγματικότητα ο κώδικας ενός plugin.',
|
||
'admin.plugins.security.worstTitle': 'Η χειρότερη περίπτωση',
|
||
'admin.plugins.security.worstBody':
|
||
'Ένα εχθρικό plugin που ενεργοποιείτε μπορεί να κάνει κακή χρήση των δεδομένων και των συνδέσεων που του παραχωρήσατε — για παράδειγμα, να διαρρεύσει τα ταξίδια που του επιτρέπεται να διαβάζει. Δεν μπορεί να κλέψει κωδικούς, να πλαστογραφήσει μια σύνδεση διαχειριστή, να εκτελέσει εντολές στον server σας ή να αποκτήσει πρόσβαση σε δεδομένα που δεν παραχωρήσατε. Η ζημιά παραμένει εντός όσων εγκρίνατε, και η απενεργοποίηση του plugin το σταματά.',
|
||
'admin.plugins.security.reviewedTitle': 'Τι σημαίνει το "Ελεγμένο"',
|
||
'admin.plugins.security.reviewedBody':
|
||
'Ένα ελεγμένο plugin σαρώθηκε χειροκίνητα για κακόβουλο λογισμικό από έναν συντηρητή του TREK σε κάθε έκδοση — ελέγχθηκε για εχθρικό κώδικα, όχι για το αν λειτουργεί καλά. Δεν αποτελεί υπόσχεση ότι το plugin είναι ακίνδυνο.',
|
||
'admin.plugins.security.signedTitle': 'Τι σημαίνει το "Υπογεγραμμένο"',
|
||
'admin.plugins.security.signedBody':
|
||
'Το checksum που επαληθεύει το TREK σε κάθε εγκατάσταση αποδεικνύει ότι τα αρχεία είναι ακριβώς αυτά για τα οποία εγγυάται το μητρώο. Μια υπογραφή αποδεικνύει κάτι διαφορετικό: ότι προέρχονται από τον δημιουργό, υπογεγραμμένα με ένα κλειδί που κατέχει μόνο εκείνος. Ένα υπογεγραμμένο plugin έχει και τα δύο. Ένα ανυπόγραφο δεν είναι επικίνδυνο — απλώς φέρει μία εγγύηση λιγότερη, και τα περισσότερα plugins στο μητρώο είναι σήμερα ανυπόγραφα.',
|
||
'admin.plugins.signed': 'Υπογεγραμμένο',
|
||
'admin.plugins.signedHint': 'Επαληθεύτηκε με το κλειδί υπογραφής του δημιουργού κατά την εγκατάσταση',
|
||
'admin.plugins.unsigned': 'Ανυπόγραφο',
|
||
'admin.plugins.unsignedHint':
|
||
'Τα αρχεία ταιριάζουν με αυτά για τα οποία εγγυάται το μητρώο, αλλά τίποτα δεν τα συνδέει με τον δημιουργό. Μία εγγύηση λιγότερη — όχι επικίνδυνο.',
|
||
'admin.plugins.updateBlocked': 'Η ενημέρωση μπλοκαρίστηκε — {reason}',
|
||
'admin.plugins.reviewBlock': 'Έλεγχος',
|
||
'admin.plugins.retrusted': 'Το νέο κλειδί υπογραφής έγινε αποδεκτό — το plugin ενημερώθηκε',
|
||
'admin.plugins.sig.title': 'Η υπογραφή του {name} δεν μπόρεσε να επαληθευτεί',
|
||
'admin.plugins.sig.keyChangedBody':
|
||
'Το κλειδί υπογραφής του δημιουργού δεν είναι αυτό με το οποίο εγκαταστάθηκε αυτό το plugin. Οι δημιουργοί όντως αλλάζουν κλειδιά — αλλά ένας επιτιθέμενος που θα είχε καταλάβει το plugin θα έμοιαζε ακριβώς έτσι.',
|
||
'admin.plugins.sig.invalidBody':
|
||
'Τα αρχεία δεν ταιριάζουν με την υπογραφή του δημιουργού. Δεν είναι αυτά που υπέγραψε ο δημιουργός — είτε αλλοιώθηκαν, είτε παραποιήθηκαν. Αυτό δεν μπορεί να παρακαμφθεί.',
|
||
'admin.plugins.sig.missingBody':
|
||
'Αυτό το plugin ήταν υπογεγραμμένο όταν το εγκαταστήσατε, αλλά η νέα έκδοση δεν περιλαμβάνει καμία υπογραφή. Το TREK δεν θα δεχτεί σιωπηλά αυτή την υποβάθμιση. Αυτό δεν μπορεί να παρακαμφθεί.',
|
||
'admin.plugins.sig.incompleteBody':
|
||
'Η καταχώριση στο μητρώο είναι μισοϋπογεγραμμένη: δηλώνει κλειδί δημιουργού αλλά η έκδοση δεν φέρει υπογραφή (ή το αντίστροφο). Αυτό είναι σφάλμα από την πλευρά του plugin. Αυτό δεν μπορεί να παρακαμφθεί.',
|
||
'admin.plugins.sig.pinnedKey': 'Κλειδί με το οποίο εγκαταστάθηκε',
|
||
'admin.plugins.sig.newKey': 'Κλειδί που προσφέρει τώρα',
|
||
'admin.plugins.sig.confirmOutOfBand':
|
||
'Το TREK δεν μπορεί να ξεχωρίσει μια νόμιμη αλλαγή κλειδιού από μια κατάληψη — από εδώ φαίνονται πανομοιότυπες. Επιβεβαιώστε το νέο κλειδί με τον δημιουργό μέσω ενός καναλιού που ήδη εμπιστεύεστε, προτού το αποδεχτείτε. Μόλις το κάνετε, το plugin ενημερώνεται και το νέο κλειδί απομνημονεύεται.',
|
||
'admin.plugins.sig.retrustConfirm': 'Εμπιστοσύνη στο νέο κλειδί & ενημέρωση',
|
||
'admin.plugins.sig.cancel': 'Να μην γίνει αποδεκτό',
|
||
'admin.plugins.sig.consentUnsigned':
|
||
'Τίποτα δεν συνδέει αυτή την έκδοση με τον δημιουργό της — τα αρχεία ταιριάζουν με το μητρώο, αλλά δεν φέρουν υπογραφή δημιουργού.',
|
||
'admin.plugins.security.trustTitle': 'Το συμπέρασμα',
|
||
'admin.plugins.security.trustBody':
|
||
'Η εγκατάσταση ενός plugin είναι σαν την εγκατάσταση οποιασδήποτε εφαρμογής τρίτου: προσθέστε κώδικα μόνο από δημιουργούς που εμπιστεύεστε, και σε περίπτωση αμφιβολίας, ελέγξτε τον πρώτα μόνοι σας. Το TREK δεν αναλαμβάνει καμία ευθύνη για plugins τρίτων.',
|
||
'admin.plugins.runtimeOn': 'Περιβάλλον εκτέλεσης ενεργό',
|
||
'admin.plugins.tabDiscover': 'Ανακάλυψη',
|
||
'admin.plugins.searchPlaceholder': 'Αναζήτηση plugins…',
|
||
'admin.plugins.filterType': 'Τύπος',
|
||
'admin.plugins.filterStatus': 'Κατάσταση',
|
||
'admin.plugins.sortBy': 'Ταξινόμηση',
|
||
'admin.plugins.allTypes': 'Όλοι οι τύποι',
|
||
'admin.plugins.allStatuses': 'Όλες',
|
||
'admin.plugins.stateOff': 'Ανενεργό',
|
||
'admin.plugins.filterUpdate': 'Διαθέσιμη ενημέρωση',
|
||
'admin.plugins.sortName': 'Όνομα',
|
||
'admin.plugins.sortRecent': 'Πρόσφατα ενημερωμένα',
|
||
'admin.plugins.sortUpdates': 'Ενημερώσεις πρώτα',
|
||
'admin.plugins.sortDownloads': 'Περισσότερες λήψεις',
|
||
'admin.plugins.updatesAvailable': 'Διαθέσιμες {count} ενημερώσεις για τα plugins σας.',
|
||
'admin.plugins.updateAll': 'Ενημέρωση όλων',
|
||
'admin.plugins.noMatchInstalled': 'Κανένα εγκατεστημένο plugin δεν ταιριάζει με την αναζήτησή σας.',
|
||
'admin.plugins.noMatchRegistry': 'Κανένα plugin στο μητρώο δεν ταιριάζει με την αναζήτησή σας.',
|
||
'admin.plugins.restart': 'Επανεκκίνηση',
|
||
'admin.plugins.restarted': 'Το plugin επανεκκινήθηκε',
|
||
'admin.plugins.cap.readsTrips': 'Διαβάζει τα ταξίδια σας',
|
||
'admin.plugins.cap.readsUsers': 'Διαβάζει βασικά προφίλ',
|
||
'admin.plugins.cap.readsCosts': 'Διαβάζει τα έξοδά σας',
|
||
'admin.plugins.cap.readsPacking': 'Διαβάζει λίστες αποσκευών',
|
||
'admin.plugins.cap.readsFiles': 'Διαβάζει αρχεία ταξιδιού',
|
||
'admin.plugins.cap.writesCosts': 'Προσθέτει έξοδα',
|
||
'admin.plugins.cap.writesPlaces': 'Επεξεργάζεται τοποθεσίες',
|
||
'admin.plugins.cap.writesDays': 'Επεξεργάζεται ημέρες',
|
||
'admin.plugins.cap.writesItinerary': 'Επεξεργάζεται δρομολόγιο',
|
||
'admin.plugins.cap.writesTrips': 'Επεξεργάζεται ταξίδια',
|
||
'admin.plugins.cap.metadata': 'Προσθέτει μεταδεδομένα',
|
||
'admin.plugins.cap.widget': 'Widget πίνακα',
|
||
'admin.plugins.cap.heroWidget': 'Widget κάρτας επιβίβασης',
|
||
'admin.plugins.cap.placeSlot': 'Λεπτομέρειες τόπου',
|
||
'admin.plugins.cap.daySlot': 'Λεπτομέρειες ημέρας',
|
||
'admin.plugins.cap.reservationSlot': 'Λεπτομέρειες κράτησης',
|
||
'admin.plugins.cap.replacesTabs': 'Αντικαθιστά καρτέλες του σχεδιαστή',
|
||
'admin.plugins.cap.realtime': 'Ενημερώσεις σε πραγματικό χρόνο',
|
||
'admin.plugins.cap.notificationChannel': 'Κανάλι ειδοποιήσεων',
|
||
'admin.plugins.cap.photos': 'Παρέχει φωτογραφίες',
|
||
'admin.plugins.cap.calendar': 'Παρέχει συμβάντα ημερολογίου',
|
||
'admin.plugins.cap.placeDetails': 'Εμπλουτίζει μέρη',
|
||
'admin.plugins.cap.warnings': 'Επισημαίνει ζητήματα',
|
||
'admin.plugins.cap.events': 'Αντιδρά σε δραστηριότητα',
|
||
'admin.plugins.cap.requiresAddon': 'Απαιτεί {addon}',
|
||
'admin.plugins.cap.dependsOn': 'Χρειάζεται {id} {version}',
|
||
'admin.plugins.dep.addonDisabledToast': 'Ενεργοποιήστε πρώτα τα απαιτούμενα πρόσθετα: {addons}',
|
||
'admin.plugins.dep.autoEnabled': 'Ενεργοποιήθηκαν πρώτα τα απαιτούμενα πρόσθετα: {plugins}',
|
||
'admin.plugins.dep.downloaded': 'Λήφθηκε το {id}',
|
||
'admin.plugins.dep.resolveTitle': 'Λείπουν εξαρτήσεις',
|
||
'admin.plugins.dep.resolveBody': 'Το «{name}» χρειάζεται να εγκατασταθούν αυτά τα πρόσθετα πριν ενεργοποιηθεί.',
|
||
'admin.plugins.dep.requires': 'Απαιτεί {version}',
|
||
'admin.plugins.dep.mismatch': 'Χρειάζεται {wanted} — είναι εγκατεστημένο το {installed}',
|
||
'admin.plugins.dep.download': 'Λήψη',
|
||
'admin.plugins.dep.update': 'Ενημέρωση',
|
||
'admin.plugins.dep.resolveHint': 'Λαμβάνει την πιο πρόσφατη συμβατή έκδοση, μαζί με τις δικές της εξαρτήσεις.',
|
||
'admin.plugins.dep.trekIncompatible': 'Απαιτεί TREK {range} — αυτός ο διακομιστής εκτελεί {host}',
|
||
'admin.plugins.dep.trekUnknown': 'Δεν δηλώνει ποιες εκδόσεις TREK υποστηρίζει',
|
||
'admin.plugins.installCompatible': 'Εγκατάσταση {version}',
|
||
'admin.plugins.incompatible': 'Μη συμβατό',
|
||
'admin.plugins.accessTitle': 'Σε τι έχει πρόσβαση',
|
||
'admin.plugins.connectsTitle': 'Συνδέεται σε',
|
||
'admin.plugins.detailsTitle': 'Λεπτομέρειες',
|
||
'admin.plugins.noAccess': 'Δεν χρειάζεται ειδική πρόσβαση.',
|
||
'admin.plugins.metaVersion': 'Έκδοση',
|
||
'admin.plugins.metaSize': 'Μέγεθος',
|
||
'admin.plugins.metaRequires': 'Απαιτεί',
|
||
'admin.plugins.metaReviewed': 'Ελέγχθηκε στις',
|
||
'admin.plugins.downloads': 'Λήψεις',
|
||
'admin.addons.title': 'Πρόσθετα',
|
||
'admin.addons.subtitle':
|
||
'Ενεργοποιήστε ή απενεργοποιήστε λειτουργίες για να εξατομικεύσετε την εμπειρία σας στο TREK.',
|
||
'admin.addons.catalog.packing.name': 'Λίστες',
|
||
'admin.addons.catalog.packing.description': 'Λίστες πακεταρίσματος και εργασίες προς εκτέλεση για τα ταξίδια σας',
|
||
'admin.addons.catalog.budget.name': 'Κόστη',
|
||
'admin.addons.catalog.budget.description': 'Παρακολουθήστε τα έξοδα και σχεδιάστε τον προϋπολογισμό του ταξιδιού σας',
|
||
'admin.addons.catalog.documents.name': 'Έγγραφα',
|
||
'admin.addons.catalog.documents.description': 'Αποθηκεύστε και διαχειριστείτε ταξιδιωτικά έγγραφα',
|
||
'admin.addons.catalog.vacay.name': 'Vacay',
|
||
'admin.addons.catalog.vacay.description': 'Προσωπικός σχεδιαστής διακοπών με προβολή ημερολογίου',
|
||
'admin.addons.catalog.atlas.name': 'Atlas',
|
||
'admin.addons.catalog.atlas.description':
|
||
'Παγκόσμιος χάρτης με χώρες που έχετε επισκεφθεί και ταξιδιωτικά στατιστικά',
|
||
'admin.addons.catalog.collab.name': 'Collab',
|
||
'admin.addons.catalog.collab.description':
|
||
'Σημειώσεις, δημοσκοπήσεις και συνομιλία πραγματικού χρόνου για σχεδιασμό ταξιδιού',
|
||
'admin.addons.catalog.memories.name': 'Φωτογραφίες (Immich)',
|
||
'admin.addons.catalog.memories.description':
|
||
'Μοιραστείτε φωτογραφίες ταξιδιού μέσω της δικής σας εγκατάστασης Immich',
|
||
'admin.addons.catalog.mcp.name': 'MCP',
|
||
'admin.addons.catalog.mcp.description': 'Model Context Protocol για ενσωμάτωση βοηθού AI',
|
||
'admin.addons.subtitleBefore':
|
||
'Ενεργοποιήστε ή απενεργοποιήστε λειτουργίες για να εξατομικεύσετε την εμπειρία σας στο ',
|
||
'admin.addons.subtitleAfter': '.',
|
||
'admin.addons.enabled': 'Ενεργοποιημένο',
|
||
'admin.addons.disabled': 'Απενεργοποιημένο',
|
||
'admin.addons.type.trip': 'Ταξίδι',
|
||
'admin.addons.type.global': 'Καθολικό',
|
||
'admin.addons.type.integration': 'Ενσωμάτωση',
|
||
'admin.addons.tripHint': 'Διαθέσιμο ως καρτέλα μέσα σε κάθε ταξίδι',
|
||
'admin.addons.globalHint': 'Διαθέσιμο ως αυτόνομη ενότητα στην κύρια πλοήγηση',
|
||
'admin.addons.integrationHint': 'Υπηρεσίες backend και ενσωματώσεις API χωρίς ειδική σελίδα',
|
||
'admin.addons.toast.updated': 'Το πρόσθετο ενημερώθηκε',
|
||
'admin.addons.toast.error': 'Αποτυχία ενημέρωσης προσθέτου',
|
||
'admin.addons.noAddons': 'Δεν υπάρχουν διαθέσιμα πρόσθετα',
|
||
'admin.weather.title': 'Δεδομένα Καιρού',
|
||
'admin.weather.badge': 'Από 24 Μαρτίου 2026',
|
||
'admin.weather.description':
|
||
'Το TREK χρησιμοποιεί το Open-Meteo ως πηγή δεδομένων καιρού. Το Open-Meteo είναι μια δωρεάν, ανοιχτού κώδικα υπηρεσία καιρού — δεν απαιτείται κλειδί API.',
|
||
'admin.weather.forecast': 'Πρόγνωση 16 ημερών',
|
||
'admin.weather.forecastDesc': 'Προηγουμένως 5 ημέρες (OpenWeatherMap)',
|
||
'admin.weather.climate': 'Ιστορικά δεδομένα κλίματος',
|
||
'admin.weather.climateDesc': 'Μέσοι όροι από τα τελευταία 85 χρόνια για ημέρες πέρα από την πρόγνωση 16 ημερών',
|
||
'admin.weather.requests': '10.000 αιτήματα / ημέρα',
|
||
'admin.weather.requestsDesc': 'Δωρεάν, δεν απαιτείται κλειδί API',
|
||
'admin.weather.locationHint':
|
||
'Ο καιρός βασίζεται στον πρώτο τόπο με συντεταγμένες σε κάθε ημέρα. Αν δεν έχει ανατεθεί τόπος σε μια ημέρα, χρησιμοποιείται ως αναφορά οποιοσδήποτε τόπος από τη λίστα.',
|
||
'admin.tabs.mcpTokens': 'Πρόσβαση MCP',
|
||
'admin.mcpTokens.title': 'Πρόσβαση MCP',
|
||
'admin.mcpTokens.subtitle': 'Διαχείριση συνεδριών OAuth και διακριτικών API για όλους τους χρήστες',
|
||
'admin.mcpTokens.sectionTitle': 'Διακριτικά API',
|
||
'admin.mcpTokens.owner': 'Κάτοχος',
|
||
'admin.mcpTokens.tokenName': 'Όνομα Διακριτικού',
|
||
'admin.mcpTokens.created': 'Δημιουργήθηκε',
|
||
'admin.mcpTokens.lastUsed': 'Τελευταία Χρήση',
|
||
'admin.mcpTokens.never': 'Ποτέ',
|
||
'admin.mcpTokens.empty': 'Δεν έχουν δημιουργηθεί διακριτικά MCP ακόμη',
|
||
'admin.mcpTokens.deleteTitle': 'Διαγραφή Διακριτικού',
|
||
'admin.mcpTokens.deleteMessage':
|
||
'Αυτό θα ανακαλέσει το διακριτικό άμεσα. Ο χρήστης θα χάσει την πρόσβαση MCP μέσω αυτού του διακριτικού.',
|
||
'admin.mcpTokens.deleteSuccess': 'Το διακριτικό διαγράφηκε',
|
||
'admin.mcpTokens.deleteError': 'Αποτυχία διαγραφής διακριτικού',
|
||
'admin.mcpTokens.loadError': 'Αποτυχία φόρτωσης διακριτικών',
|
||
'admin.oauthSessions.sectionTitle': 'Συνεδρίες OAuth',
|
||
'admin.oauthSessions.clientName': 'Πελάτης',
|
||
'admin.oauthSessions.owner': 'Κάτοχος',
|
||
'admin.oauthSessions.scopes': 'Scopes',
|
||
'admin.oauthSessions.created': 'Δημιουργήθηκε',
|
||
'admin.oauthSessions.empty': 'Δεν υπάρχουν ενεργές συνεδρίες OAuth',
|
||
'admin.oauthSessions.revokeTitle': 'Ανάκληση Συνεδρίας',
|
||
'admin.oauthSessions.revokeMessage':
|
||
'Αυτό θα ανακαλέσει τη συνεδρία OAuth άμεσα. Ο πελάτης θα χάσει την πρόσβαση MCP.',
|
||
'admin.oauthSessions.revokeSuccess': 'Η συνεδρία ανακλήθηκε',
|
||
'admin.oauthSessions.revokeError': 'Αποτυχία ανάκλησης συνεδρίας',
|
||
'admin.oauthSessions.loadError': 'Αποτυχία φόρτωσης συνεδριών OAuth',
|
||
'admin.tabs.github': 'GitHub',
|
||
'admin.audit.subtitle': 'Συμβάντα ασφαλείας και διαχείρισης (αντίγραφα ασφαλείας, χρήστες, MFA, ρυθμίσεις).',
|
||
'admin.audit.empty': 'Δεν υπάρχουν εγγραφές ελέγχου ακόμη.',
|
||
'admin.audit.refresh': 'Ανανέωση',
|
||
'admin.audit.loadMore': 'Φόρτωση περισσότερων',
|
||
'admin.audit.showing': '{count} φορτώθηκαν · {total} σύνολο',
|
||
'admin.audit.col.time': 'Ώρα',
|
||
'admin.audit.col.user': 'Χρήστης',
|
||
'admin.audit.col.action': 'Ενέργεια',
|
||
'admin.audit.col.resource': 'Πόρος',
|
||
'admin.audit.col.ip': 'IP',
|
||
'admin.audit.col.details': 'Λεπτομέρειες',
|
||
'admin.github.title': 'Ιστορικό Εκδόσεων',
|
||
'admin.github.subtitle': 'Τελευταίες ενημερώσεις από {repo}',
|
||
'admin.github.latest': 'Τελευταία',
|
||
'admin.github.prerelease': 'Προ-έκδοση',
|
||
'admin.github.showDetails': 'Εμφάνιση λεπτομερειών',
|
||
'admin.github.hideDetails': 'Απόκρυψη λεπτομερειών',
|
||
'admin.github.loadMore': 'Φόρτωση περισσότερων',
|
||
'admin.github.loading': 'Φόρτωση...',
|
||
'admin.github.error': 'Αποτυχία φόρτωσης εκδόσεων',
|
||
'admin.github.by': 'από',
|
||
'admin.github.support': 'Βοηθά να συνεχίσω την ανάπτυξη του TREK',
|
||
'admin.update.available': 'Διαθέσιμη ενημέρωση',
|
||
'admin.update.text': 'Το TREK {version} είναι διαθέσιμο. Εκτελείτε το {current}.',
|
||
'admin.update.button': 'Προβολή στο GitHub',
|
||
'admin.update.install': 'Εγκατάσταση Ενημέρωσης',
|
||
'admin.update.confirmTitle': 'Εγκατάσταση Ενημέρωσης;',
|
||
'admin.update.confirmText':
|
||
'Το TREK θα ενημερωθεί από {current} σε {version}. Ο server θα επανεκκινήσει αυτόματα στη συνέχεια.',
|
||
'admin.update.dataInfo':
|
||
'Όλα τα δεδομένα σας (ταξίδια, χρήστες, κλειδιά API, μεταφορτώσεις, Vacay, Atlas, προϋπολογισμοί) θα διατηρηθούν.',
|
||
'admin.update.warning': 'Η εφαρμογή θα είναι σύντομα μη διαθέσιμη κατά την επανεκκίνηση.',
|
||
'admin.update.confirm': 'Ενημέρωση Τώρα',
|
||
'admin.update.installing': 'Ενημέρωση…',
|
||
'admin.update.success': 'Η ενημέρωση εγκαταστάθηκε! Ο server επανεκκινεί…',
|
||
'admin.update.failed': 'Η ενημέρωση απέτυχε',
|
||
'admin.update.backupHint': 'Συνιστούμε να δημιουργήσετε ένα αντίγραφο ασφαλείας πριν την ενημέρωση.',
|
||
'admin.update.backupLink': 'Μετάβαση στο Αντίγραφο Ασφαλείας',
|
||
'admin.update.howTo': 'Πώς να Ενημερώσετε',
|
||
'admin.update.dockerText':
|
||
'Η εγκατάστασή σας TREK εκτελείται σε Docker. Για να ενημερωθείτε στο {version}, εκτελέστε τις ακόλουθες εντολές στον server σας:',
|
||
'admin.update.nonDockerText':
|
||
'Αυτή η εγκατάσταση TREK δεν εκτελείται σε Docker. Για να ενημερωθείτε στο {version}, εκτελέστε ξανά τη μέθοδο εγκατάστασης ή ενημέρωσης που χρησιμοποιήσατε — για παράδειγμα, στα Proxmox Community Scripts εκτελέστε την ενημέρωση από την κονσόλα LXC:',
|
||
'admin.update.wikiLink': 'Άνοιγμα του οδηγού ενημέρωσης',
|
||
'admin.update.reloadHint': 'Παρακαλώ ανανεώστε τη σελίδα σε λίγα δευτερόλεπτα.',
|
||
'admin.tabs.permissions': 'Δικαιώματα',
|
||
'admin.addons.catalog.journey.name': 'Ταξίδι',
|
||
'admin.addons.catalog.journey.description':
|
||
'Παρακολούθηση ταξιδιών & ημερολόγιο ταξιδιών με αφίξεις, φωτογραφίες και καθημερινές ιστορίες',
|
||
'admin.addons.catalog.collections.name': 'Συλλογές',
|
||
'admin.addons.catalog.collections.description':
|
||
'Προσωπική βιβλιοθήκη μερών — αποθήκευσε μέρη από όλα τα ταξίδια σε ονομασμένες λίστες, αντίγραψέ τα σε οποιοδήποτε ταξίδι, μοιράσου τα με άλλους',
|
||
'admin.passkey.title': 'Σύνδεση με passkey',
|
||
'admin.passkey.cardHint':
|
||
'Επιτρέψτε στους χρήστες να συνδέονται με passkeys (WebAuthn). Απενεργοποιημένο από προεπιλογή.',
|
||
'admin.passkey.login': 'Ενεργοποίηση σύνδεσης με passkey',
|
||
'admin.passkey.loginHint':
|
||
'Εμφανίστε μια επιλογή "Σύνδεση με passkey" και επιτρέψτε στους χρήστες να καταχωρούν passkeys στις ρυθμίσεις τους.',
|
||
'admin.passkey.notConfigured':
|
||
'Δεν αναλύεται ακόμη κανένας τομέας WebAuthn για αυτή την εγκατάσταση. Ορίστε το APP_URL ή το Relying Party ID παρακάτω — τα passkeys παραμένουν κρυφά μέχρι τότε.',
|
||
'admin.passkey.rpId': 'Relying Party ID (τομέας)',
|
||
'admin.passkey.rpIdHint':
|
||
'Ο σκέτος τομέας στον οποίο δεσμεύονται τα passkeys, π.χ. trek.example.org. Αφήστε το κενό για να παραχθεί από το APP_URL. Η μεταγενέστερη αλλαγή του ακυρώνει τα υπάρχοντα passkeys.',
|
||
'admin.passkey.origins': 'Επιτρεπόμενες προελεύσεις',
|
||
'admin.passkey.originsHint':
|
||
'Πλήρεις προελεύσεις χωρισμένες με κόμμα, π.χ. https://trek.example.org. Αφήστε το κενό για χρήση του APP_URL.',
|
||
'admin.passkey.reset': 'Επαναφορά passkeys',
|
||
'admin.passkey.resetHint':
|
||
'Αφαιρέστε όλα τα passkeys αυτού του χρήστη (π.χ. σε περίπτωση χαμένης συσκευής). Μπορούν ακόμη να συνδεθούν με τον κωδικό τους.',
|
||
'admin.passkey.resetConfirm': 'Αφαίρεση όλων των passkeys για τον/την {name};',
|
||
'admin.passkey.resetDone': 'Αφαιρέθηκαν {count} passkey(s)',
|
||
'admin.defaultSettings.mapProvider': 'Μηχανή χάρτη',
|
||
'admin.defaultSettings.mapProviderHint':
|
||
'Ο προεπιλεγμένος χάρτης για όλους σε αυτή την εγκατάσταση. Κάθε χρήστης μπορεί να τον αλλάξει στις δικές του ρυθμίσεις.',
|
||
'admin.defaultSettings.providerLeaflet': 'Τυπικός (δωρεάν)',
|
||
'admin.defaultSettings.providerMapbox': 'Mapbox (3D)',
|
||
'admin.defaultSettings.providerMapLibre': 'MapLibre (OpenFreeMap)',
|
||
'admin.defaultSettings.mapboxToken': 'Κοινόχρηστο διακριτικό Mapbox',
|
||
'admin.defaultSettings.mapboxTokenHint':
|
||
'Χρησιμοποιείται για κάθε χρήστη που δεν έχει εισαγάγει το δικό του διακριτικό — έτσι ολόκληρη η εγκατάσταση αποκτά Mapbox χωρίς να μοιράζεται το κλειδί ξεχωριστά. Αποθηκεύεται κρυπτογραφημένο.',
|
||
'admin.defaultSettings.mapboxStyle': 'Στυλ χάρτη',
|
||
'admin.defaultSettings.mapboxStylePlaceholder': 'Επιλέξτε ένα στυλ…',
|
||
'admin.defaultSettings.mapbox3d': 'Κτίρια & ανάγλυφο 3D',
|
||
'admin.defaultSettings.mapboxQuality': 'Λειτουργία υψηλής ποιότητας',
|
||
'admin.group.users': 'Users',
|
||
'admin.group.config': 'Configuration',
|
||
'admin.group.integration': 'Integrations',
|
||
'admin.group.maintenance': 'Maintenance',
|
||
'admin.invite.tripLabel': 'Προσθήκη σε ταξίδι (προαιρετικό)',
|
||
'admin.invite.tripNone': 'Χωρίς ταξίδι',
|
||
'admin.invite.tripHint': 'Ο νέος χρήστης προστίθεται αυτόματα σε αυτό το ταξίδι όταν εγγραφεί μέσω του συνδέσμου.',
|
||
'admin.invite.boundTo': 'προσθήκη στο {trip}',
|
||
};
|
||
export default admin;
|